Completed
Push — master ( df43f8...12407a )
by Ruben
01:27
created

EndpointResource::addAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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