Liaison Development Status

Sep 2, 2024

v1.0 is abandoned. See README

Dec 16, 2023

ClassFinder.php from my utility library is getting --declaration-missing-- for its 3rd method ... idk why ... need to log that in code scrawl or lexer and/or fix it (not a big deal really). This is from code scrawl's class template.

Routing is basically done. Implemented new test. Need to work on ApplyTheme. Might want to change the signature for route handler callables ... cuz right now it literally just gets the route & the output of the callable is the response body, and it has no way to interact with the response object itself... so yeah need to think about that. That is in the Http\Responder.

FullDeliver is failing still because I haven't started on views ... I don't think I can really improve ApplyTheme until I have views implemented.

This is copied from Dec 12:

Next time:

  • Visit app/addon/Router.php and:
    • Done? improve onSingleHttpRoute.
    • DONE Develop onNoHttpRoute & onMultipleHttpRoutes.
    • DONE (subsequently implement NoRoute & ConflictingRoutes tests)
    • Improve onApplyTheme.
  • Probably View. Maybe CliExecution (but idc about cli rn)
  • How do I document configs? With an enum? (probably, and a scrawl extension)
  • I need to be thinking about documentation - do I need to develop templates or extensions? (honestly, its probably easiest to use a system command & write a script). Currently, the placeholder docsrc has a decent structure, but it's organized partially by Features, instead of by Things You Can Do. It might be fine though.

Dec 14, 2023

Sooner, rather than later, I should setup a full stack test. I know it will fail a lot throughout development, but I should make sure the bones work before I get too ahead of myself. It needs a deliver script and an app. Database should not be required.

This should also serve as my sample app.

I did that. It required a few fairly minor code updates. A home page that just prints html, with no theme, is delivering & its test is passing. I also added a FakeServer class to taeluf/tester so I don't have to start a php server.

-- So, I'm using the Http Router to carry the theme_name to a Response object, if the response's theme_name isn't set, then that theme_name is used to actually apply a theme. It starts in a config.json (router.default_theme). I don't love it.

It works though. I have config set to html_page in my default app. Now we get an exception because Lia::view() doesn't exist. There's still more to do on Router before I get into View. I'm still not sure how to handle/delegate NoRoute & ConflictingRoutes ... or what to do if I have multiple callables handling the routing methods & what if I want to stop execution / ignore the rest of the event handlers? idk if I can do that.

Okay. Next time, I continue working on the Router-related stuff. See the 'Next time:' notes below from Dec 12, 2023

Dec 12, 2023

Partially improved SingleHttpRoute (its not done!!!!). Added support for executable files (off by default). Added default configs to built-in app. Realized addons (like the router addon that loads public dirs) are only enabled if explicitly enabled by an app's configs. Now, the Router would still handle events (I think), but there wouldn't be any routers for it to do routing, without the config enabled. This config (for router) has been added to the main src/app/config.json

Added Responder class, so I can create method signature for PHP file routes to reference. Responder can't be overridden right now, but that should be added sometime.

Added PageNotFound() to Response class (to set 404 header). I might have done a couple other things.

Next time:

  • Visit app/addon/Router.php and:
    • Done? improve onSingleHttpRoute.
    • DONE Develop onNoHttpRoute & onMultipleHttpRoutes.
    • DONE (subsequently implement NoRoute & ConflictingRoutes tests)
    • Improve onApplyTheme.
  • Probably View. Maybe CliExecution (but idc about cli rn)
  • How do I document configs? With an enum? (probably, and a scrawl extension)
  • I need to be thinking about documentation - do I need to develop templates or extensions? (honestly, its probably easiest to use a system command & write a script). Currently, the placeholder docsrc has a decent structure, but it's organized partially by Features, instead of by Things You Can Do. It might be fine though.

Dec 11, 2023 Round 2

