I have two plugins I'm looking at currently. Each has a function called plugin_classes which attaches other classes to the base class.

Both of these plugins have init and hooks functions.

In the first the call to $this->plugin_classes() occurs in the hooks function while in the second it is called in the init function.

In both cases the hooks functions call the init functions.

So AFAIK it seems that there is no real difference other than in the plugin using init the classes are added slightly after those in hooks (potentially). Is there anything I'm missing?


It's hard to answer that without some additional code to accompany it as those aren't WordPress core functions and could be doing anything really. Based on a previous question, I'll assume one of the plugins you're referring to is the LiquidChurch/lqd-messages plugin and I see those methods in the main plugin file. Even if this isn't the correct file, hopefully explaining the order of execution of those will help explain when things are being called.

File 1

The order of execution for that code looks like this:

  1. The GC_Sermons_Plugin->hooks function is added in plugins_loaded on L321.
  2. This adds a hook to tgmpa_register to run the function register_required_plugin, which checks the plugin's dependencies are installed (Uses TGMPA) on L186.
  3. If that check passes, then the method GC_Sermons_Plugin->init to the init hook on L189.
  4. GC_Sermons_Plugin->plugin_classes is called, which is called inside of the plugins_loaded hook on L190.

In WordPress plugins_loaded occurs before init (not to be confused with GC_Sermons_Plugin->init, as that could potentially be called anything you want).

The code which is calling GC_Sermons_Plugin->plugin_classes is happening in this file in the WordPress hook plugins_loaded, and the GC_Sermons_Plugin->init function is being ran in the WordPress init hook. This means GC_Sermons_Plugin->plugin_classes is called before GC_Sermons_Plugin->init.

File 2

Looking at other repos under that organization, I assume the second plugin might be LiquidChurch/lqd-messages-fns as I see code that fits your question there in the main plugin file.

  1. Calls LiquidChurch_Functionality->hooks in WordPress' plugins_loaded hook on L440
  2. calls LiquidChurch_Functionality->init in WordPress' init hook.
  3. In the LiquidChurch_Functionality->init it calls LiquidChurch_Functionality->plugin_classes.

This was probably done in this manner so that LiquidChurch/lqd-messages-fns' code is ran after LiquidChurch/lqd-messages since the hook plugins_loaded happens before init inside of WordPress.

A Potential Problem

I don't know if there is an issue or not in the given scenario, but I wanted to touch upon one thing to look out for. If any of the classes that are loaded by GC_Sermons_Plugin->plugin_classes from the example from File 1 add code to the WordPress hook init - this could be fired before or after the code from File 2, which is also ran in the WordPress hook init.

From what I recall, the plugins in WordPress are loaded in alphabetical sort order most of the time, but this is where using the priority argument for add_action and add_filter would be important. Instead of relying on the fact that plugins_loaded happens before init, it would be better to rely on the fact that all of the code you want to run on init occurs in the order you want it to. I see from the first plugin there are multiple composer dependencies, so those external codebases could be calling certain parts of code at any point in WordPress' execution. Some could be before or after that you intended.

If we were to instead do this scenario:

// Plugin 1
add_action( 'init', array( $this, 'plugin_classes' ), 10 );

// Plugin 2
add_action( 'init', array( $this, 'plugin_classes' ), 20 );

We would be using the priority argument to say run this code at priority 10 which gets executed before priority 20 - ensuring that Plugin 1's code is always executed on the same hook, and before Plugin 2 does. This is generally the best approach to take instead of relying on the hook order being fired, or the alphabetical sort order of folder names for plugins. There's nothing wrong with the given implementation overall, you just have to be careful to ensure that code is ran in the order you are expecting to avoid conflicts or weird scenarios.

Hopefully this explanation helps!

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.