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

ControllerLinkType::clearCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Spatie\ResourceLinks\LinkTypes;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Routing\Route;
7
use Illuminate\Routing\Router;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Str;
11
12
class ControllerLinkType extends LinkType
13
{
14
    /** @var string */
15
    private $controller;
16
17
    /** @var array */
18
    private $methods = [];
19
20
    /** @var array */
21
    private static $cachedRoutes = [];
22
23
    /** @var array */
24
    private $names = [];
25
26
    public static function make(string $controller): ControllerLinkType
27
    {
28
        return new ControllerLinkType($controller);
29
    }
30
31
    public function __construct(string $controller)
32
    {
33
        $this->controller = $controller;
34
    }
35
36
    public function methods($methods): ControllerLinkType
37
    {
38
        $this->methods = Arr::wrap($methods);
39
40
        return $this;
41
    }
42
43
    public function names(array $names): ControllerLinkType
44
    {
45
        $this->names = $names;
46
47
        return $this;
48
    }
49
50
    public function getLinks(Model $model = null): array
51
    {
52
        $methodsToInclude = empty($this->methods)
53
            ? ['show', 'edit', 'update', 'destroy']
54
            : $this->methods;
55
56
        return $this->resolveLinks($methodsToInclude, $model);
57
    }
58
59
    public function getCollectionLinks(): array
60
    {
61
        $methodsToInclude = empty($this->methods)
62
            ? ['index', 'store', 'create']
63
            : $this->methods;
64
65
        return $this->resolveLinks($methodsToInclude);
66
    }
67
68
    public static function clearCache(): void
69
    {
70
        self::$cachedRoutes = [];
71
    }
72
73
    private function resolveLinks(array $methodsToInclude, Model $model = null): array
74
    {
75
        $links = self::getRoutesForController($this->controller)
76
            ->filter(function (Route $route) use ($methodsToInclude) {
77
                return in_array($route->getActionMethod(), $methodsToInclude);
78
            })->map(function (Route $route) use ($model) {
79
                $route = RouteLinkType::make($route)
80
                    ->parameters($this->parameters)
81
                    ->name($this->resolveNameForRoute($route))
82
                    ->prefix($this->prefix)
83
                    ->serializer($this->serializer)
84
                    ->getLinks($model);
85
86
                return $route;
87
            })->toArray();
88
89
        return ! empty($links)
90
            ? array_merge_recursive(...$links)
91
            : [];
92
    }
93
94
    private static function getRoutesForController(string $controller): Collection
95
    {
96
        if (array_key_exists($controller, self::$cachedRoutes)) {
97
            return self::$cachedRoutes[$controller];
98
        }
99
100
        $routes = collect(resolve(Router::class)->getRoutes()->getRoutes());
101
102
        self::$cachedRoutes[$controller] = $routes
103
            ->filter(function (Route $route) use ($controller) {
104
                return $controller === Str::before($route->getActionName(), '@');
105
            });
106
107
        return self::$cachedRoutes[$controller];
108
    }
109
110
    private function resolveNameForRoute(Route $route): string
111
    {
112
        $method = $route->getActionMethod();
113
114
        if (array_key_exists($method, $this->names)) {
115
            return $this->names[$method];
116
        }
117
118
        return $method;
119
    }
120
}
121