Packages

A Liaison package wraps together a bunch of fuctionality into a single directory and integrates seamlessly with Liaison.

A Liaison package includes addons, public files (routes), views, methods, hooks, configuration, a bootsrap file, custom Package subclass and more (or less!). A most basic package will typically include public files and views.

Most Liaison features can be accessed without using a package, such as if you just want to add a route or two, but Packages are generally recommended for building Liaison-powered websites. If you're integrating existing Liaison packages into a non-Liaison website, you likely won't create your own package.

There is a base package class, but most Liaison packages will extend from the Server package subclass, and this documentation is geared toward that Server subclass.

Note: The Server Package is not to be confused with the Server Addon. The addon compiles requests and processes routes. The package class puts together packages.

Related: Views, Routes, Addons, Package Base Class, Server Package Subclass, Redirect Addon, Server Addon

Docs

  • Useful Methods
  • Initialize a package
  • Directory Structure
  • Configs (config.json)
  • bootstrap.php
  • Subclassing Server Package

Useful Methods

  • $package->dir('/rel-dir/') gets the path to a directory within the package. Does NOT remove any path traversal or double-slashes.
  • $package->url('/some-relative-url/') prepends the package's base_url and returns a full path (no domain). Any double-slashes are removed. Does NOT remove any path traversal.
  • $package->goto('/some-relative-url/') redirects to a path within $package, using the Redirect addon. (same rules as url() method)
  • $package->config(string $key) get a config from a package
  • $package->setConfig(string $key, mixed $value) set a configuration value

Initialize a package

A package can use the built-in Server package class or a subclass of it.

<?php  
// Create your site's package, containing your routes, views, theme, addons, hooks, and more  
$site_package = new \Lia\Package\Server($lia, 'vendor:namespace', __DIR__.'/Site/', '/base_url/');    
  
// or using a subclass  
$site_package = new \My\WebsitePackage($lia);   
// base_url could be overwritten, but the package fqn and directory should typically be pre-defined in your package class's code.  

Directory Structure

This is the structure for a typical package, with each file and directory being optional.

packages/Site/  
    - config.json <- Package settings  
    - bootstrap.php <- called right after the package is initialized. Use `$this` for your `Package`.  
    - public/ <- Public files to be routed to.   
        - index.php <- home page  
        - contact.php <- /contact/  
    - view/ <- Views  
        - theme.php <- site layout  
        - theme.css <- automatically included when theme is displayed  
    - addon/ <- Addons (extend \Lia\Addon)  
        - MarkdownSupport.php <- A custom addon to add features to Liaison  
    - class/ <- Point composer's autoloader to this directory. The Autoload addon within Liaison is not recommended.  

Configs (config.json)

The config.json configures some settings on a package, and provides dynamic configurability for other packages to reference. For example, an addon that enables markdown support might check if an added package set vendor:namespace.markdown_support = true in its config.json.

Built-in configuratinos available:

{  
    "base_url": "/my-package/",  
    "fqn": "vendor:namespace",  
    "public_file_params": {}  
}  

Notes:

  • $package->config(string $key) get a config from a package
  • $package->setConfig(string $key, mixed $value) set a configuration value
  • base_url defaults to /, can be set in config.json or can be overwritten via a paramater passed to the constructor.
  • fqn is the fully qualified name of a package
  • public_file_params are extract()ed and exposed to public files within the package.
  • 2025-02-11: The config.json is loaded BEFORE the bootstrap is loaded, however base_url, fqn, and public_file_params are set AFTER bootstrapping. base_url and fqn will be overwritten by configs/constructor, whereas public_file_params will be array_merge()d (config ovewrites same-named-keys). This implementation is likely to be changed.

bootstrap.php

If bootstrap.php exists in the root of your package, it is called at the end of Package::__construct(), prior to any additional setup done by the Server package subclass.

Example boostrap.php, adding some routes & protecting requests to /admin/ pages within it:

<?php  
/**  
* This file is loaded after the base Package class is initialized, before addons are loaded. For access to addons within your package, call `$this->load_addons()`. For guarantees that other packages are loaded, setup hooks here (*assuming you've loaded the main package first*).  
*  
* @param $this \Lia\Package the package this bootstrap file belongs to (typically a subclass)  
*/  
    $package = $this;  
    $lia = $this->lia;  
  
    // Add a directory of additional routes for admin pages  
    \Lia\Addon\Router::from($lia)  
        ->addDirectoryRoutes($package, \My\ClassOfConsts::DIR_ADMIN, $package->url('/admin/'),['.php']);  
        // `['.php']` is an array of extensions to be hidden. i.e. public2/bear.php becomes /bear/  
  
  
    // protect all requests to `admin/*` with a hook, only if this package is being requested.  
    $lia->hook(\Lia\Hooks::ROUTES_FILTERED,  
        function(\Lia\Obj\Route $route) use ($package){  
            if ($route->package() !== $package)return; // we're not filtering for other's packages.  
  
            $admin_url = $package->url("/admin/"); // we must consider the base_url if the package is portable.  
  
            if (substr($route->url(), 0, strlen($admin_url)) == $admin_url){  
                // current_user_is_admin() is NOT part of Liaison, but might be part of your package subclass.  
                if (!$package->current_user_is_admin()){  
                    // Elsewhere, you might catch \My\Exception and display a message to the user.  
                    throw new \My\Exception(\My\ClassOfConsts::ERR_ADMIN_REQUIRED);  
                }  
            }  
        }  
    );  
  

Subclassing Server Package

A custom Package class makes it easier for others to setup your package, allows you to declare properties and methods, and the constructor can serve as a bootstrapper.

Minimal Example:

<?php  
  
namespace ReedyBear\PageCreator;  
  
class Package extends \Lia\Package\Server {  
  
    public string $fqn = 'reedybear:page_creator';  
    public string $name = 'page_creator';  
  
    public function __construct(\Lia $lia, ?string $base_url=null){  
        parent::__construct($lia, $this->fqn, \ReedyBear\PageCreator::DIR_PACKAGE, $base_url);  
  
        // implement liaison integrations so the user of your package doesn't have to do extra work, such as automatically setting up hooks.  
    }  
  
    // define additional methods  
  
}