Passed
Pull Request — 1.2 (#405)
by
unknown
08:49
created

ModuleRepository::bulkForceDelete()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 1
nop 1
dl 0
loc 19
ccs 0
cts 11
cp 0
crap 6
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace A17\Twill\Repositories;
4
5
use A17\Twill\Models\Behaviors\HasMedias;
6
use A17\Twill\Models\Behaviors\Sortable;
7
use A17\Twill\Repositories\Behaviors\HandleDates;
8
use A17\Twill\Repositories\Behaviors\HandleBrowsers;
9
use A17\Twill\Repositories\Behaviors\HandleRepeaters;
10
use A17\Twill\Repositories\Behaviors\HandleFieldsGroups;
11
use Illuminate\Support\Arr;
12
use Illuminate\Support\Collection;
13
use Illuminate\Support\Facades\App;
14
use Illuminate\Support\Facades\Config;
15
use Illuminate\Support\Facades\DB;
16
use Illuminate\Support\Facades\Log;
17
use Illuminate\Support\Str;
18
use PDO;
19
20
abstract class ModuleRepository
21
{
22
    use HandleDates, HandleBrowsers, HandleRepeaters, HandleFieldsGroups;
0 ignored issues
show
Bug introduced by
The trait A17\Twill\Repositories\Behaviors\HandleRepeaters requires the property $id which is not provided by A17\Twill\Repositories\ModuleRepository.
Loading history...
introduced by
The trait A17\Twill\Repositories\Behaviors\HandleBrowsers requires some properties which are not provided by A17\Twill\Repositories\ModuleRepository: $titleInBrowser, $id, $adminEditUrl, $title
Loading history...
23
  
24
    /**
25
     * @var \A17\Twill\Models\Model
26
     */
27
    protected $model;
28
29
    /**
30
     * @var string[]
31
     */
32
    protected $ignoreFieldsBeforeSave = [];
33
34
    /**
35
     * @var array
36
     */
37
    protected $countScope = [];
38
39
    /**
40
     * @var array
41
     */
42
    protected $fieldsGroups = [];
43
44
    /**
45
     * @param array $with
46
     * @param array $scopes
47
     * @param array $orders
48
     * @param int $perPage
49
     * @param bool $forcePagination
50
     * @return \Illuminate\Database\Eloquent\Collection
51
     */
52 12
    public function get($with = [], $scopes = [], $orders = [], $perPage = 20, $forcePagination = false)
53
    {
54 12
        $query = $this->model->with($with);
55
56 12
        $query = $this->filter($query, $scopes);
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::filter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
        $query = $this->filter(/** @scrutinizer ignore-type */ $query, $scopes);
Loading history...
57 12
        $query = $this->order($query, $orders);
58
59 12
        if (!$forcePagination && $this->model instanceof Sortable) {
60 3
            return $query->ordered()->get();
61
        }
62
63 10
        if ($perPage == -1) {
64
            return $query->get();
65
        }
66
67 10
        return $query->paginate($perPage);
68
    }
69
70
    /**
71
     * @param string $slug
72
     * @param array $scope
73
     * @return int
74
     */
75 6
    public function getCountByStatusSlug($slug, $scope = [])
76
    {
77 6
        $this->countScope = $scope;
78
79 6
        switch ($slug) {
80 6
            case 'all':
81 5
                return $this->getCountForAll();
82 6
            case 'published':
83 6
                return $this->getCountForPublished();
84 6
            case 'draft':
85 6
                return $this->getCountForDraft();
86 6
            case 'trash':
87 6
                return $this->getCountForTrash();
88
        }
89
90 5
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
91 5
            if (($count = $this->$method($slug)) !== false) {
92 5
                return $count;
93
            }
94
        }
95
96
        return 0;
97
    }
98
99
    /**
100
     * @return int
101
     */
102 5
    public function getCountForAll()
103
    {
104 5
        $query = $this->model->newQuery();
105 5
        return $this->filter($query, $this->countScope)->count();
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::filter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

105
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->count();
Loading history...
106
    }
107
108
    /**
109
     * @return int
110
     */
111 5
    public function getCountForPublished()
112
    {
113 5
        $query = $this->model->newQuery();
114 5
        return $this->filter($query, $this->countScope)->published()->count();
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::filter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->published()->count();
Loading history...
115
    }
116
117
    /**
118
     * @return int
119
     */
120 5
    public function getCountForDraft()
121
    {
122 5
        $query = $this->model->newQuery();
123 5
        return $this->filter($query, $this->countScope)->draft()->count();
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::filter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

123
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->draft()->count();
Loading history...
124
    }
125
126
    /**
127
     * @return int
128
     */
129 5
    public function getCountForTrash()
130
    {
131 5
        $query = $this->model->newQuery();
132 5
        return $this->filter($query, $this->countScope)->onlyTrashed()->count();
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::filter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->onlyTrashed()->count();
Loading history...
133
    }
134
135
    /**
136
     * @param $id
137
     * @param array $with
138
     * @param array $withCount
139
     * @return \A17\Twill\Models\Model
140
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
141
     */
142 14
    public function getById($id, $with = [], $withCount = [])
143
    {
144 14
        return $this->model->with($with)->withCount($withCount)->findOrFail($id);
145
    }
146
147
    /**
148
     * @param string $column
149
     * @param array $orders
150
     * @param null $exceptId
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $exceptId is correct as it would always require null to be passed?
Loading history...
151
     * @return \Illuminate\Support\Collection
152
     */
153
    public function listAll($column = 'title', $orders = [], $exceptId = null)
154
    {
155
        $query = $this->model->newQuery();
156
157
        if ($exceptId) {
0 ignored issues
show
introduced by
$exceptId is of type null, thus it always evaluated to false.
Loading history...
158
            $query = $query->where($this->model->getTable() . '.id', '<>', $exceptId);
159
        }
160
161
        if ($this->model instanceof Sortable) {
162
            $query = $query->ordered();
163
        } elseif (!empty($orders)) {
164
            $query = $this->order($query, $orders);
0 ignored issues
show
Bug introduced by
$query of type Illuminate\Database\Eloquent\Builder is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of A17\Twill\Repositories\ModuleRepository::order(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
            $query = $this->order(/** @scrutinizer ignore-type */ $query, $orders);
Loading history...
165
        }
166
167
        if (property_exists($this->model, 'translatedAttributes')) {
168
            $query = $query->withTranslation();
169
        }
170
171
        return $query->get()->pluck($column, 'id');
172
    }
173
174
    /**
175
     * @param $search
176
     * @param array $fields
177
     * @return \Illuminate\Database\Eloquent\Collection
178
     */
179
    public function cmsSearch($search, $fields = [])
180
    {
181
        $query = $this->model->latest();
182
183
        $translatedAttributes = $this->model->translatedAttributes ?? [];
0 ignored issues
show
Bug introduced by
The property translatedAttributes does not seem to exist on A17\Twill\Models\Model. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
184
185
        foreach ($fields as $field) {
186
            if (in_array($field, $translatedAttributes)) {
187
                $query->orWhereHas('translations', function ($q) use ($field, $search) {
188
                    $q->where($field, $this->getLikeOperator(), "%{$search}%");
189
                });
190
            } else {
191
                $query->orWhere($field, $this->getLikeOperator(), "%{$search}%");
192
            }
193
        }
194
195
        return $query->get();
196
    }
197
198
    /**
199
     * @param $attributes
200
     * @param $fields
201
     * @return \A17\Twill\Models\Model
202
     */
203
    public function firstOrCreate($attributes, $fields)
204
    {
205
        return $this->model->where($attributes)->first() ?? $this->create($fields);
206
    }
207
208
    /**
209
     * @param string[] $fields
210
     * @return \A17\Twill\Models\Model
211
     */
212 27
    public function create($fields)
213
    {
214
        return DB::transaction(function () use ($fields) {
215 27
            $original_fields = $fields;
216
217 27
            $fields = $this->prepareFieldsBeforeCreate($fields);
218
219 27
            $object = $this->model->create(Arr::except($fields, $this->getReservedFields()));
220
221 27
            $this->beforeSave($object, $original_fields);
222
223 27
            $fields = $this->prepareFieldsBeforeSave($object, $fields);
224
225 27
            $object->save();
226
227 27
            $this->afterSave($object, $fields);
228
229 23
            return $object;
230 27
        }, 3);
231
    }
232
233
    /**
234
     * @param array $fields
235
     * @return \A17\Twill\Models\Model
236
     */
237 2
    public function createForPreview($fields)
238
    {
239 2
        $fields = $this->prepareFieldsBeforeCreate($fields);
240
241 2
        $object = $this->model->newInstance(Arr::except($fields, $this->getReservedFields()));
242
243 2
        return $this->hydrate($object, $fields);
244
    }
245
246
    /**
247
     * @param array $attributes
248
     * @param array $fields
249
     * @return \A17\Twill\Models\Model
250
     */
251
    public function updateOrCreate($attributes, $fields)
252
    {
253
        $object = $this->model->where($attributes)->first();
254
255
        if (!$object) {
256
            return $this->create($fields);
257
        }
258
259
        $this->update($object->id, $fields);
260
    }
261
262
    /**
263
     * @param mixed $id
264
     * @param array $fields
265
     * @return void
266
     */
267 10
    public function update($id, $fields)
268
    {
269
        DB::transaction(function () use ($id, $fields) {
270 10
            $object = $this->model->findOrFail($id);
271
272 10
            $this->beforeSave($object, $fields);
273
274 10
            $fields = $this->prepareFieldsBeforeSave($object, $fields);
275
276 10
            $object->fill(Arr::except($fields, $this->getReservedFields()));
277
278 10
            $object->save();
279
280 10
            $this->afterSave($object, $fields);
281 10
        }, 3);
282 10
    }
283
284
    /**
285
     * @param mixed $id
286
     * @param array $values
287
     * @param array $scopes
288
     * @return mixed
289
     */
290 4
    public function updateBasic($id, $values, $scopes = [])
291
    {
292
        return DB::transaction(function () use ($id, $values, $scopes) {
293
            // apply scopes if no id provided
294 4
            if (is_null($id)) {
295 1
                $query = $this->model->query();
296
297 1
                foreach ($scopes as $column => $value) {
298
                    $query->where($column, $value);
299
                }
300
301 1
                $query->update($values);
302
303
                $query->get()->each(function ($object) use ($values) {
304
                    $this->afterUpdateBasic($object, $values);
305 1
                });
306
307 1
                return true;
308
            }
309
310
            // apply to all ids if array of ids provided
311 3
            if (is_array($id)) {
312
                $query = $this->model->whereIn('id', $id);
313
                $query->update($values);
314
315
                $query->get()->each(function ($object) use ($values) {
316
                    $this->afterUpdateBasic($object, $values);
317
                });
318
319
                return true;
320
            }
321
322 3
            if (($object = $this->model->find($id)) != null) {
323 2
                $object->update($values);
324 2
                $this->afterUpdateBasic($object, $values);
325 2
                return true;
326
            }
327
328 1
            return false;
329 4
        }, 3);
330
    }
331
332
    /**
333
     * @param array $ids
334
     * @return void
335
     */
336 2
    public function setNewOrder($ids)
337
    {
338
        DB::transaction(function () use ($ids) {
339 2
            $this->model->setNewOrder($ids);
340 2
        }, 3);
341 1
    }
342
343
    /**
344
     * @param mixed $id
345
     * @return mixed
346
     */
347 2
    public function delete($id)
348
    {
349
        return DB::transaction(function () use ($id) {
350 2
            if (($object = $this->model->find($id)) === null) {
351
                return false;
352
            }
353
354 2
            if (!method_exists($object, 'canDeleteSafely') || $object->canDeleteSafely()) {
355 2
                $object->delete();
356 2
                $this->afterDelete($object);
357 2
                return true;
358
            }
359
            return false;
360 2
        }, 3);
361
    }
362
363
    /**
364
     * @param array $ids
365
     * @return mixed
366
     */
367 17
    public function bulkDelete($ids)
368
    {
369
        return DB::transaction(function () use ($ids) {
370
            try {
371
                Collection::make($ids)->each(function ($id) {
372
                    $this->delete($id);
373 17
                });
374
            } catch (\Exception $e) {
375
                Log::error($e);
376
                return false;
377
            }
378
379 17
            return true;
380 17
        }, 3);
381
    }
382
383
    /**
384
     * @param mixed $id
385
     * @return mixed
386
     */
387
    public function forceDelete($id)
388
    {
389
        return DB::transaction(function () use ($id) {
390
            if (($object = $this->model->onlyTrashed()->find($id)) === null) {
391
                return false;
392
            } else {
393
                $object->forceDelete();
394
                $this->afterDelete($object);
395
                return true;
396
            }
397
        }, 3);
398
    }
399
400
    /**
401
     * @param mixed $id
402
     * @return mixed
403
     */
404
    public function bulkForceDelete($ids)
405
    {
406
        return DB::transaction(function () use ($ids) {
407
            try {
408
                $query = $this->model->onlyTrashed()->whereIn('id', $ids);
409
                $objects = $query->get();
410
411
                $query->forceDelete();
412
413
                $objects->each(function ($object) {
414
                    $this->afterDelete($object);
415
                });
416
            } catch (\Exception $e) {
417
                Log::error($e);
418
                return false;
419
            }
420
421
            return true;
422
        }, 3);
423
    }
424
425
    /**
426
     * @param mixed $id
427
     * @return mixed
428
     */
429 2
    public function restore($id)
430
    {
431
        return DB::transaction(function () use ($id) {
432 2
            if (($object = $this->model->withTrashed()->find($id)) != null) {
433 1
                $object->restore();
434 1
                $this->afterRestore($object);
435 1
                return true;
436
            }
437
438 1
            return false;
439 2
        }, 3);
440
    }
441
442
    /**
443
     * @param array $ids
444
     * @return mixed
445
     */
446
    public function bulkRestore($ids)
447
    {
448
        return DB::transaction(function () use ($ids) {
449
            try {
450
                $query = $this->model->withTrashed()->whereIn('id', $ids);
451
                $objects = $query->get();
452
453
                $query->restore();
454
455
                $objects->each(function ($object) {
456
                    $this->afterRestore($object);
457
                });
458
            } catch (\Exception $e) {
459
                Log::error($e);
460
                return false;
461
            }
462
463
            return true;
464
        }, 3);
465
    }
466
467
    /**
468
     * @param \A17\Twill\Models\Model $object
469
     * @param array $fields
470
     * @return array
471
     */
472 28
    public function cleanupFields($object, $fields)
473
    {
474 28
        if (property_exists($this->model, 'checkboxes')) {
475 21
            foreach ($this->model->checkboxes as $field) {
0 ignored issues
show
Bug introduced by
The property checkboxes does not seem to exist on A17\Twill\Models\Model. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
476 21
                if (!$this->shouldIgnoreFieldBeforeSave($field)) {
477 21
                    if (!isset($fields[$field])) {
478 5
                        $fields[$field] = false;
479
                    } else {
480 21
                        $fields[$field] = !empty($fields[$field]);
481
                    }
482
                }
483
            }
484
        }
485
486 28
        if (property_exists($this->model, 'nullable')) {
487
            foreach ($this->model->nullable as $field) {
0 ignored issues
show
Bug introduced by
The property nullable does not seem to exist on A17\Twill\Models\Model. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
488
                if (!isset($fields[$field]) && !$this->shouldIgnoreFieldBeforeSave($field)) {
489
                    $fields[$field] = null;
490
                }
491
            }
492
        }
493
494 28
        foreach ($fields as $key => $value) {
495 28
            if (!$this->shouldIgnoreFieldBeforeSave($key)) {
496 28
                if (is_array($value) && empty($value)) {
497 7
                    $fields[$key] = null;
498
                }
499 28
                if ($value === '') {
500
                    $fields[$key] = null;
501
                }
502
            }
503
        }
504
505 28
        return $fields;
506
    }
507
508
    /**
509
     * @param array $fields
510
     * @return array
511
     */
512 22
    public function prepareFieldsBeforeCreate($fields)
513
    {
514 22
        $fields = $this->cleanupFields(null, $fields);
515
516 22
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
517 22
            $fields = $this->$method($fields);
518
        }
519
520 22
        return $fields;
521
    }
522
523
    /**
524
     * @param \A17\Twill\Models\Model $object
525
     * @param array $fields
526
     * @return string[]
527
     */
528 27
    public function prepareFieldsBeforeSave($object, $fields)
529
    {
530 27
        $fields = $this->cleanupFields($object, $fields);
531
532 27
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
533 27
            $fields = $this->$method($object, $fields);
534
        }
535
536 27
        return $fields;
537
    }
