如何删除带有扩展的类中的操作

时间:2017-12-30 作者:Cameron Scott

在WooCommerce插件中,PayPal网关最近进行了更新,以捕获状态更改为“正在处理”或“已完成”的付款。

我们只希望在订单状态更新为“完成”后才允许捕获。

为了做到这一点,我已经确定需要删除一个操作。该操作位于class wc gateway paypal中。php,代码如下:

class WC_Gateway_Paypal extends WC_Payment_Gateway {

/** @var bool Whether or not logging is enabled */
public static $log_enabled = false;

/** @var WC_Logger Logger instance */
public static $log = false;

/**
 * Constructor for the gateway.
 */
public function __construct() {
    $this->id                 = \'paypal\';
    $this->has_fields         = false;
    $this->order_button_text  = __( \'Proceed to PayPal\', \'woocommerce\' );
    $this->method_title       = __( \'PayPal\', \'woocommerce\' );
    $this->method_description = sprintf( __( \'PayPal Standard sends customers to PayPal to enter their payment information. PayPal IPN requires fsockopen/cURL support to update order statuses after payment. Check the <a href="%s">system status</a> page for more details.\', \'woocommerce\' ), admin_url( \'admin.php?page=wc-status\' ) );
    $this->supports           = array(
        \'products\',
        \'refunds\',
    );

    // Load the settings.
    $this->init_form_fields();
    $this->init_settings();

    // Define user set variables.
    $this->title          = $this->get_option( \'title\' );
    $this->description    = $this->get_option( \'description\' );
    $this->testmode       = \'yes\' === $this->get_option( \'testmode\', \'no\' );
    $this->debug          = \'yes\' === $this->get_option( \'debug\', \'no\' );
    $this->email          = $this->get_option( \'email\' );
    $this->receiver_email = $this->get_option( \'receiver_email\', $this->email );
    $this->identity_token = $this->get_option( \'identity_token\' );

    self::$log_enabled    = $this->debug;

    add_action( \'woocommerce_update_options_payment_gateways_\' . $this->id, array( $this, \'process_admin_options\' ) );
    add_action( \'woocommerce_order_status_on-hold_to_processing\', array( $this, \'capture_payment\' ) );
最后一行是我要删除的操作。

add_action( \'woocommerce_order_status_on-hold_to_processing\', array( $this, \'capture_payment\' ) ); 
我有自己的插件,用来调用各种函数。在我搞砸之前,我希望有人能验证(或纠正)我计划使用的代码:

add_action( \'woocommerce_order_status_on-hold_to_completed\',\'remove_PaypalCapture_action\' );
function remove_PaypalCapture_action(){ 
global $WC_Gateway_Paypal; //get access to the class object instance
remove_action(\'woocommerce_order_status_on-hold_to_processing\', array($WC_Gateway_Paypal, \'capture_payment\' )); //DO NOT capture payment upon order change to processing
} 
这能行吗,还是我遗漏了什么?

2 个回复
SO网友:Nathan Johnson

要删除该操作,您需要做两件事。

WC\\u Gateway\\u Paypal的确切实例知道何时添加操作以及何时执行操作,如果没有这些,将很困难,但不可能删除操作。获取WC\\u Gateway\\u Paypal的实例应该很简单。

//* Make sure class-wc-payment-gateways.php is included once
include_once PATH_TO . class-wc-payment-gateways.php;

//* Get the gateways
$gateways = \\WC_Payment_Gateways::instance();

//* The class instances are located in the payment_gateways property
$gateways->payment_gateways
贝宝网关实例应在此阵列中。我现在没有在这台机器上安装WooCommerce,所以我不知道它是如何存储的。但你应该能找到答案

[补充:感谢@willington vega了解WC如何在阵列中存储支付网关。我已经更新了get_wc_paypal_payment_gateway() 以下功能与此相关。]

幸运的是,该操作在优先级10处添加到woocommerce_order_status_on-hold_to_completed 钩我们所能做的就是以较早的优先级挂接并移除挂接。

add_action( \'woocommerce_order_status_on-hold_to_completed\', \'remove_PaypalCapture_action\', 9 );
function remove_PaypalCapture_action() {
  //* This is where we\'ll remove the action

  //* Get the instance
  $WC_Paypal_Payment_Gateway = get_wc_paypal_payment_gateway();
  remove_action( \'woocommerce_order_status_on-hold_to_completed\', [ $WC_Paypal_Payment_Gateway , \'capture_payment\' ] );
}
function get_wc_paypal_payment_gateway() {

  //* Make sure class-wc-payment-gateways.php is included once
  include_once PATH_TO . class-wc-payment-gateways.php;

  //* Return the paypal gateway
  return \\WC_Payment_Gateways::instance()->payment_gateways[ \'paypal\' ];
}

SO网友:Frank P. Walentynowicz

如果插件声明$WC_Gateway_Paypal 作为全局变量:

global $WC_Gateway_Paypal;
并实例化WC_Gateway_Paypal class 作为:

$WC_Gateway_Paypal = new WC_Gateway_Paypal;
那么,是的,代码如下:

global $WC_Gateway_Paypal;
remove_action(\'woocommerce_order_status_on-hold_to_processing\', array($WC_Gateway_Paypal, \'capture_payment\'), 10);
将正确删除此操作。

Note: remove_action() 必须在函数内调用,不能在插件或主题中直接调用(来自Codex)。

结束

相关推荐