Skip to content

Commit

Permalink
Merge pull request #14 from umpirsky/feature/get-request-fixer
Browse files Browse the repository at this point in the history
Get request fixer
  • Loading branch information
umpirsky committed Nov 30, 2015
2 parents d3d111f + 707ae3f commit 0c80ccd
Show file tree
Hide file tree
Showing 14 changed files with 363 additions and 18 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,3 @@ before_script:

script:
- phpunit

matrix:
allow_failures:
- php: 7.0
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You can run these commands to easily access ``symfony-upgrade-fixer`` from anywh
your system:

```bash
$ sudo wget https://github.com/umpirsky/Symfony-Upgrade-Fixer/releases/download/v0.1.1/symfony-upgrade-fixer.phar -O /usr/local/bin/symfony-upgrade-fixer
$ sudo wget https://github.com/umpirsky/Symfony-Upgrade-Fixer/releases/download/v0.1.2/symfony-upgrade-fixer.phar -O /usr/local/bin/symfony-upgrade-fixer
$ sudo chmod a+x /usr/local/bin/symfony-upgrade-fixer
```
Then, just run ``symfony-upgrade-fixer``.
Expand Down Expand Up @@ -67,6 +67,7 @@ $ symfony-upgrade-fixer fix /path/to/code --dry-run
| form_option_names | Options precision and virtual was renamed to scale and inherit_data. |
| form_parent_type | Returning type instances from FormTypeInterface::getParent() is deprecated, return the fully-qualified class name of the parent type class instead. |
| form_type_names | Instead of referencing types by name, you should reference them by their fully-qualified class name (FQCN) instead. |
| get_request | The getRequest method of the base controller class was removed, request object is injected in the action method instead. |
| inherit_data_aware_iterator | The class VirtualFormAwareIterator was renamed to InheritDataAwareIterator. |
| progress_bar | ProgressHelper has been removed in favor of ProgressBar. |
| property_access | Renamed PropertyAccess::getPropertyAccessor to PropertyAccess::createPropertyAccessor. |
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Upgrade/Fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class Fixer
{
const VERSION = '0.1.1';
const VERSION = '0.1.2';

private $fixers = [];
private $finder;
Expand Down
14 changes: 14 additions & 0 deletions src/Symfony/Upgrade/Fixer/AbstractFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,18 @@ protected function addUseStatement(Tokens $tokens, array $fqcn)
)
);
}

protected function extendsClass(Tokens $tokens, array $fqcn)
{
if (!$this->hasUseStatements($tokens, $fqcn)) {
return false;
}

return null !== $tokens->findSequence([
[T_CLASS],
[T_STRING],
[T_EXTENDS],
[T_STRING, array_pop($fqcn)],
]);
}
}
1 change: 0 additions & 1 deletion src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Symfony\Upgrade\Fixer;

use Symfony\CS\Tokenizer\Token;
use Symfony\CS\Tokenizer\Tokens;

class FormConfigureOptionsFixer extends FormTypeFixer
Expand Down
12 changes: 1 addition & 11 deletions src/Symfony/Upgrade/Fixer/FormTypeFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Symfony\Upgrade\Fixer;

use Symfony\CS\Tokenizer\Token;
use Symfony\CS\Tokenizer\Tokens;

abstract class FormTypeFixer extends AbstractFixer
Expand Down Expand Up @@ -41,16 +40,7 @@ abstract class FormTypeFixer extends AbstractFixer

protected function isFormType(Tokens $tokens)
{
if (!$this->hasUseStatements($tokens, ['Symfony', 'Component', 'Form', 'AbstractType'])) {
return false;
}

return null !== $tokens->findSequence([
[T_CLASS],
[T_STRING],
[T_EXTENDS],
[T_STRING, 'AbstractType'],
]);
return $this->extendsClass($tokens, ['Symfony', 'Component', 'Form', 'AbstractType']);
}

protected function addTypeUse(Tokens $tokens, $name)
Expand Down
227 changes: 227 additions & 0 deletions src/Symfony/Upgrade/Fixer/GetRequestFixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
<?php

namespace Symfony\Upgrade\Fixer;

use Symfony\CS\Tokenizer\Token;
use Symfony\CS\Tokenizer\Tokens;

