33
44use GT \Config \Config ;
55use GT \Config \ConfigFactory ;
6- use GT \Http \Request ;
76use GT \Http \Response ;
87use Gt \Http \ServerRequest ;
98use GT \Http \Stream ;
@@ -33,11 +32,19 @@ class Application {
3332 private Dispatcher $ dispatcher ;
3433 private bool $ finished = false ;
3534
35+ /**
36+ * @param null|array<string, array<string, string>> $globals
37+ * @SuppressWarnings("PHPMD.Superglobals")
38+ */
3639 public function __construct (
3740 ?Redirect $ redirect = null ,
41+ ?Config $ config = null ,
42+ ?array $ globals = null ,
3843 ) {
39- $ this ->config = $ this ->loadConfig ();
44+ $ this ->gtCompatibility ();
45+ $ this ->config = $ config ?? $ this ->loadConfig ();
4046 $ this ->redirect = $ redirect ?? new Redirect ();
47+ $ this ->globals = $ globals ?? $ GLOBALS ;
4148 register_shutdown_function ($ this ->handleShutdown (...));
4249 }
4350
@@ -61,7 +68,7 @@ public function start():void {
6168// PHP.GT provides object-oriented interfaces to all values stored in $_SERVER,
6269// $_FILES, $_GET, and $_POST - to enforce good encapsulation and safe variable
6370// usage, the globals are protected against accidental misuse.
64- $ this ->globals = $ this -> protectGlobals ();
71+ $ this ->protectGlobals ();
6572
6673 $ requestFactory = new RequestFactory ();
6774
@@ -73,7 +80,14 @@ public function start():void {
7380 $ this ->globals ["post " ],
7481 );
7582
76- $ this ->dispatcher = new Dispatcher ($ request );
83+ $ this ->dispatcher = new Dispatcher (
84+ $ this ->config ,
85+ $ request ,
86+ $ this ->globals ["get " ],
87+ $ this ->globals ["post " ],
88+ $ this ->globals ["files " ],
89+ $ this ->globals ["server " ],
90+ );
7791
7892 try {
7993 $ response = $ this ->dispatcher ->generateResponse ();
@@ -111,22 +125,42 @@ private function finish(
111125 }
112126
113127 /**
114- * @return array<string, array<string, mixed>>
115- * @SuppressWarnings("PHPMD.Superglobals")
128+ * Registers a namespace compatibility autoloader to bridge the
129+ * Gt -> GT namespace transition.
130+ *
131+ * As part of the PHP.GT rebranding for WebEngine v5, all references to
132+ * "GT" are being standardised to uppercase. However, the framework
133+ * consists of 40+ repositories that cannot all be refactored
134+ * simultaneously. This compatibility layer allows new code to reference
135+ * classes using the GT\ namespace while the underlying packages still
136+ * define classes with the Gt\ namespace.
116137 */
117- private function protectGlobals ():array {
118- $ originalGlobals = [
119- "server " => $ _SERVER ,
120- "files " => $ _FILES ,
121- "get " => $ _GET ,
122- "post " => $ _POST ,
123- "env " => $ _ENV ,
124- "cookie " => $ _COOKIE
125- ];
138+ private function gtCompatibility ():void {
139+ spl_autoload_register (function (string $ class ):void {
140+ if (str_starts_with ($ class , 'GT \\' )) {
141+ $ legacyClass = 'Gt ' . substr ($ class , 2 );
142+ // Trigger autoloading for the legacy class
143+ spl_autoload_call ($ legacyClass );
144+ // Only create alias if it was loaded and target doesn't already exist
145+ if ((class_exists ($ legacyClass , false ) || interface_exists ($ legacyClass , false ) || trait_exists ($ legacyClass , false ))
146+ && !class_exists ($ class , false ) && !interface_exists ($ class , false ) && !trait_exists ($ class , false )) {
147+ class_alias ($ legacyClass , $ class );
148+ }
149+ }
150+ }, true , true );
151+ }
126152
153+ private function protectGlobals ():void {
127154 $ protection = new Protection ();
128155 $ protection ->overrideInternals (
129- $ protection ->removeGlobals ($ originalGlobals , [
156+ $ protection ->removeGlobals ([
157+ "server " => $ this ->globals ["_SERVER " ],
158+ "files " => $ this ->globals ["_FILES " ],
159+ "get " => $ this ->globals ["_GET " ],
160+ "post " => $ this ->globals ["_POST " ],
161+ "env " => $ this ->globals ["_ENV " ],
162+ "cookie " => $ this ->globals ["_COOKIE " ],
163+ ], [
130164 "_ENV " => explode (", " , $ this ->config ->getString ("app.globals_whitelist_env " ) ?? "" ),
131165 "_SERVER " => explode (", " , $ this ->config ->getString ("app.globals_whitelist_server " ) ?? "" ),
132166 "_GET " => explode (", " , $ this ->config ->getString ("app.globals_whitelist_get " ) ?? "" ),
@@ -135,8 +169,6 @@ private function protectGlobals():array {
135169 "_COOKIES " => explode (", " , $ this ->config ->getString ("app.globals_whitelist_cookies " ) ?? "" ),
136170 ])
137171 );
138-
139- return $ originalGlobals ;
140172 }
141173
142174 private function loadConfig ():Config {
@@ -188,8 +220,15 @@ private function handleShutdown():void {
188220 $ this ->finish ($ response );
189221 }
190222 catch (Throwable $ innerThrowable ) {
191- $ this ->dispatcher ->generateBasicErrorResponse ($ innerThrowable , $ throwable );
223+ $ response = $ this ->dispatcher ->generateBasicErrorResponse ($ innerThrowable , $ throwable );
192224 }
225+ $ this ->outputHeaders (
226+ $ response ->getStatusCode (),
227+ $ response ->getHeaders (),
228+ );
229+ /** @var Stream $responseBody */
230+ $ responseBody = $ response ->getBody ();
231+ $ this ->outputResponseBody ($ responseBody );
193232 }
194233
195234 private function logError (Throwable $ throwable ):void {
0 commit comments