All my implemented tests are passing again (broke some during dev). Further, just general API cleanup. Basically all the ResponseInterface things receive a request, response, and (where reasonable) routes. Added ApplyTheme event & rudimentary implementation (except views aren't functional yet!). Renamed RequestStarted & RequestFinished to StartRequest & EndRequest (updated ResponseInterface & RouterAddon, plus similar-named AppInterface method). Added more configs to the app config.json (but those configs don't actually do anything ... yet ... i don't think...)

Next time:

  • Visit app/addon/Router.php and:
    • improve onSingleHttpRoute.
    • Develop onNoHttpRoute & onMultipleHttpRoutes.
    • Improve onApplyTheme.
    • (subsequently implement NoRoute & ConflictingRoutes tests)
  • Router might seriously be getting close to done. After that, we can work on CLI Execution, since it's a very very similar concept, OR we can work on View, which is a much more exciting idea.
  • I need to be thinking about documentation - do I need to develop templates or extensions? (honestly, its probably easiest to use a system command & write a script). Currently, the placeholder docsrc has a decent structure, but it's organized partially by Features, instead of by Things You Can Do. It might be fine though.

Dec 11, 2023

Everything in src/class/Http/ is very nice. Refactored, strongly typed, docblocked, sensible API. The Http Router still has some messy crazy code, but it's all internal protected methods so Idc rn. Those messy parsing algos may need attention at a later time, but it's not a priority.

The http router tests are all passing.

The Addon Router tests are started. I wrote a passing test for SingleRoute, but I'm not happy with how the ResponseInterface events work. The Router addon needs to work with a response object, NOT output a response directly.

Also, the HTTP response has a theme_name on it ... I think this is fine, but it might be confusing or difficult if you want to globally set the theme name from any random piece of code. So there should probably be some kind of global override.

Next time:

  • pt SingleRoute ... and look at the notes in that test method.
  • Work in app/addon/Router.php
  • Modify the ResponseInterface.php for new decisions.
  • Finish Router Addon tests ... they should stay very simple. The Http Router tests handle all the route parsing & stuff. The Router Addon tests just need to test the event-stuff, with the simplest routes & things. Some param testing stuff will be needed probably.

Nov 7, 2023

I implemented Router tests. All the pure router tests are now deleted from test/old-run and copied into run/Classes/Router.php old-run/Addon/Router.php & Router.Other.php both still exist, and contain some tests ... but those tests are not strictly of the Router utility object & instead test the router addon or something else ... idk. One is to test the caching of routes, which I'm not sure I ever really implemented.

Next time, I need to finish implementing the Router addon. I'm answering onSingleHttpRoute hook, but not multi-route or no-route. Also, there's some TODOs in onSingleHttpRoute that should be addressed.

Oct 16, 2023

The Router addon is now successfully delivering routes! Though this implementation is incomplete. See the Router addon, which contains several TODOs. I'm able to deliver the test site's home page, though.

There's still a lot of work to do, to make this all ... good. But, it's a functional proof of concept. I also renamed some things today. Also updated the taeluf/utils lib so the class finder actually works. And I moved all the old tests to the test/old-run dir. I haven't written any new tests yet. I may still use a lot of the old tests, but idk. Probably everything is going to break, so the old tests will be unlikely to be very helpful.

Oct 15, 2023

I've more fully scaffolded the lia/app/addon structure. I wrote src/app/addon/Router.php and it is SUCCESSFULLY setting up routes for my test app test/Server/site (just the index.php). It's also successfully hooking into the liaison event GetHttpResponse, and it is returning the route correctly.

I have work to do in Lia::deliver() because ... Router is returning ROUTEs, not RESPONSEs, and I think that's the right approach. But Lia::deliver() is expecting RESPONSEs from the GetHTTPResponse event.

I created src/app/class/Router.php to be the actualy router class, so that routing can be unit tested without any context or Liaison setup. the addon/Router.php uses this class/Router.php for the actual routing. addon/Router.php deals with liaison, essentially building a bridge between liaison/liaison apps and the class/Router.php that actually does the routing.

Next time:

  • Continue routing work. Get things setup so they actually function. I think we work in src/app/addon/Router.php, src/app/class/Router.php, and src/class/Lia.php (mainly deliver(). Will need to run phptest serverto start the server attest/Server`.

We MAY be at a point of creating unit tests for the class/Router.php. Also... I simply copy+pasted the old Lia\Obj\Request into Lia\HttpRequest. I might want to use the PSR interface for http request & response, so that my router is portable. (it's also tempting to say f' that, then make a light wrapper around my own interface that works with PSR ... that way PSR is not a required package, but a suggested one. I like reducing dependencies, but sometimes it's just silly nonsense so idk).

NOTE: As I work through this new system, I am very likely to change a lot of interfaces & to change how certain methods are named. And at some point, I'll need to write up good documentation. But I don't want to write docs until I mostly have everything working again.

Oct 9, 2023 (end of coding)

I wrote up the Addon class a bit. I've started working in Lia, App, and Addon to connect everything together & get it working. It's not really working right now. My brain is spent, so I don't really know where things are at. I'll need to run the test server, look at test/Server/deliver.php, and try to get test/Server/site/public/index.php to deliver. OH! I was trying to get src/app/addon/Router.php to actually work & setup routes. I moved all the pre-existing addons to src/app/addon.bak/.

So. Basically. Next time: run the test server. And get src/app/addon/Router.php to function with test/Server/site app.

October 9, 2023 (later)

How do I instantiate addons? I've said that App is responsible for setting up it's own Addons. That means I can enforce a particular constructor within the built-in app, but a different App using the AppInterface could instantiate Addons any way it wants to.

I also might want to change Lia\App to something like Lia\DirectoryApp, so that I can use Lia\App as the interface. But that's literally just a naming issue.

I want to remember to use AppInterface as the type & not the App class itself. I need to change many places where I've already typed as App and not AppInterface.

October 9, 2023

I worked on ... a lot. Moved some code to the Old dir. reorganized so the Liaison app is in an app dir. Started the new Lia class. Add Lia\Events, for App Callbacks on deliver(). Wrote deliver(), with event emitting. Need to do execute(). (do I want to log events? And/or add wildcard events?)

I don't love my Objects, but I also don't want to needlessly remake them from scratch. I think they all need docblocks and strict typing. Maybe some tweaks. I feel similarly about my Utility classes.

I haven't visted Addon.php. The bulk of App.php is done. The bulk of Lia.php, I think, is done too. Though I need to finish on methods. And same for AppInterface, though it definitely needs one or two more events.

Oh! And Lia needs caching too. And logging. These are all such crucial features that I think they should be first-class. Perhaps my built-in implementations can be protected, allowing them to be overwritten through addMethod(), but be the fallbacks if nobody has added the 'log' or 'cache' methods.

Oh ... and I want lia->dump(), buut probably as a trait this time;

I have a feeling all the addons can be re-worked to respect the structure I'm going for.

And I need have ... when an app defines an array of addons that are active for the app ... each of those addons needs to get called like ... onAppEnabled(\Lia\App $app). So Lia\Addon\Router->onAppEnabled($app) will be called anytime an app's config.json lists addons:{"lia:router": "public"}

October 8, 2023 - Version 1.0

See v1.0.md for planning...

branch v1.0 is for the planned Version 1! For Version 1, I want an App-Centric Liaison, and I don't want any "Simple" subclass for "simple" setups. Liaison setup should be as simple as adding apps and configs, and everything should be very easy to understand.

Package will be renamed to App, and the code will hopefully be cleaned up.

I will no longer have a ... Server package, instead opting for a different, more extensive of initialization.

I'll use src/ dir instead of code.

There will be a clear system of events, for built-in app stuff.

May 27, 2023

I started work on a new README which would come with a whole host of new, cleaned up, better organized documentation. It's sitting in the .docsrc dir. I should probably move it before running scrawl next time, so that it doesn't break my current (bad) docs.

May 23, 2023

Scrawl ext now has method doc generation & route doc generation. Both could be improved.

Apr 26, 2023

Worked on CodeScrawlExt to generate documentation of a liaison instance. Started the main doc page & nearly finished with the Methods template. See code/integration.

I'll need to document how to use this. Two configs are needed in a server generating liaison docs:

    "ScrawlExtensions": ["\\Lia\\Integration\\CodeScrawlExt"],
    "Lia.init_script": "deliver.php"

I want to refactor. The ast-getting code may be moved to CodeScrawl or to the Lexer. The Methods template contains some convenience code for getting certain ast information & that would be convenient to use elsewhere, and probably belongs in the lexer.

Next up is to finish the methods stuff, then do routes, addons, packages, etc. See Lia.md.php, which has a list of things I want to document.

Nov 12, 2022

I made test/ServerAdmin as a prototype of a web-based admin interface. It's quite rudimentary, but it is a good start.

Work in Progress (lia\Simple)

  • error page
    • DNOE displays /generic-error-page/
    • DONE need to cache the result to disk so it can be displayed on error
  • analytics
    • DONE analytics are enabled
    • DONE todo need a way to create the analytics table
    • DONE need to add the analytics phad view
  • other
    • add cli command to initialize the user database tables
    • add cli command to generate sitemaps
    • add cli command to regenerate all phad items
    • add cli command to clear the cache

themes

  • $lia->setTheme('name/of-theme');
  • $theme = new \Lia\Theme('name/of-theme');
  • $response->sendHeaders();
  • $theme->setContent($response->content);
  • $theme->display();
  • themes can be found in the view folder or theme folder
  • themes are available globally (if any app makes theme dir, those themes are shared)
  • theme is a subclass of view and has extra features (maybe)

How do I test this? Create a Lia\Simple instance initialize it? create an app with several themes in it set the theme add a route for / getResponse() for / check output of $response->content

WARNING

i did some work to cache routes, but decided not to finish the work but now i want to get rid of that code but maybe i want to keep it around and atm i don't care to work on this more so don't commit this in its current state Okay?

TODO

  • base url just doesn't work any more
  • re-enable config.json
  • testing with my user lib, v0.6 seems to be slower than v0.5 and i DONT UNDERSTAND
  • Improve varDelim. varDelim is an awful mechanism bc it applies globally to all routes
  • Compile list of views to reduce disk scanning

Changes required with this new version

  • addons & packages are no longer liaison objects
  • chained $package_or_addon->lia->method() must be used to call a global method, instead of calling it directly on the package or the addon.
  • addons MUST receive a \Lia\Package or null (instead of a liaison object)
  • addons MUST set public string $fqn = 'ns:package_name.addon_name'
  • remove all $lia->props[] uses
  • $lia->addons['key'] always points to an addon, never to a package. use $lia->packages['namespace:key'] for a package.
  • $lia->set('server.server.useTheme', false); now must be $lia->set('lia:server.server.useTheme') or $lia->set('server.useTheme') - it's either fully qualified name or JUST the addon name (no namespace)
  • new \Lia\Package($lia, 'ns:package_name', $dir), the ns:package_name. $dir is still optional, but $lia & the package name are now required.
    • though, name is optional for the server package... hmmm....
  • config.json inside a package dir is not currently loaded at all (this will be re-enabled as i figure out what i need from it)
  • $package->addon_name no longer works at all, must use $package->addons['addon_name'] or re-write the __get that will return the addon
  • $addon->init_lia() must be called to setup global methods & such. This is handled automatically by the Server package, though.
  • $addon->lia now points to a \Lia object and NOT it's parent/package object

Issues to fix with v0.6

  • I can't change the cache dir. calling $lia->set('cache.dir') can only be used after the Cache & Resource addons are initialized. But onPackageReady() calls scan() on the resource addon, seting up routes. onPackageReady() is called before i have access to the instantiated addon. This is a pervasive issue. Generally, i have no way to pass configurations to addons at time of their construction. I could use fqns, maybe... like lia->set('lia:server.cache.dir) then when lia:server.cache is added to $lia->addons() i dump all values from that fqn onto the cache addon. I was previously (in v0.5) doing this with references to $lia->props, which sucked. I could use $lia->addAddon() method (would require a change to addon class), then do this propagation during addAddon().

Notes

  • default name for server package is lia:server, and i really don't like that.
  • need to review & clean up some code & docs
  • i WILL need global properties on the liaison object itself.
  • i'm having issues with set() calls that didn't specify package, or didn't specify namespace, or were called BEFORE the addon is instantiated.

Apr 26, 2022

New Style:

  • Addons go in packages AND liaison
  • Packages go in liaison

Package no longer extends from Addon. I removed some things from Lia, Package, and Addon & made it all much simpler. I made addons require fqn, though name is still optional. I made $lia->get() & set() only work on addons, working both with fqn addon key & non-fqn addon keys

I also just ... removed some things that seemed complicated? idr what exactly.

  • removed $name from addon constructor, since it doesn't really make sense to make addon names configurable. (all addon usefulness is INSIDE the addon)

Updated Server package to remove complexities, ... commented out code that sets config.json to $package->props[] & i'll need to figure out what to do with those configs.

I updated types of $fqn and $name on server package & addons to string. All but 5 tests are failing now. I suspect the requirement of having an actual package instance will be a big cause of this.

In theory, many addons should be useable on their own. Like I don't think cache or view actually requires any features of package in order to function. But maybe they do? Idunno. I might remove the requirement that package be non-nullable.

I just made package (& lia) optional in addon. but the cache fails because it sets lia->methods ... so idunno what to do about that.

It might be nice to have separate initialization methods to setup liaison (that is separate from the constructor). Same goes for package? idk. That's a future problem.

Apr 21, 2022

There are some features I just want to remove from Liaison or otherwise significantly change. It's nice that $lia->get() & $lia->set() can reach into packages & into addons. It's also a waste of resources, generally speaking.

I used to have this really ... anything goes mindset about liaison, which just makes it hard to ... have the things I want go.

So we have:

  • Liaison/Lia: Central piece which gives you access to methods, properties, addons, and packages
  • Package: Initializes & holds a group of addons
  • Addon: actually does something

In Liaison:

  • addons
  • packages
  • props???
    • ... idk ...

Old Features

  • set (& get)
    • KEEP? set('package.addon.property', value)
    • DELETE set('array_key.property', value)
    • KEEP set('addon.property', value)
  • DELETE $lia->props['key']['subkey'] ...
  • DELETE addon is a lia instance
  • DELETE package is a lia instance
  • calling methods
    • DELETE $addon->global_method()
    • KEEP $lia->global_method()
    • DELETE $this->methods[key] = ... (on an addon) ... change to $this->lia->methods[key]

I'm having inconsistency issues ...

  • lia:package.addon.prop = value
  • package.addon.prop = value
  • addon.prop = value
  • package.prop = value

I'm gonna just have to drop some of the features.

I think the biggest issue I'm going to have with this refactor is figuring out which tests are better for deleting. I think many of my tests will just need to be deleted because they're testing internal functionality that was never truly needed.

I COULD create some wrappers & stuff to make the current api continue working exactly as it is.

I'm going ot have issue copying config array to its addons, possibly though.

TODO (v0.6)

  • review this 600+ line file & relegate most stuff into a history.md file or just delete it. Really, most of it need not be read, such as the day-to-day updates that are written lengthily.
  • benchmark diff between an object calling another object implementing interface vs an object calling a method in an array through __call() ... if the interfaced approach is significantly faster, then perhaps Liaison is just a complete bust & i should abandon it (though i'm not likely going to)

This new version

v0.5 is really slow compared to v0.3. On one of my sites, testing 11 pages went from about 350ms to about 550ms on my localhost. That's ... terrible. 550 / 11 = 50ms per request from 350 / 11 = ~34.8ms. 50ms server response time is awful. I'd like it to be less than 20ms, esepecially with all the overhead of https + script & css files + being on shared hosting.

There is also some quality-of-life stuff i'd like to do

Performance

I believe the main reasons for this slowness are:

  1. by-reference properties
  2. multi-dim properties array
  3. package & addon are subclasses of lia (and the implementation surrounding this is unnecessarily complex)

My solutions are to:

  • rewrite get() to retrieve an addon & then return a property of the addon
    • maybe return this by-reference??
  • rewrite set() to retrieve an addon & then set the property to the addon
  • rewrite append() basically same way as set()
  • I don't know what to do about default()
    • i COULD still have a props array that just stores namespace:dot.property=>value instead of using nested arrays with by-reference
  • rewrite dump() to retrieve all public properties from all addons manually & ... well dump doesn't need to be performant at all bc it is very limited debugging purposes
  • remove copy() method

Polish / Ease of use

  • setup() method: I might add a separate setup() method for addons & packages that is called after the constructor so that configuration can be done after instantiation, before initializing everything
  • ... idk ... there's other things.

Other Notes

  • extending from Addon should never be required to integrate a method or hook with liaison
  • The Addon class should have some nice convenience for setting up addons:
    • shared methods
    • add self to liaison->addons[]
    • shared properties
    • hooks
    • built-in hooks for like onCreated, onPackageReady, onServerReady
  • maybe hooks should be a part of liaison's core

What even is the purpose of liaison?

  1. Create packages for websites that are easily shared & integrated into other sites
  2. Extremely easy on-boarding
  3. Integrate with non-liaison websystems

Benchmarking

phptest -class Benchmark with 100,000 loops yields:

  • InterfaceObjectUsingCall 34.4930ms
    • almost all of the slowdown appears to be due to __call() routing rather than due to using callabls. WOW
  • InterfaceObject 12.4068ms
  • ArrayMethods 36.6769ms
  • ArrayMethodsWithFunctions 32.2399ms
  • InstantiateInterfaceObject 8.9591ms
  • InstantiateArrayMethods 18.4569ms
  • InstantiateArrayMethodsWithFunctions 22.5091ms

Takeway: The approach to code sharing used in Liaison is MORE THAN twice as slow as using the standard approach that uses objects and interfaces ... it's actually THREE TIMES FASTER calling the dependency object directly than it is to use __call() to call the dependency object.

The reason i use the methods array is ... it's just easier a lot of the time. I don't have to write a bunch of interfaces or implement a class. I can just write a method & use that directly. It's also really easy to switch out one method for another. This makes liaison super customizable.

An additional problem with this is: interfaces make it really easy to properly document what methods do & how they are used. This array-methods approach does NOT make it easy to communicate what the method must do.

Evaluation of what it will take to make these changes

To clarify, there are TWO stages of changes. The first is changing the internal implementation of sharing. The second is to add polish. Here, i am evaluating the internal implementation changes. The polish would come after & I am not evaluating that right now.

  • re-implement addon base class (1-2 hours?)
  • delete some tests that explicitly test current liaison features (30 minutes)
  • ideally these internal changes will not cause any breakage in tests
  • re-implement liaison get/set (30-60 minutes)
  • constructor changes in every single addon (1-3 hours)
  • new package base class? & update constructors (1-2 hours)
  • new tests for new internal implementation (1-2 hours)
  • In all my foss libs and websites using liaison, create a new branch & bump the liaison version (2-3 hours)
    • maybe write a simple bin script that creates a new branch & bumps the version so i can do it automatically, but that would probably be a waste of my time
  • Unforseen stuff (4-6 hours)
    • potential changes in liaison libraries

old notes (from v0.5)

polish / niceties / fixes

  • make $package available in a view (being the same package that the view came from)
  • make new packages not override lia:server.package
  • having addon->name not match addon->fqn causes it not to be added to liasion...
  • Redirect addon directly calls header() instead of using a hook to modify the response before headers are sent by the server addon.
  • Ex: POST /user/register redirects to /user/register/ which breaks the POST. Maybe allow POST to work with or without trailing slash?

Apr 8, 2022

  • added dump() method
  • server package now adds itself to fqn_addons: This is likely to cause problems as is uses $this->fqn in the constructor. So if you instantiate two server packages, the 2nd server package will overwrite ... this is bad. But it's how it is for now & it does not cause a breaking change.
  • add a default cache dir so it works out of the box
  • recently added MinimalServer test for documentation purposes

TODO

  • add no-cache header to most responses
  • 3 tests are failing ... fix them!
  • my immediate cache invalidation is not working (at least on reedybear.com), so i have to manually delete the cache dir for every css change. fix this!
  • Write docs for:
    • create a new app
    • add a css or js file to the request
    • .... stuff

Versions (Dec 8, 2021)

v0.5 (with minor changes) will likely become an official beta. Then after some usage, it'll become v1.0. Probably by June, 2022, but who knows?

  • v0.5: Uses Addons instead of Compos. Much more direct access to methods, properties & major overhaul. Internally uses a lot of memory pointers. All addons ARE liaison instances. Packages are too. Lots of other changes. Dec 8, 2021: Under development, nearly ready
  • v0.4: abandoned ... WAS intended to do what v0.5 is while providing backward-compatability to v0.3 setups ...
  • v0.3: abandoned. Uses Compos (Components). A major version ... used ->api('namespace:key', $arg1, $arg2) all over the place ... abandoned dec 8, 2021

Idea (March 25, 2022)

Liaison is confusing because there is so much magic. Liaison holds packages. Packages hold addons. Addons communicate with each other through liaison & through their packages.

There are also settings/configs that can be set through liaison or on an addon directly.

There are global methods which can be directly called on liaison.

There are other things that ought to be inspectable, too - views, routes, resources, idk what else

So the idea is to add debugging features. First, a view (and an associated public route) to display inspection information for all of these.

An integration with code scrawl to inspect an addon class would be really cool. /liaison/debug/class/?name=whatever

And then maybe having certain inspection views display on errors ... like if there's no routes, that could show the inspection for routes.

Exceptions could also be handled nicer. I mean ... every exception could dump liaison debug info, if i want! (seems overkill)

There's also some really weird things, like ... since you don't instantiate addons directly, certain configs have to be instantiated before initializing their package. Idk if that's fixable or properly inspectable ...

I REALLY need to document how to write a custom router & return a route list (need an easy way to make routes for this purpose)

I also need a way to get PACKAGES that don't have any addons ...

PROBLEM (march 23, 2022)

I have to set server.cache.dir BEFORE initializing the main server package:

$lia->set('server.cache.dir', $server_dir.'/cache/');
$server = new \Lia\Package\Server($lia, 'server', $server_dir);

Otherwise, compiled resource files do not deliver!!!

Jan 25, 2022: New stuff

  • added code/class/Router/FastFileRouter.php with an extremely simple and fast routing mechanism for files in a directory
  • added code/file/mime_types/*.txt where there's a file for every extension & the file only contains the mimetype
  • FastRoute was added to the test server deliver script

... this could be used in place of the current (awful) StaticFile implementation

Known Issues (jan 4, 2022)

  • a dynamic portion of a url cannot contain - by default. this is BAD ... slugs contain hyphens, silly

Problems (jan 16)

  • must explicitly add views for a package like: ... not true ... the dir just needs to be /view/ & this is not clear
    • $view = $lia->addon('lia:server.view'); $view->addDir($site->dir.'/views/', $site);
  • $lia->set('server.cache.dir', $dir) must be called BEFORE the main server package is setup
  • use \Lia\Package\Server for most setups ... but it's not obvious

Jan 15, 2022

  • WARNING: when cache dir is not set, now an exception is thrown, instead of just returning false ... somewhere in the cache addon class ... several tests are failing ... I should address this. I might have to roll back. idk
  • i attempted toa dd global args to view, but I commented out the code & just didn't finish it.

Dec 17, 2021

  • review dec 16 TODOs & CONSIDERs
  • add header('Cache: no-cache') to all requests that are NOT static-file requests

Dec 16, 2021

  • DONE view/theme priority (new views always overwrite null-namespace)

  • DONE for view/theme.php also add view/theme/*.css & theme/*.js

  • DONE make $lia->server access $lia->addons['server'] & $lia->server->cache would access $lia->addons['server']->addons['cache']

  • DONE: add config.json file to app dir for server-package

    • DONE: Test it
  • DONE: Add fqn for addons, like lia:server.cache that is accessible from ALL liaison objects by that string. Maybe $lia->addon('lia:sever.cache')...

  • DONE: fix confusion around addon->addon_name & addon->name;

    • removed addon_name and only using addon->name now
  • DONE??: fix _lia scoping. The lia object passed to views is NOT the root object.

    • i couldn't reproduce the bug with my test. The bug came from taeluf.com
  • TODO: Add a logging feature! Just to log messages to a file.

  • TODO?? debug feature to help inspect addons, properties, and more... ?

  • TODO: $this->depend('lia:server.cache') feature (or $this->depend(\Lia\Addon\Cache)?)

  • TODO: review disabled tests & get them passing or remove them

  • TODO: Add robust setup-events for packages/addons

    • all addons within package are loaded
    • all other packages are loaded
    • everything is ready
  • TODO: Add global objects ... example: mdblog->blog would fit well at lia->blog

  • CONSIDER: Does server package REALLY need the default server package to be added in order to function at all?

  • CONSIDER: Should fqn_addons[ns:package.addon-name] also have null-ns, like views do? (leaning yes, but let's wait til I need it)

  • CONSIDER: Removing name from constructor for addons, package, lia. Subclasses generally don't need them ... but then again the server package needs it.

  • CONSIDER: Should package->name be overwritten by config.json[name]?

Dec 15, 2021

  • add onPackageReady() to addons, called by \Lia\Package->ready(), which is NOT called during the package constructor, but IS called during the Server package constructor
  • I was having issues with _lia scoping ... (maybe see mdblog? idr)
  • I want addons to be accessible via __get() & __set()
  • Server package should default it's name to server
  • Should hook become part of liaison proper? (i lean yes) also maybe error & cache? No, cache is thicc. Error logging, maybe? Maybe

Dec 14, 2021

  • TODO: Add a logging feature! Just to log messages to a file.

Dec 10, 2021, end of day

  • I was last working in MdBlog addon ... go look at that
  • Review Server PACKAGE and ensure some simplicity
    • should the server ADDON be a package? (leaning no)
  • need a way to have addons always be stored in their namespace-form, like lia:server.hook or lia:server.seo, etc... So I can have a guaranteed way to reference an addon. Probably just use those simple string keys. Could use an addon() function to retrieve them from current data structuer?
  • i'm not in love with how I set up addons ... idunno ...
  • name/addon_name is still a mess & just needs some thinking & review & updating

Dec 7, 2021

Main:

  • I was working on the server integration test. It is failing, only because the test needs updated. Parts of getting this working:
    • Wrote code/Server.php (server PACKAGE)
    • add addDir() to view addon
    • add dir_to_patterns() to router addon
    • messed with the addon nesting in package (maybe in lia too?)
    • fixed the built in theme view & error/header view
    • wrote test/Server/deliver.php
    • wrote test/run/Server (needs corrected)

Issues:

  • Package->name & package->addon_name & Package::__construct($lia, $package_name) ... confusion, uncertainty, duplication ... the nesting of ->addons is ... idk.
  • need unit test in router for dir-to-patterns & it's helper function(s)
  • PackageAddonIntegration test is failing. Several Liaison tests are still disabled.
  • the ExceptionCatcher is ... bad
    • in set_error_handler, i need to call ExceptionCatcher::throw(new ErrorException(...)), instead of re-throwing there
  • need to test view conflicts

Dec 2, 2021

  • Error header message test is passing because I added an explicit print to the test theme view. I don't know if this is how I want it to work. I need to review this with a fresh mind. Also, the display is checking $this->lia->addons['error']->headerMessage which ... is probably the wrong way to do things.

Dec 1, 2021

  • Error Addon: Started on it ... one test passing ... needs some TLC to get things sorted

TODO

  • Error addon:
    • Review & Update
  • Server addon:
    • test the hooks
    • test deliver() method?
    • general refactor so it just ... makes more sense
  • implement Resource addon tests DeliverJs & DeliverCss after Server is re-done
  • Check Server integration for:
    • Resources
    • ResourceSorter
    • Autoload
  • completely get rid of the response & request objects (& maybe Route object)
    • refactor router
    • refactor server
    • refactor resources

Nov 30, 2021

  • Resources addon changes:
    • Remove forceRecompile config (only using useCache)
    • recompileJsAfter & css is removed (these weren't implemented anyway!)
    • refactor ??

Nov 29, 2021

  • refactor seo addon
  • refactor (slightly) & clean up (massively) and document router addon. Add new (simpler) router addon tests. Separate old router tests into RouterOther tests (bc they are sloppy & I don't want to refactor them).

Nov 26, 2021

I feel a bit uneasy about the work I did today. Everything is working - tests are passing ... but I just feel like some things are undone. I think I want to review, at least, the router addon & look for any api() calls, at the very least.

I also may want to add additional tests - like testing that seo & router work with package & work with liaison -> package -> addons setup

  • Seo Addon
    • converted to addon
    • tests passing (fixed one old one)
    • no exception catcher
  • Router Addon
    • all tests passing (including ones that I had failing previously)
    • no exception catcher ...
    • converted to addon
  • Cache Addon
    • added an exception catcher case

Nov 24, 2021

  • View addon
    • all tests passing
    • added to exception catcher
    • docs written (docblocks)

Nov 23, 2021

NEXT I have some confusion about how to handle scanning?? Or something. Idk. It doesn't matter.

Just working through additional component's one at a time, turning them into addons. Let's keep most changes simple so I can get through it all asap & start using the new system in prod & adding features

DONE

  • add hook handling to exception catcher
  • add scan() method to liaison
  • add prefix integration to hook
  • add hook to package test
  • move GlobalParam to old folder (likely will not use)
  • add prefix/scan test class
  • add OldTests test class

Nov 18, 2021

5:00pm: package integration test written. cache & autoloader both working nicely with it. Need to work on next addon, then update package integration to include it.

Latest: I'm working on prefixes inside the hook addon class code/addon/Hook.php

  • IDEA: Scanner should be an addon & depends feature will make it so easy to use

    • NO. Scanner is fundamental to Liaison.
  • LATER: create a liaison test that creates multiple packages so that they work together.

  • LATER: Add prefix scanning for Hook after implementing it.

  • LATER: (i disabled the tests) The cache class & tests are all passing. AddMethods & AddDotMethods are still failing on the Liaison test. I think I removed nesting of methods on Monday?? This will need addressed, but I want to focus on the addons and making sure new Lia provides what they need, instead of getting caught up on what Lia "should" do. So I'll revisit this decision later after I've written more tests & used Lia more

  • LATER: (i disabled the tests) Package tests AddAddonsPackageAddons & AddAddonsPackage are failing because I used to have $lia->addons['ns']['package'] = $package, but I removed it ... because it caused a test to fail & it just didn't FEEL right having it there. But now I see / remember why it was. I don't know what I prefer. Maybe add a packages property to Lia to hold packages. Maybe keep the package in the addons list. I don't know. I'll write more tests, see what feels right in practice & re-visit this decision. I will not fix the tests until then.

  • NOW? I want to start a new Package class who's entire job is to setup addons & invoke them. I want a base package class for use on any Liaison setup, then a Server package that ties together all the built-in components into a web-server (which is kind of what the old Package does).

  • DONE I want to rename configs to props because ... I think it is more intuitive

Nov 15th, 2021

Success! I re-wrote the autoloader & autoloader tests. I started rewriting cache & its tests. Cache is successfull for everything I've re-implemented. Notes:

  • main cache: set() get(), write(), read()
    • this is a new feature to set key=>value pairs
    • it uses the config stack that exists from liaison & essentially writes $lia->configs['cache'] to disk as php
  • classic file cache: I have not touched it yet & its tests are currently failing

BIG new thing

I have properties declared on both Autoloader & Cache, which each of them use directly. In their constructors, each addon is setting those properties to $addon->prop_name = &$this->configs['prop_name']. I REALLY like this so far, bc it makes a tree of all the values that are set & need to be set. I have no idea about the performance ... But I imagine it's not too bad.

Next

  • finish updating the cache tests & cache class. I do want to keep the ability to cache files. The code needs re-factored & other than that ... I think it's basically fine. I want a cache_file method on liaison as well.

How to think about Liaison

Liaison is a singular object that holds all shared information & methods & addons Addons are objects that provide specific functionality. Packages are objects that set up addons on Liaison

Does Liaison officially recognize packages? I think yes ... I think so Do Addons officially recognize packages? Not normally ... I don't think so Do Packages officially recognize addons? Yes, I think so. Kinda have to

So the entire thing exists to server addons. Addons need to be able to communicate with other addons. Packages helps set things up. Liaison does the actual communication. User-land code ALSO needs to be able to communicate with addons.

Repeat:

  • Addons provide functionality and need to communicate with (and depend upon) other addons
  • Packages provide utility that makes it easier to set up multiple addons
  • Liaison is the object which provides communication featurse between addons
  • User-land code uses Packages to setup addons & uses Liaison to access those addons.

Note:

  • Addons are simply a way of packaging features together. Ex: Cache addon has a suite of functions to handle caching. Alternative Ex: Several cache functions exist & user-land code just registers them to Liaison, no addon needed. This is NOT the intent, but it's how it ought to work.

So, how do I provide global access to methods & properties?

  • $lia->method_name(); calls whatever method was registered
  • $lia->methods[method_name]();
  • $lia->prop_name gets whatever value is registered at $lia->props[prop_name]
  • $lia->props[prop_name]

How do I access packages & addons?

  • $lia->addons['name'] gets whatever addon is registered
  • $lia->packages['name'] gets whatever package is registered
  • $lia->packages['name']->addons['name'] gets an addon from a package

How do I get namespace access to methods and properties?

  • $lia->get('ns.name.prop') gets $lia->packages['ns']->addons['name']->prop where ->prop is a real property on the addon?

How does an Autoloader addon access a cache addon?

  • $this->lia->cache() to call the global cache method
  • $this->lia->call('pkg.addon.cache') to call a specific addon's cache method
  • $this->lia->packages['pkg']->addons['addon']->cache() to call the specific addon's cache method
  • shorthand: $this->lia->addons['cache']->cache() to get the global cache object & call its method

Features

Liaison object has:

  • global methods (set by anyone, normally by addons)
  • global objects (set by anyone, normally by addons or packages)
  • global properties (set by anyone, normally by addons or packages)
  • namespaced methods
  • namespaced objects
  • namespaced properties

So if I have an autoloader class that needs configs & cache, it could access those via: $lia->configs->methods(); or by $lia->config_method where the config objects' method has been explicitly set to liaison

What are my actual needs?

  • one object from which I can access:
    • all packages
    • all addons
    • all root-set properties
    • all root-set methods
  • Does it need to support:
    • $lia->get('addon.propname')?
    • $lia->call('addon.methodname')? Is this good enough:
    • $lia->addons['name']->method();
    • $lia->packages['name']->addons['name']->method();
    • $lia->addons['name']->property
    • $lia->packages['name']->addons['name']->property Can i THEN add convenience methods?
    • $lia->set('pkg.addn.property', 'value');
      • calls $lia->packages['pkg']->addons['addn']->property = value; What am i doing currently?
    • $lia->set('pkg.addn.property', 'value');
      • $lia->configs['pkg]['addn']['property'] = $value;
      • $package->configs === $lia->configs['package']
      • $lia->addons['pkg']->addons['addn']->property = $value;
    • $lia->call('pkg.addn.method',$arg1,$arg2)
      • $lia->methods['pkg']['addn']'method'
      • (would be) $lia->addons['pkg']->addons['addn']->method($arg1,$arg2);

v0.5

v0.5 is like v0.4 except I'm abandoning the entire backwar-compatability idea. I'm going to re-code tests & addons using the new setup instead of trying to make it all fit seamlessly with the old setup.

So v0.4 branch is dead. It will not be developed further, unless I change my mind after working on v0.5 a bit.

Next:

Think about my approach to this refactor. I've spent several hours and a lot of energy making everything backward compatible. It's kind of a nightmare. So I'm not entirely sure how I want to go about things. I may go away from the "constant BC" route & just dive full-in. I really don't want everything to break at once, because fixing THAT will be a nightmare. I WANT to go through pieces of this library one at a time, switching things out as I need. Fuck. I might rewrite some tests too. Idunno. Its the end of the day and it all sounds terrible lol. Need to re-asses with a fresh mind.

I'm also having a hard time understanding how the backward compatability actually benefits me. I think it's so I can switch a site to the newest liaison & have it keep working ... but as long as it's using the BC liaison object and the old components ... I just have to keep both around! Either way, I'm glad the original Liaison object is done for. So freaking glad

  • meh ... "Function name must be a string": Running into this issue because there is a null value at the location a method should exist. Why/how does that null value happen? Can I catch the error with my fancy exception handler?
  • Start turning the components into Addons, one at a time. They will subclass liaison. It will be interesting.

Notes:

  • package is a subclass of addon & addon a subclass of Liaison, but they have significantly different needs, so the constructors don't call parent::constructors. Instead they call $this->copy() which should be a bit more consistent in how it operates between liaison subclasses.
    • perhaps package should not be a subclass of addon?

State

  • DONE setup by-ref properties
  • DONE add methods
  • DONE add api()
  • DONE add get/set
  • DONE test all of the above
  • DONE add addons management
  • DONE add ->_lia for root liaison object & ->lia for parent liaison object
  • DONE start ExceptionCatcher
  • DONE get package tests passing (see Other/OneOffTests.php)
  • DONE Get the Scanner tests passing
    • There are two scanner tests that are NOT passing. Focus on those??
    • Setup the new scanner trait & use it on Lia (see notes below)
  • DONE Start passing individual component tests (one at a time. take it easy. take it slow.)

Re-testing with LiaBC class

  • DONE some tests are stalling due to re-addition of lia:config.default api (see LiaBC where this api is added to liaison)
    • FIXED OneOffTests->ComponentsAndRequestLifecycle
      • done There is an issue with cacheFile() getting a null dir ... but only for the css resources, not the js
      • done spawns from getHeadHtml() ... it is a MESSSSSS
    • FIXED Redirect->GoTo
    • FIXED Error->ErrorHeader
    • FIXED Error->ErrorPage
  • FIXED OneOffTests kind of seem like a nightmare ... uhh idunno
  • WILL NOT FIX Exceptions test are failing & I don't think I'm going to fix it.
  • DONE all the component tests are passing, except for the ones that use a non-bare liaison ... so the only issue now is getting package to work with LiaBC.
  • DONE Other/LiaisonApi.php works. I disabled a couple mediator tests because I don't use mediators ANYWHERE, so it's not worth fixing
  • DONE Other/OneOffTests.php: These are significant integration tets, so these need to go later.
  • DONE ScannerTrait (test/CompoTrait/Scanner.php): The old implementation is SUCH a mess. The whole thing is terrible. I think it may be worth rewriting the scanner from scratch with almost no features. It should be VERY simple. The old version uses $lia->api(...) to call the prefix handler method... I want to have methods that accept callables for particular purposes (like registering an event). When a prefixed-method is found, it should be passed to that setup-function (event registration, etc).
    • I made a new scanner trait with minimal modification to sustain backward compatability.

ScannerTrait: New Design

What does it need to do?

  • have a list of prefixes
  • build an array of methods that have those prefixes
  • pass the methods ([$this, 'method']) to the functions responsible for setting up those prefixes

How do I do it?

  • public array $prefixes = ['on'=>[$event, 'prefix_setup']];
  • get_methods($this) ... substr($method_name,0,$prefix_len)==$prefix ... $methods = [$prefix=>[list_of_methods_on_this_object]]
  • foreach $methods as $prefix=>$method_name: $this->prefixes[$prefix]([$this, $method_name])
    • usually $this->prefixes will refer to the root liaison's array of prefixes (because of $lia->copy()). BUT any lia object (addons/packages, etc) could have it's own array of prefixes that is not referencing the root.

v0.4 Goals

Approaches to Liaising

  • by-reference properties
  • via method calls on the Addon class that remap to Liaison methods

Step 1: Prototyping by-ref

I want to prototype a new system for having addons call liaison methods. I'm tired of $liaison->whatever... & want this to be more streamlined. I want to try copying liaison properties by reference to make it easier. Example:

$lia = new \Liaison();
$package = new \Lia\Package($lia);
    //$package->__construct() will call
        // $this->copy($lia)
            // $this->configs = &$lia->configs;
        // $this->configs['namespace'] = []; 
        // $this->configs = &$this->configs['namespace'];
$addon = new \Lia\Addon($package);
    // $addon->__construct() will do:
        // $this->copy($package) (where packge is a liaison instance)
            // $this->configs = &$package->configs;
        // $this->configs['addon_name'] = [];
        $this->configs = &$this->configs['addon_name'];

So rather than modifying anything, I think I should start with a new class & just try out these basics.

Major Changes Overview

  • Change "compo" to "addon"
  • Add a system for addons to call liaison via $this->liaison_method()
    • MAYBE make addons into instances of liaison & use by-ref properties
  • turn Package into an addon
  • MAYBE Move 'event's onto Liaison, but call them hooks.
  • MAYBE add dependency hooks onto Liaison proper
  • MAYBE add scanning onto Liaison proper

Extended notes / thoughts

Rename compo to addon. Add methods to make them work more friendly with liaison. Like get, set, add method, add prefix. Basically remap all the core liaison functions to auto-include ... Namespace & name.

Turn package into an addon. It will all be much easier to understand then. Then do i add addons to liaison? Does liaison auto-setup an addon? No. The addon sets itself up. This means different types of addons csn be made. Most of mine will be subclasses.

So then package is an addon & basically it sets up dependent addons for certain sub-directories of a dir given to it.

Liaison should have it's own property for addons. A key/val array. & a method to add an addon. The main addon class will call that in its constructor.

Package is an addon but it will contain other addons & provide features for easily setting up addons. Package will probably also host it's own array of addons. But then do addons IN the package have to also call the package's method?

Maybe liaison can have hooks on its get/set methods, then package can just copy when addons are added. This is a performance hit through constant branch checking. I think it would be far more efficient to use a liaison subclass that routes all the methods liaison has, allowing the package to be a liaison instance & the addons it initializes to use it (the package addon) as liaison.

So an addon then would do: $lia->addAddon($this, get_class($this)); which invokes $package's $lia->addAddon($addon, $namespace.':'.$addon_name); call which invokes actual $liaison & does $liaison->addons[$addon_name] = $addon; this all.happens during the addon's constructor. In this chain, package can also maintain it's own addon array.

Should events go on liaison? No i don't think so. Just prefixes, methods, and apis.

Then in my addon's constructor, it will do $this->addMethod('ownMethodName'). $addon->addMethod($methodNameForLiaison, $ownMethodName=(defaults to arg1)), which will call package's addMethod() which roures directly to liaison.

Shooot. What if they all access their own properties directly without any redirects by referencing memory addresses?

So package would do $lia->configs['namespace'] = [];. Then do this.configs = &lia.configs.'namespace'; so the package's configs directly reference the variable held in liaison. Do the same for addons?

Maybe add a copy method to liaison that takes in a liaison object & does the by-ref thing. Package maybe would override copy, call the parent, then do it's own setup. Or just call copy, then do its set up.

Now that package is setup by-ref, it will construct the addons & pass itself to the addon. So when the addon does this.methods[name] = this, it's setting it to package's ref of methods prop. (Errr ... Maybe make methods completely flat, but have an api array that is nested.

So then ... Views. Do i just assert that onto liaison? Like lia.views[name] will work? Perhaps i put it in the namespaced configs & in the flat.

Make a PackageAddon class that responds to hooks in the package. Hooks could be a very simple trait ... Idunno. Maybe hooks/events belong on liaison. ...

Server requires hooks. Some addons can't do their setup until dependent addons have already been setup, which requires them to hook on the dependents or ... Or on the package. I like hooking on the dependents. That means each depended upon addon would have to execute the hook when it was done setting up.

It would make sense for certain addons to broadcast when they are ready. The server addon might respond to the public dir addon broadcasting that it has set up a public dir. And that it's about to. Maybe the server addon could stop it from scanning a public dir if a cache of the routes is recent enough. It makes sense for the server to be responsible for state management while a separate addon is responsibke for scanning & setting up a public directory. Tbh, package is probably where public dir setup belongs. I could add it to router though. Idunno. I feel like routers responsibility is already complex enough that i don't want to add things to it.

Latest

  • updated Route object to is_string($target) && is_file($target), so isFile() doesn't give error when it's non-string target
  • added basic url normalization to the server component. it needs refactored.

Current

  • attempted to add - & : to valid chars to separate dynamic values in a url. But a couple tests are failing, Idk why & it needs to be troubleshot
  • add https://github.com/matthiasmullie/minify as optional dependency
    • Tried cerdic/css-tidy and had problems

v0.3-candidate Plans

  • default() should be able to receive an array to set multiple defaults at once
  • Delete all exceptions except for my base exception

Get/set

Can I do a readonly feature? I may be able to condense some of my simple components into a single one since there's no more data structure management.

  • add get & set to Liaison Proper, doing away with Config component
  • Use $lia->set() & get to store packages, compos, and basically anything that's currently being managed by a single component
    • Router still needs its own internal data structure
  • add arget() and arset() for getting/setting to an array.
    • arset('namespace:some.key', 'keyInTheArray', 'valueForKeyInTheArray')
    • arget('namespace:some.key', 'keyInTheArray') returns valueForKeyInTheArray
    • get(namespace:some.key) returns the array containing keyInTheArray => valueForKeyInTheArray

Events

Since Liaison's goal is to, well, Liaise... I think it should do events, too. It can already to 1-to-1 method calls & I'm adding 1-to-1 property setting / getting. So it would make sense to be able to emit an event. Here's the implementation idea:

  • $lia->emit('namespace:Event.Name', arg1, arg2, arg3)
    • Internally, it creates new Event($lia, arg1, arg2, arg3). then $event->emit()
      • & this way, the event gets listeners from Liaison, then goes through all of them. & each events listener gets an instance of the event object, plus all the passed args. Any values can be set directly to the event object
    • You can also directly do new Event()... & emit it yourself, without the helper method

Code Work

Next

  • add error reporting when a package directory does not exist.
  • (current) Error Component
    • Working on error_goto.
      • Need an Error Route (maybe as a public file, idk. Might make it configurable)
      • Need to setup test. I started the test, but can't really wrap my head around how to do it.
  • Improve error views (header & page)
  • Middleware & Routing
    • Add a 'handleRequest()' method that allows any component to handle a request
    • How does the web-developer decide who's handling requests? The middleware approach might be best. addMiddleWare() & removeMiddleWare() could be used by the Server component... It might use a couple if statements to determine which middlewares to add. But the flow would be the same regardless.
  • Caching:
    • Routes from public files (Router)
    • Classmap of a package (autoloader)
  • Cleaner Route interface/object
  • Cleaner View interface/object

Latest

  • Refactored Scanner to have only two methods & be more efficient. Updated all tests so they're now passing
  • Router component can have additional routers added to it for custom routing.
  • Add append method to Config component
  • Renamed package setup functions to setup_the_thing & added setup() function to move setup out of the constructor.
  • Add namespaces to the view component
  • Modify package to use namespace when calling view component
  • Remove 'lia.packages'. This was a mistype & should have been 'lia.package' all along
  • Convert package list to use namespace instead of name
  • Separate SEO methods/api from Resource compo
  • namespaced apis. converted api('lia.action', 'handler',...$args) to api('lia:action.handler', ...$args)
  • namespaced configs with consistent naming like lia:componame.configName.
  • Ensure there is a default() call for every config

Documentation work

Next

  • Review property docblocks in Liaison class. They don't match with the api namespaces refactor.
  • Continue Docblocking as marked below (in class/Objects/)
  • Don't forget the Objects/ViewCallable.php: Need to review this when I'm doing the view component
  • Write Markdown documentation AFTER docblocking is done
    • Write examples as tests & import

Latest

  • Docblocked everything except compos
  • Updated docblocks on Liaison methods to match api namespace refactor

Things that need to be in markdown documentation

  • Specify your package's namespace in config.json. This is separate from name.
  • List of available configs
  • Full api reference for code/class and code/core
  • Featured API Reference? For only listing featured methods & classes
  • TODO reference file (grouped by file name in a single markdown file)
  • All events & the paramaters they pass

Docblocking status

  • Liaison.php
    • Mostly good
    • api methods (addApi, addApiMethod, etc...) are not well documented. Since I want to remove $handler, I'll probably wait on that.
    • Some things are a little under-documented, but the method-signature and the short function bodies... makes it not that big a deal
    • Not @tagged very well
  • Compo.php
    • Well documented
    • @featured & @tag pretty well
  • Package.php
    • Pretty well documented
    • Not sure about my @tags. There are @tag setup & @featured. I think there could be more organization there.
  • CompoTrait/
    • Scanner.php
      • Docs pretty good.
      • trait needs some rewrite (thus docs will, too)
      • Only the class has @tag internals, component... Idk.
  • Exception/
    • Base.php
      • Wrote @todos.
      • Nothing really needs documented here. You just create an exception
    • *.php
      • I plan to delete the other exceptions & improve BaseException with extensibility. So... No. Not documenting these
  • LiaisonInterface/
    • LifeCycler.php
      • @deprecated & @todo delete, because its not in use far as I could grep
    • PackageLifeCycle.php
      • Documented nicely. But documentation is nearly identical to documentaiton on \Lia\Compo for these methods. Perhaps I can remove identical docs from compo.
  • Objects/
    • IView.php
      • Documented, some @todos
    • View.php
      • Well Documented, some @todos
    • Request.php
      • Well Documented, very basic class
    • Response.php
      • Reasonably well documented. Some @todos
    • Route.php
      • Adequately documented... bad class.
      • No tags... I might want tags
    • ViewCallable.php
      • TODO <- There is no structure. It's all setup by the View component, I think. So its not well setup for documenting
  • Utility/
    • ClassFinder.php
      • Barely documented, because it comes from my Utility repo. So its fine.
    • DotNotation.php
      • documented well enough. No tags
    • FancyClosure.php
      • documented well enough. No tags
    • Files.php
      • Documented well enough. No tags
    • StaticFile.php
      • Documented well enough. No tags
  • ../core/
    • Has not been started

Future Work

View Getters

The base View Component will implement a view() method. This view() method will loop over all active view_getters & call getView() on each of them. The returned view will be an instantiated class with a __toString() method. Exactly one view getter must return a view. Each view getter MUST support namespaced view names.

  • Phad templates & Lia views will both be accessible through $lia->view().
  • Lia\Compo\View will
    • implement a view getter
    • have an add_view_dir($dir, $namespace, $args) function that adds a dir for PSR-4 style view-name loading
    • have an add_view_callable($callable, $fullyQualifiedViewName, $args) function to explicitly add a callable as a view
    • have an add_view($dir, $fullyQualifiedViewName, $args) fucntion to explicitly add a single view
      • this is already implemented
  • Phad\Compo will
    • implement a view getter
    • have an add_view_dir($dir, $namespace, $args) function for psr-4 style view loading
  • Some Future View Component will
    • implement a view getter
    • have an add_whatever function to add whatever.... to be later retrieved by the view getter method