Passed
Push — 1.2 ( d1c999...7e4501 )
by Quentin
05:19
created

ModuleRepository::traitsMethods()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 14
rs 10
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\HandleFieldsGroups;
10
use Illuminate\Support\Arr;
11
use Illuminate\Support\Collection;
12
use Illuminate\Support\Facades\App;
13
use Illuminate\Support\Facades\Config;
14
use Illuminate\Support\Facades\DB;
15
use Illuminate\Support\Facades\Log;
16
use Illuminate\Support\Str;
17
use PDO;
18
19
abstract class ModuleRepository
20
{
21
    use HandleDates, HandleBrowsers, HandleFieldsGroups;
0 ignored issues
show
introduced by
The trait A17\Twill\Repositories\Behaviors\HandleBrowsers requires some properties which are not provided by A17\Twill\Repositories\ModuleRepository: $titleInBrowser, $id, $adminEditUrl, $browsers, $title
Loading history...
22
  
23
    /**
24
     * @var \A17\Twill\Models\Model
25
     */
26
    protected $model;
27
28
    /**
29
     * @var string[]
30
     */
31
    protected $ignoreFieldsBeforeSave = [];
32
33
    /**
34
     * @var array
35
     */
36
    protected $countScope = [];
37
38
    /**
39
     * @var array
40
     */
41
    protected $fieldsGroups = [];
42
43
    /**
44
     * @param array $with
45
     * @param array $scopes
46
     * @param array $orders
47
     * @param int $perPage
48
     * @param bool $forcePagination
49
     * @return \Illuminate\Database\Eloquent\Collection
50
     */
51
    public function get($with = [], $scopes = [], $orders = [], $perPage = 20, $forcePagination = false)
52
    {
53
        $query = $this->model->with($with);
54
55
        $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

55
        $query = $this->filter(/** @scrutinizer ignore-type */ $query, $scopes);
Loading history...
56
        $query = $this->order($query, $orders);
57
58
        if (!$forcePagination && $this->model instanceof Sortable) {
59
            return $query->ordered()->get();
60
        }
61
62
        if ($perPage == -1) {
63
            return $query->get();
64
        }
65
66
        return $query->paginate($perPage);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $query->paginate($perPage) returns the type Illuminate\Pagination\LengthAwarePaginator which is incompatible with the documented return type Illuminate\Database\Eloquent\Collection.
Loading history...
67
    }
68
69
    /**
70
     * @param string $slug
71
     * @param array $scope
72
     * @return int
73
     */
74
    public function getCountByStatusSlug($slug, $scope = [])
75
    {
76
        $this->countScope = $scope;
77
78
        switch ($slug) {
79
            case 'all':
80
                return $this->getCountForAll();
81
            case 'published':
82
                return $this->getCountForPublished();
83
            case 'draft':
84
                return $this->getCountForDraft();
85
            case 'trash':
86
                return $this->getCountForTrash();
87
        }
88
89
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
90
            if (($count = $this->$method($slug)) !== false) {
91
                return $count;
92
            }
93
        }
94
95
        return 0;
96
    }
97
98
    /**
99
     * @return int
100
     */
101
    public function getCountForAll()
102
    {
103
        $query = $this->model->newQuery();
104
        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

104
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->count();
Loading history...
105
    }
106
107
    /**
108
     * @return int
109
     */
110
    public function getCountForPublished()
111
    {
112
        $query = $this->model->newQuery();
113
        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

113
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->published()->count();
Loading history...
114
    }
115
116
    /**
117
     * @return int
118
     */
119
    public function getCountForDraft()
120
    {
121
        $query = $this->model->newQuery();
122
        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

122
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->draft()->count();
Loading history...
123
    }
124
125
    /**
126
     * @return int
127
     */
128
    public function getCountForTrash()
129
    {
130
        $query = $this->model->newQuery();
131
        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

131
        return $this->filter(/** @scrutinizer ignore-type */ $query, $this->countScope)->onlyTrashed()->count();
Loading history...
132
    }
133
134
    /**
135
     * @param $id
136
     * @param array $with
137
     * @param array $withCount
138
     * @return \A17\Twill\Models\Model
139
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
140
     */
141
    public function getById($id, $with = [], $withCount = [])
142
    {
143
        return $this->model->with($with)->withCount($withCount)->findOrFail($id);
144
    }
145
146
    /**
147
     * @param string $column
148
     * @param array $orders
149
     * @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...
150
     * @return \Illuminate\Support\Collection
151
     */
152
    public function listAll($column = 'title', $orders = [], $exceptId = null)
