README.src.md.bak

<!-- DO NOT EDIT. This file generated from template by Code Scrawl https://tluf.me/php/code-scrawl/ -->  
# Liaison  
A PHP Framework and a set of components for developing webapps and websites. The software is fairly robust, but the documentation is horrible. The code is also messy & needs a lot of refactoring that may or may not happen.  
  
# Lia\Simple  
Lia\Simple extends \Lia and simplifies a lot of server setup. Simple is also pretty messy & confusing.  
  
Much more documentation is needed  
  
## Server Setup  
This is basically all thoe code you need to setup a Liaison server.   
```php  
<?php  
require(__DIR__.'/vendor/autoload.php');  
  
$site = __DIR__.'/site/';  
$apps = __DIR__.'/apps/';  
$lia = new \Lia\Simple();  
$lia->debug = !$lia->is_production();  
$lia->generic_error_page = __DIR__.'/cache/generic-error-page.html';  
$lia->root_dir = __DIR__;  
// very simple path-based delivery of static files  
$lia->deliver_files("$site/public-archive/");  
// by default it will auto-load `$lia->root_dir.'/RSettings.json'`  
R()->load("$site/RSettings.json");  
// load Liaison apps.  
$lia->load_apps("$site", "$apps/Files", "$apps/Blog", "$apps/Forms");  
// initialize the apps. See Lifecycle below  
$lia->setup();  
  
// retrieve phad instance from a liaison app & configure it.  
$files_phad = $lia->phad_from_dir("$apps/Files/");  
$files_phad->dir_upload = __DIR__.'/backup/files-upload/';  
  
// sends a response, redirect, or whatever  
$lia->respond();  
```  
  
## Lifecycle of Lia\Simple  
`Lia\Simple::__construct` initializes the default `\Lia\Package\Server` instance, which loads the built-in package & addons like the Router, Seo, View, and others.  
  
`Lia\Simple::load_apps($dir1, $dir2, ...)` will initialize the given app directories, creating instances of `\Lia\Package\Server` for each. Simple does not allow a custom Package class when using `load_apps()` or `load_app`  
  
`Lia\Package\Server::__construct` - called for each app when `load_apps()` is called.  
1. Set configs from `"$app_dir/config.json"`, if file exists.  
2. Set up routes, views, cache dir, default settings like `$lia->base_url` & cache dir  
3. Initialize addons found within the app dir  
4. Call `$addon->init_lia($package)` on each addon  
5. Call `$package->ready()`, which calls `$addon->onPackageReady()` for each addon in the package.  
  
`Lia\Simple::setup()` - This is bad feature because `Lia\Package\Server` already calls `$package->ready()` during its `__construct`  
1. Loop over all packages (each app has a `Lia\Package` class instance)  
2. Call each `$package->ready()`  
3. `$package` loops over each of its `$package->addons` and calls `$addon->onPackageReady($package)`  
4. Override `onPackageReady()` in your `Lia\Addon` for any app to do further setup. The base Addon class doesn't do anything with `onPackageReady()`.  
  
  
`Lia\Simple::respond()` - calls `$lia->deliver()`, but wraps it in error handling.   
Notes:  
- Will try to deliver a generic error page. if an exception is thrown. Worst case scenario, just prints that there was an error & a generic link to the home page.   
- If `$_SERVER['DO_NOT_RESPOND'] == true`, then simply returns and does nothing.   
- If `$lia->debug == true` AND the request is to `/debug/`, call `$lia->debug()` and `exit;`.  
- If `$lia->debug == true`, will throw errors instead of showing generic error page. `respond()` DOES NOT change php error display/reporting settings.  
- Generic error page must be absolute path set at `$lia->cache->dir.'/generic-error-page.html'` OR `$lia->generic_error_page`.  
  
