Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In PHP how can I access a ":private" array in an object?

Up until around 3.3beta1 items in the WP_Admin_Bar Object could be accessed using this type of syntax, for example to change the CSS class of one of the existing menu items:

$wp_admin_bar->menu->{'wp-logo'}['meta']['class'] = 'new-class';

When running print_r($wp_admin_bar) the output looked something like this:

WP_Admin_Bar Object
(
    [menu] => stdClass Object
        (
            [my-account] => Array
                (

However, around version 3.3beta2 the above syntax for changing a menu item's CSS class no longer works, and the output from print_r($wp_admin_bar) reveals a different structure for that object:

WP_Admin_Bar Object
(
    [nodes:WP_Admin_Bar:private] => Array
        (
            [my-account] => stdClass Object
                (
                    [id] => my-account

                )

I realize that Wordpress may not want me fiddling with the menus this way, and if there was a more standardized way to do this I would love to use it, but as far as I know there are only two functions that are available to modify the admin bar, add_menu_item and remove_menu_item, and these do not give the flexibility to do things like changing the attributes of existing menu items.

To confirm, I looked at wp-includes/class-wp-admin-bar.php it is clear that Wordpress has changed the way they define the variables.

Old Class

class WP_Admin_Bar {
    var $menu;
    var $proto = 'http://';
    var $user;

New Class

class WP_Admin_Bar {
    private $nodes = array();
    private $root = array();

    public $proto = 'http://';
    public $user;

So my question is if I have access to the global $wp_admin_bar object, is there I way I can access the objects inside nodes:WP_Admin_Bar:private? And if not, is there another way to get to these objects, such as creating a new class that extends the WP_Admin_Bar class and then accessing the objects from there?

ps: I'm trying to overcome this challenge without changing the core Wordpress files...

Link to the file: http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-includes/class-wp-admin-bar.php.source.html

like image 939
cwd Avatar asked Nov 27 '11 15:11

cwd


1 Answers

If you dont want to touch the core files, then you have to use Reflection:

$adminBar = new WP_Admin_Bar();
$reflector = new ReflectionObject($adminBar);
$nodes = $reflector->getProperty('nodes');
$nodes->setAccessible(true);
print_r($nodes->getValue($adminBar));

The hackish alternative would be casting the object to array and then doing:

$adminbar = (array) new WP_Admin_Bar;
$nodes = $adminbar[chr(0) . 'WP_Admin_Bar' . chr(0) . 'nodes'];
print_r($nodes);
like image 93
Gordon Avatar answered Sep 21 '22 08:09

Gordon