Completed
Push — master ( d9d1e2...b73c31 )
by Ruben
01:14
created

ActionLinkType::isInvokableController()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 4
nc 3
nop 0
1
<?php
2
3
namespace Spatie\ResourceLinks\LinkTypes;
4
5
use Exception;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Routing\Route;
8
use Illuminate\Routing\Router;
9
use Illuminate\Support\Arr;
10
use Illuminate\Support\Str;
11
12
class ActionLinkType extends LinkType
13
{
14
    /** @var array|string */
15
    private $action;
16
17
    /** @var string|null */
18
    private $httpVerb;
19
20
    /** @var string|null */
21
    private $name;
22
23
    public static function make($action): ActionLinkType
24
    {
25
        return new self($action);
26
    }
27
28
    public function __construct($action)
29
    {
30
        $this->action = $action;
31
    }
32
33
    public function httpVerb(?string $httpVerb): ActionLinkType
34
    {
35
        $this->httpVerb = $httpVerb;
36
37
        return $this;
38
    }
39
40
    public function name(?string $name): ActionLinkType
41
    {
42
        $this->name = $name;
43
44
        return $this;
45
    }
46
47
    public function getLinks(Model $model = null): array
48
    {
49
        $formattedAction = $this->formatAction();
50
51
        $route = app(Router::class)
52
            ->getRoutes()
53
            ->getByAction($formattedAction);
54
55
        if ($route === null) {
56
            throw new Exception("Route `{$formattedAction}` does not exist!");
57
        }
58
59
        return RouteLinkType::make($route)
60
            ->name($this->resolveName())
61
            ->httpVerb($this->httpVerb)
62
            ->prefix($this->prefix)
63
            ->parameters($this->getParameters($model))
64
            ->serializer($this->serializer)
65
            ->getLinks($model);
66
    }
67
68
    private function formatAction(): string
69
    {
70
        return is_array($this->action)
71
            ? trim('\\'.implode('@', $this->action), '\\')
72
            : $this->action;
73
    }
74
75
    private function resolveName(): ?string
76
    {
77
        if ($this->name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->name of type string|null is loosely compared to true; 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...
78
            return $this->name;
79
        }
80
81
        if ($this->isInvokableController()) {
82
            return 'invoke';
83
        }
84
85
        return null;
86
    }
87
88
    private function isInvokableController(): bool
89
    {
90
        if (is_array($this->action) && count($this->action) > 1) {
91
            return false;
92
        }
93
94
        $action = is_array($this->action) ? $this->action[0] : $this->action;
95
96
        return ! Str::contains($action, '@');
97
    }
98
99
    private function getParameters(?Model $model)
100
    {
101
        if (! optional($model)->exists) {
102
            return $this->parameters;
103
        }
104
105
        return array_merge($this->parameters, [$model]);
106
    }
107
}
108