9
votes

I'm trying to create a hook in one Wordpress plugin that could be used by other plugins. First off, is this even possible? I'm also sending some additional args so this may be 2 questions in one since I've been having trouble finding definitive information on how to do this.

Here is what I've tried so far:

In the plugin that is creating the hook (call it Plugin 1) I added:

do_action('plugin1_hook', $customArg1, $customArg2, $customArg3);

at the point that I want the hook to fire. Then, in a different plugin (Plugin 2), I added:

add_action('plugin1_hook', 'my_function');

and

function my_function($customArg1, $customArg2, $customArg3) { //my code }

This does not seem to be firing the function, however. My refence for this has been the Wordpress hook comment_post, which is defined by Wordpress as:

do_action('comment_post', $comment_ID, $commentdata['comment_approved']);

and I am using as:

add_action('comment_post', 'my_comment'); 
function my_comment($comment_id) { //my code }

The above snippet is functioning properly.

3

3 Answers

5
votes

I thought I'd post this as an answer as it's a little clearer to explain :)

When you hook a function, but do not specify the number of arguments, WordPress will always pass back one argument.

You won't get errors for something like this;

function do_my_hook($arg1, $arg2 = '', $arg3 = '') {}
add_action('my_hook', 'do_my_hook');

But you will for something like this;

function do_my_hook($arg1, $arg2, $arg3) {}
add_action('my_hook', 'do_my_hook');

WordPress is trying to call do_my_hook(), but it's only passing back one argument. The first example uses PHP default function arguments, so that you can call a function without passing all available arguments, but without error.

The second example will trigger a 'missing argument(s)' PHP error, as all three arguments are required.

The fix?

add_action('my_hook', 'do_my_hook', 10, 3);

The idea behind defining how many arguments your function takes is to avoid errors like these (though technically they are as easily avoided using default arguments!).

1
votes

My guess is the second plugin is loading after the first one, so the hook has already fired by the time you add an action to it. You might try this for the first plugin:

function my_custom_hook_insertion($arg1, $arg2, $arg3){
  do_action('plugin1_hook', $arg1, $arg2, $arg3);
}
add_action('plugins_loaded', 'my_custom_hook_insertion');

That will wait until all plugins are loaded before firing the hook.

0
votes

Changing my add_action to this fixed the problem:

add_action('plugin1_hook', 'my_function', 10, 3);

The 10 represents the priority, and the 3 represents the number of args that the function will take. I'm not exactly sure how the matching works, since the default is 1, and I use plenty of hooks without specifying 0 args and I've used hooks that pass more than 1 arg but only used 1 arg in my function signature. Source: WordPress Codex: Function Reference/add action

It is working though, so cross plugin hooks are possible.