153
    {
154
        $query = $this->model->newQuery();
155
156
        if ($exceptId) {
0 ignored issues
show
introduced by
$exceptId is of type null, thus it always evaluated to false.
Loading history...
157
            $query = $query->where($this->model->getTable() . '.id', '<>', $exceptId);
158
        }
159
160
        if ($this->model instanceof Sortable) {
161
            $query = $query->ordered();
162
        } elseif (!empty($orders)) {
163
            $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

163
            $query = $this->order(/** @scrutinizer ignore-type */ $query, $orders);
Loading history...
164
        }
165
166
        if (property_exists($this->model, 'translatedAttributes')) {
167
            $query = $query->withTranslation();
168
        }
169
170
        return $query->get()->pluck($column, 'id');
171
    }
172
173
    /**
174
     * @param $search
175
     * @param array $fields
176
     * @return \Illuminate\Database\Eloquent\Collection
177
     */
178
    public function cmsSearch($search, $fields = [])
179
    {
180
        $query = $this->model->latest();
181
182
        $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...
183
184
        foreach ($fields as $field) {
185
            if (in_array($field, $translatedAttributes)) {
186
                $query->orWhereHas('translations', function ($q) use ($field, $search) {
187
                    $q->where($field, $this->getLikeOperator(), "%{$search}%");
188
                });
189
            } else {
190
                $query->orWhere($field, $this->getLikeOperator(), "%{$search}%");
191
            }
192
        }
193
194
        return $query->get();
195
    }
196
197
    /**
198
     * @param $attributes
199
     * @param $fields
200
     * @return \A17\Twill\Models\Model
201
     */
202
    public function firstOrCreate($attributes, $fields)
203
    {
204
        return $this->model->where($attributes)->first() ?? $this->create($fields);
205
    }
206
207
    /**
208
     * @param string[] $fields
209
     * @return \A17\Twill\Models\Model
210
     */
211
    public function create($fields)
212
    {
213
        return DB::transaction(function () use ($fields) {
214
            $original_fields = $fields;
215
216
            $fields = $this->prepareFieldsBeforeCreate($fields);
217
218
            $object = $this->model->create(Arr::except($fields, $this->getReservedFields()));
219
220
            $this->beforeSave($object, $original_fields);
221
222
            $fields = $this->prepareFieldsBeforeSave($object, $fields);
223
224
            $object->save();
225
226
            $this->afterSave($object, $fields);
227
228
            return $object;
229
        }, 3);
230
    }
231
232
    /**
233
     * @param array $fields
234
     * @return \A17\Twill\Models\Model
235
     */
236
    public function createForPreview($fields)
237
    {
238
        $fields = $this->prepareFieldsBeforeCreate($fields);
239
240
        $object = $this->model->newInstance(Arr::except($fields, $this->getReservedFields()));
241
242
        return $this->hydrate($object, $fields);
243
    }
244
245
    /**
246
     * @param array $attributes
247
     * @param array $fields
248
     * @return \A17\Twill\Models\Model
249
     */
250
    public function updateOrCreate($attributes, $fields)
251
    {
252
        $object = $this->model->where($attributes)->first();
253
254
        if (!$object) {
255
            return $this->create($fields);
256
        }
257
258
        $this->update($object->id, $fields);
259
    }
260
261
    /**
262
     * @param mixed $id
263
     * @param array $fields
264
     * @return void
265
     */
266
    public function update($id, $fields)
267
    {
268
        DB::transaction(function () use ($id, $fields) {
269
            $object = $this->model->findOrFail($id);
270
271
            $this->beforeSave($object, $fields);
272
273
            $fields = $this->prepareFieldsBeforeSave($object, $fields);
274
275
            $object->fill(Arr::except($fields, $this->getReservedFields()));
276
277
            $object->save();
278
279
            $this->afterSave($object, $fields);
280
        }, 3);
281
    }
282
283
    /**
284
     * @param mixed $id
285
     * @param array $values
286
     * @param array $scopes
287
     * @return mixed
288
     */
289
    public function updateBasic($id, $values, $scopes = [])
290
    {
291
        return DB::transaction(function () use ($id, $values, $scopes) {
292
            // apply scopes if no id provided
293
            if (is_null($id)) {
294
                $query = $this->model->query();
295
296
                foreach ($scopes as $column => $value) {
297
                    $query->where($column, $value);
298
                }
299
300
                $query->update($values);
301
302
                $query->get()->each(function ($object) use ($values) {
303
                    $this->afterUpdateBasic($object, $values);
304
                });
305
306
                return true;
307
            }
308
309
            // apply to all ids if array of ids provided
310
            if (is_array($id)) {
311
                $query = $this->model->whereIn('id', $id);
312
                $query->update($values);
313
314
                $query->get()->each(function ($object) use ($values) {
315
                    $this->afterUpdateBasic($object, $values);
316
                });
317
318
                return true;
319
            }
320
321
            if (($object = $this->model->find($id)) != null) {
322
                $object->update($values);
323
                $this->afterUpdateBasic($object, $values);
324
                return true;
325
            }
326
327
            return false;
328
        }, 3);
329
    }
