php - Access Child Class of Plugin Main Class Instance

admin2025-01-07  4

In a WordPress plugin where the author has defined a parent class and uses a standard instance method for other plugin authors to access the plugin example:

function WP_Plugin() {
     return WP_PLUGIN_NAME::instance();
}

In the __construct function of initializing this plugin class it uses require_once on several other classes example:

require_once( 'includes/class-wp-plugin-child-class.php' );

This class also has a __construct function (which is run when the main class is initialized.

The problem is that the other classes that are loaded from the main class do not have an instance method or any way of directly accessing them (that I can find)

How do I access any of the functions/hooks/etc. in those other classes. Without of course redeclaring the class i.e.:

$subclass = new WpPluginChildClass();

Will not work (it will trigger all of the __construct functions, etc. to run again).


Edit - adding much more detail and exact code of sample plugin trying to do this with.

I've run into this with several different larger plugins (especially relating to WooCommerce). The current one I'm attempting to work on is a paid plugin so I feel it's only responsible of me to include what should be relative to the question :)

The plugin uses a singleton instantiation pattern:

class WC_Freshdesk {
    protected static $instance = null;

    public static function get_instance() {
        // If the single instance hasn't been set, set it now.
        if ( null == self::$instance ) {
            self::$instance = new self;
        }
        return self::$instance;
    }
}

In the __construct() method the parent class includes several files. One of these is a child class.

class WC_Freshdesk_Integration extends WC_Integration {
    public function __construct() {
        add_action( 'woocommerce_view_order', array( $this, 'view_order_create_ticket' ), 40 );
    }
}

I am trying to access that add_action to remove it from a theme's template.

I've tried the following:

$freshdesk = WC_Freshdesk::get_instance();

remove_action( 'woocommerce_view_order', array( $freshdesk, 'view_order_create_ticket', 40 ) );

No dice there.

Then when trying:

$freshdesk = new WC_Freshdesk_Integration();

remove_action( 'woocommerce_view_order', array( $freshdesk, 'view_order_create_ticket', 40 ) );

Evidently I end up re declaring the WC_Freshdesk_integration() class because the add_action hook runs twice.

What is the correct way of access this child class to remove that action?

In a WordPress plugin where the author has defined a parent class and uses a standard instance method for other plugin authors to access the plugin example:

function WP_Plugin() {
     return WP_PLUGIN_NAME::instance();
}

In the __construct function of initializing this plugin class it uses require_once on several other classes example:

require_once( 'includes/class-wp-plugin-child-class.php' );

This class also has a __construct function (which is run when the main class is initialized.

The problem is that the other classes that are loaded from the main class do not have an instance method or any way of directly accessing them (that I can find)

How do I access any of the functions/hooks/etc. in those other classes. Without of course redeclaring the class i.e.:

$subclass = new WpPluginChildClass();

Will not work (it will trigger all of the __construct functions, etc. to run again).


Edit - adding much more detail and exact code of sample plugin trying to do this with.

I've run into this with several different larger plugins (especially relating to WooCommerce). The current one I'm attempting to work on is a paid plugin so I feel it's only responsible of me to include what should be relative to the question :)

The plugin uses a singleton instantiation pattern:

class WC_Freshdesk {
    protected static $instance = null;

    public static function get_instance() {
        // If the single instance hasn't been set, set it now.
        if ( null == self::$instance ) {
            self::$instance = new self;
        }
        return self::$instance;
    }
}

In the __construct() method the parent class includes several files. One of these is a child class.

class WC_Freshdesk_Integration extends WC_Integration {
    public function __construct() {
        add_action( 'woocommerce_view_order', array( $this, 'view_order_create_ticket' ), 40 );
    }
}

I am trying to access that add_action to remove it from a theme's template.

I've tried the following:

$freshdesk = WC_Freshdesk::get_instance();

remove_action( 'woocommerce_view_order', array( $freshdesk, 'view_order_create_ticket', 40 ) );

No dice there.

Then when trying:

$freshdesk = new WC_Freshdesk_Integration();

remove_action( 'woocommerce_view_order', array( $freshdesk, 'view_order_create_ticket', 40 ) );

Evidently I end up re declaring the WC_Freshdesk_integration() class because the add_action hook runs twice.

What is the correct way of access this child class to remove that action?

Share Improve this question edited Mar 1, 2016 at 19:05 W00tW00t111 asked Mar 1, 2016 at 17:03 W00tW00t111W00tW00t111 573 silver badges12 bronze badges 5
  • What's the name of the plugin? BTW, the pattern you are describing is called the 'Singleton' pattern. Generally classes are created in a way to control access to certain functions/properties by making aspects public/private/static/const/getter/setter. Scope will determine if you have access to the sub class instances but if they are include then you still have access to the class itself. You really need to show how the class is constructed and what you're trying to get/set/invoke in order for any answer here to be successful. Hooks and filters are in the global scope so you always have access. – jgraup Commented Mar 1, 2016 at 17:23
  • @jgraup thanks for the reply - I've included additional code in the edit. There are hooks in the child classes...which should be there for me to access; however since they include the class object that's where I'm struggling. In the parent class WC_Freshdesk there is no variable that is accessible where the child class is set i.e. $this->freshdesk_integration ...Let me know if there's more info that would help. – W00tW00t111 Commented Mar 1, 2016 at 19:08
  • I think you have it correct -- from what I can see. You just need remove_action after it has been hooked. It may be possible to hook it yourself with add_action('action', 'callback', 0); and as the first subscriber, unhook it then. Also, I don't think remove_action really needs a priority. Just the 'action' and 'callback'. – jgraup Commented Mar 1, 2016 at 19:13
  • 1 @jgraup you need to define the priority, if it has one, when using remove_action – Adam Commented Mar 1, 2016 at 21:47
  • Seems odd. Is there another function that doesn't require priority? – jgraup Commented Mar 2, 2016 at 7:39
Add a comment  | 

1 Answer 1

Reset to default 0

If you want to get a hold of the WC_Freshdesk instance without re-instantiating it then call:

$integrations = WC()->integrations->get_integrations();

remove_action('woocommerce_view_order', array($inegrations['wc-freshdesk'], view_order_create_ticket'), 40 ); 

Note: I'm just guessing the key of wc-freskdesk, inspect the array otherwise

The call to WC()->integrations->get_integrations() returns all the integrations that were instantiated early in the woocommerce init process, you can pluck the instance you want from there given that you know the id of the integration.

You will find the id class property within the class that extends WC_Integration, in this case WC_Freshdesk_Integration.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736262057a789.html

最新回复(0)