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

ClauseTrait::processValueArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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