【问题标题】:need help removing action from plugin file需要帮助从插件文件中删除操作
【发布时间】:2016-11-03 01:39:03
【问题描述】:

您好,我正在尝试从 wordpress 插件文件中删除一个操作。该插件称为 Woocommerce 积分和奖励。我在其中一个类文件中找到了要删除的操作。当我注释掉“add_action”时,它正是我想要的。但我试图从我孩子的functions.php中删除动作。我一直在阅读这个,我认为我的问题是我需要“全球化”动作所在的类变量;但我不确定那个类变量是什么……

这是添加动作的代码(文件的一部分):

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

我要删除的功能是这个:

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

到目前为止还没有成功将其删除;这是我在functions.php中的内容:

global $woocommerce, $wc_points_rewards;

/*
global $this;
*/

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

所以 - 我确信这可以通过这种方式完成,至少我已经读过它可以完成,我想我只是在这方面有些问题......

我尝试将 $this 全球化,但这只是给了我一条错误消息...

如果您需要查看整个文件或其他内容,请告诉我...

所以我希望这里有人可以帮助我找出我做错了什么......

** 2018 年 8 月星期一更新 ******** 寻找类在哪里被实例化;我在“woo commerce-points-and-rewards.php”文件中找到了这个;看起来可能是这样,但不确定我在看什么;

  1. 这看起来像“WC_Points_Rewards_Cart_Checkout”的实例化位置吗?

  2. 如果是这样,我不确定如何使用它在 functions.php 中编写“删除操作”...

    私有函数包括() {

    // 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();
    }
    

非常感谢...

【问题讨论】:

  • 请说明WC_Points_Rewards_Cart_Checkout 类是如何实例化的。
  • 你好 Brasofilo,我想我可能已经找到了 - 我将它添加到我上面的问题中......谢谢,
  • Geesh...在另一个类中实例化...看看this solution,应该可以工作。

标签: php wordpress


【解决方案1】:

试试这个:

// 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 );

由于$this 是其所在类的内部引用,因此将其全球化可能不是一件好事。

插件是否允许您使用自己的类扩展并使用它?

【讨论】:

  • 哦,您还需要添加挂钩操作的确切实例才能删除挂钩操作。查看 Woocommerce WC() 初始化程序和类关系,也许想要的类在 $woocommerce 全局下的某个地方。否则尝试以其他方式找到WC_Points_Rewards_Cart_Checkout
  • 你好 Ojrask:我想我可能已经找到了;我将它添加到上面的问题中......谢谢,
  • 很好,感谢更新。 $this 是一个类,它包含将钩子添加为类属性的类。我会尝试将$this -> cart 的类实例(假设cart 包含挂钩类)分配给您可以在remove_action( '...', array( $thiscart, '...' ), ... ) 中使用的变量(例如$thiscart = $this -> cart)。
【解决方案2】:

您找到了解决方案吗?另一个 wc 插件也有同样的问题;)

好的。在 wc 文档中找到了答案。就我而言:

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

所以在你的情况下应该是这样的:

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】:

    如果其他人想知道,我只是通过以下方式完成了删除此插件中的操作。

    我想删除第 34 行 class-wc-points-rewards.php 中定义的操作:

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

    为此,我查看了woocommerce-points-and-rewards.php。第 46 行显示:

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

    在同一个文件中,WC_Points_Rewards 类的定义在第 249-250 行显示:

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

    有了这些信息,我就可以删除操作了:

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

    【讨论】:

      【解决方案4】:

      我能够通过以下代码弄清楚如何有效地删除 render_redeem_points_message:

      /* 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' );
      

      为了分享更多信息,我想创建一个能够兑换积分的最低购买金额:

      /* 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' );
      

      我希望这可以帮助其他尝试类似扩展 WooCommerce 积分和奖励插件的人。

      【讨论】:

        【解决方案5】:

        解决方案-1: 在这种情况下,因为我们有插件对象的全局实例,所以我们可以很容易地做到:

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

        解决方案-2: 如果任何插件作者匿名创建类对象而不将其存储到任何全局变量或不保留任何可以返回它自己的实例的方法,我们将不会总是像上面的解决方案那样幸运地获取类对象的实例。在这些情况下,我们可以使用以下内容:)

        //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
                        );
                    }
                }
            }
        }
        

        并在我们需要时适当地调用以下行(可能带有钩子或其他东西):

        //-->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】:

          正是这个功能对我有用

          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 );
          }
          

          【讨论】:

            猜你喜欢
            • 2019-06-23
            • 2020-01-07
            • 2015-10-10
            • 1970-01-01
            • 2012-09-21
            • 1970-01-01
            • 1970-01-01
            • 2023-04-04
            • 2014-08-04
            相关资源
            最近更新 更多