I want to modify a function in a plugin. It is declared in the plugin\'s main file like this:
class WCPGSK_Main {
...
public function wcpgsk_email_after_order_table($order) {
...
}
}
Add called from there like this:
add_action( \'woocommerce_email_after_order_table\', array($this, \'wcpgsk_email_after_order_table\') );
I guess it would be possible to replace it if had an access to the class in functions.php. Then I would be able to write something like this:
$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\') );
My thought to get an access to the class in the functions.php file was to include the file where the class is declared in functions.php:
require_once(\'/wp-content/plugins/woocommerce-poor-guys-swiss-knife/woocommerce-poor-guys-swiss-knife.php\');
$wcpgsk = new WCPGSK_Main;
...
But this does not work because the plugin\'s file is included when the plugin is getting initialized in WordPress, I guess.
Is there a way to rewrite the function without touching plugin\'s files?
SO网友:s_ha_dum
如果您的插件是这样注册的:
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();
这是资源密集型的,除非你别无选择,否则不应该这样做。
SO网友:bonger
该插件使其init函数wcpgsk_init()
可插拔的,所以另一种覆盖它的方法是首先在必须使用的插件中定义它(因为在主题的“functions.php”中已经太晚了)。因此,您可以将覆盖放在“wp-content/mu-plugins/functions.php”中:
function wcpgsk_init() {
global $wcpgsk, $wcpgsk_about, $wcpgsk_options, $wcpgsk_session, $wcpgsk_woocommerce_active;
//only continue loading
if ( $wcpgsk_woocommerce_active && version_compare( WOOCOMMERCE_VERSION, "2.0" ) >= 0 ) {
$FILE = WP_PLUGIN_DIR . \'/woocommerce-poor-guys-swiss-knife/woocommerce-poor-guys-swiss-knife.php\'; // Fake __FILE__
$dirname = dirname( $FILE ) . \'/\';
$wcpgsk_options = get_option(\'wcpgsk_settings\', true);
require_once( $dirname . \'classes/woocommerce-poor-guys-swiss-knife.php\' );
require_once( $dirname . \'classes/woocommerce-poor-guys-swiss-knife-about.php\' );
require_once( $dirname . \'wcpgsk-af.php\' );
if ( !is_admin() ) :
add_action( \'plugins_loaded\', \'wcpgsk_load_wcsession_helper\' );
endif;
// Your override.
class My_WCPGSK_Main extends WCPGSK_Main {
public function wcpgsk_email_after_order_table($order) {
echo "O la la";
}
}
define( \'WCRGSK_DOMAIN\', WCPGSK_DOMAIN ); // Fix typo! (WooCommerce Rich Guys Swiss Knife?)
//load into our global
$wcpgsk = new My_WCPGSK_Main( $FILE );
$wcpgsk->version = \'2.2.4\';
$wcpgsk->wcpgsk_hook_woocommerce_filters();
} elseif ( version_compare( WOOCOMMERCE_VERSION, "2.0" ) < 0 ) {
add_action( \'admin_notices\', \'wcpgsk_woocommerce_version_message\', 0 ) ;
return;
} else {
return;
}
}
但覆盖它的更好方法是安装
runkit
(
https://github.com/padraic/runkit) 然后直接在主题的“functions.php”中替换它:
add_action( \'init\', function () {
$code = <<<\'EOD\'
echo "O la la";
EOD;
runkit_method_redefine(
\'WCPGSK_Main\',
\'wcpgsk_email_after_order_table\',
\'$order\',
$code,
RUNKIT_ACC_PUBLIC
);
} );
(顺便说一句,这是个玩笑。)