GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

SnappyRouter   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 239
ccs 97
cts 97
cp 1
rs 9.84
c 0
b 0
f 0
wmc 32
lcom 1
cbo 6

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setLogger() 0 4 1
A getHandlers() 0 4 1
A handleHttpRoute() 0 5 1
A handleCliRoute() 0 5 1
B handleRoute() 0 22 7
A invokeHandler() 0 23 2
A handleInvocationException() 0 29 4
B determineHandler() 0 21 6
A parseConfig() 0 15 3
A setupHandlers() 0 21 5
1
<?php
2
3
namespace Vectorface\SnappyRouter;
4
5
use \Exception;
6
use Psr\Log\LoggerInterface;
7
use Psr\Log\NullLogger;
8
use Vectorface\SnappyRouter\Config\Config;
9
use Vectorface\SnappyRouter\Config\ConfigInterface;
10
use Vectorface\SnappyRouter\Di\Di;
11
use Vectorface\SnappyRouter\Di\DiInterface;
12
use Vectorface\SnappyRouter\Exception\ResourceNotFoundException;
13
use Vectorface\SnappyRouter\Exception\RouterExceptionInterface;
14
use Vectorface\SnappyRouter\Handler\AbstractHandler;
15
use Vectorface\SnappyRouter\Response\AbstractResponse;
16
use Vectorface\SnappyRouter\Response\Response;
17
18
/**
19
 * The main routing class that handles the full request.
20
 * @copyright Copyright (c) 2014, VectorFace, Inc.
21
 * @author Dan Bruce <[email protected]>
22
 */