Lifecycle `Lia::deliver()` - called by `Simple::respond()`, and actually calls `Lia\Addon\Server::deliver()` (*Apr 13, 2023*)  
1. Call hooks `ServerStart`, `PreAllPackagesReady`, and `AllPackagesReady` with no params  
2. Initialize `Lia\Obj\Request` and `Lia\Obj\Response`  
3. Call hook `RequestStarted` with params `$request, $response`.  
4. Call `$lia->route($request)`, which calls `Lia\Addon\Router::route($request);`. Gets a list of matching routes from the routeMap. ALTERNATIVELY, if `$router->routers` contains an array of callables & one of those callables returns something truthy (supposed to be an array of routes), then return that.  
5. Call hook `RoutesFound` with param `$routeList`  
6. Foreach route, call hook `FilterRoute` with param `$route`. If ANY of the hook handlers returns strict (`===`) `false`, remove `$route` from the list.  
7. Filter remaining `$routeList` down to one route using an oversimplified and bad algorithm.   
8. if route is null, then `try_redirect_to_corrected_url()`, which is a url normalizer & redirecter that `exit`s. If it does not `exit`, throw an excpetion that no routes were found.  
9. Call `RoutesFiltered` hook with param `\Lia\Obj\Route $route`  
10. Set `$response->useTheme = true`  
11. Call `$server->process_route($route, $response);` - executes callable, `require`s php file, or loads static file. Considers cache for static file. Theme is disabled for static file. Enabled for  callable or php file. Sets `$response->content` instead of outputting content.  
12. If `$_GET['theme']=='json'`, then sets `$server->theme = 'json'` and compiles resource files (js & css files)  
13. Call hook `RouteResolved` with params `$route, $response`.  
14. Apply Theme. if EITHER `$response->useTheme` OR `$server->useTheme` are falsy, do nothing. if `$server->theme=='json'`, build array with keys `content`, `scripts`, and `stylesheets`, json_encode that array, and set `$response->content` to that json string. Otherwise, load the view with name `$server->themeName` and pass keys `response` and `content` to that view. Then call hook `ThemeLoaded` with param `\Lia\Obj\View $themeView`. Then set `$response->content` to stringified `$themeView`.  
15. Call hook `ResponseReady` with param `$response`  
16. send `$response->headers`, then `$response->content`  
17. Call hooks `ResponseSent` then `RequestFinished`, both with one param `$response`   
  
# Old Documentation (prior to Apr 13, 2023)  
These docs below are probably accurate for the most part ... but they are not in reference to Lia\Simple, and they need reviewed.  
  
## Next Version (release TBD)  
This version is planned for the future & as of Apr 12, 2022 development has not begun. Just notes. See Status.md  
  
`v0.6` will be the next version & will come with major internal changes but likely will not have any significant changes to the API. The current version has Package & Addon as sub-classes of Lia. Also, there are MANY properties by-reference. These complexities are slow & confusing. In the new version, Packages & Addons will likely not extend from Liaison any further. And by-reference properties will be removed.  
  
## Beta Version (April 5, 2021)  
`v0.5` marks the official beta. Software-wise, it's basically ready to go. Documentation wise, it's pretty poor. There are some weird things in here that will make it hard for you to use to it's full ability until I finish writing proper documentation. There's also some minor code issues in Liaison that I do need to fix.  
  
**My advice:** Admire what it could be, keep an eye on it, and use it when it is a little more mature.  
  
## Quick Start  
1. Write a deliver script, such as `deliver.php`. Comment out the `require add-route.php` line  
```php  
<?php  
  
require_once(dirname(__DIR__,2).'/vendor/autoload.php');  
  
$lia = new \Lia();  
  
$main = \Lia\Package\Server::main($lia);  
$site = new \Lia\Package\Server($lia, 'site', __DIR__);  
  
  
//comment this line out in step 1  
require(__DIR__.'/add-route.php');  
  
$lia->deliver();  
```  
  
2. Write a home page.  
Create a file `public/index.php`  
```html  
<h1>Index Page</h1>  
<p>Any file in the `public` dir will be routed to automatically. Any public/*.php files are routed with NO file extension.</p>  
```  
  
3. Start the server: `php -S localhost:3000 deliver.php`. Visit `http://localhost:3000/` in your browser  
      
