create-prisma-php-app 1.9.15 → 1.9.17

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/composer.json CHANGED
@@ -17,6 +17,7 @@
17
17
  "php": "^8.1",
18
18
  "vlucas/phpdotenv": "^5.6@dev",
19
19
  "firebase/php-jwt": "dev-main",
20
- "phpmailer/phpmailer": "^6.9"
20
+ "phpmailer/phpmailer": "^6.9",
21
+ "psr/log": "^3.0"
21
22
  }
22
23
  }
package/dist/.htaccess CHANGED
@@ -14,16 +14,11 @@ RewriteEngine On
14
14
  Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
15
15
  </IfModule>
16
16
 
17
- # Exclude OPTIONS method from being redirected
18
- RewriteCond %{REQUEST_METHOD} !OPTIONS
19
-
20
- # Redirect all AJAX requests to bootstrap-ajax.php
21
- RewriteCond %{HTTP:X-Requested-With} ^XMLHttpRequest$
22
- RewriteRule ^(.*)$ bootstrap-ajax.php [L,QSA]
23
-
24
- # Redirect all non-file and non-directory requests not starting with src/app/ to src/app/layout.php
25
- RewriteRule !^src/app/ src/app/layout.php [QSA,L]
17
+ # Exclude static files from being redirected
18
+ RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico|pdf)$ [NC]
19
+ RewriteCond %{REQUEST_URI} !^/bootstrap.php
20
+ RewriteRule ^(.*)$ bootstrap.php [QSA,L]
26
21
 
27
22
  # Add this to ensure OPTIONS requests are handled correctly
28
23
  RewriteCond %{REQUEST_METHOD} OPTIONS
