Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/typo3-fractor/config/typo3-10.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use a9f\Typo3Fractor\TYPO3v10\Fluid\RemoveNoCacheHashAndUseCacheHashAttributeFluidFractor;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\MigrateLegacyTypoScriptConditionsFractor;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\MigrateTypoScriptMultipleConditionBracketsFractor;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\MigrateTypoScriptPageConditionPipeAccessFractor;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\RemoveConfigConcatenateJsAndCssFractor;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\RemoveConfigDefaultGetVarsFractor;
Expand Down Expand Up @@ -39,6 +40,7 @@
$services->set(RemoveNoCacheHashAndUseCacheHashAttributeFluidFractor::class);
$services->set(RemoveUseCacheHashFromTypolinkTypoScriptFractor::class);
$services->set(MigrateLegacyTypoScriptConditionsFractor::class);
$services->set(MigrateTypoScriptMultipleConditionBracketsFractor::class);
$services->set(MigrateTypoScriptPageConditionPipeAccessFractor::class);
$services->set(RemoveConfigConcatenateJsAndCssFractor::class);
$services->set(RemoveConfigDefaultGetVarsFractor::class);
Expand Down
26 changes: 25 additions & 1 deletion packages/typo3-fractor/docs/typo3-fractor-rules.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 68 Rules Overview
# 69 Rules Overview

## AbstractMessageGetSeverityFluidFractor

Expand Down Expand Up @@ -744,6 +744,30 @@ Migrate TypoScript loginUser and usergroup conditions (both function-call and eq

<br>

## MigrateTypoScriptMultipleConditionBracketsFractor

Merge multiple TypoScript condition bracket pairs into a single bracket with logical operators inside

- class: [`a9f\Typo3Fractor\TYPO3v10\TypoScript\MigrateTypoScriptMultipleConditionBracketsFractor`](../rules/TYPO3v10/TypoScript/MigrateTypoScriptMultipleConditionBracketsFractor.php)

```diff
-[conditionA] || [conditionB]
+[conditionA || conditionB]
page = PAGE
[end]
```

<br>

```diff
-[conditionA] && [conditionB]
+[conditionA && conditionB]
page = PAGE
[end]
```

<br>

## MigrateTypoScriptPageConditionPipeAccessFractor

Migrate page pipe access in TypoScript conditions to bracket array access syntax
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[conditionA] || [conditionB]
page = PAGE
[end]
-----
[conditionA || conditionB]
page = PAGE
[end]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[conditionA] && [conditionB]
page = PAGE
[end]
-----
[conditionA && conditionB]
page = PAGE
[end]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[conditionA] || [conditionB] || [conditionC]
page = PAGE
[end]
-----
[conditionA || conditionB || conditionC]
page = PAGE
[end]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[traverse(request?.getQueryParams(), 'tx_t3extblog_blogsystem/post') > 0] || [traverse(request?.getQueryParams(), 'tx_news_pi1/news') > 0]
page = PAGE
[end]
-----
[traverse(request?.getQueryParams(), 'tx_t3extblog_blogsystem/post') > 0 || traverse(request?.getQueryParams(), 'tx_news_pi1/news') > 0]
page = PAGE
[end]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace a9f\Typo3Fractor\Tests\TYPO3v10\TypoScript\MigrateTypoScriptMultipleConditionBracketsFractor;

use a9f\Fractor\Testing\PHPUnit\AbstractFractorTestCase;
use PHPUnit\Framework\Attributes\DataProvider;

final class MigrateTypoScriptMultipleConditionBracketsFractorTest extends AbstractFractorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): \Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixtures', '*.typoscript.fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/fractor.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

use a9f\Fractor\Configuration\FractorConfiguration;
use a9f\FractorTypoScript\Configuration\TypoScriptProcessorOption;
use a9f\Typo3Fractor\TYPO3v10\TypoScript\MigrateTypoScriptMultipleConditionBracketsFractor;
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConditionTermination;
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConfiguration;

return FractorConfiguration::configure()
->withOptions([
TypoScriptProcessorOption::INDENT_SIZE => 4,
TypoScriptProcessorOption::INDENT_CHARACTER => PrettyPrinterConfiguration::INDENTATION_STYLE_SPACES,
TypoScriptProcessorOption::ADD_CLOSING_GLOBAL => false,
TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS => true,
TypoScriptProcessorOption::INDENT_CONDITIONS => true,
TypoScriptProcessorOption::CONDITION_TERMINATION => PrettyPrinterConditionTermination::Keep,
])
->withRules([MigrateTypoScriptMultipleConditionBracketsFractor::class]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

declare(strict_types=1);

namespace a9f\Typo3Fractor\TYPO3v10\TypoScript;

use a9f\FractorTypoScript\AbstractTypoScriptFractor;
use Helmich\TypoScriptParser\Parser\AST\ConditionalStatement;
use Helmich\TypoScriptParser\Parser\AST\Statement;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @changelog https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/9.5/Deprecation-86068-OldConditionSyntax.html
* @see \a9f\Typo3Fractor\Tests\TYPO3v10\TypoScript\MigrateTypoScriptMultipleConditionBracketsFractor\MigrateTypoScriptMultipleConditionBracketsFractorTest
*/
final class MigrateTypoScriptMultipleConditionBracketsFractor extends AbstractTypoScriptFractor
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Merge multiple TypoScript condition bracket pairs into a single bracket with logical operators inside',
[
new CodeSample(
<<<'CODE_SAMPLE'
[conditionA] || [conditionB]
page = PAGE
[end]
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
[conditionA || conditionB]
page = PAGE
[end]
CODE_SAMPLE
),
new CodeSample(
<<<'CODE_SAMPLE'
[conditionA] && [conditionB]
page = PAGE
[end]
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
[conditionA && conditionB]
page = PAGE
[end]
CODE_SAMPLE
),
]
);
}

public function refactor(Statement $statement): ?Statement
{
if (! $statement instanceof ConditionalStatement) {
return null;
}

$condition = $statement->condition;
$originalCondition = $condition;

$condition = $this->mergeMultipleBracketConditions($condition);

if ($condition === $originalCondition) {
return null;
}

$statement->condition = $condition;

return $statement;
}

private function mergeMultipleBracketConditions(string $condition): string
{
// Quick check: does it contain the pattern '] ||' or '] &&'?
if (! preg_match('/\]\s*(\|\||&&)\s*\[/', $condition)) {
return $condition;
}

$expressions = [];
$operators = [];
$remaining = trim($condition);

while ($remaining !== '') {
if (! preg_match('/^\[([^\]]*)\](.*)$/s', $remaining, $m)) {
// Unexpected format, bail out without changing anything
return $condition;
}

$expressions[] = $m[1];
$remaining = trim($m[2]);

if ($remaining === '') {
break;
}

if (preg_match('/^(\|\||&&)\s*(.*)$/s', $remaining, $opMatch)) {
$operators[] = $opMatch[1];
$remaining = trim($opMatch[2]);
} else {
// Unexpected token after closing bracket, bail out
return $condition;
}
}

if (count($expressions) < 2) {
return $condition;
}

$merged = '';
foreach ($expressions as $i => $expr) {
if ($i > 0) {
$merged .= ' ' . $operators[$i - 1] . ' ';
}

$merged .= $expr;
}

return '[' . $merged . ']';
}
}