Global Rank · of 601 Skills
typo3-rector AI Agent Skill
View Source: dirnbauer/webconsulting-skills
SafeInstallation
npx skills add dirnbauer/webconsulting-skills --skill typo3-rector 47
Installs
TYPO3 Rector Upgrade Patterns
Compatibility: TYPO3 v14.x
This skill covers patterns for writing code that works on TYPO3 v14.
TYPO3 API First: Always use TYPO3's built-in APIs, core features, and established conventions before creating custom implementations. Do not reinvent what TYPO3 already provides. Always verify that the APIs and methods you use exist and are not deprecated in TYPO3 v14 by checking the official TYPO3 documentation.
1. Introduction to TYPO3 Rector
Rector is an automated refactoring tool that helps migrate TYPO3 PHP code between major versions. It applies predefined rules to update deprecated code patterns. For non-PHP migrations (FlexForms, TypoScript, Fluid, YAML), use Fractor -- see the typo3-fractor skill.
Installation
composer require --dev ssch/typo3-rector
# or with DDEV:
ddev composer require --dev ssch/typo3-rectorImportant: Rector loads your project's autoloader. For TYPO3 v14 projects, Rector
must run on PHP 8.2+ because TYPO3 v14 packages usereadonlyclasses and other
PHP 8.2 syntax. If your local PHP is older, always use DDEV or a container:ddev exec vendor/bin/rector process --dry-run
Always run Rector, never skip it. Manual replacements (e.g.
strpos->str_starts_with)
miss edge cases that Rector rules handle correctly. Rector also catches deprecated TYPO3
namespace changes and method signature updates that are hard to find manually.
Basic configuration (TYPO3 v14 target)
Create rector.php in your project root:
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\ValueObject\PhpVersion;
use Ssch\TYPO3Rector\Set\Typo3LevelSetList;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/packages',
__DIR__ . '/public/typo3conf/ext',
])
->withSkip([
__DIR__ . '/public/typo3conf/ext/*/Resources/',
__DIR__ . '/public/typo3conf/ext/*/Tests/',
])
->withPhpVersion(PhpVersion::PHP_82)
->withSets([
LevelSetList::UP_TO_PHP_82,
Typo3LevelSetList::UP_TO_TYPO3_14,
])
->withImportNames();Incremental upgrades: On a very old codebase you may run
UP_TO_TYPO3_13in a dedicated step first, thenUP_TO_TYPO3_14. Published extensions should still declaretypo3/cms-core: ^14.0once you ship for v14.
2. Running Rector
Dry Run (Preview Changes)
# Show what would be changed
ddev exec vendor/bin/rector process --dry-run
# For specific extension
ddev exec vendor/bin/rector process packages/my_extension --dry-runApply Changes
# Apply all changes
ddev exec vendor/bin/rector process
# Apply to specific path
ddev exec vendor/bin/rector process packages/my_extensionClear Cache After
ddev typo3 cache:flush
ddev composer dump-autoload3. Version constraints and extra Rector sets
Version constraints
For extensions targeting TYPO3 v14:
<?php
// ext_emconf.php
$EM_CONF[$_EXTKEY] = [
'title' => 'My Extension',
'version' => '2.0.0',
'state' => 'stable',
'constraints' => [
'depends' => [
'typo3' => '14.0.0-14.99.99',
'php' => '8.2.0-8.4.99',
],
'conflicts' => [],
'suggests' => [],
],
];// composer.json
{
"require": {
"php": "^8.2",
"typo3/cms-core": "^14.0"
}
}Optional: TYPO3 v14 rule set only
Add explicit v14 rules (in addition to or instead of the level set, depending on your Rector version):
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Ssch\TYPO3Rector\Set\Typo3SetList;
return RectorConfig::configure()
->withPaths([__DIR__ . '/packages'])
->withSets([
Typo3SetList::TYPO3_14,
]);4. Key Migration Patterns (TYPO3 v14)
Fluid ViewFactory (Replaces StandaloneView)
The ViewFactory approach works on TYPO3 v14:
<?php
declare(strict_types=1);
namespace Vendor\Extension\Service;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\View\ViewFactoryData;
use TYPO3\CMS\Core\View\ViewFactoryInterface;
final class RenderingService
{
public function __construct(
private readonly ViewFactoryInterface $viewFactory,
) {}
public function render(ServerRequestInterface $request): string
{
$viewFactoryData = new ViewFactoryData(
templateRootPaths: ['EXT:my_extension/Resources/Private/Templates'],
partialRootPaths: ['EXT:my_extension/Resources/Private/Partials'],
layoutRootPaths: ['EXT:my_extension/Resources/Private/Layouts'],
request: $request,
);
$view = $this->viewFactory->create($viewFactoryData);
$view->assign('data', ['key' => 'value']);
$view->assignMultiple([
'items' => [],
'settings' => [],
]);
return $view->render('MyTemplate');
}
}Extbase controller response (TYPO3 v14)
<?php
declare(strict_types=1);
namespace Vendor\Extension\Controller;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
final class ItemController extends ActionController
{
// ✅ Correct: Return ResponseInterface (required in TYPO3 v14)
public function listAction(): ResponseInterface
{
$items = $this->itemRepository->findAll();
$this->view->assign('items', $items);
return $this->htmlResponse();
}
// ✅ Correct: JSON response
public function apiAction(): ResponseInterface
{
$data = ['success' => true];
return $this->jsonResponse(json_encode($data));
}
// ✅ Correct: Redirect
public function createAction(Item $item): ResponseInterface
{
$this->itemRepository->add($item);
return $this->redirect('list');
}
}PSR-14 Events (Preferred over Hooks)
PSR-14 events work on TYPO3 v14. Use them instead of legacy hooks:
<?php
declare(strict_types=1);
namespace Vendor\Extension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent;
#[AsEventListener(identifier: 'vendor-extension/modify-pagelink')]
final class ModifyPageLinkListener
{
public function __invoke(ModifyPageLinkConfigurationEvent $event): void
{
$configuration = $event->getConfiguration();
// Modify link configuration
$event->setConfiguration($configuration);
}
}Backend Module Registration (TYPO3 v14)
<?php
// Configuration/Backend/Modules.php
return [
'web_myextension_mymodule' => [
'parent' => 'content',
'position' => ['after' => 'records'],
'access' => 'user,group',
'iconIdentifier' => 'myextension-module',
'path' => '/module/content/myextension',
'labels' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang_mod.xlf',
'extensionName' => 'MyExtension',
'controllerActions' => [
\Vendor\MyExtension\Controller\ModuleController::class => [
'index',
'edit',
],
],
],
];Service Configuration (Services.yaml)
# Configuration/Services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Vendor\MyExtension\:
resource: '../Classes/*'
exclude:
- '../Classes/Domain/Model/*'5. TCA Best Practices (TYPO3 v14)
Static TCA Only
In v14, $GLOBALS['TCA'] becomes read-only after loading. Always use static TCA files:
<?php
// Configuration/TCA/Overrides/tt_content.php
defined('TYPO3') or die();
// ✅ Correct: Static TCA configuration
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
'tt_content',
'CType',
[
'label' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mytype.title',
'value' => 'myextension_mytype',
'icon' => 'content-text',
'group' => 'default',
]
);
$GLOBALS['TCA']['tt_content']['types']['myextension_mytype'] = [
'showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
--palette--;;general,
header;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_formlabel,
bodytext,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
--palette--;;hidden,
--palette--;;access,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
],
],
],
];6. TYPO3 v14 platform snapshot
| Topic | TYPO3 v14 |
|---|---|
| PHP | 8.2 minimum; 8.3/8.4 supported |
| PSR-14 events | Preferred over legacy hooks |
| ViewFactory | Preferred over removed StandaloneView patterns |
| Content Blocks | Current major aligned with v14 (see Packagist) |
| TCA | Static Configuration/TCA only — no runtime $GLOBALS['TCA'] writes |
7. Step-by-Step Migration Process
1. Prepare
# Create backup
ddev snapshot --name=before-migration
# Ensure tests pass
ddev exec vendor/bin/phpunit -c packages/my_extension/Tests/phpunit.xml
# Check deprecation log
tail -f var/log/typo3_deprecations_*.log2. Configure Rector for TYPO3 v14
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Ssch\TYPO3Rector\Set\Typo3LevelSetList;
return RectorConfig::configure()
->withPaths([__DIR__ . '/packages/my_extension/Classes'])
->withSets([
Typo3LevelSetList::UP_TO_TYPO3_14,
]);3. Run Rector
# Dry run first
ddev exec vendor/bin/rector process --dry-run
# Apply changes
ddev exec vendor/bin/rector process
# Review changes
git diff4. Manual Fixes
- Review Rector output for skipped files
- Check deprecation log for remaining issues
- Update TCA configurations manually
- Test all backend modules
5. Test on TYPO3 v14
ddev composer require "typo3/cms-core:^14.0" --no-update
ddev composer update
ddev typo3 cache:flush
ddev exec vendor/bin/phpunit6. Commit
git add -A
git commit -m "feat: Apply Rector migrations for TYPO3 v14"8. Troubleshooting
Rector Fails
# Clear Rector cache
rm -rf .rector_cache/
# Run with verbose output
ddev exec vendor/bin/rector process --dry-run -vvvExtension Incompatibility
Check for updates:
ddev composer outdated
ddev composer show -lSearch for TYPO3 v14-compatible alternatives on:
Database Issues
# Core CLI: extension setup / schema alignment
ddev typo3 extension:setup --extension=my_extension
# `database:updateschema` is provided by helhum/typo3-console, not plain Core — only if installed:
# ddev typo3 list | rg database
# ddev typo3 database:updateschema --verbose9. Common Rector Rules
Namespace Changes (Auto-Migrated)
Rector automatically handles namespace changes between versions.
Utility Method Changes
<?php
// ❌ Old (deprecated)
GeneralUtility::getIndpEnv('TYPO3_REQUEST_HOST');
// ✅ New (TYPO3 v14)
$request = $GLOBALS['TYPO3_REQUEST'];
$normalizedParams = $request->getAttribute('normalizedParams');
$host = $normalizedParams->getRequestHost();ObjectManager Removal
<?php
// ❌ Old (removed in TYPO3 v14 migration path)
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$service = $objectManager->get(MyService::class);
// ✅ New (Dependency Injection)
public function __construct(
private readonly MyService $myService,
) {}10. Resources
- TYPO3 Rector: https://github.com/sabbelasichon/typo3-rector
- Upgrade Guide: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Administration/Upgrade/Index.html
- v14 Changelog: https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog-14.html
v14-only Rector targets
The following patterns are v14-focused migration targets. Prefer
Typo3LevelSetList::UP_TO_TYPO3_14; apply remaining items manually if Rector skips them.
New Rector Migration Targets [v14 only]
| Removed/Changed | Migration |
|---|---|
TypoScriptFrontendController |
Use request attributes (frontend.page.information, language) |
Extbase annotations (@validate, @ignorevalidation) |
Use PHP attributes (#[Validate], #[IgnoreValidation]) |
FlexFormService class |
Merged into FlexFormTools (#107945) |
Various BackendUtility helpers (#106393) |
Deprecated in v14, removal planned for v15 — migrate per changelog for each method |
MailMessage->send() |
Inject TYPO3\CMS\Core\Mail\MailerInterface and call $this->mailer->send($email) |
GeneralUtility::createVersionNumberedFilename() |
Use System Resource API |
PathUtility::getPublicResourceWebPath() |
Use System Resource API |
PathUtility::getRelativePath() / getRelativePathTo() |
Use new path resolution |
AbstractTypolinkBuilder->build() |
Use TypolinkBuilderInterface |
DataHandler->userid / ->admin / ->storeLogMessages |
Removed, no replacement |
v14.0 Deprecation Targets (prepare for v15 removal)
| Deprecated | Migration |
|---|---|
ButtonBar/Menu/MenuRegistry make* methods (#107823) |
Use ComponentFactory |
Scheduler task registration via SC_OPTIONS (#98453) |
Use TCA-based registration |
Localization parsers (XliffParser, etc.) (#107436) |
Symfony Translation Component |
v14.2 Deprecation Targets (prepare for v15 removal)
| Deprecated | Migration |
|---|---|
PageDoktypeRegistry config methods |
Migrate to TCA allowedRecordTypes |
PageRenderer->addInlineLanguageDomain() (#108963) |
Use alternative API |
ExtensionManagementUtility::addFieldsToUserSettings (#108843) |
Use TCA for user settings |
FormEngine "additionalHiddenFields" key (#109102) |
Removed in v15 |
Credits & Attribution
Thanks to Netresearch DTT GmbH for their contributions to the TYPO3 community.
Installs
Security Audit
Power your AI Agents with
the best open-source models.
Drop-in OpenAI-compatible API. No data leaves Europe.
Explore Inference APIGLM
GLM 5
$1.00 / $3.20
per M tokens
Kimi
Kimi K2.5
$0.60 / $2.80
per M tokens
MiniMax
MiniMax M2.5
$0.30 / $1.20
per M tokens
Qwen
Qwen3.5 122B
$0.40 / $3.00
per M tokens
How to use this skill
Install typo3-rector by running npx skills add dirnbauer/webconsulting-skills --skill typo3-rector in your project directory. Run the install command above in your project directory. The skill file will be downloaded from GitHub and placed in your project.
No configuration needed. Your AI agent (Claude Code, Cursor, Windsurf, etc.) automatically detects installed skills and uses them as context when generating code.
The skill enhances your agent's understanding of typo3-rector, helping it follow established patterns, avoid common mistakes, and produce production-ready output.
What you get
Skills are plain-text instruction files — not executable code. They encode expert knowledge about frameworks, languages, or tools that your AI agent reads to improve its output. This means zero runtime overhead, no dependency conflicts, and full transparency: you can read and review every instruction before installing.
Compatibility
This skill works with any AI coding agent that supports the skills.sh format, including Claude Code (Anthropic), Cursor, Windsurf, Cline, Aider, and other tools that read project-level context files. Skills are framework-agnostic at the transport level — the content inside determines which language or framework it applies to.
Chat with 100+ AI Models in one App.
Use Claude, ChatGPT, Gemini alongside with EU-Hosted Models like Deepseek, GLM-5, Kimi K2.5 and many more.