Skip to content

Commit 47a60fd

Browse files
authored
[FEATURE] Add RemoveExternalOptionFromTypoScriptFractor (#370)
Resolves: sabbelasichon/typo3-rector#4743
1 parent 7411acf commit 47a60fd

File tree

6 files changed

+197
-1
lines changed

6 files changed

+197
-1
lines changed

packages/typo3-fractor/config/typo3-14.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use a9f\Typo3Fractor\TYPO3v14\TypoScript\MigrateTypoScriptConditionGetTSFEFractor;
88
use a9f\Typo3Fractor\TYPO3v14\TypoScript\MigrateTypoScriptGetDataPathFractor;
99
use a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveExposeNonexistentUserInForgotPasswordDialogSettingInFeLoginFractor;
10+
use a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveExternalOptionFromTypoScriptFractor;
1011
use a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveFrontendAssetConcatenationAndCompressionFractor;
1112
use a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveModWebLayoutDefLangBindingFractor;
1213
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
@@ -24,4 +25,5 @@
2425
$services->set(MigrateTypoScriptConditionGetTSFEFractor::class);
2526
$services->set(RemoveFrontendAssetConcatenationAndCompressionFractor::class);
2627
$services->set(MigrateTypoScriptGetDataPathFractor::class);
28+
$services->set(RemoveExternalOptionFromTypoScriptFractor::class);
2729
};

packages/typo3-fractor/docs/typo3-fractor-rules.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 37 Rules Overview
1+
# 38 Rules Overview
22

33
## AbstractMessageGetSeverityFluidFractor
44

@@ -527,6 +527,25 @@ Remove plugin.tx_felogin_login.settings.exposeNonexistentUserInForgotPasswordDia
527527

528528
<br>
529529

530+
## RemoveExternalOptionFromTypoScriptFractor
531+
532+
Remove "external" option from TypoScript
533+
534+
- class: [`a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveExternalOptionFromTypoScriptFractor`](../rules/TYPO3v14/TypoScript/RemoveExternalOptionFromTypoScriptFractor.php)
535+
536+
```diff
537+
page = PAGE
538+
page.includeCSS {
539+
main = https://example.com/styles/main.css
540+
- main.external = 1
541+
- other = /styles/main.css
542+
- other.external = 1
543+
+ other = URI:/styles/main.css
544+
}
545+
```
546+
547+
<br>
548+
530549
## RemoveFrontendAssetConcatenationAndCompressionFractor
531550