538
539
    /**
540
     * @param \A17\Twill\Models\Model $object
541
     * @param array $fields
542
     * @return void
543
     */
544 2
    public function afterUpdateBasic($object, $fields)
545
    {
546 2
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
547
            $this->$method($object, $fields);
548
        }
549 2
    }
550
551
    /**
552
     * @param \A17\Twill\Models\Model $object
553
     * @param array $fields
554
     * @return void
555
     */
556 27
    public function beforeSave($object, $fields)
557
    {
558 27
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
559 17
            $this->$method($object, $fields);
560
        }
561 27
    }
562
563
    /**
564
     * @param \A17\Twill\Models\Model $object
565
     * @param array $fields
566
     * @return void
567
     */
568 23
    public function afterSave($object, $fields)
569
    {
570 23
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
571 23
            $this->$method($object, $fields);
572
        }
573 23
    }
574
575
    /**
576
     * @param \A17\Twill\Models\Model $object
577
     * @return void
578
     */
579 2
    public function afterDelete($object)
580
    {
581 2
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
582 2
            $this->$method($object);
583
        }
584 2
    }
585
586
    /**
587
     * @param \A17\Twill\Models\Model $object
588
     * @return void
589
     */
590 1
    public function afterRestore($object)
591
    {
592 1
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
593 1
            $this->$method($object);
594
        }
