Completed
Pull Request — master (#435)
by Anton
04:35
created

AbstractMapper::addMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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