diff --git a/src/Sifo/Cookie.php b/src/Sifo/Cookie.php index 7ad4507c..82f30253 100644 --- a/src/Sifo/Cookie.php +++ b/src/Sifo/Cookie.php @@ -53,19 +53,14 @@ static private function _initDomain() self::$path = '/'; } - static public function set( $name, $value, $days = 14, $domain = false ) + static public function set( $name, $value, $days = 14, $domain = false, $secure = false, $httpOnly = false, string $samesite = null ) { - $domain ?: self::_initDomain(); - if ( 0 == $days ) - { - $result = setcookie( $name, $value, 0, self::$path, self::$domain ); - } - else - { - $result = setcookie( $name, $value, time() + ( 86400 * $days ), self::$path, self::$domain ); - } + $expires = 0 == $days ? 0 : time() + ( 86400 * $days ); + + $result = static::setCookie( $name, $value, $expires, self::$path, self::$domain, $secure, $httpOnly, $samesite ); + if ( !$result ) { trigger_error( "COOKIE WRITE FAIL: Tried to write '$name' with value '$value' but failed." ); @@ -81,7 +76,7 @@ static public function set( $name, $value, $days = 14, $domain = false ) static public function delete( $name ) { self::_initDomain(); - $result = setcookie( $name, '', time() - 3600, self::$path, self::$domain ); + $result = static::setCookie( $name, '', time() - 3600, self::$path, self::$domain); if ( !$result ) { trigger_error( "COOKIE DELETE FAIL: Tried to delete '$name' but failed." ); @@ -140,4 +135,21 @@ static private function _sanitizeCookie( $cookie ) return false; } -} \ No newline at end of file + + static protected function setCookie(string $name, $value = "", $expires = 0, $path = "", $domain = "", $secure = false, $httponly = false, string $samesite = null): bool + { + $options = [ + 'expires' => $expires, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly, + ]; + + if ( $samesite !== null) { + $options['samesite'] = $samesite; + } + + return setcookie( $name, $value, $options ); + } +} diff --git a/test/Sifo/CookieTest.php b/test/Sifo/CookieTest.php new file mode 100644 index 00000000..364a3101 --- /dev/null +++ b/test/Sifo/CookieTest.php @@ -0,0 +1,104 @@ +assertEquals( + $defaultExpiration, + TestCookie::getExpires($cookieName), + "Expires doesn't match with expected." + ); + $this->assertSame( + 'sifo.local', + TestCookie::getDomain($cookieName), + "Domain doesn't match with expected." + ); + $this->assertSame( + '/', + TestCookie::getPath($cookieName), + "Path doesn't match with expected." + ); + $this->assertNull(TestCookie::getSameSite($cookieName)); + $this->assertFalse(TestCookie::isSecure($cookieName)); + $this->assertFalse(TestCookie::isHttpOnly($cookieName)); + } + + public function testCookieCanBeSetWithoutExpiration(): void + { + $cookieName = 'test_cookie'; + + TestCookie::set($cookieName, 'oreo', 0); + + $this->assertSame(0, TestCookie::getExpires($cookieName)); + } + + public function testCookieIsSetWithCustomParameters(): void + { + $cookieName = 'test_cookie'; + $expirationDays = 7; + $defaultExpiration = time() + ( 86400 * $expirationDays ); + + TestCookie::set($cookieName, 'chips_ahoy', $expirationDays, false, true, true, 'Lax'); + + $this->assertEquals( + $defaultExpiration, + TestCookie::getExpires($cookieName), + "Expires doesn't match with expected." + ); + $this->assertSame( + 'sifo.local', + TestCookie::getDomain($cookieName), + "Domain doesn't match with expected." + ); + $this->assertSame( + '/', + TestCookie::getPath($cookieName), + "Path doesn't match with expected." + ); + $this->assertSame( + 'Lax', + TestCookie::getSameSite($cookieName), + "Same site doesn't match with expected." + ); + $this->assertTrue(TestCookie::isSecure($cookieName)); + $this->assertTrue(TestCookie::isHttpOnly($cookieName)); + } + + public function testCookieValueIsStoredInFilterCookie(): void + { + $cookieName = 'test_cookie'; + + TestCookie::set($cookieName, 'oreo'); + + $this->assertSame( + 'oreo', + FilterCookieRuntime::getInstance()->getString('test_cookie') + ); + } + + public function testCookieValueIsDeletedFromFilterCookie(): void + { + $cookieName = 'test_cookie'; + + TestCookie::set($cookieName, 'oreo'); + TestCookie::delete($cookieName); + + $this->assertTrue(FilterCookieRuntime::getInstance()->isEmpty('test_cookie')); + } +} diff --git a/test/Sifo/TestCookie.php b/test/Sifo/TestCookie.php new file mode 100644 index 00000000..ffbfd681 --- /dev/null +++ b/test/Sifo/TestCookie.php @@ -0,0 +1,92 @@ + $value, + 'expires' => $expires, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly, + 'samesite' => $samesite, + ]; + + return true; + } + + public static function getCookieParam(string $name, string $param) + { + if (!array_key_exists($name, self::$cookies)) { + throw new InvalidArgumentException("Cookie of name $name is not set."); + } + + if (!array_key_exists($param, self::$cookies[$name] ?? [])) { + return null; + } + + return self::$cookies[$name][$param]; + } + + public static function getValue(string $name): string + { + return (string) self::getCookieParam($name, 'value'); + } + + public static function getExpires(string $name) + { + return self::getCookieParam($name, 'expires'); + } + + public static function getPath(string $name): string + { + return (string) self::getCookieParam($name, 'path'); + } + + public static function getDomain(string $name): string + { + return (string) self::getCookieParam($name, 'domain'); + } + + public static function isSecure(string $name): bool + { + return (bool) self::getCookieParam($name, 'secure'); + } + + public static function isHttpOnly(string $name): bool + { + return (bool) self::getCookieParam($name, 'httponly'); + } + + public static function getSameSite(string $name): ?string + { + return self::getCookieParam($name, 'samesite'); + } + + public static function clearCookies(): void + { + self::$cookies = []; + } +}