Custom hooks in WordPress across plugins - php

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.

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!).

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.

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.

Related

How can apply_filters be used to create a filter hook in wordpress?

Wordpress documentation about apply_filters mentions:
It is possible to create new filter hooks by simply calling this function, specifying the name of the new hook using the $hook_name parameter.
Ok, I want to create a filter hook called the_content2, so I do what the docs suggest:
$custom_hook = apply_filters("the_content2", the_content());
Now I assume the_content2 hook is created and is similar to the_content. So on a single post page I should be able to use the_content2 hook like the_content2:
the_content2()
This throws error, function is not defined. I am beginner in wordpress, can someone please explain comprehensively how apply_filters can be used to create your own filters.
Hooks (actions and filters) have two main components, the part that declares the hook, and the callbacks that implement the hook.
A very simple example is:
$name = "Chris";
$name = apply_filters("change_name", $name);
echo $name;
If no one registers a callback, then Chris will be outputted. However, if someone writes this:
add_filter(
"change_name",
function($name){ return "Steve";}
);
Then Steve will be outputted.
At no point, however, will a new function called change_name() be created.
As it relates to hooks, I would generally steer you away from thinking about a hook "being created", and instead think about it as "being called". A function always exists, but hooks are only used if they are actually called.
To your main issue as it relates to the_content(), I would determine what you want to do with that. If you want to transform the result of that function for all instances, a hook is probably a good idea. However, if you just want to use it differently sometimes, a custom function (without a hook) that calls the original, does something and returns it might be more appropriate.
EDIT
Below is a mock of how the hook system works. I've simplified it a bunch, but it should give you a gist of how it works.
function add_filter($name, $callback) {
global $filters;
$filters[$name][] = $callback;
}
function apply_filters($name, $value) {
global $filters;
if(array_key_exists($name, $filters)) {
foreach($filters[$name] as $callback) {
$value = $callback($value);
}
}
return $value;
}
I can't stress this enough, no one is really declaring or registering things. At most, an array key is added with a name when the add_filter/add_action is used. Then, if someone calls the apply_filters/do_action then the key is looked up, and if it exists, the callbacks are run.
So add_filter/add_action has to happen first. It is "I'm interested in XYZ if it actually happens". There's many cases where it might not happen, but if it does, then the callback will fire.
The apply_filters can't/shouldn't throw an error if no one registered a callback, because that is totally a valid case. I often write code that is extensible for future callers but you'll notice that if no one adds a filter, the initial value is returned.

How can I pass my own variables between functions tied to action hooks in wordpress plugins

I am writing a Wordpress plugin in PHP and I want to be able to use a variable that is not provided in the action hook (of other separate) plugin. I want to pass a variable from one hook to another.
These functions are in my functions.php file (not the theme functions file).
I cannot nest the action hooks because they happen at different times, specifically, the one with the variable happens after the one with where I want it.
I don't think I can use a closure because the variable is inside another hook.
I can't use a class because if I set the class in action 1 then it's not in scope in action 2 and I need to make a new one.
I could use a global or access the DB but I feel like there should be a better way than either of those.
action 1 - my plugin
function foo($level){
do stuff
}
add_action('change-membership', 'foo');
action 2 - my plugin
function bar(){
if($level==0){
do stuff
}
}
add_action('put-in-checkout-text', 'bar');
Other devs plugin
do_action('change_membership', $level);
// a little later
do_action('put_in_checkout_text');
$levels exists at the time I want it - but there is no action hook at that point to grab it.
What I understand is you have something like this:
// Plugin 2, the plugin you are writing.
do_action('put_in_checkout'); // --> bar()
// Plugin 1, another author's plugin
$level = "definition of level";
do_action('change_membership', $level); // --> foo($level)
You say you need to access to $level before the change_membership action happens, so $level may not be defined at that time. Even if it was, it may be in a scope not reachable from put_in_checkout handler functions.
Just in case, check if plugin 2 instanciates a global variable where you have access to the value of $level. Otherwise, you need to take it from the database (if it is stored there) or generate it somehow.

How to hook a function into filter in a class of plugin from wordpress

