Follow Jeff Sayre on Twitter

Introducing WordPress Hook Sniffer: a Developer Plugin

By

As a developer, one of the benefits to sophisticated Open Source projects like WordPress and BuddyPress is that a significant amount of foundational code is already in place. This makes adding additional functionality, additional value, to the platform easier. You just create a plugin.

As a developer, one of the downsides to Open Source projects like WordPress and BuddyPress is that a significant amount of foundational code is already in place. There are hundreds of functions, classes, methods, and general code that you never actually get to know. Sure, you might call them from within your code, you might know how and when to use them, but you more than likely do not understand how and why they work and what they actually do to accomplish their task.

Why? Because you were (more than likely) not part of the team that wrote the code, that figured out what each function was required to accomplish and in what ways that code would interact with other parts of the foundation.

This is exactly the situation I found myself in several weeks ago as I was trying to figure out why one of my custom do_action events in my BuddyPress Privacy Component was not working as I had expected. My investigation into this issue not only opened my eyes into the inner workings of WordPress’ Plugin API, but also helped me figure out why a few BuddyPress action events were not behaving as intended.

Understanding Hook Firing Sequence

How can you know the firing sequence of action functions or filter functions that you attach to existing WordPress and BuddyPress hooks? Why is this even important?

To answer the second question, read my article, WordPress Hooks, Barbs, and Snags. The answer to the first question is more difficult.

Since many internal WordPress and BuddyPress functions may be tying into the same action or filter hooks, there is no easy way to know the firing sequence of action functions or filter functions. Add to that the fact that 3rd-party external plugins can also tie into these same action or filter hooks and the issue becomes even more murky.

As I had a serious issue with a custom do_action event in my BuddyPress Privacy Component not working as expected, I set out to solve the first question. Although my problem appeared to be with my custom do_action event, I soon discovered that it was caused by another hook to which I had tied in to.

The result of my investigation: a new tool for WordPress and BuddyPress developers called the WordPress Hook Sniffer. What does this plugin do? It helps plugin developers determine the sequence in which action and filter functions are fired, providing a window into the inner workings of the WordPress Plugin API.

As with all of my other WordPress and BuddyPress plugins, this plugin is licensed under the GNU General Public License 3.0 (GPL).

Download WordPress Hook Sniffer and Donate!

You can download the WordPress Hook Sniffer via the WP Plugin Repository. Even more excitingly, you can help me support this plugin, encourage me to create new ones, and enable me to keep living by selecting a sponsorship level below and clicking the “Pay Now” button. Thank you!


Sponsorship Levels




If you are a corporate user, consultant, plugin developer, or theme designer and profit from using my plugin, please consider donating at one of the upper levels. Thank you!

Using the Plugin

WARNING: This plugin is to be used only in a development sandbox and not in a production environment. It is intended solely for use by plugin developers to help determine the sequence in which action and filter functions are fired. Use at your own risk. As this plugin should not be installed on an active WordPress-based site (a production site), no support for broken sites will be given. You have been warned!

As with all plugins, please read the installation instructions in the readme.txt file. You may find the FAQ in the readme.txt file useful. Also, if you have been using an older version of this plugin, the installation process is now much simpler—see this post for details.

  1. Once installed and activated, you will find a new menu option in the Settings menu
  2. Clicking on that will bring up the WordPress Hook Sniffer Settings screen. The first thing to do is look in the upper left-hand corner of the screen. See that gratuitous “Please Support My Work” section? Go ahead and select a nice, juicy amount and then click the “Pay Now” button. Your donation (in any amount) is greatly appreciated! Okay, enough begging.
  3. Next, read the “Usage Notes” section at the end of this article for a few additional bits of important information
  4. Finally, select “Enabled” in the Main Sniffer Settings section, choose what data you wish to view in the Output Options section, and then select where you would like the output to go in the Output Location section
  5. It’s that easy!

Output Settings Options

Whereas getting the WordPress Hook Sniffer to work is relatively straight forward, interpreting the output is a different story. What does all of that crap stuff mean?

Here is a brief overview of each of the output options and what information it can provide. However, to truly understand how to interpret the output and how best to use it in your development work, you will need to read my article, WordPress Hooks, Barbs, and Snags article.

A. Added Functions

Selecting this option outputs the special WP Hook Sniffer array that holds, in the order in which they were encountered during code execution, all add_action calls and add_filter calls. The file and line number from which a given function was triggered is also provided.

B. Removed Functions

Selecting this option outputs the special WP Hook Sniffer array that holds, in the order in which they were encountered during code execution, all remove_action calls and remove_filter calls. The file and line number from which a given function was triggered is also provided.

C. Action and Filter Function Array

