我正在尝试覆盖WordPress插件上的插件类。 这是原始的插件类:
class WCV_Vendor_Dashboard
{
/**
* __construct()
*/
function __construct()
{
add_shortcode( 'wcv_shop_settings', array( $this, 'display_vendor_settings' ) );
add_shortcode( 'wcv_vendor_dashboard', array( $this, 'display_vendor_products' ) );
add_action( 'template_redirect', array( $this, 'check_access' ) );
add_action( 'init', array( $this, 'save_vendor_settings' ) );
}
public function save_vendor_settings(){
//some codes here
}
}
这是我正在尝试的(在functions.php中),但它不起作用:
$wcv_vendor_dashboard = new WCV_Vendor_Dashboard();
global $wcv_vendor_dashboard;
remove_action( 'init', array( $wcv_vendor_dashboard , 'save_vendor_settings' ) );
如何正确删除它以及如何创建替换?
其他信息: 我在WooCommerce核心上做了类似的事情。当我想覆盖一个类/函数时,我使用它(例如):
remove_action( 'template_redirect', array( 'WC_Form_Handler', 'save_account_details' ) );
function new_save_account_details() {
//custom code here
}
add_action( 'template_redirect', 'new_save_account_details' );
它在WooCommerce核心上正常运行。我在WCV_Vendor_Dashboard上尝试了类似的东西,但它不起作用。
答案 0 :(得分:0)
为什么它与woocommerce合作,但在这种情况下不起作用?
当您将函数附加到特定操作时,WoredPress会为该回调创建唯一ID,并将其存储在全局$wp_filter
数组中(事实上,它之前是一个数组,但现在它是一个对象)。对于对象方法回调(如array( $this, 'save_vendor_settings' )
),使用spl_object_hash
php函数生成id。对于上面的例子,
spl_object_hash( $this ) . 'save_vendor_settings'
,看起来像000000001c0af63f000000006d7fe83asave_vendor_settings
。
到法律上"使用remove_action()
删除对象方法,您将需要访问用于首先附加函数的原始对象。如果对象存在于全局命名空间中:
global $wcv;
remove_action( 'init', array( $wcv, 'save_vendor_settings' ) );
创建另一个类实例将不起作用,因为生成的id对于每个对象都是唯一的,即使它们是同一个类的实例。
在WooCommerce的情况下,我猜它是关于静态类方法。不同的逻辑用于生成静态类方法的id,函数和静态方法回调只是作为字符串返回。对于你的例子,它将是:
'WC_Form_Handler' . '::' . 'save_account_details'
你知道为什么它适用于一个案例,但不适用于另一个案例。
通过直接在全局$wp_filter
对象中替换它们来替换附加的函数是一种破解,但它不是100%可靠的。由于我们无法访问原始对象,因此我们只能通过函数名称过滤$wp_filter
,如果相同操作的名称相同,则会替换错误的处理程序。
global $wp_filter;
foreach ( $wp_filter['init']->callbacks as $priority => &$callbacks ) {
foreach ( $callbacks as $id => &$callback ) {
if ( substr( $id, -strlen( 'save_vendor_settings' ) ) === 'save_vendor_settings' ) {
// replace the callback with new function
$callback['function'] = 'new_save_vendor_settings';
}
}
}
我希望它会起作用,问候。