Completed
Pull Request — master (#427)
by Anton
06:09
created

AbstractMapper::run()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
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
     * @param AbstractCrud $crud
92
     */
93 16
    public function __construct(AbstractCrud $crud)
94
    {
95 16
        $this->crud = $crud;
96 16
    }
97
98
    /**
99
     * Add mapping data
100
     *
101
     * @param string $method
102
     * @param string $module
103
     * @param string $controller
104
     * @param String $acl
105
     */
106 15
    public function addMap($method, $module, $controller, $acl = null)
107
    {
108 15
        $this->map[strtoupper($method)] = [
109 15
            'module' => $module,
110 15
            'controller' => $controller,
111 15
            'acl' => $acl
112
        ];
113 15
    }
114
115
    /**
116
     * Add mapping for HEAD method
117
     *
118
     * @param string $module
119
     * @param string $controller
120
     * @param String $acl
121
     */
122
    public function head($module, $controller, $acl = null)
123
    {
124
        $this->addMap(RequestMethod::HEAD, $module, $controller, $acl);
125
    }
126
127
    /**
128
     * Add mapping for GET method
129
     *
130
     * @param string $module
131
     * @param string $controller
132
     * @param String $acl
133
     */
134
    public function get($module, $controller, $acl = null)
135
    {
136
        $this->addMap(RequestMethod::GET, $module, $controller, $acl);
137
    }
138
139
    /**
140
     * Add mapping for POST method
141
     *
142
     * @param string $module
143
     * @param string $controller
144
     * @param String $acl
145
     */
146
    public function post($module, $controller, $acl = null)
147
    {
148
        $this->addMap(RequestMethod::POST, $module, $controller, $acl);
149
    }
150
151
    /**
152
     * Add mapping for PATCH method
153
     *
154
     * @param string $module
155
     * @param string $controller
156
     * @param String $acl
157
     */
158
    public function patch($module, $controller, $acl = null)
159
    {
160
        $this->addMap(RequestMethod::PATCH, $module, $controller, $acl);
161
    }
162
163
    /**
164
     * Add mapping for PUT method
165
     *
166
     * @param string $module
167
     * @param string $controller
168
     * @param String $acl
169
     */
170
    public function put($module, $controller, $acl = null)
171
    {
172
        $this->addMap(RequestMethod::PUT, $module, $controller, $acl);
173
    }
174
175
    /**
176
     * Add mapping for DELETE method
177
     *
178
     * @param string $module
179
     * @param string $controller
180
     * @param String $acl
181
     */
182
    public function delete($module, $controller, $acl = null)
183
    {
184
        $this->addMap(RequestMethod::DELETE, $module, $controller, $acl);
185
    }
186
187
    /**
188
     * Add mapping for OPTIONS method
189
     *
190
     * @param string $module
191
     * @param string $controller
192
     * @param String $acl
193
     */
194
    public function options($module, $controller, $acl = null)
195
    {
196
        $this->addMap(RequestMethod::OPTIONS, $module, $controller, $acl);
197
    }
198
199
    /**
200
     * Run
201
     *
202
     * @return Controller
203
     * @throws ControllerException
204
     * @throws ForbiddenException
205
     * @throws NotImplementedException
206
     */
207 16
    public function run()
208
    {
209 16
        $this->prepareRequest();
210 16
        return $this->dispatch();
211
    }
212
213
    /**
214
     * Prepare request for processing
215
     *
216
     * @throws \Bluz\Controller\ControllerException
217
     */
218 16
    protected function prepareRequest()
219
    {
220
        // HTTP method
221 16
        $method = Request::getMethod();
222 16
        $this->method = strtoupper($method);
223
224
        // get path
225
        // %module% / %controller% / %id% / %relation% / %id%
226 16
        $path = Router::getCleanUri();
227
228 16
        $this->params = explode('/', rtrim($path, '/'));
229
230
        // module
231 16
        $this->module = array_shift($this->params);
232
233
        // controller
234 16
        $this->controller = array_shift($this->params);
235
236 16
        $data = Request::getParams();
237
238 16
        unset($data['_method'], $data['_module'], $data['_controller']);
239
240 16
        $this->data = $data;
241
242 16
        $primary = $this->crud->getPrimaryKey();
243 16
        $this->primary = array_intersect_key($this->data, array_flip($primary));
244 16
    }
245
246
    /**
247
     * Prepare params
248
     *
249
     * @return array
250
     */
251 6
    protected function prepareParams(): array
252
    {
253
        return [
254 6
            'crud' => $this->crud,
255 6
            'primary' => $this->primary,
256 6
            'data' => $this->data
257
        ];
258
    }
259
260
    /**
261
     * Dispatch REST or CRUD controller
262
     *
263
     * @return mixed
264
     * @throws ForbiddenException
265
     * @throws NotImplementedException
266
     */
267 16
    protected function dispatch()
268
    {
269
        // check implementation
270 16
        if (!isset($this->map[$this->method])) {
271 1
            throw new NotImplementedException;
272
        }
273
274 15
        $map = $this->map[$this->method];
275
276
        // check permissions
277 15
        if (isset($map['acl'])) {
278 2
            if (!Acl::isAllowed($this->module, $map['acl'])) {
279 2
                throw new ForbiddenException;
280
            }
281
        }
282
283
        // dispatch controller
284 13
        return Application::getInstance()->dispatch(
285 13
            $map['module'],
286 13
            $map['controller'],
287 13
            $this->prepareParams()
288
        );
289
    }
290
}
291