WhereTrait::buildCondition()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 14
nc 8
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
20
/**
21
 * WhereTrait
22
 *
23
 * Implementation of WhereInterface
24
 *
25
 * @package Phossa2\Query
26
 * @author  Hong Zhang <[email protected]>
27
 * @see     WhereInterface
28
 * @version 2.0.0
29
 * @since   2.0.0 added
30
 */
31
trait WhereTrait
32
{
33
    use AbstractTrait;
34
35
    /**
36
     * {@inheritDoc}
37
     */
38
    public function where(
39
        $col,
40
        $operator = WhereInterface::NO_OPERATOR,
41
        $value = WhereInterface::NO_VALUE
42
    ) {
43
        return $this->realWhere($col, $operator, $value);
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49
    public function whereTpl(/*# string */ $template, $col, array $params = [])
50
    {
51
        $template = $this->positionedParam($template, $params);
52
        return $this->realWhere(
53
            new Template($template, $col),
54
            WhereInterface::NO_OPERATOR,
55
            WhereInterface::NO_VALUE,
56
            'AND',
57
            ''
58
        );
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    public function orWhereTpl(/*# string */ $template, $col, array $params = [])
65
    {
66
        $template = $this->positionedParam($template, $params);
67
        return $this->realWhere(
68
            new Template($template, $col),
69
            WhereInterface::NO_OPERATOR,
70
            WhereInterface::NO_VALUE,
71
            'OR',
72
            ''
73
        );
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79 View Code Duplication
    public function whereRaw(/*# string */ $rawString, array $params = [])
80
    {
81
        $rawString = $this->positionedParam($rawString, $params);
82
        return $this->realWhere(
83
            $rawString,
84
            WhereInterface::NO_OPERATOR,
85
            WhereInterface::NO_VALUE,
86
            'AND',
87
            '',
88
            true
89
        );
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95 View Code Duplication
    public function orWhereRaw(/*# string */ $rawString, array $params = [])
96
    {
97
        $rawString = $this->positionedParam($rawString, $params);
98
        return $this->realWhere(
99
            $rawString,
100
            WhereInterface::NO_OPERATOR,
101
            WhereInterface::NO_VALUE,
102
            'OR',
103
            '',
104
            true
105
        );
106
    }
107
108
    /**
109
     * {@inheritDoc}
110
     */
111
    public function andWhere(
112
        $col,
113
        $operator = WhereInterface::NO_OPERATOR,
114
        $value = WhereInterface::NO_VALUE
115
    ) {
116
        return $this->realWhere($col, $operator, $value);
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122
    public function orWhere(
123
        $col,
124
        $operator = WhereInterface::NO_OPERATOR,
125
        $value = WhereInterface::NO_VALUE
126
    ) {
127
        return $this->realWhere($col, $operator, $value, 'OR');
128
    }
129
130
    /**
131
     * {@inheritDoc}
132
     */
133
    public function whereNot(
134
        $col,
135
        $operator = WhereInterface::NO_OPERATOR,
136
        $value = WhereInterface::NO_VALUE
137
    ) {
138
        return $this->realWhere($col, $operator, $value, 'AND', 'NOT');
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function orWhereNot(
145
        $col,
146
        $operator = WhereInterface::NO_OPERATOR,
147
        $value = WhereInterface::NO_VALUE
148
    ) {
149
        return $this->realWhere($col, $operator, $value, 'OR', 'NOT');
150
    }
151
152
    /**
153
     * Real where
154
     *
155
     * @param  string|string[]|Template $col col or cols
156
     * @param  mixed $operator
157
     * @param  mixed $value
158
     * @param  string $logicAnd 'AND'
159
     * @param  string $whereNot 'WHERE NOT'
160
     * @param  bool $rawMode
161
     * @param  string $clause 'where' or 'having'
162
     * @return $this
163
     * @access protected
164
     */
165
    protected function realWhere(
166
        $col,
167
        $operator = WhereInterface::NO_OPERATOR,
168
        $value = WhereInterface::NO_VALUE,
169
        /*# string */ $logicAnd = 'AND',
170
        /*# string */ $whereNot = '',
171
        /*# bool */ $rawMode = false,
172
        /*# string */ $clause = 'WHERE'
173
    ) {
174
        $clause = &$this->getClause($clause);
175
        if (is_array($col)) {
176
            $this->multipleWhere($col, $logicAnd, $whereNot, $rawMode);
177
            return $this;
178
        }
179
        // fix raw mode
180
        $rawMode = $this->isRaw($col, $rawMode);
181
        // fix operator to '='
182
        $this->fixOperator($operator, $value, $rawMode);
183
        $clause[] = [$rawMode, $whereNot, $logicAnd, $col, $operator, $value];
184
        return $this;
185
    }
186
187
    /**
188
     * @param  array $cols
189
     * @param  string $logicAnd
190
     * @param  string $whereNot
191
     * @param  bool $rawMode
192
     * @access protected
193
     */
194
    protected function multipleWhere(
195
        array $cols,
196
        /*# string */ $logicAnd = 'AND',
197
        /*# string */ $whereNot = '',
198
        /*# bool */ $rawMode = false
199
    ) {
200
        foreach ($cols as $fld => $val) {
201
            if (is_array($val)) {
202
                $opr = $val[0];
203
                $val = $val[1];
204
            } else {
205
                $opr = '=';
206
            }
207
            $this->realWhere($fld, $opr, $val, $logicAnd, $whereNot, $rawMode);
208
        }
209
    }
210
211
    /**
212
     * Fix where('id', 18) to where('id', '=', 18)
213
     *
214
     * @param  mixed &$operator
215
     * @param  mixed &$value
216
     * @param  bool $rawMode
217
     * @access protected
218
     */
219
    protected function fixOperator(&$operator, &$value, $rawMode)
220
    {
221
        if (!$rawMode && WhereInterface::NO_VALUE === $value) {
222
            $value = $operator;
223
            $operator = '=';
224
        }
225
    }
226
227
    /**
228
     * Build WHERE
229
     *
230
     * @param  prefix
231
     * @param  array $settings
232
     * @return array
233
     * @access protected
234
     */
235
    protected function buildWhere(
236
        /*# string */ $prefix,
237
        array $settings
238
    )/*# : string */ {
239
        $result = [];
240
        if ('HAVING' === $prefix) {
241
            $wheres = &$this->getClause($prefix);
242
        } else {
243
            $wheres = &$this->getClause('WHERE');
244
        }
245
        foreach ($wheres as $idx => $where) {
246
            $cls = [];
247
            // build AND part
248
            $this->buildAndOr($cls, $where, $idx);
249
            // build COL = VAL
250
            $result[] = $this->buildCondition($cls, $where, $settings);
251
        }
252
        return $this->joinClause($prefix, '', $result, $settings);
253
    }
254
255
    /**
256
     * build 'AND NOT' part of the clause part
257
     *
258
     * @param  array &$cls
259
     * @param  array $where
260
     * @param  int $idx
261
     * @access protected
262
     */
263
    protected function buildAndOr(array &$cls, array $where, $idx)
264
    {
265
        // AND OR
266
        if ($idx) {
267
            $cls[] = $where[2];
268
        }
269
        // NOT
270
        if ($where[1]) {
271
            $cls[] = $where[1];
272
        }
273
    }
274
275
    /**
276
     * Build 'col = val' part
277
     *
278
     * @param  array $cls
279
     * @param  array $where
280
     * @param  array $settings
281
     * @return string
282
     * @access protected
283
     */
284
    protected function buildCondition(array $cls, array $where, array $settings)
285
    {
286
        if (!empty($where[3])) {
287
            $cls[] = $this->quoteItem(
288
                $where[3],
289
                $settings,
290
                $this->isRaw($where[3], $where[0])
291
            );
292
        }
293
        if (WhereInterface::NO_OPERATOR !== $where[4]) {
294
            $cls[] = $where[4];
295
        }
296
        if (WhereInterface::NO_VALUE !== $where[5]) {
297
            $cls[] = $this->processValue(
298
                $where[5],
299
                $settings,
300
                (bool) preg_match('/\bbetween\b/i', $where[4])
301
            );
302
        }
303
        return join(' ', $cls);
304
    }
305
}
306