我一直在拼命寻找解决这个问题的办法。这个网站(和其他网站)上到处都有这个问题的例子,但没有一个答案对我有帮助。如果您想跳过背景来回答我的问题,请在代码片段之后结束。
How I got here:我需要删除插件在未实例化的类中添加的操作。也就是说,在所讨论的类中没有这样的全局实例化(示例):
global $Class_name;
$Class_name = new This_Class;
在插件(Woocommerce服务)中,添加了如下操作(必须删除):
add_action( \'woocommerce_email_after_order_table\', array( $this, \'add_tracking_info_to_emails\' ), 10, 3 );
我已经看到并阅读了许多关于如何成功删除操作的文章。这些建议都很有帮助,建议如下:
1) 确保正时正确。只有在首先添加操作后,才能删除该操作。
2) 您必须使用添加操作时使用的相同优先级来删除该操作。
但是,当要删除添加到没有实例的类中的操作时。。。他们没有达到目标。大多数人建议通过传入类名本身(在本例中为“WC\\u Connect\\u Loader”)以这种方式删除操作:
remove_action( \'woocommerce_email_after_order_table\', array( \'WC_Connect_Loader\', \'add_tracking_info_to_emails\' ), 10 );
一些人声称上述方法对他们有效,所以我尝试了很多次,但都没有成功。我确信我是在遵循研究的指导。1) 我确认,我正在尝试删除添加后的操作(检查)。2) 我确认我使用与添加操作时相同的优先级删除操作,在本例中为10(检查)。我不知所措。
经过大量调试和实验后,很明显,我不能仅仅通过传入类名来删除该操作。最后,我不得不修改插件本身(我讨厌)来创建类“WC\\u Connect\\u Loader”的全局实例,然后在尝试删除该操作时传入该实例。
在这篇文章/问题中,我加入了代码的调试版本,以显示我如何能够确认哪些工作正常,哪些不正常。我确信有比wp\\u mail()更好的方法,但这对我来说是最简单的。我让WP给我发了一封电子邮件,让我确定成功/失败。
在以下两种情况下,只有轻微的变化。我已经对更改的行进行了注释。
This does NOT work:
//woocommerce-services.php:
...
public function attach_hooks() {
...
add_action( \'woocommerce_email_after_order_table\', array( $this, \'add_tracking_info_to_emails\' ), 10, 3 );
...
}
...
if ( ! defined( \'WC_UNIT_TESTING\' ) ) {
new WC_Connect_Loader();
}
//functions.php
...
add_action(\'woocommerce_init\',\'remove_add_tracking_info_to_emails\',999);
function remove_add_tracking_info_to_emails() {
if (remove_action(\'woocommerce_email_after_order_table\',array(\'WC_Connect_Loader\',\'add_tracking_info_to_emails\'),10)){
wp_mail(\'[email protected]\',\'Successfully removed the hook\',\'Message\');
}
else {
wp_mail(\'[email protected]\',\'Failed to remove the hook\',\'Message\');
}
}
This DOES work:
//woocommerce-services.php
...
public function attach_hooks() {
...
add_action( \'woocommerce_email_after_order_table\', array( $this, \'add_tracking_info_to_emails\' ), 10, 3 );
...
}
...
if ( ! defined( \'WC_UNIT_TESTING\' ) ) {
global $WC_Connect; // created global
$WC_Connect = new WC_Connect_Loader(); // Class \'WC_Connect_Loader\' now has a global instance
}
// functions.php
...
add_action(\'woocommerce_init\',\'remove_add_tracking_info_to_emails\',999);
function remove_add_tracking_info_to_emails() {
global $WC_Connect; // Global instance of class
if (remove_action(\'woocommerce_email_after_order_table\',array($WC_Connect,\'add_tracking_info_to_emails\'),10)){ // Pass in global instance here
wp_mail(\'[email protected]\',\'Successfully removed the hook\',\'Message\');
}
else {
wp_mail(\'[email protected]\',\'Failed to remove the hook\',\'Message\');
}
}
My question:为什么我不能像许多人所建议和声称的那样传入类名?为什么我必须传入类实例才能工作?
我似乎找不到任何能帮助我理解这一点的东西。我希望通过发布以下问题获得两个结果中的一个:
1) 有人可能会解释这一限制是不可避免的,插件应该正确编写才能扩展。希望其他人能从我花在这方面的时间和那些回应中受益。
2) 我错过了一些东西,也没有我想象的那么聪明。在这种情况下,我敢打赌,我不是第一个遇到这个问题的人,我会从这个问题中受益匪浅。