WhereTrait::andWhere()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
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 = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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