595 1
    }
596
597
    /**
598
     * @param \A17\Twill\Models\Model $object
599
     * @param array $fields
600
     * @return \A17\Twill\Models\Model
601
     */
602 3
    public function hydrate($object, $fields)
603
    {
604 3
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
605 3
            $object = $this->$method($object, $fields);
606
        }
607
608 3
        return $object;
609
    }
610
611
    /**
612
     * @param \A17\Twill\Models\Model $object
613
     * @return array
614
     */
615 5
    public function getFormFields($object)
616
    {
617 5
        $fields = $object->attributesToArray();
618
619 5
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
620 5
            $fields = $this->$method($object, $fields);
621
        }
622
623 5
        return $fields;
624
    }
625
626
    /**
627
     * @param \Illuminate\Database\Query\Builder $query
628
     * @param array $scopes
629
     * @return \Illuminate\Database\Query\Builder
630
     */
631 12
    public function filter($query, array $scopes = [])
632
    {
633 12
        $likeOperator = $this->getLikeOperator();
634
635 12
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
636 11
            $this->$method($query, $scopes);
637
        }
638
639 12
        unset($scopes['search']);
640
641 12
        if (isset($scopes['exceptIds'])) {
642 2
            $query->whereNotIn($this->model->getTable() . '.id', $scopes['exceptIds']);
643 2
            unset($scopes['exceptIds']);
644
        }
