Passed
Push — master ( fc16cc...94b874 )
by Vince
01:35
created

map::isEndpoint()   D

Complexity

Conditions 19
Paths 24

Size

Total Lines 123
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 19
eloc 57
c 5
b 0
f 0
nc 24
nop 2
dl 0
loc 123
rs 4.5166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * ==================================
5
 * Responsible PHP API
6
 * ==================================
7
 *
8
 * @link Git https://github.com/vince-scarpa/responsibleAPI.git
9
 *
10
 * @api Responible API
11
 * @package responsible\core\endpoints
12
 *
13
 * @author Vince scarpa <[email protected]>
14
 *
15
 */
16
namespace responsible\core\endpoints;
17
18
use responsible\core\endpoints;
19
use responsible\core\exception;
20
use responsible\core\route;
21
use responsible\core\interfaces;
22
23
class map extends route\router implements interfaces\optionsInterface
24
{
25
    use \responsible\core\traits\optionsTrait;
26
27
    /**
28
     * [$BASE_ENDPOINTS]
29
     * @var array
30
     */
31
    private $BASE_ENDPOINTS = array();
32
33
    /**
34
     * [$BASE_ENDPOINTS]
35
     * @var array
36
     */
37
    private $NAMESPACE_ENDPOINTS = array();
38
39
    /**
40
     * [$registry]
41
     * @var array
42
     */
43
    private $registry = array();
44
45
    /**
46
     * [$middleWareClass Holds middleware class object]
47
     * @var object
48
     */
49
    private static $middleWareClass;
50
51
    /**
52
     * [$SYSTEM_ENDPOINTS Reserved system Endpoints]
53
     * @var array
54
     */
55
    const SYSTEM_ENDPOINTS = [
56
        'token' => '/token/access_token',
57
        'user' => [
58
            '/user/create',
59
            '/user/load',
60
        ],
61
    ];
62
63
    /**
64
     * [__construct Silence...]
65
     */
66
    public function __construct() {}
67
68
    /**
69
     * [register Scan and register endpoints defined in services]
70
     * @return array
71
     */
72
    public function register()
73
    {
74
        $options = $this->options;
75
76
        /**
77
         * Check if a custom directory was set in the Responsible API options
78
         */
79
        if( (isset($options['classRoute']) && !empty($options['classRoute'])) && 
80
            (isset($options['classRoute']['directory']) && isset($options['classRoute']['namespace']))
81
        ) {
82
            $customService = $this->options['classRoute'];
83
            $directory = $customService['directory'];
84
            $middleware = $customService['namespace'];
85
86
        }else {
87
            $middleware = 'responsible';
88
89
            $endpoint = str_replace(
90
                array('core', '/', '\\'),
91
                array('service', DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR),
92
                __NAMESPACE__
93
            );
94
95
            $directory = $this->route()->base['root'] . '/' . str_replace('responsible/', '', $endpoint);
96
        }
97
98
        if (!is_dir($directory)) {
99
            (new exception\errorException)
100
                ->message('Directory Error:: responsible\service needs to exist. See documentation on setting up a service.')
101
                ->error('NOT_EXTENDED');
102
        }
103
104
        $scanned = '';
105
        $scanDir = scandir($directory);
106
107
        if (!empty($scanDir)) { 
108
            $scanned = array_values(
109
                array_diff(
110
                    $scanDir,
111
                    array('..', '.', '.DS_Store')
112
                )
113
            );
114
        }
115
116
        if (empty($scanned)) {
117
            (new exception\errorException)
118
                ->message('Class Error:: responsible\service\endpoints needs at least 1 class file. See documentation on setting up a service.')
119
                ->error('NOT_EXTENDED');
120
        }
121
122
        foreach ($scanned as $e => $point) {
123
124
            if (substr($point, -4) == '.php') {
125
                $point = str_replace('.php', '', $point);
126
127
                $this->BASE_ENDPOINTS[] = $point;
128
129
                $endpoint = str_replace('core', 'service', __NAMESPACE__) . '\\' . $point;
130
131
                if ($middleware !== 'responsible') {
132
                    $endpoint = $middleware . '\\service\\endpoints\\' . $point;
133
                }
134
135
                $child = $endpoint;
136
137
                $this->NAMESPACE_ENDPOINTS[$point] = $endpoint;
138
139
                if (class_exists($child)) {
140
                    self::$middleWareClass = new $child;
141
                    $this->registry[$point] = self::$middleWareClass->register();
142
                }else{
143
                    (new exception\errorException)
144
                        ->message("Class Error:: class {$child} needs to exist. See documentation on setting up a service.")
145
                        ->error('NOT_EXTENDED');
146
                }
147
            }
148
        }
149
150
        return $this->registry;
151
    }
152
153
    /**
154
     * [isSystemEndpoint Check if the endpoint request is a ResponsibleAPI reserved endpoint]
155
     * @param  string  $api
156
     * @param  string  $endpoint
157
     * @return object|null
158
     */
159
    private function isSystemEndpoint($api, $endpoint)
160
    {
161
        $endpointSettings = [];
162
163
        if (isset(self::SYSTEM_ENDPOINTS[$api]) &&
164
            (
165
                in_array($endpoint, self::SYSTEM_ENDPOINTS) ||
166
                array_search($endpoint, self::SYSTEM_ENDPOINTS[$api]) !== false
167
            )
168
        ) {
169
            $methodCreate = explode('/', $endpoint);
170
            $methodCreate = array_values(array_filter($methodCreate));
171
            $method = '';
172
173
            foreach ($methodCreate as $i => $parts) {
174
                if (preg_match_all('#_#', $parts)) {
175
                    $parts = str_replace('_', '', lcfirst(ucwords($parts, '_')));
176
                }
177
                if ($i > 0) {
178
                    $method .= ucfirst($parts);
179
                } else {
180
                    $method .= $parts;
181
                }
182
            }
183
184
            $endpointSettings['model'] = array(
185
                'scope' => 'system',
186
                'namespace' => 'responsible\core\endpoints\system',
187
                'class' => 'system',
188
                'method' => $method,
189
                'arguments' => '',
190
            );
191
192
            return (object) $endpointSettings;
193
        }
194
195
        return null;
196
    }
197
198
    /**
199
     * [isEndpoint Check the requested endpoint, scope and tier parts]
200
     * @param  string  $api
201
     * @param  string  $endpoint
202
     * @return object|null
203
     */
204
    public function isEndpoint($api, $endpoint)
205
    {
206
        $endpointSettings = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $endpointSettings is dead and can be removed.
Loading history...
207
208
        /**
209
         * Return if it's a system endpoint
210
         */
211
        if (null !== ($endpointSettings = $this->isSystemEndpoint($api, $endpoint))) {
212
            return $endpointSettings;
213
        }
214
215
        $endpoint = htmlspecialchars($endpoint, ENT_QUOTES, 'UTF-8');
216
        $index = array_search($api, $this->BASE_ENDPOINTS);
217
218
        if ($index !== false) {
219
            if (isset($this->registry[$api])) {
220
                $endpointSettings = array(
221
                    'path' => $endpoint,
222
                    'model' => array(
223
                        'namespace' => $this->NAMESPACE_ENDPOINTS[$api],
224
                        'class' => $this->BASE_ENDPOINTS[$index],
225
                        'method' => basename($endpoint),
226
                        'scope' => 'private',
227
                    ),
228
                );
229
230
                /**
231
                 * Nothing dynamic, found an exact match
232
                 * @var array
233
                 */
234
                if (array_search($endpoint, $this->registry[$api]) !== false) {
235
                    if( method_exists($this->NAMESPACE_ENDPOINTS[$api], 'scope') ) {
236
                        $classScope = (new $this->NAMESPACE_ENDPOINTS[$api])->scope();
237
                        $position = array_search($endpoint, $this->registry[$api]);
238
                        
239
                        if( is_array($classScope) && isset($classScope[$position]) ) {
240
                            $endpointSettings['model']['scope'] = $classScope[$position];
241
242
                        }else{
243
244
                            if( !is_array($classScope) ) {
245
                                $endpointSettings['model']['scope'] = $classScope;
246
                            }
247
                        }
248
                    }
249
                    return (object) $endpointSettings;
250
                }
251
252
                /**
253
                 * Check for dynamic uri eg: {asset_id}
254
                 * Dynamic uri's must be wrapped in {} for a true return
255
                 */
256
                foreach ($this->registry[$api] as $i => $path) {
257
                    $endpointRegister = $path;
258
                    $methodArgs = [];
259
260
                    /**
261
                     * If comparing the two sizes are not equal
262
                     * then no use continuing through the loop
263
                     */
264
                    if (!$this->uriCheckSize($endpointRegister, $endpoint)) {
265
                        continue;
266
                    }
267
268
                    /**
269
                     * This replacment will create a pattern to use as a match all expression
270
                     * @var [string]
271
                     */
272
                    $endpointRegister = preg_replace('@/{(.*?)}@', '/(.*?)', $endpointRegister);
273
274
                    if (preg_match_all('@^' . $endpointRegister . '$@i', $endpoint, $dynamicParts)) {
275
                        $endpointFilter = $this->filterParts($endpoint, $dynamicParts);
276
                        $model = $this->getClassModel($path);
277
278
                        /**
279
                         * Find the dynamic parts and set them as argument key(s)
280
                         * then combine them with the endpoint request and set the request parts
281
                         * as argument value(s)
282
                         */
283
                        if (preg_match_all("/(?<={).*?(?=})/", $path, $registerParts)) {
284
                            if (isset($registerParts[0][0])) {
285
                                $registerParts = $registerParts[0];
286
287
                                if (sizeof($endpointFilter) == sizeof($registerParts)) {
288
                                    $methodArgs = array_combine($registerParts, $endpointFilter);
289
                                }
290
                            }
291
                        }
292
293
                        $scope = 'private';
294
295
                        if( method_exists($this->NAMESPACE_ENDPOINTS[$api], 'scope') ) {
296
                            $classScope = (new $this->NAMESPACE_ENDPOINTS[$api])->scope();
297
                            $position = array_search($path, $this->registry[$api]);
298
                            
299
                            if( is_array($classScope) && isset($classScope[$position]) ) {
300
                                $scope = $classScope[$position];
301
302
                            }else{
303
304
                                if( !is_array($classScope) ) {
305
                                    $scope = $classScope;
306
                                }
307
                            }
308
                        }
309
310
                        $endpointSettings['model'] = array(
311
                            'scope' => $scope,
312
                            'namespace' => $this->NAMESPACE_ENDPOINTS[$api],
313
                            'class' => $model['class'],
314
                            'method' => $model['method'],
315
                            'arguments' => $methodArgs,
316
                        );
317
318
                        return (object) $endpointSettings;
319
                    } else {
320
                        continue;
321
                    }
322
                }
323
            }
324
        }
325
326
        return;
327
    }
328
329
    /**
330
     * [filterParts Prepare routed parts]
331
     * @return array
332
     */
333
    private function filterParts($uri, $parts)
334
    {
335
        $filter = array();
336
337
        foreach ($parts as $p => $part) {
338
            if (is_array($part)) {
339
                foreach ($part as $i => $parti) {
340
                    if ($parti !== $uri) {
341
                        $filter[] = $parti;
342
                    }
343
                }
344
            }
345
        }
346
347
        return $filter;
348
    }
349
350
    /**
351
     * [uriCheckSize]
352
     *
353
     * Compare the current request endpoint with the registered endpoint
354
     * only return the same tier sizes
355
     *
356
     * @return boolean
357
     */
358
    private function uriCheckSize($endpointRegister, $endpoint)
359
    {
360
        $registerExplode = explode('/', $endpointRegister);
361
        $endpointExplode = explode('/', $endpoint);
362
        return (sizeof($registerExplode) === sizeof($endpointExplode));
363
    }
364
365
    /**
366
     * [getClassModel Class, Method]
367
     * @return array
368
     */
369
    private function getClassModel($request_path)
370
    {
371
        $cm = explode('/', $request_path);
372
373
        if (!empty($cm) && sizeof($cm) >= 2) {
374
            $cm = array_values(array_filter($cm));
375
376
            return array(
377
                'class' => $cm[0],
378
                'method' => $cm[1],
379
            );
380
        }
381
382
        return;
383
    }
384
}
385