typo3-extension-upgrade

Systematic TYPO3 extension upgrades to newer LTS versions. Covers Extension Scanner, Rector, Fractor, PHPStan, and testing. Use when working with extension, upgrade, fractor, rector, migration.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "typo3-extension-upgrade" with this command: npx skills add dirnbauer/webconsulting-skills/dirnbauer-webconsulting-skills-typo3-extension-upgrade

TYPO3 Extension Upgrade Skill

Systematic framework for upgrading TYPO3 extensions to newer LTS versions.

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 your target TYPO3 version (v13 or v14) by checking the official TYPO3 documentation.

Scope: Extension code upgrades only. NOT for TYPO3 project/core upgrades.

Upgrade Toolkit

ToolPurposeFiles
Extension ScannerDiagnose deprecated APIsTYPO3 Backend
RectorAutomated PHP migrations.php
FractorNon-PHP migrations (see typo3-fractor skill)FlexForms, TypoScript, YAML, Fluid
PHPStanStatic analysis.php

Planning Phase (Required)

Before ANY code changes for major upgrades:

  1. List all files with hardcoded versions (composer.json, CI, Docker, Rector)
  2. Document scope - how many places need changes?
  3. Present plan to user for approval
  4. Track progress with todo list

Pre-Upgrade Checklist

  • Extension key and current TYPO3 version documented
  • Target TYPO3 version(s) identified (v13, v14, or both)
  • Current PHP version and target PHP version noted
  • All deprecation warnings from logs collected
  • Extension Scanner report reviewed
  • Dependencies checked for target version compatibility

Upgrade Workflow

1. Prepare Environment

# Create backup/snapshot
ddev snapshot --name=before-upgrade

# Verify git is clean
git status

# Create feature branch
git checkout -b feature/typo3-14-upgrade

PHP version requirement: Rector and Fractor load your project's autoloader, which means TYPO3 v14 packages are parsed by PHP. You must run these tools with PHP 8.2+ (matching TYPO3 v14's minimum). If your local PHP is older, use DDEV (ddev exec vendor/bin/rector ...) or a Docker container. Do not skip Rector/Fractor and do manual replacements instead -- the tools catch patterns that are easy to miss manually (namespace renames, FlexForm structure changes, TypoScript condition syntax).

2. Install Upgrade Tools

Add the upgrade tools as dev dependencies before updating version constraints:

composer require --dev ssch/typo3-rector a9f/typo3-fractor

This ensures the tools can analyze your code against the target version's rules.

3. Update Version Constraints

// composer.json
{
    "require": {
        "php": "^8.2",
        "typo3/cms-core": "^13.0 || ^14.0"
    }
}
// ext_emconf.php
$EM_CONF[$_EXTKEY] = [
    'constraints' => [
        'depends' => [
            'typo3' => '13.0.0-14.99.99',
            'php' => '8.2.0-8.4.99',
        ],
    ],
];

4. Run Rector

Rector handles PHP code migrations automatically.

Configuration

<?php
// rector.php
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Ssch\TYPO3Rector\Set\Typo3LevelSetList;
use Ssch\TYPO3Rector\Set\Typo3SetList;

return RectorConfig::configure()
    ->withPaths([
        __DIR__ . '/Classes',
        __DIR__ . '/Configuration',
        __DIR__ . '/Tests',
    ])
    ->withSkip([
        __DIR__ . '/Resources',
    ])
    ->withSets([
        // PHP version upgrades
        LevelSetList::UP_TO_PHP_82,
        
        // TYPO3 upgrades
        Typo3LevelSetList::UP_TO_TYPO3_13,
        Typo3SetList::TYPO3_13,
    ])
    ->withImportNames();

Run Rector

# Dry run first
vendor/bin/rector process --dry-run

# Review changes, then apply
vendor/bin/rector process

# Review git diff
git diff

5. Run Fractor

