Completed
Push — master ( 3dff4f...2f5fe2 )
by Ruben
08:28
created

ControllerEndpointType::names()   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 $names = [];
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 names(array $names): ControllerEndpointType
45
    {
46
        $this->names = $names;
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
                    ->formatter($this->formatter)
97
                    ->getEndpoints($model);
98
            })->toArray();
99
    }
100
101
    private static function getRoutesForController(string $controller): Collection
102
    {
103
        if (in_array($controller, self::$cachedRoutes)) {
104
            return self::$cachedRoutes[$controller];
105
        }
106
107
        $routes = collect(resolve(Router::class)->getRoutes()->getRoutes());
108
109
        self::$cachedRoutes[$controller] = $routes
110
            ->filter(function (Route $route) use ($controller) {
111
                return $controller === Str::before($route->getActionName(), '@');
112
            });
113
114
        return self::$cachedRoutes[$controller];
115
    }
116
117
    private function resolveNameForRoute(Route $route) : string
118
    {
119
        $method = $route->getActionMethod();
120
121
        if (array_key_exists($method, $this->names)) {
122
            return $this->names[$method];
123
        }
124
125
        return $method;
126
    }
127
}
128