typo3-rector について
TYPO3 開発者向けに、Rector で PHP コードを TYPO3 v14 向けに移行する方法を案内するスキルです。設定、変更のプレビュー、自動ルールの適用、代表的な移行パターンを扱い、PHP 以外の移行は Fractor の範囲として区別します。
主な機能
- 01TYPO3 v14 向け Rector 設定ガイド
- 02PHP の自動移行パターン
- 03移行のプレビューと適用手順
- 04TYPO3 API と規約の指針
- 05v14 の代表的なコード例
活用シーン
- 01TYPO3 PHP プロジェクトの v14 移行準備
- 02適用前に移行内容をプレビュー
- 03Rector ルールによる拡張コードの更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dirnbauer/ webconsulting-skills --skill typo3-rectorインストール後、Claude Code で/typo3-rectorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/06-typo3-v14-platform-snapshot.md07-step-by-step-migration-process.md08-troubleshooting.md09-common-rector-rules.md10-resources.mdcredits-and-attribution.mdfull-guide.mdv14-only-rector-targets.md詳細
TYPO3 Rector アップグレードパターン
互換性: TYPO3 v14.x このスキルでは、TYPO3 v14 で動作するコードを記述するためのパターンを扱います。
TYPO3 API を優先: カスタム実装を作成する前に、必ず TYPO3 の組み込み API、コア機能、確立された規約を使用してください。TYPO3 がすでに提供している機能を再実装しないでください。使用する API とメソッドが TYPO3 v14 に存在し、非推奨になっていないことを、必ず TYPO3 の公式ドキュメントで確認してください。
1. TYPO3 Rector の概要
Rector は、TYPO3 のメジャーバージョン間で PHP コードを移行するための自動リファクタリングツールです。あらかじめ定義されたルールを適用し、非推奨のコードパターンを更新します。PHP 以外の移行(FlexForms、TypoScript、Fluid、YAML)には Fractor を使用してください。詳しくは typo3-fractor スキルを参照してください。
インストール
composer require --dev ssch/typo3-rector
# or with DDEV:
ddev composer require --dev ssch/typo3-rector
重要: Rector はプロジェクトのオートローダーを読み込みます。TYPO3 v14 プロジェクトでは、TYPO3 v14 パッケージが
readonlyクラスやその他の PHP 8.2 構文を使用するため、Rector は 必ず PHP 8.2 以降で実行する必要があります。また、webconsulting のプロジェクトは PHP 8.4 以降を対象としているため、プロジェクトが必要とするものと同じ PHP バージョンで Rector を実行してください。ローカルの PHP が古い場合は、必ず DDEV またはコンテナーを使用してください:ddev exec vendor/bin/rector process --dry-run
Rector は必ず実行し、省略しないでください。 手動での置き換え(例:
strposからstr_starts_with)では、Rector のルールが正しく処理するエッジケースを見落とします。また Rector は、手作業では見つけにくい TYPO3 の非推奨名前空間の変更やメソッドシグネチャの更新も検出します。
基本設定(TYPO3 v14 を対象)
プロジェクトのルートに rector.php を作成します:
<?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_84)
->withSets([
LevelSetList::UP_TO_PHP_84,
Typo3LevelSetList::UP_TO_TYPO3_14,
])
->withImportNames();
段階的なアップグレード: 非常に古いコードベースでは、まず専用の手順で
UP_TO_TYPO3_13を実行し、その後UP_TO_TYPO3_14を実行できます。公開するエクステンションでは、v14 向けのリリース時にtypo3/cms-core: ^14.3を指定してください。14.0 から 14.2 には、セキュリティ更新が提供されなくなっています。
現在の状況(typo3-rector v3.14、2026 年半ば)
typo3-rector 3.14 は Rector 2.5 上で動作し、Simon Schaufelberger によって保守されています。一部は TYPO3 コミュニティの予算による資金提供を受けています。各移行の前に composer update ssch/typo3-rector を実行し、最新の v14 ルールが適用されるようにしてください。3.14 の主な変更点:
- TYPO3 にバンドルされていた Fluid のクラス名を、TYPO3 v14 が使用する独立版 Fluid のクラス名に移行
makeCategorizable()の登録を移行$GLOBALS['TSFE']->fe_userの移行対象を拡大HashServiceとMailMessage::send()の移行を強化
2. Rector の実行
ドライラン(変更内容のプレビュー)
# 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-run
変更を適用
# Apply all changes
ddev exec vendor/bin/rector process
# Apply to specific path
ddev exec vendor/bin/rector process packages/my_extension
実行後にキャッシュをクリア
ddev typo3 cache:flush
ddev composer dump-autoload
3. バージョン制約と追加の Rector セット
バージョン制約
TYPO3 v14 を対象とするエクステンションの場合:
<?php
// ext_emconf.php
$EM_CONF[$_EXTKEY] = [
'title' => 'My Extension',
'version' => '2.0.0',
'state' => 'stable',
'constraints' => [
'depends' => [
'typo3' => '14.3.0-14.99.99',
'php' => '8.4.0-8.5.99',
],
'conflicts' => [],
'suggests' => [],
],
];
// composer.json
{
"require": {
"php": "^8.4",
"typo3/cms-core": "^14.3"
}
}
オプション:TYPO3 v14 のルールセットのみ
Rector のバージョンに応じて、レベルセットに追加するか、レベルセットの代わりに、v14 のルールを明示的に追加します:
<?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. 主な移行パターン(TYPO3 v14)
Fluid ViewFactory(StandaloneView を置き換え)
ViewFactory のアプローチは 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 コントローラーのレスポンス(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 イベント(フックより推奨)
PSR-14 イベントは TYPO3 v14 で動作します。従来のフックの代わりに使用してください:
<?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);
}
}
バックエンドモジュールの登録(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',
],
],
],
];
サービス設定(Services.yaml)
# Configuration/Services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Vendor\MyExtension\:
resource: '../Classes/*'
exclude:
- '../Classes/Domain/Model/*'
5. TCA のベストプラクティス(TYPO3 v14)
静的 TCA のみ
v14 では、読み込み後に $GLOBALS['TCA'] が読み取り専用になります。必ず静的 TCA ファイルを使用してください:
<?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,
],
],
],
];
詳細リファレンス
詳細な例、長いテンプレート、トラブルシューティング用の一覧表、付録、または上記に含まれていないセクションが必要な場合は、完全ガイドをお読みください。スキルが段階的開示に従うよう、範囲の限られたタスクではこのファイルを読み込まないでください。