Function Documentation

WordPress Function Documentation Progress

Writing Plugins: What is the Class Callback Format?

Prior to WordPress 2.3.0, there was a bug that prevented object referenced method callbacks from being removed. In WordPress 2.3.x and upcoming WordPress 2.5, in order to remove the original method in the class, you have to use the original object reference. In PHP4, where objects are passed by value, this can be a problem, but PHP5 users shouldn’t have much to worry about as long as the variable they are using holds the original class reference.

Explanation of Problem Prior to WordPress 2.3

To demonstrate the problem, take a look at this code. If you were to run this prior to WordPress 2.3, the hook would not be removed because you changed the class property $test.

class MyPlugin
{
    var $test;

    function MyPlugin() {
        $this->test = false;
        add_action('init', array(&$this, '_init'));
        $this->test = true;
    }

    function init() {
        remove_action('init', array(&$this, '_init));
    }
}

This is a poor example, in that the ‘init’ hook will never run again. Other hooks will demonstrate the problem better in real world practice. That said, the method of adding callbacks to the hook array wouldn’t have allowed you to remove the hook until the state of the class was back in its original form prior to the addition of adding the MyPlugin::_init() to the init hook.

It is a little complicated to explain, but basically, once you changed the properties of the class, you wouldn’t be able to remove any hook you added prior to the change. For most plugins this was a huge deal since they had everything in one Singleton class (big mistake, will detail in later post).

How Method Callbacks are handled in WordPress 2.3+

A new private function was introduced to manage object referenced method callbacks. The form of which is below.

$myplugin = new MyPlugin();

add_action( 'init', array(&$myplugin, '_init') );

As you can see, the callback references the $myplugin variable along with the method in the second element. The reason this can cause a problem, is if you unset the variable afterwards.

$myplugin = new MyPlugin();

add_action( 'init', array(&$myplugin, '_init') );

unset($myplugin);

If you think this will magically remove the reference in the hook array, you are mistaken. PHP will retain the reference to the object and will call the method. This will hinder, but not prevent the removal of the object’s callbacks later.

For a workaround, you can recreate the object reference and it should (purely conjecture) recreate the needed hook string to reference to previously added object reference callback. This will not work if two or more object references of the same class were created, so it is assumed that in most cases only one object reference will be created. If only one were created and destroyed, it might be possible to remove the callbacks from the action or filter using the Plugin API.

New format

The new format for the above object referenced method callbacks are always: class name, followed immediately by the method name, followed by the amount of previously added (classname+methodname). For classes, this allows you to add as many object referenced classes and add methods which don’t override each other.

For static method callbacks, the format is always: class name followed immediately by method name. There is no need to protect against overrides because no two classes can have the same class name (yes, I do know there is an exception to this rule).

For functions, nothing changes, it is just the function name.

Advertisements

January 13, 2008 Posted by | Writing Plugins Series | , , , | 5 Comments

Writing Plugins: The ‘all’ Hook

The ‘all’ hook is run on every action and filter hook. It is good for debugging and not much else. Also, prior to WordPress 2.5, the ‘all’ hook was broken and shouldn’t be hooked into.

The fix removes the logic that merges the all hook into the rest of the other hooks. This should have a nice benefit of speeding up the plugin cycle. The all hook will also only be processed if there is a function that was added to it. For almost all users, they will never run the all hook.

The ‘all’ hook is technically an action since it does not offer an interface for returning data to other functions that are in the ‘all’ hook. However, it will run for all actions and filters, but will not have access to the filter contents.

Well, for filters, the ‘all’ hook will have access to the initial parameter value or values if there is more than one parameter (more on that later), but will not have access to the completed value after all of the functions in the hook have processed the initial value.

Adding a Function to the ‘all’ Hook

add_action('all', 'myplugin_all_hook');

function myplugin_all_hook( $parameters ) {
    // Do stuff here
}

The all hook has access to the parameters that were passed to the hook as an array and that will be passed to the functions. The ‘all’ hook does not have access to manipulate those parameter values before they get to the filter or action functions.

The $parameters is an array, which holds all of the values for from each of the parameters. You can count the array, test the contents of the parameters, test the types of the values.

Use Cases

What the ‘all’ hook can do however is a few evaluations.

  1. Do sanity checks against how many parameters the current hook (Will be discussed in a later post) should have verses how many were actually passed.
  2. Count how many times a hook was called during a run of WordPress and for each page. (The ‘all’ hook will not be able to profile how long each hook took to process however.)
  3. Using debug_backtrace(), can figure out which functions called the hook.
  4. Fine tune your plugin by seeing what the hook you are plugin to is giving your function.

Those are the common use cases of the ‘all’ hook. However, like it has already been stated, only debuggers are likely to plugin to the ‘all’ hook. Most plugin authors and users should not concern themselves. However, if you wish to debug the hooks, then there is a built-in way to do so.

January 10, 2008 Posted by | Writing Plugins Series | , , , | Leave a comment

Codex Documentation for Deprecated Function and File Hooks

I put this together after Peter Westwood announced on his blog about the commit of the deprecated functions and their hooks.

The functions are run for any function that resides in wp-includes/deprecated.php and will not report for any other deprecated function not in that file. There are also two files in wp-includes folder that are deprecated and will give a notice.

Most users won’t notice this however, since the notices won’t be shown unless WP_DEBUG constant exists and is set to true. Most installations and current WordPress versions don’t have that set by default, so the majority of users won’t see anything. Which is stated on the codex page.

I have a problem however with the name of the page and therefore the location. I wish that the name was better, but there is already a page linking to it, so I’m currently too lazy at this point to change the location. I’m also not sure what a better name would be.

It needs more code snippets and I would have added them, but after writing and spending that much time. I decided that placing working or semi-working code snippets would be better left to plugin authors.

To be honest, I didn’t fully agree with the enhancement in the first place. However, the code Westi put in is super sweet and hopefully should allow for further notices to theme and plugin authors that they are using functions or files they should not be using in a future version of their plugin or theme. If a user is interested in whether or not their plugin or theme is using a function or file that may soon disappear and breaking their site, they may follow the instructions to enable WP_DEBUG for WordPress 2.4.

Well, since WordPress 2.4 isn’t released yet, there isn’t much reason for explanation. I suspect more documentation will be written for WordPress 2.4. The current page is just a jump start for any plugin authors who are interested in Peter’s post and want more information. As a co-author of the patch, I was very happy in providing documentation, both source and codex on more information.

As an aside, it is completely possible for a plugin author to also use the functions on their own themes and plugins to allow anyone that might use their code for their own plugin or theme that the function or file is deprecated. The functions are documented as private however, so purists will hate you if you do so.

January 1, 2008 Posted by | WordPress | , , | Leave a comment