call()
method is called, then one cannot apply any other method (e.g root()
) below it.
This is because the shutter system method by default is configured to handle one shutter method at a time by any window method.
This means that once a shutter method is called, all other shutters are disabled from functioning because once a url does not exist,
a 404 error page has to be returned. In order to keep a window open when a shutter is applied, a pending directive must be applied on the specific call type
which tells the shutter method to prevent automatic closing of the windows. This option may be employed when handling complex applications or urls.
This can be done by setting the third argument as a boolean value of false
.
Whenever any of the shutters are pended, developer must be careful to properly close invalid urls, most especially for basecall()
because
failure to close may result in faulty or black pages if not properly handled.
window()
function and lastUrl()
function. The
window()
function returns specific divisions of a visited url while lastUrl()
function is used to detect the last url called. More documentations about these methods are provided
here. It is suggested to visit the documentation of these methods before proceeding with the
documentations below.
class Home extends Window { function __construct(){ $accepted_urls = [ 'home' => 'index', // index will be called on any url having "home" as its entry point ]; self::rootcall($this, $accepted_urls); } function index() { self::load('index', fn() => compile() ); // load an index template file } }
rootcall
will only match the url's window entry point "home". Since our root class name is "home", this means that using
window(':')
within this class
will also return "home". The we can rewrite our code as :
class Index extends Window {
function __construct(){
self::rootcall($this, [window(':') => 'root']);
}
function root() {
self::load('index', fn() => compile() ); // load an index template file
}
}
root()
method is only realistic for use in window root server files. This is because the
rootcall()
only works on the root entry point. As long as a urls root name is matched, the rootcall()
method will not bother to check the relative paths on that particular request url. The figure below best explain this behavior.
self::rootcall($this, ['home' => 'index']); valid url: http://{domain}/home valid url: http://{domain}/home/... called method: index invalid url: http://{domain}/some invalid url: http://{domain}/some/...
home
is the root entry point, the window url
will become a valid url. If a basic logic is employed for example, this means that all urls will be handled by a base window server class. This class
is expected to be directly within the windows/Routes
directory. Assuming the server class name is Index, then
the Index class may be configured to use the rootcall()
method to initialize other classes based on the url's
window name, since it is the class that manages every other url. In this way, rather than use methods, we can
directly call classes using the format below:
class Index extends Window {
function __construct(){
$accepted_urls = [
'index' => 'root',
'home' => 'win:Routes\Home',
'profile' => 'win:Routes\Profile',
];
self::rootcall($this, $accepted_urls);
}
function root() {
//This is triggered when index page is visited.
}
}
win:
directive is used to call a class within the spoova\mi\windows
namespace.
Using the above sample as reference, the "home"
key under the $accepted_urls
specifies that when a url with its parent structure as http://domain/home
is visited,
the class spoova\mi\windows\Routes\Home
will be triggered. The profile
also works in a similar way.
However, the key index
specifies that when an index page such as http://domain
, http://domain/index
or any url that has its parent structure as the index page
is visited, the root()
method is triggered. Remember that if the index page is visited, then window(':')
will also return the name "index"
. This means that we can replace our array key 'index'
with window(':')
and our class will still run perfectly. The rootcall()
method is a top level logic and is used internally by the application.
This method in most cases is not applied when working within routes.
window('path')
function returns the path of the current request url. By using the Window::pathcall()
method, this acts
directly on a list of path that follow the current url's root entry point. The pathcall()
method does not
care about the window root entry point name. Instead, it only deals with the path supplied on the root entry name by making sure that the currently visited url's
entry path supplied exists in the list of specified url paths. If the currently requested url has its path in the list specified urls paths,
pathcall
will trigger the corresponding handler method or class, else a 404 error page is returned.
namespace spoova\mi\windows; use Window; class Home extends Window { function __construct(){ $accepted_paths = [ 'users' => 'users', 'users/profile' => 'profile' ]; //set accepted paths on Home window self::pathcall($this, $accepted_paths); } function users(){ self::load('users', fn() => compile() ); load tempate file } function profile(){ self::load('profile', fn() => compile() ); load tempate file } }
Home
was added into the window's Routes folder, when a url
(e.g http://domain/home/whatever/path
) is visited, the Home file is triggered. If the Home window file does not exist, a 404
response is returned. Home
route, we may not need to validate this anymore. This is where the pathcall()
method becomes useful.
The lists of acceptable paths on the Home window will be validated. The sample above illustrates that: http://{domain}/home/users
, the users()
method is called. http://{domain}/home/users/profile
, the profile()
method is called. pathcall
does not check if the window root is home
. We assume that standard logic will already do this validation for us.
The pathcall()
method only checks if the path supplied on the window root "home"
matches the list of specified url paths.
call
method must be the full path of a url.
The full path of any url is the combination of the root and window's path. When using the call
method, the first path supplied must be the window name itself else a 404 error will be returned.
An example is displayed below:
<?php namespace spoova\mi\windows; use Window; class Home extends Window { function __construct(){ $accepted_paths = [ 'home' => 'index', 'home/users' => 'profile' ]; //set accepted paths for Home window self::call($this, $accepted_paths); } function index(){ self::load('home', fn() => compile() ); load tempate file } function profile(){ self::load('user', fn() => compile() ); load tempate file } }
call()
requires the direct full path
of the urls accepted. When working with multiple urls, redefining the class name at every
step of the array supplied may prove tedious in cases which class names may be redefined. Hence,
the following may be considered:
function __construct(){
$accepted_paths = [
'home' => 'index',
'home/users' => 'profile'
];
//set accepted paths for Home window
self::call($this, $accepted_paths);
}
function __construct(){
$accepted_paths = [
window(':') => 'index',
window(':users') => 'profile'
];
//set accepted paths for Home window
self::call($this, $accepted_paths);
}
call
, one may give
preference to example 2 because it keeps track of the current window name should it ever change. This is done with the window()
helper function.
A much better approach will be to to use the lastUrl()
helper function which is mostly recommended. Also, developers are encouraged to
favor this method than other calls as it acts directly on any url supplied, making it easier to read and
understand. An example is shown below
function __construct(){
$accepted_paths = [
lastUrl() => 'index',
lastUrl('/users') => 'profile'
];
//set accepted paths for Home window
self::call($this, $accepted_paths);
}
lastUrl()
method usually start from the url's root entry point and goes on to keep tracks of the urls visited by
each route. This makes it the ideal and best approach for subroutes.
basecall()
method works similarly as the call()
method on the direct path
supplied. However, the difference is that a basecall method is applied on urls that must have a specific
parent path structure. For example, a url of home/users
and home/users/profile
both have the
same parent path of home/users
. Hence, the basecall
will be triggered for both urls
mentioned earlier if the url supplied was home/users
. The dangers of this method is that it can leave
unwanted urls opened. When working with urls, it is important to be precise. This makes the handling of urls to be less
ambiguous. This method could however prove useful in certain cases when we are trying to call a different class or trying to
accept any path on a specific window url. When it is used anyway, developers must make sure that
all non-essential urls are properly closed or handled properly.
<?php use Window; class Home { function __construct(){ $accepted_paths = [ window(':user') => 'index', ]; //set accepted parent paths from Home window self::call($this, $accepted_paths); } function index() { //called by all "home/user" parent urls } }
home/user
(e.g home/user/settings) will call or trigger the
index()
method.
call()
method, then we cannot use, rootcall()
, pathcall()
, basecall()
or even call()
itself after.
This idea is generated from the fact that two different urls (or files) should not be loaded (or resolved) in a single url. Naturally, if any shutter cannot resolve its list of acceptable urls, it will automatically
close unless pended. However complications may arise when we need to resolve multiple urls or resolve urls differently.
Shutters can be pended by supplying a third parameter of false
to any shutter method used. When this is done,
a shutter will only allow a subsequent shutter to run if it was unable to resolve any of its urls.
...
self::call($this, ['home' => 'method'], false);
$basecall = self::basecall($this, ['home/user' => 'method']);
if(!$basecall) self::close();
call()
was pended to allow the basecall()
to also run.
If a url is resolved by call()
, then basecall()
will trip off. However,
if a url is not resolved by the call()
method, then the basecall
will try to resolve its own
list of urls. If basecall()
cannot resolve its urls, then, a 404 error page is displayed and a false value is returned.
Also, if the call()
was able to resolve its url, we can force basecall()
to work by declaring the previous call()
as unresolved. This can be done by adding the $this->resolved(false)
immediately below the call()
method. Another method to force our basecall()
to work is to call it within the self::clearResolved()
method which takes a closure as callback argument.
These are shown below: ... self::call($this, ['home' => 'method']); $this->resolved(false); // allow another shutter to work self::basecall($this, ['home/user' => 'method']); // now it works!
... self::call($this, ['home' => 'method']); self::clearResolved(function(){ self::basecall($this, ['home/user' => 'method']); // now it works! })
basecall()
which is a soft shutter (i.e allows unlimited paths on it).
...
$call = self::call($this, ['home' => 'method'], false);
if(!$call) {
if(basecall($this, ['home/user' => 'method'])); self::close();
}
call()
cannot resolve its urls,
then since it was pended, this will allow basecall
to try to resolve its own urls. If basecall happens to resolve it urls,
since it is a soft shutter, it will leave the resolved url opened to allow multiple paths unless it is handled properly. Naturally, we don't
want to close a url with self::close()
when it is resolved because that will send a 404 response to server. However, the self::close()
method above
is just a way to show that a url can be closed using
the self::close()
method.
SELF::ARG
or
SELF::PARAM
array key can be used in shutters. This is shown below: <?php ... class Home { function __construct() { $var = ['name' => 'Brown']; self::call($this, [ window(':') => 'root', window(':user') => 'user', SELF::ARG => $var ]); } function root($var) { var_dump($var); //['name' => 'Brown'] } function user(Request $Request, $var) { var_dump($var); //['name' => 'Brown'] } }
$var
was passed across to all methods called.
As in the case of user()
method, when dependencies are parsed, they must precede
every other argument parsed into a method. We can also parse different arguments for each method through a function. This is
shown below:
<?php ... class Home { function __construct() { $var = ['name' => 'Brown']; self::call($this, [ window(':') => 'root', window(':user') => 'user', SELF::ARG => function($method) { return [ 'root' => 'foo', 'user' => ['foo', 'bar'], ]; } ]); } function root($args) { $args = $args(__FUNCTION__); //foo } function user(Request $Request, $args) { $args = $args(__FUNCTION__); //['foo', 'bar'] } }
win:
identifier. Naturally, all window
files are expected to be within the Window
directory. When a window identifier win:
is applied, then, such
path must follow the folder directory. <?php ... class Home { function __construct() { $var = ['name' => 'Brown']; self::call($this, [ window(':') => 'root', window(':user') => 'win:Path\To\File', SELF::ARG => $vars ]); } function root($var) { var_dump($var); //['name' => 'Brown'] } }
home
url will call the root()
method of the current window, the home/user
will call the spoova\mi\Windows\Path\To\File
class.
The win:
directive specifies the spoova\mi\windows
namespace.
We can also pass an object as value rather than strings. The variable $var
will also be passed down as an argument to the class, object or method defined.
lastcall()
function can be applied just like the window()
function earlier discussed except
for a few differences. This function returns the last resolved url. When parameters are supplied, it appends the last resolved
url to the new parameter supplied. However, this function does not support dot convention. Rather, paths must be strictly defined
with slashes. The example below is a relationship between shutters and lastCall function.
<?php ... namespace spoova\mi\windows\Routes; class Home { function __construct() { $var = ['name' => 'Brown']; self::call($this, [ window(':') => 'root', lastCall('/user') => 'win:Routes\User', SELF::ARG => $vars ]); } function root() { # This is called when home is visited (or resolved) } }
<?php ... namespace spoova\mi\windows\Routes\Home; class User { function __construct($var) { self::call($this, [ lastCall() => 'root', # This is home/user ]); } function root() { # This is called when home/user is visited (or resolved) } }
Home
class uses its shutter method to call its
root()
method when home
is visited. However, when home/user
is visited,
the User
class is called. The lastCall()
function tracks this movement and makes it easier
to harvest the last resolved url. Rather than use window(':user')
, we can use the lastCall()
function which will naturally return the last resolved call. If any argument is supplied on it (e.g lastCall('/path')
)
then home/user/path
will be returned.