Completed
Push — master ( 36eb3a...3830bc )
by Samuel
02:27
created

Api   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 175
Duplicated Lines 6.86 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 48.15%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
c 1
b 0
f 0
lcom 1
cbo 11
dl 12
loc 175
ccs 26
cts 54
cp 0.4815
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 29 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\HandlerException;
6
use Kelemen\ApiNette\Route\RouteResolverInterface;
7
use Kelemen\ApiNette\Route\Route;
8
use Kelemen\ApiNette\Route\RouteContainer;
9
use Kelemen\ApiNette\Validator\Input\CustomInput;
10
use Kelemen\ApiNette\Validator\Validator;
11
use Kelemen\ApiNette\Validator\ValidatorInterface;
12
use Nette\DI\Container;
13
use Nette\DI\MissingServiceException;
14
use Nette\Http\IResponse;
15
use Nette\Http\Request;
16
use Nette\Http\Response;
17
use Kelemen\ApiNette\Response\JsonApiResponse;
18
19
class Api
20
{
21
    /** @var RouteResolverInterface */
22
    private $routeResolver;
23
24
    /** @var RouteContainer */
25
    private $routes;
26
27
    /** @var Request */
28
    private $request;
29
30
    /** @var Response */
31
    private $response;
32
33
    /** @var Container */
34
    private $container;
35
36
    /** @var ValidatorInterface */
37
    private $validator;
38
39
    /**
40
     * @param RouteResolverInterface $routeResolver
41
     * @param Request $request
42
     * @param Response $response
43
     * @param Container $container
44
     * @param ValidatorInterface $validator
45
     */
46 4
    public function __construct(
47
        RouteResolverInterface $routeResolver,
48
        Request $request,
49
        Response $response,
50
        Container $container,
51
        ValidatorInterface $validator = null
52
    ) {
53 4
        $this->routeResolver = $routeResolver;
54 4
        $this->request = $request;
55 4
        $this->response = $response;
56 4
        $this->container = $container;
57 4
        $this->validator = $validator ?: new Validator();
58 4
        $this->routes = new RouteContainer();
59 4
    }
60
61
    /**
62
     * Add api call
63
     * @param string $method
64
     * @param string $pattern
65
     * @param string $handler
66
     * @param array $params
67
     */
68 2
    public function add($method, $pattern, $handler, $params = [])
69
    {
70 2
        $this->routes->add(new Route($method, $pattern, $handler, $params));
71 2
    }
72
73
    /**
74
     * Add get api call
75
     * @param string $pattern
76
     * @param string $handler
77
     * @param array $params
78
     */
79
    public function get($pattern, $handler, $params = [])
80
    {
81
        $this->add('get', $pattern, $handler, $params);
82
    }
83
84
    /**
85
     * Add post api call
86
     * @param string $pattern
87
     * @param string $handler
88
     * @param array $params
89
     */
90 2
    public function post($pattern, $handler, $params = [])
91
    {
92 2
        $this->add('post', $pattern, $handler, $params);
93 2
    }
94
95
    /**
96
     * Add put api call
97
     * @param string $pattern
98
     * @param string $handler
99
     * @param array $params
100
     */
101
    public function put($pattern, $handler, $params = [])
102
    {
103
        $this->add('put', $pattern, $handler, $params);
104
    }
105
106
    /**
107
     * Add patch api call
108
     * @param string $pattern
109
     * @param string $handler
110
     * @param array $params
111
     */
112
    public function patch($pattern, $handler, $params = [])
113
    {
114
        $this->add('patch', $pattern, $handler, $params);
115
    }
116
117
    /**
118
     * Add delete api call
119
     * @param string $pattern
120
     * @param string $handler
121
     * @param array $params
122
     */
123
    public function delete($pattern, $handler, $params = [])
124
    {
125
        $this->add('delete', $pattern, $handler, $params);
126
    }
127
128
    /**
129
     * Add options api call
130
     * @param string $pattern
131
     * @param string $handler
132
     * @param array $params
133
     */
134
    public function options($pattern, $handler, $params = [])
135
    {
136
        $this->add('options', $pattern, $handler, $params);
137
    }
138
139
    /**
140
     * Run api
141
     * @param string $url
142
     * @return JsonApiResponse
143
     * @throws Exception\ValidatorException
144
     * @throws HandlerException
145
     */
146 4
    public function run($url)
147
    {
148 4
        $resolvedRoute = $this->routeResolver->resolve($this->routes, $url);
149 4
        if (!$resolvedRoute) {
150 2
            return new JsonApiResponse(IResponse::S400_BAD_REQUEST, ['error' => 'Unresolved api route']);
151
        }
152
153 2
        $handler = $this->getFromContainer($resolvedRoute->getRoute()->getHandler());
154 2
        if (!$handler) {
155 2
            throw new HandlerException('Handler ' . $resolvedRoute->getRoute()->getHandler() . ' not found in container');
156
        }
157
158
        $this->validator->setInput('path', new CustomInput($resolvedRoute->getParams()));
159
        $this->validator->validate($handler->validate());
160
161
        if (!$this->validator->isValid()) {
162
            return new JsonApiResponse(IResponse::S400_BAD_REQUEST, [
163
                'error' => 'Bad input parameter',
164
                'errors' => $this->validator->getErrors()
165
            ]);
166
        }
167
168
        $handler->setValidatedValues($this->validator->getValues());
169
170
        $middleware = $resolvedRoute->getRoute()->getConfig('middleware');
171
        $runner = new Runner($middleware ?: [], $handler, $this->container);
172
        $response = $runner($this->request, $this->response);
173
        return $response;
174
    }
175
176
    /**
177
     * Get service by type or name from container
178
     * @param string $entry
179
     * @return bool|object
180
     */
181 2 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...
182
    {
183
        try {
184 2
            if (substr($entry, 0, 1) === '#') {
185 2
                return $this->container->getService(substr($entry, 1));
186
            }
187
188
            return $this->container->getByType($entry);
189 2
        } catch (MissingServiceException $e) {
190 2
            return false;
191
        }
192
    }
193
}
194