@@ -120,30 +120,32 @@ public function capture()
120120 * Retrieve query variables
121121 *
122122 * @param string|null $key
123- * @return array
123+ * @param mixed $default
124+ * @return mixed
124125 */
125- public function query (?string $ key = null ): array
126+ public function query (?string $ key = null , mixed $ default = null ): mixed
126127 {
127128 if ($ key === null ) {
128129 return $ this ->query ;
129130 }
130131
131- return $ this ->query [$ key ] ?? [] ;
132+ return $ this ->query [$ key ] ?? $ default ;
132133 }
133134
134135 /**
135136 * Get posted data
136137 *
137138 * @param string|null $key
138- * @return array
139+ * @param mixed $default
140+ * @return mixed
139141 */
140- public function post (?string $ key = null ): array
142+ public function post (?string $ key = null , mixed $ default = null ): mixed
141143 {
142144 if ($ key === null ) {
143145 return $ this ->post ;
144146 }
145147
146- return $ this ->post [$ key ] ?? [] ;
148+ return $ this ->post [$ key ] ?? $ default ;
147149 }
148150
149151 /**
@@ -210,6 +212,17 @@ public function method(): ?string
210212 return $ method ;
211213 }
212214
215+ /**
216+ * Check that the request method matches the given one.
217+ *
218+ * @param string $method
219+ * @return bool
220+ */
221+ public function isMethod (string $ method ): bool
222+ {
223+ return strtoupper ($ method ) === $ this ->method ();
224+ }
225+
213226 /**
214227 * Retrieve a value or a collection of values.
215228 *
@@ -228,6 +241,36 @@ public function get(string $key, mixed $default = null): mixed
228241 return $ value ;
229242 }
230243
244+ /**
245+ * Alias of get, retrieve an input value.
246+ *
247+ * @param string $key
248+ * @param mixed|null $default
249+ * @return mixed
250+ */
251+ public function input (string $ key , mixed $ default = null ): mixed
252+ {
253+ return $ this ->get ($ key , $ default );
254+ }
255+
256+ /**
257+ * Retrieve an input value as a boolean.
258+ *
259+ * Truthy values are 1, "1", true, "true", "on" and "yes".
260+ *
261+ * @param string $key
262+ * @param bool $default
263+ * @return bool
264+ */
265+ public function boolean (string $ key , bool $ default = false ): bool
266+ {
267+ if (!$ this ->has ($ key )) {
268+ return $ default ;
269+ }
270+
271+ return filter_var ($ this ->get ($ key ), FILTER_VALIDATE_BOOLEAN );
272+ }
273+
231274 /**
232275 * Get the request ID
233276 *
@@ -317,7 +360,7 @@ private function scheme(): string
317360 */
318361 public function hostname (): string
319362 {
320- return $ _SERVER ['HTTP_HOST ' ];
363+ return $ _SERVER ['HTTP_HOST ' ] ?? '' ;
321364 }
322365
323366 /**
@@ -327,9 +370,9 @@ public function hostname(): string
327370 */
328371 public function domain (): string
329372 {
330- $ part = explode (': ' , $ this ->hostname () ?? '' );
373+ $ part = explode (': ' , $ this ->hostname ());
331374
332- return $ part [0 ] ?? 'unknown ' ;
375+ return $ part [0 ] ?: 'unknown ' ;
333376 }
334377
335378 /**
@@ -339,25 +382,24 @@ public function domain(): string
339382 */
340383 public function path (): string
341384 {
342- $ position = strpos ($ _SERVER ['REQUEST_URI ' ], '? ' );
385+ $ request_uri = $ _SERVER ['REQUEST_URI ' ] ?? '/ ' ;
386+ $ position = strpos ($ request_uri , '? ' );
343387
344- if ($ position ) {
345- $ uri = substr ($ _SERVER ['REQUEST_URI ' ], 0 , $ position );
346- } else {
347- $ uri = $ _SERVER ['REQUEST_URI ' ];
388+ if ($ position !== false ) {
389+ return substr ($ request_uri , 0 , $ position );
348390 }
349391
350- return $ uri ;
392+ return $ request_uri ;
351393 }
352394
353395 /**
354- * Get path sent by client .
396+ * Get the request time as a UNIX timestamp .
355397 *
356- * @return string
398+ * @return int
357399 */
358- public function time (): string
400+ public function time (): int
359401 {
360- return $ _SESSION ['REQUEST_TIME ' ];
402+ return ( int ) ( $ _SERVER ['REQUEST_TIME ' ] ?? time ()) ;
361403 }
362404
363405 /**
@@ -402,7 +444,7 @@ public function file(string $key): UploadedFile|Collection|null
402444 return null ;
403445 }
404446
405- if (!is_uploaded_file ($ _FILES [$ key ]['tmp_name ' ]) === UPLOAD_ERR_OK ) {
447+ if (!is_array ($ _FILES [$ key ]['tmp_name ' ]) && ! is_uploaded_file ( $ _FILES [ $ key ][ ' tmp_name ' ]) ) {
406448 return null ;
407449 }
408450
@@ -430,14 +472,14 @@ public function file(string $key): UploadedFile|Collection|null
430472 * Get previous request data
431473 *
432474 * @param string $key
433- * @param mixed $fullback
475+ * @param mixed $fallback
434476 * @return mixed
435477 */
436- public function old (string $ key , mixed $ fullback ): mixed
478+ public function old (string $ key , mixed $ fallback = null ): mixed
437479 {
438480 $ old = Session::getInstance ()->get ('__bow.old ' , []);
439481
440- return $ old [$ key ] ?? $ fullback ;
482+ return $ old [$ key ] ?? $ fallback ;
441483 }
442484
443485 /**
@@ -531,7 +573,23 @@ public function referer(): string
531573 */
532574 public function ip (): ?string
533575 {
534- return $ _SERVER ['REMOTE_ADDR ' ] ?? null ;
576+ $ candidates = [
577+ $ _SERVER ['HTTP_CF_CONNECTING_IP ' ] ?? null ,
578+ isset ($ _SERVER ['HTTP_X_FORWARDED_FOR ' ])
579+ ? explode (', ' , $ _SERVER ['HTTP_X_FORWARDED_FOR ' ])[0 ]
580+ : null ,
581+ $ _SERVER ['HTTP_X_REAL_IP ' ] ?? null ,
582+ $ _SERVER ['REMOTE_ADDR ' ] ?? null ,
583+ ];
584+
585+ foreach ($ candidates as $ candidate ) {
586+ $ ip = trim ((string ) $ candidate );
587+ if ($ ip !== '' && filter_var ($ ip , FILTER_VALIDATE_IP ) !== false ) {
588+ return $ ip ;
589+ }
590+ }
591+
592+ return null ;
535593 }
536594
537595 /**
@@ -557,9 +615,15 @@ public function locale(): ?string
557615 {
558616 $ accept_language = $ this ->getHeader ('accept-language ' );
559617
618+ if (!$ accept_language ) {
619+ return null ;
620+ }
621+
560622 $ tmp = explode ('; ' , $ accept_language )[0 ];
561623
562- preg_match ('^([a-z]+)[-_]?/i ' , $ tmp , $ match );
624+ if (!preg_match ('/([a-z]+)[-_]?/i ' , $ tmp , $ match )) {
625+ return null ;
626+ }
563627
564628 return end ($ match );
565629 }
@@ -644,6 +708,22 @@ public function userAgent(): ?string
644708 return $ this ->getHeader ('USER_AGENT ' );
645709 }
646710
711+ /**
712+ * Get the Bearer token from the Authorization header.
713+ *
714+ * @return ?string
715+ */
716+ public function bearerToken (): ?string
717+ {
718+ $ authorization = $ this ->getHeader ('authorization ' );
719+
720+ if ($ authorization && str_starts_with ($ authorization , 'Bearer ' )) {
721+ return substr ($ authorization , 7 );
722+ }
723+
724+ return null ;
725+ }
726+
647727 /**
648728 * Get session information
649729 *
0 commit comments