Completed
Push — master ( 3830bc...2c9d17 )
by Samuel
02:31
created

Api   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 172
Duplicated Lines 6.98 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 73.08%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
c 1
b 0
f 0
lcom 1
cbo 12
dl 12
loc 172
ccs 38
cts 52
cp 0.7308
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 2
A add() 0 4 1
A get() 0 4 1
A post() 0 4 1
A put() 0 4 1
A patch() 0 4 1
A delete() 0 4 1
A options() 0 4 1
B run() 0 26 5
A getFromContainer() 12 12 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Kelemen\ApiNette;
4
5
use Kelemen\ApiNette\Exception\UnresolvedHandlerException;
6
use Kelemen\ApiNette\Exception\UnresolvedRouteException;
7
use Kelemen\ApiNette\Exception\ValidationFailedException;
8
use Kelemen\ApiNette\Route\RouteResolverInterface;
9
use Kelemen\ApiNette\Route\Route;
10
use Kelemen\ApiNette\Route\RouteContainer;
11
use Kelemen\ApiNette\Validator\Input\CustomInput;
12
use Kelemen\ApiNette\Validator\Validator;
13
use Kelemen\ApiNette\Validator\ValidatorInterface;
14
use Nette\Application\IResponse;
15
use Nette\DI\Container;
16
use Nette\DI\MissingServiceException;
17
use Nette\Http\Request;
18
use Nette\Http\Response;
19
20
class Api
21
{
22
    /** @var RouteResolverInterface */
23
    private $routeResolver;
24
25
    /** @var RouteContainer */
26
    private $routes;
27
28
    /** @var Request */
29
    private $request;
30
31
    /** @var Response */
32
    private $response;
33
34
    /** @var Container */
35
    private $container;
36
37
    /** @var ValidatorInterface */
38
    private $validator;
39
40
    /**
41
     * @param RouteResolverInterface $routeResolver
42
     * @param Request $request
43
     * @param Response $response
44
     * @param Container $container
45
     * @param ValidatorInterface $validator
46
     */
47 12
    public function __construct(
48
        RouteResolverInterface $routeResolver,
49 1
        Request $request,
50
        Response $response,
51
        Container $container,
52
        ValidatorInterface $validator = null
53
    ) {
54 12
        $this->routeResolver = $routeResolver;
55 12
        $this->request = $request;
56 12
        $this->response = $response;
57 12
        $this->container = $container;
58 12
        $this->validator = $validator ?: new Validator();
59 12
        $this->routes = new RouteContainer();
60 12
    }
61
62
    /**
63
     * Add api call
64
     * @param string $method
65
     * @param string $pattern
66
     * @param string $handler
67
     * @param array $params
68
     */
69 12
    public function add($method, $pattern, $handler, $params = [])
70
    {
71 12
        $this->routes->add(new Route($method, $pattern, $handler, $params));
72 12
    }
73
74
    /**
75
     * Add get api call
76
     * @param string $pattern
77
     * @param string $handler
78
     * @param array $params
79
     */
80 10
    public function get($pattern, $handler, $params = [])
81
    {
82 10
        $this->add('get', $pattern, $handler, $params);
83 10
    }
84
85
    /**
86
     * Add post api call
87
     * @param string $pattern
88
     * @param string $handler
89
     * @param array $params
90
     */
91 2
    public function post($pattern, $handler, $params = [])
92
    {
93 2
        $this->add('post', $pattern, $handler, $params);
94 2
    }
95
96
    /**
97
     * Add put api call
98
     * @param string $pattern
99
     * @param string $handler
100
     * @param array $params
101
     */
102
    public function put($pattern, $handler, $params = [])
103
    {
104
        $this->add('put', $pattern, $handler, $params);
105
    }
106
107
    /**
108
     * Add patch api call
109
     * @param string $pattern
110
     * @param string $handler
111
     * @param array $params
112
     */
113
    public function patch($pattern, $handler, $params = [])
114
    {
115
        $this->add('patch', $pattern, $handler, $params);
116
    }
117
118
    /**
119
     * Add delete api call
120
     * @param string $pattern
121
     * @param string $handler
122
     * @param array $params
123
     */
124
    public function delete($pattern, $handler, $params = [])
125
    {
126
        $this->add('delete', $pattern, $handler, $params);
127
    }
128
129
    /**
130
     * Add options api call
131
     * @param string $pattern
132
     * @param string $handler
133
     * @param array $params
134
     */
135
    public function options($pattern, $handler, $params = [])
136
    {
137
        $this->add('options', $pattern, $handler, $params);
138
    }
139
140
    /**
141
     * @param string $url
142
     * @return IResponse
143
     * @throws UnresolvedHandlerException
144
     * @throws UnresolvedRouteException
145
     * @throws ValidationFailedException
146
     */
147 12
    public function run($url)
148
    {
149 12
        $resolvedRoute = $this->routeResolver->resolve($this->routes, $url);
150 12
        if (!$resolvedRoute) {
151 2
            throw new UnresolvedRouteException();
152
        }
153
154 10
        $handler = $this->getFromContainer($resolvedRoute->getRoute()->getHandler());
155 10
        if (!$handler) {
156 4
            throw new UnresolvedHandlerException('Handler ' . $resolvedRoute->getRoute()->getHandler() . ' not found in container');
157
        }
158
159 6
        $this->validator->setInput('path', new CustomInput($resolvedRoute->getParams()));
160 6
        $this->validator->validate($handler->validate());
161
162 6
        if (!$this->validator->isValid()) {
163 2
            throw new ValidationFailedException($this->validator);
164
        }
165
166 4
        $handler->setValidatedValues($this->validator->getValues());
167
168 4
        $middleware = $resolvedRoute->getRoute()->getConfig('middleware');
169 4
        $runner = new Runner($middleware ?: [], $handler, $this->container);
170 4
        $response = $runner($this->request, $this->response);
171
        return $response;
172
    }
173
174
    /**
175
     * Get service by type or name from container
176
     * @param string $entry
177
     * @return bool|object
178
     */
179 10 View Code Duplication
    private function getFromContainer($entry)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
    {
181
        try {
182 10
            if (substr($entry, 0, 1) === '#') {
183 10
                return $this->container->getService(substr($entry, 1));
184
            }
185
186
            return $this->container->getByType($entry);
187 4
        } catch (MissingServiceException $e) {
188 4
            return false;
189
        }
190
    }
191
}
192