Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
76.92% covered (warning)
76.92%
10 / 13
CRAP
45.45% covered (danger)
45.45%
15 / 33
RouteConfig
0.00% covered (danger)
0.00%
0 / 1
76.92% covered (warning)
76.92%
10 / 13
70.58
45.45% covered (danger)
45.45%
15 / 33
 any
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 delete
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 get
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 head
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 options
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 patch
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 post
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 put
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getConfig
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setBaseConfig
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 5
 setRouteConfig
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 4
 loadFromArray
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 9
 addRouteToMap
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
<?php
/**
 * Director
 *
 * A general purpose url router and generator
 *
 * @package     Director
 * @author      Timothy J. Warren
 * @copyright   Copyright (c) 2016
 * @link        https://git.timshomepage.net/timw4mail/director
 * @license     MIT
 */
namespace Aviat\Director;
/**
 * Class to configure routes
 */
class RouteConfig {
    /**
     * Route mapping
     *
     * @var array
     */
    protected $map = [
        'base' => [
            'namespace' => '',
            'class' => '',
            'method' => 'index',
        ],
        'routes' => [
            'get' => [],
            'post' => [],
            'put' => [],
            'patch' => [],
            'options' => [],
            'any' => [],
        ]
    ];
    
    /**
     * Add a route matching any HTTP verb
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
     * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function any($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('any', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a DELETE HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
      * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function delete($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('delete', $name, $path, $callback, $options);
    }
    /**
     * Add a route matching a GET HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
     * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function get($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('get', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a HEAD HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
     * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function head($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('head', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a OPTIONS HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
      * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function options($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('options', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a PATCH HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
     * @return RouteConfig
     */
    public function patch($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('patch', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a POST HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
      * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function post($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('post', $name, $path, $callback, $options);
    }
    
    /**
     * Add a route matching a PUT HTTP request
     *
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
      * @param [array] $options - additional route options, such as placeholders
     * @return RouteConfig
     */
    public function put($name, $path, $callback, array $options = [])
    {
        return $this->addRouteToMap('put', $name, $path, $callback, $options);
    }
    
    
    /**
     * Returns the routing config array
     *
     * @return array
     */
    public function getConfig()
    {
        return $this->map;
    }
    
    /**
     * Set route config defaults
     *
     * @param string $namespace - namespace used for controllers, unless explicit
     * @param [string] $class - controller class to default to, if no routes match
     * @param [string] $method - default controller method, if not specified in the config item
     * @return RouteConfig
     */
    public function setBaseConfig($namespace, $class = '', $method = 'index')
    {
        $this->map['base'] = [
            'namespace' => $namespace,
            'class' => $class,
            'method' => $method
        ];
        
        return $this;
    }
    
    /**
     * Batch set the routes 
     * 
     * @example // Route config format
     *    $routes = [
     *        'get' => [ // GET routes
     *            'homepage' => [ // route name => params
     *                'path' => '/',
     *                'callback' => [ // Array like so, or callable, like a lamda
     *                    'class' => 'HomeController',
     *                    'method' => 'index',
     *                    'args' => [], // Arguments to pass to controller method
     *                ],
     *            ],
     *        ],
     *        ...
     *    ];
     *
     * @param array $routes - the route mapping
     * @return RouteConfig
     */
    public function setRouteConfig(array $routes)
    {
        foreach($routes as $verb => $map)
        {
            foreach($map as $path => $setup)
            {
                $this->map['routes'][$verb][$path] = $setup;
            }
        }
        
        return $this;
    }
    
    /**
     * Batch set all the route options with one array
     *
     * If no 'routes' key is set in the array, only the routes config will be loaded.
     * 
     * @example 
     *    // Route config format
     *    $config = [
     *         'base' => [ // Default Controller setup
     *            'namespace' => 'Foo\\Bar', // namespace used for controllers, unless explicit
     *            'class' => 'Baz', // controller class to default to, if no routes match
     *            'method' => 'index', // default controller method, if not specified in the config item
     *        ],
     *        'routes' => [ // Route mapping
     *            'get' => [ // GET routes
     *                'homepage' => [ // route name => params
     *                    'path' => '/',
     *                    'callback' => [ // Array like so, or callable, like a lamda
     *                        'class' => 'HomeController',
     *                        'method' => 'index',
     *                        'args' => [], // Arguments to pass to controller method
     *                    ],
     *                ],
     *            ],
     *            ...
     *        ]
     *    ];
     *
     * @param array $config - the configuration array
     * @return RouteConfig
     */
    public function loadFromArray(array $config)
    {
        if (array_key_exists('routes', $config) && array_key_exists('base', $config))
        {
            $this->setBaseConfig(
                $config['base']['namespace'],
                $config['base']['class'],
                $config['base']['method']
            );
            
            $routes = $config['routes'];
        }
        else
        {
            $routes = $config;
        }
        
        $this->setRouteConfig($routes);
        
        return $this;
    }
    
    /**
     * Helper method to add a route to the internal map
     *
     * @param string $verb - The http verb of the route
     * @param string $name - The name of the route
     * @param string $path - The path or pattern to match
     * @param array|callable $callback - The callback to dispatch on match
     * @return RouteConfig
     */
    protected function addRouteToMap($verb, $name, $path, $callback, array $options = [])
    {
        $route = [
            'path' => $path,
            'callback' => $callback,
        ];
        
        if ( ! empty($options))
        {
            $route['options'] = $options;
        }
        
        $this->map['routes'][$verb][$name] = $route;
    }
}