Passed
Branch main (5746ae)
by Sammy
02:23
created

ClauseWhere::whereFilterContent()   B

Complexity

Conditions 9
Paths 23

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 22
nc 23
nop 3
dl 0
loc 37
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
namespace HexMakina\Crudites\Queries;
4
5
use HexMakina\BlackBox\Database\TableManipulationInterface;
6
7
trait ClauseWhere
8
{
9
    public static $OP_AND = 'AND';
10
    public static $OP_OR = 'OR';
11
12
    public static $OP_GT = '>';
13
    public static $OP_LT = '<';
14
    public static $OP_EQ = '=';
15
    public static $OP_GTE = '>=';
16
    public static $OP_LTE = '<=';
17
    public static $OP_NEQ = '<>';
18
    public static $OP_LIKE = 'LIKE';
19
    public static $OP_NLIKE = 'NOT LIKE';
20
21
22
    public static $WHERE_LIKE_PRE = '%TERM';
23
    public static $WHERE_LIKE_POST = 'TERM%';
24
    public static $WHERE_LIKE_BOTH = '%TERM%';
25
26
    protected $where = null;
27
28
    abstract public function table(TableManipulationInterface $setter = null): TableManipulationInterface;
29
    abstract public function tableLabel($table_name = null);
30
    abstract public function backTick($field, $table_name = null);
31
    abstract public function addBinding($field, $value, $table_name = null, $bind_label = null): string;
32
33
    public function where($where_condition)
34
    {
35
        $this->where = $this->where ?? [];
36
37
        $this->where[] = "($where_condition)";
38
39
        return $this;
40
    }
41
42
    public function whereEqualOrNull($field, $value, $table_name = null, $bindname = null)
43
    {
44
        $bind_name = $this->addBinding($field, $value, $table_name, $bindname);
45
        $field_name = $this->backTick($field, $table_name);
46
47
        return $this->where("($field_name = $bind_name OR $field_name IS NULL)");
48
    }
49
50
    public function whereEQ($field, $value, $table_name = null, $bindname = null)
51
    {
52
               return $this->whereBindField($table_name, $field, self::$OP_EQ, $value, $bindname);
53
    }
54
55
    public function whereGT($field, $value, $table_name = null, $bindname = null)
56
    {
57
               return $this->whereBindField($table_name, $field, self::$OP_GT, $value, $bindname);
58
    }
59
60
    public function whereLT($field, $value, $table_name = null, $bindname = null)
61
    {
62
               return $this->whereBindField($table_name, $field, self::$OP_LT, $value, $bindname);
63
    }
64
65
    public function whereGTE($field, $value, $table_name = null, $bindname = null)
66
    {
67
               return $this->whereBindField($table_name, $field, self::$OP_GTE, $value, $bindname);
68
    }
69
70
    public function whereLTE($field, $value, $table_name = null, $bindname = null)
71
    {
72
              return $this->whereBindField($table_name, $field, self::$OP_LTE, $value, $bindname);
73
    }
74
75
    public function whereNotEQ($field, $value, $table_name = null, $bindname = null)
76
    {
77
          return $this->whereBindField($table_name, $field, self::$OP_NEQ, $value, $bindname);
78
    }
79
80
    public function wherePrimary($pk_values)
81
    {
82
        $pks = $this->table()->primaryKeysMatch($pk_values);
83
84
        if (empty($pks)) {
85
            $this->where('1=0');
86
        } else {
87
            $this->whereFieldsEQ($pks);
88
        }
89
90
        return $this;
91
    }
92
93
    public function whereLike($field, $prep_value, $table_name = null, $bindname = null)
94
    {
95
        return $this->whereBindField($table_name, $field, self::$OP_LIKE, $prep_value, $bindname);
96
    }
97
    public function whereNotLike($field, $prep_value, $table_name = null, $bindname = null)
98
    {
99
        return $this->whereBindField($table_name, $field, self::$OP_NLIKE, $prep_value, $bindname);
100
    }
101
102
103
    public function whereFieldsEQ($assoc_data, $table_name = null)
104
    {
105
        $table_name = $this->tableLabel($table_name);
106
        foreach ($assoc_data as $field => $value) {
107
            $this->whereBindField($table_name, $field, self::$OP_EQ, $value);
108
        }
109
110
        return $this;
111
    }
112
113
    private function whereBindField($table_name, $field, $operator, $value, $bind_name = null)
114
    {
115
        $bind_name = $this->addBinding($field, $value, $table_name, $bind_name);
116
        return $this->whereField($field, "$operator $bind_name", $table_name);
117
    }
118
119
    public function whereNumericIn($field, $values, $table_name = null)
120
    {
121
        if (is_array($values) && !empty($values)) {
122
            return $this->whereField($field, sprintf(' IN (%s)', implode(',', $values)), $table_name);
123
        }
124
125
        return $this;
126
    }
127
128
    public function whereStringIn($field, $values, $table_name = null)
129
    {
130
        if (is_array($values) && !empty($values)) {
131
            $count_values = count($values);
132
            $in = '';
133
            foreach ($values as $i => $v) {
134
                // TODO dirty patching. mathematical certainty needed
135
                $placeholder_name = ':' . $table_name . '_' . $field . '_awS_in_' . $count_values . '_' . $i;
136
                $this->addBinding($field, $v, null, $placeholder_name);
137
                $in .= "$placeholder_name,";
138
            }
139
            // $this->whereField($field, sprintf(" IN ('%s')", implode("','", $values)), $table_name);
140
            $this->whereField($field, sprintf(" IN (%s)", rtrim($in, ',')), $table_name);
141
        }
142
        return $this;
143
    }
144
145
    public function whereIsNull($field, $table_name = null)
146
    {
147
        return $this->whereField($field, 'IS NULL', $table_name);
148
    }
149
150
    public function whereField($field, $condition, $table_name = null)
151
    {
152
        $table_field = $this->backTick($field, $table_name);
153
        return $this->where("$table_field $condition");
154
    }
155
156
    public function whereNotEmpty($field, $table_name = null)
157
    {
158
        $table_field = $this->backTick($field, $table_name);
159
        return $this->where("($table_field IS NOT NULL AND $table_field <> '') ");
160
    }
161
162
    public function whereEmpty($field, $table_name = null)
163
    {
164
        $table_field = $this->backTick($field, $table_name);
165
        return $this->where("($table_field IS NULL OR $table_field = '')");
166
    }
167
168
    /**
169
     * @param array $filters_content  with 2 indexes: 'term', the search string, 'fields', the search fields
170
     * @param $search_table     String to filter
171
     * @param $filters_operator Object, inclusive or exclusive search
172
     */
173
174
     // sub array filters[$content]
175
    public function whereFilterContent($filters_content, $search_table = null, $filters_operator = null)
176
    {
177
        if (!isset($filters_content['term']) || !isset($filters_content['fields'])) {
178
            return $this;
179
        }
180
181
        if (is_null($search_table)) {
182
            $search_table = $this->tableLabel();
183
        }
184
185
        $search_term = trim($filters_content['term']);
186
        if ($search_term === '') {
187
            return $this;
188
        }
189
190
        $content_wc = [];
191
        foreach ($filters_content['fields'] as $search_field => $search_mode) {
192
            if (isNumeric($search_field)) {
0 ignored issues
show
Bug introduced by
The function isNumeric was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

192
            if (/** @scrutinizer ignore-call */ isNumeric($search_field)) {
Loading history...
193
                $search_field = $search_mode;
194
                $search_mode = self::$WHERE_LIKE_BOTH;
195
            }
196
            $search_field = $this->backTick($search_field, $search_table);
197
198
            if ($search_mode === self::$OP_EQ) {
199
                $content_wc [] = "$search_field = '$search_term' "; // TODO bindthis
200
            } else // %%
201
            {
202
                $pattern = str_replace('TERM', $search_term, $search_mode);
203
                $content_wc [] = " $search_field LIKE '$pattern' "; // TODO bindthis
204
            }
205
        }
206
207
        if (!empty($content_wc)) {
208
            $operator = self::validWhereOperator($filters_operator, self::$OP_OR);
209
            $content_wc = implode(" $operator ", $content_wc);
210
211
            $this->where(" ($content_wc) ");
212
        }
213
    }
214
    // //------------------------------------------------------------  FIELDS
215
    protected static function validWhereOperator($operator, $default)
216
    {
217
        $operator = strtoupper("$operator");
218
        $choices = [self::$OP_AND, self::$OP_OR];
219
220
        if (in_array($operator, $choices) === true) {
221
            return $operator;
222
        }
223
224
        if (in_array($default, $choices) === true) {
225
            return $default;
226
        }
227
228
        throw new \Exception('ERR_INVALID_QUERY_OPERATOR');
229
    }
230
231
    protected function generateWhere()
232
    {
233
        if (!empty($this->where)) {
234
            return PHP_EOL . ' WHERE ' . implode(PHP_EOL . ' AND ', $this->where);
235
        }
236
    }
237
}
238