0

What is the best way of using WordPress's core classes in the context of an object-oriented design?

I am trying to use $wp_admin_bar to remove a couple of the default WordPress designs but I am not able to find where to add $wp_admin_bar that does not trigger an error.

Below is my code. The comments should help to understand what I have tried, and what my thought process was:

<?php

    defined( 'ABSPATH' ) or die('Nothing to see here');

// Since wp_admin_bar is a class I probably need to extend to it but I am unsure what 
//file needs to be required to achieve this
class adminPanel {

  //I tried adding it here
  //protected $wp_admin_bar;
  //I also tried public $wp_admin_bar

  //resgister() function is treated as something like a __construct and is called by a 
  //Init class so $wp_admin_bar can't be declared global before the class is 
  //instantiated
  public function register(){

      //Remove wordpress logo from top nav
      add_action( 'wp_before_admin_bar_render', array( $this, 'remove_wp_logo' ), 0 );


  }

  function remove_wp_logo() {
      //As pointed out in one of the answers "global $wp_admin_bar;" might 
      //be added here but this causes: Parse error: syntax error, 
      //unexpected 'global' (T_GLOBAL)  
      $wp_admin_bar->remove_menu( 'wp-logo' );
  }

}

I even tried to add it as a global before the class that creates an object of this class is called.

if ( function_exists('add_action') && class_exists('Init')){
   global $wp_admin_bar;
   Init::register_services();
}

The error I am getting is:

Fatal error: Uncaught Error: Call to a member function remove_menu() on null

I have a feeling that I am not calling $wp_admin_bar correctly but I could also by wrong about what the actual cause of the error is.

I have tried other solutions from other questions on this site but everything so far is returning the same error.

2 Answers 2

2

I am trying to use $wp_admin_bar to remove a couple of the default WordPress designs but I am not able to find where to add $wp_admin_bar that does not trigger an error.

The wp_before_admin_bar_render hook doesn't pass the admin bar object, but you can access it manually (from within a function or a class method) using global like so, just like the Codex example here:

function remove_wp_logo() {
    global $wp_admin_bar;

    $wp_admin_bar->remove_menu( 'wp-logo' );
}
7
  • Thanks, I tried this but I get the error: Parse error: syntax error, unexpected 'global' (T_GLOBAL) Jan 13 at 3:28
  • What's your code? Can you post the full code on Pastebin.com?
    – Sally CJ
    Jan 13 at 3:32
  • Sure. So all of the code I'm using is here except for the function.php which I added here Jan 13 at 3:38
  • Did you actually use global $wp_admin_bar; or just global; ? (I'm just curious..)
    – Sally CJ
    Jan 13 at 3:39
  • 1
    This is the correct answer. I had to change a private function to public and it worked. Jan 13 at 3:54
1

As Sally pointed out, you can use the global variable. However, that makes your code a bit harder to test and to understand. The better way is using the proper hook admin_bar_menu. Like this:

add_action( 'admin_bar_menu', function( \WP_Admin_Bar $wp_admin_bar ) {
    new adminPanel( $wp_admin_bar );    
});

And then take this object in your constructor:

class adminPanel 
{
    private $admin_bar;
    
    public function __construct( \WP_Admin_Bar $wp_admin_bar )
    {
        $this-admin_bar = $wp_admin_bar;
    }
}

Then you can access this object in all your methods, and you can mock it in your unit tests.

5
  • Thank you, I think this is a great alternative for others to look to. Unfortunately, I'm not able to use this solution because I'm trying to avoid using a __construct. Here is my function.php to explain the structure in a better way. Jan 13 at 13:14
  • @User37849012643 why are you avoiding using a __construct?
    – Tom J Nowell
    Jan 13 at 21:17
  • @TomJNowell That's a great question. Maybe it's personal preference, or maybe it's a useful security feature. I haven't decided which one outweighs the other. I try to avoid using __construct because __construct is triggered whenever someone instantiates the class. I prefer the control that is allowed by using a function in the place of the __construct. Jan 14 at 0:51
  • 1
    I see no security benefits to avoiding __construct, in this case I see nothing in the question that requires the use of a class, it's just unnecessary boilerplate that complicates things. The important thing in this answer though is that Fuxia used dependency injection, and Fuxia's class has a member variable so that the admin bar object can be assigned prior to when it's needed
    – Tom J Nowell
    Jan 14 at 1:37
  • @User37849012643 There is no good reason to avoid constructors. Using them correctly will teach you a lot about proper OOP. What you have now is not OOP, but procedural code obscured with OOP syntax. Do one or the other, but do it well, and don't mix both styles, or maintenance will become a nightmare. When in doubt, keep your code as simple as possible.
    – fuxia
    Jan 14 at 4:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.