PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.91.6
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.91.6
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Database / BaseGrammar.php

BaseGrammar.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.91.6, at vendor/wpfluent/framework/src/WPFluent/Database/BaseGrammar.php

395 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Database;
4
5 use RuntimeException;
6 use FluentBoards\Framework\Support\Helper;
7 use FluentBoards\Framework\Database\Schema;
8 use FluentBoards\Framework\Support\MacroableTrait;
9 use FluentBoards\Framework\Database\Query\Expression;
10
11 abstract class BaseGrammar
12 {
13 use MacroableTrait;
14
15 /**
16 * Cache of aliased table names.
17 *
18 * @var array
19 */
20 protected $alias = [];
21
22 /**
23 * The connection used for escaping values.
24 *
25 * @var \FluentBoards\Framework\Database\ConnectionInterface
26 */
27 protected $connection;
28
29 /**
30 * The base prefix frpm $wpdb.
31 *
32 * @var string
33 */
34 protected $basePrefix = '';
35
36 /**
37 * The grammar table prefix.
38 *
39 * @var string
40 */
41 protected $tablePrefix = '';
42
43 /**
44 * Check if the given table is a built-in table.
45 *
46 * @param string $table
47 * @return boolean
48 */
49 public function isAliasedTable($table)
50 {
51 return in_array("`$table`", $this->alias);
52 }
53
54 /**
55 * Wrap an array of values.
56 *
57 * @param array $values
58 * @return array
59 */
60 public function wrapArray(array $values)
61 {
62 return array_map([$this, 'wrap'], $values);
63 }
64
65 /**
66 * Wrap a value in keyword identifiers.
67 *
68 * @param \FluentBoards\Framework\Database\Query\Expression|string $value
69 * @return string
70 */
71 public function wrap($value)
72 {
73 if ($this->isExpression($value)) {
74 return $this->getValue($value);
75 }
76
77 // If the value being wrapped has a column alias we will need to separate // out the pieces so we can wrap each of the segments of the
78 // expression on its own, and then join these both
79 // back together using the "as" connector.
80 if (stripos($value, ' as ') !== false) {
81 return $this->wrapAliasedValue($value);
82 }
83
84 // If the given value is a JSON selector we will wrap it differently than a
85 // traditional value. We will need to split this path and wrap each part
86 // wrapped, etc. Otherwise, we will simply wrap the value as a string.
87 if ($this->isJsonSelector($value)) {
88 return $this->wrapJsonSelector($value);
89 }
90
91 return $this->wrapSegments(explode('.', $value));
92 }
93
94 /**
95 * Wrap a table in keyword identifiers.
96 *
97 * @param \FluentBoards\Framework\Database\Query\Expression|string $table
98 * @return string
99 */
100 public function wrapTable($table)
101 {
102 if ($this->isExpression($table)) {
103 return $this->getValue($table);
104 }
105
106 // If the table being wrapped has an alias we'll need to separate the pieces
107 // so we can prefix the table and then wrap each of the segments on their
108 // own and then join these both back together using the "as" connector.
109 if (stripos($table, ' as ') !== false) {
110 return $this->wrapAliasedTable($table);
111 }
112
113 $tablePrefix = $this->resolveTablePrefix($table);
114
115 // If the table being wrapped has a custom schema name specified, we need to
116 // prefix the last segment as the table name then wrap each segment alone
117 // and eventually join them both back together using the dot connector.
118 if (str_contains($table, '.')) {
119 $table = substr_replace(
120 $table, '.' . $tablePrefix, strrpos($table, '.'), 1
121 );
122
123 return Helper::collect(explode('.', $table))
124 ->map(function($value) {
125 return $this->wrapValue($value);
126 })
127 ->implode('.');
128 }
129
130 if ($this->isAliasedTable($table)) {
131 return $table;
132 }
133
134 return $this->wrapValue($tablePrefix.$table);
135 }
136
137 /**
138 * Resolve the table prefix based on the table name.
139 *
140 * @param string $table
141 * @return string
142 */
143 protected function resolveTablePrefix($table)
144 {
145 if (!is_multisite()) {
146 return $this->tablePrefix;
147 }
148
149 $sharedTables = [
150 'users',
151 'usermeta',
152 'site',
153 'sitemeta',
154 'blogs',
155 'blog_versions',
156 'registration_log',
157 'signups',
158 ];
159
160 return in_array(
161 $table, $sharedTables
162 ) ? $this->basePrefix : $this->tablePrefix;
163 }
164
165 /**
166 * Wrap a value that has an alias.
167 *
168 * @param string $value
169 * @return string
170 */
171 protected function wrapAliasedValue($value)
172 {
173 $segments = preg_split('/\s+as\s+/i', $value);
174
175 return $this->wrap(
176 $segments[0]
177 ) . ' as ' . $this->wrapValue($segments[1]);
178 }
179
180 /**
181 * Wrap a table that has an alias.
182 *
183 * @param string $value
184 * @return string
185 */
186 protected function wrapAliasedTable($value)
187 {
188 $segments = preg_split('/\s+as\s+/i', $value);
189
190 $tablePrefix = $this->resolveTablePrefix($segments[0]);
191
192 $this->alias[] = $alias = $this->wrapValue($segments[1]);
193
194 return $this->wrapTable($segments[0]) . ' as ' . $alias;
195 }
196
197 /**
198 * Wrap the given value segments.
199 *
200 * @param array $segments
201 * @return string
202 */
203 protected function wrapSegments($segments)
204 {
205 return Helper::collect($segments)->map(function (
206 $segment, $key
207 ) use ($segments) {
208 return $key == 0 && count($segments) > 1
209 ? $this->wrapTable($segment)
210 : $this->wrapValue($segment);
211 })->implode('.');
212 }
213
214 /**
215 * Wrap a single string in keyword identifiers.
216 *
217 * @param string $value
218 * @return string
219 */
220 protected function wrapValue($value)
221 {
222 if ($value !== '*') {
223 return '"'.str_replace('"', '""', $value).'"';
224 }
225
226 return $value;
227 }
228
229 /**
230 * Wrap the given JSON selector.
231 *
232 * @param string $value
233 * @return string
234 *
235 * @throws \RuntimeException
236 */
237 protected function wrapJsonSelector($value)
238 {
239 throw new RuntimeException(
240 'This database engine does not support JSON operations.'
241 );
242 }
243
244 /**
245 * Determine if the given string is a JSON selector.
246 *
247 * @param string $value
248 * @return bool
249 */
250 protected function isJsonSelector($value)
251 {
252 return str_contains($value, '->');
253 }
254
255 /**
256 * Convert an array of column names into a delimited string.
257 *
258 * @param array $columns
259 * @return string
260 */
261 public function columnize(array $columns)
262 {
263 return implode(', ', array_map([$this, 'wrap'], $columns));
264 }
265
266 /**
267 * Create query parameter place-holders for an array.
268 *
269 * @param array $values
270 * @return string
271 */
272 public function parameterize(array $values)
273 {
274 return implode(', ', array_map([$this, 'parameter'], $values));
275 }
276
277 /**
278 * Get the appropriate query parameter place-holder for a value.
279 *
280 * @param mixed $value
281 * @return string
282 */
283 public function parameter($value)
284 {
285 return $this->isExpression($value) ? $this->getValue($value) : '?';
286 }
287
288 /**
289 * Quote the given string literal.
290 *
291 * @param string|array $value
292 * @return string
293 */
294 public function quoteString($value)
295 {
296 if (is_array($value)) {
297 return implode(', ', array_map([$this, __FUNCTION__], $value));
298 }
299
300 return "'$value'";
301 }
302
303 /**
304 * Escapes a value for safe SQL embedding.
305 *
306 * @param string|float|int|bool|null $value
307 * @param bool $binary
308 * @return string
309 */
310 public function escape($value, $binary = false)
311 {
312 if (is_null($this->connection)) {
313 throw new RuntimeException(
314 "The database driver's grammar implementation does not support escaping values."
315 );
316 }
317
318 return $this->connection->escape($value, $binary);
319 }
320
321 /**
322 * Determine if the given value is a raw expression.
323 *
324 * @param mixed $value
325 * @return bool
326 */
327 public function isExpression($value)
328 {
329 return $value instanceof Expression;
330 }
331
332 /**
333 * Transforms expressions to their scalar types.
334 *
335 * @param \FluentBoards\Framework\Database\Query\Expression|string|int|float $expression
336 * @return string|int|float
337 */
338 public function getValue($expression)
339 {
340 if ($this->isExpression($expression)) {
341 return $this->getValue($expression->getValue($this));
342 }
343
344 return $expression;
345 }
346
347 /**
348 * Get the format for database stored dates.
349 *
350 * @return string
351 */
352 public function getDateFormat()
353 {
354 return 'Y-m-d H:i:s';
355 }
356
357 /**
358 * Get the grammar's table prefix.
359 *
360 * @return string
361 */
362 public function getTablePrefix()
363 {
364 return $this->tablePrefix;
365 }
366
367 /**
368 * Set the grammar's table prefix.
369 *
370 * @param string $prefix
371 * @return $this
372 */
373 public function setTablePrefix($wpdb)
374 {
375 $this->basePrefix = $wpdb->base_prefix;
376
377 $this->tablePrefix = $wpdb->prefix;
378
379 return $this;
380 }
381
382 /**
383 * Set the grammar's database connection.
384 *
385 * @param \FluentBoards\Framework\Database\ConnectionInterface $connection
386 * @return $this
387 */
388 public function setConnection($connection)
389 {
390 $this->connection = $connection;
391
392 return $this;
393 }
394 }
395