Passed
Push — feature/duplication ( 011e93 )
by
unknown
11:47
created

ModuleRepository::duplicate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
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\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 duplicate($id)
347
    {
348
        return true;
349
350
        // TODO: Implement duplication logic
351
352
        // return DB::transaction(function () use ($id) {
353
        //     if (($object = $this->model->find($id)) === null) {
354
        //         return false;
355
        //     }
356
357
        //     $object->duplicate();
358
        //     $this->afterDuplicate($object);
359
        //     return true;
360
        // }, 3);
361
    }
362
363
    /**
364
     * @param mixed $id
365
     * @return mixed
366
     */
367
    public function delete($id)
368
    {
369
        return DB::transaction(function () use ($id) {
370
            if (($object = $this->model->find($id)) === null) {
371
                return false;
372
            }
373
374
            if (!method_exists($object, 'canDeleteSafely') || $object->canDeleteSafely()) {
375
                $object->delete();
376
                $this->afterDelete($object);
377
                return true;
378
            }
379
            return false;
380
        }, 3);
381
    }
382
383
    /**
384
     * @param array $ids
385
     * @return mixed
386
     */
387
    public function bulkDelete($ids)
388
    {
389
        return DB::transaction(function () use ($ids) {
390
            try {
391
                Collection::make($ids)->each(function ($id) {
392
                    $this->delete($id);
393
                });
394
            } catch (\Exception $e) {
395
                Log::error($e);
396
                return false;
397
            }
398
399
            return true;
400
        }, 3);
401
    }
402
403
    /**
404
     * @param mixed $id
405
     * @return mixed
406
     */
407
    public function restore($id)
408
    {
409
        return DB::transaction(function () use ($id) {
410
            if (($object = $this->model->withTrashed()->find($id)) != null) {
411
                $object->restore();
412
                $this->afterRestore($object);
413
                return true;
414
            }
415
416
            return false;
417
        }, 3);
418
    }
419
420
    /**
421
     * @param array $ids
422
     * @return mixed
423
     */
424
    public function bulkRestore($ids)
425
    {
426
        return DB::transaction(function () use ($ids) {
427
            try {
428
                $query = $this->model->withTrashed()->whereIn('id', $ids);
429
                $objects = $query->get();
430
431
                $query->restore();
432
433
                $objects->each(function ($object) {
434
                    $this->afterRestore($object);
435
                });
436
            } catch (\Exception $e) {
437
                Log::error($e);
438
                return false;
439
            }
440
441
            return true;
442
        }, 3);
443
    }
444
445
    /**
446
     * @param \A17\Twill\Models\Model $object
447
     * @param array $fields
448
     * @return array
449
     */
450
    public function cleanupFields($object, $fields)
451
    {
452
        if (property_exists($this->model, 'checkboxes')) {
453
            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...
454
                if (!$this->shouldIgnoreFieldBeforeSave($field)) {
455
                    if (!isset($fields[$field])) {
456
                        $fields[$field] = false;
457
                    } else {
458
                        $fields[$field] = !empty($fields[$field]);
459
                    }
460
                }
461
            }
462
        }
463
464
        if (property_exists($this->model, 'nullable')) {
465
            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...
466
                if (!isset($fields[$field]) && !$this->shouldIgnoreFieldBeforeSave($field)) {
467
                    $fields[$field] = null;
468
                }
469
            }
470
        }
471
472
        foreach ($fields as $key => $value) {
473
            if (!$this->shouldIgnoreFieldBeforeSave($key)) {
474
                if (is_array($value) && empty($value)) {
475
                    $fields[$key] = null;
476
                }
477
                if ($value === '') {
478
                    $fields[$key] = null;
479
                }
480
            }
481
        }
482
483
        return $fields;
484
    }
485
486
    /**
487
     * @param array $fields
488
     * @return array
489
     */
490
    public function prepareFieldsBeforeCreate($fields)
491
    {
492
        $fields = $this->cleanupFields(null, $fields);
493
494
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
495
            $fields = $this->$method($fields);
496
        }
497
498
        return $fields;
499
    }
500
501
    /**
502
     * @param \A17\Twill\Models\Model $object
503
     * @param array $fields
504
     * @return string[]
505
     */
506
    public function prepareFieldsBeforeSave($object, $fields)
507
    {
508
        $fields = $this->cleanupFields($object, $fields);
509
510
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
511
            $fields = $this->$method($object, $fields);
512
        }
513
514
        return $fields;
515
    }
516
517
    /**
518
     * @param \A17\Twill\Models\Model $object
519
     * @param array $fields
520
     * @return void
521
     */
522
    public function afterUpdateBasic($object, $fields)