I am not very old on Wordpress.
I am developing a website which has a Third party plugin having class Plugin_Class and there are some filters in the construct of it. I want to hook my additional function to filter Plugin_filter_1 from functions.php.
I have tried with the syntax add_filter( 'Plugin_filter_1', array('Plugin_Class', 'my_function_defined_in_functions_php' ) );,
it gives me error even if the class is visible ( checked with get_declared_classes() )
The detailed answer will be appreciated
Thanks for your help
Regards
Possibly the issue is that your second parameter for add_filter is an array with Plugin_Class as the first element- this means wordpress will try to fire PluginClass::my_function_defined_in_functions_php, which doesn't exist.
Instead, just pass it a string of 'my_function_defined_in_functions_php'.
If this doesn't work with just this edit, show us the code in the plugin class- including the class name and entire construct method. There are more possible issues.

Trying to "add_action" to "create_order" function in Woocommerce/Wordpress

I'm trying to hook into the WooCommerce function that creates orders create_order or wc_create_order - and pull some of the variables from it. I've hooked into functions before, but they've never been this complicated. The functions are inside the WC_Checkout Class - and I can't seem to find the right tool to get over that wall.
The code inside the function is irrelevant at this point in time. I just want the function to fire. I've tried the basic add_action function.
add_action( 'create_order', 'my_function', 1, 1 );
I also tried a few more options that were a little complicated, but the resources for this were a little sketch. I'm pretty sure it's more complicated than this too:
function init() {
add_action('create_order', array(&$this, 'my_function'), 1, 1 );
}
I've seen some posts including __construct() but they weren't specific enough to work.

WordPress do_action and add_action; running arguments in add_action call

I am currently writing a plugin for WordPress, and I'm stumped with the add_action and do_action functions. I think I may be trying to use them in the wrong context, and if that's the case - could someone point me in the right direction?
I've come from hating WordPress to loving it, I never thought I'd write a wordpress plugin but now I am getting the hang of things, it's not all that different from normal PHP Development.
Anyway, if I was to have the following code in a plugin:
class aCoolPlugin {
function __construct() {
add_action('clear_auth_cookie', array( $this, 'aCoolFunction' ), 10, 2 );
}
function aCoolFunction( $arg1, $arg2 ) {
// Do something with the arguments
}
}
How would I actually run the aCoolFunction function? Now, I have tried the following:
do_action( 'init', "arg1 value", "arg2 value" );
However, before even trying to run that code I realised:
It makes no sense, since it will essentially be running the init action far too early, and;
It just doesn't work anyway!
So, from that I learnt:
I use add_action to hook into already existing functions for WP
do_action is reserved for new hooks really, can't really think of a useful situation where a hook should be called earlier, and then again later?
So, my question now is: How the heck can I pass my variables into the add_action code? The Codex doesn't say anything regarding arguments, so what are my options? or, is my logic and understanding flawed?
And what is the overall goal? The goal is to have a function with set arguments run every time a specific hook is called, and for the original hook to not be called any earlier/later than it should be
The add action does not accept any new variables nor will it return any variables to the function that runs it. But you can access variables that are passed to the function.
function custom_function($arga){
echo $arga;
}
add_action ('callname', 'custom_function', 10, 1);// 1= number of arguments accepted, use 2 for 2 etc...must add variables to do action call
//sometime later in the code
do_action('callname', $arga);
If you want to inject variables in you have to think a little bit back to basics. If you want to access variables within functions that are not passed you have 2 options:
Retrieve them from DB or server storage or similar
Use the Global declaration. You can accesss all variables that are set at the time the do_action is run.
You would rarely call do_action for wordpress hooks (see note below), but you may end up in a situation where you are coding a template FILE (which runs after plugins and then after themes) and you want to keep your logic in the plugin you could add do_action() into the template file and the actions set in the plugin will run at that point. Or similarly if you design a plugin that you want to be able to modify in the theme you could add an action to a late wp hook, within the called function, you could call do_action for your custom hook and hook functions to it in your theme. Loads of possibilities.
Whatever your logic for calling a WP hook early is, don't if you are within the WP load pattern

Categories