ActionLinkType::getLinks()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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