PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.94
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.94
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Database / BaseGrammar.php

BaseGrammar.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.94, at vendor/wpfluent/framework/src/WPFluent/Database/BaseGrammar.php

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