Fractor handles non-PHP file migrations (FlexForms, TypoScript, Fluid, YAML, Htaccess). See the typo3-fractor skill for detailed configuration, all available rules, code style options, and custom rule creation.

Configuration

<?php
// fractor.php
declare(strict_types=1);

use a9f\Fractor\Configuration\FractorConfiguration;
use a9f\Typo3Fractor\Set\Typo3LevelSetList;

return FractorConfiguration::configure()
    ->withPaths([
        __DIR__ . '/Configuration/',
        __DIR__ . '/Resources/',
    ])
    ->withSets([
        Typo3LevelSetList::UP_TO_TYPO3_13,
    ]);

Run Fractor

# Dry run first
vendor/bin/fractor process --dry-run

# Review changes, then apply
vendor/bin/fractor process

6. Fix Code Style

# Run PHP-CS-Fixer
vendor/bin/php-cs-fixer fix

# Verify no issues remain
vendor/bin/php-cs-fixer fix --dry-run

7. Run PHPStan

# Analyze codebase
vendor/bin/phpstan analyse

# Fix any reported issues
# Then re-run until clean

8. Run Tests

# Unit tests
vendor/bin/phpunit -c Tests/UnitTests.xml

# Functional tests
vendor/bin/phpunit -c Tests/FunctionalTests.xml

# Fix failing tests

9. Manual Testing

# Test in target TYPO3 version
ddev composer require "typo3/cms-core:^14.0" --no-update
ddev composer update
ddev typo3 cache:flush

# Test all extension functionality:
# - Backend modules
# - Frontend plugins
# - CLI commands
# - Scheduler tasks

Common Migration Patterns

ViewFactory (Replaces StandaloneView)

// ❌ OLD (deprecated in v13, removed in v14)
use TYPO3\CMS\Fluid\View\StandaloneView;

$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplatePathAndFilename('...');

// ✅ NEW (v13/v14 compatible)
use TYPO3\CMS\Core\View\ViewFactoryInterface;
use TYPO3\CMS\Core\View\ViewFactoryData;

public function __construct(
    private readonly ViewFactoryInterface $viewFactory,
) {}

public function render(ServerRequestInterface $request): string
{
    $viewFactoryData = new ViewFactoryData(
        templateRootPaths: ['EXT:my_ext/Resources/Private/Templates'],
        request: $request,
    );
    $view = $this->viewFactory->create($viewFactoryData);
    $view->assign('data', $data);
    return $view->render('MyTemplate');
}

Controller ResponseInterface

// ❌ OLD (v12 and earlier)
public function listAction(): void
{
    $this->view->assign('items', $items);
}

// ✅ NEW (v13+ required)
public function listAction(): ResponseInterface
{
    $this->view->assign('items', $items);
    return $this->htmlResponse();
}

PSR-14 Events (Replace Hooks)

// ❌ OLD (hooks deprecated)
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['...']['hook'][] = MyHook::class;

// ✅ NEW (PSR-14 events)
// Configuration/Services.yaml
services:
  Vendor\MyExt\EventListener\MyListener:
    tags:
      - name: event.listener
        identifier: 'myext/my-listener'

// Or use PHP attribute
#[AsEventListener(identifier: 'myext/my-listener')]
final class MyListener
{
    public function __invoke(SomeEvent $event): void
    {
        // Handle event
    }
}

Static TCA (No Runtime Modifications)

// ❌ OLD (runtime TCA modification - forbidden in v14)
// ext_tables.php
$GLOBALS['TCA']['tt_content']['columns']['myfield'] = [...];

// ✅ NEW (static TCA files only)
// Configuration/TCA/Overrides/tt_content.php
$GLOBALS['TCA']['tt_content']['columns']['myfield'] = [...];

Backend Module Registration

// ❌ OLD (ext_tables.php registration)
ExtensionUtility::registerModule(...);

// ✅ NEW (Configuration/Backend/Modules.php)
return [
    'web_mymodule' => [
        'parent' => 'web',
        'access' => 'user,group',
        'iconIdentifier' => 'myext-module',
        'labels' => 'LLL:EXT:my_ext/Resources/Private/Language/locallang_mod.xlf',
        'extensionName' => 'MyExt',
        'controllerActions' => [
            MyController::class => ['index', 'list'],
        ],
    ],
];

API Changes Reference

TYPO3 v13 Breaking Changes

Removed/ChangedReplacement
StandaloneViewViewFactoryInterface
ObjectManagerConstructor injection
TSFE->fe_user->userRequest attribute
Various hooksPSR-14 events

TYPO3 v14 Breaking Changes

Removed/ChangedReplacement
Runtime TCA changesStatic TCA only
Legacy backend modulesModules.php
$GLOBALS['TYPO3_DB']QueryBuilder

Troubleshooting

Rector Fails

# Clear Rector cache
rm -rf .rector_cache/

# Run with verbose output
vendor/bin/rector process --dry-run -vvv

# Skip problematic rules
# Add to rector.php:
->withSkip([
    \Ssch\TYPO3Rector\SomeRule::class,
])

PHPStan Errors

# Generate baseline for existing issues
vendor/bin/phpstan analyse --generate-baseline

# Add to phpstan.neon:
includes:
    - phpstan-baseline.neon

Extension Not Found

# Regenerate autoload
ddev composer dump-autoload

# Clear all caches
ddev typo3 cache:flush
rm -rf var/cache/*

# Re-setup extension
ddev typo3 extension:setup

Database Issues

# Check for schema differences
ddev typo3 database:updateschema --verbose

# Apply schema changes
ddev typo3 database:updateschema "*.add,*.change"

Success Criteria

Before considering upgrade complete:

  • rector --dry-run shows no changes
  • fractor --dry-run shows no changes
  • phpstan analyse passes
  • php-cs-fixer --dry-run passes
  • All unit tests pass
  • All functional tests pass
  • Manual testing in target version(s) complete
  • No deprecation warnings in logs
  • Extension works in TYPO3 v13
  • Extension works in TYPO3 v14

Resources

v14-Only Upgrade Targets

The following upgrade targets are v14-specific breaking changes to address during extension upgrades.

Critical v14 Breaking Changes

ChangeMigration
$GLOBALS['TSFE'] / TypoScriptFrontendController removedUse request attributes (frontend.page.information, language)
Extbase annotations removedUse #[Validate], #[IgnoreValidation] PHP attributes
MailMessage->send() removedUse Mailer::send()
FlexFormService removedUse FlexFormTools
DataHandler userid/admin/storeLogMessages removedUse $GLOBALS['BE_USER'] directly
Frontend asset concat/compress removedDelegate to web server or build tools
Plugin subtypes removedRegister separate plugins via configurePlugin()
TCA ctrl.searchFields removedUse per-column 'searchable' => true
Backend module parent IDs changedwebcontent, filemedia, toolsadministration
Fluid 5.0 strict typesFix ViewHelper argument types, remove underscore-prefixed variables

v14.2 Deprecations (prepare for v15)

DeprecatedImpact
PageDoktypeRegistry methodsMigrate to TCA allowedRecordTypes
ExtensionManagementUtility::addFieldsToUserSettingsUse TCA
Localization parsers (XliffParser)Symfony Translation Component
ButtonBar/Menu make* methodsUse ComponentFactory
Scheduler task registration via SC_OPTIONSUse TCA-based registration

Credits & Attribution

Thanks to Netresearch DTT GmbH for their contributions to the TYPO3 community.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ai-search-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
General

document-processing

No summary provided by upstream source.

Repository SourceNeeds Review
General

typo3-content-blocks

No summary provided by upstream source.

Repository SourceNeeds Review
General

php-modernization

No summary provided by upstream source.

Repository SourceNeeds Review