1

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?

  • 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 Mar 1 '16 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 Mar 1 '16 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 Mar 1 '16 at 19:13
  • 1
    @jgraup you need to define the priority, if it has one, when using remove_action – userabuser Mar 1 '16 at 21:47
  • Seems odd. Is there another function that doesn't require priority? – jgraup Mar 2 '16 at 7:39
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.

  • So does that mean that any classes loaded can be accessed through the WC()->integrations? – W00tW00t111 Mar 1 '16 at 22:15
  • For integration classes, yes, they should be.. – userabuser Mar 1 '16 at 22:21
  • I tried your suggestion and it does pull up one class (that is an official integration with WooCommerce) but I'm needing help in a broader scope. Accessing children classes that have already been instansiated that are not necessarily integrations. The Freshdesk example may have been a bad example. But, how do you access a child class without re-initializing it. – W00tW00t111 Mar 9 '16 at 19:39
  • If the class is not stored on some globally accessible variable or available through some hook or does not have the ability to retrieve the same instance such as a singleton then you're out of luck I believe. – userabuser Mar 10 '16 at 3:03

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.