In our tutorial "Using Classes as Code Wrappers for WordPress Plugins" we took a plugin that used a global function for its filter hook and converted it to using a PHP class as a code wrapper. Unfortunately the approach we showed didn't allow other plugins and/or themes to remove or chain the actions and/or filters if needed.

Let's explore the hook removal problem. We'll start with the example from the prior tutorial:

Unfortunately this adds yet another global variable that may conflict with other plugins or themes. It also adds to the list of global variables making for more to scan in IDE debuggers like PhpStorm. For these and other reasons we don't recommend using global variables for plugins like this.

Use a Private Static Property Instead

Rather than use global we'll declare a privatestatic variable we'll call $_this.

class Thanks_For_Reading_Plugin {

private static $_this;

...

}

class Thanks_For_Reading_Plugin {
private static $_this;
...
}

The Static Declaration

The static declaration in PHP means that all instances of the class share the same single value. But as we only want one instance of this class we use static to allow us to access the instance using the class name, as you'll see below.

The Private Qualifier

In PHP the private variable qualifier "hides" the variable to any code outside of the class. In our case we want to ensure other code doesn't change its value accidentally, again as you'll see below.

Capture the Plugin's Instance

Inside the constructor we'll assign the object's instance from the $this variable to the static variable self::$_this:

Add a Read-Only Access Function

Next add a static function to the class which we'll name this() and have it return the value of self::$_this. This function will be public[1]by default providing read-only access to the single instance used by the plugin's class:

Summary

If you use classes as code wrappers for your WordPress plugins, which we recommend, you should take the tiny bit of extra effort to enable your users the flexibility they might need to remove or chain your filters. Fortunately the code required is almost completely copy-and-paste so it doesn't require in-depth understanding to get started; just grab the code template below and get started with your plugin:

Footnotes

For those whom the term "method" confuses, methods are simply functions declared within a class using the PHP function keyword. Methods act on instances of the class, i.e. $object->get_name() means that $object is calling it's get_name() method which would likely return a different value for each of the different instances of the class on which it was called.

It’s such a pita to remove actions & filters hooks called from classes. Makes me hate the overzealous use of classes especially in cases when there are no major benefits to use a class to start with. At least it’s one step forward if authors make it a bit easier to access those hooks for removal, but it’s still a nightmare for people who are not coders.

I believe that I tend to push the limits of what’s possible with WordPress given how often other plugin developers tell me they don’t understand why I need the improvements to WordPress core that I ask for, but to push the limits you need a solid code architecture or you’ll end up with an unmaintainable mess. But I’m also highly sensitive to the needs of people who are not yet “hardcore” or who do not actually want to be but instead just want to get stuff done.

I once switched from Windows/IIS/SQL Server/ASP+VBScript after 12 years to Windows/Apache/MySQL/PHP and then to Mac OSX/Apache/MySQL/PHP so I’m very aware of how frustrating it can be to need to get something done but feel overwhelmed by the understanding required to do it. I also ran a web entrepreneur meetup for 3+ years and organized a lot of trainings for members including at least one training for WordPress so I’ve seen firsthand the frustration that others feels when they want to use WordPress but it’s just a bit more technical than they can grasp on their own.

So I’d really love to explore the issues you have and how we coders who publish plugins could make it better for you. tried to address the hook removal use-case abive and posted the code showing how to do it: remove_filter( 'the_content', array( Thanks_For_Reading_Plugin::this(), 'the_content' ) ); which compares to:remove_filter( 'the_content', 'thanks_for_reading_the_content' ); Please help me understand your concerns about the former; it is just too complicated to understand for a non-coder, or it it something else? If the plugin’s README.TXT file had instructions for hook removal, would that be sufficient? Or would this be better? Thanks_For_Reading_Plugin::remove_filter( 'the_content' ); It seems like it’s mostly a documentation issue on the part of the plugin developer, but maybe I misunderstand?

Again, I’d really love to understand how we plugin developers could improve our plugins so theme developers and site builders can be more comfortable using and extending our plugins. Thanks in advance.

Well your solution is a hell of a lot better than hunting through the wp_filters global cowboy style. If this were the standard for all plugin developers that would be a step forward. Obviously, it doesn’t get any easier than remove_filter( 'the_content', 'thanks_for_reading_the_content' );. My view is that developers should do a cost-benefit analysis from a user point of view and not just stick commonly used hooks inside classes if it can be done without.

The problem also lies in the discoverability. If it’s documented, at least a user could potentially find it. The truth is most plugins aren’t going to have a ton of documentation and would a non-savvy user know what to look for? It would require more explanation.

