Is it possible to add an action to the currently running action?

My question is very simple but I haven’t found this answer yet. Here’s an example:

class MyClass {
  public function __construct(){
    add_action('init', array($this, 'init'));
    add_action('wp_footer', array($this, 'footer'));
  }

  public function init(){
    add_action('init', array($this, 'register_scripts'));
  }

  public function register_scripts(){
    wp_register_script('my-script', plugins_url('/script.js', __FILE__));
  }

  public function footer(){
    echo('<div class="style-me">Rawr this is my plugin.</div>');
  }
}

This is how my code looks and it’s failing. It displays the div but the javascript does not get applied. So I wondered if my problem was running the init() function in the init action and then adding register_scripts() to the init action but I’m already in that action. Is this possible?

Related posts

3 comments

  1. You have to use a later (higher) priority. So use current_filter() to get the current hook and priority, add 1 to that priority, and register the next action:

    add_action( 'init', 'func_1' );
    
    function func_1()
    {
        global $wp_filter;
    
        $hook = current_filter();
        add_action( $hook, 'func_2', key( $wp_filter[ $hook ] ) + 1 );
    }
    
    function func_2()
    {
        echo 'hi!';
    }
    
  2. Yes, this is probably the problem. Why are you using this approach?

    Why not just do the following?

    public function init(){
         wp_register_script('my-script', plugins_url('/script.js', __FILE__));
      }
    
  3. I know this is an old question, but in version 4.7, WordPress changed how they handled hooks, so the answer above will no longer work.

    The relevant difference is in the my-functions.php file which contains a function that will return the current priority of a hook for versions before and after 4.7.

    ( Note: I don’t like adding hooks in the constructor, so I’ve taken the liberty to structure the plugin a little differently, but it will work the same. )

    In my-plugin.php:

    require_once( PATH_TO . '/my-functions.php' );
    require_once( PATH_TO . '/my-class.php' );
    
    add_action( 'plugins_loaded', [ new MyClass(), 'register' ] );
    

    In my-functions.php:

    if( ! functions_exists( 'current_priority' ) ):
    function current_priority() {
      global $wp_filter;
      global $wp_version;
      return version_compare( $wp_version, '4.7', '<' ) ?
        key( $wp_filter[ current_filter() ] ) :
        $wp_filter[ current_filter() ]->current_priority();
    }
    endif;
    

    In myclass.php:

    class MyClass {
    
      public function register() {
        add_action( 'init', [ $this, 'init' ] );
        add_action( 'wp_footer', [ $this, 'footer' ] );
      }
    
      public function init(){
        //* Add action to current filter at the next priority
        add_action( current_filter(), [ $this, 'register_scripts' ], current_priority() + 1 );
      }
    
      public function register_scripts(){
        wp_register_script( 'my-script', plugins_url( '/script.js', __FILE__) );
      }
    
      public function footer(){
        echo( '<div class="style-me">Rawr this is my plugin.</div>' );
      }
    }
    

Comments are closed.