523
    {
524
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
525
            $this->$method($object, $fields);
526
        }
527
    }
528
529
    /**
530
     * @param \A17\Twill\Models\Model $object
531
     * @param array $fields
532
     * @return void
533
     */
534
    public function beforeSave($object, $fields)
535
    {
536
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
537
            $this->$method($object, $fields);
538
        }
539
    }
540
541
    /**
542
     * @param \A17\Twill\Models\Model $object
543
     * @param array $fields
544
     * @return void
545
     */
546
    public function afterSave($object, $fields)
547
    {
548
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
549
            $this->$method($object, $fields);
550
        }
551
    }
552
553
    /**
554
     * @param \A17\Twill\Models\Model $object
555
     * @return void
556
     */
557
    public function afterDelete($object)
558
    {
559
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
560
            $this->$method($object);
561
        }
562
    }
563
564
    /**
565
     * @param \A17\Twill\Models\Model $object
566
     * @return void
567
     */
568
    public function afterRestore($object)
569
    {
570
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
571
            $this->$method($object);
572
        }
573
    }
574
575
    /**
576
     * @param \A17\Twill\Models\Model $object
577
     * @param array $fields
578
     * @return \A17\Twill\Models\Model
579
     */
580
    public function hydrate($object, $fields)
581
    {
582
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
583
            $object = $this->$method($object, $fields);
584
        }
585
586
        return $object;
587
    }
588
589
    /**
590
     * @param \A17\Twill\Models\Model $object
591
     * @return array
592
     */
593
    public function getFormFields($object)
594
    {
595
        $fields = $object->attributesToArray();
596
597
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
598
            $fields = $this->$method($object, $fields);
599
        }
600
601
        return $fields;
602
    }
603
604
    /**
605
     * @param \Illuminate\Database\Query\Builder $query
606
     * @param array $scopes
607
     * @return \Illuminate\Database\Query\Builder
608
     */
609
    public function filter($query, array $scopes = [])
610
    {
611
        $likeOperator = $this->getLikeOperator();
612
613
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
614
            $this->$method($query, $scopes);
615
        }
616
617
        unset($scopes['search']);
618
619
        if (isset($scopes['exceptIds'])) {
620
            $query->whereNotIn($this->model->getTable() . '.id', $scopes['exceptIds']);
621
            unset($scopes['exceptIds']);
622
        }
623
624
        foreach ($scopes as $column => $value) {
625
            if (method_exists($this->model, 'scope' . ucfirst($column))) {
626
                $query->$column();
627
            } else {
628
                if (is_array($value)) {
629
                    $query->whereIn($column, $value);
630
                } elseif ($column[0] == '%') {
631
                    $value && ($value[0] == '!') ? $query->where(substr($column, 1), "not $likeOperator", '%' . substr($value, 1) . '%') : $query->where(substr($column, 1), $likeOperator, '%' . $value . '%');
632
                } elseif (isset($value[0]) && $value[0] == '!') {
633
                    $query->where($column, '<>', substr($value, 1));
634
                } elseif ($value !== '') {
635
                    $query->where($column, $value);
636
                }
637
            }
638
        }
639
640
        return $query;
641
    }
642
643
    /**
644
     * @param \Illuminate\Database\Query\Builder $query
645
     * @param array $orders
646
     * @return \Illuminate\Database\Query\Builder
647
     */
648
    public function order($query, array $orders = [])
649
    {
650
        foreach ($this->traitsMethods(__FUNCTION__) as $method) {
651
            $this->$method($query, $orders);
652
        }
653
654
        foreach ($orders as $column => $direction) {
655
            $query->orderBy($column, $direction);
656
        }
657
658
        return $query;
659
    }
660
661
    /**
662
     * @param \A17\Twill\Models\Model $object
663
     * @param array $fields
664
     * @param string $relationship
665
     * @param string $formField
666
     * @param string $attribute
667
     * @return void
668
     */
669
    public function updateOneToMany($object, $fields, $relationship, $formField, $attribute)
670
    {
671
        if (isset($fields[$formField])) {
672
            foreach ($fields[$formField] as $id) {
673
                $object->$relationship()->updateOrCreate([$attribute => $id]);
674
            }
675
676
            foreach ($object->$relationship as $relationshipObject) {
677
                if (!in_array($relationshipObject->$attribute, $fields[$formField])) {
678
                    $relationshipObject->delete();
679
                }
680
            }
681
        } else {
682
            $object->$relationship()->delete();
683
        }
684
    }
685
686
    /**
687
     * @param \A17\Twill\Models\Model $object
688
     * @param array $fields
689
     * @param string $relationship
690
     * @return void
691
     */
