GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Addresses   F
last analyzed

Complexity

Total Complexity 60

Size/Duplication

Total Lines 566
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 141
c 1
b 0
f 0
dl 0
loc 566
rs 3.6
wmc 60

17 Methods

Rating   Name   Duplication   Size   Complexity  
A pool() 0 8 1
A head() 0 5 1
A put() 0 5 1
A delete() 0 5 1
A options() 0 5 1
A getTranslation() 0 17 5
A any() 0 5 1
A middleware() 0 13 4
C getTranslations() 0 50 12
A get() 0 5 1
A connect() 0 5 1
A domains() 0 4 2
A trace() 0 5 1
A domain() 0 15 3
B addTranslation() 0 41 8
A post() 0 5 1
C getDomain() 0 44 16

How to fix   Complexity   

Complex Class

Complex classes like Addresses often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Addresses, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Kernel\Http\Router;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Kernel\Http\Message\Uri\Domain;
19
20
/**
21
 * Class Addresses
22
 *
23
 * @package O2System\Kernel\Http\Router
24
 */
25
class Addresses
26
{
27
    /**
28
     * Addresses::HTTP_GET
29
     *
30
     * The GET method is used to retrieve information from the given server using a given URI.
31
     * Requests using GET should only retrieve data and should have no other effect on the data.
32
     *
33
     * @var string
34
     */
35
    const HTTP_GET = 'GET';
36
37
    /**
38
     * Addresses::HTTP_HEAD
39
     *
40
     * The HEAD method is used to retrieve only the status line and header section information from the given server
41
     * using a given URI. Requests using HEAD should only retrieve data and should have no other effect on the data.
42
     *
43
     * @var string
44
     */
45
    const HTTP_HEAD = 'HEAD';
46
47
    /**
48
     * Addresses::HTTP_POST
49
     *
50
     * The POST method is used to send data to the server.
51
     *
52
     * @var string
53
     */
54
    const HTTP_POST = 'POST';
55
56
    /**
57
     * Addresses::HTTP_PUT
58
     *
59
     * The PUT method is used to replaces all current representations of the target resource with the
60
     * uploaded content.
61
     *
62
     * @var string
63
     */
64
    const HTTP_PUT = 'PUT';
65
66
    /**
67
     * Addresses::HTTP_DELETE
68
     *
69
     * Removes all current representations of the target resource given by a URI.
70
     *
71
     * @var string
72
     */
73
    const HTTP_DELETE = 'DELETE';
74
75
    /**
76
     * Addresses::HTTP_CONNECT
77
     *
78
     * Establishes a tunnel to the server identified by a given URI.
79
     *
80
     * @var string
81
     */
82
    const HTTP_CONNECT = 'CONNECT';
83
84
    /**
85
     * Addresses::HTTP_OPTIONS
86
     *
87
     * Describes the communication options for the target resource.
88
     *
89
     * @var string
90
     */
91
    const HTTP_OPTIONS = 'OPTIONS';
92
93
    /**
94
     * Addresses::HTTP_TRACE
95
     *
96
     * Performs a message loop-back test along the path to the target resource.
97
     *
98
     * @var string
99
     */
100
    const HTTP_TRACE = 'TRACE';
101
102
    /**
103
     * Addresses::HTTP_ANY
104
     *
105
     * Any http type.
106
     *
107
     * @var string
108
     */
109
    const HTTP_ANY = 'ANY';
110
111
    /**
112
     * Addresses::$subDomains
113
     *
114
     * @var array
115
     */
116
    protected $domains = [];
117
118
    /**
119
     * Addresses::$translations
120
     *
121
     * @var array
122
     */
123
    protected $translations = [];
124
125
    /**
126
     * Addresses::$attributes
127
     *
128
     * @var array
129
     */
130
    protected $attributes = [];
131
132
    // ------------------------------------------------------------------------
133
134
    /**
135
     * @param      $path
136
     * @param null $domain
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $domain is correct as it would always require null to be passed?
Loading history...
137
     *
138
     * @return bool|\O2System\Kernel\Http\Router\DataStructures\Action
139
     */
140
    public function getTranslation($path, $domain = null)
141
    {
142
        $path = '/' . ltrim($path, '/');
143
        $translations = $this->getTranslations($domain);
144
145
        if (isset($translations[ $path ])) {
146
            return $translations[ $path ];
147
        } elseif (count($translations)) {
148
            foreach ($translations as $translation => $action) {
149
                if ($action->isValidUriString($path)) {
150
                    return $action;
151
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
152
                }
153
            }
154
        }
155
156
        return false;
157
    }
158
159
    // ------------------------------------------------------------------------
160
161
    /**
162
     * Addresses::getTranslations
163
     *
164
     * Gets array of domain routes translations.
165
     *
166
     * @param string $domain The domain url.
167
     *
168
     * @return array Returns array of domain routes maps.
169
     */
170
    public function getTranslations($domain = null)
171
    {
172
        $hostDomain = new Domain();
173
174
        if (is_null($domain)) {
175
            $domain = $hostDomain->getOrigin();
176
        }
177
178
        $translations = [];
179
180
        if (isset($this->translations[ $domain ])) {
181
            $translations = $this->translations[ $domain ];
182
        } else {
183
            $domain = new Domain($domain);
184
            if (array_key_exists($domain->getString(), $this->translations)) {
185
                $translations = $this->translations[ $domain->getString() ];
186
            } else {
187
                foreach ($this->translations as $domainRoute => $domainMap) {
188
                    if (preg_match('/[{][a-zA-Z0-9$_]+[}]/', $domainRoute)) {
189
                        $domainRoute = new Domain($domainRoute);
190
191
                        if ($domain->getParentDomain() === $domainRoute->getParentDomain() AND
192
                            $domain->getTotalSubDomains() == $domainRoute->getTotalSubDomains()
193
                        ) {
194
                            if (isset($domainMap[ $domainRoute->getSubDomain() ])) {
195
                                $translations = $domainMap;
196
                                $address = $translations[ $domainRoute->getSubDomain() ]->setClosureParameters(
197
                                    $domain->getSubDomains()
198
                                );
199
200
                                unset($translations[ $domainRoute->getSubDomain() ]);
201
202
                                if (false !== ($closureParameters = $address->getClosure())) {
203
204
                                    $closureParameters = ! is_array($closureParameters)
205
                                        ? [$closureParameters]
206
                                        : $closureParameters;
207
208
                                    foreach ($translations as $address) {
209
                                        $address->setClosureParameters((array)$closureParameters);
210
                                    }
211
                                }
212
                            }
213
                        }
214
                    }
215
                }
216
            }
217
        }
218
219
        return $translations;
220
    }
221
222
    // ------------------------------------------------------------------------
223
224
    /**
225
     * Addresses::any
226
     *
227
     * @param string $path    The URI string path.
228
     * @param mixed  $address The routing map of the URI:
229
     *                        [string]: string of controller name.
230
     *                        [array]: array of URI segment.
231
     *                        [\Closure]: the closure map of URI.
232
     *
233
     * @return static
234
     */
235
    public function any($path, $address)
236
    {
237
        $this->addTranslation($path, $address, self::HTTP_ANY);
238
239
        return $this;
240
    }
241
242
    // ------------------------------------------------------------------------
243
244
    /**
245
     * Addresses::addTranslation
246
     *
247
     * @param string  $path
248
     * @param string  $address
249
     * @param string  $method
250
     *
251
     * @return static
252
     */
253
    public function addTranslation($path, $address, $method = self::HTTP_GET)
254
    {
255
        $path = '/' . ltrim($path, '/');
256
257
        if ($address instanceof \Closure) {
0 ignored issues
show
introduced by
$address is never a sub-type of Closure.
Loading history...
258
            $closure = $address;
259
        } else {
260
261
            if (is_string($address)) {
0 ignored issues
show
introduced by
The condition is_string($address) is always true.
Loading history...
262
                $namespace = isset($this->attributes[ 'namespace' ])
263
                    ? $this->attributes[ 'namespace' ]
264
                    : null;
265
                $controllerClassName = trim($namespace, '\\') . '\\' . $address;
266
267
                if (class_exists($controllerClassName)) {
268
                    $address = $controllerClassName;
269
                }
270
            }
271
272
            $closure = function () use ($address) {
273
                return $address;
274
            };
275
        }
276
277
        $domain = isset($this->attributes[ 'domain' ])
278
            ? $this->attributes[ 'domain' ]
279
            : null;
280
281
        $prefix = isset($this->attributes[ 'prefix' ])
282
            ? $this->attributes[ 'prefix' ]
283
            : null;
284
285
        if ( ! preg_match('/[{][a-zA-Z0-9$_]+[}]/', $path)) {
286
            $path = '/' . trim(trim($prefix, '/') . '/' . trim($path, '/'), '/');
287
        }
288
289
        $action = new DataStructures\Action($method, $path, $closure, $domain);
290
291
        $this->translations[ $action->getDomain() ][ $action->getPath() ] = $action;
292
293
        return $this;
294
    }
295
296
    // ------------------------------------------------------------------------
297
298
    /**
299
     * Addresses::middleware
300
     *
301
     * @param array $middleware
302
     * @param bool  $register
303
     *
304
     * @return static
305
     */
306
    public function middleware(array $middleware, $register = true)
307
    {
308
        foreach ($middleware as $offset => $object) {
309
            $offset = is_numeric($offset) ? $object : $offset;
310
311
            if ($register) {
312
                middleware()->register($object, $offset);
0 ignored issues
show
Bug introduced by
The function middleware was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

312
                /** @scrutinizer ignore-call */ 
313
                middleware()->register($object, $offset);
Loading history...
313
            } else {
314
                middleware()->unregister($offset);
315
            }
316
        }
317
318
        return $this;
319
    }
320
321
    // ------------------------------------------------------------------------
322
323
    /**
324
     * Addresses::pool
325
     *
326
     * @param          $attributes
327
     * @param \Closure $closure
328
     */
329
    public function pool($attributes, \Closure $closure)
330
    {
331
        $parentAttributes = $this->attributes;
332
        $this->attributes = $attributes;
333
334
        call_user_func($closure, $this);
335
336
        $this->attributes = $parentAttributes;
337
    }
338
339
    // ------------------------------------------------------------------------
340
341
    /**
342
     * Addresses::domains
343
     *
344
     * @param array $domains
345
     */
346
    public function domains(array $domains)
347
    {
348
        foreach ($domains as $domain => $address) {
349
            $this->domain($domain, $address);
350
        }
351
    }
352
353
    // ------------------------------------------------------------------------
354
355
    /**
356
     * Addresses::domain
357
     *
358
     * @param string $domain
359
     * @param string $address
360
     */
361
    public function domain($domain, $address)
362
    {
363
        if ($domain !== '*') {
364
            $hostDomain = new Domain();
365
            $domainParts = explode('.', $domain);
366
367
            if (count($domainParts) == 1) {
368
                $domain = $domain . '.' . $hostDomain->getParentDomain();
369
            } else {
370
                $domain = str_replace('.' . $hostDomain->getParentDomain(), '',
371
                        $domain) . '.' . $hostDomain->getParentDomain();
372
            }
373
        }
374
375
        $this->domains[ $domain ] = $address;
376
    }
377
378
    // ------------------------------------------------------------------------
379
380
    /**
381
     * Addresses::getDomain
382
     *
383
     * @param string|null $domain
384
     *
385
     * @return int|mixed|string|null
386
     */
387
    public function getDomain($domain = null)
388
    {
389
        $domain = is_null($domain)
390
            ? isset($_SERVER[ 'HTTP_HOST' ])
391
                ? $_SERVER[ 'HTTP_HOST' ]
392
                : $_SERVER[ 'SERVER_NAME' ]
393
            : $domain;
394
395
        if (array_key_exists($domain, $this->domains)) {
396
            if (is_callable($this->domains[ $domain ])) {
397
                return call_user_func($this->domains[ $domain ]);
398
            }
399
400
            return $this->domains[ $domain ];
401
        } elseif (isset($this->domains[ '*' ]) and is_callable($this->domains[ '*' ])) {
402
            // check wildcard domain closure
403
            if (false !== ($address = call_user_func($this->domains[ '*' ], $domain))) {
404
                return $address;
405
            }
406
        } elseif (count($this->domains)) {
407
            // check pregmatch domain closure
408
            foreach ($this->domains as $address => $closure) {
409
                if (preg_match('/[{][a-zA-Z0-9$_]+[}]/', $address) and $closure instanceof \Closure) {
410
                    $addressDomain = new Domain($address);
411
                    $checkDomain = new Domain($domain);
412
                    $parameters = [];
413
414
                    if ($addressDomain->getTotalSubDomains() === $checkDomain->getTotalSubDomains()) {
415
                        foreach ($addressDomain->getSubDomains() as $level => $name) {
416
                            if (false !== ($checkDomainName = $checkDomain->getSubDomain($level))) {
417
                                $parameters[] = $checkDomainName;
418
                            }
419
                        }
420
421
                        if (false !== ($address = call_user_func_array($closure, $parameters))) {
422
                            return $address;
423
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
424
                        }
425
                    }
426
                }
427
            }
428
        }
429
430
        return null;
431
    }
432
433
    // ------------------------------------------------------------------------
434
435
    /**
436
     * Addresses::get
437
     *
438
     * @param string $path    The URI string path.
439
     * @param mixed  $address The routing map of the URI:
440
     *                        [string]: string of controller name.
441
     *                        [array]: array of URI segment.
442
     *                        [\Closure]: the closure map of URI.
443
     *
444
     * @return static
445
     */
446
    public function get($path, $address)
447
    {
448
        $this->addTranslation($path, $address, self::HTTP_GET);
449
450
        return $this;
451
    }
452
453
    // ------------------------------------------------------------------------
454
455
    /**
456
     * Addresses::post
457
     *
458
     * @param string $path    The URI string path.
459
     * @param mixed  $address The routing map of the URI:
460
     *                        [string]: string of controller name.
461
     *                        [array]: array of URI segment.
462
     *                        [\Closure]: the closure map of URI.
463
     *
464
     * @return static
465
     */
466
    public function post($path, $address)
467
    {
468
        $this->addTranslation($path, $address, self::HTTP_POST);
469
470
        return $this;
471
    }
472
473
    // ------------------------------------------------------------------------
474
475
    /**
476
     * Addresses::put
477
     *
478
     * @param string $path    The URI string path.
479
     * @param mixed  $address The routing map of the URI:
480
     *                        [string]: string of controller name.
481
     *                        [array]: array of URI segment.
482
     *                        [\Closure]: the closure map of URI.
483
     *
484
     * @return static
485
     */
486
    public function put($path, $address)
487
    {
488
        $this->addTranslation($path, $address, self::HTTP_PUT);
489
490
        return $this;
491
    }
492
493
    // ------------------------------------------------------------------------
494
495
    /**
496
     * Addresses::connect
497
     *
498
     * @param string $path    The URI string path.
499
     * @param mixed  $address The routing map of the URI:
500
     *                        [string]: string of controller name.
501
     *                        [array]: array of URI segment.
502
     *                        [\Closure]: the closure map of URI.
503
     *
504
     * @return static
505
     */
506
    public function connect($path, $address)
507
    {
508
        $this->addTranslation($path, $address, self::HTTP_CONNECT);
509
510
        return $this;
511
    }
512
513
    // ------------------------------------------------------------------------
514
515
    /**
516
     * Addresses::delete
517
     *
518
     * @param string $path    The URI string path.
519
     * @param mixed  $address The routing map of the URI:
520
     *                        [string]: string of controller name.
521
     *                        [array]: array of URI segment.
522
     *                        [\Closure]: the closure map of URI.
523
     *
524
     * @return static
525
     */
526
    public function delete($path, $address)
527
    {
528
        $this->addTranslation($path, $address, self::HTTP_DELETE);
529
530
        return $this;
531
    }
532
533
    // ------------------------------------------------------------------------
534
535
    /**
536
     * Addresses::delete
537
     *
538
     * @param string $path    The URI string path.
539
     * @param mixed  $address The routing map of the URI:
540
     *                        [string]: string of controller name.
541
     *                        [array]: array of URI segment.
542
     *                        [\Closure]: the closure map of URI.
543
     *
544
     * @return static
545
     */
546
    public function head($path, $address)
547
    {
548
        $this->addTranslation($path, $address, self::HTTP_HEAD);
549
550
        return $this;
551
    }
552
553
    // ------------------------------------------------------------------------
554
555
    /**
556
     * Addresses::options
557
     *
558
     * @param string $path    The URI string path.
559
     * @param mixed  $address The routing map of the URI:
560
     *                        [string]: string of controller name.
561
     *                        [array]: array of URI segment.
562
     *                        [\Closure]: the closure map of URI.
563
     *
564
     * @return static
565
     */
566
    public function options($path, $address)
567
    {
568
        $this->addTranslation($path, $address, self::HTTP_OPTIONS);
569
570
        return $this;
571
    }
572
573
    // ------------------------------------------------------------------------
574
575
    /**
576
     * Addresses::trace
577
     *
578
     * @param string $path    The URI string path.
579
     * @param mixed  $address The routing map of the URI:
580
     *                        [string]: string of controller name.
581
     *                        [array]: array of URI segment.
582
     *                        [\Closure]: the closure map of URI.
583
     *
584
     * @return static
585
     */
586
    public function trace($path, $address)
587
    {
588
        $this->addTranslation($path, $address, self::HTTP_TRACE);
589
590
        return $this;
591
    }
592
}