Skip to content

Commit 37670e2

Browse files
committed
New rector: Rector for _drupal_flush_css_js through new VersionedFunctionToServiceRector
1 parent b5ad678 commit 37670e2

File tree

6 files changed

+208
-0
lines changed

6 files changed

+208
-0
lines changed

config/drupal-10/drupal-10.2-deprecations.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
declare(strict_types=1);
44

5+
use DrupalRector\Drupal10\Rector\Deprecation\VersionedFunctionToServiceRector;
6+
use DrupalRector\Drupal10\Rector\ValueObject\VersionedFunctionToServiceConfiguration;
57
use DrupalRector\Rector\Deprecation\FunctionToStaticRector;
68
use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector;
79
use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration;
@@ -24,4 +26,9 @@
2426
new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'),
2527
new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'),
2628
]);
29+
30+
// https://www.drupal.org/node/3358337
31+
$rectorConfig->ruleWithConfiguration(VersionedFunctionToServiceRector::class, [
32+
new VersionedFunctionToServiceConfiguration('10.2.0', '_drupal_flush_css_js', 'asset.query_string', 'reset'),
33+
]);
2734
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DrupalRector\Drupal10\Rector\Deprecation;
6+
7+
use DrupalRector\Contract\VersionedConfigurationInterface;
8+
use DrupalRector\Drupal10\Rector\ValueObject\VersionedFunctionToServiceConfiguration;
9+
use DrupalRector\Rector\AbstractDrupalCoreRector;
10+
use PhpParser\Node;
11+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
12+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
13+
14+
/**
15+
* Replaces deprecated function call with service method call with backwards compatibility.
16+
*/
17+
class VersionedFunctionToServiceRector extends AbstractDrupalCoreRector
18+
{
19+
/**
20+
* @var array|VersionedFunctionToServiceConfiguration[]
21+
*/
22+
protected array $configurations = [];
23+
24+
public function configure(array $configuration): void
25+
{
26+
foreach ($configuration as $value) {
27+
if (!($value instanceof VersionedFunctionToServiceConfiguration)) {
28+
throw new \InvalidArgumentException(sprintf('Each configuration item must be an instance of "%s"', VersionedFunctionToServiceConfiguration::class));
29+
}
30+
}
31+
32+
parent::configure($configuration);
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function getNodeTypes(): array
39+
{
40+
return [
41+
Node\Expr\FuncCall::class,
42+
];
43+
}
44+
45+
/**
46+
* @param Node\Expr\FuncCall $node
47+
* @param VersionedFunctionToServiceConfiguration $configuration
48+
*
49+
* @return Node|null
50+
*/
51+
public function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node
52+
{
53+
/** @var Node\Expr\FuncCall $node */
54+
if ($this->getName($node->name) === $configuration->getDeprecatedFunctionName()) {
55+
// This creates a service call like `\Drupal::service('file_system').
56+
$service = new Node\Expr\StaticCall(new Node\Name\FullyQualified('Drupal'), 'service', [new Node\Arg(new Node\Scalar\String_($configuration->getServiceName()))]);
57+
58+
$method_name = new Node\Identifier($configuration->getServiceMethodName());
59+
60+
return new Node\Expr\MethodCall($service, $method_name, $node->args);
61+
}
62+
63+
return null;
64+
}
65+
66+
public function getRuleDefinition(): RuleDefinition
67+
{
68+
return new RuleDefinition('Fixes deprecated function to service calls, used in Drupal 8 and 9 deprecations', [
69+
new ConfiguredCodeSample(
70+
<<<'CODE_BEFORE'
71+
_drupal_flush_css_js();
72+
CODE_BEFORE
73+
,
74+
<<<'CODE_AFTER'
75+
\Drupal::service('asset.query_string')->reset();
76+
CODE_AFTER
77+
,
78+
[
79+
new VersionedFunctionToServiceConfiguration('10.2.0', '_drupal_flush_css_js', 'asset.query_string', 'reset'),
80+
]
81+
),
82+
]);
83+
}
84+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DrupalRector\Drupal10\Rector\ValueObject;
6+
7+
use DrupalRector\Contract\VersionedConfigurationInterface;
8+
9+
class VersionedFunctionToServiceConfiguration implements VersionedConfigurationInterface
10+
{
11+
/**
12+
* The deprecated function name.
13+
*/
14+
protected string $deprecatedFunctionName;
15+
16+
/**
17+
* The replacement service name.
18+
*/
19+
protected string $serviceName;
20+
21+
/**
22+
* The replacement service method.
23+
*/
24+
protected string $serviceMethodName;
25+
26+
protected string $introducedVersion;
27+
28+
public function __construct(string $introducedVersion, string $deprecatedFunctionName, string $serviceName, string $serviceMethodName)
29+
{
30+
$this->deprecatedFunctionName = $deprecatedFunctionName;
31+
$this->serviceName = $serviceName;
32+
$this->serviceMethodName = $serviceMethodName;
33+
$this->introducedVersion = $introducedVersion;
34+
}
35+
36+
public function getDeprecatedFunctionName(): string
37+
{
38+
return $this->deprecatedFunctionName;
39+
}
40+
41+
public function getServiceName(): string
42+
{
43+
return $this->serviceName;
44+
}
45+
46+
public function getServiceMethodName(): string
47+
{
48+
return $this->serviceMethodName;
49+
}
50+
51+
public function getIntroducedVersion(): string
52+
{
53+
return $this->introducedVersion;
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DrupalRector\Tests\Rector\Deprecation\VersionedFunctionToServiceRector;
6+
7+
use Iterator;
8+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
9+
10+
class VersionedFunctionToServiceRectorTest extends AbstractRectorTestCase
11+
{
12+
/**
13+
* @covers ::refactor
14+
*
15+
* @dataProvider provideData
16+
*/
17+
public function test(string $filePath): void
18+
{
19+
$this->doTestFile($filePath);
20+
}
21+
22+
/**
23+
* @return Iterator<<string>>
24+
*/
25+
public static function provideData(): \Iterator
26+
{
27+
return self::yieldFilesFromDirectory(__DIR__.'/fixture');
28+
}
29+
30+
public function provideConfigFilePath(): string
31+
{
32+
// must be implemented
33+
return __DIR__.'/config/configured_rule.php';
34+
}
35+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use DrupalRector\Drupal10\Rector\Deprecation\VersionedFunctionToServiceRector;
6+
use DrupalRector\Drupal10\Rector\ValueObject\VersionedFunctionToServiceConfiguration;
7+
use DrupalRector\Tests\Rector\Deprecation\DeprecationBase;
8+
use Rector\Config\RectorConfig;
9+
10+
return static function (RectorConfig $rectorConfig): void {
11+
DeprecationBase::addClass(VersionedFunctionToServiceRector::class, $rectorConfig, false, [
12+
new VersionedFunctionToServiceConfiguration('10.2.0', '_drupal_flush_css_js', 'asset.query_string', 'reset'),
13+
]);
14+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
function simple_example() {
4+
_drupal_flush_css_js();
5+
}
6+
?>
7+
-----
8+
<?php
9+
10+
function simple_example() {
11+
\Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.2.0', fn() => \Drupal::service('asset.query_string')->reset(), fn() => _drupal_flush_css_js());
12+
}
13+
?>

0 commit comments

Comments
 (0)