532551
Remove Frontend Asset Concatenation and Compression
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
page = PAGE
2+
page.includeCSS {
3+
main = https://example.com/styles/main.css
4+
main.external = 1
5+
other = /styles/main.css
6+
other.external = 1
7+
}
8+
page.includeCSSLibs {
9+
main = https://example.com/styles/main.css
10+
main.external = 1
11+
other = /styles/main.css
12+
other.external = 1
13+
}
14+
page.includeJS {
15+
main = https://example.com/styles/main.css
16+
main.external = 1
17+
other = /styles/main.css
18+
other.external = 1
19+
}
20+
page.includeJSFooter {
21+
main = https://example.com/styles/main.css
22+
main.external = 1
23+
other = /styles/main.css
24+
other.external = 1
25+
}
26+
page.includeJSFooterlibs {
27+
main = https://example.com/styles/main.css
28+
main.external = 1
29+
other = /styles/main.css
30+
other.external = 1
31+
}
32+
page.includeJSLibs {
33+
main = https://example.com/styles/main.css
34+
main.external = 1
35+
other = /styles/main.css
36+
other.external = 1
37+
}
38+
-----
39+
page = PAGE
40+
page.includeCSS {
41+
main = https://example.com/styles/main.css
42+
other = URI:/styles/main.css
43+
}
44+
page.includeCSSLibs {
45+
main = https://example.com/styles/main.css
46+
other = URI:/styles/main.css
47+
}
48+
page.includeJS {
49+
main = https://example.com/styles/main.css
50+
other = URI:/styles/main.css
51+
}
52+
page.includeJSFooter {
53+
main = https://example.com/styles/main.css
54+
other = URI:/styles/main.css
55+
}
56+
page.includeJSFooterlibs {
57+
main = https://example.com/styles/main.css
58+
other = URI:/styles/main.css
59+
}
60+
page.includeJSLibs {
61+
main = https://example.com/styles/main.css
62+
other = URI:/styles/main.css
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\Typo3Fractor\Tests\TYPO3v14\TypoScript\RemoveExternalOptionFromTypoScriptFractor;
6+
7+
use a9f\Fractor\Testing\PHPUnit\AbstractFractorTestCase;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
10+
final class RemoveExternalOptionFromTypoScriptFractorTest extends AbstractFractorTestCase
11+
{
12+
#[DataProvider('provideData')]
13+
public function test(string $filePath): void
14+
{
15+
$this->doTestFile($filePath);
16+
}
17+
18+
public static function provideData(): \Iterator
19+
{
20+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixtures', '*.typoscript.fixture');
21+
}
22+
23+
public function provideConfigFilePath(): string
24+
{
25+
return __DIR__ . '/config/fractor.php';
26+
}
27+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use a9f\Fractor\Configuration\FractorConfiguration;
6+
use a9f\Fractor\ValueObject\Indent;
7+
use a9f\FractorXml\Configuration\XmlProcessorOption;
8+
use a9f\Typo3Fractor\TYPO3v14\TypoScript\RemoveExternalOptionFromTypoScriptFractor;
9+
10+
return FractorConfiguration::configure()
11+
->withOptions([
12+
XmlProcessorOption::INDENT_CHARACTER => Indent::STYLE_TAB,
13+
XmlProcessorOption::INDENT_SIZE => 1,
14+
])
15+
->withRules([RemoveExternalOptionFromTypoScriptFractor::class]);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\Typo3Fractor\TYPO3v14\TypoScript;
6+
7+
use a9f\FractorTypoScript\AbstractTypoScriptFractor;
8+
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
9+
use Helmich\TypoScriptParser\Parser\AST\Operator\Assignment;
10+
use Helmich\TypoScriptParser\Parser\AST\Statement;
11+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
12+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
13+
14+
/**
15+
* @changelog https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/14.0/Breaking-107927-ExternalAttributesRemoved.html
16+
* @see \a9f\Typo3Fractor\Tests\TYPO3v14\TypoScript\RemoveExternalOptionFromTypoScriptFractor\RemoveExternalOptionFromTypoScriptFractorTest
17+
*/
18+
final class RemoveExternalOptionFromTypoScriptFractor extends AbstractTypoScriptFractor
19+
{
20+
public function getRuleDefinition(): RuleDefinition
21+
{
22+
return new RuleDefinition('Remove "external" option from TypoScript', [new CodeSample(
23+
<<<'CODE_SAMPLE'
24+
page = PAGE
25+
page.includeCSS {
26+
main = https://example.com/styles/main.css
27+
main.external = 1
28+
other = /styles/main.css
29+
other.external = 1
30+
}
31+
CODE_SAMPLE
32+
,
33+
<<<'CODE_SAMPLE'
34+
page = PAGE
35+
page.includeCSS {
36+
main = https://example.com/styles/main.css
37+
other = URI:/styles/main.css
38+
}
39+
CODE_SAMPLE
40+
)]);
41+
}
42+
43+
public function refactor(Statement $statement): null|Statement|int
44+
{
45+
if (! $statement instanceof Assignment) {
46+
return null;
47+
}
48+
49+
if (! str_contains($statement->object->absoluteName, 'includeCSS')
50+
&& ! str_contains($statement->object->absoluteName, 'includeCSSLibs')
51+
&& ! str_contains($statement->object->absoluteName, 'includeJS')
52+
&& ! str_contains($statement->object->absoluteName, 'includeJSFooter')
53+
&& ! str_contains($statement->object->absoluteName, 'includeJSFooterlibs')
54+
&& ! str_contains($statement->object->absoluteName, 'includeJSLibs')
55+
) {
56+
return null;
57+
}
58+
59+
if (str_ends_with($statement->object->relativeName, 'external')) {
60+
return TypoScriptStatementsIterator::REMOVE_NODE;
61+
}
62+
63+
if (str_starts_with($statement->value->value, '/')) {
64+
$statement->value->value = 'URI:' . $statement->value->value;
65+
return $statement;
66+
}
67+
68+
return null;
69+
}
70+
}

0 commit comments

Comments
 (0)