問題描述
我想修改外掛中的一個函式。它在外掛的主檔案中宣告如下:
class WCPGSK_Main {
...
public function wcpgsk_email_after_order_table($order) {
...
}
}
從這裡新增呼叫:
add_action( 'woocommerce_email_after_order_table', array($this, 'wcpgsk_email_after_order_table') );
我想這是可以替換它,如果有訪問在 functions.php 中的類。然後我可以寫這樣的東西:
$wcpgsk = new WCPGSK_Main;
remove_action( 'woocommerce_email_after_order_table', array($wcpgsk, 'wcpgsk_email_after_order_table') );
function customized_wcpgsk_email_after_order_table($order) {
...
}
add_action( 'woocommerce_email_after_order_table', array($wcpgsk, 'customized_wcpgsk_email_after_order_table') );
我想要在 functions.php 檔案中獲取類的訪問是包含在 functions.php 中宣告類的檔案:
require_once('/wp-content/plugins/woocommerce-poor-guys-swiss-knife/woocommerce-poor-guys-swiss-knife.php');
$wcpgsk = new WCPGSK_Main;
...
但是這並不奏效,因為當外掛在 WordPress 中被初始化時,外掛的檔案被包含在內。
有沒有辦法重寫功能,而不會觸控外掛的檔案?
最佳解決方案
這應該工作:
add_action( 'woocommerce_init', 'remove_wcpgsk_email_order_table' );
function remove_wcpgsk_email_order_table() {
global $wcpgsk;
remove_action( 'woocommerce_email_after_order_table', array( $wcpgsk, 'wcpgsk_email_after_order_table' ) );
}
次佳解決方案
如果你的外掛是這樣註冊的:
class Test_Class_Parent {
function __construct() {
add_action('wp_head',array($this,'test_method'));
}
function test_method() {
echo 'Echoed from the parent';
}
}
$p = new Test_Class_Parent();
那麼你應該可以透過訪問全域性來刪除過濾器:
class Test_Class_Child extends Test_Class_Parent {
function __construct() {
$this->unregister_parent_hook();
add_action('wp_head',array($this,'test_method'));
}
function unregister_parent_hook() {
global $p;
remove_action('wp_head',array($p,'test_method'));
}
function test_method() {
echo 'Echoed from the child';
}
}
$c = new Test_Class_Child();
否則,您將需要爬行 $wp_filter global 作為註冊碼:
class Test_Class_Child extends Test_Class_Parent {
function __construct() {
$this->unregister_parent_hook();
add_action('wp_head',array($this,'test_method'));
}
function unregister_parent_hook() {
global $wp_filter;
if (!empty($wp_filter['wp_head'])) {
foreach($wp_filter['wp_head'] as $cb) {
foreach ($cb as $k => $v) {
if (
isset($v['function'])
&& is_a($v['function'][0],'Test_Class_Parent')
&& isset($v['function'][1])
&& 'test_method' == $v['function'][1]
) {
remove_action('wp_head',$k);
}
}
}
}
}
function test_method() {
echo 'Echoed from the child';
}
}
$c = new Test_Class_Child();
這是資源密集型的,除非你沒有其他選擇,否則應該沒有辦法。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。