Completed
Push — master ( c3f5de...3ceb61 )
by Samuel
03:26
created

Api::patch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 3
crap 1
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 16
    public function __construct(
48
        RouteResolverInterface $routeResolver,
49 1
        Request $request,
50
        Response $response,
51
        Container $container,
52
        ValidatorInterface $validator = null
53
    ) {
54 16
        $this->routeResolver = $routeResolver;
55 16
        $this->request = $request;
56 16
        $this->response = $response;
57 16
        $this->container = $container;
58 16
        $this->validator = $validator ?: new Validator();
59 16
        $this->routes = new RouteContainer();
60 16
    }
61
62
    /**
63
     * Add api call
64
     * @param string $method
65
     * @param string $pattern
66
     * @param string $handler
67
     * @param array $params
68
     */
69 16
    public function add($method, $pattern, $handler, $params = [])
70
    {
71 16
        $this->routes->add(new Route($method, $pattern, $handler, $params));
72 16
    }
73
74
    /**
75
     * Add get api call
76
     * @param string $pattern
77
     * @param string $handler
78
     * @param array $params
79
     */
80 14
    public function get($pattern, $handler, $params = [])
81
    {
82 14
        $this->add('get', $pattern, $handler, $params);
83 14
    }
84
85
    /**
86
     * Add post api call
87
     * @param string $pattern
88
     * @param string $handler
89
     * @param array $params
90
     */
91 4
    public function post($pattern, $handler, $params = [])
92
    {
93 4
        $this->add('post', $pattern, $handler, $params);
94 4
    }
95
96
    /**
97
     * Add put api call
98
     * @param string $pattern
99
     * @param string $handler
100
     * @param array $params
101
     */
102 2
    public function put($pattern, $handler, $params = [])
103
    {
104 2
        $this->add('put', $pattern, $handler, $params);
105 2
    }
106
107
    /**
108
     * Add patch api call
109
     * @param string $pattern
110
     * @param string $handler
111
     * @param array $params
112
     */
113 2
    public function patch($pattern, $handler, $params = [])
114
    {
115 2
        $this->add('patch', $pattern, $handler, $params);
116 2
    }
117
118
    /**
119
     * Add delete api call
120
     * @param string $pattern
121
     * @param string $handler
122
     * @param array $params
123
     */
124 2
    public function delete($pattern, $handler, $params = [])
125
    {
126 2
        $this->add('delete', $pattern, $handler, $params);
127 2
    }
128
129
    /**
130
     * Add options api call
131
     * @param string $pattern
132
     * @param string $handler
133
     * @param array $params
134
     */
135 2
    public function options($pattern, $handler, $params = [])
136
    {
137 2
        $this->add('options', $pattern, $handler, $params);
138 2
    }
139
140
    /**
141
     * Returns all registered routes
142
     * @return RouteContainer
143
     */
144 2
    public function getRoutes()
145
    {
146 2
        return $this->routes;
147
    }
148
149
    /**
150
     * @param string $url
151
     * @return IResponse
152
     * @throws UnresolvedHandlerException
153
     * @throws UnresolvedRouteException
154
     * @throws ValidationFailedException
155
     */
156 14
    public function run($url)
157
    {
158 14
        $resolvedRoute = $this->routeResolver->resolve($this->routes, $url);
159 14
        if (!$resolvedRoute) {
160 2
            throw new UnresolvedRouteException();
161
        }
162
163 12
        $handler = $this->getFromContainer($resolvedRoute->getRoute()->getHandler());
164 12
        if (!$handler) {
165 4
            throw new UnresolvedHandlerException('Handler ' . $resolvedRoute->getRoute()->getHandler() . ' not found in container');
166
        }
167
168 8
        $this->validator->setInput('path', new CustomInput($resolvedRoute->getParams()));
169 8
        $this->validator->validate($handler->validate());
170
171 8
        if (!$this->validator->isValid()) {
172 2
            throw new ValidationFailedException($this->validator);
173
        }
174
175 6
        $handler->setValidatedValues($this->validator->getValues());
176
177 6
        $middleware = $resolvedRoute->getRoute()->getConfig('middleware');
178 6
        $runner = new Runner($middleware ?: [], $handler, $this->container);
179 6
        $response = $runner($this->request, $this->response);
180 2
        return $response;
181
    }
182
183
    /**
184
     * Get service by type or name from container
185
     * @param string $entry
186
     * @return bool|object
187
     */
188 12 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...
189
    {
190
        try {
191 12
            if (substr($entry, 0, 1) === '#') {
192 12
                return $this->container->getService(substr($entry, 1));
193
            }
194
195
            return $this->container->getByType($entry);
196 4
        } catch (MissingServiceException $e) {
197 4
            return false;
198
        }
199
    }
200
}
201