v1.0 under development

v1.0 is abandoned. See README

Goals:

  • Convert to App
  • Strongly type as much as reasonable
  • DocBlock document the core things
  • Write great intro documentation
  • Remove need for Server Package.
    • Each App will have a config saying which directories to setup with which addons. I may include a default config for built-in addons, but I'm not sure.
  • Separate the Router class from the Router addon. Use the addon to invoke the class.
    • This shooouuuld allow me to a different router class (but same addon) for each app that's added. This would allow customizing the var delimiter. It would also add a lot of overhead. I can still separate Router class from Addon and use one instance for all apps if I really must. I could, also, use base urls to only run certain routers.
  • Use enums for all the built-in events
  • Use well-documented value objects for routes
  • Caching as first-class feature?

Long-term hopeful:

  • Compile Liaison installs
  • Create interface to show what methods are exposed through liaison object
  • Create class that ... every method is added as a global method on Liaison

Philosophy

A Liaison Server or CLI has 3 components: Lia (Liaison's Core), Apps, and Addons.

Lia is the core class. Apps are added to Lia. Addons exist within Apps.

Addons do all the meaningful work. Apps setup their addons and configs. Liaison ties independent addons and apps together, using events and namespaces.

Each App's config defines a namespace and hook()s to built-in events. Addons can also subscribe to built-in events, create new events, or hook to other addons' events.

Apps may subscribe to onReady(), called before an HTTP request or CLI input is processed, and onFinish(), which is called after input is processed.

Apps may hook to onRequestReady(), onCliReady(), and onTerminated(), which are only called in certain circumstances.

Install

composer require ...

Addons

Documentation for built-in addons

Documentation

  • API - Overview of most important features.
  • Full API - All classes, methods, properties, etc.
  • Tips / FAQ - All the tips & tricks you'll need to know.
  • Test - Test your liaison app, website, or cli program.
  • Troubleshoot - Troubleshoot any problems you encounter.

Setup | Run Liaison

Server setup uses deliver(), cli setup uses execute(). Custom setups use ready() & finish().

<?php
    require(__DIR__.'/vendor/autoload.php');

    $lia = new \Lia();
    $lia->load_config('/path/to/user-config.json');

    $server = new \Lia\App\Server($lia); // main app with router addon, cache addon, and more. 

    $my_site = new \Lia\App($lia, __DIR__.'/site/'); // see belo

    $user_login = new \Tlf\UserLogin($lia); // a third-party app for user authentication

    // $lia->ready(); # custom setup
    $lia->deliver();
    # $lia->execute(); // cli
    // $lia->finish(); # custom setup

(php -S localhost:3000 deliver.php)

Setup | Create App

Apps go in a directory, have a config, optional bootstrap, optional App.php, and sub-directories to implement addons' features.

File Tree

Depends on Lia\App\Server for public, view, and src.

config.json
App.php 
bootstrap.php
addon/ -- autoload Addons, by Lia\App
public/ -- automatic routes, by Router addon
    index.php
view/ -- re-usable views, by View addon
    theme.php
src/ -- class autoloader, by Autoloader addon
    MyUtilityClass.php

config.json

Most configs are used by addons in other apps, not by Liaison itself.

{
    "namespace": "MySite", -- format is up to you. vendor/package is recommended for libraries.
    "class": "MyAppClass", -- NOT required if you have an App.php
    "addons": { -- list of addons to enable. App\Site assume defaults if this key is not set
        "lia:router": "public" -- relative directory to load
        "lia:view": "view" -- 
        "lia:autoload": "src" -- this doesn't HAVE to be a directory. It's up to the addon
    },
    "lia:router.base_url": "/", -- default is `/`
    "lia:router.varDelim": "'\\.\\/\\-\\:'", -- default regex for which characters will separate dynamic portions of urls.

}

For "lia:router.base_url", lia is the namespace, router is the addon's name, and base_url is the actual property/feature to configure. Router will call $your_app->get("lia:router.base_url") ?? '/' when building routes.

App.php

Lia\App does basic setup with some default configs. Subclass it for additional setup, or implements \Lia\AppInterface if you're wild.

<?php

class MyApp extends \Lia\App { // implements \Lia\AppInterface to fully customize!

    // all methods optional, since Lia\App has empty placeholders

    /** called before an HTTP request or CLI input is processed */
    public function onReady(\Lia $lia){
        // magic __get() returns addons
        $theme_name = $this->user_config("mysite:themer.theme_name") ?? 'simple-flex'; 
        $this->themer->use_theme($theme_name); // this custom Themer addon has it's own theme loader
    }

    /** called after input is processed */
    public function onFinish(\Lia $lia){
        if ($this->custom_cache->age() > THREE_DAYS) 
            $this->custom_cache->clear();
    }

    /** Called when `$lia->terminate()` is called, which will `exit` after the `onTerminate()` event. */
    public function onTerminate(\Lia $lia){
        if (file_exists(PATH_TO_SOME_LOCK_FILE))
            unlink(PATH_TO_SOME_LOCK_FILE);
    }

    /** called by $lia->deliver() after onReady() event */
    public function onRequestReady(\Lia\HttpRequest $request){}

    /** called by $lia->execute() after onReady() event */
    public function onCliReady(\Lia\CliExecution $cli){}
}

bootstrap.php

example ...

Addon example ...