簡體   English   中英

如何使用WordPress插件上的構造函數覆蓋類?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM