[Laravel] Add MinutesToSecondsInCacheRector

This commit is contained in:
Tomas Votruba 2019-03-04 00:43:34 +01:00
parent b53e3cfada
commit 2769f7a25d
6 changed files with 246 additions and 6 deletions

View File

@ -46,3 +46,4 @@ services:
str_start: ['Illuminate\Support\Str', 'start']
studly_case: ['Illuminate\Support\Str', 'studly']
title_case: ['Illuminate\Support\Str', 'title']
Rector\Laravel\Rector\StaticCall\MinutesToSecondsInCacheRector: ~

View File

@ -39,7 +39,6 @@ services:
Symplify\CodingStandard\Fixer\Naming\PropertyNameMatchingTypeFixer:
extra_skipped_classes:
- 'PhpParser\PrettyPrinter\Standard'
# - 'PhpParser\Node'
Symplify\CodingStandard\Sniffs\Naming\ClassNameSuffixByParentSniff:
extra_parent_types_to_suffixes:
@ -48,14 +47,14 @@ services:
parameters:
exclude_files:
- '*tests/*Source/*.php'
- '*tests/**Source/*.php'
# tests files
- '*tests/*/Fixture/*'
- '*tests/*/Expected/*'
- '*utils/ContributorTools/templates/*'
skip:
# run manually from time to time, not to bother user with it
# run manually from time to time - performance demanding + not to bother user with it
Symplify\CodingStandard\Fixer\Order\PropertyOrderByComplexityFixer: ~
Symplify\CodingStandard\Fixer\Order\PrivateMethodOrderByUseFixer: ~
@ -131,6 +130,3 @@ parameters:
Symplify\CodingStandard\Sniffs\DependencyInjection\NoClassInstantiationSniff:
# 3rd party api
- 'src/PhpParser/Node/Value/ValueResolver.php'
# SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversableParameterTypeHintSpecification:
# - 'src/Testing/PHPUnit/AbstractRectorTestCase.php'

View File

@ -0,0 +1,115 @@
<?php declare(strict_types=1);
namespace Rector\Laravel\Rector\StaticCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Mul;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Scalar\LNumber;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
/**
* @see https://github.com/laravel/framework/pull/27276
*/
final class MinutesToSecondsInCacheRector extends AbstractRector
{
/**
* @var int[][]
*/
private $typesToMethods = [
'Illuminate\Support\Facades\Cache' => [
'put' => 2, // time argument position
'add' => 2,
],
'Illuminate\Contracts\Cache\Store' => [
'put' => 2,
'putMany' => 1,
],
'Illuminate\Cache\DynamoDbStore' => [
'add' => 2,
],
];
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
'Change minutes argument to seconds in Illuminate\Contracts\Cache\Store and Illuminate\Support\Facades\Cache',
[
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
Illuminate\Support\Facades\Cache::put('key', 'value', 60);
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
Illuminate\Support\Facades\Cache::put('key', 'value', 60 * 60);
}
}
CODE_SAMPLE
),
]
);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [StaticCall::class, MethodCall::class];
}
/**
* @param StaticCall|MethodCall $node
*/
public function refactor(Node $node): ?Node
{
foreach ($this->typesToMethods as $type => $methodsToArguments) {
if (! $this->isType($node, $type)) {
continue;
}
foreach ($methodsToArguments as $method => $argumentPosition) {
if (! $this->isName($node, $method)) {
continue;
}
if (! isset($node->args[$argumentPosition])) {
continue;
}
return $this->processArgumentPosition($node, $argumentPosition);
}
}
return $node;
}
/**
* @param StaticCall|MethodCall $expr
* @return StaticCall|MethodCall
*/
private function processArgumentPosition(Expr $expr, int $argumentPosition): Expr
{
$oldValue = $expr->args[$argumentPosition]->value;
$newArgumentValue = new Mul($oldValue, new LNumber(60));
$expr->args[$argumentPosition] = new Arg($newArgumentValue);
return $expr;
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector\Fixture;
use Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector\Source\ArrayStore;
class SomeClass
{
/**
* @var ArrayStore
*/
private $arrayStore;
public function __construct(ArrayStore $arrayStore)
{
$this->arrayStore = $arrayStore;
}
public function run()
{
\Illuminate\Support\Facades\Cache::put('key', 'value', 60);
$this->arrayStore->put('key', 'value', 60);
$seconds = 60;
$this->arrayStore->putMany(['key' => 'value'], $seconds);
}
}
?>
-----
<?php
namespace Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector\Fixture;
use Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector\Source\ArrayStore;
class SomeClass
{
/**
* @var ArrayStore
*/
private $arrayStore;
public function __construct(ArrayStore $arrayStore)
{
$this->arrayStore = $arrayStore;
}
public function run()
{
\Illuminate\Support\Facades\Cache::put('key', 'value', 60 * 60);
$this->arrayStore->put('key', 'value', 60 * 60);
$seconds = 60;
$this->arrayStore->putMany(['key' => 'value'], $seconds * 60);
}
}
?>

View File

@ -0,0 +1,19 @@
<?php declare(strict_types=1);
namespace Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector;
use Rector\Laravel\Rector\StaticCall\MinutesToSecondsInCacheRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class MinutesToSecondsInCacheRectorTest extends AbstractRectorTestCase
{
public function test(): void
{
$this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc']);
}
protected function getRectorClass(): string
{
return MinutesToSecondsInCacheRector::class;
}
}

View File

@ -0,0 +1,48 @@
<?php declare(strict_types=1);
namespace Rector\Laravel\Tests\Rector\StaticCall\MinutesToSecondsInCacheRector\Source;
use Illuminate\Contracts\Cache\Store;
final class ArrayStore implements Store
{
public function get($key)
{
}
public function many(array $keys)
{
}
public function put($key, $value, $seconds)
{
}
public function putMany(array $values, $seconds)
{
}
public function increment($key, $value = 1)
{
}
public function decrement($key, $value = 1)
{
}
public function forever($key, $value)
{
}
public function forget($key)
{
}
public function flush()
{
}
public function getPrefix()
{
}
}