Test Failed
Push — master ( 257d98...3364ef )
by Yunus Emre
06:12
created

BaseRepository   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 10
Bugs 2 Features 0
Metric Value
wmc 14
eloc 76
c 10
b 2
f 0
dl 0
loc 155
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 18 1
A rawDataToAttributes() 0 10 2
A sortByAttribute() 0 5 2
A paginate() 0 6 1
A __construct() 0 3 1
A generateCreationBodyForModel() 0 15 3
A find() 0 18 1
A all() 0 22 1
A multipleRawDataToAttributes() 0 12 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
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
    public function __construct()
27
    {
28
        $this->clientGateway = app(ClientGateway::class);
29
    }
30
31
    // region CRUD
32
33
    public function all(): Collection
34
    {
35
        $rawData = $this->clientGateway->call(
0 ignored issues
show
Bug introduced by
The method call() 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->call(
Loading history...
36
            HttpMethods::GET,
37
            $this->endpoint,
38
            $this->filters,
39
            $this->sorts,
40
            $this->includes,
41
            null,
42
            $this->page ?? null,
43
            $this->pageSize ?? null
44
        );
45
46
        $this->meta = new Meta($rawData['meta']);
47
        $this->links = new Links($rawData['links']);
48
49
        // TODO: Find a way to remove initilize model with sushi without a draft record creation
50
        $this->model::first()->delete();
51
52
        $this->model::insert($this->multipleRawDataToAttributes($rawData['data']));
53
54
        return $this->model::all();
55
    }
56
57
    public function find(int $id): ?BaseModel
58
    {
59
        $rawData = $this->clientGateway->call(
60
            HttpMethods::GET,
61
            $this->endpoint.'/'.$id,
62
            null,
63
            null,
64
            $this->includes,
65
            null,
66
            null,
67
            null
68
        );
69
70
        $attributes = $this->rawDataToAttributes($rawData['data']);
71
72
        $this->model::insert($attributes);
73
74
        return $this->model::find($attributes['id']);
75
    }
76
77
    public function create(BaseModel $model): BaseModel
78
    {
79
        $rawData = $this->clientGateway->call(
80
            HttpMethods::POST,
81
            $this->endpoint,
82
            null,
83
            null,
84
            $this->includes,
85
            $this->generateCreationBodyForModel($model),
86
            null,
87
            null
88
        );
89
90
        $attributes = $this->rawDataToAttributes($rawData['data']);
91
92
        $this->model::insert($attributes);
93
94
        return $this->model::find($attributes['id']);
95
    }
96
97
    // endregion
98
99
    // region Supports
100
101
    protected function generateCreationBodyForModel(BaseModel $model): array
102
    {
103
        $attributes = [];
104
105
        foreach ($model->getAttributes() as $name => $value) {
106
            if (! empty($value)) {
107
                $attributes[$name] = $value;
108
            }
109
        }
110
111
        return [
112
            'data' => [
113
                'type'       => $this->endpoint,
114
                'attributes' => $attributes,
115
                'relationships' => [],
116
            ],
117
        ];
118
    }
119
120
    // TODO: Merge `rawDataToAttributes()` and `multipleRawDataToAttributes()`
121
122
    protected function rawDataToAttributes(array $rawData): array
123
    {
124
        $mappings = [];
125
        $mappings['id'] = $rawData['id'];
126
127
        foreach ((new $this->model)->getFillable() as $field) {
128
            $mappings[$field] = $rawData['attributes'][$field];
129
        }
130
131
        return $mappings;
132
    }
133
134
    protected function multipleRawDataToAttributes(array $rawData): array
135
    {
136
        return array_map(function ($item) {
137
            $mappings = [];
138
            $mappings['id'] = $item['id'];
139
140
            foreach ((new $this->model)->getFillable() as $field) {
141
                $mappings[$field] = $item['attributes'][$field];
142
            }
143
144
            return $mappings;
145
        }, $rawData);
146
    }
147
148
    // endregion
149
150
    // region Helpers
151
152
    public function sortByAttribute(string $attribute, bool $descending = false): self
153
    {
154
        $this->sorts[] = ($descending ? '-' : '').$attribute;
155
156
        return $this;
157
    }
158
159
    public function paginate(int $perPage, int $pageNumber): self
160
    {
161
        $this->pageSize = $perPage;
162
        $this->page = $pageNumber;
163
164
        return $this;
165
    }
166
167
    // endregion
168
}
169