Completed
Push — master ( ab0b2f...ec71aa )
by Ruben
01:19
created

EndpointResource::addInvokableController()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Spatie\LaravelEndpointResources;
4
5
use Illuminate\Support\Arr;
6
use Spatie\LaravelEndpointResources\EndpointTypes\ControllerEndpointType;
7
use Spatie\LaravelEndpointResources\EndpointTypes\EndpointType;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Http\Resources\Json\JsonResource;
10
11
class EndpointResource extends JsonResource
12
{
13
    /** @var string */
14
    private $endpointResourceType;
15
16
    /** @var \Spatie\LaravelEndpointResources\EndpointsGroup */
17
    private $endpointsGroup;
18
19
    public function __construct(Model $model = null, string $endpointResourceType = null)
20
    {
21
        parent::__construct($model);
22
23
        $this->endpointResourceType = $endpointResourceType ?? EndpointResourceType::ITEM;
24
        $this->endpointsGroup = new EndpointsGroup();
25
    }
26
27
    public function addController(string $controller, $parameters = null): EndpointResource
28
    {
29
        if (method_exists($controller, '__invoke')) {
30
            return $this->addInvokableController($controller, $parameters);
31
        }
32
33
        $this->endpointsGroup->controller($controller)
34
            ->parameters(Arr::wrap($parameters));
35
36
        return $this;
37
    }
38
39
    public function addAction(array $action, $parameters = null, string $httpVerb = null): EndpointResource
40
    {
41
        $this->endpointsGroup->action($action)
42
            ->httpVerb($httpVerb)
43
            ->parameters(Arr::wrap($parameters));
44
45
        return $this;
46
    }
47
48
    public function addInvokableController(string $controller, $parameters = null): EndpointResource
49
    {
50
        $this->endpointsGroup->invokableController($controller)
51
            ->parameters(Arr::wrap($parameters));
52
53
        return $this;
54
    }
55
56
    public function addEndpointsGroup(EndpointsGroup $endpointsGroup): EndpointResource
57
    {
58
        $this->endpointsGroup->endpointsGroup($endpointsGroup);
59
60
        return $this;
61
    }
62
63
    public function mergeCollectionEndpoints(): EndpointResource
64
    {
65
        $this->endpointResourceType = EndpointResourceType::MULTI;
66
67
        return $this;
68
    }
69
70
    public function toArray($request)
71
    {
72
        $this->ensureCollectionEndpointsAreAutomaticallyMerged();
73
74
        return $this->endpointsGroup
75
            ->getEndpointTypes()
76
            ->map(function (EndpointType $endpointType) use ($request) {
77
                return $endpointType->hasParameters() === false
78
                    ? $endpointType->parameters($request->route()->parameters())
79
                    : $endpointType;
80
            })
81
            ->mapWithKeys(function (EndPointType $endpointType) {
82
                if ($endpointType instanceof ControllerEndpointType) {
83
                    return $this->resolveEndpointsFromControllerEndpointType($endpointType);
84
                }
85
86
                return $endpointType->getEndpoints($this->resource);
87
            });
88
    }
89
90
    private function resolveEndpointsFromControllerEndpointType(ControllerEndpointType $endpointType): array
91
    {
92
        if ($this->endpointResourceType === EndpointResourceType::ITEM) {
93
            return $endpointType->getEndpoints($this->resource);
94
        }
95
96
        if ($this->endpointResourceType === EndpointResourceType::COLLECTION) {
97
            return $endpointType->getCollectionEndpoints();
98
        }
99
100
        if ($this->endpointResourceType === EndpointResourceType::MULTI) {
101
            return array_merge(
102
                $endpointType->getEndpoints($this->resource),
103
                $endpointType->getCollectionEndpoints()
104
            );
105
        }
106
107
        return [];
108
    }
109
110
    private function ensureCollectionEndpointsAreAutomaticallyMerged()
111
    {
112
        if ($this->endpointResourceType !== EndpointResourceType::ITEM) {
113
            return;
114
        }
115
116
        if(config('laravel-endpoint-resources.automatically-merge-endpoints') === false){
117
            return;
118
        }
119
120
        if (is_null($this->resource) || $this->resource->exists === false) {
121
            $this->mergeCollectionEndpoints();
122
        }
123
    }
124
}
125