Passed
Push — master ( 883956...b69e20 )
by Tom
01:03 queued 10s
created

LinkBuilder::buildLink()   C

Complexity

Conditions 10
Paths 23

Size

Total Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 61
rs 6.9842
c 0
b 0
f 0
cc 10
nc 23
nop 4

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
namespace TomHart\Restful;
4
5
use Illuminate\Routing\Exceptions\UrlGenerationException;
6
use Illuminate\Routing\Router;
7
use TomHart\Restful\Concerns\HasLinks;
8
9
class LinkBuilder
10
{
11
    /**
12
     * Builds a link if possible
13
     *
14
     * @param HasLinks $model
15
     * @param string $routePart
16
     * @param Router $router
17
     * @param string|null $method
18
     * @return mixed[]|bool
19
     */
20
    public static function buildLink(HasLinks $model, string $routePart, Router $router, string $method = null)
21
    {
22
        $routeStub = $model->getRouteName();
23
24
        if ($routeStub === null) {
25
            return false;
26
        }
27
28
        if (!$model->getKeyName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $model->getKeyName() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
29
            return false;
30
        }
31
32
        // Make the route name, and check if it exists.
33
        $routeName = "$routeStub.$routePart";
34
35
        if (!($route = $router->getRoutes()->getByName($routeName))) {
36
            return false;
37
        }
38
39
        // Get any params needed to build the URL.
40
        $params = [];
41
        switch ($routePart) {
42
            case 'destroy':
43
            case 'update':
44
            case 'show':
45
                $params = [$model->getRouteKey() => $model->getAttribute((string)$model->getKeyName())];
46
                break;
47
            case 'show.extra':
48
                $params = [
49
                    $model->getRouteKey() => $model->getAttribute((string)$model->getKeyName()),
50
                    'extra' => $method
51
                ];
52
                break;
53
        }
54
55
        // Get the methods applicable to the route, ignoring HEAD and PATCH.
56
        $methods = collect($route->methods());
57
        $methods = $methods->filter(static function ($item) {
58
            return !in_array($item, ['HEAD', 'PATCH']);
59
        })->map(static function ($str) {
60
            return strtolower($str);
61
        });
62
63
        // If there's only 1, return just that, otherwise, return an array.
64
        if ($methods->count() === 1) {
65
            $methods = $methods->first();
66
        }
67
68
        // Add!
69
        try {
70
            return [
71
                'method' => $methods,
72
                'href' => [
73
                    'relative' => route($routeName, $params, false),
74
                    'absolute' => route($routeName, $params, true)
75
                ]
76
            ];
77
        } catch (UrlGenerationException $ex) {
78
            return false;
79
        }
80
    }
81
}
82