3

I see a lot of plugins that consist of a class that is instantiated in the same file, eg:

class My_Plugin {

  function __construct() {
    add_action('init', array( __CLASS__, 'baz' ) ); 
  }

  static function baz() {
    // some stuff that should happen in admin
  }

}

new My_Plugin();

Now, it would work to wrap the inner workings of each function in a conditional, but could I wrap the add_action() statements in if( is_admin() ) instead, and keep from bloating the site's respective lists of filters?

  • Have you encountered a situation where is_admin is unavailable? Note that it would be impossible to test that class as loading the file immediately creates the object, and creating the object registers all the hooks, making control over when the object is created, and when it starts doing work impossible – Tom J Nowell Oct 11 '18 at 1:31
  • No, I haven't - reading the core files I see is_admin is declared very early on - but it also won't be fatal if the result isn't available - just false. – Isaac Lubow Oct 11 '18 at 17:58
2

When is is_admin() available?

Pretty much everywhere. The only example I can think of where it wouldn't be available, is super early in files such as wp-config.php, and some drop-ins. But by the time an mu-plugin, a theme, or a plugin is loaded it's present.

Now, it would work to wrap the inner workings of each function in a conditional, but could I wrap the add_action() statements in if( is_admin() ) instead, and keep from bloating the site's respective lists of filters?

Yes, but in the example you gave it's easier to just hook into admin_init instead. Adding stuff to hooks isn't expensive, it's what happens when the hook fires and the function runs that's expensive.

Some Extra Notes

I see a lot of plugins that consist of a class that is instantiated in the same file, eg:

This is bad practice, you're right to question it, and should not be copied. Do not create an object in the same file that its class is defined, it brings with it problems.

function __construct() {
  add_action('init', array( __CLASS__, 'baz' ) ); 
}

This means the moment you create this object, it will register hooks and start doing things. This can be annoying or create problems that are easily avoided by having a run or start function. It also makes writing unit tests very difficult, and in some cases impossible. A constructor should prepare the object for work, but it shouldn't do the work. Think of it as buying a washing machine vs washing clothes with it. A constructor might assemble the machine and prep it ready, but it's handy to be able to say when and if it runs

   add_action('init', array( __CLASS__, 'baz' ) ); 
 }

 static function baz() {

Because the function bar is static, if more than one of this object were created, baz would run multiple times

new My_Plugin();

There's a few issues here:

  • Loading the file immediately creates an object and does stuff. You might not want it to do that stuff yet, so you've lost control of that
  • The object that gets created is never assigned to anything, it's just left dangling. This makes stack traces and debugging significantly harder to do because it's now an anonymous class
  • Because it's anonymous, you can never unhook any of it's actions. To do that you need a reference to the object, but that's impossible here

The TLDR of the original answer though is that you can rely on is_admin being available, and you should never encounter a situation in a plugin or theme where it's unavailable

  • 1
    Yeah sorry - I was trying to simplify the code as much as possible for an example. It was actually a singleton pattern whose class is referred to by a static function that returns its instance. The question was about is_admin() - and you've answered it - and the rest is helpful too! – Isaac Lubow Oct 11 '18 at 16:58
  • I'd avoid singletons, they're even harder to test and work with – Tom J Nowell Oct 11 '18 at 17:31
  • I edited my answer a little to organise it better and expand a little on some things – Tom J Nowell Oct 11 '18 at 19:36

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.