Passed
Push — master ( 3b3a40...5c106c )
by Yunus Emre
03:01
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 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 10
    public function __construct()
28
    {
29 10
        $this->clientGateway = app(ClientGateway::class);
30 10
    }
31
32
    // region CRUD
33
34 2
    public function all(): ?Collection
35
    {
36 2
        $rawData = $this->clientGateway->send(
37 2
            HttpMethods::GET,
38 2
            [$this->endpoint],
39 2
            $this->filters,
40 2
            $this->sorts,
41 2
            $this->includes,
42 2
            null,
43 2
            $this->page ?? null,
44 2
            $this->pageSize ?? null
45
        );
46
47 2
        $this->meta = ! empty($rawData['meta'])
48 2
            ? $this->createMeta($rawData['meta'])
49
            : null;
50
51 2
        $this->links = ! empty($rawData['links'])
52 2
            ? new Links($rawData['links'])
53
            : null;
54
55 2
        $this->removeFirstSushiModel();
56
57 2
        if (!empty($rawData['data']))
58
        {
59 2
            $this->model::insert($this->multipleRawDataToAttributes($rawData['data']));
60
        }
61
62 2
        return $this->model::all();
63
    }
64
65 2
    public function find(int $id): ?BaseModel
66
    {
67 2
        $rawData = $this->clientGateway->send(
68 2
            HttpMethods::GET,
69 2
            [$this->endpoint, $id],
70 2
            null,
71 2
            null,
72 2
            $this->includes,
73 2
            null,
74 2
            null,
75 2
            null
76
        );
77
78 2
        $attributes = $this->rawDataToAttributes($rawData['data']);
79
80 2
        $this->removeFirstSushiModel();
81 2
        $this->model::insert($attributes);
82
83 2
        return $this->model::find($attributes['id']);
84
    }
85
86 6
    public function create(BaseModel $model): BaseModel
87
    {
88 6
        $rawData = $this->clientGateway->send(
89 6
            HttpMethods::POST,
90 6
            [$this->endpoint],
91 6
            null,
92 6
            null,
93 6
            $this->includes,
94 6
            $this->generateCreationBodyForModel($model),
95 6
            null,
96 6
            null
97
        );
98
99 6
        $attributes = $this->rawDataToAttributes($rawData['data']);
100
101 6
        $this->model::insert($attributes);
102
103 6
        return $this->model::find($attributes['id']);
104
    }
105
106 2
    public function update(BaseModel $model): ?BaseModel
107
    {
108 2
        $rawData = $this->clientGateway->send(
109 2
            HttpMethods::PUT,
110 2
            [$this->endpoint, $model->id],
111 2
            null,
112 2
            null,
113 2
            $this->includes,
114 2
            $this->generateCreationBodyForModel($model),
115 2
            null,
116 2
            null
117
        );
118
119 2
        $attributes = $this->rawDataToAttributes($rawData['data']);
120
121 2
        $model->update($attributes);
122
123 2
        return $model;
124
    }
125
126 2
    public function delete(BaseModel $model): bool
127
    {
128 2
        $this->clientGateway->send(
129 2
            HttpMethods::DELETE,
130 2
            [$this->endpoint, $model->id],
131 2
            null,
132 2
            null,
133 2
            null,
134 2
            $this->generateCreationBodyForModel($model),
135 2
            null,
136 2
            null
137
        );
138
139 2
        return $model->delete();
140
    }
141
142
    // endregion
143
144
    // region Supports
145
146 6
    protected function generateCreationBodyForModel(BaseModel $model): array
147
    {
148 6
        $attributes = [];
149
150 6
        foreach ($model->getAttributes() as $name => $value) {
151 6
            if (! empty($value)) {
152 6
                $attributes[$name] = $value;
153
            }
154
        }
155
156
        return [
157
            'data' => [
158 6
                'type'       => $this->endpoint,
159 6
                'attributes' => $attributes,
160
                'relationships' => [],
161
            ],
162
        ];
163
    }
164
165 10
    protected function rawDataToAttributes(array $rawData): array
166
    {
167 10
        $mappings = [];
168 10
        $mappings['id'] = $rawData['id'];
169
170 10
        foreach ((new $this->model)->getFillable() as $field) {
171 10
            $mappings[$field] = $rawData['attributes'][$field];
172
        }
173
174 10
        return $mappings;
175
    }
176
177 2
    protected function multipleRawDataToAttributes(array $rawData): array
178
    {
179
        return array_map(function ($item) {
180 2
            return $this->rawDataToAttributes($item);
181 2
        }, $rawData);
182
    }
183
184
    // endregion
185
186
    // region Helpers
187
188 4
    protected function removeFirstSushiModel(): void
189
    {
190
        // TODO: Find a way to remove initilize model with sushi without a draft record creation
191 4
        $this->model::first()->delete();
192 4
    }
193
194
    public function sortByAttribute(string $attribute, bool $descending = false): self
195
    {
196
        $this->sorts[] = ($descending ? '-' : '').$attribute;
197
198
        return $this;
199
    }
200
201
    public function paginate(int $perPage, int $pageNumber): self
202
    {
203
        $this->pageSize = $perPage;
204
        $this->page = $pageNumber;
205
206
        return $this;
207
    }
208
209
    abstract protected static function createMeta(array $meta): BaseMeta;
210
211
    // endregion
212
}
213