The Molajo Locator is a Resource Locator and Class Loader utilizing URI Namespaces.
A class loader
and resource locator
share a significant amount of code. This shared code includes building namespace and resource maps and searching those structures. Only a small portion of the code is unique. For each type of processing expected by the application (i.e., return a path, read a file, save a Url, etc.), 'handlers' are created and contain minimal code. A ClassLoader handler, for example, simply includes the path and returns.
During normal application bootstrap processing, the core addNamespace
commands are processed to establish a canonical namespace for each file and folder resource. Next, a set ofsearch term tags
are compared to the names of folders and files. Those path results and tag values are used to create additional addNamespace
. Combined, the canoncial namespace
and the namespace tag
are either used to build a resource map
or serve as the basis for real time resource searching.
Examples of tags I use when creating Molajo namespaces:
- Views;
- Component Type;
- Media;
- Services;
- Css;
- or, Exclusion searches.
Next, a resource map
is created if the configuration is set to do so.
If the resource map is not created, the system looks to see if a resource map file
exists.
The namespace pairs
and the resource map
are held to be injected into the class when it is instantiated.
Since all resources share the same code base and map, and since the handlers are nominal, the pure adapter pattern
is used but slightly modified to first load the Resource Adapter
and then each requested handler is instantiated, the results of which are stored in an adapter array. When complete, the adapter instance
is stored in the IoCC
so that it is available as a dependency
for application classes which require it.
Information about the physical filesystem, the path it is located, or the protocol it uses, the name of the file, is masked from view. Instead the associated namespace[s]
serve as pointers to file and folder resources. To request a resource, the application issues a get
Resource command. As a result, a location request for an FTP file could look the same as a request for a local file, they could have even have the same path, but different file names.
The point being the application is no longer constrained to the filesystem.
The ResourceMapInterface is used for the administrative namespace methods listed below:
- addScheme($scheme, array $extensions = array());
- addNamespace($namespace_prefix, $base_directory, $prepend = false);
- createMap();
- editMap();
A single Resource Map
is shared across all schemes.
In a data modeling sense, a scheme
maps to one handler
. Handlers
can be shared by multiple schemes
. Handlers
are classes
with a method named handlePath
that executes following the findResource
for the purpose of preparing the response expected by the application.
The Scheme
defines it's valid extension(s)
, Handler
, and what the handler
does with the located path(s). A scheme
can have only one handler
, and 0:M file extensions
.
class
=>.exe
=> ClassLoader => include the file;- [default] => n/a => FileHandler => return path;
xml
=>.xls
=> reads the XML file and returns the results.
Handlers
might not be defined by PSR-R. In my application, the goal would be to have a solid 80% of the handlers defined and then developers can create and include their own handlers for special cases.
Note: Scheme
is not specified for addNamespace
. Instead, scheme
data is selected on the basis of the results of the namespace mapping
, for example: addNamespace('My\Views', 'Path\To\Views\My\Views');
collects Views
in the namespace My\Views
, and file extensions added with the addScheme
method.
Runtime addNamespace
entries are processed before the injected values so that they will be selected first and can therefore serve as overrides.
The ResourceLocatorInterface is used anytime the application issues a get
command for a specific $uri_namespace
or a set of values accumulated using the getCollection
scheme.
- get($uri_namespace);
- getCollection($scheme);
Note get
Processing
- parse the
$uri_namespace
intoscheme
,namespace
, andparameters
(if needed by the post getScheme Handler
); - executes the common
locate method
, passing in thenamespace
which returns the file system path(s) matching; - using the
Scheme
to identifies thehandler
; - passes the
Handler
thefile system path
and anyparameters
from the URI; - passes back the results from the
handler
;
Example: get
an Image
<?php
$path = $locator->get('file:///Vendor/Package/Image1');
echo $path; // result echoed is /Path/To/File/Image1.jpg
Example: get
CSS files within a folder
The CSS handler
accumulates CSS
files until the getCollection
method is executed in the render Head Response.
<?php
$results = $locator->get('folder:///Vendor/Package/Css/MyTemplate');
if [$results === true] {
// all is well ...
Note getCollection
Processing
- Uses the
scheme
to identify thehandler
; - Executes the handler's
getCollection
method which processes the values collected during the duration of the class instance and returns results.
The ResourceHandlerInterface is used behind the scenes to communicate between the adapter
and the handler
.
- handlePath($path, array $options = array());
- getCollection(array $options = array());
get($uri_path)
uses the $uri_path to the file system path, passing the value into the handlePath
method for the Handler
. Any parameters passed into get
are also passed to the handler.
Each handler
can be used by multiple schemes
.
Each scheme
will have one and only one handler.
Standard handlers
include:
ClassHandler
(which includes thepath
);CssHandler
(store CSSpath
for head rendering);JsHandler
(store JSpath
for head rendering);FileHandler
(returnpath
);MapHandler
(returned rows associated with the request),XML Handler
(reads file in the path, returning the XML).
The getCollection
handler
method is called by the same-named adapter method. It is useful for acting on a collection of paths for a specific reason, like CSS files, or JS files.
The ClassLoaderInterface has two methods specific to class loading to register and unregister classes.
- registerClassAutoload($prepend = true);
- unregister();
- ClassLoaderInterface;
- registerClassLoader($prepend = true);
- cancelClassLoader();
- createMap();
- editMap();
- addNamespace($namespace_prefix, $base_directory, $prepend = false);
- get($uri_namespace);
- getCollection($uri_namespace);
- Handlers:
- handlePath($path, $options);
- getCollection(array $options = array());