This is the grandaddy, grandmommy, grandchild, Grand Ole Opry of output data. It contains the output of the $wp_filter array, the array that holds all of the added action and filter functions and is used by the do_action and apply_filters functions call to determine function firing order—although there is a twist here. You must read my article WordPress Hooks, Barbs, and Snags article to learn what it is.

D. Action Event Firing Order

This option contains the output of the $wp_actions array. A simple, one dimensional array that holds the sequential listing of all the do_action events that need to be processed. The events within this array used in conjunction with with corresponding data in the $wp_filter array determines the firing sequence of all action functions

E. Action Event Firing Sequence

Selecting this option outputs the special WP Hook Sniffer array that holds the sequential listing of do_action events with their corresponding fired action function(s). This listing shows you exactly the sequence in which each triggered action event fires its hooked action functions.

F. Filter Event Firing Sequence

Selecting this option outputs the special WP Hook Sniffer array that holds the sequential listing of apply_filters events with their corresponding fired filter function(s). This listing shows you exactly the sequence in which each triggered filter event fires its hooked filter functions.

Usage Notes

  1. Reporting Bugs: If you find bugs or are having issues using this plugin, you can either post a comment in this article or visit the support forum for this plugin. Assistance in providing patches to this plugin is appreciated.
  2. Increasing Precision: If you want to see a more precise accounting of the execution time of a given function, you have to edit your php.ini file to increase the precision displayed for floating point numbers. Search your php.ini file for the entry:

    precision = 12

    and change that to:

    ; precision = 12
    precision = 16

    As you can see, I like to comment out any changes to my default php.ini settings just in case I decide to revert the changes later. This allows you to do so easily without having to remember or look up what the default setting is supposed to be.

    Save your modified php.ini file and then restart your development server and you should now see the time-executed stamp displaying 6 significant figures instead of 2. This provides a sufficient level of detail.

  3. Text Output Issues: If you’re using SSL or are behind a proxy server, you may have issues when selecting to send the output to a text file. There are a few work arounds for this, but suffice it to say that since this plugin is to be used exclusively in a development sandbox environment, I will not be coding these into the plugin. If you must use this plugin with SSL or behind a proxy server, then simply select the screen output option. You can learn more about this in the PHP manual for the fopen function.
  4. Screen Output: When printing to screen, it may take a several seconds for output to finish. The output will start just below your theme’s footer.

