diff --git a/.github/workflows/rector-cs.yml b/.github/workflows/rector-cs.yml new file mode 100644 index 0000000..e79b80c --- /dev/null +++ b/.github/workflows/rector-cs.yml @@ -0,0 +1,27 @@ +name: Rector & CS fix + +on: + pull_request: + paths: + - 'config/**' + - 'src/**' + - 'tests/**' + - 'rector.php' + - '.php-cs-fixer.dist.php' + - 'composer.json' + - '.github/workflows/rector-cs.yml' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rector-cs: + permissions: + contents: write # Required to commit formatting fixes back to the PR + uses: yiisoft/actions/.github/workflows/rector-cs.yml@master + with: + php: '8.0' diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml deleted file mode 100644 index 11a3e74..0000000 --- a/.github/workflows/rector.yml +++ /dev/null @@ -1,26 +0,0 @@ -on: - pull_request: - paths-ignore: - - 'docs/**' - - 'README.md' - - 'CHANGELOG.md' - - '.gitignore' - - '.gitattributes' - - 'infection.json.dist' - - 'psalm.xml' - -name: rector - -permissions: - contents: read - -jobs: - rector: - permissions: - contents: write # Required to commit automated Rector and CS fixes. - uses: yiisoft/actions/.github/workflows/rector.yml@master - with: - os: >- - ['ubuntu-latest'] - php: >- - ['8.4'] diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..9851c4e --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,23 @@ +in([ + __DIR__ . '/src', + __DIR__ . '/tests', + __DIR__ . '/config', +]); + +return ConfigBuilder::build() + ->setCacheFile(__DIR__ . '/runtime/.php-cs-fixer.cache') + ->setRiskyAllowed(true) + ->setParallelConfig(ParallelConfigFactory::detect()) + ->setRules([ + '@Yiisoft/Core' => true, + '@Yiisoft/Core:risky' => true, + ]) + ->setFinder($finder); diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 1ab379b..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,85 +0,0 @@ -preset: psr12 -risky: true - -version: 8.1 - -finder: - exclude: - - docs - - vendor - -enabled: - - alpha_ordered_traits - - array_indentation - - array_push - - combine_consecutive_issets - - combine_consecutive_unsets - - combine_nested_dirname - - declare_strict_types - - dir_constant - - fully_qualified_strict_types - - function_to_constant - - hash_to_slash_comment - - is_null - - logical_operators - - magic_constant_casing - - magic_method_casing - - method_separation - - modernize_types_casting - - native_function_casing - - native_function_type_declaration_casing - - no_alias_functions - - no_empty_comment - - no_empty_phpdoc - - no_empty_statement - - no_extra_block_blank_lines - - no_short_bool_cast - - no_superfluous_elseif - - no_unneeded_control_parentheses - - no_unneeded_curly_braces - - no_unneeded_final_method - - no_unset_cast - - no_unused_imports - - no_unused_lambda_imports - - no_useless_else - - no_useless_return - - normalize_index_brace - - php_unit_dedicate_assert - - php_unit_dedicate_assert_internal_type - - php_unit_expectation - - php_unit_mock - - php_unit_mock_short_will_return - - php_unit_namespaced - - php_unit_no_expectation_annotation - - phpdoc_no_empty_return - - phpdoc_no_useless_inheritdoc - - phpdoc_order - - phpdoc_property - - phpdoc_scalar - - phpdoc_singular_inheritdoc - - phpdoc_trim - - phpdoc_trim_consecutive_blank_line_separation - - phpdoc_type_to_var - - phpdoc_types - - phpdoc_types_order - - print_to_echo - - regular_callable_call - - return_assignment - - self_accessor - - self_static_accessor - - set_type_to_cast - - short_array_syntax - - short_list_syntax - - simplified_if_return - - single_quote - - standardize_not_equals - - ternary_to_null_coalescing - - trailing_comma_in_multiline_array - - unalign_double_arrow - - unalign_equals - - empty_loop_body_braces - - integer_literal_case - - union_type_without_spaces - -disabled: - - function_declaration diff --git a/CHANGELOG.md b/CHANGELOG.md index 772bcfa..f04b5bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 3.0.2 under development -- no changes in this release. +- Chg #81: Add explicit use imports for classes and constants (@vjik) ## 3.0.1 December 17, 2025 diff --git a/composer.json b/composer.json index a1b22fd..41f3173 100644 --- a/composer.json +++ b/composer.json @@ -37,13 +37,15 @@ "yiisoft/cookies": "^1.0" }, "require-dev": { - "maglnet/composer-require-checker": "^4.4", + "bamarni/composer-bin-plugin": "*", + "friendsofphp/php-cs-fixer": "^3.95", "nyholm/psr7": "^1.8.2", "phpunit/phpunit": "^9.6.22", "rector/rector": "^2.0.10", "roave/infection-static-analysis-plugin": "^1.25", "spatie/phpunit-watcher": "^1.23.6", "vimeo/psalm": "^4.30 || ^5.6 || ^6.8.8", + "yiisoft/code-style": "^1.0", "yiisoft/di": "^1.2.1" }, "suggest": { @@ -60,6 +62,11 @@ } }, "extra": { + "bamarni-bin": { + "bin-links": true, + "target-directory": "tools", + "forward-command": true + }, "config-plugin-options": { "source-directory": "config" }, @@ -72,10 +79,13 @@ "sort-packages": true, "allow-plugins": { "infection/extension-installer": true, - "composer/package-versions-deprecated": true + "composer/package-versions-deprecated": true, + "bamarni/composer-bin-plugin": true } }, "scripts": { + "cs-fix": "php-cs-fixer fix", + "rector": "rector", "test": "phpunit --testdox --no-interaction", "test-watch": "phpunit-watcher watch" } diff --git a/rector.php b/rector.php index 63713ce..f6a4dcd 100644 --- a/rector.php +++ b/rector.php @@ -4,19 +4,18 @@ use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector; use Rector\Config\RectorConfig; -use Rector\Set\ValueObject\LevelSetList; +use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; -return static function (RectorConfig $rectorConfig): void { - $rectorConfig->paths([ +return RectorConfig::configure() + ->withPaths([ __DIR__ . '/src', __DIR__ . '/tests', + __DIR__ . '/config', + ]) + ->withPhpSets(php80: true) + ->withRules([ + InlineConstructorDefaultToPropertyRector::class, + ]) + ->withSkip([ + ClosureToArrowFunctionRector::class, ]); - - // register a single rule - $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); - - // define sets of rules - $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_80, - ]); -}; diff --git a/runtime/.gitignore b/runtime/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/Flash/Flash.php b/src/Flash/Flash.php index 207df27..e7682eb 100644 --- a/src/Flash/Flash.php +++ b/src/Flash/Flash.php @@ -20,9 +20,7 @@ final class Flash implements FlashInterface private ?string $sessionId = null; - public function __construct(private SessionInterface $session) - { - } + public function __construct(private SessionInterface $session) {} public function get(string $key) { diff --git a/src/NullSession.php b/src/NullSession.php index 7602e34..9faf51c 100644 --- a/src/NullSession.php +++ b/src/NullSession.php @@ -14,39 +14,27 @@ public function get(string $key, $default = null) return null; } - public function set(string $key, $value): void - { - } + public function set(string $key, $value): void {} - public function close(): void - { - } + public function close(): void {} - public function open(): void - { - } + public function open(): void {} public function isActive(): bool { return false; } - public function regenerateId(): void - { - } + public function regenerateId(): void {} - public function discard(): void - { - } + public function discard(): void {} public function all(): array { return []; } - public function remove(string $key): void - { - } + public function remove(string $key): void {} public function has(string $key): bool { @@ -58,9 +46,7 @@ public function pull(string $key, $default = null) return null; } - public function destroy(): void - { - } + public function destroy(): void {} public function getCookieParameters(): array { @@ -72,16 +58,12 @@ public function getId(): ?string return null; } - public function setId(string $sessionId): void - { - } + public function setId(string $sessionId): void {} public function getName(): string { return 'null'; } - public function clear(): void - { - } + public function clear(): void {} } diff --git a/src/Session.php b/src/Session.php index 5b3ca4b..a83fede 100644 --- a/src/Session.php +++ b/src/Session.php @@ -7,6 +7,8 @@ use SessionHandlerInterface; use Throwable; +use const PHP_SESSION_ACTIVE; + /** * Session provides session data management and the related configurations. * @@ -99,7 +101,7 @@ public function open(): void */ $this->sessionId = session_id(); } catch (Throwable $e) { - throw new SessionException('Failed to start session.', (int)$e->getCode(), $e); + throw new SessionException('Failed to start session.', (int) $e->getCode(), $e); } } @@ -124,7 +126,7 @@ public function regenerateId(): void $this->sessionId = session_id(); } } catch (Throwable $e) { - throw new SessionException('Failed to regenerate ID.', (int)$e->getCode(), $e); + throw new SessionException('Failed to regenerate ID.', (int) $e->getCode(), $e); } } } diff --git a/src/SessionException.php b/src/SessionException.php index 344ea05..6c37b8b 100644 --- a/src/SessionException.php +++ b/src/SessionException.php @@ -6,6 +6,4 @@ use RuntimeException; -final class SessionException extends RuntimeException -{ -} +final class SessionException extends RuntimeException {} diff --git a/src/SessionMiddleware.php b/src/SessionMiddleware.php index 73a060d..7e337bf 100644 --- a/src/SessionMiddleware.php +++ b/src/SessionMiddleware.php @@ -11,6 +11,7 @@ use Psr\Http\Server\RequestHandlerInterface; use Throwable; use Yiisoft\Cookies\Cookie; +use Exception; /** * Session middleware handles storing session ID into a response cookie and @@ -18,9 +19,7 @@ */ final class SessionMiddleware implements MiddlewareInterface { - public function __construct(private SessionInterface $session) - { - } + public function __construct(private SessionInterface $session) {} public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { @@ -42,7 +41,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface /** * Close session and add/modify response session cookie if necessary. * - * @throws \Exception + * @throws Exception */ private function commitSession(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { @@ -83,8 +82,8 @@ private function commitSession(ServerRequestInterface $request, ResponseInterfac ->getUri() ->getScheme() !== 'https') { throw new SessionException( - '"cookie_secure" is on but connection is not secure. ' . - 'Either set Session "cookie_secure" option to "0" or make connection secure.' + '"cookie_secure" is on but connection is not secure. ' + . 'Either set Session "cookie_secure" option to "0" or make connection secure.', ); } diff --git a/tests/BadSessionHandler.php b/tests/BadSessionHandler.php index 1d8c695..e650361 100644 --- a/tests/BadSessionHandler.php +++ b/tests/BadSessionHandler.php @@ -4,11 +4,14 @@ namespace Yiisoft\Session\Tests; -final class BadSessionHandler implements \SessionHandlerInterface +use ReturnTypeWillChange; +use SessionHandlerInterface; + +use function in_array; + +final class BadSessionHandler implements SessionHandlerInterface { - public function __construct(private array $failAt = []) - { - } + public function __construct(private array $failAt = []) {} public function close(): bool { @@ -20,7 +23,7 @@ public function destroy($session_id): bool return $this->getReturnValue('destroy'); } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function gc($maxlifetime) { return $this->getReturnValue('gc'); @@ -31,7 +34,7 @@ public function open($save_path, $name): bool return $this->getReturnValue('open'); } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function read($session_id) { return ''; diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 0f50d3b..a8c6137 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -12,6 +12,8 @@ use Yiisoft\Session\Session; use Yiisoft\Session\SessionInterface; +use function dirname; + final class ConfigTest extends TestCase { public function testBase(): void @@ -29,8 +31,8 @@ private function createContainer(?array $params = null): Container { return new Container( ContainerConfig::create()->withDefinitions( - $this->getDiConfig($params) - ) + $this->getDiConfig($params), + ), ); } diff --git a/tests/Flash/FlashTest.php b/tests/Flash/FlashTest.php index 7177a79..1f2c751 100644 --- a/tests/Flash/FlashTest.php +++ b/tests/Flash/FlashTest.php @@ -15,11 +15,6 @@ final class FlashTest extends TestCase */ private SessionInterface $session; - private function getSession(array $contents = []): SessionInterface - { - return new MockArraySessionStorage($contents); - } - protected function setUp(): void { parent::setUp(); @@ -235,4 +230,9 @@ public function testGetAll(): void 'error' => 'Some error message to show', ], $flashes); } + + private function getSession(array $contents = []): SessionInterface + { + return new MockArraySessionStorage($contents); + } } diff --git a/tests/Flash/MockArraySessionStorage.php b/tests/Flash/MockArraySessionStorage.php index 08b19eb..bb7ce70 100644 --- a/tests/Flash/MockArraySessionStorage.php +++ b/tests/Flash/MockArraySessionStorage.php @@ -16,9 +16,7 @@ final class MockArraySessionStorage implements SessionInterface private bool $closed = false; - public function __construct(private array $data = []) - { - } + public function __construct(private array $data = []) {} public function get(string $key, $default = null) { diff --git a/tests/SessionMiddlewareTest.php b/tests/SessionMiddlewareTest.php index 1125fba..7de1eba 100644 --- a/tests/SessionMiddlewareTest.php +++ b/tests/SessionMiddlewareTest.php @@ -137,7 +137,7 @@ private function setUpRequestHandlerMock(ResponseInterface $response): void private function setUpSessionMock( bool $cookieDomainProvided = true, bool $isActive = true, - ?string $sessionId = self::CURRENT_SID + ?string $sessionId = self::CURRENT_SID, ): void { $this->sessionMock ->expects($this->any()) diff --git a/tests/SessionTest.php b/tests/SessionTest.php index 0186abc..3d38dbd 100644 --- a/tests/SessionTest.php +++ b/tests/SessionTest.php @@ -9,6 +9,8 @@ use Yiisoft\Session\Session; use Yiisoft\Session\SessionException; +use const PHP_SESSION_NONE; + /** * @runTestsInSeparateProcesses */ @@ -16,6 +18,14 @@ final class SessionTest extends TestCase { private ?Session $session = null; + protected function tearDown(): void + { + if ($this->session !== null) { + $this->session->destroy(); + $this->session = null; + } + } + public function getSession(array $options = [], ?SessionHandlerInterface $handler = null): Session { if ($this->session === null) { @@ -25,14 +35,6 @@ public function getSession(array $options = [], ?SessionHandlerInterface $handle return $this->session; } - protected function tearDown(): void - { - if ($this->session !== null) { - $this->session->destroy(); - $this->session = null; - } - } - public function testGetAndSet(): void { $session = $this->getSession(); diff --git a/tests/SpySessionHandler.php b/tests/SpySessionHandler.php index 3de12f5..3e63c96 100644 --- a/tests/SpySessionHandler.php +++ b/tests/SpySessionHandler.php @@ -4,9 +4,12 @@ namespace Yiisoft\Session\Tests; +use ReturnTypeWillChange; +use SessionHandlerInterface; + use function array_key_exists; -final class SpySessionHandler implements \SessionHandlerInterface +final class SpySessionHandler implements SessionHandlerInterface { private array $calls = []; @@ -27,7 +30,7 @@ public function destroy($session_id): bool return true; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function gc($maxlifetime) { $this->record('gc'); @@ -40,7 +43,7 @@ public function open($save_path, $name): bool return true; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function read($session_id) { $this->record('read'); diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 0000000..cf452dc --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1,2 @@ +/*/vendor +/*/composer.lock diff --git a/tools/composer-require-checker/composer.json b/tools/composer-require-checker/composer.json new file mode 100644 index 0000000..498425c --- /dev/null +++ b/tools/composer-require-checker/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "maglnet/composer-require-checker": "^4.4" + } +}