create-prisma-php-app 1.11.9 → 1.11.11
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 +145 -65
- package/dist/settings/public-functions.php +7 -0
- package/dist/src/app/index.php +1 -1
- package/package.json +1 -1
package/dist/bootstrap.php
CHANGED
|
@@ -39,6 +39,16 @@ function determineContentToInclude()
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
if (empty($includePath)) {
|
|
43
|
+
$dynamicRoute = dynamicRoute($uri);
|
|
44
|
+
if ($dynamicRoute) {
|
|
45
|
+
$path = __DIR__ . $dynamicRoute;
|
|
46
|
+
if (file_exists($path)) {
|
|
47
|
+
$includePath = $path;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
$currentPath = $baseDir;
|
|
43
53
|
$getGroupFolder = getGroupFolder($groupFolder);
|
|
44
54
|
$modifiedUri = $uri;
|
|
@@ -88,51 +98,9 @@ function uriExtractor(string $scriptUrl): string
|
|
|
88
98
|
return "/";
|
|
89
99
|
}
|
|
90
100
|
|
|
91
|
-
function checkForDuplicateRoutes()
|
|
92
|
-
{
|
|
93
|
-
$routes = json_decode(file_get_contents(SETTINGS_PATH . "/files-list.json"), true);
|
|
94
|
-
|
|
95
|
-
$normalizedRoutesMap = [];
|
|
96
|
-
foreach ($routes as $route) {
|
|
97
|
-
$routeWithoutGroups = preg_replace('/\(.*?\)/', '', $route);
|
|
98
|
-
$routeTrimmed = ltrim($routeWithoutGroups, '.\\/');
|
|
99
|
-
$routeTrimmed = preg_replace('#/{2,}#', '/', $routeTrimmed);
|
|
100
|
-
$routeTrimmed = preg_replace('#\\\\{2,}#', '\\', $routeTrimmed);
|
|
101
|
-
$routeNormalized = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $routeTrimmed);
|
|
102
|
-
$normalizedRoutesMap[$routeNormalized][] = $route;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
$errorMessages = [];
|
|
106
|
-
foreach ($normalizedRoutesMap as $normalizedRoute => $originalRoutes) {
|
|
107
|
-
$basename = basename($normalizedRoute);
|
|
108
|
-
if ($basename === 'layout.php') continue;
|
|
109
|
-
|
|
110
|
-
if (count($originalRoutes) > 1 && strpos($normalizedRoute, DIRECTORY_SEPARATOR) !== false) {
|
|
111
|
-
$directGroupMatchFound = false;
|
|
112
|
-
foreach ($originalRoutes as $originalRoute) {
|
|
113
|
-
if (preg_match('~^\\.\\/src\\/app[\\/\\\\]\\(.*?\\)[\\/\\\\].*?\\.php$~', $originalRoute, $matches)) {
|
|
114
|
-
$directGroupMatchFound = true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if ($directGroupMatchFound) continue;
|
|
119
|
-
|
|
120
|
-
$errorMessages[] = "Duplicate route found after normalization: " . $normalizedRoute;
|
|
121
|
-
|
|
122
|
-
foreach ($originalRoutes as $originalRoute) {
|
|
123
|
-
$errorMessages[] = "- Grouped original route: " . $originalRoute;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!empty($errorMessages)) {
|
|
129
|
-
$errorMessageString = implode("<br>", $errorMessages);
|
|
130
|
-
modifyOutputLayoutForError($errorMessageString);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
101
|
function writeRoutes()
|
|
135
102
|
{
|
|
103
|
+
global $filesListRoutes;
|
|
136
104
|
$directory = './src/app';
|
|
137
105
|
|
|
138
106
|
if (is_dir($directory)) {
|
|
@@ -149,6 +117,10 @@ function writeRoutes()
|
|
|
149
117
|
$jsonData = json_encode($filesList, JSON_PRETTY_PRINT);
|
|
150
118
|
$jsonFileName = SETTINGS_PATH . '/files-list.json';
|
|
151
119
|
@file_put_contents($jsonFileName, $jsonData);
|
|
120
|
+
|
|
121
|
+
if (file_exists($jsonFileName)) {
|
|
122
|
+
$filesListRoutes = json_decode(file_get_contents($jsonFileName), true);
|
|
123
|
+
}
|
|
152
124
|
}
|
|
153
125
|
}
|
|
154
126
|
|
|
@@ -171,6 +143,37 @@ function findGroupFolder($uri): string
|
|
|
171
143
|
}
|
|
172
144
|
}
|
|
173
145
|
|
|
146
|
+
function dynamicRoute($uri)
|
|
147
|
+
{
|
|
148
|
+
global $filesListRoutes;
|
|
149
|
+
$uriMatch = null;
|
|
150
|
+
$normalizedUri = ltrim(str_replace('\\', '/', $uri), './');
|
|
151
|
+
$normalizedUriEdited = "src/app/$normalizedUri/route.php";
|
|
152
|
+
$uriSegments = explode('/', $normalizedUriEdited);
|
|
153
|
+
|
|
154
|
+
foreach ($filesListRoutes as $route) {
|
|
155
|
+
$normalizedRoute = trim(str_replace('\\', '/', $route), '.');
|
|
156
|
+
$routeSegments = explode('/', ltrim($normalizedRoute, '/'));
|
|
157
|
+
$singleDynamic = preg_match_all('/\[[^\]]+\]/', $normalizedRoute, $matches) === 1 && !strpos($normalizedRoute, '[...');
|
|
158
|
+
if ($singleDynamic) {
|
|
159
|
+
if (singleDynamicRoute($uriSegments, $routeSegments)) {
|
|
160
|
+
$uriMatch = $normalizedRoute;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
} elseif (strpos($normalizedRoute, '[...') !== false) {
|
|
164
|
+
$cleanedRoute = preg_replace('/\[\.\.\..*?\].*/', '', $normalizedRoute);
|
|
165
|
+
if (strpos('/src/app/' . $normalizedUri, $cleanedRoute) === 0) {
|
|
166
|
+
if (strpos($normalizedRoute, 'route.php') !== false) {
|
|
167
|
+
$uriMatch = $normalizedRoute;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return $uriMatch;
|
|
175
|
+
}
|
|
176
|
+
|
|
174
177
|
function isGroupIdentifier($segment): bool
|
|
175
178
|
{
|
|
176
179
|
return preg_match('/^\(.*\)$/', $segment);
|
|
@@ -178,15 +181,16 @@ function isGroupIdentifier($segment): bool
|
|
|
178
181
|
|
|
179
182
|
function matchGroupFolder($constructedPath): ?string
|
|
180
183
|
{
|
|
181
|
-
$
|
|
184
|
+
global $filesListRoutes;
|
|
182
185
|
$bestMatch = null;
|
|
183
186
|
$normalizedConstructedPath = ltrim(str_replace('\\', '/', $constructedPath), './');
|
|
184
187
|
|
|
185
188
|
$routeFile = "/src/app/$normalizedConstructedPath/route.php";
|
|
186
189
|
$indexFile = "/src/app/$normalizedConstructedPath/index.php";
|
|
187
190
|
|
|
188
|
-
foreach ($
|
|
191
|
+
foreach ($filesListRoutes as $route) {
|
|
189
192
|
$normalizedRoute = trim(str_replace('\\', '/', $route), '.');
|
|
193
|
+
|
|
190
194
|
$cleanedRoute = preg_replace('/\/\([^)]+\)/', '', $normalizedRoute);
|
|
191
195
|
if ($cleanedRoute === $routeFile) {
|
|
192
196
|
$bestMatch = $normalizedRoute;
|
|
@@ -211,10 +215,63 @@ function getGroupFolder($uri): string
|
|
|
211
215
|
return "";
|
|
212
216
|
}
|
|
213
217
|
|
|
214
|
-
function
|
|
218
|
+
function singleDynamicRoute($uriSegments, $routeSegments)
|
|
219
|
+
{
|
|
220
|
+
if (count($routeSegments) != count($uriSegments)) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
foreach ($routeSegments as $index => $segment) {
|
|
225
|
+
if (preg_match('/^\[[^\]]+\]$/', $segment)) {
|
|
226
|
+
} else {
|
|
227
|
+
if ($segment !== $uriSegments[$index]) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function checkForDuplicateRoutes()
|
|
215
236
|
{
|
|
216
|
-
|
|
217
|
-
|
|
237
|
+
global $filesListRoutes;
|
|
238
|
+
$normalizedRoutesMap = [];
|
|
239
|
+
foreach ($filesListRoutes as $route) {
|
|
240
|
+
$routeWithoutGroups = preg_replace('/\(.*?\)/', '', $route);
|
|
241
|
+
$routeTrimmed = ltrim($routeWithoutGroups, '.\\/');
|
|
242
|
+
$routeTrimmed = preg_replace('#/{2,}#', '/', $routeTrimmed);
|
|
243
|
+
$routeTrimmed = preg_replace('#\\\\{2,}#', '\\', $routeTrimmed);
|
|
244
|
+
$routeNormalized = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $routeTrimmed);
|
|
245
|
+
$normalizedRoutesMap[$routeNormalized][] = $route;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
$errorMessages = [];
|
|
249
|
+
foreach ($normalizedRoutesMap as $normalizedRoute => $originalRoutes) {
|
|
250
|
+
$basename = basename($normalizedRoute);
|
|
251
|
+
if ($basename === 'layout.php') continue;
|
|
252
|
+
|
|
253
|
+
if (count($originalRoutes) > 1 && strpos($normalizedRoute, DIRECTORY_SEPARATOR) !== false) {
|
|
254
|
+
$directGroupMatchFound = false;
|
|
255
|
+
foreach ($originalRoutes as $originalRoute) {
|
|
256
|
+
if (preg_match('~^\\.\\/src\\/app[\\/\\\\]\\(.*?\\)[\\/\\\\].*?\\.php$~', $originalRoute, $matches)) {
|
|
257
|
+
$directGroupMatchFound = true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if ($directGroupMatchFound) continue;
|
|
262
|
+
|
|
263
|
+
$errorMessages[] = "Duplicate route found after normalization: " . $normalizedRoute;
|
|
264
|
+
|
|
265
|
+
foreach ($originalRoutes as $originalRoute) {
|
|
266
|
+
$errorMessages[] = "- Grouped original route: " . $originalRoute;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (!empty($errorMessages)) {
|
|
272
|
+
$errorMessageString = implode("<br>", $errorMessages);
|
|
273
|
+
modifyOutputLayoutForError($errorMessageString);
|
|
274
|
+
}
|
|
218
275
|
}
|
|
219
276
|
|
|
220
277
|
function setupErrorHandling(&$content)
|
|
@@ -240,9 +297,12 @@ function setupErrorHandling(&$content)
|
|
|
240
297
|
}
|
|
241
298
|
|
|
242
299
|
ob_start();
|
|
300
|
+
require_once SETTINGS_PATH . '/public-functions.php';
|
|
243
301
|
require_once SETTINGS_PATH . '/request-methods.php';
|
|
244
302
|
$metadataArray = require_once APP_PATH . '/metadata.php';
|
|
303
|
+
$filesListRoutes = [];
|
|
245
304
|
$metadata = "";
|
|
305
|
+
$uri = "";
|
|
246
306
|
$pathname = "";
|
|
247
307
|
$content = "";
|
|
248
308
|
$childContent = "";
|
|
@@ -250,9 +310,12 @@ $childContent = "";
|
|
|
250
310
|
function containsChildContent($filePath)
|
|
251
311
|
{
|
|
252
312
|
$fileContent = file_get_contents($filePath);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
313
|
+
if (
|
|
314
|
+
(strpos($fileContent, 'echo $childContent') === false &&
|
|
315
|
+
strpos($fileContent, 'echo $childContent;') === false) &&
|
|
316
|
+
(strpos($fileContent, '<?= $childContent ?>') === false) &&
|
|
317
|
+
(strpos($fileContent, '<?= $childContent; ?>') === false)
|
|
318
|
+
) {
|
|
256
319
|
return true;
|
|
257
320
|
} else {
|
|
258
321
|
return false;
|
|
@@ -262,8 +325,12 @@ function containsChildContent($filePath)
|
|
|
262
325
|
function containsContent($filePath)
|
|
263
326
|
{
|
|
264
327
|
$fileContent = file_get_contents($filePath);
|
|
265
|
-
|
|
266
|
-
|
|
328
|
+
if (
|
|
329
|
+
(strpos($fileContent, 'echo $content') === false &&
|
|
330
|
+
strpos($fileContent, 'echo $content;') === false) &&
|
|
331
|
+
(strpos($fileContent, '<?= $content ?>') === false) &&
|
|
332
|
+
(strpos($fileContent, '<?= $content; ?>') === false)
|
|
333
|
+
) {
|
|
267
334
|
return true;
|
|
268
335
|
} else {
|
|
269
336
|
return false;
|
|
@@ -300,8 +367,10 @@ try {
|
|
|
300
367
|
$parentLayoutPath = APP_PATH . '/layout.php';
|
|
301
368
|
$isParentLayout = !empty($layoutsToInclude) && strpos($layoutsToInclude[0], 'src/app/layout.php') !== false;
|
|
302
369
|
|
|
303
|
-
|
|
304
|
-
|
|
370
|
+
$isContentIncluded = false;
|
|
371
|
+
$isChildContentIncluded = false;
|
|
372
|
+
if (containsContent($parentLayoutPath)) {
|
|
373
|
+
$isContentIncluded = true;
|
|
305
374
|
}
|
|
306
375
|
|
|
307
376
|
ob_start();
|
|
@@ -312,13 +381,16 @@ try {
|
|
|
312
381
|
$childContent = ob_get_clean();
|
|
313
382
|
}
|
|
314
383
|
foreach (array_reverse($layoutsToInclude) as $layoutPath) {
|
|
315
|
-
|
|
316
|
-
|
|
384
|
+
if ($parentLayoutPath === $layoutPath) {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
|
|
317
388
|
if (containsChildContent($layoutPath)) {
|
|
318
|
-
|
|
319
|
-
} else {
|
|
320
|
-
$content .= "<div class='error'>The layout file does not contain <?php echo \$childContent ?> Or <?= \$childContent ?><br>" . "<strong>$layoutPath</strong></div>";
|
|
389
|
+
$isChildContentIncluded = true;
|
|
321
390
|
}
|
|
391
|
+
|
|
392
|
+
ob_start();
|
|
393
|
+
require_once $layoutPath;
|
|
322
394
|
$childContent = ob_get_clean();
|
|
323
395
|
}
|
|
324
396
|
} else {
|
|
@@ -333,11 +405,19 @@ try {
|
|
|
333
405
|
$childContent = ob_get_clean();
|
|
334
406
|
}
|
|
335
407
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
408
|
+
if (!$isContentIncluded && !$isChildContentIncluded) {
|
|
409
|
+
$content .= $childContent;
|
|
410
|
+
ob_start();
|
|
411
|
+
require_once APP_PATH . '/layout.php';
|
|
412
|
+
} else {
|
|
413
|
+
if ($isContentIncluded) {
|
|
414
|
+
$content .= "<div class='error'>The parent layout file does not contain <?php echo \$content; ?> Or <?= \$content ?><br>" . "<strong>$parentLayoutPath</strong></div>";
|
|
415
|
+
modifyOutputLayoutForError($content);
|
|
416
|
+
} else {
|
|
417
|
+
$content .= "<div class='error'>The layout file does not contain <?php echo \$childContent; ?> or <?= \$childContent ?><br><strong>$layoutPath</strong></div>";
|
|
418
|
+
modifyOutputLayoutForError($content);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
341
421
|
} catch (Throwable $e) {
|
|
342
422
|
$content = ob_get_clean();
|
|
343
423
|
$content .= "<div class='error'>Unhandled Exception: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
|
package/dist/src/app/index.php
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="flex flex-col min-h-[100vh]">
|
|
2
2
|
<header class="px-4 lg:px-6 h-14 flex items-center">
|
|
3
|
-
<a class="flex items-center justify-center" href="
|
|
3
|
+
<a class="flex items-center justify-center" href="/">
|
|
4
4
|
<img class="h-10 w-10" src="<?= $baseUrl ?>assets/images/prisma-php.png" alt="Prisma PHP">
|
|
5
5
|
<span class="sr-only">Prisma PHP</span>
|
|
6
6
|
</a>
|