need help removing action from plugin file

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

Hello I am trying to remove an action from a wordpress plugin file. The plugin is called Woocommerce Points and Rewards. I have found the action I want to remove in one of the class files. When I comment out the "add_action" it does exactly what I want. But I am trying to remove the action from functions.php in my child them. I have been reading on this and I think my problem is I need to "globalize" the class variable that the action is in; but I am not sure what that class variable is…

here is the code where it adds the action (part of a file):

class WC_Points_Rewards_Cart_Checkout {   /**  * Add cart/checkout related hooks / filters  *  * @since 1.0  */ public function __construct() {      // Coupon display     add_filter( 'woocommerce_cart_totals_coupon_label', array( $this, 'coupon_label' )      );     // Coupon loading     add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'points_last' ) );     add_action( 'woocommerce_applied_coupon', array( $this, 'points_last' ) );      // add earn points/redeem points message above cart / checkout     add_action( 'woocommerce_before_cart', array( $this, 'render_earn_points_message' ), 15 );      add_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 );      add_action( 'woocommerce_before_checkout_form', array( $this, 'render_earn_points_message' ), 5 );     add_action( 'woocommerce_before_checkout_form', array( $this, 'render_redeem_points_message' ), 6 );      // handle the apply discount submit on the cart page     add_action( 'wp', array( $this, 'maybe_apply_discount' ) );      // handle the apply discount AJAX submit on the checkout page     add_action( 'wp_ajax_wc_points_rewards_apply_discount', array( $this, 'ajax_maybe_apply_discount' ) ); } 

The function I want to remove is this one:

add_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 ); 

so far no luck in getting it removed; here is what I have in functions.php:

global $woocommerce, $wc_points_rewards;  /* global $this; */  remove_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 ); 

so - I am sure this can be done in this way at least I have read that it can be done, I think I just have some thing wrong on this…

I tried globalizing $this, but that just gave me an error message...

if you need to see the entire file or something else please just let me know…

So I am hoping someone on here can help me identify what I am doing wrong…

** UPDATE Monday 8/18 ******** Looking for where class is instantiated; I have found this in the "woo commerce-points-and-rewards.php" file; this looks like this may be it but not sure what I am looking at;

  1. does this look like where the "WC_Points_Rewards_Cart_Checkout" is instantiated?

  2. And if so I am not sure how i use this to write my "remove action" in functions.php...

    private function includes() {

    // product class require( 'classes/class-wc-points-rewards-product.php' ); $this->product = new WC_Points_Rewards_Product();  // cart / checkout class require( 'classes/class-wc-points-rewards-cart-checkout.php' ); $this->cart = new WC_Points_Rewards_Cart_Checkout();  // order class require( 'classes/class-wc-points-rewards-order.php' ); $this->order = new WC_Points_Rewards_Order();  // discount class require( 'classes/class-wc-points-rewards-discount.php' ); $this->discount = new WC_Points_Rewards_Discount();  // actions class require( 'classes/class-wc-points-rewards-actions.php' ); $this->actions = new WC_Points_Rewards_Actions();  // manager class require( 'classes/class-wc-points-rewards-manager.php' );  // points log access class require( 'classes/class-wc-points-rewards-points-log.php' );  if ( is_admin() )     $this->admin_includes(); } 

Thanks so much...

回答1:

Try this:

// Use the class name instead of a globalized $this remove_action( 'woocommerce_before_cart', array( 'WC_Points_Rewards_Cart_Checkout', 'render_redeem_points_message' ), 16 ); 

As $this is an internal referrer to the class it is used in, globalizing it may not be a good thing.

Does the plugin allow you to extend the class with your own and use it instead?



回答2:

you found a solution for this? having the same problem with another wc plugin ;)

alright. found an answer in the wc docs. in my case:

function wc_move_checkout_addons() {     remove_action( 'woocommerce_checkout_after_customer_details', array( $GLOBALS['wc_checkout_add_ons']->frontend, 'render_add_ons' ) );      add_action( 'woocommerce_checkout_before_customer_details', array( $GLOBALS['wc_checkout_add_ons']->frontend, 'render_add_ons' ) ); } add_action( 'init', 'wc_move_checkout_addons' ); 

