Completed
Push — master ( 188ba1...86d637 )
by Samuel
02:55
created

Api::run()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 6.4268

Importance

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