Passed
Push — master ( fd15bd...b021d0 )
by Yunus Emre
03:23
created

BaseRepository::createMeta()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 0
cts 2
cp 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace TarfinLabs\Parasut\Repositories;
4
5
use Illuminate\Database\Eloquent\Collection;
6
use TarfinLabs\Parasut\API\ClientGateway;
7
use TarfinLabs\Parasut\Enums\HttpMethods;
8
use TarfinLabs\Parasut\Models\BaseModel;
9
use TarfinLabs\Parasut\Repositories\Meta\BaseMeta;
10
11
abstract class BaseRepository
12
{
13
    protected ClientGateway $clientGateway;
14
15
    protected string $endpoint;
16
    protected string $model;
17
18
    protected BaseMeta $meta;
19
    protected Links $links;
20
21
    protected array $sorts = [];
22
    protected array $filters = [];
23
    protected array $includes = [];
24
    protected int $page;
25
    protected int $pageSize;
26
27 5
    public function __construct()
28
    {
29 5
        $this->clientGateway = app(ClientGateway::class);
30 5
    }
31
32
    // region CRUD
33
34 1
    public function all(): Collection
35
    {
36 1
        $rawData = $this->clientGateway->send(
37 1
            HttpMethods::GET,
38 1
            $this->endpoint,
39 1
            $this->filters,
40 1
            $this->sorts,
41 1
            $this->includes,
42 1
            null,
43 1
            $this->page ?? null,
44 1
            $this->pageSize ?? null
45
        );
46
47 1
        $this->meta = $this->createMeta($rawData['meta']);
48 1
        $this->links = new Links($rawData['links']);
49
50 1
        $this->removeFirstSushiModel();
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->removeFirstSushiModel();
73 1
        $this->model::insert($attributes);
74
75 1
        return $this->model::find($attributes['id']);
76
    }
77
78 3
    public function create(BaseModel $model): BaseModel
79
    {
80 3
        $rawData = $this->clientGateway->send(
81 3
            HttpMethods::POST,
82 3
            $this->endpoint,
83 3
            null,
84 3
            null,
85 3
            $this->includes,
86 3
            $this->generateCreationBodyForModel($model),
87 3
            null,
88 3
            null
89
        );
90
91 3
        $attributes = $this->rawDataToAttributes($rawData['data']);
92
93 3
        $this->model::insert($attributes);
94
95 3
        return $this->model::find($attributes['id']);
96
    }
97
98 1
    public function update(BaseModel $model): ?BaseModel
99
    {
100 1
        $rawData = $this->clientGateway->send(
101 1
            HttpMethods::PUT,
102 1
            $this->endpoint.'/'.$model->id,
103 1
            null,
104 1
            null,
105 1
            $this->includes,
106 1
            $this->generateCreationBodyForModel($model),
107 1
            null,
108 1
            null
109
        );
110
111 1
        $attributes = $this->rawDataToAttributes($rawData['data']);
112
113 1
        $model->update($attributes);
114
115 1
        return $model;
116
    }
117
118 1
    public function delete(BaseModel $model): bool
119
    {
120 1
        $this->clientGateway->send(
121 1
            HttpMethods::DELETE,
122 1
            $this->endpoint.'/'.$model->id,
123 1
            null,
124 1
            null,
125 1
            null,
126 1
            $this->generateCreationBodyForModel($model),
127 1
            null,
128 1
            null
129
        );
130
131 1
        return $model->delete();
132
    }
133
134
    // endregion
135
136
    // region Supports
137
138 3
    protected function generateCreationBodyForModel(BaseModel $model): array
139
    {
140 3
        $attributes = [];
141
142 3
        foreach ($model->getAttributes() as $name => $value) {
143 3
            if (! empty($value)) {
144 3
                $attributes[$name] = $value;
145
            }
146
        }
147
148
        return [
149
            'data' => [
150 3
                'type'       => $this->endpoint,
151 3
                'attributes' => $attributes,
152
                'relationships' => [],
153
            ],
154
        ];
155
    }
156
157 5
    protected function rawDataToAttributes(array $rawData): array
158
    {
159 5
        $mappings = [];
160 5
        $mappings['id'] = $rawData['id'];
161
162 5
        foreach ((new $this->model)->getFillable() as $field) {
163 5
            $mappings[$field] = $rawData['attributes'][$field];
164
        }
165
166 5
        return $mappings;
167
    }
168
169 1
    protected function multipleRawDataToAttributes(array $rawData): array
170
    {
171
        return array_map(function ($item) {
172 1
            return $this->rawDataToAttributes($item);
173 1
        }, $rawData);
174
    }
175
176
    // endregion
177
178
    // region Helpers
179
180 2
    protected function removeFirstSushiModel(): void
181
    {
182
        // TODO: Find a way to remove initilize model with sushi without a draft record creation
183 2
        $this->model::first()->delete();
184 2
    }
185
186
    public function sortByAttribute(string $attribute, bool $descending = false): self
187
    {
188
        $this->sorts[] = ($descending ? '-' : '').$attribute;
189
190
        return $this;
191
    }
192
193
    public function paginate(int $perPage, int $pageNumber): self
194
    {
195
        $this->pageSize = $perPage;
196
        $this->page = $pageNumber;
197
198
        return $this;
199
    }
200
201
    abstract protected static function createMeta(array $meta): BaseMeta;
202
203
    // endregion
204
}
205