1616use CodeIgniter \Cookie \Exceptions \CookieException ;
1717use CodeIgniter \HTTP \Exceptions \HTTPException ;
1818use CodeIgniter \Pager \PagerInterface ;
19+ use CodeIgniter \Security \Exceptions \SecurityException ;
1920use Config \Services ;
2021use DateTime ;
2122use DateTimeZone ;
2223use InvalidArgumentException ;
2324
2425/**
25- * Request Trait
26+ * Response Trait
2627 *
2728 * Additional methods to make a PSR-7 Response class
2829 * compliant with the framework's own ResponseInterface.
@@ -446,7 +447,7 @@ public function send()
446447 }
447448
448449 /**
449- * Sends the headers of this HTTP request to the browser.
450+ * Sends the headers of this HTTP response to the browser.
450451 *
451452 * @return Response
452453 */
@@ -535,15 +536,15 @@ public function redirect(string $uri, string $method = 'auto', ?int $code = null
535536 * Accepts an arbitrary number of binds (up to 7) or an associative
536537 * array in the first parameter containing all the values.
537538 *
538- * @param array|string $name Cookie name or array containing binds
539- * @param string $value Cookie value
540- * @param string $expire Cookie expiration time in seconds
541- * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
542- * @param string $path Cookie path (default: '/')
543- * @param string $prefix Cookie name prefix
544- * @param bool $secure Whether to only transfer cookies via SSL
545- * @param bool $httponly Whether only make the cookie accessible via HTTP (no javascript)
546- * @param string|null $samesite
539+ * @param array|Cookie| string $name Cookie name / array containing binds / Cookie object
540+ * @param string $value Cookie value
541+ * @param string $expire Cookie expiration time in seconds
542+ * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
543+ * @param string $path Cookie path (default: '/')
544+ * @param string $prefix Cookie name prefix
545+ * @param bool $secure Whether to only transfer cookies via SSL
546+ * @param bool $httponly Whether only make the cookie accessible via HTTP (no javascript)
547+ * @param string|null $samesite
547548 *
548549 * @return $this
549550 */
@@ -558,6 +559,12 @@ public function setCookie(
558559 $ httponly = false ,
559560 $ samesite = null
560561 ) {
562+ if ($ name instanceof Cookie) {
563+ $ this ->cookieStore = $ this ->cookieStore ->put ($ name );
564+
565+ return $ this ;
566+ }
567+
561568 if (is_array ($ name )) {
562569 // always leave 'name' in last place, as the loop will break otherwise, due to $$item
563570 foreach (['samesite ' , 'value ' , 'expire ' , 'domain ' , 'path ' , 'prefix ' , 'secure ' , 'httponly ' , 'name ' ] as $ item ) {
@@ -689,7 +696,51 @@ protected function sendCookies()
689696 return ;
690697 }
691698
692- $ this ->cookieStore ->dispatch ();
699+ $ this ->dispatchCookies ();
700+ }
701+
702+ private function dispatchCookies (): void
703+ {
704+ /** @var IncomingRequest $request */
705+ $ request = Services::request ();
706+
707+ foreach ($ this ->cookieStore ->display () as $ cookie ) {
708+ if ($ cookie ->isSecure () && ! $ request ->isSecure ()) {
709+ throw SecurityException::forDisallowedAction ();
710+ }
711+
712+ $ name = $ cookie ->getPrefixedName ();
713+ $ value = $ cookie ->getValue ();
714+ $ options = $ cookie ->getOptions ();
715+
716+ if ($ cookie ->isRaw ()) {
717+ $ this ->doSetRawCookie ($ name , $ value , $ options );
718+ } else {
719+ $ this ->doSetCookie ($ name , $ value , $ options );
720+ }
721+ }
722+
723+ $ this ->cookieStore ->clear ();
724+ }
725+
726+ /**
727+ * Extracted call to `setrawcookie()` in order to run unit tests on it.
728+ *
729+ * @codeCoverageIgnore
730+ */
731+ private function doSetRawCookie (string $ name , string $ value , array $ options ): void
732+ {
733+ setrawcookie ($ name , $ value , $ options );
734+ }
735+
736+ /**
737+ * Extracted call to `setcookie()` in order to run unit tests on it.
738+ *
739+ * @codeCoverageIgnore
740+ */
741+ private function doSetCookie (string $ name , string $ value , array $ options ): void
742+ {
743+ setcookie ($ name , $ value , $ options );
693744 }
694745
695746 /**
0 commit comments