Commit 0b41871e authored by Andrzej Prusinowski's avatar Andrzej Prusinowski

shorten dispatcher

parent fb4dbbd9
Pipeline #7725723 passed with stage
in 3 seconds
......@@ -62,7 +62,7 @@ Its keys are route names (same as controller name and view name) and values are
'itemList' => '/item/list',
'itemShow' => '/item/(\d+)/show',
Assumeing this set of routes: URL `/` will run the `home` controller, `/item/list` -- the `itemList` controller,
Assuming this set of routes: URL `/` will run the `home` controller, `/item/list` -- the `itemList` controller,
and anything like `/item/1/show`, `/item/7/show`, `/item/666/show`, etc. -- the `itemShow` controller.
Anything other than that will throw a 404 exception.
......@@ -110,7 +110,7 @@ There are 5 constants defined by Picco:
#### Dependency Injection Container
Atfer Picco sets the system services (`router`, `controllers`, `view`, `dispatcher`),
it runs `App\Services::get($c)'` method. In there you can define your services and parameters:
it runs `App\Services::get(Container $c)` method. In there you can define your services and parameters:
$c->foo = 'bar';
......@@ -135,13 +135,14 @@ To retrieve a service/parameter, simply get it, like: `$c->db->findAll(...)`.
To define an event listener:
$c->dispatcher->set('event_name', function(Container $c, $moreParameters) {
$c->dispatcher->event_name = function(Container $c, $moreParameters) {
// do something...
});
};
To trigger it:
$c->dispatcher->trigger('event_name')
$d = $c->dispatcher;
$d('event_name', [$c, 'and', 'other', 'params']);
Listeners are triggered in the order they were defined. The default listeners for the system events
(`request`, `response` and `error`) go off **after** user defined ones.
......@@ -171,5 +172,5 @@ Note: no testing frameworks were used, to run the testsuite go to the library di
### Copyright ###
* **Author:** Andrzej Prusinowski [(Avris.it)](https://avris.it)
* **Licence:** [MIT](https://opensource.org/licenses/MIT)
* **Licence:** [MIT](https://mit.avris.it/)
<?namespace Picco;class App{
function __construct($e){session_start();$s=$_SERVER;define('D',dirname($s['SCRIPT_FILENAME']).'/../');$l=strlen($r=@$s['PATH_INFO']);$u=explode('?',$s['REQUEST_URI'])[0];define('F',$l?substr($u,0,-$l):$u);define('R',rtrim($r,'/')?:'/');define('B',preg_replace('#/[^/]+\.php$#','',F).'/');define('E',$e);}
function run(){$c=new Container();$c->router=new Router(\App\Routing::get());$c->view=new View;$q=$c->controllers=new\App\Controllers;$d=$c->dispatcher=new Dispatcher;\App\Services::get($c);
$t=function($f,$m)use($c,$q,$d){$r=(array)call_user_func_array([$q,$f],$m);return$d->trigger('response',[$c,&$r])?:$c->view->render($f,$r+['r'=>$c->router]);};
$d->set('error',function($c,$e)use($t){if(E)throw$e;return$t('error',[$c,$e]);});
set_error_handler(function($t,$m,$f,$l)use($c,$d){if(error_reporting()){echo$d->trigger('error',[$c,new\ErrorException("$m in $f line $l",500)]);die;}},E_ALL);
try{list($f,$m)=$c->router->match(R);return$d->trigger('request',[$c,$f,$m])?:$t($f,[0=>$c]+$m);}catch(\Exception$e){return$d->trigger('error',[$c,$e]);}}}
\ No newline at end of file
$t=function($f,$m)use($c,$q,$d){$r=(array)call_user_func_array([$q,$f],$m);return$d('response',[$c,&$r])?:$c->view->render($f,$r+['r'=>$c->router]);};
$d->error=function($c,$e)use($t){if(E)throw$e;return$t('error',[$c,$e]);};
set_error_handler(function($t,$m,$f,$l)use($c,$d){if(error_reporting()){echo$d('error',[$c,new\ErrorException("$m in $f line $l",500)]);die;}},E_ALL);
try{list($f,$m)=$c->router->match(R);return$d('request',[$c,$f,$m])?:$t($f,[0=>$c]+$m);}catch(\Exception$e){return$d('error',[$c,$e]);}}}
\ No newline at end of file
<?namespace Picco;class Container{protected$s,$r;
function __set($n,$v){$this->s[$n]=$v;}
function __get($n){return isset($this->r[$n])?$this->r[$n]:$this->r[$n]=is_callable($s=$this->s[$n])?$s($this):$s;}}
\ No newline at end of file
function __get($n){return isset($this->r[$n])?$this->r[$n]:$this->r[$n]=is_callable($s=$this->s[$n])&&!$s instanceof Dispatcher?$s($this):$s;}}
\ No newline at end of file
<?namespace Picco;class Dispatcher{protected$e;
function set($n,$c){$this->e[$n][]=$c;}
function trigger($n,$a){foreach((array)@$this->e[$n]as$e)if(null!==$r=call_user_func_array($e,$a))return$r;}}
\ No newline at end of file
function __set($n,$c){$this->e[$n][]=$c;}
function __invoke($n,$a){foreach(@$this->e[$n]?:[]as$e)if(null!==$r=call_user_func_array($e,$a))return$r;}}
\ No newline at end of file
......@@ -44,11 +44,11 @@ Mock::$services = function(Container $c) { };
a($a->run() === "<p>message = Route for /test not found</p>\n");
Mock::$routing = [ 'foo' => '/test' ];
Mock::$services = function(Container $c) { $c->dispatcher->set('request', function() { return 'blocked'; }); };
Mock::$services = function(Container $c) { $c->dispatcher->request = function() { return 'blocked'; }; };
a($a->run() === 'blocked');
Mock::$routing = [ 'foo' => '/test' ];
Mock::$services = function(Container $c) { $c->dispatcher->set('response', function(Container $c, &$vars) { $vars['foo'] = 'overwritten'; }); };
Mock::$services = function(Container $c) { $c->dispatcher->response = function(Container $c, &$vars) { $vars['foo'] = 'overwritten'; }; };
$expected = <<<HTML
<p>foo = overwritten</p>
<p>view = foo</p>
......@@ -60,5 +60,5 @@ HTML;
a($a->run() === $expected . "\n");
Mock::$routing = [];
Mock::$services = function(Container $c) { $c->dispatcher->set('error', function(Container $c, \Exception $e) { return $e->getMessage(); }); };
Mock::$services = function(Container $c) { $c->dispatcher->error = function(Container $c, \Exception $e) { return $e->getMessage(); }; };
a($a->run() === "Route for /test not found");
......@@ -4,21 +4,21 @@ $d = new Picco\Dispatcher;
$out = 0;
$d->set('foo', function($a, $b) use (&$out) { $out += $a + $b; if ($a == 0) { return true; } });
$d->foo = function($a, $b) use (&$out) { $out += $a + $b; if ($a == 0) { return true; } };
$d->trigger('foo', [1,2]);
$d('foo', [1,2]);
a(3 == $out);
$d->trigger('foo', [3,4]);
$d('foo', [3,4]);
a(10 == $out);
$d->trigger('foo', [0,1]);
$d('foo', [0,1]);
a(11 == $out);
$d->set('foo', function($a, $b) use (&$out) { $out += 2*($a + $b); });
$d->foo = function($a, $b) use (&$out) { $out += 2*($a + $b); };
$d->trigger('foo', [1,2]);
$d('foo', [1,2]);
a(20 == $out); // current 11 + first listener 3 + second listener 6
$d->trigger('foo', [0,4]);
$d('foo', [0,4]);
a(24 == $out); // current 20 + first listener 4, second listener not executed
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment