Completed
Push — master ( f56a01...af237a )
by Hong
02:39
created

WhereTrait::realWhere()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 18
nc 3
nop 7
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
    /**
34
     * {@inheritDoc}
35
     */
36
    public function where(
37
        $col,
38
        $operator = WhereInterface::NO_OPERATOR,
39
        $value = WhereInterface::NO_VALUE
40
    ) {
41
        return $this->realWhere($col, $operator, $value);
42
    }
43
44
    /**
45
     * {@inheritDoc}
46
     */
47
    public function whereTpl(/*# string */ $template, $col)
48
    {
49
        return $this->realWhere(new Template($template, $col),
50
            WhereInterface::NO_OPERATOR, WhereInterface::NO_VALUE,
51
            'AND', '', true);
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,
61
            'OR', '', true);
62
    }
63
64
    /**
65
     * {@inheritDoc}
66
     */
67 View Code Duplication
    public function whereRaw(/*# string */ $rawString)
1 ignored issue
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...
68
    {
69
        if (func_num_args() > 1) {
70
            $rawString = $this->getBuilder()->raw($rawString, func_get_arg(1));
71
        }
72
        return $this->realWhere($rawString, WhereInterface::NO_OPERATOR,
73
            WhereInterface::NO_VALUE, 'AND', '', true);
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79 View Code Duplication
    public function orWhereRaw(/*# string */ $rawString)
1 ignored issue
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
        if (func_num_args() > 1) {
82
            $rawString = $this->getBuilder()->raw($rawString, func_get_arg(1));
83
        }
84
        return $this->realWhere($rawString, WhereInterface::NO_OPERATOR,
85
            WhereInterface::NO_VALUE, 'OR', '', true);
86
    }
87
88
    /**
89
     * {@inheritDoc}
90
     */
91
    public function andWhere(
92
        $col,
93
        $operator = WhereInterface::NO_OPERATOR,
94
        $value = WhereInterface::NO_VALUE
95
    ) {
96
        return $this->realWhere($col, $operator, $value);
97
    }
98
99
    /**
100
     * {@inheritDoc}
101
     */