692
    public function updateMultiSelect($object, $fields, $relationship)
693
    {
694
        $object->$relationship()->sync($fields[$relationship] ?? []);
695
    }
696
697
    /**
698
     * @param \Illuminate\Database\Query\Builder $query
699
     * @param array $scopes
700
     * @param string $scopeField
701
     * @param string $scopeRelation
702
     * @return void
703
     */
704
    public function addRelationFilterScope($query, &$scopes, $scopeField, $scopeRelation)
705
    {
706
        if (isset($scopes[$scopeField])) {
707
            $id = $scopes[$scopeField];
708
            $query->whereHas($scopeRelation, function ($query) use ($id, $scopeField) {
709
                $query->where($scopeField, $id);
710
            });
711
            unset($scopes[$scopeField]);
712
        }
713
    }
714
715
    /**
716
     * @param \Illuminate\Database\Query\Builder $query
717
     * @param array $scopes
718
     * @param string $scopeField
719
     * @return void
720
     */
721
    public function addLikeFilterScope($query, &$scopes, $scopeField)
722
    {
723
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
724
            $query->where($scopeField, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
725
            unset($scopes[$scopeField]);
726
        }
727
    }
728
729
    /**
730
     * @param \Illuminate\Database\Query\Builder $query
731
     * @param array $scopes
732
     * @param string $scopeField
733
     * @param string[] $orFields
734
     */
735
    public function searchIn($query, &$scopes, $scopeField, $orFields = [])
736
    {
737
738
        if (isset($scopes[$scopeField]) && is_string($scopes[$scopeField])) {
739
            $query->where(function ($query) use (&$scopes, $scopeField, $orFields) {
740
                foreach ($orFields as $field) {
741
                    $query->orWhere($field, $this->getLikeOperator(), '%' . $scopes[$scopeField] . '%');
742
                    unset($scopes[$field]);
743
                }
744
            });
745
        }
746
    }
747
748
    /**
749
     * @return bool
750
     */
751
    public function isUniqueFeature()
752
    {
753
        return false;
754
    }
755
756
    /**
757
     * @param array $ignore
758
     * @return void
759
     */
760
    public function addIgnoreFieldsBeforeSave($ignore = [])
761
    {
762
        $this->ignoreFieldsBeforeSave = is_array($ignore)
0 ignored issues
show
introduced by
The condition is_array($ignore) is always true.
Loading history...
763
        ? array_merge($this->ignoreFieldsBeforeSave, $ignore)
764
        : array_merge($this->ignoreFieldsBeforeSave, [$ignore]);
765
    }
766
767
    /**
768
     * @param string $ignore
769
     * @return bool
770
     */
771
    public function shouldIgnoreFieldBeforeSave($ignore)
772
    {
773
        return in_array($ignore, $this->ignoreFieldsBeforeSave);
774
    }
775
776
    /**
777
     * @return string[]
778
     */
779
    public function getReservedFields()
780
    {
781
        return [
782
            'medias',
783
            'browsers',
784
            'repeaters',
785
            'blocks',
786
        ];
787
    }
788
789
    /**
790
     * @param string $relation
791
     * @param \A17\Twill\Models\Model|null $model
792
     * @return mixed
793
     */
794
    protected function getModelRepository($relation, $model = null)
795
    {
796
        if (!$model) {
797
            $model = ucfirst(Str::singular($relation));
798
        }
799
800
        return App::make(Config::get('twill.namespace') . "\\Repositories\\" . ucfirst($model) . "Repository");
801
    }
802
803
    /**
804
     * @param string|null $method
805
     * @return array
806
     */
807
    protected function traitsMethods(string $method = null)
808
    {
809
        $method = $method ?? debug_backtrace()[1]['function'];
810
811
        $traits = array_values(class_uses_recursive(get_called_class()));
812
813
        $uniqueTraits = array_unique(array_map('class_basename', $traits));
814
815
        $methods = array_map(function (string $trait) use ($method) {
816
            return $method . $trait;
817
        }, $uniqueTraits);
818
819
        return array_filter($methods, function (string $method) {
820
            return method_exists(get_called_class(), $method);
821
        });
822
    }
823
824
    /**
825
     * @return string
826
     */
827
    private function getLikeOperator()
828
    {
829
        if (DB::connection()->getPDO()->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') {
830
            return 'ILIKE';
831
        }
832
833
        return 'LIKE';
834
    }
835
836
    /**
837
     * @param string $method
838
     * @param array $parameters
839
     * @return mixed
840
     */
841
    public function __call($method, $parameters)
842
    {
843
        return $this->model->$method(...$parameters);
844
    }
845
}
846