Some plugins just are the kinds of plugins where you are going to spend a lot of time trawling through documentation (S2Member springs to mind), in those situations I like this solution a lot if the plugin is heavily into object oriented code.

If it’s about pushing core changes, I would rather see them make remove_action & remove_filter smarter so that you don’t have to reference the class instance in the first place. That would retroactively make all relevant plugins easier to customize without requiring plugin authors to implement workarounds (even pretty elegant ones like yours). Are there any critical objections to that that you could think of?

As a self taught dev who’s learning was based mostly around WP projects, I am happy that most code I encountered wasn’t object oriented in the early days. I’ve found OO much hard to grasp initially. Now that I’ve got some years under my belt, I’m comfortable with it (just wrote a class yesterday because it made the most sense) but I still wish to see less of it in plugins because I find it gets in the way a lot of the time. I imagine lots of new users might feel similar. I do think the offical WP docs contribute to that as well (not a ton of examples with classes etc).

I have to say reading your story about switching between windows/iis/apache/mac environments, I realize I’m very much married to my current setup. The thought of having to change makes me feel quite inflexible. I guess it’s all about having a really compelling reason to change is key. Reminds me of a recent Ohz post about learning git (when he was quite comfy with svn). I love learning like nothing else, but having to relearn how to do simple things in a different way isn’t always fun (especially when you get the same result as the ‘old’ way).

Okay so my takeaway is that part of the problem is 1.) developers who don’t expose a method to remove or chain hooks, 2.) (lack of) documentation and 3.) that anything besides remove_filter( 'bar', 'foo_bar' ); is non-standard and thus will require discovery and/or more learning.

So if I got it right, I hear you. (Almost?) everyone on our current team is very concerned about making tools the majority of WordPress site builders will find easy to use. Frankly we’re a lot more interested in discussing how we can better address needs like yours than to debate the more pedantic points about alternate PHP code architectures.

If our goals are to build significant and reusable open-source libraries — they are — and the goal of this blog is to teach people how to use them and then advocate for their use and standardization then we’ve got to use object-orientation. From our experience not using object-orientation in many cases leads to a level of complexity that we can’t easily manage; I know, I’ve actually tried.

But so far none of our posts on this blog have even gotten close to the level of complexity I’m talking about. Still we have to start with a foundation to build on.

If it’s about pushing core changes, I would rather see them make remove_action & remove_filter smarter so that you don’t have to reference the class instance in the first place.

If you are referring to global scope I don’t see how that would be possible unless you mean to reference class name instead of instance. This approach could become standard if WordPress were to adopt a base class for WordPress plugins which would make this possible: A_Plug_Class::remove_filter( 'hook_name' ); Is that what you are suggesting?

You wouldn’t know this from reading the blog as we’ve not yet been explicit but we plan future posts to build up to recommending the use of a defacto-standard base class for WordPress plugins and then it won’t be a workaround as it will be built into the base class. And if a lot of plugin developers follow our lead (or if the core WordPress team were to adopt what a similar approach) then it would become a (defacto) standard approach, and that’s our goal.

As a self taught dev who’s learning was based mostly around WP projects, I am happy that most code I encountered wasn’t object oriented in the early days. I’ve found OO much hard to grasp initially. Now that I’ve got some years under my belt, I’m comfortable with it (just wrote a class yesterday because it made the most sense) but I still wish to see less of it in plugins because I find it gets in the way a lot of the time. I imagine lots of new users might feel similar. I do think the offical WP docs contribute to that as well (not a ton of examples with classes etc).

As I’ve mentioned in several other comments the techniques described above are not object-oriented. Unfortunately numerous WordPress-related bloggers have called the use of classes to encapsulate function names used for hooks as “object oriented” but that’s a misnomer. All we are doing here is using the class syntax to create defacto namespaces(since PHP doesn’t support namespaces in PHP 5.2.4) and then we also use a few syntactic techniques to ensure we get the visibility we require such as what we need to enabling filter removal. Yes, the syntax is a little more complex, I’ll give you that. But it’s not object-oriented.

That said, object-orientation is critical for being able to build plugins with advanced functionality. OTOH, there’s no reason real object-orientation needs to be exposed to most site builders if the plugin developers care about meeting the needs of site builders vs. just end users (I know we do.)

Honestly what would be great is if the core WordPress team would be open to adding more hooks for things like this. For example, if remove_filter() had a filter of it’s own that would allow a plugin developer to filter the $function_to_remove parameter then our plugin could support the following approach for removing a filter: remove_filter( 'the_content', 'Thanks_For_Reading_Plugin::the_content' ); would this approach be better?

Alas, I’ve found the core team less than amenable to adding filters and actions; more than once they told me there’s not a need which I think makes it really hard for plugin developers to make things easier for site builders in cases like this.

I have to say reading your story about switching between windows/iis/apache/mac environments, I realize I’m very much married to my current setup. The thought of having to change makes me feel quite inflexible.

Here’s what my own journey of self-discovery taught me; I really enjoy learning new things but I really don’t enjoy going from highly productive to almost completely unproductive. If I have to learn how to do 5-10 new things before I can get a single new unit of work done that’s when I get annoyed. So it’s evolutionary learning which I embrace and revolutionary learning I abhor.

I guess it’s all about having a really compelling reason to change is key.

The reason I switched from IIS/Sql Server/ASP+VBScript to Apache/MySQL/PHP was because I became very disenchanted with the Microsoft and their web stack and the fact that most developer components were commercial meant developers could not build on other developers’s work without having a commerical licensing arrangement in place. So I left the company I founded where we got all the .NET-related add-ons from vendors for free since we were a reseller and started doing web development where I had to pay for all the software I used. All of that made me switch to PHP and I even blogged about it at the start of the process of switching.

The reason I switched to Mac was I knew lots of the people in Atlanta who were interested in building web startups and almost all of them used Mac. So when I started using Twitter and I would tweet a question asking how to do something on Windows and I would get a shitstorm of replies telling me to get a Mac and if so all my problems would be solved. Rather than fight I finally switched in hopes to be able to get help from the people I knew on Twitter and in person (seriously, that’s really why I switched.) In hindsight they were wrong, the Mac is not a panacea. But while I don’t love the Mac I do see a lot of benefits to it over Windows now that I’m proficient with it.

Reminds me of a recent Ohz post about learning git (when he was quite comfy with svn).

Oh I struggle with Git too because it’s so obtuse. OTOH I have always hated SVN. What I really like and still do is Mercurial; how I wish that GitHub supported Hg (as if there were any chance of that!) One of my pet planned projects is to implement a wrapper around Git to make it more Mercurial-like and call it “Rational Git.”

I love learning like nothing else, but having to relearn how to do simple things in a different way isn’t always fun (especially when you get the same result as the ‘old’ way).

Agreed. And I would say not only not fun but also damn frustrating.

Anywho, I really do appreciate your comments and hope you’ll feel motivated to leave similar comments on future posts because addressing the issues that people with your perspective have is one of the main reasons we launched this blog. And when we advocate for adding hooks to WordPress it would be helpful if we readers could validate that we do in fact need what we’re asking for.

Honestly what would be great is if the core WordPress team would be open to adding more hooks for things like this. For example, if remove_filter() had a filter of it’s own that would allow a plugin developer to filter the $function_to_remove parameter then our plugin could support the following approach for removing a filter: remove_filter( 'the_content', 'Thanks_For_Reading_Plugin::the_content' ); would this approach be better?

I think definitely it would be better yes.

Thanks for your thoughts, have your site in my RSS (thanks to Ryan Hellyer)

Thanks so much for asking. I love these kind of comments, it’s fun to try to deduce coding problems.

I cannot tell for sure because you didn’t provide the source code for APP_View_Page::get_id(); I don’t know if it is returning the actual instance or another value. If it is not providing the instance there’s one of your problems; you’ll need to get the actual instance used.

Assuming you have the correct instance then the problem is almost certainly that the 'appthemes_init' hook you are using is fired before WordPress’ 'template_redirect' hook. Instead of using 'appthemes_init' find the priority AppThemes are using to call CP_User_Dashboard::template_redirect() and use the 'template_redirect' hook with a priority at least 1 higher than they are using which will result in your code being called by WordPress to remove the hook shortly after their code that added the hook is called.

If AppThemes are using the default priority of 10(and if $instance does indeed have the actual Singleton instance) then using priorty 11 should probably work:

Hope this helps; please leave a reply comment to let me know either way. If not I’d be happy to figure it out for you if you can get me a full copy of the code to debug. If yes send me an email via my about.me page.

P.S. I edited you comment for formatting and shorten it to show just the relevant code.

Thanks for emailing me your code. I was able to figure out the problem and the problem is that AppThemes does not provide any method to access the Singleton instance of the class they use for their apps. In other words, they don’t follow the best practices I presented in this post! 🙁