330
331
    /**
332
     * @param array $ids
333
     * @return void
334
     */
335
    public function setNewOrder($ids)
336
    {
337
        DB::transaction(function () use ($ids) {
338
            $this->model->setNewOrder($ids);
339
        }, 3);
340
    }
341
342
    /**
343
     * @param mixed $id
344
     * @return mixed
345
     */
346
    public function delete($id)
347
    {
348
        return DB::transaction(function () use ($id) {
349
            if (($object = $this->model->find($id)) === null) {
350
                return false;
351
            }
352
353
            if (!method_exists($object, 'canDeleteSafely') || $object->canDeleteSafely()) {
354
                $object->delete();
355
                $this->afterDelete($object);
356
                return true;
357
            }
358
            return false;
359
        }, 3);
360
    }
361
362
    /**
363
     * @param array $ids
364
     * @return mixed
365
     */
366
    public function bulkDelete($ids)
367
    {
368
        return DB::transaction(function () use ($ids) {
369
            try {
370
                Collection::make($ids)->each(function ($id) {
371
                    $this->delete($id);
372
                });
373
            } catch (\Exception $e) {
374
                Log::error($e);
375
                return false;
376
            }
377
378
            return true;
379
        }, 3);
380
    }
381
382
    /**
383
     * @param mixed $id
384
     * @return mixed
385
     */
386
    public function restore($id)
387
    {
388
        return DB::transaction(function () use ($id) {
389
            if (($object = $this->model->withTrashed()->find($id)) != null) {
390
                $object->restore();
391
                $this->afterRestore($object);
392
                return true;
393
            }
394
395
            return false;
396
        }, 3);
397
    }
398
399
    /**
400
     * @param array $ids
401
     * @return mixed
402
     */
403
    public function bulkRestore($ids)
404
    {
405
        return DB::transaction(function () use ($ids) {
406
            try {
407
                $query = $this->model->withTrashed()->whereIn('id', $ids);
408
                $objects = $query->get();
409
410
                $query->restore();
411
412
                $objects->each(function ($object) {
413
                    $this->afterRestore($object);
414
                });
415
            } catch (\Exception $e) {
416
                Log::error($e);
417
                return false;
418
            }
419
420
            return true;
421
        }, 3);
422
    }
423
424
    /**
425
     * @param \A17\Twill\Models\Model $object
426
     * @param array $fields
427
     * @return array
428
     */
429
    public function cleanupFields($object, $fields)
430
    {
431
        if (property_exists($this->model, 'checkboxes')) {
432
            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...
433
                if (!$this->shouldIgnoreFieldBeforeSave($field)) {
434
                    if (!isset($fields[$field])) {
435
                        $fields[$field] = false;
436
                    } else {
437
                        $fields[$field] = !empty($fields[$field]);
438
                    }
439
                }
440
            }
441
        }
442
443
        if (property_exists($this->model, 'nullable')) {
444
            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...
445
                if (!isset($fields[$field]) && !$this->shouldIgnoreFieldBeforeSave($field)) {
446
                    $fields[$field] = null;
447
                }
448
            }
449
        }
450
451
        foreach ($fields as $key => $value) {
452
            if (!$this->shouldIgnoreFieldBeforeSave($key)) {
453
                if (is_array($value) && empty($value)) {
454
                    $fields[$key] = null;
455
                }
456
                if ($value === '') {
457
                    $fields[$key] = null;
458
                }
459
            }
460
        }
461
462
        return $fields;
463
    }
464
465
    /**
466
     * @param array $fields
467
     * @return array
468
     */
469
    public function prepareFieldsBeforeCreate($fields)
470
    {
471
        $fields = $this->cleanupFields(null, $fields);
472
473
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
474
            $fields = $this->$method($fields);
475
        }
476
477
        return $fields;
478
    }
479
480
    /**
481
     * @param \A17\Twill\Models\Model $object
482
     * @param array $fields
483
     * @return string[]
484
     */
485
    public function prepareFieldsBeforeSave($object, $fields)
486
    {
487
        $fields = $this->cleanupFields($object, $fields);
488
489
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
490
            $fields = $this->$method($object, $fields);
491
        }
492
493
        return $fields;
