Issues (14)

src/DynamicBuilder.php (4 issues)

Labels
1
<?php
2
3
namespace Halalsoft\LaravelDynamicColumn;
4
5
use Closure;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\DB;
9
use Illuminate\Database\ConnectionInterface;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Query\Builder as QueryBuilder;
12
use Illuminate\Database\Query\Expression;
13
use Illuminate\Database\Query\Grammars\Grammar;
14
use Illuminate\Database\Query\Processors\Processor;
15
16
class DynamicBuilder extends QueryBuilder
17
{
18
19
    private $model;
20
    private $dynamicColumns;
21
22
    public function __construct(
23
        ConnectionInterface $connection,
24
        Grammar $grammar = null,
25
        Processor $processor = null,
26
        Model $model = null
27
    ) {
28
        $this->connection     = $connection;
29
        $this->grammar        = $grammar ?: $connection->getQueryGrammar();
30
        $this->processor      = $processor ?: $connection->getPostProcessor();
31
        $this->model          = $model;
32
        $this->dynamicColumns = $this->model->getDynamicColumns() ?? [];
0 ignored issues
show
The method getDynamicColumns() does not exist on null. ( Ignorable by Annotation )

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

32
        $this->dynamicColumns = $this->model->/** @scrutinizer ignore-call */ getDynamicColumns() ?? [];

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...
33
    }
34
35
36
    /**
37
     * Override a basic where clause to the query.
38
     *
39
     * @param  Closure|string|array  $column
40
     * @param  mixed  $operator
41
     * @param  mixed  $value
42
     * @param  string  $boolean
43
     *
44
     * @return $this
45
     */
46
    public function where($column, $operator = null, $value = null, $boolean = 'and')
47
    {
48
        if ($this->model !== null && !empty($this->dynamicColumns)) {
49
            if (strpos($column, '->')) {
50
                $parts = explode('->', $column, 2);
51
                if (in_array($parts[0], $this->dynamicColumns)) {
0 ignored issues
show
It seems like $this->dynamicColumns can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

51
                if (in_array($parts[0], /** @scrutinizer ignore-type */ $this->dynamicColumns)) {
Loading history...
52
                    $column = DB::raw("COLUMN_GET(`$parts[0]`, '$parts[1]' as char)");
53
                }
54
            }
55
        }
56
57
        parent::where($column, $operator, $value, $boolean);
58
    }
59
60
61
    /**
62
     * Add a "where null" clause to the query.
63
     *
64
     * @param  string|array  $columns
65
     * @param  string  $boolean
66
     * @param  bool  $not
67
     *
68
     * @return $this
69
     */
70
    public function whereNull($columns, $boolean = 'and', $not = false)
71
    {
72
        $type = $not ? 'NotNull' : 'Null';
73
74
        foreach (Arr::wrap($columns) as $column) {
75
            if ($this->model !== null && !empty($this->dynamicColumns)) {
76
                if (strpos($column, '->')) {
77
                    $parts = explode('->', $column, 2);
78
                    if (in_array($parts[0], $this->dynamicColumns)) {
0 ignored issues
show
It seems like $this->dynamicColumns can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

78
                    if (in_array($parts[0], /** @scrutinizer ignore-type */ $this->dynamicColumns)) {
Loading history...
79
                        $column = DB::raw("COLUMN_GET(`$parts[0]`, '$parts[1]' as char)");
80
                    }
81
                }
82
            }
83
            $this->wheres[] = compact('type', 'column', 'boolean');
84
        }
85
86
        return $this;
87
    }
88
89
90
    public function whereDynamicExists($column, $value = null, $boolean = 'and', $not = false)
91
    {
92
        $type = 'DynamicColumnExists';
93
94
        $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not');
95
96
        if (!$value instanceof Expression) {
97
            $this->addBinding($this->grammar->prepareBindingForJsonContains($value));
98
        }
99
100
        return $this;
101
    }
102
103
    /**
104
     * Execute the query as a "select" statement.
105
     *
106
     * @param  array|string  $columns
107
     *
108
     * @return Collection
109
     */
110
    public function get($columns = ['*'])
111
    {
112
        if ($this->model !== null && !empty($this->dynamicColumns)) {
113
            $i = 0;
114
            foreach ($this->wheres as $where) {
115
                if (strpos($where['column'], '->')) {
116
                    $parts = explode('->', $where['column'], 2);
117
                    if (in_array($parts[0], $this->dynamicColumns)) {
0 ignored issues
show
It seems like $this->dynamicColumns can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

117
                    if (in_array($parts[0], /** @scrutinizer ignore-type */ $this->dynamicColumns)) {
Loading history...
118
                        $this->wheres[$i]['column'] = DB::raw("COLUMN_GET(`$parts[0]`, '$parts[1]' as char)");
119
                    }
120
                }
121
122
                $i++;
123
            }
124
        }
125
126
        return collect(
127
            $this->onceWithColumns(
128
                Arr::wrap($columns),
129
                function() {
130
                    return $this->processor->processSelect($this, $this->runSelect());
131
                }
132
            )
133
        );
134
    }
135
136
}
137