PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.41
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.41
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.41, at vendor/wpfluent/framework/src/WPFluent/Database/BaseGrammar.php

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