645
646 12
        foreach ($scopes as $column => $value) {
647 5
            if (method_exists($this->model, 'scope' . ucfirst($column))) {
648 1
                $query->$column();
649
            } else {
650 4
                if (is_array($value)) {
651 2
                    $query->whereIn($column, $value);
652 2
                } elseif ($column[0] == '%') {
653
                    $value && ($value[0] == '!') ? $query->where(substr($column, 1), "not $likeOperator", '%' . substr($value, 1) . '%') : $query->where(substr($column, 1), $likeOperator, '%' . $value . '%');
654 2
                } elseif (isset($value[0]) && $value[0] == '!') {
655
                    $query->where($column, '<>', substr($value, 1));
656 2
                } elseif ($value !== '') {
657 2
                    $query->where($column, $value);
658
                }
659
            }
660
        }
661
662 12
        return $query;
663
    }
664
665
    /**
666
     * @param \Illuminate\Database\Query\Builder $query
667
     * @param array $orders
668
     * @return \Illuminate\Database\Query\Builder
669
     */
670 12
    public function order($query, array $orders = [])
671
    {
672 12
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
673 7
            $this->$method($query, $orders);
674
        }
675
676 12
        foreach ($orders as $column => $direction) {
677 5
            $query->orderBy($column, $direction);
678
        }
