[英]How to override a class with constructor on a WordPress plugin?
我正在嘗試覆蓋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上嘗試了類似的東西,但它不起作用。
子類的示例
class WCV_Vendor_Dashboard_Child extends WCV_Vendor_Dashboard
{
/**
* __construct()
*/
function __construct()
{
parent::__construct();
}
public function new_save_vendor_settings(){
//some codes here
}
}
為什么它與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
對象中直接替換它們來替換附加的函數有一個hack,但它不是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';
}
}
}
我希望它會起作用,問候。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.