23
class SnappyRouter
24
{
25
    /** the DI key for the main configuration */
26
    const KEY_CONFIG = 'config';
27
28
    private $config; // the configuration
29
    private $handlers; // array of registered handlers
30
31
    /**
32
     * @var LoggerInterface
33
     */
34
    private $logger;
35
36
    /**
37
     * The constructor for the service router.
38
     * @param array $config The configuration array.
39
     */
40 8
    public function __construct(ConfigInterface $config)
41
    {
42 8
        $this->config = $config;
43 8
        $this->parseConfig();
44 7
        $this->logger = new NullLogger();
45 7
    }
46
47
    /**
48
     * Configure SnappyRouter to log its actions.
49
     *
50
     * @param LoggerInterface $logger
51
     */
52 1
    public function setLogger(LoggerInterface $logger)
53
    {
54 1
        $this->logger = $logger;
55 1
    }
56
57
    /**
58
     * Returns the array of registered handlers.
59
     * @return The array of registered handlers.
60
     */
61 7
    public function getHandlers()
62
    {
63 7
        return $this->handlers;
64
    }
65
66
    /**
67
     * Handles the standard route. Determines the execution environment
68
     * and makes the appropriate call.
69
     * @param string $environment (optional) An optional environment variable, if not
70
     *        specified, the method will fallback to php_sapi_name().
71
     * @return string Returns the encoded response string.
72
     */
73 4
    public function handleRoute($environment = null)
74
    {
75 4
        if (null === $environment) {
76 3
            $environment = PHP_SAPI;
77
        }
78
79
        switch ($environment) {
80 4
            case 'cli':
81 1
            case 'phpdbg':
82 3
                $components = empty($_SERVER['argv']) ? array() : $_SERVER['argv'];
83 3
                return $this->handleCliRoute($components).PHP_EOL;
84
            default:
85 1
                $queryPos = strpos($_SERVER['REQUEST_URI'], '?');
86 1
                $path = (false === $queryPos) ? $_SERVER['REQUEST_URI'] : substr($_SERVER['REQUEST_URI'], 0, $queryPos);
87 1
                return $this->handleHttpRoute(
88 1
                    $path,
89 1
                    $_GET,
90 1
                    $_POST,
91 1
                    isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET'
92
                );
93
        }
94
    }
95
96
    /**
97
     * Handles routing an HTTP request directly.
98
     * @param string $path The URL path from the client.
99
     * @param array $query The query parameters as an array.
100
     * @param array $post The post data as an array.
101
     * @param string $verb The HTTP verb used in the request.
102
     * @return string Returns an encoded string to pass back to the client.
103
     */
104 4
    public function handleHttpRoute($path, $query, $post, $verb)
105
    {
106 4
        $this->logger->debug("SnappyRouter: Handling HTTP route: $path");
107 4
        return $this->invokeHandler(false, array($path, $query, $post, $verb));
108
    }
109
110
    /**
111
     * Handles routing a CLI request directly.
112
     * @param array $pathComponents The array of path components to the CLI script.
113
     * @return string Returns an encoded string to be output to the CLI.
114
     */
115 3
    public function handleCliRoute($pathComponents)
116
    {
117 3
        $this->logger->debug("SnappyRouter: Handling CLI route: " . implode("/", $pathComponents));
118 3
        return $this->invokeHandler(true, array($pathComponents));
119
    }
120
121
    /**
122
     * Determines which handler is appropriate for this request.
123
     *
124
     * @param bool $isCli True for CLI handlers, false otherwise.
125
     * @param array $handlerParams An array parameters required by the handler.
126
     * @return Returns the handler to be used for the route.
127
     */
128 7
    private function invokeHandler($isCli, $handlerParams)
129
    {
130 7
        $activeHandler = null;
131
        try {
132
            // determine which handler should handle this path
133 7
            $activeHandler = $this->determineHandler($isCli, $handlerParams);
134 5
            $this->logger->debug("SnappyRouter: Selected handler: " . get_class($activeHandler));
135
            // invoke the initial plugin hook
136 5
            $activeHandler->invokePluginsHook(
137 5
                'afterHandlerSelected',
138 5
                array($activeHandler)
139
            );
140 5
            $this->logger->debug("SnappyRouter: routing");
141 5
            $response = $activeHandler->performRoute();
142 3
            $activeHandler->invokePluginsHook(
143 3
                'afterFullRouteInvoked',
144 3
                array($activeHandler)
145
            );
146 3
            return $response;
147 4
        } catch (Exception $e) {
148 4
            return $this->handleInvocationException($e, $activeHandler, $isCli);
149
        }
150
    }
151
152
    /**
153
     * Attempts to mop up after an exception during handler invocation.
154
     *
155
     * @param \Exception $exception The exception that occurred during invocation.
156
     * @param HandlerInterface $activeHandler The active handler, or null.
157
     * @param bool $isCli True for CLI handlers, false otherwise.
158
     * @return mixed Returns a handler-dependent response type, usually a string.
159
     */
160 4
    private function handleInvocationException($exception, $activeHandler, $isCli)
161
    {
162 4
        $this->logger->debug(sprintf(
163 4
            "SnappyRouter: caught exception while invoking handler: %s (%d)",
164 4
            $exception->getMessage(),
165 4
            $exception->getCode()
166
        ));
167
168
        // if we have a valid handler give it a chance to handle the error
169 4
        if (null !== $activeHandler) {
170 2
            $activeHandler->invokePluginsHook(
171 2
                'errorOccurred',
172 2
                array($activeHandler, $exception)
173
            );
174 2
            return $activeHandler->getEncoder()->encode(
175 2
                new Response($activeHandler->handleException($exception))
176
            );
177
        }
178
179
        // if not on the command line, set an HTTP response code
180 2
        if (!$isCli) {
181 1
            $responseCode = AbstractResponse::RESPONSE_SERVER_ERROR;
182 1
            if ($exception instanceof RouterExceptionInterface) {
183 1
                $responseCode = $exception->getAssociatedStatusCode();
184
            }
185 1
            \Vectorface\SnappyRouter\http_response_code($responseCode);
186
        }
187 2
        return $exception->getMessage();
188
    }
189
190
    /**
191
     * Determines which handler is appropriate for this request.
192
     *
193
     * @param bool $isCli True for CLI handlers, false otherwise.
194
     * @param array $checkParams An array parameters for the handler isAppropriate method.
195
     * @return Returns the handler to be used for the route.
196
     */
197 7
    private function determineHandler($isCli, $checkParams)
198
    {
199
        // determine which handler should handle this path
200 7
        foreach ($this->getHandlers() as $handler) {
201 6
            if ($isCli !== $handler->isCliHandler()) {
202 5
                continue;
203
            }
204 6
            $callback = array($handler, 'isAppropriate');
205 6
            if (true === call_user_func_array($callback, $checkParams)) {
206 6
                return $handler;
207
            }
208
        }
209
210 2
        $config = Di::getDefault()->get('config');
211 2
        if ($isCli) {
212 1
            $errorMessage = 'No CLI handler registered.';
213
        } else {
214 1
            $errorMessage = ($config->isDebug()) ? 'No handler responded to the request.' : '';
215
        }
216 2
        throw new ResourceNotFoundException($errorMessage);
217
    }
218
219
    /**
220
     * Parses the config, sets up the default DI and registers the config
221
     * in the DI.
222
     */
223 8
    private function parseConfig()
224
    {
225
        // setup the DI layer
226 8
        $diClass = $this->config->get(Config::KEY_DI);
227 8
        if (class_exists($diClass)) {
228 7
            $di = new $diClass();
229 7
            if ($di instanceof DiInterface) {
230 7
                Di::setDefault($di);
231
            }
232
        }
233 8
        Di::getDefault()->set(self::KEY_CONFIG, $this->config);
234 8
        $this->setupHandlers(
235 8
            $this->config->get(Config::KEY_HANDLERS, array())
236
        );
237 7
    }
238
239
    // helper to setup the array of handlers
240 8
    private function setupHandlers($handlers)
241
    {
242 8
        $this->handlers = array();
243 8
        foreach ($handlers as $handlerClass => $handlerDetails) {
244 7
            $options = array();
245 7
            if (isset($handlerDetails[Config::KEY_OPTIONS])) {
246 7
                $options = (array)$handlerDetails[Config::KEY_OPTIONS];
247
            }
248
249 7
            if (isset($handlerDetails[Config::KEY_CLASS])) {
250 7
                $handlerClass = $handlerDetails[Config::KEY_CLASS];
251
            }
252
253 7
            if (!class_exists($handlerClass)) {
254 1
                throw new Exception(
255 1
                    'Cannot instantiate instance of '.$handlerClass
256
                );
257
            }
258 7
            $this->handlers[] = new $handlerClass($options);
259
        }
260 7
    }
261
}
262