kayue / WordpressBundle

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

Wordpress rewrote the $_GET variable #8

Open kayue opened 12 years ago

kayue commented 12 years ago

If I do a var_dump($_GET) before Wordpress, I get this:

array(1) {
  ["test"]=>
  string(9) "quote"
}

And this is what I get after Wordpress loaded, something similar to magic quote in PHP!

array(1) {
  ["test"]=>
  string(9) "\"quote\""
}

All this happens in load.php of Wordpress, called by wp-settings.php

/**
 * Add magic quotes to $_GET, $_POST, $_COOKIE, and $_SERVER.
 *
 * Also forces $_REQUEST to be $_GET + $_POST. If $_SERVER, $_COOKIE,
 * or $_ENV are needed, use those superglobals directly.
 *
 * @access private
 * @since 3.0.0
 */
function wp_magic_quotes() {
    // If already slashed, strip.
    if ( get_magic_quotes_gpc() ) {
        $_GET    = stripslashes_deep( $_GET    );
        $_POST   = stripslashes_deep( $_POST   );
        $_COOKIE = stripslashes_deep( $_COOKIE );
    }

    // Escape with wpdb.
    $_GET    = add_magic_quotes( $_GET    );
    $_POST   = add_magic_quotes( $_POST   );
    $_COOKIE = add_magic_quotes( $_COOKIE );
    $_SERVER = add_magic_quotes( $_SERVER );

    // Force REQUEST to be GET + POST.
    $_REQUEST = array_merge( $_GET, $_POST );
}
mrtorrent commented 12 years ago

Strange! Does it affect your Symfony app? On Feb 10, 2012 10:01 AM, "Ka Yue Yeung" < reply@reply.github.com> wrote:

If I do a var_dump($_GET) before Wordpress, I get this:

array(1) {
 ["test"]=>
 string(9) "quote"
}

And this is what I get after Wordpress loaded, something similar to magic quote in PHP!

array(1) {
 ["test"]=>
 string(9) "\"quote\""
}

OMG!


Reply to this email directly or view it on GitHub: https://github.com/kayue/WordpressBundle/issues/8

kayue commented 12 years ago

This is a problem if I initiate Symfony after Wordpress is loaded.

If I do it the other way around, it seems it won't affect Symfony's HttpFoundation\Request object because Symfony seems keep a copy of the globals in somewhere else.

I am taking a look.

kayue commented 12 years ago

Yes Symfony\Component\HttpFoundation\Request::createFromGlobals() keep a copy of the globals.

So to fix this we have to strip slashes before $kernel->handle(Request::createFromGlobals()), I don't think we can fix this in Wordpress bundle.

...
$_GET     = stripslashes_deep($_GET);
$_POST    = stripslashes_deep($_POST);
$_COOKIE  = stripslashes_deep($_COOKIE);
$_SERVER  = stripslashes_deep($_SERVER);
$_REQUEST = array_merge($_GET, $_POST);

$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$response = $kernel->handle(Request::createFromGlobals());
...
mrtorrent commented 12 years ago

No, I don't think this is within the scope of the bundle. Also, what's the use case for loading WordPress before Symfony? Generally if you're using the bundle it will happen after. On Feb 11, 2012 2:01 AM, "Ka Yue Yeung" < reply@reply.github.com> wrote:

Yes Symfony\Component\HttpFoundation\Request::createFromGlobals() keep a copy of the globals.

So to fix this we have to strip slashes before $kernel->handle(Request::createFromGlobals());, I don't think we can fix this in Wordpress bundle.

...
$_GET     = stripslashes_deep($_GET);
$_POST    = stripslashes_deep($_POST);
$_COOKIE  = stripslashes_deep($_COOKIE);
$_SERVER  = stripslashes_deep($_SERVER);
$_REQUEST = array_merge($_GET, $_POST);

$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$response = $kernel->handle(Request::createFromGlobals());
...

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

kayue commented 12 years ago

I want to run Wordpress first because most people visit my site are for the blog, not my Symfony app, so I only want to load Symfony if I need to.

I use the status_header filter in Wordpress to detect is page found or not, if page not found, then I load Symfony. I added the following code to my Wordpress theme's functions.php:

<?php

require_once __DIR__.'/symfony/app/bootstrap.php.cache';
require_once __DIR__.'/symfony/app/AppKernel.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;

/**
 * Send response from Symfony if page not found in Wordpress.
 *
 * @see /wp-includes/functions.php
 */
add_filter('status_header', function($status){  
    // if page not found in Wordpress
    if('Not Found' === substr($status,strlen('Not Found') * -1)) {
        $kernel = new AppKernel('prod', false);

        // strips magic quotes added by Wordpress
        $_GET     = stripslashes_deep($_GET);
        $_POST    = stripslashes_deep($_POST);
        $_COOKIE  = stripslashes_deep($_COOKIE);
        $_SERVER  = stripslashes_deep($_SERVER);
        $_REQUEST = array_merge($_GET, $_POST);

        // load Symfony
        $kernel->loadClassCache();
        $response = $kernel->handle(Request::createFromGlobals());

        // send response from Symfony if found
        if(404 !== $response->getStatusCode()) {
            $response->send();

            // We already got what we want. Exit from Wordpress so it won't return 404 from Wordpress.
            exit(); 
        }
    }

    return $status;
});