679
680 12
        return $query;
681
    }
682
683
    /**
684
     * @param \A17\Twill\Models\Model $object
685
     * @param array $fields
686
     * @param string $relationship
687
     * @param string $formField
688
     * @param string $attribute
689
     * @return void
690
     */
691
    public function updateOneToMany($object, $fields, $relationship, $formField, $attribute)
692
    {
693
        if (isset($fields[$formField])) {
694
            foreach ($fields[$formField] as $id) {
695
                $object->$relationship()->updateOrCreate([$attribute => $id]);
696
            }
697
698
            foreach ($object->$relationship as $relationshipObject) {
699
                if (!in_array($relationshipObject->$attribute, $fields[$formField])) {
700
                    $relationshipObject->delete();
701
                }
702
            }
703
        } else {
704
            $object->$relationship()->delete();
705
        }
706
    }
707
708
    /**
709
     * @param \A17\Twill\Models\Model $object
710
     * @param array $fields
711
     * @param string $relationship
712
     * @return void
713
     */
714
    public function updateMultiSelect($object, $fields, $relationship)
715
    {
716
        $object->$relationship()->sync($fields[$relationship] ?? []);
717
    }
718
719
    /**
720
     * @param \Illuminate\Database\Query\Builder $query
721
     * @param array $scopes
722
     * @param string $scopeField
723
     * @param string $scopeRelation
724
     * @return void
725
     */
