Completed
Push — master ( 36e9e8...73c72f )
by Hong
02:28
created

WhereTrait::fixOperatorValue()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 3
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Query
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Query\Traits\Clause;
16
17
use Phossa2\Query\Misc\Template;
18
use Phossa2\Query\Interfaces\Clause\WhereInterface;
19
use Phossa2\Query\Interfaces\Statement\SelectStatementInterface;
20
21
/**
22
 * WhereTrait
23
 *
24
 * Implementation of WhereInterface
25
 *
26
 * @package Phossa2\Query
27
 * @author  Hong Zhang <[email protected]>
28
 * @see     WhereInterface
29
 * @version 2.0.0
30
 * @since   2.0.0 added
31
 */
32
trait WhereTrait
33
{
34
    /**
35
     * {@inheritDoc}
36
     */
37
    public function where(
38
        $col,
39
        $operator = WhereInterface::NO_OPERATOR,
40
        $value = WhereInterface::NO_VALUE
41
    ) {
42
        return $this->realWhere($col, $operator, $value);
43
    }
44
45
    /**
46
     * {@inheritDoc}
47
     */
48
    public function whereTpl(/*# string */ $template, $col)
49
    {
50
        return $this->realWhere(new Template($template, $col),
51
            WhereInterface::NO_OPERATOR, WhereInterface::NO_VALUE, 'AND', '');
52
    }
53
54
    /**
55
     * {@inheritDoc}
56
     */
57
    public function orWhereTpl(/*# string */ $template, $col)
58
    {
59
        return $this->realWhere(new Template($template, $col),
60
            WhereInterface::NO_OPERATOR, WhereInterface::NO_VALUE, 'OR', '');
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function whereRaw(/*# string */ $rawString)
67
    {
68
        return $this->realWhere($rawString, WhereInterface::NO_OPERATOR,
69
            WhereInterface::NO_VALUE, 'AND', '', true);
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function orWhereRaw(/*# string */ $rawString)
76
    {
77
        return $this->realWhere($rawString, WhereInterface::NO_OPERATOR,
78
            WhereInterface::NO_VALUE, 'OR', '', true);
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    public function andWhere(
85
        $col,
86
        $operator = WhereInterface::NO_OPERATOR,
87
        $value = WhereInterface::NO_VALUE
88
    ) {
89
        return $this->realWhere($col, $operator, $value);
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function orWhere(
96
        $col,
97
        $operator = WhereInterface::NO_OPERATOR,
98
        $value = WhereInterface::NO_VALUE
99
    ) {
100
        return $this->realWhere($col, $operator, $value, 'OR');
101
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106
    public function whereNot(
107
        $col,
108
        $operator = WhereInterface::NO_OPERATOR,
109
        $value = WhereInterface::NO_VALUE
110
    ) {
111
        return $this->realWhere($col, $operator, $value, 'AND', 'NOT');
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117
    public function orWhereNot(
118
        $col,
119
        $operator = WhereInterface::NO_OPERATOR,
120
        $value = WhereInterface::NO_VALUE
121
    ) {
122
        return $this->realWhere($col, $operator, $value, 'OR', 'NOT');
123
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128
    public function whereIn(/*# string */ $col, $value)
129
    {
130
        return $this->realWhere($col, 'IN', $value);
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136
    public function orWhereIn(/*# string */ $col, $value)
137
    {
138
        return $this->realWhere($col, 'IN', $value, 'OR');
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function whereNotIn(/*# string */ $col, $value)
145
    {
146
        return $this->realWhere($col, 'NOT IN', $value);
147
    }
148
149
    /**
150
     * {@inheritDoc}
151
     */
152
    public function orWhereNotIn(/*# string */ $col, $value)
153
    {
154
        return $this->realWhere($col, 'NOT IN', $value, 'OR');
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160
    public function whereBetween(/*# string */ $col, $value1, $value2)
161
    {
162
        $val = sprintf('%s AND %s', $value1, $value2);
163
        return $this->realWhere($col, 'BETWEEN', $val);
164
    }
165
166
    /**
167
     * {@inheritDoc}
168
     */
169
    public function orWhereBetween(/*# string */ $col, $value1, $value2)
170
    {
171
        $val = sprintf('%s AND %s', $value1, $value2);
172
        return $this->realWhere($col, 'BETWEEN', $val, 'OR');
173
    }
174
175
    /**
176
     * {@inheritDoc}
177
     */
178
    public function whereNotBetween(/*# string */ $col, $value1, $value2)
179
    {
180
        $val = sprintf('%s AND %s', $value1, $value2);
181
        return $this->realWhere($col, 'NOT BETWEEN', $val);
182
    }
183
184
    /**
185
     * {@inheritDoc}
186
     */
187
    public function orWhereNotBetween(/*# string */ $col, $value1, $value2)
188
    {
189
        $val = sprintf('%s AND %s', $value1, $value2);
190
        return $this->realWhere($col, 'NOT BETWEEN', $val, 'OR');
191
    }
192
193
    /**
194
     * {@inheritDoc}
195
     */
196
    public function whereNull(/*# string */ $col)
197
    {
198
        return $this->realWhere($col, 'IS', 'NULL');
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204
    public function orWhereNull(/*# string */ $col)
205
    {
206
        return $this->realWhere($col, 'IS', 'NULL', 'OR');
207
    }
208
209
    /**
210
     * {@inheritDoc}
211
     */
212
    public function whereNotNull(/*# string */ $col)
213
    {
214
        return $this->realWhere($col, 'IS', 'NOT NULL');
215
    }
216
217
    /**
218
     * {@inheritDoc}
219
     */
220
    public function orWhereNotNull(/*# string */ $col)
221
    {
222
        return $this->realWhere($col, 'IS', 'NOT NULL', 'OR');
223
    }
224
225
    /**
226
     * WHERE EXISTS
227
     *
228
     * ```php
229
     * // WHERE EXISTS (SELECT `user_id` FROM `users`)
230
     * ->whereExists($users->select('user_id'))
231
     * ```
232
     *
233
     * @param  SelectStatementInterface $sel
234
     * @return $this
235
     * @see    WhereInterface::where()
236
     * @access public
237
     * @api
238
     */
239
    public function whereExists(SelectStatementInterface $sel)
240
    {
241
        return $this->realWhere('', 'EXISTS', $sel);
242
    }
243
244
    /**
245
     * {@inheritDoc}
246
     */
247
    public function orWhereExists(SelectStatementInterface $sel)
248
    {
249
        return $this->realWhere('', 'EXISTS', $sel, 'OR');
250
    }
251
252
    /**
253
     * {@inheritDoc}
254
     */
255
    public function whereNotExists(SelectStatementInterface $sel)
256
    {
257
        return $this->realWhere('', 'NOT EXISTS', $sel);
258
    }
259
260
    /**
261
     * {@inheritDoc}
262
     */
263
    public function orWhereNotExists(SelectStatementInterface $sel)
264
    {
265
        return $this->realWhere('', 'NOT EXISTS', $sel, 'OR');
266
    }
267
268
    /**
269
     * Real where
270
     *
271
     * @param  string|string[]|Template $col col or cols
272
     * @param  mixed $operator
273
     * @param  mixed $value
274
     * @param  string $logicAnd 'AND'
275
     * @param  string $whereNot 'WHERE NOT'
276
     * @param  bool $rawMode
277
     * @param  string $clause 'where' or 'having'
278
     * @return $this
279
     * @access protected
280
     */
281
    protected function realWhere(
282
        $col,
283
        $operator = WhereInterface::NO_OPERATOR,
284
        $value    = WhereInterface::NO_VALUE,
285
        /*# string */ $logicAnd = 'AND',
286
        /*# string */ $whereNot = '',
287
        /*# bool */ $rawMode = false,
288
        /*# string */ $clause = 'WHERE'
289
    ) {
290
        $clause = &$this->getClause($clause);
291
        if (is_array($col)) {
292
            $this->multipleWhere($col, $logicAnd, $whereNot, $rawMode);
293
            return $this;
294
        }
295
296
        if (WhereInterface::NO_VALUE === $value) {
297
            $value = $operator;
298
            $operator = '=';
299
        }
300
301
        $clause[] = [$rawMode, $whereNot, $logicAnd, $col, $operator, $value];
302
        return $this;
303
    }
304
305
    /**
306
     * @param  array $cols
307
     * @param  string $logicAnd
308
     * @param  string $whereNot
309
     * @param  bool $rawMode
310
     * @access protected
311
     */
312
    protected function multipleWhere(
313
        array $cols,
314
        /*# string */ $logicAnd = 'AND',
315
        /*# string */ $whereNot = '',
316
        /*# bool */ $rawMode  = false
317
    ) {
318
        foreach ($cols as $fld => $val) {
319
            if (is_array($val)) {
320
                $opr = $val[0];
321
                $val = $val[1];
322
            } else {
323
                $opr = '=';
324
            }
325
            $this->realWhere($fld, $opr, $val, $logicAnd, $whereNot, $rawMode);
326
        }
327
    }
328
329
    /**
330
     * Build WHERE
331
     *
332
     * @param  string $clause 'where|having'
333
     * @return array
334
     * @access protected
335
     */
336
    protected function buildWhere(
337
        array $settings,
338
        /*# string */ $clause = 'WHERE'
339
    )/*# : string */ {
340
        $result = [];
341
        $wheres = &$this->getClause($clause);
342
        foreach ($wheres as $idx => $where) {
343
            $cls = [];
344
            // AND OR
345
            if ($idx) {
346
                $cls[] = $where[2];
347
            }
348
            // NOT
349
            if ($where[1]) {
350
                $cls[] = $where[1];
351
            }
352
            $result[] = $this->buildWhereClause($cls, $where, $settings);
353
        }
354
        return $this->joinClause($clause, '', $result, $settings);
355
    }
356
357
    /**
358
     * Build 'col = val' part
359
     *
360
     * @param  array $cls
361
     * @param  array $where
362
     * @param  array $settings
363
     * @return string
364
     * @access protected
365
     */
366
    protected function buildWhereClause(array $cls, array $where, array $settings)
367
    {
368
        // col
369
        if (!empty($where[3])) {
370
            $cls[] = $this->quoteItem(
371
                $where[3], $settings, $this->isRaw($where[3], $where[0])
372
            );
373
        }
374
375
        // operator
376
        if (WhereInterface::NO_OPERATOR !== $where[4]) {
377
            $cls[] = $where[4];
378
        }
379
380
        // value
381
        if (WhereInterface::NO_VALUE !== $where[5]) {
382
            $cls[] = $this->processValue($where[5], $settings);
383
        }
384
385
        return join(' ', $cls);
386
    }
387
388
    abstract protected function isRaw($str, /*# bool */ $rawMode)/*# : bool */;
389
    abstract protected function processValue($value, array $settings)/*# : string */;
390
    abstract protected function &getClause(/*# string */ $clauseName)/*# : array */;
391
    abstract protected function quoteItem($item, array $settings, /*# bool */ $rawMode = false)/*# : string */;
392
    abstract protected function joinClause(
393
        /*# : string */ $prefix,
394
        /*# : string */ $seperator,
395
        array $clause,
396
        array $settings
397
    )/*# : string */;
398
}
399