diff --git a/composer.lock b/composer.lock index f37f6e35..5472c395 100644 --- a/composer.lock +++ b/composer.lock @@ -8,33 +8,33 @@ "packages": [ { "name": "laminas/laminas-eventmanager", - "version": "3.13.1", + "version": "3.14.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-eventmanager.git", - "reference": "933d1b5cf03fa4cf3016cebfd0555fa2ba3f2024" + "reference": "1837cafaaaee74437f6d8ec9ff7da03e6f81d809" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-eventmanager/zipball/933d1b5cf03fa4cf3016cebfd0555fa2ba3f2024", - "reference": "933d1b5cf03fa4cf3016cebfd0555fa2ba3f2024", + "url": "https://api.github.com/repos/laminas/laminas-eventmanager/zipball/1837cafaaaee74437f6d8ec9ff7da03e6f81d809", + "reference": "1837cafaaaee74437f6d8ec9ff7da03e6f81d809", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { "container-interop/container-interop": "<1.2", "zendframework/zend-eventmanager": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-stdlib": "^3.18", - "phpbench/phpbench": "^1.2.15", - "phpunit/phpunit": "^10.5.5", - "psalm/plugin-phpunit": "^0.18.4", + "laminas/laminas-coding-standard": "~3.0.0", + "laminas/laminas-stdlib": "^3.20", + "phpbench/phpbench": "^1.3.1", + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", "psr/container": "^1.1.2 || ^2.0.2", - "vimeo/psalm": "^5.18" + "vimeo/psalm": "^5.26.1" }, "suggest": { "laminas/laminas-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature", @@ -72,7 +72,7 @@ "type": "community_bridge" } ], - "time": "2024-06-24T14:01:06+00:00" + "time": "2024-11-21T11:31:22+00:00" }, { "name": "laminas/laminas-servicemanager", @@ -849,29 +849,27 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -879,7 +877,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -890,9 +888,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "felixfbecker/advanced-json-rpc", @@ -1191,8 +1189,8 @@ "type": "library", "extra": { "laminas": { - "config-provider": "Laminas\\Cache\\Storage\\Adapter\\Memory\\ConfigProvider", - "module": "Laminas\\Cache\\Storage\\Adapter\\Memory" + "module": "Laminas\\Cache\\Storage\\Adapter\\Memory", + "config-provider": "Laminas\\Cache\\Storage\\Adapter\\Memory\\ConfigProvider" } }, "autoload": { @@ -1412,23 +1410,23 @@ }, { "name": "laminas/laminas-http", - "version": "2.20.0", + "version": "2.21.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-http.git", - "reference": "a66bfb65c698aad6ee9f10df42cb5902f2c3dec8" + "reference": "a9867e4d1cda3dbad208903239c83a3d670cce10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-http/zipball/a66bfb65c698aad6ee9f10df42cb5902f2c3dec8", - "reference": "a66bfb65c698aad6ee9f10df42cb5902f2c3dec8", + "url": "https://api.github.com/repos/laminas/laminas-http/zipball/a9867e4d1cda3dbad208903239c83a3d670cce10", + "reference": "a9867e4d1cda3dbad208903239c83a3d670cce10", "shasum": "" }, "require": { "laminas/laminas-loader": "^2.10", "laminas/laminas-stdlib": "^3.6", "laminas/laminas-uri": "^2.11", - "laminas/laminas-validator": "^2.15", + "laminas/laminas-validator": "^2.15 || ^3.0", "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { @@ -1473,20 +1471,20 @@ "type": "community_bridge" } ], - "time": "2024-10-18T07:35:59+00:00" + "time": "2024-12-04T09:17:39+00:00" }, { "name": "laminas/laminas-loader", - "version": "2.11.0", + "version": "2.11.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-loader.git", - "reference": "f2eedd3a6e774d965158fd11946bb1eba72e298c" + "reference": "c507d5eccb969f7208434e3980680a1f6c0b1d8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/f2eedd3a6e774d965158fd11946bb1eba72e298c", - "reference": "f2eedd3a6e774d965158fd11946bb1eba72e298c", + "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/c507d5eccb969f7208434e3980680a1f6c0b1d8d", + "reference": "c507d5eccb969f7208434e3980680a1f6c0b1d8d", "shasum": "" }, "require": { @@ -1529,25 +1527,26 @@ "type": "community_bridge" } ], - "time": "2024-10-16T09:06:57+00:00" + "abandoned": true, + "time": "2024-12-05T14:43:32+00:00" }, { "name": "laminas/laminas-uri", - "version": "2.12.0", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-uri.git", - "reference": "95a41a7592bacf4c648648a88b7c94b0c5c22b9e" + "reference": "de53600ae8153b3605bb6edce8aeeef524eaafba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-uri/zipball/95a41a7592bacf4c648648a88b7c94b0c5c22b9e", - "reference": "95a41a7592bacf4c648648a88b7c94b0c5c22b9e", + "url": "https://api.github.com/repos/laminas/laminas-uri/zipball/de53600ae8153b3605bb6edce8aeeef524eaafba", + "reference": "de53600ae8153b3605bb6edce8aeeef524eaafba", "shasum": "" }, "require": { "laminas/laminas-escaper": "^2.9", - "laminas/laminas-validator": "^2.39", + "laminas/laminas-validator": "^2.39 || ^3.0", "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { @@ -1587,20 +1586,20 @@ "type": "community_bridge" } ], - "time": "2024-08-03T21:22:51+00:00" + "time": "2024-12-03T12:27:51+00:00" }, { "name": "laminas/laminas-validator", - "version": "2.64.1", + "version": "2.64.2", "source": { "type": "git", "url": "https://github.com/laminas/laminas-validator.git", - "reference": "9db115056b666b7540c951b6d4477b8e0b52b9ad" + "reference": "771e504760448ac7af660710237ceb93be602e08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/9db115056b666b7540c951b6d4477b8e0b52b9ad", - "reference": "9db115056b666b7540c951b6d4477b8e0b52b9ad", + "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/771e504760448ac7af660710237ceb93be602e08", + "reference": "771e504760448ac7af660710237ceb93be602e08", "shasum": "" }, "require": { @@ -1671,7 +1670,7 @@ "type": "community_bridge" } ], - "time": "2024-08-01T09:32:54+00:00" + "time": "2024-11-26T21:29:17+00:00" }, { "name": "mongodb/mongodb", @@ -2090,16 +2089,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c" + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c", - "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", "shasum": "" }, "require": { @@ -2148,9 +2147,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" }, - "time": "2024-11-12T11:25:25+00:00" + "time": "2024-12-07T09:39:29+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -4215,16 +4214,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -4262,7 +4261,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -4278,7 +4277,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", @@ -4822,16 +4821,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -4885,7 +4884,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -4901,7 +4900,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", @@ -5114,11 +5113,11 @@ "type": "project", "extra": { "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", + "dev-1.x": "1.x-dev", "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-master": "5.x-dev" } }, "autoload": { diff --git a/src/SessionManager.php b/src/SessionManager.php index 3bb41b3c..2f969a3d 100644 --- a/src/SessionManager.php +++ b/src/SessionManager.php @@ -9,6 +9,8 @@ use function array_key_exists; use function array_merge; +use function constant; +use function defined; use function headers_sent; use function is_array; use function iterator_to_array; @@ -91,12 +93,19 @@ public function sessionExists() return true; } - if ($this->getId()) { + /** + * @var string|false $sid + */ + $sid = defined('SID') ? constant('SID') : false; + + if ($sid !== false && $this->getId()) { return true; } + if (headers_sent()) { return true; } + return false; } diff --git a/test/SessionManagerTest.php b/test/SessionManagerTest.php index 301f7034..ceb684cf 100644 --- a/test/SessionManagerTest.php +++ b/test/SessionManagerTest.php @@ -17,6 +17,8 @@ use Laminas\Session\Validator\Id; use Laminas\Session\Validator\RemoteAddr; use LaminasTest\Session\TestAsset\Php81CompatibleStorageInterface; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; use PHPUnit\Framework\TestCase; use Traversable; @@ -35,6 +37,7 @@ use function session_write_close; use function set_error_handler; use function stristr; +use function uniqid; use function var_export; use function xdebug_get_headers; @@ -157,20 +160,14 @@ public function testCanDisableAttachDefaultValidators(): void $this->assertAttributeEquals([], 'validators', $manager); } - // Session-related functionality - - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSessionExistsReturnsFalseWhenNoSessionStarted(): void { $this->manager = new SessionManager(); self::assertFalse($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSessionExistsReturnsTrueWhenSessionStarted(): void { $this->manager = new SessionManager(); @@ -178,9 +175,8 @@ public function testSessionExistsReturnsTrueWhenSessionStarted(): void self::assertTrue($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testSessionExistsReturnsTrueWhenSessionStartedThenWritten(): void { $this->manager = new SessionManager(); @@ -189,9 +185,8 @@ public function testSessionExistsReturnsTrueWhenSessionStartedThenWritten(): voi self::assertTrue($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testSessionExistsReturnsFalseWhenSessionStartedThenDestroyed(): void { $this->manager = new SessionManager(); @@ -200,9 +195,7 @@ public function testSessionExistsReturnsFalseWhenSessionStartedThenDestroyed(): self::assertFalse($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSessionIsStartedAfterCallingStart(): void { $this->manager = new SessionManager(); @@ -211,9 +204,8 @@ public function testSessionIsStartedAfterCallingStart(): void self::assertTrue($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testStartDoesNothingWhenCalledAfterWriteCloseOperation(): void { $this->manager = new SessionManager(); @@ -226,9 +218,7 @@ public function testStartDoesNothingWhenCalledAfterWriteCloseOperation(): void self::assertEquals($id1, $id2); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testStartWithOldTraversableSessionData(): void { // pre-populate session with data @@ -245,9 +235,7 @@ public function testStartWithOldTraversableSessionData(): void self::assertEquals('value2', $_SESSION->key2); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testStorageContentIsPreservedByWriteCloseOperation(): void { $this->manager = new SessionManager(); @@ -259,9 +247,8 @@ public function testStorageContentIsPreservedByWriteCloseOperation(): void self::assertEquals('bar', $storage['foo']); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testStartCreatesNewSessionIfPreviousSessionHasBeenDestroyed(): void { $this->manager = new SessionManager(); @@ -274,9 +261,7 @@ public function testStartCreatesNewSessionIfPreviousSessionHasBeenDestroyed(): v self::assertNotEquals($id1, $id2); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testStartConvertsSessionDataFromStorageInterfaceToArrayBeforeMerging(): void { $this->manager = new SessionManager(); @@ -298,9 +283,7 @@ public function testStartConvertsSessionDataFromStorageInterfaceToArrayBeforeMer self::assertSame($data[$key], $_SESSION[$key]); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testStartConvertsSessionDataFromTraversableToArrayBeforeMerging(): void { $this->manager = new SessionManager(); @@ -334,9 +317,7 @@ public function testStartWillNotBlockHeaderSentNotices(): void self::assertContains('already sent', $this->error); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testGetNameReturnsSessionName(): void { $this->manager = new SessionManager(); @@ -344,9 +325,7 @@ public function testGetNameReturnsSessionName(): void self::assertEquals($ini, $this->manager->getName()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSetNameRaisesExceptionOnInvalidName(): void { $this->manager = new SessionManager(); @@ -355,9 +334,7 @@ public function testSetNameRaisesExceptionOnInvalidName(): void $this->manager->setName('foo bar!'); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSetNameSetsSessionNameOnSuccess(): void { $this->manager = new SessionManager(); @@ -366,9 +343,8 @@ public function testSetNameSetsSessionNameOnSuccess(): void self::assertEquals('foobar', session_name()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testCanSetNewSessionNameAfterSessionDestroyed(): void { $this->manager = new SessionManager(); @@ -379,9 +355,7 @@ public function testCanSetNewSessionNameAfterSessionDestroyed(): void self::assertEquals('foobar', session_name()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSettingNameWhenAnActiveSessionExistsRaisesException(): void { $this->manager = new SessionManager(); @@ -391,9 +365,7 @@ public function testSettingNameWhenAnActiveSessionExistsRaisesException(): void $this->manager->setName('foobar'); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testDestroyByDefaultSendsAnExpireCookie(): void { if (! extension_loaded('xdebug')) { @@ -424,9 +396,7 @@ public function testDestroyByDefaultSendsAnExpireCookie(): void self::assertTrue($found, 'No session cookie found: ' . var_export($headers, true)); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSendingFalseToSendExpireCookieWhenCallingDestroyShouldNotSendCookie(): void { if (! extension_loaded('xdebug')) { @@ -461,9 +431,7 @@ public function testSendingFalseToSendExpireCookieWhenCallingDestroyShouldNotSen } } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testDestroyDoesNotClearSessionStorageByDefault(): void { $this->manager = new SessionManager(); @@ -475,9 +443,7 @@ public function testDestroyDoesNotClearSessionStorageByDefault(): void self::assertEquals('bar', $storage['foo']); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testPassingClearStorageOptionWhenCallingDestroyClearsStorage(): void { $this->manager = new SessionManager(); @@ -488,9 +454,7 @@ public function testPassingClearStorageOptionWhenCallingDestroyClearsStorage(): self::assertFalse(isset($storage['foo'])); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testDestroySessionWhenHeadersHaveBeenSent(): void { $this->manager = new SessionManager(); @@ -503,9 +467,7 @@ public function testDestroySessionWhenHeadersHaveBeenSent(): void self::assertFalse(isset($storage['foo'])); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testCallingWriteCloseMarksStorageAsImmutable(): void { $this->manager = new SessionManager(); @@ -516,9 +478,8 @@ public function testCallingWriteCloseMarksStorageAsImmutable(): void self::assertTrue($storage->isImmutable()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] + #[IgnoreDeprecations] public function testCallingWriteCloseShouldNotAlterSessionExistsStatus(): void { $this->manager = new SessionManager(); @@ -527,18 +488,14 @@ public function testCallingWriteCloseShouldNotAlterSessionExistsStatus(): void self::assertTrue($this->manager->sessionExists()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testIdShouldBeEmptyPriorToCallingStart(): void { $this->manager = new SessionManager(); self::assertSame('', $this->manager->getId()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testIdShouldBeMutablePriorToCallingStart(): void { $this->manager = new SessionManager(); @@ -547,9 +504,7 @@ public function testIdShouldBeMutablePriorToCallingStart(): void self::assertSame(self::class, session_id()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testIdShouldNotBeMutableAfterSessionStarted(): void { $this->manager = new SessionManager(); @@ -561,9 +516,7 @@ public function testIdShouldNotBeMutableAfterSessionStarted(): void $this->manager->setId(__METHOD__); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRegenerateIdShouldWorkAfterSessionStarted(): void { $this->manager = new SessionManager(); @@ -573,9 +526,7 @@ public function testRegenerateIdShouldWorkAfterSessionStarted(): void self::assertNotSame($origId, $this->manager->getId()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRegenerateIdDoesNothingWhenSessioIsNotStarted(): void { $this->manager = new SessionManager(); @@ -585,9 +536,7 @@ public function testRegenerateIdDoesNothingWhenSessioIsNotStarted(): void self::assertEquals('', $this->manager->getId()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRegeneratingIdAfterSessionStartedShouldSendExpireCookie(): void { if (! extension_loaded('xdebug')) { @@ -617,9 +566,7 @@ public function testRegeneratingIdAfterSessionStartedShouldSendExpireCookie(): v self::assertTrue($found, 'No session cookie found: ' . var_export($headers, true)); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRememberMeShouldSendNewSessionCookieWithUpdatedTimestamp(): void { if (! extension_loaded('xdebug')) { @@ -663,9 +610,7 @@ public function testRememberMeShouldSendNewSessionCookieWithUpdatedTimestamp(): ); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRememberMeShouldSetTimestampBasedOnConfigurationByDefault(): void { if (! extension_loaded('xdebug')) { @@ -715,9 +660,7 @@ public function testRememberMeShouldSetTimestampBasedOnConfigurationByDefault(): ); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testForgetMeShouldSendCookieWithZeroTimestamp(): void { if (! extension_loaded('xdebug')) { @@ -748,9 +691,7 @@ public function testForgetMeShouldSendCookieWithZeroTimestamp(): void self::assertStringNotContainsString('expires=', $header); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testStartingSessionThatFailsAValidatorShouldRaiseException(): void { $this->manager = new SessionManager(); @@ -761,9 +702,7 @@ public function testStartingSessionThatFailsAValidatorShouldRaiseException(): vo $this->manager->start(); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testResumeSessionThatFailsAValidatorShouldRaiseException(): void { $this->manager = new SessionManager(); @@ -773,9 +712,7 @@ public function testResumeSessionThatFailsAValidatorShouldRaiseException(): void $this->manager->start(); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSessionWriteCloseStoresMetadata(): void { $this->manager = new SessionManager(); @@ -787,9 +724,7 @@ public function testSessionWriteCloseStoresMetadata(): void self::assertSame($_SESSION['__Laminas'], $metaData); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testSessionValidationDoesNotHaltOnNoopListener(): void { $this->manager = new SessionManager(); @@ -804,9 +739,7 @@ public function testSessionValidationDoesNotHaltOnNoopListener(): void self::assertTrue($validatorCalled); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testProducedSessionManagerWillNotReplaceSessionSuperGlobalValues(): void { $this->manager = new SessionManager(); @@ -818,9 +751,7 @@ public function testProducedSessionManagerWillNotReplaceSessionSuperGlobalValues self::assertSame('bar', $_SESSION['foo']); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testValidatorChainSessionMetadataIsPreserved(): void { $this->manager = new SessionManager(); @@ -836,9 +767,7 @@ public function testValidatorChainSessionMetadataIsPreserved(): void self::assertEquals('', $_SESSION['__Laminas']['_VALID'][RemoteAddr::class]); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRemoteAddressValidationWillFailOnInvalidAddress(): void { $this->manager = new SessionManager(); @@ -850,9 +779,7 @@ public function testRemoteAddressValidationWillFailOnInvalidAddress(): void $this->manager->start(); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRemoteAddressValidationWillSucceedWithValidPreSetData(): void { $this->manager = new SessionManager(); @@ -869,9 +796,7 @@ public function testRemoteAddressValidationWillSucceedWithValidPreSetData(): voi self::assertTrue($this->manager->isValid()); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testRemoteAddressValidationWillFailWithInvalidPreSetData(): void { $this->manager = new SessionManager(); @@ -888,9 +813,7 @@ public function testRemoteAddressValidationWillFailWithInvalidPreSetData(): void $this->manager->start(); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testIdValidationWillFailOnInvalidData(): void { $this->manager = new SessionManager(); @@ -902,6 +825,30 @@ public function testIdValidationWillFailOnInvalidData(): void $this->manager->start(); } + #[RunInSeparateProcess] + #[IgnoreDeprecations] + public function testSettingTheIdentifierBeforeStartingTheSessionYieldsTheExpectedId(): void + { + $manager = new SessionManager(); + + $id = uniqid(); + + $manager->setId($id); + + // setting a session id does not mark a session as started + self::assertFalse($manager->sessionExists()); + + $manager->start(); + + self::assertTrue($manager->sessionExists()); + + $manager->writeClose(); + + // calling writeClose() does not mark the session as closed + self::assertTrue($manager->sessionExists()); + self::assertSame($id, $manager->getId()); + } + /** @param non-empty-string $property */ private function assertAttributeEquals(mixed $expected, string $property, object $object): void {