Wie entferne ich eine Aktion innerhalb einer class mit extends?

Im WooCommerce-Plugin wurde das PayPal-Gateway kürzlich aktualisiert, um die Zahlung für die Statusänderung TO entweder “Verarbeitung” oder “Abgeschlossen” zu erfassen.

Wir möchten NUR die Erfassung erlauben, nachdem der Bestellstatus auf ABGESCHLOSSEN aktualisiert wurde.

Um dies zu tun, habe ich festgestellt, dass ich eine Aktion entfernen muss. Die Aktion befindet sich in der class-wc-gateway-paypal.php und der Code ist unten:

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 system status 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' ) ); 

Die letzte Zeile ist die Aktion, die ich entfernen möchte.

 add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'capture_payment' ) ); 

Ich habe ein eigenes Plugin, mit dem ich verschiedene functionen aufrufen kann. Bevor ich etwas vermassle, hoffe ich, dass jemand den Code, den ich verwenden möchte, validieren (oder korrigieren) kann:

 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 } 

Wird das funktionieren oder fehlt mir etwas?

Solutions Collecting From Web of "Wie entferne ich eine Aktion innerhalb einer class mit extends?"

Es gibt zwei Dinge, die Sie benötigen, um die Aktion zu entfernen.

  1. Die genaue Instanz von WC_Gateway_Paypal
  2. Wissen, wann die Aktion hinzugefügt und wann sie ausgeführt wird

Ohne diese wird es schwierig, aber unmöglich, die Aktion zu entfernen. Die Instanz von WC_Gateway_Paypal zu erhalten sollte einfach sein.

 //* 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 

Die Paypal-Gateway-Instanz sollte in diesem Array enthalten sein. Ich habe WooCommerce gerade nicht auf dieser Maschine installiert, daher weiß ich nicht genau, wie es gespeichert ist. Aber Sie sollten es herausfinden können.

[Hinzugefügt: Danke an @ willerton-vega, um herauszufinden, wie WC die Zahlungs-Gateways im Array speichert. Ich habe die function get_wc_paypal_payment_gateway() hierunter aktualisiert.]

Glücklicherweise wird die Aktion dem woocommerce_order_status_on-hold_to_completed Hook mit der Priorität 10 hinzugefügt. Was wir tun können, ist bei einer früheren Priorität einzuhaken und den Haken zu entfernen.

 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' ]; } 

Wenn das WooCommerce- Plugin $WC_Gateway_Paypal als globale Variable deklariert:

 global $WC_Gateway_Paypal; 

und instanziiert WC_Gateway_Paypal class als:

 $WC_Gateway_Paypal = new WC_Gateway_Paypal; 

dann, ja, der Code unten:

 global $WC_Gateway_Paypal; remove_action('woocommerce_order_status_on-hold_to_processing', array($WC_Gateway_Paypal, 'capture_payment'), 10); 

wird diese Aktion ordnungsgemäß entfernen.

Hinweis : remove_action() muss innerhalb einer function aufgerufen werden und kann nicht direkt in Ihrem Plugin oder Theme ( aus Codex ) aufgerufen werden.