Completed
Push — master ( ccfc27...d48d2e )
by Anton
14s
created

AbstractMapper::dispatch()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 3
nop 0
dl 0
loc 21
ccs 10
cts 10
cp 1
crap 4
rs 9.0534
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link      https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Controller\Mapper;
12
13
use Bluz\Application\Application;
14
use Bluz\Application\Exception\ForbiddenException;
15
use Bluz\Application\Exception\NotImplementedException;
16
use Bluz\Controller\Controller;
17
use Bluz\Controller\ControllerException;
18
use Bluz\Crud\AbstractCrud;
19
use Bluz\Http\RequestMethod;
20
use Bluz\Proxy\Acl;
21
use Bluz\Proxy\Request;
22
use Bluz\Proxy\Router;
23
24
/**
25
 * Mapper for controller
26
 *
27
 * @package  Bluz\Rest
28
 * @author   Anton Shevchuk
29
 */
30
abstract class AbstractMapper
31
{
32
    /**
33
     * @var string HTTP Method
34
     */
35
    protected $method = RequestMethod::GET;
36
37
    /**
38
     * @var string
39
     */
40
    protected $module;
41
42
    /**
43
     * @var string
44
     */
45
    protected $controller;
46
47
    /**
48
     * @var array identifier
49
     */
50
    protected $primary;
51
52
    /**
53
     * @var string relation list
54
     */
55
    protected $relation;
56
57
    /**
58
     * @var string relation Id
59
     */
60
    protected $relationId;
61
62
    /**
63
     * @var array params of query
64
     */
65
    protected $params = [];
66
67
    /**
68
     * @var array query data
69
     */
70
    protected $data = [];
71
72
    /**
73
     * @var AbstractCrud instance of CRUD
74
     */
75
    protected $crud;
76
77
    /**
78
     * [
79
     *     METHOD => [
80
     *         'module' => 'module',
81
     *         'controller' => 'controller',
82
     *         'acl' => 'privilege',
83
     *     ],
84
     * ]
85
     *
86
     * @var array
87
     */
88
    protected $map = [];
89
90
    /**
91
     * Prepare params
92
     *
93
     * @return array
94
     */
95
    abstract protected function prepareParams(): array;
96
97
    /**
98
     * @param AbstractCrud $crud
99
     */
100 16
    public function __construct(AbstractCrud $crud)
101
    {
102 16
        $this->crud = $crud;
103 16
    }
104
105
    /**
106
     * Add mapping data
107
     *
108
     * @param string $method
109
     * @param string $module
110
     * @param string $controller
111
     * @param String $acl
112
     */
113 15
    public function addMap($method, $module, $controller, $acl = null)
114
    {
115 15
        $this->map[strtoupper($method)] = [
116 15
            'module' => $module,
117 15
            'controller' => $controller,
118 15
            'acl' => $acl
119
        ];
120 15
    }
121
122
    /**
123
     * Add mapping for HEAD method
124
     *
125
     * @param string $module
126
     * @param string $controller
127
     * @param String $acl
128
     */
129
    public function head($module, $controller, $acl = null)
130
    {
131
        $this->addMap(RequestMethod::HEAD, $module, $controller, $acl);
132
    }
133
134
    /**
135
     * Add mapping for GET method
136
     *
137
     * @param string $module
138
     * @param string $controller
139
     * @param String $acl
140
     */
141
    public function get($module, $controller, $acl = null)
142
    {
143
        $this->addMap(RequestMethod::GET, $module, $controller, $acl);
144
    }
145
146
    /**
147
     * Add mapping for POST method
148
     *
149
     * @param string $module
150
     * @param string $controller
151
     * @param String $acl
152
     */
153
    public function post($module, $controller, $acl = null)
154
    {
155
        $this->addMap(RequestMethod::POST, $module, $controller, $acl);
156
    }
157
158
    /**
159
     * Add mapping for PATCH method
160
     *
161
     * @param string $module
162
     * @param string $controller
163
     * @param String $acl
164
     */
165
    public function patch($module, $controller, $acl = null)
166
    {
167
        $this->addMap(RequestMethod::PATCH, $module, $controller, $acl);
168
    }
169
170
    /**
171
     * Add mapping for PUT method
172
     *
173
     * @param string $module
174
     * @param string $controller
175
     * @param String $acl
176
     */
177
    public function put($module, $controller, $acl = null)
178
    {
179
        $this->addMap(RequestMethod::PUT, $module, $controller, $acl);
180
    }
181
182
    /**
183
     * Add mapping for DELETE method
184
     *
185
     * @param string $module
186
     * @param string $controller
187
     * @param String $acl
188
     */
189
    public function delete($module, $controller, $acl = null)
190
    {
191
        $this->addMap(RequestMethod::DELETE, $module, $controller, $acl);
192
    }
193
194
    /**
195
     * Add mapping for OPTIONS method
196
     *
197
     * @param string $module
198
     * @param string $controller
199
     * @param String $acl
200
     */
201
    public function options($module, $controller, $acl = null)
202
    {
203
        $this->addMap(RequestMethod::OPTIONS, $module, $controller, $acl);
204
    }
205
206
    /**
207
     * Run
208
     *
209
     * @return Controller
210
     * @throws ControllerException
211
     * @throws ForbiddenException
212
     * @throws NotImplementedException
213
     */
214 16
    public function run()
215
    {
216 16
        $this->prepareRequest();
217 16
        return $this->dispatch();
218
    }
219
220
    /**
221
     * Prepare request for processing
222
     *
223
     * @throws \Bluz\Controller\ControllerException
224
     */
225 16
    protected function prepareRequest()
226
    {
227
        // HTTP method
228 16
        $method = Request::getMethod();
229 16
        $this->method = strtoupper($method);
230
231
        // get path
232
        // %module% / %controller% / %id% / %relation% / %id%
233 16
        $path = Router::getCleanUri();
234
235 16
        $this->params = explode('/', rtrim($path, '/'));
236
237
        // module
238 16
        $this->module = array_shift($this->params);
239
240
        // controller
241 16
        $this->controller = array_shift($this->params);
242
243 16
        $data = Request::getParams();
244
245 16
        unset($data['_method'], $data['_module'], $data['_controller']);
246
247 16
        $this->data = $data;
248
249 16
        $primary = $this->crud->getPrimaryKey();
250 16
        $this->primary = array_intersect_key($this->data, array_flip($primary));
251 16
    }
252
253
    /**
254
     * Dispatch REST or CRUD controller
255
     *
256
     * @return mixed
257
     * @throws ForbiddenException
258
     * @throws NotImplementedException
259
     */
260 16
    protected function dispatch()
261
    {
262
        // check implementation
263 16
        if (!isset($this->map[$this->method])) {
264 1
            throw new NotImplementedException;
265
        }
266
267 15
        $map = $this->map[$this->method];
268
269
        // check permissions
270 15
        if (isset($map['acl']) && !Acl::isAllowed($this->module, $map['acl'])) {
271 2
            throw new ForbiddenException;
272
        }
273
274
        // dispatch controller
275 13
        return Application::getInstance()->dispatch(
276 13
            $map['module'],
277 13
            $map['controller'],
278 13
            $this->prepareParams()
279
        );
280
    }
281
}
282