create-prisma-php-app 4.0.0-alpha.6 → 4.0.0-alpha.61
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/.htaccess +54 -41
- package/dist/bootstrap.php +150 -94
- package/dist/index.js +546 -131
- package/dist/settings/auto-swagger-docs.ts +196 -95
- package/dist/settings/bs-config.ts +53 -58
- package/dist/settings/class-log.ts +172 -70
- package/dist/settings/files-list.json +1 -1
- package/dist/settings/project-name.ts +2 -0
- package/dist/settings/restart-mcp.ts +58 -0
- package/dist/settings/restart-websocket.ts +44 -45
- package/dist/settings/utils.ts +240 -0
- package/dist/src/Lib/Auth/Auth.php +544 -0
- package/dist/src/Lib/Auth/AuthConfig.php +89 -0
- package/dist/src/Lib/MCP/WeatherTools.php +104 -0
- package/dist/src/Lib/MCP/mcp-server.php +80 -0
- package/dist/src/Lib/Middleware/AuthMiddleware.php +157 -0
- package/dist/src/Lib/Middleware/CorsMiddleware.php +130 -0
- package/dist/src/Lib/Websocket/ConnectionManager.php +1 -1
- package/dist/src/Lib/Websocket/websocket-server.php +106 -14
- package/dist/src/app/index.php +21 -4
- package/dist/src/app/js/index.js +1 -1
- package/package.json +1 -1
- package/dist/settings/restart-websocket.bat +0 -28
- package/dist/src/app/assets/images/prisma-php-black.svg +0 -6
- package/vendor/autoload.php +0 -25
- package/vendor/composer/ClassLoader.php +0 -579
- package/vendor/composer/InstalledVersions.php +0 -359
- package/vendor/composer/LICENSE +0 -21
- package/vendor/composer/autoload_classmap.php +0 -10
- package/vendor/composer/autoload_namespaces.php +0 -9
- package/vendor/composer/autoload_psr4.php +0 -10
- package/vendor/composer/autoload_real.php +0 -38
- package/vendor/composer/autoload_static.php +0 -25
- package/vendor/composer/installed.json +0 -825
- package/vendor/composer/installed.php +0 -132
- package/vendor/composer/platform_check.php +0 -26
package/dist/.htaccess
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
1
|
# Turn on rewrite engine
|
|
2
2
|
RewriteEngine On
|
|
3
3
|
|
|
4
|
-
#
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Block sensitive files (Apache 2.2 + 2.4 compatible)
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
5
7
|
<FilesMatch "(^\.htaccess|\.git|\.env|composer\.(json|lock)|package(-lock)?\.json|phpunit\.xml)$">
|
|
8
|
+
<IfModule mod_authz_core.c>
|
|
9
|
+
Require all denied
|
|
10
|
+
</IfModule>
|
|
11
|
+
<IfModule !mod_authz_core.c>
|
|
6
12
|
Order allow,deny
|
|
7
13
|
Deny from all
|
|
14
|
+
</IfModule>
|
|
8
15
|
</FilesMatch>
|
|
9
16
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
|
|
15
|
-
</IfModule>
|
|
17
|
+
# ------------------------------------------------------------------------------
|
|
18
|
+
# CORS: handled in PHP via Lib\Middleware\CorsMiddleware
|
|
19
|
+
# (Remove any Apache-level Access-Control-* headers to avoid conflicts)
|
|
20
|
+
# ------------------------------------------------------------------------------
|
|
16
21
|
|
|
17
|
-
#
|
|
22
|
+
# ------------------------------------------------------------------------------
|
|
23
|
+
# Content-Type with charset UTF-8 for HTML, CSS, and JS files
|
|
24
|
+
# ------------------------------------------------------------------------------
|
|
18
25
|
<IfModule mod_headers.c>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Header set Content-Type "application/javascript; charset=UTF-8"
|
|
32
|
-
</FilesMatch>
|
|
26
|
+
# HTML
|
|
27
|
+
<FilesMatch "\.(html|htm)$">
|
|
28
|
+
Header set Content-Type "text/html; charset=UTF-8"
|
|
29
|
+
</FilesMatch>
|
|
30
|
+
# CSS
|
|
31
|
+
<FilesMatch "\.(css)$">
|
|
32
|
+
Header set Content-Type "text/css; charset=UTF-8"
|
|
33
|
+
</FilesMatch>
|
|
34
|
+
# JS
|
|
35
|
+
<FilesMatch "\.(js)$">
|
|
36
|
+
Header set Content-Type "application/javascript; charset=UTF-8"
|
|
37
|
+
</FilesMatch>
|
|
33
38
|
</IfModule>
|
|
34
39
|
|
|
35
|
-
#
|
|
40
|
+
# ------------------------------------------------------------------------------
|
|
41
|
+
# Content Security Policy
|
|
42
|
+
# ------------------------------------------------------------------------------
|
|
36
43
|
<IfModule mod_headers.c>
|
|
37
44
|
Header set Content-Security-Policy "\
|
|
38
45
|
default-src 'self' https:; \
|
|
@@ -44,32 +51,38 @@ RewriteEngine On
|
|
|
44
51
|
object-src 'none';"
|
|
45
52
|
</IfModule>
|
|
46
53
|
|
|
47
|
-
#
|
|
54
|
+
# ------------------------------------------------------------------------------
|
|
55
|
+
# Security headers
|
|
56
|
+
# ------------------------------------------------------------------------------
|
|
48
57
|
<IfModule mod_headers.c>
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
# HSTS (only meaningful over HTTPS)
|
|
59
|
+
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
# XSS Protection (legacy but harmless)
|
|
62
|
+
Header set X-XSS-Protection "1; mode=block"
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
# Prevent MIME-type sniffing
|
|
65
|
+
Header set X-Content-Type-Options "nosniff"
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
# Clickjacking protection
|
|
68
|
+
Header always set X-Frame-Options "DENY"
|
|
60
69
|
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
# Referrer Policy
|
|
71
|
+
Header set Referrer-Policy "strict-origin-when-cross-origin"
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
# Permissions Policy (tune as needed)
|
|
74
|
+
Header set Permissions-Policy "geolocation=(), microphone=(), camera=(), autoplay=()"
|
|
66
75
|
</IfModule>
|
|
67
76
|
|
|
68
|
-
#
|
|
77
|
+
# ------------------------------------------------------------------------------
|
|
78
|
+
# Preflight: route all OPTIONS to bootstrap so CorsMiddleware can reply 204
|
|
79
|
+
# ------------------------------------------------------------------------------
|
|
80
|
+
RewriteCond %{REQUEST_METHOD} =OPTIONS
|
|
81
|
+
RewriteRule ^ bootstrap.php [QSA,L]
|
|
82
|
+
|
|
83
|
+
# ------------------------------------------------------------------------------
|
|
84
|
+
# Front controller: exclude static files, everything else -> bootstrap.php
|
|
85
|
+
# ------------------------------------------------------------------------------
|
|
69
86
|
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpe?g|gif|svg|webp|woff2?|ttf|eot|ico|pdf|mp4|webm|mp3|ogg)$ [NC]
|
|
70
87
|
RewriteCond %{REQUEST_URI} !^/bootstrap.php
|
|
71
88
|
RewriteRule ^(.*)$ bootstrap.php [QSA,L]
|
|
72
|
-
|
|
73
|
-
# Ensure OPTIONS requests are handled correctly
|
|
74
|
-
RewriteCond %{REQUEST_METHOD} OPTIONS
|
|
75
|
-
RewriteRule ^ - [R=200,L]
|
package/dist/bootstrap.php
CHANGED
|
@@ -2,19 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
declare(strict_types=1);
|
|
4
4
|
|
|
5
|
-
if (session_status() === PHP_SESSION_NONE) {
|
|
6
|
-
session_start();
|
|
7
|
-
}
|
|
8
|
-
|
|
9
5
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
10
6
|
require_once __DIR__ . '/settings/paths.php';
|
|
11
7
|
|
|
12
8
|
use Dotenv\Dotenv;
|
|
9
|
+
use Lib\Middleware\CorsMiddleware;
|
|
10
|
+
|
|
11
|
+
// Load environment variables
|
|
12
|
+
Dotenv::createImmutable(DOCUMENT_PATH)->load();
|
|
13
|
+
|
|
14
|
+
// CORS must run before sessions/any output
|
|
15
|
+
CorsMiddleware::handle();
|
|
16
|
+
|
|
17
|
+
if (session_status() === PHP_SESSION_NONE) {
|
|
18
|
+
session_start();
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
use PPHP\Request;
|
|
14
22
|
use PPHP\PrismaPHPSettings;
|
|
15
23
|
use PPHP\StateManager;
|
|
16
|
-
use
|
|
17
|
-
use
|
|
24
|
+
use Lib\Middleware\AuthMiddleware;
|
|
25
|
+
use Lib\Auth\Auth;
|
|
18
26
|
use PPHP\MainLayout;
|
|
19
27
|
use PPHP\PHPX\TemplateCompiler;
|
|
20
28
|
use PPHP\CacheHandler;
|
|
@@ -56,9 +64,6 @@ final class Bootstrap extends RuntimeException
|
|
|
56
64
|
|
|
57
65
|
public static function run(): void
|
|
58
66
|
{
|
|
59
|
-
// Load environment variables
|
|
60
|
-
Dotenv::createImmutable(DOCUMENT_PATH)->load();
|
|
61
|
-
|
|
62
67
|
// Set timezone
|
|
63
68
|
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'UTC');
|
|
64
69
|
|
|
@@ -84,6 +89,13 @@ final class Bootstrap extends RuntimeException
|
|
|
84
89
|
// Set a function call key as a cookie
|
|
85
90
|
self::functionCallNameEncrypt();
|
|
86
91
|
|
|
92
|
+
self::$secondRequestC69CD = Request::$data['secondRequestC69CD'] ?? false;
|
|
93
|
+
|
|
94
|
+
// Check if the request is for a local store callback
|
|
95
|
+
if (Request::$isWire && !self::$secondRequestC69CD) {
|
|
96
|
+
self::isLocalStoreCallback();
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
$contentInfo = self::determineContentToInclude();
|
|
88
100
|
self::$contentToInclude = $contentInfo['path'] ?? '';
|
|
89
101
|
self::$layoutsToInclude = $contentInfo['layouts'] ?? [];
|
|
@@ -114,7 +126,6 @@ final class Bootstrap extends RuntimeException
|
|
|
114
126
|
self::$isContentIncluded = true;
|
|
115
127
|
}
|
|
116
128
|
|
|
117
|
-
self::$secondRequestC69CD = Request::$data['secondRequestC69CD'] ?? false;
|
|
118
129
|
self::$isPartialRequest =
|
|
119
130
|
!empty(Request::$data['pphpSync71163'])
|
|
120
131
|
&& !empty(Request::$data['selectors'])
|
|
@@ -128,6 +139,31 @@ final class Bootstrap extends RuntimeException
|
|
|
128
139
|
ErrorHandler::checkFatalError();
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
private static function isLocalStoreCallback(): void
|
|
143
|
+
{
|
|
144
|
+
$data = self::getRequestData();
|
|
145
|
+
|
|
146
|
+
if (empty($data['callback'])) {
|
|
147
|
+
self::jsonExit(['success' => false, 'error' => 'Callback not provided', 'response' => null]);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
$aesKey = self::getAesKeyFromJwt();
|
|
152
|
+
} catch (RuntimeException $e) {
|
|
153
|
+
self::jsonExit(['success' => false, 'error' => $e->getMessage()]);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
$callbackName = self::decryptCallback($data['callback'], $aesKey);
|
|
158
|
+
} catch (RuntimeException $e) {
|
|
159
|
+
self::jsonExit(['success' => false, 'error' => $e->getMessage()]);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if ($callbackName === PrismaPHPSettings::$localStoreKey) {
|
|
163
|
+
self::jsonExit(['success' => true, 'response' => 'localStorage updated']);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
131
167
|
private static function functionCallNameEncrypt(): void
|
|
132
168
|
{
|
|
133
169
|
$hmacSecret = $_ENV['FUNCTION_CALL_SECRET'] ?? '';
|
|
@@ -588,108 +624,117 @@ final class Bootstrap extends RuntimeException
|
|
|
588
624
|
|
|
589
625
|
public static function wireCallback(): void
|
|
590
626
|
{
|
|
591
|
-
$
|
|
592
|
-
'success' => false,
|
|
593
|
-
'error' => 'Callback not provided',
|
|
594
|
-
'response' => null,
|
|
595
|
-
];
|
|
627
|
+
$data = self::getRequestData();
|
|
596
628
|
|
|
597
|
-
if (
|
|
598
|
-
|
|
599
|
-
foreach ($_FILES as $key => $file) {
|
|
600
|
-
if (is_array($file['name'])) {
|
|
601
|
-
$files = [];
|
|
602
|
-
foreach ($file['name'] as $i => $name) {
|
|
603
|
-
$files[] = [
|
|
604
|
-
'name' => $name,
|
|
605
|
-
'type' => $file['type'][$i],
|
|
606
|
-
'tmp_name' => $file['tmp_name'][$i],
|
|
607
|
-
'error' => $file['error'][$i],
|
|
608
|
-
'size' => $file['size'][$i],
|
|
609
|
-
];
|
|
610
|
-
}
|
|
611
|
-
$data[$key] = $files;
|
|
612
|
-
} else {
|
|
613
|
-
$data[$key] = $file;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
} else {
|
|
617
|
-
$raw = file_get_contents('php://input');
|
|
618
|
-
$data = json_decode($raw, true);
|
|
619
|
-
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
620
|
-
$data = $_POST;
|
|
621
|
-
}
|
|
629
|
+
if (empty($data['callback'])) {
|
|
630
|
+
self::jsonExit(['success' => false, 'error' => 'Callback not provided', 'response' => null]);
|
|
622
631
|
}
|
|
623
632
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
633
|
+
try {
|
|
634
|
+
$aesKey = self::getAesKeyFromJwt();
|
|
635
|
+
} catch (RuntimeException $e) {
|
|
636
|
+
self::jsonExit(['success' => false, 'error' => $e->getMessage()]);
|
|
627
637
|
}
|
|
628
638
|
|
|
639
|
+
try {
|
|
640
|
+
$callbackName = self::decryptCallback($data['callback'], $aesKey);
|
|
641
|
+
} catch (RuntimeException $e) {
|
|
642
|
+
self::jsonExit(['success' => false, 'error' => $e->getMessage()]);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
$args = self::convertToArrayObject($data);
|
|
646
|
+
$out = str_contains($callbackName, '->') || str_contains($callbackName, '::')
|
|
647
|
+
? self::dispatchMethod($callbackName, $args)
|
|
648
|
+
: self::dispatchFunction($callbackName, $args);
|
|
649
|
+
|
|
650
|
+
if ($out !== null) {
|
|
651
|
+
self::jsonExit($out);
|
|
652
|
+
}
|
|
653
|
+
exit;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
private static function getAesKeyFromJwt(): string
|
|
657
|
+
{
|
|
629
658
|
$token = $_COOKIE['pphp_function_call_jwt'] ?? null;
|
|
630
659
|
$jwtSecret = $_ENV['FUNCTION_CALL_SECRET'] ?? null;
|
|
660
|
+
|
|
631
661
|
if (!$token || !$jwtSecret) {
|
|
632
|
-
|
|
633
|
-
exit;
|
|
662
|
+
throw new RuntimeException('Missing session key or secret');
|
|
634
663
|
}
|
|
664
|
+
|
|
635
665
|
try {
|
|
636
666
|
$decoded = JWT::decode($token, new Key($jwtSecret, 'HS256'));
|
|
637
667
|
} catch (Throwable) {
|
|
638
|
-
|
|
639
|
-
exit;
|
|
668
|
+
throw new RuntimeException('Invalid session key');
|
|
640
669
|
}
|
|
670
|
+
|
|
641
671
|
$aesKey = base64_decode($decoded->k, true);
|
|
642
672
|
if ($aesKey === false || strlen($aesKey) !== 32) {
|
|
643
|
-
|
|
644
|
-
exit;
|
|
673
|
+
throw new RuntimeException('Bad key length');
|
|
645
674
|
}
|
|
646
675
|
|
|
647
|
-
|
|
676
|
+
return $aesKey;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
private static function jsonExit(array $payload): void
|
|
680
|
+
{
|
|
681
|
+
echo json_encode($payload, JSON_UNESCAPED_UNICODE);
|
|
682
|
+
exit;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
private static function decryptCallback(string $encrypted, string $aesKey): string
|
|
686
|
+
{
|
|
687
|
+
$parts = explode(':', $encrypted, 2);
|
|
648
688
|
if (count($parts) !== 2) {
|
|
649
|
-
|
|
650
|
-
exit;
|
|
689
|
+
throw new RuntimeException('Malformed callback payload');
|
|
651
690
|
}
|
|
652
|
-
[$
|
|
653
|
-
|
|
654
|
-
$
|
|
691
|
+
[$ivB64, $ctB64] = $parts;
|
|
692
|
+
|
|
693
|
+
$iv = base64_decode($ivB64, true);
|
|
694
|
+
$ct = base64_decode($ctB64, true);
|
|
695
|
+
|
|
655
696
|
if ($iv === false || strlen($iv) !== 16 || $ct === false) {
|
|
656
|
-
|
|
657
|
-
exit;
|
|
697
|
+
throw new RuntimeException('Invalid callback payload');
|
|
658
698
|
}
|
|
699
|
+
|
|
659
700
|
$plain = openssl_decrypt($ct, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
|
|
660
701
|
if ($plain === false) {
|
|
661
|
-
|
|
662
|
-
exit;
|
|
702
|
+
throw new RuntimeException('Decryption failed');
|
|
663
703
|
}
|
|
664
704
|
|
|
665
|
-
$
|
|
666
|
-
if ($
|
|
667
|
-
|
|
668
|
-
exit;
|
|
705
|
+
$callback = preg_replace('/[^a-zA-Z0-9_:\->]/', '', $plain);
|
|
706
|
+
if ($callback === '' || $callback[0] === '_') {
|
|
707
|
+
throw new RuntimeException('Invalid callback');
|
|
669
708
|
}
|
|
670
709
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
$callbackName === PrismaPHPSettings::$localStoreKey
|
|
674
|
-
) {
|
|
675
|
-
echo json_encode([
|
|
676
|
-
'success' => true,
|
|
677
|
-
'response' => 'localStorage updated',
|
|
678
|
-
], JSON_UNESCAPED_UNICODE);
|
|
679
|
-
exit;
|
|
680
|
-
}
|
|
710
|
+
return $callback;
|
|
711
|
+
}
|
|
681
712
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
$
|
|
713
|
+
private static function getRequestData(): array
|
|
714
|
+
{
|
|
715
|
+
if (!empty($_FILES)) {
|
|
716
|
+
$data = $_POST;
|
|
717
|
+
foreach ($_FILES as $key => $file) {
|
|
718
|
+
$data[$key] = is_array($file['name'])
|
|
719
|
+
? array_map(
|
|
720
|
+
fn($i) => [
|
|
721
|
+
'name' => $file['name'][$i],
|
|
722
|
+
'type' => $file['type'][$i],
|
|
723
|
+
'tmp_name' => $file['tmp_name'][$i],
|
|
724
|
+
'error' => $file['error'][$i],
|
|
725
|
+
'size' => $file['size'][$i],
|
|
726
|
+
],
|
|
727
|
+
array_keys($file['name'])
|
|
728
|
+
)
|
|
729
|
+
: $file;
|
|
730
|
+
}
|
|
731
|
+
return $data;
|
|
687
732
|
}
|
|
688
733
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
734
|
+
$raw = file_get_contents('php://input');
|
|
735
|
+
$json = json_decode($raw, true);
|
|
736
|
+
|
|
737
|
+
return (json_last_error() === JSON_ERROR_NONE) ? $json : $_POST;
|
|
693
738
|
}
|
|
694
739
|
|
|
695
740
|
private static function dispatchFunction(string $fn, mixed $args)
|
|
@@ -702,7 +747,11 @@ final class Bootstrap extends RuntimeException
|
|
|
702
747
|
}
|
|
703
748
|
return $res;
|
|
704
749
|
} catch (Throwable $e) {
|
|
705
|
-
|
|
750
|
+
if (isset($_ENV['SHOW_ERRORS']) && $_ENV['SHOW_ERRORS'] === 'false') {
|
|
751
|
+
return ['success' => false, 'error' => 'An error occurred. Please try again later.'];
|
|
752
|
+
} else {
|
|
753
|
+
return ['success' => false, 'error' => "Function error: {$e->getMessage()}"];
|
|
754
|
+
}
|
|
706
755
|
}
|
|
707
756
|
}
|
|
708
757
|
return ['success' => false, 'error' => 'Invalid callback'];
|
|
@@ -739,10 +788,13 @@ final class Bootstrap extends RuntimeException
|
|
|
739
788
|
if ($res !== null) {
|
|
740
789
|
return ['success' => true, 'error' => null, 'response' => $res];
|
|
741
790
|
}
|
|
742
|
-
|
|
743
791
|
return $res;
|
|
744
792
|
} catch (Throwable $e) {
|
|
745
|
-
|
|
793
|
+
if (isset($_ENV['SHOW_ERRORS']) && $_ENV['SHOW_ERRORS'] === 'false') {
|
|
794
|
+
return ['success' => false, 'error' => 'An error occurred. Please try again later.'];
|
|
795
|
+
} else {
|
|
796
|
+
return ['success' => false, 'error' => "Instance call error: {$e->getMessage()}"];
|
|
797
|
+
}
|
|
746
798
|
}
|
|
747
799
|
} else {
|
|
748
800
|
if (!class_exists($class) || !is_callable([$class, $method])) {
|
|
@@ -755,7 +807,11 @@ final class Bootstrap extends RuntimeException
|
|
|
755
807
|
}
|
|
756
808
|
return $res;
|
|
757
809
|
} catch (Throwable $e) {
|
|
758
|
-
|
|
810
|
+
if (isset($_ENV['SHOW_ERRORS']) && $_ENV['SHOW_ERRORS'] === 'false') {
|
|
811
|
+
return ['success' => false, 'error' => 'An error occurred. Please try again later.'];
|
|
812
|
+
} else {
|
|
813
|
+
return ['success' => false, 'error' => "Static call error: {$e->getMessage()}"];
|
|
814
|
+
}
|
|
759
815
|
}
|
|
760
816
|
}
|
|
761
817
|
|
|
@@ -993,13 +1049,6 @@ try {
|
|
|
993
1049
|
Bootstrap::createUpdateRequestData();
|
|
994
1050
|
}
|
|
995
1051
|
|
|
996
|
-
// If there’s caching
|
|
997
|
-
if (isset(Bootstrap::$requestFilesData[Request::$decodedUri])) {
|
|
998
|
-
if ($_ENV['CACHE_ENABLED'] === 'true') {
|
|
999
|
-
CacheHandler::serveCache(Request::$decodedUri, intval($_ENV['CACHE_TTL']));
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
1052
|
// For wire calls, re-include the files if needed
|
|
1004
1053
|
if (Request::$isWire && !Bootstrap::$secondRequestC69CD) {
|
|
1005
1054
|
if (isset(Bootstrap::$requestFilesData[Request::$decodedUri])) {
|
|
@@ -1019,6 +1068,13 @@ try {
|
|
|
1019
1068
|
Bootstrap::wireCallback();
|
|
1020
1069
|
}
|
|
1021
1070
|
|
|
1071
|
+
// If there’s caching
|
|
1072
|
+
if ((!Request::$isWire && !Bootstrap::$secondRequestC69CD) && isset(Bootstrap::$requestFilesData[Request::$decodedUri])) {
|
|
1073
|
+
if ($_ENV['CACHE_ENABLED'] === 'true') {
|
|
1074
|
+
CacheHandler::serveCache(Request::$decodedUri, intval($_ENV['CACHE_TTL']));
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1022
1078
|
MainLayout::$children = MainLayout::$childLayoutChildren . Bootstrap::getLoadingsFiles();
|
|
1023
1079
|
|
|
1024
1080
|
ob_start();
|
|
@@ -1029,7 +1085,7 @@ try {
|
|
|
1029
1085
|
MainLayout::$html = "<!DOCTYPE html>\n" . MainLayout::$html;
|
|
1030
1086
|
|
|
1031
1087
|
if (
|
|
1032
|
-
http_response_code() === 200 && isset(Bootstrap::$requestFilesData[Request::$decodedUri]['fileName']) && $_ENV['CACHE_ENABLED'] === 'true'
|
|
1088
|
+
http_response_code() === 200 && isset(Bootstrap::$requestFilesData[Request::$decodedUri]['fileName']) && $_ENV['CACHE_ENABLED'] === 'true' && (!Request::$isWire && !Bootstrap::$secondRequestC69CD)
|
|
1033
1089
|
) {
|
|
1034
1090
|
CacheHandler::saveCache(Request::$decodedUri, MainLayout::$html);
|
|
1035
1091
|
}
|