so in your case it should be something like that:

function wc_remove_message() {     remove_action( 'woocommerce_before_cart', array( $GLOBALS['wc_points_rewards_cart_checkout']->frontend, 'render_redeem_points_message' ) );  } add_action( 'init', 'wc_remove_message' ); 


回答3:

In case anyone else is wondering, I just accomplished removing the action in this plugin in the following way.

I wanted to remove the action defined in class-wc-points-rewards.php on line 34:

add_action( 'woocommerce_single_product_summary', array( $this, 'render_product_message' ) ); 

To do that, I looked at woocommerce-points-and-rewards.php. On line 46 it shows:

$GLOBALS['wc_points_rewards'] = new WC_Points_Rewards(); 

And in the same file for the definition of the WC_Points_Rewards class, on line 249-250 it shows:

require( 'includes/class-wc-points-rewards-product.php' ); $this->product = new WC_Points_Rewards_Product(); 

With that information, I was able to remove the action:

remove_action( 'woocommerce_single_product_summary', array( $GLOBALS['wc_points_rewards']->product, 'render_product_message' ) ); 


回答4:

I was able to figure out how to remove the render_redeem_points_message effectively with the following code:

/* Removes render_redeem_points_message() */ function wc_remove_points_message() {     global $woocommerce;     global $wc_points_rewards;      // Removes message from cart page     remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 );      // Removes message from checkout page     remove_action( 'woocommerce_before_checkout_form', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 6 );  } // Removes action on init add_action( 'init', 'wc_remove_points_message' ); 

To share a bit more, I wanted to create a minimum purchase amount to be able to redeem points:

/* Adds Minimum Order for Points Redemption */ function wc_min_order_points_message() {     global $woocommerce;     global $wc_points_rewards;      // Get cart subtotal, excluding tax     $my_cart_total = $woocommerce->cart->subtotal_ex_tax;      if ($my_cart_total < 30) { // $30 minimum order          remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 );         remove_action( 'woocommerce_before_checkout_form', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 6 );      } // endif $my_cart_total   } // Adds action for cart and checkout pages instead of on init add_action( 'woocommerce_before_cart', 'wc_min_order_points_message' ); add_action( 'woocommerce_before_checkout_form', 'wc_min_order_points_message' ); 

I hope this helps anyone else trying to similarly expand on the WooCommerce Points and Rewards plugin.



回答5:

SOLUTION-1: In this case, as we have the plugin object's global instance, then we can do it easily:

remove_action('woocommerce_before_cart',array($GLOBALS['wc_points_rewards']->cart,'render_redeem_points_message'),16); 

SOLUTION-2: We will not be lucky always like the above solution getting the instance of the class object if any plugin author creates the class object anonymously without storing it to any global variables or keeping no method which can return it's own instance. In those cases, we can use the following :)

//keeping this function in our functions.php function remove_anonymous_object_action( $tag, $class, $method, $priority=null ){      if( empty($GLOBALS['wp_filter'][ $tag ]) ){         return;     }      foreach ( $GLOBALS['wp_filter'][ $tag ] as $filterPriority => $filter ){         if( !($priority===null || $priority==$filterPriority) )             continue;          foreach ( $filter as $identifier => $function ){             if( is_array( $function)                 and is_a( $function['function'][0], $class )                 and $method === $function['function'][1]             ){                 remove_action(                     $tag,                     array ( $function['function'][0], $method ),                     $filterPriority                 );             }         }     } } 

And calling the following line appropriately when we need (may be with a hook or something):

//-->Actual Target: this line does not work; //remove_action( 'personal_options', array('myCRED_Admin','show_my_balance') );  //-->But instead this line will work ;) remove_anonymous_object_action('personal_options','myCRED_Admin','show_my_balance'); 


回答6:

exactly this function worked for me

if (class_exists('WC_Points_Rewards')) { global $woocommerce, $wc_points_rewards;    remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_earn_points_message' ), 15 );         remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 ); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!