726 9
    public function addRelationFilterScope($query, &$scopes, $scopeField, $scopeRelation)
727
    {
728 9
        if (isset($scopes[$scopeField])) {
729
            $id = $scopes[$scopeField];
730
            $query->whereHas($scopeRelation, function ($query) use ($id, $scopeField) {
731
                $query->where($scopeField, $id);
732
            });
733
            unset($scopes[$scopeField]);
734
        }
735 9
    }
736
737
    /**
738
     * @param \Illuminate\Database\Query\Builder $query
739
     * @param array $scopes
740
     * @param string $scopeField
741
     * @return void
742
     */
743
    public function addLikeFilterScope($query, &$scopes, $scopeField)
744
    {
745
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
746
            $query->where($scopeField, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
747
            unset($scopes[$scopeField]);
748
        }
749
    }
750
751
    /**
752
     * @param \Illuminate\Database\Query\Builder $query
753
     * @param array $scopes
754
     * @param string $scopeField
755
     * @param string[] $orFields
756
     */
757 5
    public function searchIn($query, &$scopes, $scopeField, $orFields = [])
758
    {
759
760 5
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
761
            $query->where(function ($query) use (&$scopes, $scopeField, $orFields) {
762 2
                foreach ($orFields as $field) {
763 2
                    $query->orWhere($field, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
764 2
                    unset($scopes[$field]);
765
                }
766 2
            });
767
        }
768 5
    }
769
770
    /**
771
     * @return bool
772
     */
773 2
    public function isUniqueFeature()
774
    {
775 2
        return false;
776
    }
777
778
    /**
779
     * @param array $ignore
780
     * @return void
781
     */
782
    public function addIgnoreFieldsBeforeSave($ignore = [])
783
    {
784
        $this->ignoreFieldsBeforeSave = is_array($ignore)
0 ignored issues
show
introduced by
The condition is_array($ignore) is always true.
Loading history...
785
        ? array_merge($this->ignoreFieldsBeforeSave, $ignore)
786
        : array_merge($this->ignoreFieldsBeforeSave, [$ignore]);
787
    }
788
789
    /**
790
     * @param string $ignore
791
     * @return bool
792
     */
793 28
    public function shouldIgnoreFieldBeforeSave($ignore)
794
    {
795 28
        return in_array($ignore, $this->ignoreFieldsBeforeSave);
796
    }
797
798
    /**
799
     * @return string[]
800
     */
801 28
    public function getReservedFields()
802
    {
803
        return [
804 28
            'medias',
805
            'browsers',
806
            'repeaters',
807
            'blocks',
808
        ];
809
    }
810
811
    /**
812
     * @param string $relation
813
     * @param \A17\Twill\Models\Model|null $model
814
     * @return mixed
815
     */
816
    protected function getModelRepository($relation, $model = null)
817
    {
818
        if (!$model) {
819
            $model = ucfirst(Str::singular($relation));
820
        }
821
822
        return App::make(Config::get('twill.namespace') . "\\Repositories\\" . ucfirst($model) . "Repository");
823
    }
824
825
    /**
826
     * @param string|null $method
827
     * @return array
828
     */
829 34
    protected function traitsMethods(string $method = null)
830
    {
831 34
        $method = $method ?? debug_backtrace()[1]['function'];
832
833 34
        $traits = array_values(class_uses_recursive(get_called_class()));
834
835 34
        $uniqueTraits = array_unique(array_map('class_basename', $traits));
836
837
        $methods = array_map(function (string $trait) use ($method) {
838 34
            return $method . $trait;
839 34
        }, $uniqueTraits);
840
841
        return array_filter($methods, function (string $method) {
842 34
            return method_exists(get_called_class(), $method);
843 34
        });
844
    }
845
846
    /**
847
     * @return string
848
     */
849 12
    private function getLikeOperator()
850
    {
851 12
        if (DB::connection()->getPDO()->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') {
852
            return 'ILIKE';
853
        }
854
855 12
        return 'LIKE';
856
    }
857
858
    /**
859
     * @param string $method
860
     * @param array $parameters
861
     * @return mixed
862
     */
863 2
    public function __call($method, $parameters)
864
    {
865 2
        return $this->model->$method(...$parameters);
866
    }
867
}
868