diff --git a/config/v11/typo3-113.php b/config/v11/typo3-113.php index dfcb7b01d..105c1d95f 100644 --- a/config/v11/typo3-113.php +++ b/config/v11/typo3-113.php @@ -14,4 +14,5 @@ $rectorConfig->rule(SwitchBehaviorOfArrayUtilityMethodsRector::class); $rectorConfig->rule(SubstituteExtbaseRequestGetBaseUriRector::class); $rectorConfig->rule(UseNormalizedParamsToGetRequestUrlRector::class); + $rectorConfig->rule(\Ssch\TYPO3Rector\TYPO311\v3\MigrateHttpUtilityRedirectRector::class); }; diff --git a/rules/TYPO311/v3/MigrateHttpUtilityRedirectRector.php b/rules/TYPO311/v3/MigrateHttpUtilityRedirectRector.php new file mode 100644 index 000000000..322d1b006 --- /dev/null +++ b/rules/TYPO311/v3/MigrateHttpUtilityRedirectRector.php @@ -0,0 +1,121 @@ +builderFactory = $builderFactory; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Migrate HttpUtilty::redirect() to responseFactory', [new CodeSample( + <<<'CODE_SAMPLE' +use TYPO3\CMS\Core\Utility\HttpUtility; + +HttpUtility::redirect('https://example.com', HttpUtility::HTTP_STATUS_303); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Psr\Http\Message\ResponseFactoryInterface; +use TYPO3\CMS\Core\Http\PropagateResponseException; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\HttpUtility; + +$response = GeneralUtility::makeInstance(ResponseFactoryInterface::class) + ->createResponse(HttpUtility::HTTP_STATUS_303) + ->withAddedHeader('location', 'https://example.com'); +throw new PropagateResponseException($response); +CODE_SAMPLE + ), + ]); + } + + public function getNodeTypes(): array + { + return [Expression::class]; + } + + /** + * @param Expression $node + * @return Node[]|null + */ + public function refactor(Node $node): ?array + { + $staticCall = $node->expr; + if (! $staticCall instanceof StaticCall) { + return null; + } + + if (! $this->nodeTypeResolver->isMethodStaticCallOrClassMethodObjectType( + $staticCall, + new ObjectType(HttpUtility::class) + )) { + return null; + } + + if (! $this->isName($staticCall->name, 'redirect')) { + return null; + } + + $target = $staticCall->args[0]; + $httpStatusCode = $staticCall->args[1] ?? $this->nodeFactory->createClassConstFetch( + HttpUtility::class, + 'HTTP_STATUS_303' + ); + + $createResponseCallNode = $this->nodeFactory->createMethodCall( + $this->createResponseFactory(), + 'createResponse', + [$httpStatusCode] + ); + $withHeaderCallNode = $this->nodeFactory->createMethodCall($createResponseCallNode, 'withAddedHeader', [ + 'location', + $target, + ]); + + $responseVariable = new Variable('response'); + $assignment = new Expression(new Assign($responseVariable, $withHeaderCallNode)); + + $exception = new Throw_($this->builderFactory->new( + '\\TYPO3\\CMS\\Core\\Http\\PropagateResponseException', + [$responseVariable] + )); + + return [new Nop(), $assignment, $exception]; + } + + private function createResponseFactory(): StaticCall + { + return $this->nodeFactory->createStaticCall( + GeneralUtility::class, + 'makeInstance', + [$this->nodeFactory->createClassConstReference('Psr\\Http\\Message\\ResponseFactoryInterface')] + ); + } +} diff --git a/rules/TYPO311/v4/MigrateRootUidToStartingPointsRector.php b/rules/TYPO311/v4/MigrateRootUidToStartingPointsRector.php index be75c6f51..9012f60f2 100644 --- a/rules/TYPO311/v4/MigrateRootUidToStartingPointsRector.php +++ b/rules/TYPO311/v4/MigrateRootUidToStartingPointsRector.php @@ -7,8 +7,6 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrayItem; -use PhpParser\Node\Expr\ConstFetch; -use PhpParser\Node\Name; use PhpParser\Node\Scalar\String_; use Ssch\TYPO3Rector\Rector\AbstractTcaRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -22,8 +20,11 @@ final class MigrateRootUidToStartingPointsRector extends AbstractTcaRector { public function getRuleDefinition(): RuleDefinition { - return new RuleDefinition('If a column has [treeConfig][rootUid] defined, migrate to [treeConfig][startingPoints] on the same level.', [new CodeSample( - <<<'CODE_SAMPLE' + return new RuleDefinition( + 'If a column has [treeConfig][rootUid] defined, migrate to [treeConfig][startingPoints] on the same level.', + [ + new CodeSample( + <<<'CODE_SAMPLE' return [ 'columns' => [ 'aField' => [ @@ -38,8 +39,8 @@ public function getRuleDefinition(): RuleDefinition ], ]; CODE_SAMPLE - , - <<<'CODE_SAMPLE' + , + <<<'CODE_SAMPLE' return [ 'columns' => [ 'aField' => [ @@ -54,7 +55,9 @@ public function getRuleDefinition(): RuleDefinition ], ]; CODE_SAMPLE - )]); + ), + + ]); } protected function refactorColumn(Expr $columnName, Expr $columnTca): void @@ -65,7 +68,7 @@ protected function refactorColumn(Expr $columnName, Expr $columnTca): void } // Fetch type - if (!$this->isConfigType($configArray, 'select') && !$this->isConfigType($configArray, 'category')) { + if (! $this->isConfigType($configArray, 'select') && ! $this->isConfigType($configArray, 'category')) { return; } @@ -91,7 +94,9 @@ protected function refactorColumn(Expr $columnName, Expr $columnTca): void return; } - $treeConfigArray->items[] = new ArrayItem(new String_((string)$rootUidValue), new String_('startingPoints')); + $treeConfigArray->items[] = new ArrayItem(new String_((string) $rootUidValue), new String_( + 'startingPoints' + )); } $this->removeArrayItemFromArrayByKey($treeConfigArray, 'rootUid'); diff --git a/stubs/TYPO3/CMS/Core/Http/PropagateResponseException.php b/stubs/TYPO3/CMS/Core/Http/PropagateResponseException.php index e93bc6688..6ad724915 100644 --- a/stubs/TYPO3/CMS/Core/Http/PropagateResponseException.php +++ b/stubs/TYPO3/CMS/Core/Http/PropagateResponseException.php @@ -10,7 +10,7 @@ final class PropagateResponseException extends ImmediateResponseException { - public function __construct(ResponseInterface $response, int $code) + public function __construct(ResponseInterface $response, int $code = 0) { parent::__construct(); } diff --git a/stubs/TYPO3/CMS/Core/Utility/HttpUtility.php b/stubs/TYPO3/CMS/Core/Utility/HttpUtility.php index c4fa3512e..364b69666 100644 --- a/stubs/TYPO3/CMS/Core/Utility/HttpUtility.php +++ b/stubs/TYPO3/CMS/Core/Utility/HttpUtility.php @@ -9,6 +9,7 @@ class HttpUtility { const HTTP_STATUS_400 = 'HTTP/1.1 400 Bad Request'; + public const HTTP_STATUS_303 = 'HTTP/1.1 303 See Other'; /** * @return string @@ -26,4 +27,8 @@ public static function setResponseCode($httpStatus) { } + + public static function redirect($url, $httpStatus = self::HTTP_STATUS_303) + { + } } diff --git a/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithOneParameters.php.inc b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithOneParameters.php.inc new file mode 100644 index 000000000..b1fc00441 --- /dev/null +++ b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithOneParameters.php.inc @@ -0,0 +1,21 @@ + +----- +createResponse(HttpUtility::HTTP_STATUS_303)->withAddedHeader('location', 'https://example.com'); +throw new PropagateResponseException($response); +?> diff --git a/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParameters.php.inc b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParameters.php.inc new file mode 100644 index 000000000..14f7a8a85 --- /dev/null +++ b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParameters.php.inc @@ -0,0 +1,21 @@ + +----- +createResponse(HttpUtility::HTTP_STATUS_303)->withAddedHeader('location', 'https://example.com'); +throw new PropagateResponseException($response); +?> diff --git a/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParametersNotInHttpUtility.php.inc b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParametersNotInHttpUtility.php.inc new file mode 100644 index 000000000..90b66a438 --- /dev/null +++ b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Fixture/RedirectCallWithTwoParametersNotInHttpUtility.php.inc @@ -0,0 +1,8 @@ + diff --git a/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/MigrateHttpUtilityRedirectRectorTest.php b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/MigrateHttpUtilityRedirectRectorTest.php new file mode 100644 index 000000000..9875b6919 --- /dev/null +++ b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/MigrateHttpUtilityRedirectRectorTest.php @@ -0,0 +1,32 @@ +doTestFile($filePath); + } + + /** + * @return Iterator> + */ + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Source/Foo.php b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Source/Foo.php new file mode 100644 index 000000000..a9e174f2b --- /dev/null +++ b/tests/Rector/v11/v3/MigrateHttpUtilityRedirectRector/Source/Foo.php @@ -0,0 +1,12 @@ +import(__DIR__ . '/../../../../../../config/config.php'); + $rectorConfig->rule(MigrateHttpUtilityRedirectRector::class); +};