Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
12 / 12
Router
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
11 / 11
14
100.00% covered (success)
100.00%
12 / 12
 __construct()
100.00% covered (success)
100.00%
1 / 1
1  
 
 anonymous function () use($ref, $args)
100.00% covered (success)
100.00%
1 / 1
1  
 
 add($method, $path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 get ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 post ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 put ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 patch ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 delete ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 options($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 head ($path, callable $cb)
100.00% covered (success)
100.00%
1 / 1
1  
 
 route($method, $path)
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
7 / 7
<?php
namespace Convey;
use Rize\UriTemplate;
class Router {
    private $table = [
        'GET' => [],
        'POST' => [],
        'PUT' => [],
        'PATCH' => [],
        'DELETE' => [],
        'OPTIONS' => [],
        'HEAD' => []
    ];
    protected $emptyRoute;
    public function __construct() { $this->emptyRoute = \Closure::bind(function () {}, null); }
    public function add($method, $path, callable $cb) {
        $this->table[strtoupper($method)][] = [$path, $cb];
    }
    // aliases for common methods
    public function get    ($path, callable $cb) { self::add('GET',     $path, $cb); }
    public function post   ($path, callable $cb) { self::add('POST',    $path, $cb); }
    public function put    ($path, callable $cb) { self::add('PUT',     $path, $cb); }
    public function patch  ($path, callable $cb) { self::add('PATCH',   $path, $cb); }
    public function delete ($path, callable $cb) { self::add('DELETE',  $path, $cb); }
    public function options($path, callable $cb) { self::add('OPTIONS', $path, $cb); }
    public function head   ($path, callable $cb) { self::add('HEAD',    $path, $cb); }
    public function route($method, $path) {
        $parser = new UriTemplate();
        $results = [];
        $routes = $this->table[strtoupper($method)];
        foreach($routes as $route) {
            $args = $parser->extract($route[0], $path, true);
            if(isset($args)) {
                // reflect this function as late as possible, since *most* routes shouldn't be called
                $ref = new \ReflectionFunction($route[1]);
                $results[] = \Closure::bind(function () use($ref, $args) { return $ref->invokeArgs($args); }, null);
            }
        }
        // always return a callable function inside an array
        return empty($results) ? [$this->emptyRoute] : $results;
    }
}