Below is the code I believe should work for you; it removes the 'show_notice' hook from the CP_Add_New class. If you want to remove that hook for all classes you’ll unfortunately need to call the function for each AppThemes class you want it removed from and/or write a custom version of the remove_anonymous_object_filter() function that can remove the hook from a list of classes.

@Mike, @Thomas, you are my heroes, this totally works. Funny enough, I found that function while I was searching for a solution but couldn’t get it to work as I was hooking into the wrong place.
As for the new ClassiPress Beta 3.3, that class alone, has not been updated but since its a major release… I have a lot of code to review.
Thanks again for your help.

I’d love to answer your question but it looks like your code got eaten by the comment system and I’m not 100% sure what you are asking. If you’ll post your code into a Gist and reply with a link to it I’ll update your original comment and then do my best to answer.

On the other hand, I really want to help but I’m still confused by your description. You say you want to replace the function with divs but the former is a PHP language structure and the latter is a markup element in HTML so I’m still not sure what you mean. Do you mean that you want to replace the function’s output of <table>, <tr> and <td> elements with <div> elements? If not, can you explain in a different way?

Also, is this part of the WooCommerce open-source code and available for download so I can look at it, or is it a paid 3rd party extension? If the above is correct then the answer you want is likely to be to subclass the current class and override the method, but that will only work if you can override the code that instantiates the class and replace it with your extension of said class. So I need to see more of the code to be able to give better guidance.

You are correct, I want to change the output of the <table> elements and use a <div> with some of my own classes.

Unfortunately it is a 3rd party extension sold on woo’s website it is for the variable swatches plug-in. That is why I only posted a snippet of that entire class. Maybe there is some other way I can share more of the class or get you the details you need?

Okay, thanks for sending me the plugin via email. I think I’ve got my head wrapped around what you need.

First, the class WC_Swatch_Picker is only called from the file in the plugin directories /templates/single-product/variable.php which appears to be a template that is used if you don’t provide your own, correct?

Assuming that you provide your own template in place of variable.php then the way to achieve your goal is to subclass WC_Swatch_Picker and call it instead in your own template that overrides variable.php. Here’s what that subclass code would look like, and you can put in your functions.php file if you like:

While there are many ways to override and extend code in WordPress, sometimes there only a few ways that are viable, and in this case that is one of the few viable ways to achieve your end goal because Lucas Stark did not implement a official way via hooks or some other approach to achieve what you need.

I am converting a plugin that does not follow modern WP plugin architecture. It’s a plugin that uses the ImageMagick image library for creating images instead of WP’s default.

The original plugin is just a bunch of functions and at the bottom of the code the add_filter('image_make_intermediate_size','imagick_sharpen_resized_files',900); filter and it works fine, both when uploading new images or with the use of the “Regenerate Thumbnails” plugin

Now I am trying to convert the plugin, wrapping in a class with the add_filter() added in the __construct() but I get:

Warning: call_user_func_array() expects parameter 1 to be a valid callback,
function \'magic_sharpen_watermark\' not found or invalid function
name in /Applications/MAMP/htdocs/claireobscuur/wp-includes/plugin.php
on line 213

I tried placing the filter in various positions in the class, even outside but still get the error.
I also tried your singleton method from this page but still get the error.
I am a NON coder and just want to get things done, why do they make it so diffucult for us a create a simple plugin following best practices?

To remove that action you will need to get the same instance of the class that blue_themes is using when it added the action. Does the class file end with an instantiation of the blue_themes class, with code that looks something like this?

P.S. BTW, in some ways the theme appears to be well-coded but in other ways, such as naming a global variable $CORE the theme is awful! A theme vendor should never create a generically named global variable, and ideally the theme vendor should create no global variables at all and instead create classes with a rather unique name, such as Premium_Press_Auction, for example.

And the entire theme is filled with generically named functions, which means there’s a great chance of conflict with a plugin that is also architected in a similarly poor manner. Caveat Emptor!

First we used a priority of 1000 which is +1 the value of 999 that WordPress SEO used to set the hook here.

Next you'll notice we access the global object $GLOBALS['wpseo_og']. That object was assigned on this line in wpseo_frontend_head_init().

The $GLOBALS['wpseo_og'] object is an instance of the WPSEO_OpenGraph class that contains a __construct() that sets the hook you want to remove.

Finally we call removed_filter() to remove the filter. This all gets called at priority 1000 on the template_redirect hook right after the wpseo_frontend_head_init() function is called at priority 999.