494
    }
495
496
    /**
497
     * @param \A17\Twill\Models\Model $object
498
     * @param array $fields
499
     * @return void
500
     */
501
    public function afterUpdateBasic($object, $fields)
502
    {
503
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
504
            $this->$method($object, $fields);
505
        }
506
    }
507
508
    /**
509
     * @param \A17\Twill\Models\Model $object
510
     * @param array $fields
511
     * @return void
512
     */
513
    public function beforeSave($object, $fields)
514
    {
515
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
516
            $this->$method($object, $fields);
517
        }
518
    }
519
520
    /**
521
     * @param \A17\Twill\Models\Model $object
522
     * @param array $fields
523
     * @return void
524
     */
525
    public function afterSave($object, $fields)
526
    {
527
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
528
            $this->$method($object, $fields);
529
        }
530
    }
531
532
    /**
533
     * @param \A17\Twill\Models\Model $object
534
     * @return void
535
     */
536
    public function afterDelete($object)
537
    {
538
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
539
            $this->$method($object);
540
        }
541
    }
542
543
    /**
544
     * @param \A17\Twill\Models\Model $object
545
     * @return void
546
     */
547
    public function afterRestore($object)
548
    {
549
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
550
            $this->$method($object);
551
        }
552
    }
553
554
    /**
555
     * @param \A17\Twill\Models\Model $object
556
     * @param array $fields
557
     * @return \A17\Twill\Models\Model
558
     */
559
    public function hydrate($object, $fields)
560
    {
561
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
562
            $object = $this->$method($object, $fields);
563
        }
564
565
        return $object;
566
    }
567
568
    /**
569
     * @param \A17\Twill\Models\Model $object
570
     * @return array
571
     */
572
    public function getFormFields($object)
573
    {
574
        $fields = $object->attributesToArray();
575
576
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
577
            $fields = $this->$method($object, $fields);
578
        }
579
580
        return $fields;
581
    }
582
583
    /**
584
     * @param \Illuminate\Database\Query\Builder $query
585
     * @param array $scopes
586
     * @return \Illuminate\Database\Query\Builder
587
     */
588
    public function filter($query, array $scopes = [])
589
    {
590
        $likeOperator = $this->getLikeOperator();
591
592
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
593
            $this->$method($query, $scopes);
594
        }
595
596
        unset($scopes['search']);
597
598
        if (isset($scopes['exceptIds'])) {
599
            $query->whereNotIn($this->model->getTable() . '.id', $scopes['exceptIds']);
600
            unset($scopes['exceptIds']);
601
        }
602
603
        foreach ($scopes as $column => $value) {
604
            if (method_exists($this->model, 'scope' . ucfirst($column))) {
605
                $query->$column();
606
            } else {
607
                if (is_array($value)) {
608
                    $query->whereIn($column, $value);
609
                } elseif ($column[0] == '%') {
610
                    $value && ($value[0] == '!') ? $query->where(substr($column, 1), "not $likeOperator", '%' . substr($value, 1) . '%') : $query->where(substr($column, 1), $likeOperator, '%' . $value . '%');
611
                } elseif (isset($value[0]) && $value[0] == '!') {
612
                    $query->where($column, '<>', substr($value, 1));
613
                } elseif ($value !== '') {
614
                    $query->where($column, $value);
615
                }
616
            }
617
        }
618
619
        return $query;
620
    }
621
622
    /**
623
     * @param \Illuminate\Database\Query\Builder $query
624
     * @param array $orders
625
     * @return \Illuminate\Database\Query\Builder
626
     */
627
    public function order($query, array $orders = [])
628
    {
629
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
630
            $this->$method($query, $orders);
631
        }
632
633
        foreach ($orders as $column => $direction) {
634
            $query->orderBy($column, $direction);
635
        }
636
637
        return $query;
638
    }
639
640
    /**
641
     * @param \A17\Twill\Models\Model $object
642
     * @param array $fields
643
     * @param string $relationship
644
     * @param string $formField
645
     * @param string $attribute
646
     * @return void
647
     */
648
    public function updateOneToMany($object, $fields, $relationship, $formField, $attribute)
649
    {
650
        if (isset($fields[$formField])) {
651
            foreach ($fields[$formField] as $id) {
652
                $object->$relationship()->updateOrCreate([$attribute => $id]);
653
            }
654
655
            foreach ($object->$relationship as $relationshipObject) {
656
                if (!in_array($relationshipObject->$attribute, $fields[$formField])) {
657
                    $relationshipObject->delete();
658
                }
659
            }
660
        } else {
661
            $object->$relationship()->delete();
662
        }
663
    }
