diff --git a/system/Common.php b/system/Common.php index 2d71e0d0493e..acdc66823db2 100644 --- a/system/Common.php +++ b/system/Common.php @@ -244,7 +244,7 @@ function config(string $name, bool $getShared = true) */ function cookie(string $name, string $value = '', array $options = []): Cookie { - return Cookie::create($name, $value, $options); + return new Cookie($name, $value, $options); } } diff --git a/system/Cookie/CloneableCookieInterface.php b/system/Cookie/CloneableCookieInterface.php index cf2f73861e5a..be276e4a265a 100644 --- a/system/Cookie/CloneableCookieInterface.php +++ b/system/Cookie/CloneableCookieInterface.php @@ -48,19 +48,15 @@ public function withValue(string $value); /** * Creates a new Cookie with a new cookie expires time. + * + * If $expires is equal to 0 (zero) the cookie will + * expires from the browser. * * @param DateTimeInterface|integer|string $expires * * @return static */ - public function withExpiresAt($expires = 0); - - /** - * Creates a new Cookie that will expire the cookie from the browser. - * - * @return static - */ - public function withExpired(); + public function withExpires($expires = 0); /** * Creates a new Cookie that will virtually never expire from the browser. diff --git a/system/Cookie/Cookie.php b/system/Cookie/Cookie.php index ac362b46071b..01d8dae1165a 100644 --- a/system/Cookie/Cookie.php +++ b/system/Cookie/Cookie.php @@ -27,7 +27,7 @@ * reassign this new instance to a new variable to capture it. * * ```php - * $cookie = Cookie::create('test_cookie', 'test_value'); + * $cookie = new Cookie('test_cookie', 'test_value'); * $cookie->getName(); // test_cookie * * $cookie->withName('prod_cookie'); @@ -149,8 +149,8 @@ public static function setDefaults($config = []) $newDefaults = $config; } - // This array union ensures that even if passed `$config` - // is not `CookieConfig` or `array`, no empty defaults will occur. + // This array union ensures that even if passed `$config` is not + // `CookieConfig` or `array`, no empty defaults will occur. self::$defaults = $newDefaults + $oldDefaults; return $oldDefaults; @@ -197,21 +197,19 @@ public static function fromHeaderString(string $cookie, bool $raw = false) $data[strtolower($attr)] = $val; } - return static::create($name, $value, $data); + return new static($name, $value, $data); } /** - * Create Cookie objects on the fly. + * Construct a new Cookie instance. * - * @param string $name - * @param string $value - * @param array $options + * @param string $name The cookie's name + * @param string $value The cookie's value + * @param array $options The cookie's options * * @throws CookieException - * - * @return static */ - public static function create(string $name, string $value = '', array $options = []) + final public function __construct(string $name, string $value = '', array $options = []) { $options += self::$defaults; @@ -224,56 +222,14 @@ public static function create(string $name, string $value = '', array $options = unset($options['max-age']); } - return new static( - $name, - $value, - $options['expires'], - $options['prefix'], - $options['path'], - $options['domain'], - $options['secure'], - $options['httponly'], - $options['raw'], - $options['samesite'] - ); - } - - /** - * Construct a new Cookie instance. - * - * @param string $name The name of the cookie - * @param string $value The value of the cookie - * @param DateTimeInterface|integer|string $expires The time the cookie expires - * @param string|null $prefix The prefix of the cookie - * @param string|null $path The path on the server in which the cookie is available - * @param string|null $domain The domain in which the cookie is available - * @param boolean $secure Whether to send back the cookie over HTTPS - * @param boolean $httponly Whether to forbid JavaScript access to cookies - * @param boolean $raw Whether the cookie should be sent with no URL encoding - * @param string $samesite Whether the cookie will be available for cross-site requests - * - * @throws CookieException - */ - final public function __construct( - string $name, - string $value = '', - $expires = 0, - string $prefix = null, - string $path = null, - string $domain = null, - bool $secure = false, - bool $httponly = true, - bool $raw = false, - string $samesite = self::SAMESITE_LAX - ) - { // to retain BC - $prefix = $prefix ?: self::$defaults['prefix']; - $path = $path ?: self::$defaults['path']; - $domain = $domain ?: self::$defaults['domain']; - $secure = $secure ?: self::$defaults['secure']; - $httponly = $httponly ?: self::$defaults['httponly']; - $samesite = $samesite ?: self::$defaults['samesite']; + $prefix = $options['prefix'] ?: self::$defaults['prefix']; + $path = $options['path'] ?: self::$defaults['path']; + $domain = $options['domain'] ?: self::$defaults['domain']; + $secure = $options['secure'] ?: self::$defaults['secure']; + $httponly = $options['httponly'] ?: self::$defaults['httponly']; + $samesite = $options['samesite'] ?: self::$defaults['samesite']; + $raw = $options['raw'] ?: self::$defaults['raw']; $this->validateName($name, $raw); $this->validatePrefix($prefix, $secure, $path, $domain); @@ -282,7 +238,7 @@ final public function __construct( $this->prefix = $prefix; $this->name = $name; $this->value = $value; - $this->expires = static::convertExpiresTimestamp($expires); + $this->expires = static::convertExpiresTimestamp($options['expires']); $this->path = $path; $this->domain = $domain; $this->secure = $secure; @@ -354,7 +310,7 @@ public function getValue(): string /** * {@inheritDoc} */ - public function getExpiresTimestamp(): int + public function getExpires(): int { return $this->expires; } @@ -438,7 +394,7 @@ public function isRaw(): bool */ public function getOptions(): array { - // This is the order of options in `setcookie`. DO NOT change. + // This is the order of options in `setcookie`. DO NOT CHANGE. return [ 'expires' => $this->expires, 'path' => $this->path, @@ -496,7 +452,7 @@ public function withValue(string $value) /** * {@inheritDoc} */ - public function withExpiresAt($expires = 0) + public function withExpires($expires = 0) { $cookie = clone $this; @@ -505,18 +461,6 @@ public function withExpiresAt($expires = 0) return $cookie; } - /** - * {@inheritDoc} - */ - public function withExpired() - { - $cookie = clone $this; - - $cookie->expires = 0; - - return $cookie; - } - /** * {@inheritDoc} */ @@ -709,7 +653,7 @@ public function __toString() $cookieHeader[] = sprintf('%s=%s', $this->getPrefixedName(), $value); - if ($this->getExpiresTimestamp() !== 0) + if ($this->getExpires() !== 0) { $cookieHeader[] = 'Expires=' . $this->getExpiresString(); $cookieHeader[] = 'Max-Age=' . $this->getMaxAge(); diff --git a/system/Cookie/CookieInterface.php b/system/Cookie/CookieInterface.php index 1dddb13a1426..34845a1107b3 100644 --- a/system/Cookie/CookieInterface.php +++ b/system/Cookie/CookieInterface.php @@ -106,7 +106,7 @@ public function getValue(): string; * * @return integer */ - public function getExpiresTimestamp(): int; + public function getExpires(): int; /** * Gets the formatted expires time. diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php index 948df6566755..e692cba525fa 100644 --- a/system/HTTP/ResponseTrait.php +++ b/system/HTTP/ResponseTrait.php @@ -607,7 +607,7 @@ public function setCookie( $expire = $expire > 0 ? time() + $expire : 0; } - $options = [ + $cookie = new Cookie($name, $value, [ 'expires' => $expire ?: 0, 'domain' => $domain, 'path' => $path, @@ -615,9 +615,7 @@ public function setCookie( 'secure' => $secure, 'httponly' => $httponly, 'samesite' => $samesite ?? '', - ]; - - $cookie = Cookie::create($name, $value, $options); + ]); $this->cookieStore = $this->cookieStore->put($cookie); @@ -715,7 +713,7 @@ public function deleteCookie(string $name = '', string $domain = '', string $pat continue; } - $cookie = $cookie->withValue('')->withExpired(); + $cookie = $cookie->withValue('')->withExpires(); $found = true; $this->cookieStore = $store->put($cookie); diff --git a/system/Security/Security.php b/system/Security/Security.php index ab1e066844f1..2de9db47500f 100644 --- a/system/Security/Security.php +++ b/system/Security/Security.php @@ -149,7 +149,7 @@ public function __construct(App $config) $expires = $security->expires ?? $config->CSRFExpire ?? 7200; Cookie::setDefaults($cookie); - $this->cookie = Cookie::create($rawCookieName, $this->generateHash(), [ + $this->cookie = new Cookie($rawCookieName, $this->generateHash(), [ 'expires' => $expires === 0 ? 0 : time() + $expires, ]); } diff --git a/system/Session/Session.php b/system/Session/Session.php index fabd2d81c1a6..6a0236002556 100644 --- a/system/Session/Session.php +++ b/system/Session/Session.php @@ -192,7 +192,7 @@ public function __construct(SessionHandlerInterface $driver, App $config) */ $config = config('Cookie'); - $this->cookie = Cookie::create($this->sessionCookieName, '', [ + $this->cookie = new Cookie($this->sessionCookieName, '', [ 'expires' => $this->sessionExpiration === 0 ? 0 : time() + $this->sessionExpiration, 'path' => $config->path, 'domain' => $config->domain, @@ -1009,7 +1009,7 @@ protected function startSession() protected function setCookie() { $expiration = $this->sessionExpiration === 0 ? 0 : time() + $this->sessionExpiration; - $this->cookie = $this->cookie->withValue(session_id())->withExpiresAt($expiration); + $this->cookie = $this->cookie->withValue(session_id())->withExpires($expiration); cookies([$this->cookie], false)->dispatch(); } diff --git a/system/Test/Mock/MockSession.php b/system/Test/Mock/MockSession.php index 32512ca14066..69b1bb06c6ea 100644 --- a/system/Test/Mock/MockSession.php +++ b/system/Test/Mock/MockSession.php @@ -57,7 +57,7 @@ protected function startSession() protected function setCookie() { $expiration = $this->sessionExpiration === 0 ? 0 : time() + $this->sessionExpiration; - $this->cookie = $this->cookie->withValue(session_id())->withExpiresAt($expiration); + $this->cookie = $this->cookie->withValue(session_id())->withExpires($expiration); $this->cookies[] = $this->cookie; } diff --git a/system/Test/TestResponse.php b/system/Test/TestResponse.php index e2c6e4781048..25ae944b6996 100644 --- a/system/Test/TestResponse.php +++ b/system/Test/TestResponse.php @@ -372,7 +372,7 @@ public function assertCookieMissing(string $key) public function assertCookieExpired(string $key, string $prefix = '') { $this->assertTrue($this->response->hasCookie($key, null, $prefix)); - $this->assertGreaterThan(time(), $this->response->getCookie($key, $prefix)->getExpiresTimestamp()); + $this->assertGreaterThan(time(), $this->response->getCookie($key, $prefix)->getExpires()); } //-------------------------------------------------------------------- diff --git a/tests/system/Cookie/CookieStoreTest.php b/tests/system/Cookie/CookieStoreTest.php index de040d2ea2a4..1c0fcf13b1d0 100644 --- a/tests/system/Cookie/CookieStoreTest.php +++ b/tests/system/Cookie/CookieStoreTest.php @@ -32,8 +32,8 @@ protected function tearDown(): void public function testCookieStoreInitialization(): void { $cookies = [ - Cookie::create('dev', 'cookie'), - Cookie::create('prod', 'cookie', ['raw' => true]), + new Cookie('dev', 'cookie'), + new Cookie('prod', 'cookie', ['raw' => true]), ]; $store = new CookieStore($cookies); @@ -76,12 +76,12 @@ public function testInvalidCookieStored(): void public function testPutRemoveCookiesInStore(): void { $cookies = [ - Cookie::create('dev', 'cookie'), - Cookie::create('prod', 'cookie', ['raw' => true]), + new Cookie('dev', 'cookie'), + new Cookie('prod', 'cookie', ['raw' => true]), ]; $store = new CookieStore($cookies); - $bottle = $store->put(Cookie::create('test', 'cookie')); + $bottle = $store->put(new Cookie('test', 'cookie')); $jar = $store->remove('dev'); $this->assertNotSame($store->display(), $bottle->display()); @@ -94,8 +94,8 @@ public function testPutRemoveCookiesInStore(): void public function testCookieDispatching(): void { $cookies = [ - 'dev' => Cookie::create('dev', 'cookie'), - 'prod' => Cookie::create('prod', 'cookie', ['raw' => true]), + 'dev' => new Cookie('dev', 'cookie'), + 'prod' => new Cookie('prod', 'cookie', ['raw' => true]), ]; $dev = $cookies['dev']->getOptions(); diff --git a/tests/system/Cookie/CookieTest.php b/tests/system/Cookie/CookieTest.php index 1e4b425b00c8..77e79756622c 100644 --- a/tests/system/Cookie/CookieTest.php +++ b/tests/system/Cookie/CookieTest.php @@ -34,14 +34,14 @@ protected function tearDown(): void public function testCookieInitializationWithDefaults(): void { - $cookie = Cookie::create('test', 'value'); + $cookie = new Cookie('test', 'value'); $options = Cookie::setDefaults(); $this->assertSame($options['prefix'] . 'test', $cookie->getPrefixedName()); $this->assertSame('test', $cookie->getName()); $this->assertSame('value', $cookie->getValue()); $this->assertSame($options['prefix'], $cookie->getPrefix()); - $this->assertSame($options['expires'], $cookie->getExpiresTimestamp()); + $this->assertSame($options['expires'], $cookie->getExpires()); $this->assertSame($options['path'], $cookie->getPath()); $this->assertSame($options['domain'], $cookie->getDomain()); $this->assertSame($options['secure'], $cookie->isSecure()); @@ -59,12 +59,12 @@ public function testConfigInjectionForDefaults(): void $old = Cookie::setDefaults($config); - $cookie = Cookie::create('test', 'value'); + $cookie = new Cookie('test', 'value'); $this->assertSame($config->prefix . 'test', $cookie->getPrefixedName()); $this->assertSame('test', $cookie->getName()); $this->assertSame('value', $cookie->getValue()); $this->assertSame($config->prefix, $cookie->getPrefix()); - $this->assertSame($config->expires, $cookie->getExpiresTimestamp()); + $this->assertSame($config->expires, $cookie->getExpires()); $this->assertSame($config->path, $cookie->getPath()); $this->assertSame($config->domain, $cookie->getDomain()); $this->assertSame($config->secure, $cookie->isSecure()); @@ -78,54 +78,54 @@ public function testConfigInjectionForDefaults(): void public function testValidationOfRawCookieName(): void { $this->expectException(CookieException::class); - Cookie::create("test;\n", '', ['raw' => true]); + new Cookie("test;\n", '', ['raw' => true]); } public function testValidationOfEmptyCookieName(): void { $this->expectException(CookieException::class); - Cookie::create('', 'value'); + new Cookie('', 'value'); } public function testValidationOfSecurePrefix(): void { $this->expectException(CookieException::class); - Cookie::create('test', 'value', ['prefix' => '__Secure-', 'secure' => false]); + new Cookie('test', 'value', ['prefix' => '__Secure-', 'secure' => false]); } public function testValidationOfHostPrefix(): void { $this->expectException(CookieException::class); - Cookie::create('test', 'value', ['prefix' => '__Host-', 'domain' => 'localhost']); + new Cookie('test', 'value', ['prefix' => '__Host-', 'domain' => 'localhost']); } public function testValidationOfSameSite(): void { Cookie::setDefaults(['samesite' => '']); - $this->assertInstanceOf(Cookie::class, Cookie::create('test')); + $this->assertInstanceOf(Cookie::class, new Cookie('test')); $this->expectException(CookieException::class); - Cookie::create('test', '', ['samesite' => 'Yes']); + new Cookie('test', '', ['samesite' => 'Yes']); } public function testValidationOfSameSiteNone(): void { $this->expectException(CookieException::class); - Cookie::create('test', '', ['samesite' => Cookie::SAMESITE_NONE, 'secure' => false]); + new Cookie('test', '', ['samesite' => Cookie::SAMESITE_NONE, 'secure' => false]); } public function testExpirationTime(): void { // expires => 0 - $cookie = Cookie::create('test', 'value'); - $this->assertSame(0, $cookie->getExpiresTimestamp()); + $cookie = new Cookie('test', 'value'); + $this->assertSame(0, $cookie->getExpires()); $this->assertSame('Thu, 01-Jan-1970 00:00:00 GMT', $cookie->getExpiresString()); $this->assertTrue($cookie->isExpired()); $this->assertSame(0, $cookie->getMaxAge()); $date = new DateTimeImmutable('2021-01-10 00:00:00 GMT', new DateTimeZone('UTC')); - $cookie = Cookie::create('test', 'value', ['expires' => $date]); - $this->assertSame((int) $date->format('U'), $cookie->getExpiresTimestamp()); + $cookie = new Cookie('test', 'value', ['expires' => $date]); + $this->assertSame((int) $date->format('U'), $cookie->getExpires()); $this->assertSame('Sun, 10-Jan-2021 00:00:00 GMT', $cookie->getExpiresString()); } @@ -139,7 +139,7 @@ public function testExpirationTime(): void public function testInvalidExpires($expires): void { $this->expectException(CookieException::class); - Cookie::create('test', 'value', ['expires' => $expires]); + new Cookie('test', 'value', ['expires' => $expires]); } public static function invalidExpiresProvider(): iterable @@ -196,20 +196,20 @@ public static function setCookieHeaderProvider(): iterable public function testValidNamePerRfcYieldsSameNameRegardlessOfRawParam(): void { - $cookie1 = Cookie::create('testing', '', ['raw' => false]); - $cookie2 = Cookie::create('testing', '', ['raw' => true]); + $cookie1 = new Cookie('testing', '', ['raw' => false]); + $cookie2 = new Cookie('testing', '', ['raw' => true]); $this->assertSame($cookie1->getPrefixedName(), $cookie2->getPrefixedName()); } public function testCloningCookies(): void { - $a = Cookie::create('dev', 'cookie'); + $a = new Cookie('dev', 'cookie'); $b = $a->withRaw(); $c = $a->withPrefix('my_'); $d = $a->withName('prod'); $e = $a->withValue('muffin'); - $f = $a->withExpiresAt('+30 days'); - $g = $a->withExpired(); + $f = $a->withExpires('+30 days'); + $g = $a->withExpires(); $h = $a->withNeverExpiring(); $i = $a->withDomain('localhost'); $j = $a->withPath('/web'); @@ -235,8 +235,8 @@ public function testStringCastingOfCookies(): void { $date = new DateTimeImmutable('2021-02-14 00:00:00 GMT', new DateTimeZone('UTC')); - $a = Cookie::create('cookie', 'lover'); - $b = $a->withValue('monster')->withPath('/web')->withDomain('localhost')->withExpiresAt($date); + $a = new Cookie('cookie', 'lover'); + $b = $a->withValue('monster')->withPath('/web')->withDomain('localhost')->withExpires($date); $c = $a->withSecure()->withHTTPOnly(false)->withSameSite(Cookie::SAMESITE_STRICT); $max = (string) $b->getMaxAge(); @@ -266,10 +266,10 @@ public function testStringCastingOfCookies(): void public function testArrayAccessOfCookie(): void { - $cookie = Cookie::create('cookie', 'monster'); + $cookie = new Cookie('cookie', 'monster'); $this->assertTrue(isset($cookie['expire'])); - $this->assertSame($cookie['expire'], $cookie->getExpiresTimestamp()); + $this->assertSame($cookie['expire'], $cookie->getExpires()); $this->assertTrue(isset($cookie['httponly'])); $this->assertSame($cookie['httponly'], $cookie->isHTTPOnly()); $this->assertTrue(isset($cookie['samesite'])); @@ -284,12 +284,14 @@ public function testArrayAccessOfCookie(): void public function testCannotSetPropertyViaArrayAccess(): void { $this->expectException(LogicException::class); - Cookie::create('cookie', 'monster')['expires'] = 7200; + $cookie = new Cookie('cookie', 'monster'); + $cookie['expires'] = 7200; } public function testCannotUnsetPropertyViaArrayAccess(): void { $this->expectException(LogicException::class); - unset(Cookie::create('cookie', 'monster')['path']); + $cookie = new Cookie('cookie', 'monster'); + unset($cookie['path']); } } diff --git a/tests/system/HTTP/ResponseCookieTest.php b/tests/system/HTTP/ResponseCookieTest.php index 16a90316f8c0..6fcfb159ebab 100644 --- a/tests/system/HTTP/ResponseCookieTest.php +++ b/tests/system/HTTP/ResponseCookieTest.php @@ -140,7 +140,7 @@ public function testCookieExpiry() $response = new Response(new App()); $response->setCookie(['name' => 'bee', 'value' => 'bop', 'expire' => -1000]); $cookie = $response->getCookie('bee'); - $this->assertSame(0, $cookie->getExpiresTimestamp()); + $this->assertSame(0, $cookie->getExpires()); } public function testCookieDelete() @@ -157,7 +157,7 @@ public function testCookieDelete() $response = new Response(new App()); $response->setCookie(['name' => 'bee', 'value' => 'bop', 'expire' => '']); $cookie = $response->getCookie('bee'); - $this->assertTrue($cookie->isExpired(), $cookie->getExpiresTimestamp() . ' should be less than ' . time()); + $this->assertTrue($cookie->isExpired(), $cookie->getExpires() . ' should be less than ' . time()); // delete with no effect $response = new Response(new App()); @@ -171,7 +171,7 @@ public function testCookieDelete() $response->setCookie(['name' => 'bee', 'value' => 'bop', 'expire' => 1000]); $response->deleteCookie('bee'); $cookie = $response->getCookie('bee'); - $this->assertTrue($cookie->isExpired(), $cookie->getExpiresTimestamp() . ' should be less than ' . time()); + $this->assertTrue($cookie->isExpired(), $cookie->getExpires() . ' should be less than ' . time()); $config = config('Cookie'); // delete cookie for real, with prefix @@ -180,7 +180,7 @@ public function testCookieDelete() $response->setCookie(['name' => 'bee', 'value' => 'bop', 'expire' => 1000]); $response->deleteCookie('bee'); $cookie = $response->getCookie('bee'); - $this->assertSame($cookie->getExpiresTimestamp(), 0); + $this->assertSame($cookie->getExpires(), 0); // delete cookie with wrong prefix? $config->prefix = 'mine'; @@ -188,10 +188,10 @@ public function testCookieDelete() $response->setCookie(['name' => 'bee', 'value' => 'bop', 'expire' => 1000]); $response->deleteCookie('bee', '', '', 'wrong'); $cookie = $response->getCookie('bee'); - $this->assertFalse($cookie->isExpired(), $cookie->getExpiresTimestamp() . ' should be less than ' . time()); + $this->assertFalse($cookie->isExpired(), $cookie->getExpires() . ' should be less than ' . time()); $response->deleteCookie('bee', '', '', 'mine'); $cookie = $response->getCookie('bee'); - $this->assertSame($cookie->getExpiresTimestamp(), 0); + $this->assertSame($cookie->getExpires(), 0); // delete cookie with wrong domain? $config->domain = '.mine.com'; @@ -199,10 +199,10 @@ public function testCookieDelete() $response->setCookie(['name' => 'bees', 'value' => 'bop', 'expire' => 1000]); $response->deleteCookie('bees', 'wrong', '', ''); $cookie = $response->getCookie('bees'); - $this->assertFalse($cookie->isExpired(), $cookie->getExpiresTimestamp() . ' should be less than ' . time()); + $this->assertFalse($cookie->isExpired(), $cookie->getExpires() . ' should be less than ' . time()); $response->deleteCookie('bees', '.mine.com', '', ''); $cookie = $response->getCookie('bees'); - $this->assertSame($cookie->getExpiresTimestamp(), 0); + $this->assertSame($cookie->getExpires(), 0); } public function testCookieDefaultSetSameSite() diff --git a/tests/system/Helpers/CookieHelperTest.php b/tests/system/Helpers/CookieHelperTest.php index 512bfc2158cb..84f8a36c7b1e 100755 --- a/tests/system/Helpers/CookieHelperTest.php +++ b/tests/system/Helpers/CookieHelperTest.php @@ -99,7 +99,7 @@ public function testDeleteCookie() // The cookie is set to be cleared when the request is sent.... $this->assertEquals('', $cookie->getValue()); - $this->assertEquals(0, $cookie->getExpiresTimestamp()); + $this->assertEquals(0, $cookie->getExpires()); } public function testGetCookie() diff --git a/tests/system/Session/SessionTest.php b/tests/system/Session/SessionTest.php index 9c51dee199c4..a65b32b4e45a 100644 --- a/tests/system/Session/SessionTest.php +++ b/tests/system/Session/SessionTest.php @@ -617,7 +617,7 @@ public function testExpires() $cookies = $session->cookies; $this->assertCount(1, $cookies); - $this->assertGreaterThan(8000, $cookies[0]->getExpiresTimestamp()); + $this->assertGreaterThan(8000, $cookies[0]->getExpires()); } public function testExpiresOnClose() @@ -627,6 +627,6 @@ public function testExpiresOnClose() $cookies = $session->cookies; $this->assertCount(1, $cookies); - $this->assertSame(0, $cookies[0]->getExpiresTimestamp()); + $this->assertSame(0, $cookies[0]->getExpires()); } } diff --git a/user_guide_src/source/libraries/cookies.rst b/user_guide_src/source/libraries/cookies.rst index 42c7d182cbab..2b675f57d2db 100644 --- a/user_guide_src/source/libraries/cookies.rst +++ b/user_guide_src/source/libraries/cookies.rst @@ -2,11 +2,11 @@ Cookies ####### -An **HTTP cookie** (web cookie, browser cookie) is a small piece of data that a -server sends to the user's web browser. The browser may store it and send it -back with later requests to the same server. Typically, it's used to tell if -two requests came from the same browser — keeping a user logged-in, for -example. It remembers stateful information for the stateless HTTP protocol. +An **HTTP cookie** (web cookie, browser cookie) is a small piece of data that a server +sends to the user's web browser. The browser may store it and send it back with later +requests to the same server. Typically, it's used to tell if two requests came from +the same browser — keeping a user logged-in, for example. +It remembers stateful information for the stateless HTTP protocol. Cookies are mainly used for three purposes: @@ -26,29 +26,15 @@ cookie interaction. Creating Cookies **************** -There are currently five (5) ways to create a new ``Cookie`` value object. +There are currently four (4) ways to create a new ``Cookie`` value object. :: use CodeIgniter\Cookie\Cookie; use DateTime; - // Providing all arguments in the constructor + // Throw the constructor $cookie = new Cookie( - 'remember_token', // name - 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6', // value - new DateTime('+2 hours'), // expires - '__Secure-', // prefix - '/', // path - '', // domain - true, // secure - true, // httponly - false, // raw - Cookie::SAMESITE_LAX // samesite - ); - - // Using the static constructor - $cookie = Cookie::create( 'remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6', [ @@ -77,24 +63,24 @@ There are currently five (5) ways to create a new ``Cookie`` value object. ->withPath('/') ->withDomain('') ->withSecure(true) - ->withHttpOnly(true) + ->withHTTPOnly(true) ->withSameSite(Cookie::SAMESITE_LAX); - // Using the global function `cookie` which implicitly calls `Cookie::create()` + // Using the global function `cookie` which implicitly calls `new Cookie()` $cookie = cookie('remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6'); When constructing the ``Cookie`` object, only the ``name`` attribute is required. All other else are optional. If the optional attributes are not modified, their values will be filled up by the default values saved in -the ``Cookie`` class. To override the defaults currently stored in the class, you can pass a ``Config\App`` +the ``Cookie`` class. To override the defaults currently stored in the class, you can pass a ``Config\Cookie`` instance or an array of defaults to the static ``Cookie::setDefaults()`` method. :: use CodeIgniter\Cookie\Cookie; - use Config\App; + use Config\Cookie as CookieConfig; // pass in an App instance before constructing a Cookie class - Cookie::setDefaults(new App()); + Cookie::setDefaults(new CookieConfig()); $cookie = new Cookie('login_token'); // pass in an array of defaults @@ -103,9 +89,9 @@ instance or an array of defaults to the static ``Cookie::setDefaults()`` method. 'samesite' => Cookie::SAMESITE_STRICT, ]; Cookie::setDefaults($myDefaults); - $cookie = Cookie::create('login_token'); + $cookie = new Cookie('login_token'); -Passing the ``Config\App`` instance or an array to ``Cookie::setDefaults()`` will effectively +Passing the ``Config\Cookie`` instance or an array to ``Cookie::setDefaults()`` will effectively overwrite your defaults and will persist until new defaults are passed. If you do not want this behavior but only want to change defaults for a limited time, you can take advantage of ``Cookie::setDefaults()`` return which returns the old defaults array. @@ -113,10 +99,10 @@ behavior but only want to change defaults for a limited time, you can take advan :: use CodeIgniter\Cookie\Cookie; - use Config\App; + use Config\Cookie as CookieConfig; - $oldDefaults = Cookie::setDefaults(new App()); - $cookie = Cookie::create('my_token', 'muffins'); + $oldDefaults = Cookie::setDefaults(new CookieConfig()); + $cookie = new Cookie('my_token', 'muffins'); // return the old defaults Cookie::setDefaults($oldDefaults); @@ -133,7 +119,7 @@ Once instantiated, you can easily access a ``Cookie``'s attribute by using one o use DateTime; use DateTimeZone; - $cookie = Cookie::create( + $cookie = new Cookie( 'remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6', [ @@ -151,7 +137,7 @@ Once instantiated, you can easily access a ``Cookie``'s attribute by using one o $cookie->getName(); // 'remember_token' $cookie->getPrefix(); // '__Secure-' $cookie->getPrefixedName(); // '__Secure-remember_token' - $cookie->getExpiresTimestamp(); // Unix timestamp + $cookie->getExpires(); // Unix timestamp $cookie->getExpiresString(); // 'Fri, 14-Feb-2025 00:00:00 GMT' $cookie->isExpired(); // false $cookie->getMaxAge(); // the difference from time() to expires @@ -159,7 +145,7 @@ Once instantiated, you can easily access a ``Cookie``'s attribute by using one o $cookie->isSecure(); // true $cookie->getPath(); // '/' $cookie->getDomain(); // '' - $cookie->isHttpOnly(); // true + $cookie->isHTTPOnly(); // true $cookie->getSameSite(); // 'Lax' // additional getter @@ -182,7 +168,7 @@ returns a new instance. You need to retain this new instance in order to use it. use CodeIgniter\Cookie\Cookie; - $cookie = Cookie::create('login_token', 'admin'); + $cookie = new Cookie('login_token', 'admin'); $cookie->getName(); // 'login_token' $cookie->withName('remember_token'); @@ -276,8 +262,8 @@ CodeIgniter provides three (3) other ways to create a new instance of the ``Cook // Passing an array of `Cookie` objects in the constructor $store = new CookieStore([ - Cookie::create('login_token'), - Cookie::create('remember_token'), + new Cookie('login_token'), + new Cookie('remember_token'), ]); // Passing an array of `Set-Cookie` header strings @@ -287,7 +273,7 @@ CodeIgniter provides three (3) other ways to create a new instance of the ``Cook ]); // using the global `cookies` function - $store = cookies([Cookie::create('login_token')], false); + $store = cookies([new Cookie('login_token')], false); // retrieving the `CookieStore` instance saved in our current `Response` object $store = cookies(); @@ -306,8 +292,8 @@ To check whether a ``Cookie`` object exists in the ``CookieStore`` instance, you // check if cookie is in the current cookie collection $store = new CookieStore([ - Cookie::create('login_token'), - Cookie::create('remember_token'), + new Cookie('login_token'), + new Cookie('remember_token'), ]); $store->has('login_token'); @@ -331,8 +317,8 @@ Retrieving a ``Cookie`` instance in a cookie collection is very easy:: // getting cookie in the current cookie collection $store = new CookieStore([ - Cookie::create('login_token'), - Cookie::create('remember_token'), + new Cookie('login_token'), + new Cookie('remember_token'), ]); $store->get('login_token'); @@ -389,12 +375,12 @@ in order to work on it. The original instance is left unchanged. use Config\Services; $store = new CookieStore([ - Cookie::create('login_token'), - Cookie::create('remember_token'), + new Cookie('login_token'), + new Cookie('remember_token'), ]); // adding a new Cookie instance - $new = $store->put(Cookie::create('admin_token', 'yes')); + $new = $store->put(new Cookie('admin_token', 'yes')); // removing a Cookie instance $new = $store->remove('login_token'); @@ -433,8 +419,8 @@ of ``headers_sent()``. use CodeIgniter\Cookie\CookieStore; $store = new CookieStore([ - Cookie::create('login_token'), - Cookie::create('remember_token'), + new Cookie('login_token'), + new Cookie('remember_token'), ]); $store->dispatch(); // After dispatch, the collection is now empty. @@ -445,19 +431,19 @@ Cookie Personalization Sane defaults are already in place inside the ``Cookie`` class to ensure the smooth creation of cookie objects. However, you may wish to define your own settings by changing the following settings in the -``Config\App`` class in ``app/Config/App.php`` file. +``Config\Cookie`` class in ``app/Config/Cookie.php`` file. ==================== ===================================== ========= ===================================================== Setting Options/ Types Default Description ==================== ===================================== ========= ===================================================== -**$cookiePrefix** ``string`` ``''`` Prefix to prepend to the cookie name. -**$cookieDomain** ``string`` ``''`` The domain property of the cookie. -**$cookiePath** ``string`` ``/`` The path property of the cookie, with trailing slash. -**$cookieSecure** ``true/false`` ``false`` If to be sent over secure HTTPS. -**$cookieHTTPOnly** ``true/false`` ``true`` If not accessible to JavaScript. -**$cookieSameSite** ``Lax|None|Strict|lax|none|strict''`` ``Lax`` The SameSite attribute. -**$cookieRaw** ``true/false`` ``false`` If to be dispatched using ``setrawcookie()``. -**$cookieExpires** ``DateTimeInterface|string|int`` ``0`` The expires timestamp. +**$prefix** ``string`` ``''`` Prefix to prepend to the cookie name. +**$expires** ``DateTimeInterface|string|int`` ``0`` The expires timestamp. +**$path** ``string`` ``/`` The path property of the cookie. +**$domain** ``string`` ``''`` The domain property of the cookie.with trailing slash. +**$secure** ``true/false`` ``false`` If to be sent over secure HTTPS. +**$httponly** ``true/false`` ``true`` If not accessible to JavaScript. +**$samesite** ``Lax|None|Strict|lax|none|strict''`` ``Lax`` The SameSite attribute. +**$raw** ``true/false`` ``false`` If to be dispatched using ``setrawcookie()``. ==================== ===================================== ========= ===================================================== In runtime, you can manually supply a new default using the ``Cookie::setDefaults()`` method. @@ -486,29 +472,11 @@ Class Reference Create a new Cookie instance from a ``Set-Cookie`` header. - .. php:staticmethod:: create(string $name[, string $value = ''[, array $options = []]]) + .. php:staticmethod:: __construct(string $name[, string $value = ''[, array $options = []]]) :param string $name: The cookie name :param string $value: The cookie value - :param aray $options: The cookie options - :rtype: ``Cookie`` - :returns: ``Cookie`` instance - :throws: ``CookieException`` - - Create Cookie objects on the fly. - - .. php:method:: __construct(string $name[, string $value = ''[, $expires = 0[, ?string $prefix = null[, ?string $path = null[, ?string $domain = null[, bool $secure = false[, bool $httpOnly = true[, bool $raw = false[, string $sameSite = self::SAMESITE_LAX]]]]]]]]]) - - :param string $name: - :param string $value: - :param DateTimeInterface|string|int $expires: - :param string|null $prefix: - :param string|null $path: - :param string|null $domain: - :param bool $secure: - :param bool $httpOnly: - :param bool $raw: - :param string $sameSite: + :param array $options: The cookie options :rtype: ``Cookie`` :returns: ``Cookie`` instance :throws: ``CookieException`` @@ -520,20 +488,20 @@ Class Reference :rtype: string :returns: The ID used in indexing in the cookie collection. - .. php:method:: isRaw(): bool .. php:method:: getPrefix(): string .. php:method:: getName(): string .. php:method:: getPrefixedName(): string .. php:method:: getValue(): string - .. php:method:: getExpiresTimestamp(): int + .. php:method:: getExpires(): int .. php:method:: getExpiresString(): string .. php:method:: isExpired(): bool .. php:method:: getMaxAge(): int .. php:method:: getDomain(): string .. php:method:: getPath(): string .. php:method:: isSecure(): bool - .. php:method:: isHttpOnly(): bool + .. php:method:: isHTTPOnly(): bool .. php:method:: getSameSite(): string + .. php:method:: isRaw(): bool .. php:method:: getOptions(): array .. php:method:: withRaw([bool $raw = true]) @@ -568,20 +536,15 @@ Class Reference Creates a new Cookie with new value. - .. php:method:: withExpiresAt($expires) + .. php:method:: withExpires([$expires = 0]) :param DateTimeInterface|string|int $expires: :rtype: ``Cookie`` :returns: new ``Cookie`` instance Creates a new Cookie with new cookie expires time. - - .. php:method:: withExpired() - - :rtype: ``Cookie`` - :returns: new ``Cookie`` instance - - Creates a new Cookie that will expire from the browser. + If $expires is equal to 0 (zero) the cookie will + expires from the browser. .. php:method:: withNeverExpiring() @@ -615,17 +578,17 @@ Class Reference Creates a new Cookie with new "Secure" attribute. - .. php:method:: withHttpOnly([bool $httpOnly = true]) + .. php:method:: withHTTPOnly([bool $httponly = true]) - :param bool $httpOnly: + :param bool $httponly: :rtype: ``Cookie`` :returns: new ``Cookie`` instance - Creates a new Cookie with new "HttpOnly" attribute. + Creates a new Cookie with new "HTTPOnly" attribute. - .. php:method:: withSameSite(string $sameSite) + .. php:method:: withSameSite(string $samesite) - :param string $sameSite: + :param string $samesite: :rtype: ``Cookie`` :returns: new ``Cookie`` instance