Can someone help me explain what is going on here? I am going through a Wordpress plugin. It has the following constructor function
protected function __construct() {
do_action_ref_array( 'plugin_specific_action_name', array( $this ) );
add_action( 'init', array( $this, 'init' ) );
}
My question is on the first line of the constructor. The action 'plugin_specific_action_name' didn't have any function associated anywhere. The action hook is plugin specific. Since it didn't have any function associated with it, what does it helps the plugin with.
The author has commented "Announce that the class is ready, and pass the object (for advanced use)". Can someone help me what exactly will that be used for? Why do I have to use this in the constructor function? What will be the advanced use cases I can use that for? Any help in clearing this for me will be appreciated
Ok. do_action or do_action_ref_array is just a placeholder. Any custom behavior can be introduced here with help of add_action. If nothing is specified the action will be muted. So it is a place holder. The eye opener for me here is do_action can exist without add_action
Related
I have this code:
add_action('woocommerce_init', 'on_woocommerce');
function on_woocommerce(){
function log_cart(){
global $woocommerce;
$cart_content = $woocommerce->cart->get_cart();
log_debug($cart_content,'$cart_content');
}
if(HLP_DEBUG){
log_cart();
}
}
But it gives me error because $woocommerce is null.
Instead if I use this:
add_action('woocommerce_init', 'on_woocommerce');
function on_woocommerce(){
function log_cart(){
$cart_content = WC()->cart->get_cart();
log_debug($cart_content,'$cart_content');
}
if(HLP_DEBUG){
log_cart();
}
}
Everything it's right and working.
The code is inside another function executed on woocommerce_init HOOK. For what is my knowledge both should work.
Could you explain why the first one doesn't?
The behavior you describe is possible if you hook onto "woocommerce_loaded", but it is not possible if you hook onto "woocommerce_init".
The last line of wp-content/plugins/woocommerce/woocommerce.php is
// Global for backwards compatibility.
$GLOBALS['woocommerce'] = WC();
This suggests that using global $woocommerce is deprecated.
The last line is global code, that runs after the file is included. So, during the creation of the class WC the constructor gets run.
/**
* WooCommerce Constructor.
*/
public function __construct() {
$this->define_constants();
$this->includes();
$this->init_hooks();
do_action( 'woocommerce_loaded' );
}
init_hooks() adds WC's init function to the higher WP init action. Then the woocommerce_loaded action is fired. This is fired before the constructor completes, and before the object is added to the globals array.
After the woocommerce_loaded action is done, the constructor returns, and the WC object is added to the globals. There is no way WP's init action can be fired, and woocommerce is hooked into it, without the global being available.
This is for WC 2.5.5, I have checked the source code back to 2.3.0, other versions may be different.
You may have a rogue plugin or theme that is calling woocomerce_init before the WC() object is made, or before it returns (i.e. on the woocommerce_loaded action).
The only real explanation is that your function on_woocommerce() is being called from another hook or in another way accidentally. There is no way that the global function WC() could be defined, but the very next line of source code hasn't executed (which is store the result of WC() in a global variable).
I'm going to structure this as best I can. Basically I have a Hook class that works by adding supplied hooks.
An example of this would be:
$this->registry->hook->add('HOOK_NAME', 'CLASS_NAME||METHOD_NAME')
The hook adding, calling, removing functions work great, now the issue resides when I set the hook in a separate method in a completely different class.
An example of this would be when a user logs in.
The path they take is User Controller -> Form Class -> Login Process Function
Now within this login process function, I'd like to set a hook to be called later to end the session. (Would be added as stated above)
The issue seems to be that it gets set but doesn't stay persistently, if that makes sense?
If anyone is interested, this is what the hook add function looks like:
function add($hook, $callback, $params = '') {
//make sure the hook is defined
if (!isset($this->hooks[$hook])) {
$this->hooks[$hook] = array();
}
//add the callback to the hook
$this->hooks[$hook]['callback'] = $callback;
// add the params if supplied
if (!empty($params)) {
$this->hooks[$hook]['params'] = $params;
}
}
Should I be using magic methods __set() and __get() ?
Any help would be appreciated! :)
I am learning about OOP, and I think I am getting the hang of it. My question is why the author of a wordpress boilerplate plugin wrote the add action function like this
add_action('admin_init', array(&$this, 'admin_init'));
According to the codex I understand the add_action hook, the paramaters to be passed are $tag "The name of the action to which $function_to_add is hooked", and the function that you want hooked $function_to_add.
Well I understand the functions in OOP are methods, and I can see why that may change the syntax, but that is just a vague representation, I want a clear answer why the author uses an array, then uses &$this. I understand why one would use $this->property but not so sure about &$this.
Is it just how you refer to the method? If so I still dont understand the array, why wouldnt it look something like $this->admin_init.
By the way the structure looks kind of like this
class my_plugin_settings {
public function __construct() {
// register actions
add_action('admin_init', array(&$this, 'admin_init'));
}
public function admin_init() {
//Settings here
}
}
&this provides context to the PHP functions under the hood that hook it up to your admin_init function. Check out the declaration of add_action or take a look at http://www.php.net/manual/en/function.call-user-func-array.php.
That's how PHP knows to use the function in that object, not a global-level function
I have a function that needs the wordpress global $post. So i have written it like so:
function custom_function($post){//stuff}
I have added the function to the wp_head:
add_action('wp_head', 'custom_function');
Is there a way to pass the function the variable through the action? the only solution I can come up with is setting global $post inside the function, but that's not good practice.
Thanks guys.
You can pass arguments parameter in do_action function like below.
add_action('wp_head', 'custom_function','10',1);
do_action( 'wp_head', $post);
Read do_action for more.
Note: To use like global $post; is totally fine. It dosen't consider as bad practice specifically for wp.
I am trying to create a wordpress plugin, I found one plugin which use oops concepts, my question is why the second parameter in the add_action function is an array instead of a function name
add_action('admin_menu', array(&$this,
'my_menu'));
my_menu is a function in the same class, please help me
Thanks
Because the second argument needs to be a callback. (and add_action internally uses call_user_func_array).
For functions we can just pass its name as a string but we can't do that with object methods, can we?
So an array is passed with 2 elements, first the object and second the method to call:-
array( $object, 'method' )
Oh and you can safely remove that useless '&', PHP4 days are gone now.
#Thomas John, you are correct about second argument in add_action also in wordpress org not mentioned anything about this so now, let me know you, we can pass array as second argument array($this,'method').
Description:
when object creates of class then constructor automatically calls and your action performs.
WHY IT REQUIRES
in wordpress how to create or initialize the class in add_action method in short add_action referencing a class check below example
class Myclass{
public function __construct() {
add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
}
}
Referencing a class using add_action().