ClauseTrait::positionedParam()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
nc 1
cc 1
eloc 4
nop 2
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\Interfaces\OutputInterface;
18
use Phossa2\Query\Interfaces\ClauseInterface;
19
use Phossa2\Query\Interfaces\BuilderInterface;
20
use Phossa2\Query\Interfaces\StatementInterface;
21
22
/**
23
 * ClauseTrait
24
 *
25
 * @package Phossa2\Query
26
 * @author  Hong Zhang <[email protected]>
27
 * @see     ClauseInterface
28
 * @version 2.0.0
29
 * @since   2.0.0 added
30
 */
31
trait ClauseTrait
32
{
33
    use QuoteTrait;
34
35
    /**
36
     * storage for clauses
37
     *
38
     * @var    array
39
     * @access protected
40
     */
41
    protected $clause = [];
42
43
    /**
44
     * Is $str a raw sql string ?
45
     *
46
     * @param  mixed $str
47
     * @param  bool $rawMode
48
     * @access protected
49
     */
50
    protected function isRaw($str, /*# bool */ $rawMode)/*# : bool */
51
    {
52
        if ($rawMode) {
53
            return true;
54
        }
55
56
        if (is_string($str)) {
57
            return (bool) preg_match('/[^0-9a-zA-Z\$_.]/', $str);
58
        }
59
60
        return is_object($str);
61
    }
62
63
    /**
64
     * Quote an alias if not an int
65
     *
66
     * @param  int|string $alias
67
     * @param  array $settings
68
     * @return string
69
     * @access protected
70
     */
71
    protected function quoteAlias($alias, array $settings)/*# : string */
72
    {
73
        if (is_int($alias)) {
74
            return '';
75
        } else {
76
            $prefix = $settings['quotePrefix'];
77
            $suffix = $settings['quoteSuffix'];
78
            return ' AS ' . $this->quoteSpace($alias, $prefix, $suffix);
79
        }
80
    }
81
82
    /**
83
     * Quote an item if it is a field/column
84
     *
85
     * @param  string|StatementInterface $item
86
     * @param  array $settings
87
     * @param  bool $rawMode
88
     * @access protected
89
     */
90
    protected function quoteItem(
91
        $item,
92
        array $settings,
93
        /*# bool */ $rawMode = false
94
    )/*# : string */ {
95
        // is an object
96
        if (is_object($item)) {
97
            return $this->quoteObject($item, $settings);
98
        }
99
100
        // is a string, quote with prefix and suffix
101
        return $rawMode ? $item : $this->quote($item, $settings);
102
    }
103
104
    /**
105
     * Quote object
106
     *
107
     * @param  object $object
108
     * @param  array $settings
109
     * @return string
110
     * @access protected
111
     */
112
    protected function quoteObject($object, $settings)/*# : string */
113
    {
114
        if ($object instanceof StatementInterface) {
115
            $settings = $this->flatSettings($settings);
116
            return '(' . ltrim($object->getStatement($settings)) . ')';
117
        } elseif ($object instanceof OutputInterface) {
118
            return $object->getStatement($settings);
119
        }
120
        return (string) $object;
121
    }
122
123
    /**
124
     * Return specific clause part
125
     *
126
     * @param  string $clauseName
127
     * @param  array
128
     * @access protected
129
     */
130
    protected function &getClause(/*# string */ $clauseName)/*# : array */
131
    {
132
        if (empty($clauseName)) {
133
            return $this->clause;
134
        } else {
135
            if (!isset($this->clause[$clauseName])) {
136
                $this->clause[$clauseName] = [];
137
            }
138
            return $this->clause[$clauseName];
139
        }
140
    }
141
142
    /**
143
     * Quote string even with space inside
144
     *
145
     * @param  string $str
146
     * @param  string $prefix
147
     * @param  string $suffix
148
     * @return string
149
     * @access protected
150
     */
151
    protected function quoteSpace(
152
        /*# string */ $str,
153
        /*# string */ $prefix,
154
        /*# string */ $suffix
155
    )/*# : string */ {
156
        return sprintf('%s%s%s', $prefix, $str, $suffix);
157
    }
158
159
    /**
160
     * Process value part in the clause
161
     *
162
     * @param  mixed $value
163
     * @param  array $settings
164
     * @return string
165
     * @access protected
166
     */
167
    protected function processValue(
168
        $value,
169
        array $settings,
170
        /*# bool */ $between = false
171
    )/*# : string */ {
172
        if (is_object($value)) {
173
            return $this->quoteObject($value, $settings);
174
        } elseif (is_array($value)) {
175
            return $this->processArrayValue($value, $settings, $between);
176
        } else {
177
            return $this->processScalarValue($value);
178
        }
179
    }
180
181
    /**
182
     * Process value array
183
     *
184
     * @param  array $value
185
     * @param  array $settings
186
     * @return string
187
     * @access protected
188
     */
189
    protected function processArrayValue(
190
        array $value,
191
        array $settings,
192
        /*# bool */ $between = false
193
    )/*# : string */ {
194
        if ($between) {
195
            $v1 = $this->processValue($value[0], $settings);
196
            $v2 = $this->processValue($value[1], $settings);
197
            return $v1 . ' AND ' . $v2;
198
        } else {
199
            $result = [];
200
            foreach ($value as $val) {
201
                $result[] = $this->processValue($val, $settings);
202
            }
203
            return '(' . join(', ', $result) . ')';
204
        }
205
    }
206
207
    /**
208
     * Process scalar value
209
     *
210
     * @param  mixed $value
211
     * @return string
212
     * @access protected
213
     */
214
    protected function processScalarValue($value)/*# : string */
215
    {
216
        if (ClauseInterface::NO_VALUE == $value) {
217
            return '?';
218
        } elseif (is_null($value) || is_bool($value)) {
219
            return strtoupper(var_export($value, true));
220
        } else {
221
            return $this->getBuilder()->getParameter()->getPlaceholder($value);
222
        }
223
    }
224
225
    /**
226
     * Join a clause with prefix and its parts
227
     *
228
     * @param  string $prefix
229
     * @param  string $seperator
230
     * @param  array $clause
231
     * @param  array $settings
232
     * @return string
233
     * @access protected
234
     */
235
    protected function joinClause(
236
        /*# : string */ $prefix,
237
        /*# : string */ $seperator,
238
        array $clause,
239
        array $settings
240
    )/*# : string */ {
241
        if (empty($clause)) {
242
            return '';
243
        } else {
244
            $sepr = $settings['seperator'];
245
            $join = $settings['join'];
246
            $pref = empty($prefix) ? $join : ($sepr . $prefix . $join);
247
            return $pref . join($seperator . $join, $clause);
248
        }
249
    }
250
251
    /**
252
     * Build a generic clause
253
     *
254
     * @param  string $clauseName
255
     * @param  string $clausePrefix
256
     * @param  array $settings
257
     * @param  array $clauseParts
258
     * @return string
259
     * @access protected
260
     */
261
    protected function buildClause(
262
        /*# string */ $clauseName,
263
        /*# string */ $clausePrefix,
264
        array $settings,
265
        array $clauseParts = []
266
    )/*# string */ {
267
        $clause = &$this->getClause($clauseName);
268
        foreach ($clause as $alias => $field) {
269
            $part =
270
                $this->quoteItem($field[0], $settings, $field[1]) .
271
                $this->quoteAlias($alias, $settings) .
272
                (isset($field[2]) ? (' ' . $field[2]) : '');
273
            $clauseParts[] = $part;
274
        }
275
        return $this->joinClause($clausePrefix, ',', $clauseParts, $settings);
276
    }
277
278
    /**
279
     * Reset settings to print flat
280
     *
281
     * @param  array $settings
282
     * @return array
283
     * @access protected
284
     */
285
    protected function flatSettings(array $settings)/*# : array */
286
    {
287
        return array_replace(
288
            $settings,
289
            ['seperator' => ' ', 'indent' => '']
290
        );
291
    }
292
293
    /**
294
     * Dealing with positioned parameters
295
     *
296
     * e.g. havingRaw('id > ?', [10]) turns into  havingRaw('id > 10')
297
     *
298
     * @param  string $rawString
299
     * @param  array $values
300
     * @access protected
301
     */
302
    protected function positionedParam(
303
        /*# string */ $rawString,
304
        array $values
305
    )/*# : string */ {
306
        return $this->getBuilder()->raw($rawString, $values);
307
    }
308
309
    /**
310
     * Return the builder
311
     *
312
     * @return BuilderInterface
313
     * @access public
314
     */
315
    abstract public function getBuilder()/*# : BuilderInterface */;
316
}
317