29
- RewriteRule ^(.*)$ $1 [R=200,L]
24
+ RewriteRule ^ - [R=200,L]
@@ -7,24 +7,25 @@ if (session_status() == PHP_SESSION_NONE) {
7
7
  require_once __DIR__ . '/settings/paths.php';
8
8
  require_once __DIR__ . '/vendor/autoload.php';
9
9
 
10
- $metadata = require_once __DIR__ . '/src/app/metadata.php';
10
+ use Lib\Middleware\AuthMiddleware;
11
+ use Dotenv\Dotenv;
12
+
13
+ $dotenv = Dotenv::createImmutable(\DOCUMENT_PATH);
14
+ $dotenv->load();
11
15
 
12
16
  function determineContentToInclude()
13
17
  {
14
- global $metadata;
15
-
16
18
  $subject = $_SERVER["SCRIPT_NAME"];
17
- preg_match("/^(.*)\/src\/app\//", $subject, $matches);
18
-
19
+ $dirname = dirname($subject);
19
20
  $requestUri = explode('?', $_SERVER['REQUEST_URI'], 2)[0];
20
21
  $requestUri = rtrim($requestUri, '/');
21
- $requestUri = str_replace($matches[1], '', $requestUri);
22
+ $requestUri = str_replace($dirname, '', $requestUri);
22
23
  $uri = trim($requestUri, '/');
23
- $baseDir = __DIR__ . '/src/app';
24
+ $baseDir = APP_PATH;
24
25
  $includePath = '';
25
26
  $layoutsToInclude = [];
26
- $metadata = $metadata[$uri] ?? $metadata['default'];
27
27
  writeRoutes();
28
+ AuthMiddleware::handle($uri);
28
29
 
29
30
  $isDirectAccessToPrivateRoute = preg_match('/^_/', $uri);
30
31
  if ($isDirectAccessToPrivateRoute) {
@@ -34,7 +35,7 @@ function determineContentToInclude()
34
35
  if ($uri) {
35
36
  $groupFolder = findGroupFolder($uri);
36
37
  if ($groupFolder) {
37
- $path = $baseDir . $groupFolder;
38
+ $path = __DIR__ . $groupFolder;
38
39
  if (file_exists($path)) {
39
40
  $includePath = $path;
40
41
  }
@@ -44,7 +45,7 @@ function determineContentToInclude()
44
45
  $getGroupFolder = getGroupFolder($groupFolder);
45
46
  $modifiedUri = $uri;
46
47
  if (!empty($getGroupFolder)) {
47
- $modifiedUri = $getGroupFolder;
48
+ $modifiedUri = trim($getGroupFolder, "/src/app/");
48
49
  }
49
50
 
50
51
  foreach (explode('/', $modifiedUri) as $segment) {
@@ -98,7 +99,7 @@ function checkForDuplicateRoutes()
98
99
 
99
100
  function writeRoutes()
100
101
  {
101
- $directory = './';
102
+ $directory = './src/app';
102
103
 
103
104
  if (is_dir($directory)) {
104
105
  $filesList = [];
@@ -146,14 +147,18 @@ function matchGroupFolder($constructedPath): ?string
146
147
  $routes = json_decode(file_get_contents(SETTINGS_PATH . "/files-list.json"), true);
147
148
  $bestMatch = null;
148
149
  $normalizedConstructedPath = ltrim(str_replace('\\', '/', $constructedPath), './');
149
- $normalizedConstructedPath = "/$normalizedConstructedPath/index.php";
150
+
151
+ $routeFile = "/src/app/$normalizedConstructedPath/route.php";
152
+ $indexFile = "/src/app/$normalizedConstructedPath/index.php";
150
153
 
151
154
  foreach ($routes as $route) {
152
155
  $normalizedRoute = trim(str_replace('\\', '/', $route), '.');
153
156
  $cleanedRoute = preg_replace('/\/\([^)]+\)/', '', $normalizedRoute);
154
- if ($cleanedRoute === $normalizedConstructedPath) {
157
+ if ($cleanedRoute === $routeFile) {
155
158
  $bestMatch = $normalizedRoute;
156
159
  break;
160
+ } elseif ($cleanedRoute === $indexFile && !$bestMatch) {
161
+ $bestMatch = $normalizedRoute;
157
162
  }
158
163
  }
159
164
 
@@ -172,66 +177,134 @@ function getGroupFolder($uri): string
172
177
  return "";
173
178
  }
174
179
 
175
- $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
176
- $domainName = $_SERVER['HTTP_HOST'];
177
- $scriptPath = dirname($_SERVER['SCRIPT_NAME']) . '/';
178
- $baseUrl = $protocol . $domainName . rtrim($scriptPath, '/') . '/';
179
- $pathname = "";
180
+ function redirect(string $url): void
181
+ {
182
+ header("Location: $url");
183
+ exit;
184
+ }
185
+
186
+ function setupErrorHandling(&$content)
187
+ {
188
+ set_error_handler(function ($severity, $message, $file, $line) use (&$content) {
189
+ $content .= "<div class='error'>Error: {$severity} - {$message} in {$file} on line {$line}</div>";
190
+ });
191
+
192
+ set_exception_handler(function ($exception) use (&$content) {
193
+ $content .= "<div class='error'>Exception: " . htmlspecialchars($exception->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
194
+ });
195
+
196
+ register_shutdown_function(function () use (&$content) {
197
+ $error = error_get_last();
198
+ if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_RECOVERABLE_ERROR])) {
199
+ $formattedError = "<div class='error'>Fatal Error: " . htmlspecialchars($error['message'], ENT_QUOTES, 'UTF-8') .
200
+ " in " . htmlspecialchars($error['file'], ENT_QUOTES, 'UTF-8') .
201
+ " on line " . $error['line'] . "</div>";
202
+ $content .= $formattedError;
203
+ modifyOutputLayoutForError($content);
204
+ }
205
+ });
206
+ }
180
207
 
181
208
  ob_start();
209
+ require_once SETTINGS_PATH . '/request-methods.php';
210
+ $metadataArray = require_once APP_PATH . '/metadata.php';
211
+ $metadata = "";
212
+ $pathname = "";
213
+ $content = "";
214
+ $childContent = "";
215
+
216
+ function containsChildContent($filePath)
217
+ {
218
+ $fileContent = file_get_contents($filePath);
219
+ $pattern = '/<\?(?:php)?[^?]*\$childContent[^?]*\?>/is';
220
+
221
+ if (preg_match($pattern, $fileContent)) {
222
+ return true;
223
+ } else {
224
+ return false;
225
+ }
226
+ }
227
+
228
+ function containsContent($filePath)
229
+ {
230
+ $fileContent = file_get_contents($filePath);
231
+ $pattern = '/<\?(?:php\s+)?(?:=|echo|print)\s*\$content\s*;?\s*\?>/i';
232
+ if (preg_match($pattern, $fileContent)) {
233
+ return true;
234
+ } else {
235
+ return false;
236
+ }
237
+ }
182
238
 
183
- set_error_handler(function ($severity, $message, $file, $line) use (&$content) {
184
- echo "<div class='error'>An error occurred: $severity - $message in $file on line $line</div>";
185
- $content .= ob_get_clean();
186
- });
239
+ function modifyOutputLayoutForError($contentToAdd)
240
+ {
241
+ $layoutContent = file_get_contents(APP_PATH . '/layout.php');
242
+ if ($layoutContent !== false) {
243
+ $newBodyContent = "<body class=\"fatal-error\">$contentToAdd</body>";
187
244
 
188
- set_exception_handler(function ($exception) use (&$content) {
189
- echo "<div class='error'>An error occurred: " . htmlspecialchars($exception->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
190
- $content .= ob_get_clean();
191
- });
245
+ $modifiedNotFoundContent = preg_replace('~<body.*?>.*?</body>~s', $newBodyContent, $layoutContent);
192
246
 
193
- register_shutdown_function(function () use (&$content) {
194
- $error = error_get_last();
195
- if ($error && ($error['type'] === E_ERROR || $error['type'] === E_PARSE || $error['type'] === E_CORE_ERROR || $error['type'] === E_COMPILE_ERROR)) {
196
- echo "<div class='error'>An error occurred: " . $error['message'] . "</div>";
197
- $content .= ob_get_clean();
247
+ echo $modifiedNotFoundContent;
248
+ exit;
198
249
  }
199
- });
250
+ }
200
251
 
201
252
  try {
202
253
  $result = determineContentToInclude();
203
254
  checkForDuplicateRoutes();
204
255
  $contentToInclude = $result['path'] ?? '';
205
256
  $layoutsToInclude = $result['layouts'] ?? [];
206
- $pathname = $result['uri'] ? "/" . $result['uri'] : "/";
207
- if (!empty($layoutsToInclude))
208
- $isParentLayout = strpos($layoutsToInclude[0], 'src/app/layout.php') !== false;
209
- else
210
- $isParentLayout = false;
257
+ $uri = $result['uri'] ?? '';
258
+ $pathname = $uri ? "/" . $uri : "/";
259
+ $metadata = $metadataArray[$uri] ?? $metadataArray['default'];
260
+ if (!empty($contentToInclude) && basename($contentToInclude) === 'route.php') {
261
+ require_once SETTINGS_PATH . '/route-request.php';
262
+ require_once $contentToInclude;
263
+ exit;
264
+ }
265
+
266
+ $parentLayoutPath = APP_PATH . '/layout.php';
267
+ $isParentLayout = !empty($layoutsToInclude) && strpos($layoutsToInclude[0], 'src/app/layout.php') !== false;
268
+
269
+ if (!containsContent($parentLayoutPath)) {
270
+ $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>";
271
+ }
211
272
 
212
273
  ob_start();
213
274
  if (!empty($contentToInclude)) {
214
275
  if (!$isParentLayout) {
276
+ ob_start();
215
277
  require_once $contentToInclude;
278
+ $childContent = ob_get_clean();
216
279
  }
217
- $childContent = ob_get_clean();
218
- for ($i = count($layoutsToInclude) - 1; $i >= 0; $i--) {
219
- $layoutPath = $layoutsToInclude[$i];
280
+ foreach (array_reverse($layoutsToInclude) as $layoutPath) {
220
281
  ob_start();
221
- require_once $layoutPath;
282
+ if ($parentLayoutPath === $layoutPath) continue;
283
+ if (containsChildContent($layoutPath)) {
284
+ require_once $layoutPath;
285
+ } else {
286
+ $content .= "<div class='error'>The layout file does not contain &lt;?php echo \$childContent ?&gt; Or &lt;?= \$childContent ?&gt<br>" . "<strong>$layoutPath</strong></div>";
287
+ }
222
288
  $childContent = ob_get_clean();
223
289
  }
224
-
225
- if ($isParentLayout) {
226
- require_once $contentToInclude;
227
- }
228
- $content = $childContent;
229
290
  } else {
230
- require_once 'not-found.php';
231
- $notFound = ob_get_clean();
291
+ ob_start();
292
+ require_once APP_PATH . '/not-found.php';
293
+ $childContent = ob_get_clean();
232
294
  }
233
- $content .= ob_get_clean();
295
+
296
+ if ($isParentLayout && !empty($contentToInclude)) {
297
+ ob_start();
298
+ require_once $contentToInclude;
299
+ $childContent = ob_get_clean();
300
+ }
301
+
302
+ $content .= $childContent;
303
+
304
+ ob_start();
305
+ require_once APP_PATH . '/layout.php';
306
+ echo ob_get_clean();
234
307
  } catch (Throwable $e) {
235
- echo "<div class='error'>An error occurred: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
236
- $content .= ob_get_clean();
308
+ $content .= "<div class='error'>Unhandled Exception: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
309
+ modifyOutputLayoutForError($content);
237
310
  }