create-prisma-php-app 1.27.3 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.php +1 -1
- package/dist/index.js +1 -1
- package/dist/prisma-client-php/index.enc +1 -1
- package/dist/prisma-php.js +1 -1
- package/dist/src/Lib/Prisma/Classes/PPHPUtility.php +725 -0
- package/dist/src/Lib/Validator.php +23 -5
- package/package.json +1 -1
- package/dist/src/Lib/Prisma/Classes/Utility.php +0 -406
|
@@ -81,6 +81,12 @@ final class Validator
|
|
|
81
81
|
*/
|
|
82
82
|
public static function cuid($value): ?string
|
|
83
83
|
{
|
|
84
|
+
// Ensure the value is a string
|
|
85
|
+
if (!is_string($value)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Perform the CUID validation
|
|
84
90
|
return preg_match('/^c[0-9a-z]{24}$/', $value) ? $value : null;
|
|
85
91
|
}
|
|
86
92
|
|
|
@@ -92,6 +98,12 @@ final class Validator
|
|
|
92
98
|
*/
|
|
93
99
|
public static function cuid2($value): ?string
|
|
94
100
|
{
|
|
101
|
+
// Ensure the value is a string
|
|
102
|
+
if (!is_string($value)) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Perform the CUID2 validation
|
|
95
107
|
return preg_match('/^[0-9a-zA-Z_-]{21,}$/', $value) ? $value : null;
|
|
96
108
|
}
|
|
97
109
|
|
|
@@ -179,15 +191,21 @@ final class Validator
|
|
|
179
191
|
}
|
|
180
192
|
|
|
181
193
|
/**
|
|
182
|
-
* Validate a datetime in a given format.
|
|
194
|
+
* Validate and format a datetime value in a given format or ISO 8601 by default.
|
|
183
195
|
*
|
|
184
196
|
* @param mixed $value The value to validate.
|
|
185
|
-
* @param string $format The datetime format.
|
|
186
|
-
* @return string|null The valid datetime string or null if invalid.
|
|
197
|
+
* @param string $format The desired datetime format (default is database-friendly 'Y-m-d H:i:s.u').
|
|
198
|
+
* @return string|null The valid datetime string for the database or null if invalid.
|
|
187
199
|
*/
|
|
188
|
-
public static function dateTime($value, string $format = 'Y-m-d H:i:s'): ?string
|
|
200
|
+
public static function dateTime($value, string $format = 'Y-m-d H:i:s.u'): ?string
|
|
189
201
|
{
|
|
190
|
-
|
|
202
|
+
try {
|
|
203
|
+
$date = new \DateTime($value);
|
|
204
|
+
} catch (\Exception) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return $date->format($format);
|
|
191
209
|
}
|
|
192
210
|
|
|
193
211
|
// Boolean Validation
|
package/package.json
CHANGED
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
namespace Lib\Prisma\Classes;
|
|
4
|
-
|
|
5
|
-
use Lib\Validator;
|
|
6
|
-
|
|
7
|
-
enum ArrayType: string
|
|
8
|
-
{
|
|
9
|
-
case Associative = 'associative';
|
|
10
|
-
case Indexed = 'indexed';
|
|
11
|
-
case Value = 'value';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
final class Utility
|
|
15
|
-
{
|
|
16
|
-
public static function checkFieldsExistWithReferences(
|
|
17
|
-
array $select,
|
|
18
|
-
array &$relatedEntityFields,
|
|
19
|
-
array &$primaryEntityFields,
|
|
20
|
-
array $relationName,
|
|
21
|
-
array $fields,
|
|
22
|
-
string $modelName,
|
|
23
|
-
string $timestamp
|
|
24
|
-
) {
|
|
25
|
-
if (isset($select) && is_array($select)) {
|
|
26
|
-
foreach ($select as $key => $value) {
|
|
27
|
-
if ($key === $timestamp) continue;
|
|
28
|
-
|
|
29
|
-
if (is_numeric($key) && is_string($value)) {
|
|
30
|
-
if (array_key_exists($value, $fields))
|
|
31
|
-
throw new \Exception("The '$value' is indexed, waiting example: ['$value' => true]");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (isset($value) && empty($value) || !is_bool($value)) {
|
|
35
|
-
if (is_string($key) && !array_key_exists($key, $fields)) {
|
|
36
|
-
throw new \Exception("The field '$key' does not exist in the $modelName model.");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (is_string($key) && array_key_exists($key, $fields)) {
|
|
40
|
-
if (!is_bool($value) && !is_array($value)) {
|
|
41
|
-
throw new \Exception("The '$key' is indexed, waiting example: ['$key' => true]");
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!is_array($value))
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (is_string($key) && is_array($value)) {
|
|
50
|
-
if (isset($value['select'])) {
|
|
51
|
-
$relatedEntityFields[$key] = $value['select'];
|
|
52
|
-
} else {
|
|
53
|
-
if (is_array($value) && empty($value)) {
|
|
54
|
-
$relatedEntityFields[$key] = [$key];
|
|
55
|
-
} else {
|
|
56
|
-
if (!is_bool($value) || empty($value)) {
|
|
57
|
-
throw new \Exception("The '$key' is indexed, waiting example: ['$key' => true] or ['$key' => ['select' => ['field1' => true, 'field2' => true]]]");
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
foreach (explode(',', $key) as $fieldName) {
|
|
63
|
-
if ($key === $timestamp || $fieldName === $timestamp) continue;
|
|
64
|
-
$fieldName = trim($fieldName);
|
|
65
|
-
|
|
66
|
-
if (!array_key_exists($fieldName, $fields)) {
|
|
67
|
-
$availableFields = implode(', ', array_keys($fields));
|
|
68
|
-
throw new \Exception("The field '$fieldName' does not exist in the $modelName model. Available fields are: $availableFields");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
in_array($fieldName, $relationName) ||
|
|
73
|
-
(isset($fields[$fieldName]) && in_array($fields[$fieldName]['type'], $relationName))
|
|
74
|
-
) {
|
|
75
|
-
$relatedEntityFields[$fieldName] = [$fieldName];
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
$isRelationalOrInverse = false;
|
|
80
|
-
if (isset($fields[$fieldName]['decorators'])) {
|
|
81
|
-
foreach ($fields[$fieldName]['decorators'] as $decoratorKey => $decoratorValue) {
|
|
82
|
-
if ($decoratorKey === 'relation' || $decoratorKey === 'inverseRelation') {
|
|
83
|
-
$isRelationalOrInverse = true;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!$isRelationalOrInverse) {
|
|
90
|
-
if (in_array($fieldName, $primaryEntityFields)) continue;
|
|
91
|
-
$primaryEntityFields[] = $fieldName;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public static function checkFieldsExist(array $select, array $fields, string $modelName)
|
|
100
|
-
{
|
|
101
|
-
foreach ($select as $key => $value) {
|
|
102
|
-
if (is_numeric($key) && is_string($value)) {
|
|
103
|
-
if (array_key_exists($value, $fields))
|
|
104
|
-
throw new \Exception("The '$value' is indexed, waiting example: ['$value' => true]");
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (isset($value) && empty($value) || !is_bool($value)) {
|
|
108
|
-
if (is_string($key) && !array_key_exists($key, $fields)) {
|
|
109
|
-
throw new \Exception("The field '$key' does not exist in the $modelName model.");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (is_array($value) && !empty($value)) {
|
|
113
|
-
|
|
114
|
-
$isRelatedModel = false;
|
|
115
|
-
|
|
116
|
-
foreach ($fields as $field) {
|
|
117
|
-
$relation = $field['decorators']['relation'] ?? null;
|
|
118
|
-
$inverseRelation = $field['decorators']['inverseRelation'] ?? null;
|
|
119
|
-
$implicitRelation = $field['decorators']['implicitRelation'] ?? null;
|
|
120
|
-
|
|
121
|
-
if (isset($relation['name']) && $relation['name'] == $key || isset($inverseRelation['fromField']) && $inverseRelation['fromField'] == $key || isset($implicitRelation['fromField']) && $implicitRelation['fromField'] == $key) $isRelatedModel = true;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if ($isRelatedModel) continue;
|
|
125
|
-
|
|
126
|
-
$keys = array_keys($value);
|
|
127
|
-
foreach ($keys as $fieldName) {
|
|
128
|
-
$fieldName = trim($fieldName);
|
|
129
|
-
if (!array_key_exists($fieldName, $fields)) {
|
|
130
|
-
throw new \Exception("The field '$fieldName' does not exist in the $modelName model.");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
foreach (explode(',', $key) as $fieldName) {
|
|
139
|
-
$fieldName = trim($fieldName);
|
|
140
|
-
if (!array_key_exists($fieldName, $fields)) {
|
|
141
|
-
throw new \Exception("The field '$fieldName' does not exist in the $modelName model.");
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
public static function checkArrayContents(array $array): ArrayType
|
|
148
|
-
{
|
|
149
|
-
foreach ($array as $key => $value) {
|
|
150
|
-
if (is_array($value)) {
|
|
151
|
-
if (array_keys($value) !== range(0, count($value) - 1)) {
|
|
152
|
-
return ArrayType::Associative;
|
|
153
|
-
} else {
|
|
154
|
-
return ArrayType::Indexed;
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
return ArrayType::Value;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
public static function checkIncludes(array $include, array &$relatedEntityFields, array &$includes, array $fields, string $modelName)
|
|
163
|
-
{
|
|
164
|
-
if (isset($include) && is_array($include)) {
|
|
165
|
-
foreach ($include as $key => $value) {
|
|
166
|
-
self::processIncludeValue($key, $value, $relatedEntityFields, $fields, $modelName, $key);
|
|
167
|
-
|
|
168
|
-
if (is_numeric($key) && is_string($value)) {
|
|
169
|
-
throw new \Exception("The '$value' is indexed, waiting example: ['$value' => true]");
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (isset($value) && empty($value) || !is_bool($value)) {
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (!array_key_exists($key, $fields)) {
|
|
177
|
-
throw new \Exception("The field '$key' does not exist in the $modelName model.");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
$includes[$key] = $value;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
private static function processIncludeValue($key, $value, &$relatedEntityFields, $fields, $modelName, $parentKey)
|
|
186
|
-
{
|
|
187
|
-
if (isset($value['select'])) {
|
|
188
|
-
$relatedEntityFields[$parentKey] = $value;
|
|
189
|
-
} elseif (is_array($value)) {
|
|
190
|
-
if (empty($value)) {
|
|
191
|
-
$relatedEntityFields[$parentKey] = [$parentKey];
|
|
192
|
-
} else {
|
|
193
|
-
foreach ($value as $k => $v) {
|
|
194
|
-
if (is_string($k) && (is_bool($v) || empty($v))) {
|
|
195
|
-
$relatedEntityFields[$parentKey]['include'] = [$k => $v];
|
|
196
|
-
} else {
|
|
197
|
-
self::processIncludeValue($k, $v, $relatedEntityFields, $fields, $modelName, $parentKey);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
if (!is_bool($value) || empty($value)) {
|
|
203
|
-
throw new \Exception("The '$value' is indexed, waiting example: ['$value' => true] or ['$value' => ['select' => ['field1' => true, 'field2' => true]]]");
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
public static function processConditions(array $conditions, &$sqlConditions, &$bindings, $dbType, $prefix = '', $level = 0)
|
|
209
|
-
{
|
|
210
|
-
foreach ($conditions as $key => $value) {
|
|
211
|
-
if (in_array($key, ['AND', 'OR', 'NOT'])) {
|
|
212
|
-
$groupedConditions = [];
|
|
213
|
-
if ($key === 'NOT') {
|
|
214
|
-
self::processNotCondition($value, $groupedConditions, $bindings, $dbType, $prefix . $key . '_', $level);
|
|
215
|
-
if (!empty($groupedConditions)) {
|
|
216
|
-
$conditionGroup = '(' . implode(" $key ", $groupedConditions) . ')';
|
|
217
|
-
$conditionGroup = 'NOT ' . $conditionGroup;
|
|
218
|
-
$sqlConditions[] = $conditionGroup;
|
|
219
|
-
}
|
|
220
|
-
} else {
|
|
221
|
-
foreach ($value as $conditionKey => $subCondition) {
|
|
222
|
-
if (is_numeric($conditionKey)) {
|
|
223
|
-
self::processConditions($subCondition, $groupedConditions, $bindings, $dbType, $prefix . $key . $conditionKey . '_', $level + 1);
|
|
224
|
-
} else {
|
|
225
|
-
self::processSingleCondition($conditionKey, $subCondition, $groupedConditions, $bindings, $dbType, $prefix . $key . $conditionKey . '_', $level + 1);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (!empty($groupedConditions)) {
|
|
229
|
-
$conditionGroup = '(' . implode(" $key ", $groupedConditions) . ')';
|
|
230
|
-
$sqlConditions[] = $conditionGroup;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
} else {
|
|
234
|
-
self::processSingleCondition($key, $value, $sqlConditions, $bindings, $dbType, $prefix, $level);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
private static function processSingleCondition($key, $value, &$sqlConditions, &$bindings, $dbType, $prefix, $level)
|
|
240
|
-
{
|
|
241
|
-
$fieldQuoted = ($dbType == 'pgsql' || $dbType == 'sqlite') ? "\"$key\"" : "`$key`";
|
|
242
|
-
if (is_array($value)) {
|
|
243
|
-
foreach ($value as $condition => $val) {
|
|
244
|
-
$bindingKey = ":" . $prefix . $key . "_" . $condition . $level;
|
|
245
|
-
switch ($condition) {
|
|
246
|
-
case 'contains':
|
|
247
|
-
case 'startsWith':
|
|
248
|
-
case 'endsWith':
|
|
249
|
-
case 'equals':
|
|
250
|
-
case 'not':
|
|
251
|
-
if ($val === null) {
|
|
252
|
-
$sqlConditions[] = "$fieldQuoted IS NOT NULL";
|
|
253
|
-
} elseif ($val === '') {
|
|
254
|
-
$sqlConditions[] = "$fieldQuoted != ''";
|
|
255
|
-
} else {
|
|
256
|
-
$validatedValue = Validator::string($val);
|
|
257
|
-
$likeOperator = $condition === 'contains' ? ($dbType == 'pgsql' ? 'ILIKE' : 'LIKE') : '=';
|
|
258
|
-
if ($condition === 'startsWith') $validatedValue .= '%';
|
|
259
|
-
if ($condition === 'endsWith') $validatedValue = '%' . $validatedValue;
|
|
260
|
-
if ($condition === 'contains') $validatedValue = '%' . $validatedValue . '%';
|
|
261
|
-
$sqlConditions[] = $condition === 'not' ? "$fieldQuoted != $bindingKey" : "$fieldQuoted $likeOperator $bindingKey";
|
|
262
|
-
$bindings[$bindingKey] = $validatedValue;
|
|
263
|
-
}
|
|
264
|
-
break;
|
|
265
|
-
case 'gt':
|
|
266
|
-
case 'gte':
|
|
267
|
-
case 'lt':
|
|
268
|
-
case 'lte':
|
|
269
|
-
if (is_float($val)) {
|
|
270
|
-
$validatedValue = Validator::float($val);
|
|
271
|
-
} elseif (is_int($val)) {
|
|
272
|
-
$validatedValue = Validator::int($val);
|
|
273
|
-
} elseif (strtotime($val) !== false) {
|
|
274
|
-
$validatedValue = date('Y-m-d H:i:s', strtotime($val));
|
|
275
|
-
} else {
|
|
276
|
-
$validatedValue = Validator::string($val);
|
|
277
|
-
}
|
|
278
|
-
$operator = $condition === 'gt' ? '>' : ($condition === 'gte' ? '>=' : ($condition === 'lt' ? '<' : '<='));
|
|
279
|
-
$sqlConditions[] = "$fieldQuoted $operator $bindingKey";
|
|
280
|
-
$bindings[$bindingKey] = $validatedValue;
|
|
281
|
-
break;
|
|
282
|
-
case 'in':
|
|
283
|
-
case 'notIn':
|
|
284
|
-
$inPlaceholders = [];
|
|
285
|
-
foreach ($val as $i => $inVal) {
|
|
286
|
-
$inKey = $bindingKey . "_" . $i;
|
|
287
|
-
$validatedValue = Validator::string($inVal);
|
|
288
|
-
$inPlaceholders[] = $inKey;
|
|
289
|
-
$bindings[$inKey] = $validatedValue;
|
|
290
|
-
}
|
|
291
|
-
$inClause = implode(', ', $inPlaceholders);
|
|
292
|
-
$sqlConditions[] = "$fieldQuoted " . ($condition === 'notIn' ? 'NOT IN' : 'IN') . " ($inClause)";
|
|
293
|
-
break;
|
|
294
|
-
default:
|
|
295
|
-
// Handle other conditions or log an error/warning for unsupported conditions
|
|
296
|
-
throw new \Exception("Unsupported condition: $condition");
|
|
297
|
-
break;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
} else {
|
|
301
|
-
if ($value === null) {
|
|
302
|
-
$sqlConditions[] = "$fieldQuoted IS NULL";
|
|
303
|
-
} elseif ($value === '') {
|
|
304
|
-
$sqlConditions[] = "$fieldQuoted = ''";
|
|
305
|
-
} else {
|
|
306
|
-
$bindingKey = ":" . $prefix . $key . $level;
|
|
307
|
-
$validatedValue = Validator::string($value);
|
|
308
|
-
$sqlConditions[] = "$fieldQuoted = $bindingKey";
|
|
309
|
-
$bindings[$bindingKey] = $validatedValue;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private static function processNotCondition($conditions, &$sqlConditions, &$bindings, $dbType, $prefix, $level = 0)
|
|
315
|
-
{
|
|
316
|
-
foreach ($conditions as $key => $value) {
|
|
317
|
-
self::processSingleCondition($key, $value, $sqlConditions, $bindings, $dbType, $prefix . 'NOT_', $level);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
public static function checkForInvalidKeys(array $data, array $fields, string $modelName)
|
|
322
|
-
{
|
|
323
|
-
foreach ($data as $key => $value) {
|
|
324
|
-
if (!empty($key) && !in_array($key, $fields)) {
|
|
325
|
-
throw new \Exception("The field '$key' does not exist in the $modelName model. Accepted fields: " . implode(', ', $fields));
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
public static function queryOptions(array $criteria, string &$sql)
|
|
331
|
-
{
|
|
332
|
-
// Handle _max, _min, _count, _avg, and _sum
|
|
333
|
-
$selectParts = [];
|
|
334
|
-
if (isset($criteria['_max'])) {
|
|
335
|
-
foreach ($criteria['_max'] as $column => $enabled) {
|
|
336
|
-
if ($enabled) {
|
|
337
|
-
$selectParts[] = "MAX($column) AS max_$column";
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
if (isset($criteria['_min'])) {
|
|
342
|
-
foreach ($criteria['_min'] as $column => $enabled) {
|
|
343
|
-
if ($enabled) {
|
|
344
|
-
$selectParts[] = "MIN($column) AS min_$column";
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (isset($criteria['_count'])) {
|
|
349
|
-
foreach ($criteria['_count'] as $column => $enabled) {
|
|
350
|
-
if ($enabled) {
|
|
351
|
-
$selectParts[] = "COUNT($column) AS count_$column";
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
if (isset($criteria['_avg'])) {
|
|
356
|
-
foreach ($criteria['_avg'] as $column => $enabled) {
|
|
357
|
-
if ($enabled) {
|
|
358
|
-
$selectParts[] = "AVG($column) AS avg_$column";
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
if (isset($criteria['_sum'])) {
|
|
363
|
-
foreach ($criteria['_sum'] as $column => $enabled) {
|
|
364
|
-
if ($enabled) {
|
|
365
|
-
$selectParts[] = "SUM($column) AS sum_$column";
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Prepend to SELECT if _max, _min, _count, _avg, or _sum is specified
|
|
371
|
-
if (!empty($selectParts)) {
|
|
372
|
-
$sql = str_replace('SELECT', 'SELECT ' . implode(', ', $selectParts) . ',', $sql);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Handle ORDER BY
|
|
376
|
-
if (isset($criteria['orderBy'])) {
|
|
377
|
-
$orderByParts = [];
|
|
378
|
-
|
|
379
|
-
// Check if orderBy is an associative array with directions or a list of columns
|
|
380
|
-
if (array_values($criteria['orderBy']) === $criteria['orderBy']) {
|
|
381
|
-
// If it's a list of columns, default to 'asc'
|
|
382
|
-
foreach ($criteria['orderBy'] as $column) {
|
|
383
|
-
$orderByParts[] = "$column asc";
|
|
384
|
-
}
|
|
385
|
-
} else {
|
|
386
|
-
// If it's an associative array with directions
|
|
387
|
-
foreach ($criteria['orderBy'] as $column => $direction) {
|
|
388
|
-
$direction = strtolower($direction) === 'desc' ? 'desc' : 'asc';
|
|
389
|
-
$orderByParts[] = "$column $direction";
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
$sql .= " ORDER BY " . implode(', ', $orderByParts);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Handle LIMIT (take)
|
|
397
|
-
if (isset($criteria['take'])) {
|
|
398
|
-
$sql .= " LIMIT " . intval($criteria['take']);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// Handle OFFSET (skip)
|
|
402
|
-
if (isset($criteria['skip'])) {
|
|
403
|
-
$sql .= " OFFSET " . intval($criteria['skip']);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|