Skip to content

Commit

Permalink
[TASK] Add MoveExtensionManagementUtilityAddStaticFileIntoTCAOverride…
Browse files Browse the repository at this point in the history
…sRector

Resolves: #4218
  • Loading branch information
simonschaufi committed Apr 16, 2024
1 parent 45b50ab commit 6cd7908
Show file tree
Hide file tree
Showing 13 changed files with 358 additions and 3 deletions.
2 changes: 2 additions & 0 deletions config/code-quality.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Ssch\TYPO3Rector\CodeQuality\General\ConvertImplicitVariablesToExplicitGlobalsRector;
use Ssch\TYPO3Rector\CodeQuality\General\ExtEmConfRector;
use Ssch\TYPO3Rector\CodeQuality\General\InjectMethodToConstructorInjectionRector;
use Ssch\TYPO3Rector\CodeQuality\General\MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector;
use Ssch\TYPO3Rector\CodeQuality\General\UseExtensionKeyInLocalizationUtilityRector;

return static function (RectorConfig $rectorConfig): void {
Expand Down Expand Up @@ -44,5 +45,6 @@
]);
$rectorConfig->rule(ConvertImplicitVariablesToExplicitGlobalsRector::class);
$rectorConfig->rule(InjectMethodToConstructorInjectionRector::class);
$rectorConfig->rule(MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector::class);
$rectorConfig->rule(UseExtensionKeyInLocalizationUtilityRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\CodeQuality\General;

use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeTraverser;
use PHPStan\Type\ObjectType;
use Rector\PhpParser\Printer\BetterStandardPrinter;
use Rector\Rector\AbstractRector;
use Ssch\TYPO3Rector\ComposerExtensionKeyResolver;
use Ssch\TYPO3Rector\Contract\FilesystemInterface;
use Ssch\TYPO3Rector\Filesystem\FilesFinder;
use Ssch\TYPO3Rector\Helper\ExtensionKeyResolverTrait;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @changelog https://review.typo3.org/c/Packages/TYPO3.CMS/+/52437
* @see \Ssch\TYPO3Rector\Tests\Rector\CodeQuality\Rector\General\MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector\MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRectorTest
*/
class MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector extends AbstractRector
{
use ExtensionKeyResolverTrait;

/**
* @readonly
*/
private FilesFinder $filesFinder;

/**
* @readonly
*/
private FilesystemInterface $filesystem;

/**
* @readonly
*/
private BetterStandardPrinter $betterStandardPrinter;

public function __construct(
FilesFinder $filesFinder,
FilesystemInterface $filesystem,
ComposerExtensionKeyResolver $composerExtensionKeyResolver,
BetterStandardPrinter $betterStandardPrinter
) {
$this->filesFinder = $filesFinder;
$this->filesystem = $filesystem;
$this->composerExtensionKeyResolver = $composerExtensionKeyResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Move ExtensionManagementUtility::addStaticFile into Configuration/TCA/Overrides/sys_template.php', [
new CodeSample(
<<<'CODE_SAMPLE'
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extensionKey', 'Configuration/TypoScript', 'Title');
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
// Move to file Configuration/TCA/Overrides/sys_template.php
CODE_SAMPLE
),
]);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Expression::class];
}


/**
* @param Expression $node
*/
public function refactor(Node $node)
{
$staticMethodCall = $node->expr;
if (! $staticMethodCall instanceof StaticCall) {
return null;
}

if ($this->shouldSkip($staticMethodCall)) {
return null;
}

$contentArgument = $staticMethodCall->args[0] ?? null;
if ($contentArgument === null) {
return null;
}

$contentArgumentValue = $contentArgument->value;
if (! $contentArgumentValue instanceof String_ && ! $contentArgumentValue instanceof Variable) {
return null;
}

$extensionKey = $this->resolvePotentialExtensionKeyByExtensionKeyParameter($contentArgumentValue);
if ($extensionKey instanceof String_) {
$contentArgument->value = $extensionKey;
}

$content = $this->betterStandardPrinter->prettyPrint([$staticMethodCall]) . ';';

$newConfigurationFile = dirname($this->file->getFilePath()) . '/Configuration/TCA/Overrides/sys_template.php';
if ($this->filesystem->fileExists($newConfigurationFile)) {
$this->filesystem->appendToFile($newConfigurationFile, $content . PHP_EOL);
} else {
$this->filesystem->write($newConfigurationFile, <<<CODE
<?php
{$content}
CODE
);
}

return NodeTraverser::REMOVE_NODE;
}