Ideally, write tests to ensure your site works as expected. See [test/run/ServerMinimal.php](/test/run/ServerMinimal.php) for simple examples. I use [php/tester](https://tluf.me/php/tester), but [Php Unit](https://phpunit.de/) is the popular go-to for php testing  
  
4. Write a view file at `view/ArticlePreview.php`  
```php  
<div class="ArticlePreview" >  
    <h1><?=$title?></h1>  
    <p><?=$description?></p>  
</div>  
```  
  
5. Write a stylesheet at `view/ArticlePreview.css`  
You can also write `view/ArticlePreview.js` and `view/ArticlePreview/*.css|*.js` files to add more styling and scripting   
```php  
.ArticlePreview {  
    border:1px solid black;  
}  
```  
  
5. Write a route in your `deliver.php` file. Alternatively, make a public file `public/{slug}.php` and `echo $view` instead of `$response->content = $view`;  
```php  
<?php  
// in production, you might use a database & have some error handling  
$articles = [  
    'cat'=>[  
        'title'=>'Cats are great',  
        'description'=>'I\'ve always loved cats. I had two when I was a little kid. As a teen I had a dog & a cat. Loved them both dearly. I love dogs too.'  
    ],  
    'dog'=>[  
        'title'=>'fill me in',  
        'description'=>'fill me in'  
    ],  
];  
  
$lia->addRoute('/{article}/',  
    function($route, $response) use ($lia, $articles){  
        $slug = $route->param('article');  
        $view = $lia->view('ArticlePreview', $articles[$slug]);  
        $response->content = $view;  
    }  
);  
```  
  
6. Write a theme at `view/theme.php`:  
Call `$lia->setTheme('theme/name')` to change the theme.  
```php  
<!DOCTYPE html>  
<html>  
<head>  
<?=$this->getHeadHtml()?>  
</head>  
<body>  
<?=$content?>  
</body>  
</html>  
```  
  
## Lia\Simple  
A class for more easily setting up a Liaison instance with several integrations.   
Notes:  
- Sets `user_has_role` handler on phad to a function that returns `$this->user->has_role($role)` or `true` if `$this->user` is not set.  
  
  
## Older Documentation  
I believe the remaining docs are still accurate, but I have not reviewed them recently for accuracy or clarity.  
  
### Structure  
- `Lia` manages methods, addons, and properties  
- `Lia\Package` is a base class for packaging addons together  
- `Lia\Addon` is a base class for writing addons   
- `Lia\Package\Server` helps deliver websites by tying together main addons (public files, views, cache, autoloading, and more)  
- dir `code/class/Object/*` are objects used by built-in components  
- dir `code/class/Utility/*` are Utility classes  
- dir `view/theme` provides a default theme  
- dir `file/mime_type_map.php` is just that  
  
### Components  
Addons create all the features. `Lia\Package` calls upon several of these components  
- Autoloader: loads classes within given directories  
- Cache: cache key/value pairs & files  
- Error: Report errors to users  
- Hook: register & call hooks (very generic form of extensibility)  
- Redirect: Redirect requests  
- Resources:   
    - Add css & js files, urls, and/or code blocks to a request  
    - Sorting api to set order of resource files in compiled output  
    - Routes to compiled resource files  
    - Manages seo information (this should go in a new component)  
    - Outputs headHtml (must be called)  
    - Passes compiled files to cache component  
- ResourceSorter: A wrapper around the `Resources` sorting api, to make it easier  
- Router: Set pattern & static routes. Parse paramaters from urls. Process url for route target (package, callable, file)  
- Server: Handles request delivery  
    - Helps all the addons work together to respond to a url  
    - delivers static non-php files  
- View: Display re-usable scripts/templates  
  
### Directory Structure  
The `Package` decides the structure, so this can be changed. Default is:  
```  
App/  
    - config.json <- Package settings  
    - public/ <- Public files to be routed to. Ex: `public/contact.php` routes to `/contact/`  
    - view/ <- Views  
    - addon/ <- Addons (generally extending from \Lia\Addon)  
    - class/ <- Classes to autoload, PSR4 style. Will be converted to classmap style later  
    - cache/ <- Dir to store cache files. Only one cache dir is used (each app does not get its own)  
```  
  
### Other Stuff  
- Environment-dependent features are not built-in, but I recommend my [php/env](https://tluf.me/php/env)   
- set `$_SERVER['DO_NOT_RESPOND'] = true;` to stop `Simple->respond()` from doing anything.  
- `\Lia\Simple->get_all_sitemap_routes()` is a useful method to know   
- send `$_GET['theme'] = 'json'` to return a response as json with keys `content`, `scripts`, and `stylesheets`.