需要帮助从插件文件中删除操作


need help removing action from plugin file

你好,我正试图从wordpress插件文件中删除一个动作。这个插件叫做Woocommerce Points and Rewards。我已经在一个类文件中找到了要删除的操作。当我注释掉"add_action"时,它确实做了我想要的。但我试图从函数。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,但这只是给了我一个错误消息…

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

所以我希望有人在这里可以帮助我确定我做错了什么…

**星期一更新8/18 ********查找类的实例化位置;我在"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();
    }
    

试试这个:

// 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是使用它的类的内部引用器,因此全球化它可能不是一件好事。

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

你找到解决方案了吗?有同样的问题与另一个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' );

如果有人想知道,我刚刚完成删除的动作在这个插件在以下方式。

我想删除在第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' ) );

我能够找出如何使用以下代码有效地删除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积分和奖励插件。

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

正是这个功能为我工作

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