2
<?php

namespace wp_gdpr_wc\controller;

use wp_gdpr\lib\Gdpr_Container;
use wp_gdpr_wc\lib\Gdpr_Wc_Translation;
use wp_gdpr_wc\model\Wc_Model;

class Controller_Wc {
    const REQUEST_TYPE = 3;

    /**
     * Controller_Form_Submit constructor.
     */
    public function __construct() {
        add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_consent_checkbox' ) );
    }

Usually I could remove it like this remove_action( 'woocommerce_after_order_notes', 'Controller_Wc::checkout_consent_checkbox'); but here seems like it's not working.

4

I did it using this function remove_filters_with_method_name( 'woocommerce_after_order_notes', 'checkout_consent_checkbox', 10 );

function remove_filters_with_method_name( $hook_name = '', $method_name = '', $priority = 0 ) {
    global $wp_filter;
    // Take only filters on right hook name and priority
    if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) || ! is_array( $wp_filter[ $hook_name ][ $priority ] ) ) {
        return false;
    }
    // Loop on filters registered
    foreach ( (array) $wp_filter[ $hook_name ][ $priority ] as $unique_id => $filter_array ) {
        // Test if filter is an array ! (always for class/method)
        if ( isset( $filter_array['function'] ) && is_array( $filter_array['function'] ) ) {
            // Test if object is a class and method is equal to param !
            if ( is_object( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) && $filter_array['function'][1] == $method_name ) {
                // Test for WordPress >= 4.7 WP_Hook class (https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/)
                if ( is_a( $wp_filter[ $hook_name ], 'WP_Hook' ) ) {
                    unset( $wp_filter[ $hook_name ]->callbacks[ $priority ][ $unique_id ] );
                } else {
                    unset( $wp_filter[ $hook_name ][ $priority ][ $unique_id ] );
                }
            }
        }
    }
    return false;
}
  • Although it feels so wrong to do so, I agree this approach is the only possible way to do it. Please also take the time to contact the author of the plugin in question, and ask for possibilities to add a configuration or make a different construct to allow for better customization. Or even better, make a pull request with the improvement. – jgangso Nov 12 at 12:17
3

To remove an action you need to pass the same callable that was used to add the action in the first place. The difference with your hook, compared to a plain function or static method, is that you have passed a method on a specific instance of your class. Note the use of $this:

add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_consent_checkbox' ) );

So when you remove the action you need to pass the same instance the same way:

add_action( 'woocommerce_after_order_notes', array( $that, 'checkout_consent_checkbox' ) );

Where $that is a variable containing the same instance of the class.

To do this you need to find that variable. This depends on how the plugin was originally built. If the class was instantiated into a global variable like this:

global $wp_gdpr_wc_controller;
$wp_gdpr_wc_controller = new Controller_Wc;

Then you would remove it like this:

global $wp_gdpr_wc_controller;
remove_action( 'woocommerce_after_order_notes', array( $wp_gdpr_wc_controller, 'checkout_consent_checkbox' ) );
  • Thing is the class was not initiated in a variable, I thought about that. – Alex Jun 4 '18 at 7:08
  • Then it can’t be unhooked the proper way. Take it up with the author. – Jacob Peattie Jun 4 '18 at 9:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.