Article Comments

  1. slaFFik says:

    Thank you, Jeff, from the whole WP-plugin-dev community!

  2. Dave Doolin says:

    Just installed it. Looking forward to digging into it in depth.

    I’m definitely going to use it against register_activation_hook. I wrote a series of articles on that one. Seems to cause so much grief, but it’s not that difficult.

  3. This is awesome…. thanks so MUCH!

    Can you distribute the plugins.php file as a patch file against 2.9.2?

    • Jeff Sayre says:

      R’phael-

      Thanks for the suggestion.

      As this is a developer’s tool only, I don’t think that the WP core team would approve my modifications to the Plugin API. My version of the API does not provide any fixes to the current file. It only offers augmentations that provide developers additional benefits.

      • I didn’t mean for inclusion in core, just so that a dev can easily patch his local working copy after an svn update so that he has a nice dev install. How is this working against 3.0 now?

        • Jeff Sayre says:

          The plugin.php files does come in the download package — although I did forget to include it in v 0.11 by accident (see last comment in thread).

          I’m not too sure of the advantage of distributing it as a patch file. I thought about it but decided that it made sense to require a manual install as it would force the developer to think about comparing any new WP versions before installing. I am not always on top of the newest changes as I have too much to do. But, a patch file could be possible.

          As far as working with WP 3.0, I personally have not experienced any issues. I need to check the WP changesets and see if there have been any changes to plugin.php since I created WP Hook Sniffer.

  4. Brian says:

    Just installed latest version, there is no plugin.php file in the accessory_files folder

  5. Jesper says:

    Hello
    I can’t find the Modified WordPress Plugin API file located in /accessory_files. That folder is empty.
    Where can I find it?

  6. Jeff Sayre says:

    Brian and Jesper-

    Thanks for the heads up. For some reason, that file failed to upload to the repository. But, I have now corrected that issue. Please redownload the plugin package.

    Since I kept the version number the same (0.12), you have two choices:

    1. Simply download the plugin package again and copy over the Modified WordPress Plugin API into the /accessory_files directory. From there, you can then move a copy into the proper location (/wp-includes).

    2. Or you can deactivate WP Hook Sniffer first, delete it from the /plugins/ directory, and then upload the new copy and activate. After that, move the Modified WordPress Plugin API into its proper place.

    I would suggest the first option, but either one will work. By the way, I would copy the Modified WordPress Plugin API into its working directory (/wp-includes) and keep a copy in the /accessory_files directory. That way, you always have a copy of that file. Also, it is not a bad idea to rename the original, default plugin.php file located in /wp-include just to keep in case you want to revert to your original setup.

  7. NPhilly says:

    Your plugin displays conflicting information. I have just installed version 0.15 and it complains with the following:

    Warning! You have not installed the Modified WordPress Plugin API file. WordPress Hook Sniffer will not work without this. Please see the readme file for more information.

    I then have a look inside the readme file which then goes on to say:

    Installation Instructions:
    IMPORTANT NOTE: As of version 0.14, the installation instructions have changed. It is no longer necessary to manually install the modified plugin.php file. WordPress Hook Sniffer automatically handles the installation of that file upon activation and then uninstalls it,
    replacing it with the original, stock plugin.php file upon deactivation.

    So which is it?

    On top of this it just doesn’t seem to work.

    Also either change your readme file to an html document or remove the html.

    • Jeff Sayre says:

      You have not provided sufficient information to help troubleshoot your issue. What version of WordPress are you running?

      As you are the first person out of over 1200 downloads who has reported this problem, I imagine it is because you have installed WordPress Hook Sniffer on an incompatible version of WordPress. Per the readme.txt file, the plugin is “Compatible up to: WP 3.0.4″.

      On top of this it just doesn’t seem to work.

      The plugin has a 5-star rating and a number of WP and BP core developers have used it with great success. This is another indication that you more than likely have either installed it on WP 3.0.5 or higher, or that you have a plugin installed and activated that is conflicting with WP Hooker Sniffer’s operation.

      Also either change your readme file to an html document or remove the html.

      This is the way many readme.txt files are created—using the Markdown syntax to provide links. See the end of this WP Codex resource for more information. The HTML Markdown syntax provides hyperlinks on the plugin’s listing page within the WordPress Plugin Repository. You can see that by visiting this plugin’s page on the WP Plugin Repo. So, the HTML Markdown is perfectly fine and standard the way it is within the readme.txt file.

      As I am no longer supporting this plugin as the time required conflicts with my needs to earn a living, you are free to fork the plugin or hire a developer to make this plugin compatible with the newer versions of WordPress. I wish the WordPress Plugin Repository had a way to indicate that a plugin is no longer being supported (as there are numerous plugins in that state). But, until that happens, most plugin developers simply rely on the compatibility statement to play that role.

      • Yes, I’ve had the same problem – I too only just noticed that this plugin is not compatible with WP 3.1. Unfortunately the hook-sniffing I need to do is only required for a WP 3.1 site, as on my WP 3.0 instance the bug is not occurring!

        Well, looking forward to a 3.1-compatible version of this plugin!

      • Krishna says:

        Yes the same message In my case too ,
        “Warning! You have not installed the Modified WordPress Plugin API file. WordPress Hook Sniffer will not work without this. Please see the readme file for more information.”

        I am using the latest version of WP as on date

  8. Mukesh Dak says:

    Thanks a lot for sharing this wonderful plugin.

  9. Aleskino says:

    Warmest thanks for providing such a good tool !
    As I had problems to catch fired WP events, in case there is a redirection or an ajax call, I have modified the following function in order to write a different file for each request, and then limiting the number of reports in the hook-sniff-report directory. Hoping it can be useful for someone.

    /**
    * wp_hook_sniff_output_hook_info()
    *
    * Outputs the selected hook intelligence.
    *
    * Uses data assembled by action_filter_backtrace(), a special
    * function added to the WP Plugin API exclusively for the
    * WP Hook Sniffer Plugin.
    *
    * @since 0.1
    * @version 1.1
    */
    function wp_hook_sniff_output_hook_info() {
    global $wp_hook_sniffer_options_set, $wp_actions, $wp_filter, $wp_hook_sniff_action_firing_sequence, $wp_hook_sniff_filter_firing_sequence, $wp_hook_sniff_functions_added_array, $wp_hook_sniff_functions_removed_array;

    /* Check to see if we should be outputting anything */

    /* If the Modified WordPress Plugin API file is not installed or not current,
    or the WordPress version is not sufficient, then exit */
    if( ( WP_HOOK_SNIFF_API == False ) || ( WP_HOOK_SNIFF_COMPATIBLE_WITH_WORDPRESS == False ) || ( WP_HOOK_SNIFF_PLUGIN_API_VER 0) {
    // create an array ordered by date
    $filesbydate = array();
    foreach ($files as $file){
    $filesbydate[filemtime($file)] = $file;
    }
    ksort($filesbydate, SORT_NUMERIC); // oldest first
    // delete oldest
    $i = 0;
    foreach ($filesbydate as $file){
    unlink($file);
    if ($i++ >= $toomuch){
    break;
    }
    }
    }

    }

Leave a Reply

Share on Twitter
Share on Facebook
Share on FriendFeed
Share on LinkedIn
Share on StumbleUpon
Share on Digg
Share on Delicious
Share on Technorati
Add to Google Bookmarks

Archives