Completed
Push — master ( 274f99...dca8df )
by Yaro
01:38
created

ModelRepository::applyOrder()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 10
nop 1
dl 0
loc 22
rs 8.6346
c 0
b 0
f 0
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
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
    public function setCrud(CRUD $crud)
23
    {
24
        $this->crud = $crud;
25
26
        return $this;
27
    }
28
29
    public function get()
30
    {
31
        $model = $this->crud->getModel();
32
        $model = $model::query();
33
34
        $this->applyFilter($model);
35
        $this->applySearchFilters($model);
36
37
        if ($this->crud->isSortableByWeightActive()) {
38
            $this->applySortableOrder($model);
39
        } else {
40
            $this->applyOrder($model);
41
        }
42
43
        $this->applyPaginate($model);
44
45
        return $model;
46
    }
47
48
    public function find($id)
49
    {
50
        $model = $this->crud->getModel();
51
        $model = $model::query();
52
        $this->applyFilter($model);
53
54
        $model = $model->find($id);
55
        if (!$model) {
56
            throw new \RuntimeException(sprintf('Not allowed or no record to edit [%s]', $id));
57
        }
58
59
        return $model;
60
    }
61
62
    public function delete($id)
63
    {
64
        $model = $this->find($id);
65
66
        return $model->delete();
67
    }
68
69 View Code Duplication
    public function store(Request $request)
70
    {
71
        $fields = $this->crud->getFieldsWithoutMarkup();
72
        $model = $this->crud->getModel();
73
74
        $data = [];
75
        /** @var AbstractField $field */
76
        foreach ($fields as $field) {
77
            if ($field->hidden('create') || /*$field->isReadonly() || */$field->shouldSkip($request)) {
78
                continue;
79
            }
80
            $data += [$field->name() => $field->value($request)];
81
        }
82
83
        $model = $model::create($data);
84
85
        /** @var AbstractField $field */
86
        foreach ($fields as $field) {
87
            $field->afterStore($model, $request);
88
        }
89
90
        return $model;
91
    }
92
93 View Code Duplication
    public function update($id, Request $request)
94
    {
95
        $fields = $this->crud->getFieldsWithoutMarkup();
96
        $model = $this->find($id);
97
98
        $data = [];
99
        /** @var AbstractField $field */
100
        foreach ($fields as $field) {
101
            if ($field->hidden('edit') || $field->isReadonly() || $field->shouldSkip($request)) {
102
                continue;
103
            }
104
            $data += [$field->name() => $field->value($request)];
105
        }
106
107
        $model->update($data);
108
109
        /** @var AbstractField $field */
110
        foreach ($fields as $field) {
111
            $field->afterUpdate($model, $request);
112
        }
113
    }
114
115
    public function updateField($id, Request $request, AbstractField $field, $value)
116
    {
117
        $model = $this->find($id);
118
119
        // FIXME: move
120
        if (!$field->isInline() || $field->isReadonly() || $field->shouldSkip($request)) {
121
            return;
122
        }
123
124
        $model->update([
125
            $field->name() => $value,
126
        ]);
127
        $field->afterUpdate($model, $request);
128
129
        return $model;
130
    }
131
132
    public function filter(\Closure $callback)
133
    {
134
        $this->filter = $callback;
135
    }
136
137
    public function order(string $column, string $direction)
138
    {
139
        $this->defaultOrder = [
140
            'column'    => $column,
141
            'direction' => $direction,
142
        ];
143
    }
144
145
    public function perPage(int $perPage = null)
146
    {
147
        if (is_null($perPage)) {
148
            return $this->perPage;
149
        }
150
151
        $this->perPage = $perPage;
152
    }
153
154
    private function applyFilter($model)
155
    {
156
        $callback = $this->filter;
157
        if ($callback) {
158
            $callback($model);
159
        }
160
    }
161
162
    private function applySearchFilters($model)
163
    {
164
        foreach ($this->crud->getAllFieldObjects() as $field) {
165
            if ($field->filter()) {
166
                $field->filter()->apply($model, $field->name());
167
            }
168
        }
169
    }
170
171
    private function applyOrder($model)
172
    {
173
        $shouldApplyDefaultOrder = true;
174
        foreach ($this->crud->getAllFieldObjects() as $field) {
175
            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
                        $shouldApplyDefaultOrder = false;
184
                    }
185
                }
186
            }
187
        }
188
189
        if ($shouldApplyDefaultOrder && array_filter($this->defaultOrder)) {
190
            $model->orderBy($this->defaultOrder['column'], $this->defaultOrder['direction']);
191
        }
192
    }
193
194
    private function applyPaginate(&$model)
195
    {
196
        $model = $model->paginate($this->perPage());
197
    }
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
    public function restore($id)
229
    {
230
        $model = $this->find($id);
231
232
        return $model->restore();
233
    }
234
235
    public function forceDelete($id)
236
    {
237
        $model = $this->find($id);
238
239
        return $model->forceDelete();
240
    }
241
}
242