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.
@@ -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
- $routes = json_decode(file_get_contents(SETTINGS_PATH . "/files-list.json"), true);
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 ($routes as $route) {
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 redirect(string $url): void
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
- header("Location: $url");
217
- exit;
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
- $pattern = '/<\?(?:php)?[^?]*\$childContent[^?]*\?>/is';
254
-
255
- if (preg_match($pattern, $fileContent)) {
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
- $pattern = '/<\?(?:php\s+)?(?:=|echo|print)\s*\$content\s*;?\s*\?>/i';
266
- if (preg_match($pattern, $fileContent)) {
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
- if (!containsContent($parentLayoutPath)) {
304
- $content .= "<div class='error'>The parent layout file does not contain &lt;?php echo \$content ?&gt; Or &lt;?= \$content ?&gt;<br>" . "<strong>$parentLayoutPath</strong></div>";
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
- ob_start();
316
- if ($parentLayoutPath === $layoutPath) continue;
384
+ if ($parentLayoutPath === $layoutPath) {
385
+ continue;
386
+ }
387
+
317
388
  if (containsChildContent($layoutPath)) {
318
- require_once $layoutPath;
319
- } else {
320
- $content .= "<div class='error'>The layout file does not contain &lt;?php echo \$childContent ?&gt; Or &lt;?= \$childContent ?&gt<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
- $content .= $childContent;
337
-
338
- ob_start();
339
- require_once APP_PATH . '/layout.php';
340
- echo ob_get_clean();
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 &lt;?php echo \$content; ?&gt; Or &lt;?= \$content ?&gt;<br>" . "<strong>$parentLayoutPath</strong></div>";
415
+ modifyOutputLayoutForError($content);
416
+ } else {
417
+ $content .= "<div class='error'>The layout file does not contain &lt;?php echo \$childContent; ?&gt; or &lt;?= \$childContent ?&gt;<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>";
@@ -0,0 +1,7 @@
1
+ <?php
2
+
3
+ function redirect(string $url): void
4
+ {
5
+ header("Location: $url");
6
+ exit;
7
+ }
@@ -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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma-php-app",
3
- "version": "1.11.9",
3
+ "version": "1.11.11",
4
4
  "description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",