private function shouldSkip(StaticCall $staticMethodCall): bool
{
if (! $this->nodeTypeResolver->isMethodStaticCallOrClassMethodObjectType(
$staticMethodCall,
new ObjectType('TYPO3\CMS\Core\Utility\ExtensionManagementUtility')
)) {
return true;
}

if (! $this->isName($staticMethodCall->name, 'addStaticFile')) {
return true;
}

return ! $this->filesFinder->isExtTables($this->file->getFilePath());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function getRuleDefinition(): RuleDefinition
new CodeSample(
<<<'CODE_SAMPLE'
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
'@import "EXT:ppw_sitepackage/Configuration/TSconfig/*/*.tsconfig"'
'@import "EXT:extension_key/Configuration/TSconfig/*/*.tsconfig"'
);
CODE_SAMPLE
,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function getRuleDefinition(): RuleDefinition
return new RuleDefinition('Migrate method call ExtensionManagementUtility::addUserTSConfig to user.tsconfig', [new CodeSample(
<<<'CODE_SAMPLE'
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addUserTSConfig(
'@import "EXT:ppw_sitepackage/Configuration/TSconfig/*/*.tsconfig"'
'@import "EXT:extension_key/Configuration/TSconfig/*/*.tsconfig"'
);
CODE_SAMPLE
,
Expand Down
22 changes: 21 additions & 1 deletion src/Helper/ExtensionKeyResolverTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ trait ExtensionKeyResolverTrait
*/
private ComposerExtensionKeyResolver $composerExtensionKeyResolver;

/**
* @param Variable|String_ $contentArgumentValue
*/
private function resolvePotentialExtensionKeyByExtensionKeyParameter($contentArgumentValue): ?String_
{
if ($contentArgumentValue instanceof String_) {
return null;
}

if (!$contentArgumentValue instanceof Variable) {
return null;
}

$resolvedExtensionKey = $this->composerExtensionKeyResolver->resolveExtensionKey($this->file);
if ($resolvedExtensionKey === null) {
return null;
}

return new String_($resolvedExtensionKey);
}

/**
* @param Concat|String_ $contentArgumentValue
*/
Expand All @@ -38,7 +59,6 @@ private function resolvePotentialExtensionKey($contentArgumentValue): void
}

$resolvedExtensionKey = $this->composerExtensionKeyResolver->resolveExtensionKey($this->file);

if ($resolvedExtensionKey === null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension1', 'Configuration/TypoScript', 'Title');
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
# sys_template.php file exist

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension2', 'Configuration/TypoScript', 'Title');
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension3', 'Configuration/TypoScript', 'Title');

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension3', 'Configuration/OtherFolder', 'Other Title');
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension1', 'Configuration/TypoScript', 'Title');
?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extension2', 'Configuration/TypoScript', 'Title');

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;


?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;

$variable = 'extension3';
$_EXTKEY = 'extension3';

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($variable, 'Configuration/TypoScript', 'Title');
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/OtherFolder', 'Other Title');
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('doing' . $variable . 'weirdStuff', 'Configuration/TypoScript', 'Title');

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v13\v0\MigrateAddPageTSConfigToPageTsConfigFileRector\Fixture;

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
$variable = 'extension3';
$_EXTKEY = 'extension3';
ExtensionManagementUtility::addStaticFile('doing' . $variable . 'weirdStuff', 'Configuration/TypoScript', 'Title');

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Tests\Rector\CodeQuality\Rector\General\MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Ssch\TYPO3Rector\Contract\FilesystemInterface;

class MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRectorTest extends AbstractRectorTestCase
{
private FilesystemInterface $filesystem;

/**
* @var string[]
*/
private array $testFilesToDelete = [];

protected function setUp(): void
{
parent::setUp();
$this->initializeFilesystem();
}

protected function tearDown(): void
{
foreach ($this->testFilesToDelete as $filename) {
$this->filesystem->delete($filename);
}

parent::tearDown();
}

/**
* @dataProvider provideData
*/
public function testWithNonExistingComposerJson(string $extensionKey, ?string $existingSysTemplateContent = null): void
{
// Arrange
if ($existingSysTemplateContent !== null) {
$sysTemplate = __DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php';
$this->testFilesToDelete[] = $sysTemplate;
$this->filesystem->write($sysTemplate, $existingSysTemplateContent);
}

// Act
$this->doTestFile(__DIR__ . '/Fixture/' . $extensionKey . '/ext_tables.php.inc');
$this->testFilesToDelete[] = __DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php';

// Assert
$content = $this->filesystem->read(__DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php');
self::assertStringEqualsFile(__DIR__ . '/Assertions/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php', $content);
}

/**
* @dataProvider provideData
*/
public function testWithExistingComposerJson(string $extensionKey, ?string $existingSysTemplateContent = null): void
{
// Arrange
$composerJson = __DIR__ . '/Fixture/' . $extensionKey . '/composer.json';
$this->testFilesToDelete[] = $composerJson;
$this->filesystem->write($composerJson, '{
"extra": {
"typo3/cms": {
"extension-key": "' . $extensionKey . '"
}
}
}
');

if ($existingSysTemplateContent !== null) {
$sysTemplate = __DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php';
$this->testFilesToDelete[] = $sysTemplate;
$this->filesystem->write($sysTemplate, $existingSysTemplateContent);
}

// Act
$this->doTestFile(__DIR__ . '/Fixture/' . $extensionKey . '/ext_tables.php.inc');
$this->testFilesToDelete[] = __DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php';

// Assert
$content = $this->filesystem->read(__DIR__ . '/Fixture/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php');
self::assertStringEqualsFile(__DIR__ . '/Assertions/' . $extensionKey . '/Configuration/TCA/Overrides/sys_template.php', $content);
}

/**
* @return Iterator<array<string>>
*/
public static function provideData(): Iterator
{
yield 'Test that new sys_template.php is created with correct content' => ['extension1'];

yield 'Test that content is appended to existing sys_template.php file' => [
'extension2',
'<?php
# sys_template.php file exist
',
];

yield 'Test that new sys_template.php is created with correct content but unresolvable content cannot be migrated properly' => [
'extension3',
];
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}

private function initializeFilesystem(): void
{
$this->filesystem = self::getContainer()
->get(FilesystemInterface::class);
}
}
Loading

0 comments on commit 6cd7908

Please sign in to comment.