a9f/typo3-fractor
Automate TYPO3 upgrades by refactoring not only PHP but also TypoScript, YAML, and Fluid templates. Built as an enhancement to TYPO3-Rector, run Fractor with configurable rule sets and dry-run support to review safe, version-controlled migrations.
Installation Run in your TYPO3 project root:
composer require a9f/typo3-fractor --dev
Ensure composer.json marks it as a dev dependency (critical for CI/CD safety).
Configuration
Create config/fractor.php (or adjust path in CLI):
return \a9f\Fractor\Configuration\FractorConfiguration::configure()
->withPaths([__DIR__ . '/Configuration/TypoScript', __DIR__ . '/Resources/Private'])
->withSets([\a9f\Typo3Fractor\Set\Typo3LevelSetList::UP_TO_TYPO3_14]);
Verify paths cover all TYPO3 config files (TypoScript, Fluid, YAML).
First Dry Run Test changes without modifying files:
vendor/bin/fractor process --dry-run
addTypoScriptSetup, renameFluidVariable).UP_TO_TYPO3_14 set in fractor.php.vendor/bin/fractor process --dry-run --format=diff
vendor/bin/fractor process
git add .
git commit -m "Apply TYPO3 14 migrations via Fractor"
CI/CD Pipeline Add a pre-merge check (e.g., GitHub Actions):
- name: Run Fractor Dry Run
run: vendor/bin/fractor process --dry-run
Fail builds if dry-run detects breaking changes.
Team Collaboration
fractor.php in the repo (not .gitignore).File Targeting
->withPaths([
__DIR__ . '/Configuration/TypoScript',
__DIR__ . '/Resources/Private/Templates',
])
->withExcludedPaths([__DIR__ . '/Tests'])
.typoscript, .yaml, or .html files via rules.| Use Case | Configuration Snippet | Notes |
|---|---|---|
| TypoScript Migrations | Typo3LevelSetList::UP_TO_TYPO3_14 |
Handles addTypoScriptSetup, removeDeprecated rules. |
| Fluid Template Fixes | Add custom rule: new FluidRule() |
Target specific template files. |
| YAML Schema Updates | Include Configuration/ paths |
Useful for ext_localconf migrations. |
| Conditional Rules | Combine sets: Typo3LevelSetList::COMBINED |
Mix upgrade levels (e.g., v12 + v13). |
artisan typo3:sync (if using a bridge package) after Fractor runs to ensure TypoScript is reloaded.?v=2 to static includes if Fractor modifies Fluid templates.$this->assertFileEquals(
__DIR__ . '/expected/Setup.typoscript',
__DIR__ . '/Configuration/TypoScript/Setup.typoscript'
);
Production Risk
fractor process in production. Always use --dry-run first.fractor.php:
if (app()->environment('production')) {
throw new \RuntimeException('Fractor disabled in production!');
}
False Positives
page.10 = TEXT).->withCustomRules([new \a9f\Typo3Fractor\Rule\SkipRule('path/to/file.typoscript')])
Path Resolution
realpath():
->withPaths([realpath(__DIR__ . '/../Configuration')])
Rule Conflicts
addTypoScriptSetup + removeDeprecated).| Symptom | Debug Command | Solution |
|---|---|---|
| No changes detected | vendor/bin/fractor debug:paths |
Verify paths include target files. |
| Unexpected file modifications | --format=verbose |
Check rule precedence and file content. |
| Rule errors | --debug |
Inspect rule stack traces. |
| Performance issues | strace -f vendor/bin/fractor process |
Optimize paths (exclude unnecessary dirs). |
Custom Rules
Extend core rules by implementing \a9f\Fractor\Rule\RuleInterface:
class MyCustomRule implements RuleInterface {
public function process(File $file): void {
if (str_contains($file->getContent(), 'old_pattern')) {
$file->replace('old_pattern', 'new_pattern');
}
}
}
Register in fractor.php:
->withCustomRules([new MyCustomRule()])
Pre/Post Hooks
Use Symfony’s EventDispatcher to intercept migrations:
$dispatcher->addListener('fractor.process.start', function () {
// Pre-processing logic
});
TYPO3-Specific Extensions
f:format.raw deprecations.extbase to extbase.typo3 migrations.composer.json to avoid unexpected rule changes:
"a9f/typo3-fractor": "1.2.0"
UP_TO_TYPO3_13, then UP_TO_TYPO3_14) to isolate changes.How can I help you explore Laravel packages today?