class GetRequestFixer extends AbstractFixer
{
private $requestVariableName = '$request';

public function fix(\SplFileInfo $file, $content)
{
$tokens = Tokens::fromCode($content);

if ($this->isController($tokens)) {
$this->fixGetRequests($tokens);
}

return $tokens->generateCode();
}

public function getDescription()
{
return 'The getRequest method of the base controller class was removed, request object is injected in the action method instead.';
}

private function isController(Tokens $tokens)
{
return $this->extendsClass($tokens, ['Symfony', 'Bundle', 'FrameworkBundle', 'Controller', 'Controller']);
}

private function fixGetRequests(Tokens $tokens)
{
$todo = [];

foreach ($this->getClassyElementsIndexed($tokens) as $i => $element) {
if ('method' === $element['type']) {
if ($this->fixActionParameters($tokens, $element['index'])) {
$todo[] = $i;
}
}
}

foreach ($this->getClassyElementsIndexed($tokens) as $i => $element) {
if (in_array($i, $todo)) {
$this->fixActionBody($tokens, $element['index']);
}
}
}

private function getClassyElementsIndexed(Tokens $tokens)
{
$elements = [];

foreach ($tokens->getClassyElements() as $index => $element) {
$element['index'] = $index;
$elements[] = $element;
}

return $elements;
}

private function fixActionParameters(Tokens $tokens, $index)
{
if (!$this->isAction($tokens, $index)) {
return;
}

$parenthesisIndexes = $this->getActionParenthesisIndexes($tokens, $index);
if ($this->hasRequestParameterSequence($tokens, $parenthesisIndexes[0], $parenthesisIndexes[1])) {
return;
}

$curlyBraceIndexes = $this->getActionCurlyBraceIndexes($tokens, $index);
if (!$this->hasGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) {
return;
}

if (null === $requestVariableName = $this->getRequestVariableName($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) {
$requestVariableName = $this->requestVariableName;
}

$insertAt = $tokens->getNextMeaningfulToken($parenthesisIndexes[0]);

$tokens->insertAt(
$insertAt,
array_merge(
[
new Token([T_STRING, 'Request']),
new Token([T_WHITESPACE, ' ']),
new Token([T_VARIABLE, $requestVariableName]),
],
$parenthesisIndexes[1] - $parenthesisIndexes[0] > 1 ? [new Token(','), new Token([T_WHITESPACE, ' '])] : []
)
);

$this->addUseStatement(
$tokens,
['Symfony', 'Component', 'HttpFoundation', 'Request']
);

return true;
}

private function fixActionBody(Tokens $tokens, $index)
{
$curlyBraceIndexes = $this->getActionCurlyBraceIndexes($tokens, $index);
if (!$this->hasGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) {
return;
}

$clearFrom = $tmp = $this->getRequestVariableTokenIndex($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1]);
$getRequestSequenceTokens = $this->getGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1]);
$keys = array_keys($getRequestSequenceTokens);
$clearTo = array_pop($keys);
$clearTo = $tokens->getNextMeaningfulToken($clearTo);
if ($tokens[$clearTo]->equals(';')) {
$tokens->clearRange($clearFrom, $clearTo);
$tokens->removeTrailingWhitespace($clearTo);

return;
}

$replace = true;
foreach ($getRequestSequenceTokens as $key => $getRequestSequenceToken) {
if ($replace) {
$getRequestSequenceToken->override([T_VARIABLE, $this->requestVariableName]);

$replace = false;
continue;
}

$tokens[$key]->clear();
}
}

private function isAction(Tokens $tokens, $index)
{
$actionNameToken = $tokens[$tokens->getNextMeaningfulToken($index)];

if (!$actionNameToken->isGivenKind(T_STRING)) {
return false;
}
if (substr($actionNameToken->getContent(), -6) !== 'Action') {
return false;
}

return true;
}

private function getActionParenthesisIndexes(Tokens $tokens, $index)
{
$openIndex = $tokens->getNextMeaningfulToken($tokens->getNextMeaningfulToken($index));
$closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openIndex);

return [$openIndex, $closeIndex];
}

private function getActionCurlyBraceIndexes(Tokens $tokens, $index)
{
$openIndex = $tokens->getNextMeaningfulToken(
$this->getActionParenthesisIndexes($tokens, $index)[1]
);
$closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $openIndex);

return [$openIndex, $closeIndex];
}

private function hasRequestParameterSequence(Tokens $tokens, $start, $end)
{
return null !== $tokens->findSequence([
[T_STRING, 'Request'],
[T_VARIABLE],
], $start, $end);
}

private function hasGetRequestSequence(Tokens $tokens, $start, $end)
{
return null !== $this->getGetRequestSequence($tokens, $start, $end);
}

private function getGetRequestSequence(Tokens $tokens, $start, $end)
{
return $tokens->findSequence([
[T_VARIABLE, '$this'],
[T_OBJECT_OPERATOR],
[T_STRING, 'getRequest'],
'(',
')',
], $start, $end);
}

private function getRequestVariableName(Tokens $tokens, $start, $end)
{
$requestVariableTokenIndex = $this->getRequestVariableTokenIndex($tokens, $start, $end);
if (null === $requestVariableTokenIndex) {
return;
}

$requestVariableToken = $tokens[$requestVariableTokenIndex];
if (!$requestVariableToken->isGivenKind(T_VARIABLE)) {
return;
}

return $requestVariableToken->getContent();
}

private function getRequestVariableTokenIndex(Tokens $tokens, $start, $end)
{
$getRequestSequence = $this->getGetRequestSequence($tokens, $start, $end);

$getRequestSequenceKeys = array_keys($getRequestSequence);
$getRequestSequenceStartIndex = $getRequestSequenceKeys[0];

if (';' !== $tokens[$tokens->getNextMeaningfulToken(array_pop($getRequestSequenceKeys))]->getContent()) {
return;
}

$assignTokenIndex = $tokens->getPrevMeaningfulToken($getRequestSequenceStartIndex);
if ('=' !== $tokens[$assignTokenIndex]->getContent()) {
return;
}

return $tokens->getPrevMeaningfulToken($assignTokenIndex);
}
}
14 changes: 14 additions & 0 deletions tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Umpirsky\UpgradeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DemoController extends Controller
{
public function showAction($slug)
{
$request = $this->getRequest();
// ...
}
}
14 changes: 14 additions & 0 deletions tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-output.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Umpirsky\UpgradeBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DemoController extends Controller
{
public function showAction(Request $request, $slug)
{
// ...
}
}
19 changes: 19 additions & 0 deletions tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Umpirsky\UpgradeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DemoController extends Controller
{
public function showAction()
{
$request = $this->getRequest();
// ...
}

private function helperMethod()
{
// ...
}
}
19 changes: 19 additions & 0 deletions tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-output.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Umpirsky\UpgradeBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DemoController extends Controller
{
public function showAction(Request $request)
{
// ...
}

private function helperMethod()
{
// ...
}
}
14 changes: 14 additions & 0 deletions tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Umpirsky\UpgradeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DemoController extends Controller
{
public function showAction()
{
$username = $this->getRequest()->request->get('username');
// ...
}
}
Loading

0 comments on commit 0c80ccd

Please sign in to comment.