Passed
Push — main ( 843490...c1da4d )
by Mohammad
07:53
created

Criteriable   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 104
rs 10
c 0
b 0
f 0
wmc 20

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setSearchables() 0 4 1
B scopeFilterByCriteria() 0 22 7
A scopeSearchByCriteria() 0 26 5
A setFilterables() 0 4 1
A scopeOrderByCriteria() 0 7 2
A getFilterables() 0 7 2
A getSearchables() 0 7 2
1
<?php
2
3
namespace Shamaseen\Repository\Utility\Models;
4
5
use Illuminate\Database\Eloquent\Builder;
6
7
trait Criteriable
8
{
9
    protected ?array $searchables = null;
10
    protected ?array $filterable = null;
11
12
    public function scopeFilterByCriteria($query, array $criteria): Builder
13
    {
14
        foreach ($this->getFilterables() as $method => $columns) {
15
            // if this is associative then it is a relation
16
            if (gettype($method) === "string") {
17
                if (method_exists($this, $method) && array_key_exists($method, $criteria)) {
18
                    $query->whereHas($method, function ($query) use ($criteria, $columns, $method) {
19
                        /* @var $query Builder */
20
                        $query->where(function ($query2) use ($criteria, $columns, $method) {
21
                            /* @var $query2 Builder */
22
                            foreach ((array)$columns as $column) {
23
                                $query2->where($column, $criteria[$method]);
24
                            }
25
                        });
26
                    });
27
                }
28
            } elseif (array_key_exists($columns, $criteria)) {
29
                $query->where($columns, $criteria);
30
            }
31
        }
32
33
        return $query;
34
    }
35
36
    public function scopeSearchByCriteria($query, array $criteria): Builder
37
    {
38
        if (isset($criteria['search'])) {
39
            $query->where(function ($q) use ($criteria) {
40
                /**
41
                 * @var Builder $q
42
                 */
43
                foreach ($this->getSearchables() as $method => $columns) {
44
                    if (method_exists($this, $method)) {
45
                        $q->orWhereHas($method, function ($query) use ($criteria, $columns) {
46
                            /* @var $query Builder */
47
                            $query->where(function ($query2) use ($criteria, $columns) {
48
                                /* @var $query2 Builder */
49
                                foreach ((array)$columns as $column) {
50
                                    $query2->orWhere($column, 'like', '%' . $criteria['search'] . '%');
51
                                }
52
                            });
53
                        });
54
                    } else {
55
                        $q->orWhere($columns, 'like', '%' . $criteria['search'] . '%');
56
                    }
57
                }
58
            });
59
        }
60
61
        return $query;
62
    }
63
64
    public function scopeOrderByCriteria($query, array $criteria): Builder
65
    {
66
        if (isset($criteria['order'])) {
67
            $query->orderBy($criteria['order'], $criteria['direction'] ?? 'desc');
68
        }
69
70
        return $query;
71
    }
72
73
    /**
74
     * By default, all fillables and not hidden are searchables, if you want to override that explicitly set an array of searchables.
75
     * For a relation this is the syntax [ relationName => [columns in the relation] ]
76
     * @return array
77
     */
78
    public function getSearchables(): array
79
    {
80
        if ($this->searchables !== null) {
81
            return $this->searchables;
82
        }
83
84
        return array_diff($this->getFillable(), $this->getHidden());
0 ignored issues
show
Bug introduced by
It seems like getHidden() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

84
        return array_diff($this->getFillable(), $this->/** @scrutinizer ignore-call */ getHidden());
Loading history...
Bug introduced by
The method getFillable() does not exist on Shamaseen\Repository\Utility\Models\Criteriable. Did you maybe mean getFilterables()? ( Ignorable by Annotation )

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

84
        return array_diff($this->/** @scrutinizer ignore-call */ getFillable(), $this->getHidden());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
85
    }
86
87
    public function setSearchables($searchables): self
88
    {
89
        $this->searchables = $searchables;
90
        return $this;
91
    }
92
93
    /**
94
     * By default, all fillables and not hidden are filterables, if you want to override that explicitly set an array of searchables.
95
     * For a relation this is the syntax [ relationName => [columns in the relation] ]
96
     * @return array
97
     */
98
    public function getFilterables(): array
99
    {
100
        if ($this->searchables !== null) {
101
            return $this->searchables;
102
        }
103
104
        return array_diff($this->getFillable(), $this->getHidden());
105
    }
106
107
    public function setFilterables($searchables): self
108
    {
109
        $this->searchables = $searchables;
110
        return $this;
111
    }
112
}
113