Merge pull request #308 from mssimi/redirect-to-route-rector

Redirect to route rector
This commit is contained in:
Tomáš Votruba 2018-02-03 23:17:46 +01:00 committed by GitHub
commit 16cb229adf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 205 additions and 0 deletions

View File

@ -0,0 +1,100 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\Controller;
use PhpParser\Node;
use Rector\Node\Attribute;
use Rector\Node\MethodCallNodeFactory;
use Rector\NodeAnalyzer\MethodArgumentAnalyzer;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\Rector\AbstractRector;
/**
* Before:
* return $this->redirect($this->generateUrl("homepage"));
* After:
* return $this->redirectToRoute("homepage");
*/
final class RedirectToRouteRector extends AbstractRector
{
/**
* @var MethodCallAnalyzer
*/
private $methodCallAnalyzer;
/**
* @var MethodArgumentAnalyzer
*/
private $methodArgumentAnalyzer;
/**
* @var MethodCallNodeFactory
*/
private $methodCallNodeFactory;
public function __construct(
MethodCallAnalyzer $methodCallAnalyzer,
MethodArgumentAnalyzer $methodArgumentAnalyzer,
MethodCallNodeFactory $methodCallNodeFactory
) {
$this->methodCallAnalyzer = $methodCallAnalyzer;
$this->methodArgumentAnalyzer = $methodArgumentAnalyzer;
$this->methodCallNodeFactory = $methodCallNodeFactory;
}
public function isCandidate(Node $node): bool
{
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
if ($parentClassName !== 'Symfony\Bundle\FrameworkBundle\Controller\Controller') {
return false;
}
if (! $this->methodCallAnalyzer->isMethod($node, 'redirect')) {
return false;
}
if (! $this->methodArgumentAnalyzer->hasMethodFirstArgument($node)) {
return false;
}
if (! $this->methodCallAnalyzer->isMethod($node->args[0]->value, 'generateUrl')) {
return false;
}
return true;
}
public function refactor(Node $node): ?Node
{
return $this->methodCallNodeFactory->createWithVariableNameMethodNameAndArguments(
'this',
'redirectToRoute',
$this->resolveArguments($node)
);
}
/**
* @return mixed[]
*/
private function resolveArguments(Node $node): array
{
$generateUrlNode = $node->args[0]->value;
$arguments = [];
$arguments[] = $generateUrlNode->args[0];
if ($generateUrlNode->args[1]) {
$arguments[] = $generateUrlNode->args[1];
}
if (! $generateUrlNode->args[1] && $node->args[1]) {
$arguments[] = [];
}
if ($node->args[1]) {
$arguments[] = $node->args[1];
}
return $arguments;
}
}

View File

@ -0,0 +1,2 @@
rectors:
Rector\Rector\Contrib\Symfony\Controller\RedirectToRouteRector: ~

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirectToRoute('something');
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirectToRoute('something', ['id' => $id]);
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirectToRoute('something', ['id' => $id], 301);
}
}

View File

@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\Controller\RedirectToRouteRector;
use Rector\Rector\Contrib\Symfony\Controller\RedirectToRouteRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class RedirectToRouteRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideWrongToFixedFiles()
*/
public function test(string $wrong, string $fixed): void
{
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
}
/**
* @return string[][]
*/
public function provideWrongToFixedFiles(): array
{
return [
[__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'],
[__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'],
[__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'],
];
}
/**
* @return string[]
*/
protected function getRectorClasses(): array
{
return [RedirectToRouteRector::class];
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirect($this->generateUrl('something'));
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirect($this->generateUrl('something', ['id' => $id]));
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function someAction()
{
return $this->redirect($this->generateUrl('something', ['id' => $id]), 301);
}
}