Passed
Pull Request — master (#87)
by Zing
05:54 queued 01:21
created

WithSearchable::applyRelationSearchable()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 1
nop 4
dl 0
loc 9
ccs 8
cts 8
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zing\QueryBuilder\Concerns;
6
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Support\Str;
9
10
trait WithSearchable
11
{
12
    use NestedRelation;
13
14 3
    public function searchable($searchable)
15
    {
16 3
        $searchable = is_array($searchable) ? $searchable : func_get_args();
17 3
        $search = $this->request->input('search');
18 3
        if ($search === null) {
19
            return $this;
20
        }
21 3
        if (is_string($search) && trim($search) === '') {
22 1
            return $this;
23
        }
24
25 2
        $searchable = $this->resolveNestedSearchable($searchable);
26
27 2
        return $this->applySearchable($search, $searchable);
28
    }
29
30 2
    protected function applySearchable($search, array $searchable = [])
31
    {
32 2
        return $this->where(
0 ignored issues
show
Bug introduced by
It seems like where() 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

32
        return $this->/** @scrutinizer ignore-call */ where(
Loading history...
33 2
            function (Builder $query) use ($search, $searchable): void {
34 2
                collect($searchable)->each(
35 2
                    function ($value, $key) use ($query, $search) {
36 2
                        if (is_numeric($key)) {
37 1
                            return $query->orWhere($value, 'like', "%{$search}%");
38
                        }
39
40 1
                        return $this->applyRelationSearchable($query, $key, $value, $search);
41 2
                    }
42
                );
43 2
            }
44
        );
45
    }
46
47 1
    protected function applyRelationSearchable($query, $relation, $fields, $search)
48
    {
49 1
        return $query->orWhereHas(
50 1
            $relation,
51 1
            function (Builder $query) use ($fields, $search): void {
52 1
                $query->where(
53 1
                    function (Builder $query) use ($fields, $search): void {
54 1
                        foreach ($fields as $field) {
55 1
                            $query->orWhere($field, 'like', "%{$search}%");
56
                        }
57 1
                    }
58
                );
59 1
            }
60
        );
61
    }
62
63
    /**
64
     * @param string $field
65
     * @param array $results
66
     *
67
     * @return array
68
     */
69 1
    private function addNestedRelation($field, array $results)
70
    {
71 1
        [$relation, $property] = $this->resolveNestedRelation($field);
72
73 1
        $results[$relation][] = $property;
74
75 1
        return $results;
76
    }
77
78 2
    private function resolveNestedSearchable(array $searchable)
79
    {
80 2
        $results = [];
81 2
        foreach ($searchable as $singleSearchable) {
82 2
            if (Str::contains($singleSearchable, '.')) {
83 1
                $results = $this->addNestedRelation($singleSearchable, $results);
84
            } else {
85 1
                $results[] = $singleSearchable;
86
            }
87
        }
88
89 2
        return $results;
90
    }
91
}
92