102
    public function orWhere(
103
        $col,
104
        $operator = WhereInterface::NO_OPERATOR,
105
        $value = WhereInterface::NO_VALUE
106
    ) {
107
        return $this->realWhere($col, $operator, $value, 'OR');
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     */
113
    public function whereNot(
114
        $col,
115
        $operator = WhereInterface::NO_OPERATOR,
116
        $value = WhereInterface::NO_VALUE
117
    ) {
118
        return $this->realWhere($col, $operator, $value, 'AND', 'NOT');
119
    }
120
121
    /**
122
     * {@inheritDoc}
123
     */
124
    public function orWhereNot(
125
        $col,
126
        $operator = WhereInterface::NO_OPERATOR,
127
        $value = WhereInterface::NO_VALUE
128
    ) {
129
        return $this->realWhere($col, $operator, $value, 'OR', 'NOT');
130
    }
131
132
    /**
133
     * Real where
134
     *
135
     * @param  string|string[]|Template $col col or cols
136
     * @param  mixed $operator
137
     * @param  mixed $value
138
     * @param  string $logicAnd 'AND'
139
     * @param  string $whereNot 'WHERE NOT'
140
     * @param  bool $rawMode
141
     * @param  string $clause 'where' or 'having'
142
     * @return $this
143
     * @access protected
144
     */
145
    protected function realWhere(
146
        $col,
147
        $operator = WhereInterface::NO_OPERATOR,
148
        $value    = WhereInterface::NO_VALUE,
149
        /*# string */ $logicAnd = 'AND',
150
        /*# string */ $whereNot = '',
151
        /*# bool */ $rawMode = false,
152
        /*# string */ $clause = 'WHERE'
153
    ) {
154
        $clause = &$this->getClause($clause);
155
        if (is_array($col)) {
156
            $this->multipleWhere($col, $logicAnd, $whereNot, $rawMode);
157
            return $this;
158
        }
159
160
        $rawMode = $this->isRaw($col, $rawMode);
161
162
        // fix operator & value
163
        if (!$rawMode && WhereInterface::NO_VALUE === $value) {
164
            $value = $operator;
165
            $operator = '=';
166
        }
167
168
        $clause[] = [$rawMode, $whereNot, $logicAnd, $col, $operator, $value];
169
        return $this;
170
    }
171
172
    /**
173
     * @param  array $cols
174
     * @param  string $logicAnd
175
     * @param  string $whereNot
176
     * @param  bool $rawMode
177
     * @access protected
178
     */
179
    protected function multipleWhere(
180
        array $cols,
181
        /*# string */ $logicAnd = 'AND',
182
        /*# string */ $whereNot = '',
183
        /*# bool */ $rawMode  = false
184
    ) {
185
        foreach ($cols as $fld => $val) {
186
            if (is_array($val)) {
187
                $opr = $val[0];
188
                $val = $val[1];
189
            } else {
190
                $opr = '=';
191
            }
192
            $this->realWhere($fld, $opr, $val, $logicAnd, $whereNot, $rawMode);
193
        }
194
    }
195
196
    /**
197
     * Build WHERE
198
     *
199
     * @param  prefix
200
     * @param  array $settings
201
     * @return array
202
     * @access protected
203
     */
204
    protected function buildWhere(
205
        /*# string */ $prefix,
206
        array $settings
207
    )/*# : string */ {
208
        $result = [];
209
        $wheres = &$this->getClause('HAVING' == $prefix ? $prefix : 'WHERE');
210
        foreach ($wheres as $idx => $where) {
211
            $cls = [];
212
            // AND OR
213
            if ($idx) {
214
                $cls[] = $where[2];
215
            }
216
            // NOT
217
            if ($where[1]) {
218
                $cls[] = $where[1];
219
            }
220
            $result[] = $this->buildCondition($cls, $where, $settings);
221
        }
222
        return $this->joinClause($prefix, '', $result, $settings);
223
    }
224
225
    /**
226
     * Build 'col = val' part
227
     *
228
     * @param  array $cls
229
     * @param  array $where
230
     * @param  array $settings
231
     * @return string
232
     * @access protected
233
     */
234
    protected function buildCondition(array $cls, array $where, array $settings)
235
    {
236
        // col
237
        if (!empty($where[3])) {
238
            $cls[] = $this->quoteItem(
239
                $where[3], $settings, $this->isRaw($where[3], $where[0])
240
            );
241
        }
242
243
        // operator
244
        if (WhereInterface::NO_OPERATOR !== $where[4]) {
245
            $cls[] = $where[4];
246
        }
247
248
        // value
249
        if (WhereInterface::NO_VALUE !== $where[5]) {
250
            $cls[] = $this->processValue(
251
                $where[5], $settings, (bool) preg_match('/\bbetween\b/i', $where[4]));
252
        }
253
254
        return join(' ', $cls);
255
    }
256
257
    abstract protected function isRaw($str, /*# bool */ $rawMode)/*# : bool */;
258
    abstract protected function processValue($value, array $settings, /*# bool */ $between = false)/*# : string */;
259
    abstract protected function &getClause(/*# string */ $clauseName)/*# : array */;
260
    abstract protected function quoteItem($item, array $settings, /*# bool */ $rawMode = false)/*# : string */;
261
    abstract protected function joinClause(
262
        /*# : string */ $prefix,
263
        /*# : string */ $seperator,
264
        array $clause,
265
        array $settings
266
    )/*# : string */;
267
    /**
268
     * Return the builder
269
     *
270
     * @return BuilderInterface
271
     * @access public
272
     */
273
    abstract public function getBuilder()/*# : BuilderInterface */;
274
}
275