PatternMatchHandler::getDispatcher()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
nc 4
nop 1
dl 0
loc 29
ccs 17
cts 17
cp 1
crap 7
rs 8.5226
c 0
b 0
f 0
1
<?php
2
3
namespace Vectorface\SnappyRouter\Handler;
4
5
use FastRoute\Dispatcher;
6
use FastRoute\RouteCollector;
7
8
/**
9
 * A handler for matching route patterns and mapping to a method.
10
 * Internally the class uses FastRoute to do the pattern matching.
11
 * @copyright Copyright (c) 2014, VectorFace, Inc.
12
 * @author Dan Bruce <[email protected]>
13
 */
14
class PatternMatchHandler extends AbstractRequestHandler
15
{
16
    /** the config key for the list of routes */
17
    const KEY_ROUTES = 'routes';
18
19
    /** the config key for the route cache */
20
    const KEY_CACHE = 'routeCache';
21
22
    // the currently active callback
23
    private $callback;
24
    // the currently active route parameters
25
    private $routeParams;
26
27
    /** All supported HTTP verbs */
28
    private static $allHttpVerbs = array(
29
        'GET',
30
        'POST',
31
        'PUT',
32
        'DELETE',
33
        'OPTIONS'
34
    );
35
36
    /** The route information from FastRoute */
37
    private $routeInfo;
38
39
    /**
40
     * Returns true if the handler determines it should handle this request and false otherwise.
41
     * @param string $path The URL path for the request.
42
     * @param array $query The query parameters.
43
     * @param array $post The post data.
44
     * @param string $verb The HTTP verb used in the request.
45
     * @return boolean Returns true if this handler will handle the request and false otherwise.
46
     */
47 4
    public function isAppropriate($path, $query, $post, $verb)
48
    {
49 4
        $routeInfo = $this->getRouteInfo($verb, $path);
50 4
        if (Dispatcher::FOUND !== $routeInfo[0]) {
51 1
            return false;
52
        }
53 4
        $this->callback = $routeInfo[1];
54 4
        $this->routeParams = isset($routeInfo[2]) ? $routeInfo[2] : array();
55 4
        return true;
56
    }
57
58
    /**
59
     * Returns the array of route info from the routing library.
60
     * @param string $verb The HTTP verb used in the request.
61
     * @param string $path The path to match against the patterns.
62
     * @param boolean $useCache (optional) An optional flag whether to use the
63
     *        cached route info or not. Defaults to false.
64
     * @return array Returns the route info as an array.
65
     */
66 33
    protected function getRouteInfo($verb, $path, $useCache = false)
67
    {
68 33
        if (!$useCache || !isset($this->routeInfo)) {
69 33
            $dispatcher = $this->getDispatcher($this->getRoutes());
70 33
            $this->routeInfo = $dispatcher->dispatch(strtoupper($verb), $path);
71
        }
72 33
        return $this->routeInfo;
73
    }
74
75
    /**
76
     * Returns the array of routes.
77
     * @return array The array of routes.
78
     */
79 4
    protected function getRoutes()
80
    {
81 4
        $options = $this->getOptions();
82 4
        return isset($options[self::KEY_ROUTES]) ? $options[self::KEY_ROUTES] : array();
83
    }
84
85
    /**
86
     * Performs the actual routing.
87
     * @return mixed Returns the result of the route.
88
     */
89 1
    public function performRoute()
90
    {
91 1
        return call_user_func($this->callback, $this->routeParams);
92
    }
93
94
    /**
95
     * Returns a request object extracted from the request details (path, query, etc). The method
96
     * isAppropriate() must have returned true, otherwise this method should return null.
97
     * @return \Vectorface\SnappyRouter\Request\HttpRequest|null Returns a
98
     *         Request object or null if this handler is not appropriate.
99
     */
100 2
    public function getRequest()
101
    {
102 2
        return null;
103
    }
104
105
    /**
106
     * Returns an instance of the FastRoute dispatcher.
107
     * @param array $routes The array of specified routes.
108
     * @return FastRoute\Dispatcher The dispatcher to use.
109
     */
110 33
    private function getDispatcher($routes)
111
    {
112 33
        $verbs = self::$allHttpVerbs;
113 33
        $f = function (RouteCollector $collector) use ($routes, $verbs) {
114 33
            foreach ($routes as $pattern => $route) {
115 33
                if (is_array($route)) {
116 2
                    foreach ($route as $verb => $callback) {
117 2
                        $collector->addRoute(strtoupper($verb), $pattern, $callback);
118
                    }
119
                } else {
120 33
                    foreach ($verbs as $verb) {
121 33
                        $collector->addRoute($verb, $pattern, $route);
122
                    }
123
                }
124
            }
125 33
        };
126
127 33
        $options = $this->getOptions();
128 33
        $cacheData = array();
129 33
        if (isset($options[self::KEY_CACHE])) {
130 1
            $cacheData = (array)$options[self::KEY_CACHE];
131
        }
132
133 33
        if (empty($cacheData)) {
134 32
            return \FastRoute\simpleDispatcher($f);
135
        } else {
136 1
            return \FastRoute\cachedDispatcher($f, $cacheData);
137
        }
138
    }
139
}
140