Passed
Push — master ( e0ab5f...89e278 )
by Yunus Emre
03:45
created

BaseRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace TarfinLabs\Parasut\Repositories;
4
5
use TarfinLabs\Parasut\Models\BaseModel;
6
use TarfinLabs\Parasut\Enums\HttpMethods;
7
use TarfinLabs\Parasut\API\ClientGateway;
8
use Illuminate\Database\Eloquent\Collection;
9
10
class BaseRepository
11
{
12
    protected ClientGateway $clientGateway;
13
14
    protected string $endpoint;
15
    protected string $model;
16
17
    protected Meta $meta;
18
    protected Links $links;
19
20
    protected array $sorts = [];
21
    protected array $filters = [];
22
    protected array $includes = [];
23
    protected int $page;
24
    protected int $pageSize;
25
26 5
    public function __construct()
27
    {
28 5
        $this->clientGateway = app(ClientGateway::class);
29 5
    }
30
31
    // region CRUD
32
33 1
    public function all(): Collection
34
    {
35 1
        $rawData = $this->clientGateway->send(
0 ignored issues
show
Bug introduced by
The method send() does not exist on TarfinLabs\Parasut\API\ClientGateway. Since it exists in all sub-types, consider adding an abstract or default implementation to TarfinLabs\Parasut\API\ClientGateway. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

35
        /** @scrutinizer ignore-call */ 
36
        $rawData = $this->clientGateway->send(
Loading history...
36 1
            HttpMethods::GET,
37 1
            $this->endpoint,
38 1
            $this->filters,
39 1
            $this->sorts,
40 1
            $this->includes,
41 1
            null,
42 1
            $this->page ?? null,
43 1
            $this->pageSize ?? null
44
        );
45
46 1
        $this->meta = new Meta($rawData['meta']);
47 1
        $this->links = new Links($rawData['links']);
48
49
        // TODO: Find a way to remove initilize model with sushi without a draft record creation
50 1
        $this->model::first()->delete();
51
52 1
        $this->model::insert($this->multipleRawDataToAttributes($rawData['data']));
53
54 1
        return $this->model::all();
55
    }
56
57 1
    public function find(int $id): ?BaseModel
58
    {
59 1
        $rawData = $this->clientGateway->send(
60 1
            HttpMethods::GET,
61 1
            $this->endpoint.'/'.$id,
62 1
            null,
63 1
            null,
64 1
            $this->includes,
65 1
            null,
66 1
            null,
67 1
            null
68
        );
69
70 1
        $attributes = $this->rawDataToAttributes($rawData['data']);
71
72 1
        $this->model::insert($attributes);
73
74 1
        return $this->model::find($attributes['id']);
75
    }
76
77 3
    public function create(BaseModel $model): BaseModel
78
    {
79 3
        $rawData = $this->clientGateway->send(
80 3
            HttpMethods::POST,
81 3
            $this->endpoint,
82 3
            null,
83 3
            null,
84 3
            $this->includes,
85 3
            $this->generateCreationBodyForModel($model),
86 3
            null,
87 3
            null
88
        );
89
90 3
        $attributes = $this->rawDataToAttributes($rawData['data']);
91
92 3
        $this->model::insert($attributes);
93
94 3
        return $this->model::find($attributes['id']);
95
    }
96
97 1
    public function update(BaseModel $model): ?BaseModel
98
    {
99 1
        $rawData = $this->clientGateway->send(
100 1
            HttpMethods::PUT,
101 1
            $this->endpoint.'/'.$model->id,
102 1
            null,
103 1
            null,
104 1
            $this->includes,
105 1
            $this->generateCreationBodyForModel($model),
106 1
            null,
107 1
            null
108
        );
109
110 1
        $attributes = $this->rawDataToAttributes($rawData['data']);
111
112 1
        $model->update($attributes);
113
114 1
        return $model;
115
    }
116
117 1
    public function delete(BaseModel $model): bool
118
    {
119 1
        $rawData = $this->clientGateway->send(
0 ignored issues
show
Unused Code introduced by
The assignment to $rawData is dead and can be removed.
Loading history...
120 1
            HttpMethods::DELETE,
121 1
            $this->endpoint.'/'.$model->id,
122 1
            null,
123 1
            null,
124 1
            null,
125 1
            $this->generateCreationBodyForModel($model),
126 1
            null,
127 1
            null
128
        );
129
130 1
        return $model->delete();
131
    }
132
133
    // endregion
134
135
    // region Supports
136
137 3
    protected function generateCreationBodyForModel(BaseModel $model): array
138
    {
139 3
        $attributes = [];
140
141 3
        foreach ($model->getAttributes() as $name => $value) {
142 3
            if (! empty($value)) {
143 3
                $attributes[$name] = $value;
144
            }
145
        }
146
147
        return [
148
            'data' => [
149 3
                'type'       => $this->endpoint,
150 3
                'attributes' => $attributes,
151
                'relationships' => [],
152
            ],
153
        ];
154
    }
155
156
    // TODO: Merge `rawDataToAttributes()` and `multipleRawDataToAttributes()`
157
158 4
    protected function rawDataToAttributes(array $rawData): array
159
    {
160 4
        $mappings = [];
161 4
        $mappings['id'] = $rawData['id'];
162
163 4
        foreach ((new $this->model)->getFillable() as $field) {
164 4
            $mappings[$field] = $rawData['attributes'][$field];
165
        }
166
167 4
        return $mappings;
168
    }
169
170 1
    protected function multipleRawDataToAttributes(array $rawData): array
171
    {
172
        return array_map(function ($item) {
173 1
            $mappings = [];
174 1
            $mappings['id'] = $item['id'];
175
176 1
            foreach ((new $this->model)->getFillable() as $field) {
177 1
                $mappings[$field] = $item['attributes'][$field];
178
            }
179
180 1
            return $mappings;
181 1
        }, $rawData);
182
    }
183
184
    // endregion
185
186
    // region Helpers
187
188
    public function sortByAttribute(string $attribute, bool $descending = false): self
189
    {
190
        $this->sorts[] = ($descending ? '-' : '').$attribute;
191
192
        return $this;
193
    }
194
195
    public function paginate(int $perPage, int $pageNumber): self
196
    {
197
        $this->pageSize = $perPage;
198
        $this->page = $pageNumber;
199
200
        return $this;
201
    }
202
203
    // endregion
204
}
205