664
665
    /**
666
     * @param \A17\Twill\Models\Model $object
667
     * @param array $fields
668
     * @param string $relationship
669
     * @return void
670
     */
671
    public function updateMultiSelect($object, $fields, $relationship)
672
    {
673
        $object->$relationship()->sync($fields[$relationship] ?? []);
674
    }
675
676
    /**
677
     * @param \Illuminate\Database\Query\Builder $query
678
     * @param array $scopes
679
     * @param string $scopeField
680
     * @param string $scopeRelation
681
     * @return void
682
     */
683
    public function addRelationFilterScope($query, &$scopes, $scopeField, $scopeRelation)
684
    {
685
        if (isset($scopes[$scopeField])) {
686
            $id = $scopes[$scopeField];
687
            $query->whereHas($scopeRelation, function ($query) use ($id, $scopeField) {
688
                $query->where($scopeField, $id);
689
            });
690
            unset($scopes[$scopeField]);
691
        }
692
    }
693
694
    /**
695
     * @param \Illuminate\Database\Query\Builder $query
696
     * @param array $scopes
697
     * @param string $scopeField
698
     * @return void
699
     */
700
    public function addLikeFilterScope($query, &$scopes, $scopeField)
701
    {
702
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
703
            $query->where($scopeField, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
704
            unset($scopes[$scopeField]);
705
        }
706
    }
707
708
    /**
709
     * @param \Illuminate\Database\Query\Builder $query
710
     * @param array $scopes
711
     * @param string $scopeField
712
     * @param string[] $orFields
713
     */
714
    public function searchIn($query, &$scopes, $scopeField, $orFields = [])
715
    {
716
717
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
718
            $query->where(function ($query) use (&$scopes, $scopeField, $orFields) {
719
                foreach ($orFields as $field) {
720
                    $query->orWhere($field, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
721
                    unset($scopes[$field]);
722
                }
723
            });
724
        }
725
    }
726
727
    /**
728
     * @return bool
729
     */
730
    public function isUniqueFeature()
731
    {
732
        return false;
733
    }
734
735
    /**
736
     * @param array $ignore
737
     * @return void
738
     */
739
    public function addIgnoreFieldsBeforeSave($ignore = [])
740
    {
741
        $this->ignoreFieldsBeforeSave = is_array($ignore)
0 ignored issues
show
introduced by
The condition is_array($ignore) is always true.
Loading history...
742
        ? array_merge($this->ignoreFieldsBeforeSave, $ignore)
743
        : array_merge($this->ignoreFieldsBeforeSave, [$ignore]);
744
    }
745
746
    /**
747
     * @param string $ignore
748
     * @return bool
749
     */
750
    public function shouldIgnoreFieldBeforeSave($ignore)
751
    {
752
        return in_array($ignore, $this->ignoreFieldsBeforeSave);
753
    }
754
755
    /**
756
     * @return string[]
757
     */
758
    public function getReservedFields()
759
    {
760
        return [
761
            'medias',
762
            'browsers',
763
            'repeaters',
764
            'blocks',
765
        ];
766
    }
767
768
    /**
769
     * @param string $relation
770
     * @param \A17\Twill\Models\Model|null $model
771
     * @return mixed
772
     */
773
    protected function getModelRepository($relation, $model = null)
774
    {
775
        if (!$model) {
776
            $model = ucfirst(Str::singular($relation));
777
        }
778
779
        return App::make(Config::get('twill.namespace') . "\\Repositories\\" . ucfirst($model) . "Repository");
780
    }
781
782
    /**
783
     * @param string|null $method
784
     * @return array
785
     */
786
    protected function traitsMethods(string $method = null)
787
    {
788
        $method = $method ?? debug_backtrace()[1]['function'];
789
790
        $traits = array_values(class_uses_recursive(get_called_class()));
791
792
        $uniqueTraits = array_unique(array_map('class_basename', $traits));
793
794
        $methods = array_map(function (string $trait) use ($method) {
795
            return $method . $trait;
796
        }, $uniqueTraits);
797
798
        return array_filter($methods, function (string $method) {
799
            return method_exists(get_called_class(), $method);
800
        });
801
    }
802
803
    /**
804
     * @return string
805
     */
806
    private function getLikeOperator()
807
    {
808
        if (DB::connection()->getPDO()->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') {
809
            return 'ILIKE';
810
        }
811
812
        return 'LIKE';
813
    }
814
815
    /**
816
     * @param string $method
817
     * @param array $parameters
818
     * @return mixed
819
     */
820
    public function __call($method, $parameters)
821
    {
822
        return $this->model->$method(...$parameters);
823
    }
824
}
825