Completed
Push — master ( 834214...ebf38e )
by Ruben
01:35
created

ControllerEndpointType::aliases()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\LaravelEndpointResources\EndpointTypes;
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
use Spatie\LaravelEndpointResources\EndpointTypes\MultiEndpointType;
12
13
class ControllerEndpointType extends EndpointType implements MultiEndpointType
14
{
15
    /** @var string */
16
    private $controller;
17
18
    /** @var array */
19
    private $methods = [];
20
21
    /** @var array */
22
    private static $cachedRoutes = [];
23
24
    /** @var array */
25
    private $aliases = [];
26
27
    public static function make(string $controller): ControllerEndpointType
28
    {
29
        return new self($controller);
30
    }
31
32
    public function __construct(string $controller)
33
    {
34
        $this->controller = $controller;
35
    }
36
37
    public function methods($methods): ControllerEndpointType
38
    {
39
        $this->methods = Arr::wrap($methods);
40
41
        return $this;
42
    }
43
44
    public function aliases(array $aliases): ControllerEndpointType
45
    {
46
        $this->aliases = $aliases;
47
48
        return $this;
49
    }
50
51
    public function getEndpoints(Model $model = null): array
52
    {
53
        $methodsToInclude = $this->resolveMethodsToInclude(
54
            'endPointMethods',
55
            ['show', 'edit', 'update', 'destroy']
56
        );
57
58
        return $this->resolveEndpoints($methodsToInclude, $model);
59
    }
60
61
    public function getCollectionEndpoints(): array
62
    {
63
        $methodsToInclude = $this->resolveMethodsToInclude(
64
            'collectionEndPointMethods',
65
            ['index', 'store', 'create']
66
        );
67
68
        return $this->resolveEndpoints($methodsToInclude);
69
    }
70
71
    private function resolveMethodsToInclude(string $classProperty, array $fallBackMethods): array
72
    {
73
        if (! empty($this->methods)) {
74
            return $this->methods;
75
        }
76
77
        $controller = new $this->controller();
78
79
        if (property_exists($controller, $classProperty)) {
80
            return $controller->$classProperty;
81
        }
82
83
        return $fallBackMethods;
84
    }
85
86
    private function resolveEndpoints(array $methodsToInclude, Model $model = null): array
87
    {
88
        return self::getRoutesForController($this->controller)
89
            ->filter(function (Route $route) use ($methodsToInclude) {
90
                return in_array($route->getActionMethod(), $methodsToInclude);
91
            })->mapWithKeys(function (Route $route) use ($model) {
92
                return RouteEndpointType::make($route)
93
                    ->parameters($this->parameters)
94
                    ->name($this->resolveNameForRoute($route))
95
                    ->prefix($this->prefix)
96
                    ->getEndpoints($model);
97
            })->toArray();
98
    }
99
100
    private static function getRoutesForController(string $controller): Collection
101
    {
102
        if (in_array($controller, self::$cachedRoutes)) {
103
            return self::$cachedRoutes[$controller];
104
        }
105
106
        $routes = collect(resolve(Router::class)->getRoutes()->getRoutes());
107
108
        self::$cachedRoutes[$controller] = $routes
109
            ->filter(function (Route $route) use ($controller) {
110
                return $controller === Str::before($route->getActionName(), '@');
111
            });
112
113
        return self::$cachedRoutes[$controller];
114
    }
115
116
    private function resolveNameForRoute(Route $route) : string
117
    {
118
        $method = $route->getActionMethod();
119
120
        if (array_key_exists($method, $this->aliases)) {
121
            return $this->aliases[$method];
122
        }
123
124
        return $method;
125
    }
126
}
127