kayue / WordpressBundle

THIS PROJECT IS DEPRECATED AND WILL NOT BE MAINTAINED ANYMORE.
48 stars 14 forks source link

Global variable $wp_rewrite is returning NULL (WP 3.3 RC1) #2

Closed kayue closed 12 years ago

kayue commented 12 years ago

Hi

I was testing with Wordpress 3.3 RC1. I got the following error when the ApiLoader was trying to require_once the wp-load.php

Fatal error: Call to a member function add_rewrite_tag() on a non-object in /Users/kayue/Sites/wordpress/wp-includes/taxonomy.php on line 333

And line 333 look like this:

$wp_rewrite->add_rewrite_tag("%$taxonomy%", $tag, $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=");

For some reason the global variable $wp_rewrite is returning null. I tried to create a simple script and require_once "wp-load.php", the script ran without any problem. And if I add $GLOBALS['wp_rewrite'] = $wp_rewrite to wp-settings.php, looks like it solved the problem

Does anyone knows what could be wrong?

Backtrace:

array(7) {
  [0]=>
  array(4) {
    ["file"]=>
    string(53) "/Users/kayue/Sites/wordpress/wp-includes/taxonomy.php"
    ["line"]=>
    int(30)
    ["function"]=>
    string(17) "register_taxonomy"
    ["args"]=>
    array(3) {
      [0]=>
      &string(8) "category"
      [1]=>
      &string(4) "post"
      [2]=>
      &array(6) {
        ["hierarchical"]=>
        bool(true)
        ["query_var"]=>
        string(13) "category_name"
        ["rewrite"]=>
        array(3) {
          ["hierarchical"]=>
          bool(true)
          ["slug"]=>
          string(8) "category"
          ["with_front"]=>
          bool(true)
        }
        ["public"]=>
        bool(true)
        ["show_ui"]=>
        bool(true)
        ["_builtin"]=>
        bool(true)
      }
    }
  }
  [1]=>
  array(2) {
    ["function"]=>
    string(25) "create_initial_taxonomies"
    ["args"]=>
    array(1) {
      [0]=>
      &string(0) ""
    }
  }
  [2]=>
  array(4) {
    ["file"]=>
    string(51) "/Users/kayue/Sites/wordpress/wp-includes/plugin.php"
    ["line"]=>
    int(405)
    ["function"]=>
    string(20) "call_user_func_array"
    ["args"]=>
    array(2) {
      [0]=>
      &string(25) "create_initial_taxonomies"
      [1]=>
      &array(1) {
        [0]=>
        string(0) ""
      }
    }
  }
  [3]=>
  array(4) {
    ["file"]=>
    string(44) "/Users/kayue/Sites/wordpress/wp-settings.php"
    ["line"]=>
    int(304)
    ["function"]=>
    string(9) "do_action"
    ["args"]=>
    array(1) {
      [0]=>
      &string(4) "init"
    }
  }
  [4]=>
  array(4) {
    ["file"]=>
    string(42) "/Users/kayue/Sites/wordpress/wp-config.php"
    ["line"]=>
    int(93)
    ["args"]=>
    array(1) {
      [0]=>
      string(44) "/Users/kayue/Sites/wordpress/wp-settings.php"
    }
    ["function"]=>
    string(12) "require_once"
  }
  [5]=>
  array(4) {
    ["file"]=>
    string(40) "/Users/kayue/Sites/wordpress/wp-load.php"
    ["line"]=>
    int(29)
    ["args"]=>
    array(1) {
      [0]=>
      string(42) "/Users/kayue/Sites/wordpress/wp-config.php"
    }
    ["function"]=>
    string(12) "require_once"
  }
...
kayue commented 12 years ago

OK I guess it has something to do with Symfony's global variable settings (if any). I added the following lines to the top of wp-load.php, and Wordpress (or default php) and Symfony will return a different result:

$is_global = 'yes';
var_dump(isset($GLOBALS['is_global'])); // return true in WP and false in Symfony

I am still looking for a solution.

kayue commented 12 years ago

OK one quick way to fix this is to add global $wp_rewrite before require the wp-load.php file.

// WordpressBundle/Wordpress/ApiLoader.php

public function load($bootstrap='wp-load.php')
{
    $bootstrap = $this->wordpress_path . DIRECTORY_SEPARATOR . $bootstrap;
    if (!file_exists($bootstrap)) {
        throw new FileNotFoundException($bootstrap);
    }

    global $wp_rewrite; // add this
    $returnValue = require_once $bootstrap;

    ...

I don't know is there a better way to fix it.

mrtorrent commented 12 years ago

The problem is that one of the many poor code practices seen in WordPress is the assumption that it will be run in the global scope. Since we are including it from a function, it is not in the global scope and variables it sets are not global unless specified as such.

Rather than adding global statements into the bundle, the variable should be globalised appropriately in WordPress:

--- wp-settings.php
+++ wp-settings.php
@@ -237,7 +237,7 @@ $wp_query =& $wp_the_query;
  * @global object $wp_rewrite
  * @since 1.5.0
  */
-$wp_rewrite = new WP_Rewrite();
+$GLOBALS['wp_rewrite'] = new WP_Rewrite();

 /**
  * WordPress Object

This report tracks the globalisation issue and I've added this patch there, so hopefully it will be incorporated into 3.3.

kayue commented 12 years ago

Thank you for your explanation.

Looks like they are not going to put it in 3.3. Should we add a global statement into the bundle as a temporary fix?

mrtorrent commented 12 years ago

It really annoys me to have to do that, because this is such a stupid thing that WordPress should just fix, and we'll probably come across more variables that are assumed to be global like this and have to add them to the list. An alternative would be to add a global $wp_rewrite statement to the bottom of your wp-config.php, before it includes wp-settings.php.

You're probably right, though; it's a small workaround that means the bundle will work better out-of-the-box -- I'll push the change.

On 06/12/11 02:19, Ka Yue Yeung wrote:

Thank you for your explanation.

Looks like they are not going to put it in 3.3. Should we add a global statement into the bundle as a temporary fix?


Reply to this email directly or view it on GitHub: https://github.com/kayue/WordpressBundle/issues/2#issuecomment-3027228

mrtorrent commented 12 years ago

I just ran across a note I made a month ago about the need to explicitly globalise $wp_rewrite. If I hadn't forgotten about it this might have made it into 3.3 :(

dgspurgin commented 12 years ago

Great thread guys! Appreciate your efforts. I'm using a call to wp-load.php from the script of a sibling website I run in parallel w/ my wordpress site (doing user synching). Of course I ran into this globals issue when I required it directly from my other site.