post-page

Actions and Filters and Classes, Oh My!

16
responses
by
 
on
August 26th, 2009
in
Tutorials, WordPress Hack, WordPress Plugins

Ever wondered how you can manipulate WordPress filters and actions that are defined inside a PHP class?

I did! I was working on a project recently that needed a plugin. The only problem was that the plugin was inserting some unnecessary cruft into the header of my theme. So, I figured I’d just use the remove_filter function WordPress provides… right?

Hold on a second! It’s not working!? But I put in the function name just how the codex explains it:

remove_filter('wp_head', 'the_crufty_function');

Why would it not work? Time to do some troubleshooting… So, I opened up the main plugin PHP file in my code editor and began to look around. What’s this? It’s a class! Hmm… But why should that make a difference?

It seems that WordPress requires a special reference to the function if it is defined inside a class. If you, the reader, are at all familiar with PHP classes then you probably know that you can usually access a class’s functions like this:

$the_class_initiator_variable->some_function();

So, lets give that a try:

remove_filter('wp_head', $the_crufty_class->the_crufty_function);

Still nothing… Oh boy… What do I do now? I guess we’ll try some Googling…

…Hmm…

…Not finding much…

Well… after much searching and trying different things I finally came upon this:

remove_filter('wp_head', array(&$the_crufty_class, 'the_crufty_function'));

It works! Wonderful!

You take the class initiator variable and the name of the function and put it in an array. Simple as that!

Note: No, that ampersand is not a typo! It sets up a reference to the original variable instead of copying it’s value. You’d be surprised how many people don’t know what the ampersand does in PHP. I didn’t know for the longest time.

Also, because the remove_filter and remove_action functions are so similar this method applies to both.

There you have it! Just a quick little tip regarding an issue that doesn’t seem to be very well documented. I’m sure some of the experts out there already know of this but, I didn’t. I’m willing to assume there are some people out there like me who are racking their brains over this very issue.

Hope it helps!

heading
16
Responses

 

Comments

  1. Amaury (1 comments.) says:

    You also can use
    array( &$this, ‘myFunction’ )

    into the class… and use a global var for initialize the class.

  2. HG (2 comments.) says:

    I was searching for that exact solution. Thank you for posting it.

  3. Hikari (79 comments.) says:

    Is this $the_class_initiator_variable an object, or is it the class name?

    • James Dimick (23 comments.) says:

      It’s the variable that is used to initialize the class. Like:

      class myClass {
      function the_function() {
      echo 'whatever';
      }
      }

      $myVar = new myClass();

      remove_filter('wp_head', array(&$myVar, 'the_function'));

      Does that help?

      • Hikari (79 comments.) says:

        tnx for the explanation and the exemple guys!

        I’m starting in wordpress plugin development, and I’m having trouble using OOP with WP.

        What I’m currently doing is using a core file with the class and another file with hook functions and so on. I also didn’t know how to make an object global, I’ll try that and then adapt my plugins for it!

        BTW: I subscripted to this post comments feed but I’m receiving report of other posts comments too. I used the correct feed URL, there seems to be a bug here.

  4. kovshenin (13 comments.) says:

    Hikari, it’s an object, therefore we can’t use &$this in this particular case. Since it’s cool to code plugins using the php OOP mode (i.e. using classes) then the actions and filters should probably be applied within the class, where you can actually use the array(&$this, ‘func_name’) that Amaury suggested above.

    The init section would be quite tricky in this case. Here’s a construction I like to use (suppose your class is called MyPlugin):

    add_action(“init”, “MyPlugin”); function MyPlugin() { global $MyPlugin; $MyPlugin = new MyPlugin(); }

    I don’t know who to thank but the first time I’ve seen this was in Viper007Bond’s Video Quicktags plugin.

    One more thing, a callback function is actually a php term, not wordpress. The wordpress codex says that the add_action, add_filter, and so on accept any valid callback functions. The php manual says that a callback function could be simply “my_func” or array(&scope, “my_func”). Thus, it works =)

    Cheers,
    ~ @kovshenin

    • James Dimick (23 comments.) says:

      Thanks for the response and thanks for clearing that up!

      • kovshenin (13 comments.) says:

        No problemo =) I actually just realized that you were refering to theme development as opposed to plugin development, where things are slightly different and perhaps a little bit more complex. I’m very used to add_action ;) My apologies if I missed anything ;)

        Have a great day!

    • Viper007Bond (91 comments.) says:

      The manual page he is referring to is this one BTW: http://www.php.net/call_user_func

      Also note that it’s important to wait until “init” to start your class. If you don’t, some functions (current_user_can()) for example will fail to work (or even be defined!).

      • kovshenin (13 comments.) says:

        Right, thank you Viper.

        What can you say about plugin activation and deactivation hooks? I believe they’re fired before the init level (I’m talking about the register_activation_hook function. The old way isn’t being used any longer AFAIK), therefore my plugin_activate and plugin_deactivate functions should be in the global scope and I can’t really wrap them up in my main plugin class unless I init it at an earlier level, which is pretty risky.

  5. kovshenin (13 comments.) says:

    Ah, totally forgot.. Thank you James, for explaining this. Great post ;)

  6. Camilo (1 comments.) says:

    Well, the problem is if you don’t have any access to that variable. If the plugin writer doesn’t make it a global accessible variable, there’s no easy way to retrieve that same variable, thus making it hard to remove the filter for a variable you don’t have any reference to.
    It’s very common for me to hook an object to WordPress inside a function and leave no other reference to that object.



Obviously Powered by WordPress. © 2003-2013

page counter
css.php