Last time out, I talked about the value of adding custom extension hooks to your add-ons.
Shortly after publication, several people got in touch to rebuke me for not discussing how to add a custom extension hook to your add-on.
That said, the conversations I’ve had since my previous post suggest that the EE documentation isn’t quite as clear on this subject as it might be. Hopefully this post will fill in the blanks 1.
A typical extension hook
Here’s an example of a typical extension hook:
$hook_result = $this->EE->extensions->call('my_hook', $hook_data);
$hook_result = is_string($hook_result) ?: '';
There are three main elements to that snippet of code; let’s look at each in turn.
Step 1: Check if the hook is “active”
The first step is to check whether any extensions have registered an interest in your extension hook. The ExpressionEngine
extensions object provides a built-in method for checking whether your extension is alone and unloved.
The EE User Guide example uses an absolute equality check, but this is unnecessary. The
active_hook method always returns a boolean.
Step 2: Call the hook
Assuming your hook is “active”, the next step is to call it. This is achieved as follows:
call method accepts an arbitrary number of arguments, enabling you to provide additional information about your hook. For example:
$this->EE->extensions->call('my_hook', 'Woody Allen', 'Sleeper');
The hook handler function will receive each additional argument as a parameter, so the handler for the previous hook would look something like this:
public function on_my_hook($actor, $film)
Step 3: Accept and validate return data
If you expect the hook handlers to return data, just assign the result of the
EE->extensions->call method to a variable:
$hook_result = $this->EE->extensions->call('my_hook');
As ever when accepting data from an external source, you should validate whatever information is returned from the extension hook handlers.
The example in the User Guide doesn’t bother with such basic security; in this instance, I don’t suggest you follow EllisLab’s example.