Hooks

Hook functions can be registered by name, then later called by code that uses them. Most hooks in this package are called by the Server addon when preparing and sending a request.

This feature is provided by the Hooks Addon, and built-in Hooks are provided as class constants (strings) on another class.

You can also define hooks in your own packages.

Related: Hooks Addon, Hooks Constants, Server, Packages, Addons

Docs

  • Register a Hook Function
  • Available Hooks
  • Lifecycle Methods
  • Creating Your Own Hooks

Register a Hook Function

Call \Lia\Addon\Hook::add(string $name, mixed $callable) to register a function to be called later. You can set these up in your bootstrap.php, in your package constructor, or even use one hook to setup other hooks!

We'll create a REQUEST_STARTED hook to add admin routes only if /admin/... is requested. We're doing this because it requires database access to determine if admin routes are accessible. (The routes should also protect themselves from unauthorized access, so this might not be the best example.)

bootsrap.php:

<?php  
// `$this` is the `\Lia\Package` instance for the given bootstrap file.  
$package = $this;  
  
\Lia\Addon\Hook::from($this->lia)  
    ->add(\Lia\Hooks::REQUEST_STARTED, // hook name is just a string  
  
        // method signature is determined by each hook  
        function(\Lia\Obj\Request $request, \Lia\Obj\Response $response) use ($package): void {  
            // in case your package has a base_url  
            $admin_url = $package->url('/admin/');  
            // if the url starts with `/admin/` then return, do nothing  
            if (substr($request->url(),0,strlen($admin_url)) != $admin_url) return;  
            // if the user is not an admin, do nothing  
            if (!$package->user_has_admin()) { // this method is not built into Liaison.  
                // If you do this here, then users on your site will get 404 Not Found errors   
                    // instead of 401 Unauthorized errors,  
                    // so you may or may not want this check here.  
                    // and your individual routes should still protect themselves.  
                return;  
            }  
            // since it is an `/admin/` request AND the current user is an admin, we'll actually add admin routes.  
            \Lia\Addon\Router::from($package->lia)    
                ->addDirectoryRoutes(    
                    $package,   
                    $package->dir('/admin-routes/'), // directory, absolute path    
                    $package->url('/admin/'), // base_url for the routes    
                    ['.php'], // array of extensions to remove    
                );   
            }  
        );  

Available Hooks

See \Lia\Hooks.php for available hooks.

Reference them as \Lia\Hooks::HOOK_NAME when registering your callables.

Note: Some hooks may not be defined there currently, but hooks not defined as class constants are likely to be changed and broken in the future. The transition to class const hooks is a work in progress. (2025-02-04)

Lifecycle Methods

Addons have Lifecycle methods that are called during certain parts of Package lifecycles. These are called by the package class, and are not part of the Hooks Addon.

Additional lifecycle methods may be added in the future. (2025-02-04)

Addon::init_lia($package)
\Lia\Package\Server calls $addon->init_lia($package) near the end of its constructor, just before $addon->onPackageReady($package). This is called for each addon in no particular order.

In your Addon, implement public function init_lia(\Lia\Package $package){} to do any additional setup that you can only do after your package is ready.

If not using or extending from the \Lia\Package\Server, then call \Lia\Package::init_lia() to invoke the init_lia() methods of all the addons.

Note: This method name is likely to change in favor of onPrepareLia($package) or something of the sort. (2025-02-04)

Addon::onPackageReady($package)
\Lia\Package\Server calls $addon->onPackageReady($package) at the very end of its constructor, on each addon. Addons are not called in any particular order.

In your Addon, implement public function onPackageReady(\Lia\Package $package){} to do any additional setup that you can only do after your package is ready and other addons have initialized themselves (i.e. their init_lia() methods have been called.).

If not using or extending from the \Lia\Package\Server, then call \Lia\Package::ready() to invoke the onPackageReady() methods of all the addons.

Creating Your Own Hooks

See \Lia\Hooks.php for an example of defining hooks.

To create a hook, all you need is a string, and to call the registered hook functions via the Hook addon. You should create a Hooks class to hold class consts that define each of your available hook names. The purpose of each hook and the required method signature should be defined in the docblock for each const. You should name the hooks like "vendor:namespace.hook_name"

When you call a hook, you will receive an array of return values - one return value for each registered function that was called. You can do whatever you please with this array of return values.

Here is an example from the Server addon, using the FILTER_ROUTE hook to check each route to see if it should be removed from the route list. This is used to resolve conflicts when multiple routes are matched for a single request.

<?php  
foreach ($routeList as $index=>$r){  
    $rets = \Lia\Addon\Hook::from($this->lia)->call(\Lia\Hooks::FILTER_ROUTE, $r, $routeList);  
    foreach ($rets as $r){  
        if ($r===false)unset($routeList[$index]);  
    }  
}  

Hooks do not need to use return values at all.

Tip: It may be better to create an object to pass to each registered callable, and allow the hooks to modify the object, instead of using the multiple-return-values feature.