Completed
Push — master ( 354bbd...8413c0 )
by John
03:53
created

Router   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
lcom 1
cbo 9
dl 0
loc 101
rs 10
c 1
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A route() 0 21 3
A validateKey() 0 5 2
A validateExtension() 0 6 3
A throttle() 0 2 1
A validateAccess() 0 2 1
A executeEndpoint() 0 3 1
1
<?php
2
namespace LunixREST\Router;
3
4
use LunixREST\AccessControl\AccessControl;
5
use LunixREST\Endpoint\Endpoint;
6
use LunixREST\Endpoint\EndpointFactory;
7
use LunixREST\Endpoint\Exceptions\UnknownEndpointException;
8
use LunixREST\Exceptions\AccessDeniedException;
9
use LunixREST\Exceptions\InvalidAPIKeyException;
10
use LunixREST\Exceptions\ThrottleLimitExceededException;
11
use LunixREST\Request\Request;
12
use LunixREST\Response\Exceptions\UnknownResponseTypeException;
13
use LunixREST\Response\Response;
14
use LunixREST\Response\ResponseData;
15
use LunixREST\Response\ResponseFactory;
16
use LunixREST\Throttle\Throttle;
17
18
/**
19
 * Class Router
20
 * @package LunixREST\Router
21
 */
22
class Router {
23
    /**
24
     * @var AccessControl
25
     */
26
    protected $accessControl;
27
    /**
28
     * @var Throttle
29
     */
30
    protected $throttle;
31
    /**
32
     * @var ResponseFactory
33
     */
34
    protected $responseFactory;
35
    /**
36
     * @var EndpointFactory
37
     */
38
    private $endpointFactory;
39
40
    /**
41
     * @param AccessControl $accessControl
42
     * @param Throttle $throttle
43
     * @param ResponseFactory $responseFactory
44
     * @param EndpointFactory $endpointFactory
45
     */
46
    public function __construct(AccessControl $accessControl, Throttle $throttle, ResponseFactory $responseFactory, EndpointFactory $endpointFactory){
47
        $this->accessControl = $accessControl;
48
        $this->throttle = $throttle;
49
        $this->responseFactory = $responseFactory;
50
        $this->endpointFactory = $endpointFactory;
51
    }
52
53
    /**
54
     * @param Request $request
55
     * @return Response
56
     * @throws AccessDeniedException
57
     * @throws InvalidAPIKeyException
58
     * @throws ThrottleLimitExceededException
59
     * @throws UnknownEndpointException
60
     * @throws UnknownResponseTypeException
61
     */
62
    public function route(Request $request): Response{
63
        $this->validateKey($request);
64
65
        $this->validateExtension($request);
66
67
        $endpoint = $this->endpointFactory->getEndpoint($request->getEndpoint(), $request->getVersion());
68
69
        if($this->throttle->shouldThrottle($request)) {
70
            throw new ThrottleLimitExceededException('Request limit exceeded');
71
        }
72
73
        if(!$this->accessControl->validateAccess($request)) {
74
            throw new AccessDeniedException("API key does not have the required permissions to access requested resource");
75
        }
76
77
        $this->throttle->logRequest($request);
78
79
        $responseData = $this->executeEndpoint($endpoint, $request);
80
81
        return $this->responseFactory->getResponse($responseData, $request->getExtension());
82
    }
83
84
    /**
85
     * @param Request $request
86
     * @throws InvalidAPIKeyException
87
     */
88
    protected function validateKey(Request $request){
89
        if(!$this->accessControl->validateKey($request->getApiKey())){
90
            throw new InvalidAPIKeyException('Invalid API key');
91
        }
92
    }
93
94
    /**
95
     * @param Request $request
96
     * @throws UnknownResponseTypeException
97
     */
98
    protected function validateExtension(Request $request) {
99
        $formats = $this->responseFactory->getSupportedTypes();
100
        if(!$formats || !in_array($request->getExtension(), $formats)){
0 ignored issues
show
Bug Best Practice introduced by
The expression $formats of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
101
            throw new UnknownResponseTypeException('Unknown response format: ' . $request->getExtension());
102
        }
103
    }
104
105
    /**
106
     * @param Request $request
107
     * @throws ThrottleLimitExceededException
108
     */
109
    protected function throttle(Request $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
110
    }
111
112
    /**
113
     * @param Request $request
114
     * @throws AccessDeniedException
115
     */
116
    protected function validateAccess(Request $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
117
    }
118
119
    protected function executeEndpoint(Endpoint $endpoint, Request $request): ResponseData {
120
        return call_user_func([$endpoint, $request->getMethod()], [$request]);
121
    }
122
}
123