Completed
Push — master ( af237a...780e00 )
by Hong
02:32
created

WhereTrait::buildCondition()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
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
    /**
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', '');
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', '');
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
        // fix operator & value
161
        $rawMode = $this->isRaw($col, $rawMode);
162
        if (!$rawMode && WhereInterface::NO_VALUE === $value) {
163
            $value = $operator;
164
            $operator = '=';
165
        }
166
167
        $clause[] = [$rawMode, $whereNot, $logicAnd, $col, $operator, $value];
168
        return $this;
169
    }
170
171
    /**
172
     * @param  array $cols
173
     * @param  string $logicAnd
174
     * @param  string $whereNot
175
     * @param  bool $rawMode
176
     * @access protected
177
     */
178
    protected function multipleWhere(
179
        array $cols,
180
        /*# string */ $logicAnd = 'AND',
181
        /*# string */ $whereNot = '',
182
        /*# bool */ $rawMode  = false
183
    ) {
184
        foreach ($cols as $fld => $val) {
185
            if (is_array($val)) {
186
                $opr = $val[0];
187
                $val = $val[1];
188
            } else {
189
                $opr = '=';
190
            }
191
            $this->realWhere($fld, $opr, $val, $logicAnd, $whereNot, $rawMode);
192
        }
193
    }
194
195
    /**
196
     * Build WHERE
197
     *
198
     * @param  prefix
199
     * @param  array $settings
200
     * @return array
201
     * @access protected
202
     */
203
    protected function buildWhere(
204
        /*# string */ $prefix,
205
        array $settings
206
    )/*# : string */ {
207
        $result = [];
208
        $wheres = &$this->getClause('HAVING' == $prefix ? $prefix : 'WHERE');
209
        foreach ($wheres as $idx => $where) {
210
            $cls = [];
211
            // AND OR
212
            if ($idx) {
213
                $cls[] = $where[2];
214
            }
215
            // NOT
216
            if ($where[1]) {
217
                $cls[] = $where[1];
218
            }
219
            $result[] = $this->buildCondition($cls, $where, $settings);
220
        }
221
        return $this->joinClause($prefix, '', $result, $settings);
222
    }
223
224
    /**
225
     * Build 'col = val' part
226
     *
227
     * @param  array $cls
228
     * @param  array $where
229
     * @param  array $settings
230
     * @return string
231
     * @access protected
232
     */
233
    protected function buildCondition(array $cls, array $where, array $settings)
234
    {
235
        if (!empty($where[3])) {
236
            $cls[] = $this->quoteItem(
237
                $where[3], $settings, $this->isRaw($where[3], $where[0])
238
            );
239
        }
240
        if (WhereInterface::NO_OPERATOR !== $where[4]) {
241
            $cls[] = $where[4];
242
        }
243
        if (WhereInterface::NO_VALUE !== $where[5]) {
244
            $cls[] = $this->processValue($where[5], $settings,
245
                (bool) preg_match('/\bbetween\b/i', $where[4]));
246
        }
247
        return join(' ', $cls);
248
    }
249
250
    abstract protected function isRaw($str, /*# bool */ $rawMode)/*# : bool */;
251
    abstract protected function processValue($value, array $settings, /*# bool */ $between = false)/*# : string */;
252
    abstract protected function &getClause(/*# string */ $clauseName)/*# : array */;
253
    abstract protected function quoteItem($item, array $settings, /*# bool */ $rawMode = false)/*# : string */;
254
    abstract protected function joinClause(
255
        /*# : string */ $prefix,
256
        /*# : string */ $seperator,
257
        array $clause,
258
        array $settings
259
    )/*# : string */;
260
    /**
261
     * Return the builder
262
     *
263
     * @return BuilderInterface
264
     * @access public
265
     */
266
    abstract public function getBuilder()/*# : BuilderInterface */;
267
}
268