Completed
Branch master (0bc14e)
by Yaro
06:47 queued 16s
created

ModelRepository::applyOrder()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 13.125

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6346
c 0
b 0
f 0
ccs 7
cts 14
cp 0.5
cc 7
nc 10
nop 1
crap 13.125
1
<?php
2
3
namespace Yaro\Jarboe\Table\Repositories;
4
5
use Illuminate\Http\Request;
6
use Yaro\Jarboe\Table\CRUD;
7
use Yaro\Jarboe\Table\Fields\AbstractField;
8
9
class ModelRepository implements ModelRepositoryInterface
10
{
11
    /**
12
     * @var CRUD
13
     */
14
    private $crud;
15
    private $filter;
16
    private $perPage = 20;
17
    private $defaultOrder = [
18
        'column'    => false,
19
        'direction' => false,
20
    ];
21
22 33
    public function setCrud(CRUD $crud)
23
    {
24 33
        $this->crud = $crud;
25
26 33
        return $this;
27
    }
28
29 1
    public function get()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
30
    {
31 1
        $model = $this->crud->getModel();
32 1
        $model = $model::query();
33
34 1
        $this->applyFilter($model);
35 1
        $this->applySearchFilters($model);
36
37 1
        if ($this->crud->isSortableByWeightActive()) {
38
            $this->applySortableOrder($model);
39
        } else {
40 1
            $this->applyOrder($model);
41
        }
42
43 1
        $this->applyPaginate($model);
44
45 1
        return $model;
46
    }
47
48 14
    public function find($id)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
49
    {
50 14
        $model = $this->crud->getModel();
51 14
        $model = $model::query();
52 14
        $this->applyFilter($model);
53
54 14
        $model = $model->find($id);
55 14
        if (!$model) {
56
            throw new \RuntimeException(sprintf('Not allowed or no record to edit [%s]', $id));
57
        }
58
59 14
        return $model;
60
    }
61
62 1
    public function delete($id)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
63
    {
64 1
        $model = $this->find($id);
65
66 1
        return $model->delete();
67
    }
68
69 1 View Code Duplication
    public function store(Request $request)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
70
    {
71 1
        $fields = $this->crud->getFieldsWithoutMarkup();
72 1
        $model = $this->crud->getModel();
73
74 1
        $data = [];
75
        /** @var AbstractField $field */
76 1
        foreach ($fields as $field) {
77 1
            if ($field->hidden('create') || /*$field->isReadonly() || */$field->shouldSkip($request)) {
78
                continue;
79
            }
80 1
            $data += [$field->name() => $field->value($request)];
81
        }
82
83 1
        $model = $model::create($data);
84
85
        /** @var AbstractField $field */
86 1
        foreach ($fields as $field) {
87 1
            $field->afterStore($model, $request);
88
        }
89
90 1
        return $model;
91
    }
92
93 1 View Code Duplication
    public function update($id, Request $request)
94
    {
95 1
        $fields = $this->crud->getFieldsWithoutMarkup();
96 1
        $model = $this->find($id);
97
98 1
        $data = [];
99
        /** @var AbstractField $field */
100 1
        foreach ($fields as $field) {
101 1
            if ($field->hidden('edit') || $field->isReadonly() || $field->shouldSkip($request)) {
102
                continue;
103
            }
104 1
            $data += [$field->name() => $field->value($request)];
105
        }
106
107 1
        $model->update($data);
108
109
        /** @var AbstractField $field */
110 1
        foreach ($fields as $field) {
111 1
            $field->afterUpdate($model, $request);
112
        }
113 1
    }
114
115 1
    public function updateField($id, Request $request, AbstractField $field, $value)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
116
    {
117 1
        $model = $this->find($id);
118
119
        // FIXME: move
120 1
        if (!$field->isInline() || $field->isReadonly() || $field->shouldSkip($request)) {
121
            return;
122
        }
123
124 1
        $model->update([
125 1
            $field->name() => $value,
126
        ]);
127 1
        $field->afterUpdate($model, $request);
128
129 1
        return $model;
130
    }
131
132 33
    public function filter(\Closure $callback)
133
    {
134 33
        $this->filter = $callback;
135 33
    }
136
137
    public function order(string $column, string $direction)
138
    {
139
        $this->defaultOrder = [
140
            'column'    => $column,
141
            'direction' => $direction,
142
        ];
143
    }
144
145 1
    public function perPage(int $perPage = null)
146
    {
147 1
        if (is_null($perPage)) {
148 1
            return $this->perPage;
149
        }
150
151
        $this->perPage = $perPage;
152
    }
153
154 15
    private function applyFilter($model)
155
    {
156 15
        $callback = $this->filter;
157 15
        if ($callback) {
158 15
            $callback($model);
159
        }
160 15
    }
161
162 1
    private function applySearchFilters($model)
163
    {
164 1
        foreach ($this->crud->getAllFieldObjects() as $field) {
165 1
            if ($field->filter()) {
166 1
                $field->filter()->apply($model, $field->name());
167
            }
168
        }
169 1
    }
170
171 1
    private function applyOrder($model)
172
    {
173 1
        $shouldApplyDefaultOrder = true;
174 1
        foreach ($this->crud->getAllFieldObjects() as $field) {
175 1
            if ($field->isOrderable()) {
176
                $direction = $this->crud->getOrderFilterParam($field->name());
177
                if (!is_null($direction)) {
178
                    $callback = $field->getOverridedOrderCallback();
179
                    if ($callback) {
180
                        $callback($model, $field, $direction, $shouldApplyDefaultOrder);
181
                    } else {
182
                        $model->orderBy($field->name(), $direction);
183 1
                        $shouldApplyDefaultOrder = false;
184
                    }
185
                }
186
            }
187
        }
188
189 1
        if ($shouldApplyDefaultOrder && array_filter($this->defaultOrder)) {
190
            $model->orderBy($this->defaultOrder['column'], $this->defaultOrder['direction']);
191
        }
192 1
    }
193
194 1
    private function applyPaginate(&$model)
195
    {
196 1
        $model = $model->paginate($this->perPage());
197 1
    }
198
199
    private function applySortableOrder($model)
200
    {
201
        $model->orderBy($this->crud->getSortableWeightFieldName(), 'asc');
202
    }
203
204
    public function reorder($id, $idPrev, $idNext)
205
    {
206
        $sort = $this->crud->getSortableWeightFieldName();
207
        $model = $this->crud->getModel();
208
        $query = $model::query();
209
        $key = (new $model)->getKeyName();
210
211
        if ($idPrev) {
212
            $weight = $this->find($idPrev)->$sort + 1;
213
            $this->find($id)->update([
214
                $sort => $weight,
215
            ]);
216
217
            $query->where($key, '!=', $id)->where($sort, '>=', $weight)->increment($sort);
218
        } elseif ($idNext) {
219
            $weight = $this->find($idNext)->$sort - 1;
220
            $this->find($id)->update([
221
                $sort => $weight,
222
            ]);
223
224
            $query->where($key, '!=', $id)->where($sort, '<=', $weight)->decrement($sort);
225
        }
226
    }
227
228 1
    public function restore($id)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
229
    {
230 1
        $model = $this->find($id);
231
232 1
        return $model->restore();
233
    }
234
235 1
    public function forceDelete($id)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
236
    {
237 1
        $model = $this->find($id);
238
239 1
        return $model->forceDelete();
240
    }
241
}
242