typo3-workspaces について
TYPO3 v14 の Workspaces を扱う開発者向けスキルで、バージョン管理、オーバーレイ、公開手順、ファイル処理の制約を扱います。TYPO3 の組み込み API の利用を重視し、ファイルやファイルコレクションに関するリスクと対策も説明します。
主な機能
- 01ワークスペースの版管理とオーバーレイの説明
- 02公開ワークフローと API の解説
- 03FAL とファイルコレクションの制約
- 04ファイルの機密性リスクの特定
- 05ワークスペース対応のファイル運用
活用シーン
- 01TYPO3 v14 の Workspaces 機能開発
- 02ワークスペースの版管理動作の確認
- 03未公開ファイルの露出防止
- 04安全性を考慮したファイルコレクションの選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dirnbauer/ webconsulting-skills --skill typo3-workspacesインストール後、Claude Code で/typo3-workspacesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/04-datahandler-setup-script.md05-making-extensions-workspace-compatible.md06-migrating-queries-without-workspaces-to-with-workspaces.md07-translations-with-workspaces.md08-debugging-and-troubleshooting.md09-testing-workspace-support.md09a-workspace-diagnostics-and-repair-playbook.md10-best-practices.md11-psr-14-events-reference.mdcredits-and-attribution.mdfull-guide.mdrelated-skills.mdv14-only-changes.md詳細
TYPO3 ワークスペース
互換性: TYPO3 v14.x このスキルのすべてのコード例は、TYPO3 v14 で動作するように設計されています。
TYPO3 API を優先: カスタム実装を作成する前に、必ず TYPO3 の組み込み API、コア機能、確立された規約を使用してください。TYPO3 がすでに提供している機能を再実装しないでください。使用する API やメソッドが TYPO3 v14 に存在し、非推奨になっていないことを、公式 TYPO3 ドキュメントで必ず確認してください。
参考資料
このスキルは、以下の17件の信頼できる資料に基づいています。
- TYPO3 Workspaces 拡張機能ドキュメント
- バージョニング(Workspaces 拡張機能)
- カスタムワークスペースの作成
- 設定オプション(Workspaces)
- PSR-14 イベント(Workspaces)
- バージョニングとワークスペース(TYPO3 Explained / コア API)
- TCA versioningWS リファレンス
- Restriction Builder(TYPO3 Explained / Doctrine DBAL)
- b13 ブログ:TYPO3 オーバーレイの優れた効率性(Benni Mack)
- スケジューラータスク(Workspaces)
- ユーザーガイド(Workspaces)
- TYPO3-CORE-SA-2025-022:Workspaces モジュールにおける情報漏えい
- ローカライズされたコンテンツのガイド
- ファイルコレクション(TYPO3 Explained)
- FAL データベースアーキテクチャ
- Forge バグ #60343:sys_file_metadata がワークスペースを認識しない
- Forge 機能 #97923:sys_file_collection 用の統合された folder_identifier フィールド
1. 基本概念
ワークスペースとは?
ワークスペースを使用すると、編集者は公開中のウェブサイトに影響を与えずにコンテンツの変更を準備できます。変更は、公開前に設定可能なレビュー手順を経ます。
ワークスペースには、次の2種類があります。
- LIVE ワークスペース(ID=0):デフォルトの状態です。すべての変更が即座に公開されます。バックエンドユーザー/グループへのアクセス権は、明示的に付与する必要があります。
- カスタムワークスペース(ID>0):安全な編集環境です。変更はバージョン管理され、プレビューでき、公開前に各ステージを経ます。
バージョン管理の仕組み(データベースレベル)
オフライン(ワークスペース)バージョンは、公開レコードと同じデータベーステーブルに保存されます。次の項目で識別されます。
| フィールド | 目的 |
|---|---|
t3ver_oid | 公開レコードの uid を指します(公開レコードとワークスペースで新規作成されたレコードでは 0) |
t3ver_wsid | このバージョンが属するワークスペース ID(公開レコードでは 0) |
t3ver_state | 特別な状態フラグ(下記参照) |
t3ver_stage | ワークフローのステージ(0=編集中、-10=公開準備完了) |
pid | 実際のページ ID(公開レコードの pid と同じ) |
注記: TYPO3 v10.4 より前は、オフラインバージョンの
pid = -1でした。v10.4 以降(Important #89555、「ワークスペース関連のデータベースレコードに正しいページ ID が格納される」)では、ワークスペースレコードに実際の pidが格納されます。別途行われた v11 の変更(Breaking #92497)では、移動用プレースホルダーが削除されました。レガシーコードやドキュメントでpid = -1を見かけた場合は、古い情報です。
t3ver_state の値(TYPO3 v14):
| 値 | 意味 |
|---|---|
0 | デフォルト:既存の公開レコードに対するワークスペースでの変更 |
1 | ワークスペース内でのみ作成された新規レコード(公開側に対応するレコードなし) |
2 | 削除用プレースホルダー(公開時に削除するようマークされたレコード) |
4 | 移動ポインター(公開時に移動されるレコード。新しい pid/sorting を格納) |
v11 で削除:
t3ver_state = -1(古い「新規バージョン」相当)、t3ver_state = 3(古い「移動用プレースホルダー」)、およびt3ver_move_idフィールド。レガシーコードでこれらの値を見かけても、TYPO3 v14 では使用されていません。
オーバーレイの仕組み
TYPO3 は必ず最初に公開レコードを取得し、その上にワークスペースのバージョンをオーバーレイします。ワークスペースを使用する翻訳では、次の順序になります。
- デフォルト言語の公開レコードを取得(language=0、workspace=0)
- ワークスペースのバージョンをオーバーレイ(
t3ver_oid=<uid>ANDt3ver_wsid=<current_ws>を検索) - 言語翻訳をオーバーレイ(対象言語で
l10n_parent=<uid>を検索) - 翻訳のワークスペースバージョンをオーバーレイ
オーバーレイ中も、公開レコードの uid は常に維持されます。これにより、すべての参照とリンクがそのまま保たれます。
公開ワークフロー
- 公開:ワークスペースの公開処理を通じて、下書きコンテンツが公開コンテンツに置き換わります。
- TYPO3 v14 では引き続き、DataHandler の
versionコマンドでaction => 'publish'(推奨)またはaction => 'swap'(DataHandlerHookで公開と同じように処理されるエイリアス)が使えます。ワークスペースバージョン UID のパラメーターキーは、引き続きswapWithであり、uidではありません。 sys_workspaceの過去の双方向ワークスペース「スワップモード」(v11 で削除、#92206)には依存しないでください。これは cmdmaps 内のswapキーワードとは別のものです。
2. 重要:ファイル/FAL の制限
ファイル(FAL)はバージョン管理されません。 これは TYPO3 Workspaces における最も重要な制限です。 フォルダーベースのコレクションに関する追加のファイルコレクションの制限については、以下のセクション 2a も参照してください。
これが意味すること
fileadmin/内のファイルは、LIVE ワークスペースにのみ存在します- ファイルを上書きすると、その変更はすべてのワークスペースに即座に反映されます
sys_file_referenceレコードはワークスペースバージョン管理されますが、物理ファイルとsys_fileレコードはコンテンツのオーバーレイと同じようにはバージョン管理されません- 既存の参照内のファイルを置き換えると、ワークスペースプレビューで予期しない問題が生じる場合があります。実際に使用する TYPO3 のマイナーバージョンでテストし、可能であれば既存ファイルの上書きより新しいファイル名を使ってください。
予測可能なファイル名によるセキュリティ上の問題
シナリオ: 編集者がページのワークスペースバージョンで、geschaeftsbericht2024.pdf を geschaeftsbericht2025.pdf に置き換えます。ワークスペースはまだ公開されていません。しかし、
- 新しい PDF はすぐに
fileadmin/にアップロードされます(ファイルは公開状態です!) - 外部の人物が年を増やして URL を推測します
geschaeftsbericht2025.pdfは、それを参照するコンテンツ要素が公開される前からアクセス可能です
これは実際に起こり得るセキュリティ/機密性のリスクです。
回避策
1. 推測されにくいファイル名を使用します:
# Instead of:
fileadmin/reports/geschaeftsbericht2025.pdf
# Use hashed/random names:
fileadmin/reports/gb-a8f3e2b1c9d4.pdf
2. 機密ファイルをウェブルートの外に保存します:
// config/system/settings.php
// Use a private storage that is NOT publicly accessible
// Deliver files programmatically via a controller
3. EXT:secure_downloads (leuchtfeuer/secure-downloads) を使用します:
ファイルは、アクセス権限を確認する PHP スクリプトを通じて配信されます。ファイルの URL に直接アクセスすることはできません。
4. 機密ディレクトリをサーバーレベルで保護します:
# Apache (.htaccess in a subdirectory)
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# NGINX
location /fileadmin/confidential/ {
deny all;
return 403;
}
5. ワークスペースのバージョンごとに別々のファイル参照を使用します:
新しいファイルは別の名前でアップロードしてください。既存のファイルを上書きしてはいけません。コンテンツ要素のワークスペースバージョンでは新しいファイルを参照し、公開中のバージョンでは古いファイルを参照します。公開後は両方のファイルが存在しますが、参照されるのは新しいファイルのみです。
ワークスペースで安全にファイルを扱うためのルール
- コンテンツ要素でワークスペース間にわたって使用されているファイルを絶対に上書きしないでください
- ワークスペース用のコンテンツを準備する際は、必ず一意の名前で新しいファイルをアップロードしてください
- ファイルの機密性を守るために「ページがまだ公開されていない」ことに絶対に頼らないでください
- 機密文書には EXT:secure_downloads の使用を検討してください
fileadmin/内に推測可能な命名パターンのファイルがないか監査してください
2a. ファイルコレクションとワークスペース
ファイルコレクション(
sys_file_collection)はレコードレベルでワークスペースのバージョン管理対象になりますが、フォルダーベースのコレクションは実行時にライブファイルシステムからファイルを解決します。オーバーレイするデータベースリレーションはありません。
ファイルコレクションの仕組み
sys_file_collection には、type フィールドで区別される3種類のコレクションが保存されます。
type の値 | 解決方法 | 関連するデータベースリレーション |
|---|---|---|
static (0) | sys_file_reference の行(tablenames='sys_file_collection'、fieldname='files') | ファイルごとに1行の sys_file_reference |
folder (1) | folder_identifier 文字列(例:1:/user_upload/gallery/) | なし -- 中間テーブルも参照行もありません |
category (2) | sys_category_record_mm を介して解決される category UID | MM テーブル(親レコードのオーバーレイで処理) |
sys_file_collection の TCA では versioningWS => true が設定されています。つまり、コレクションレコード自体に t3ver_* フィールドを持つワークスペースバージョンが作成されます。ただし、レコードレベルのバージョン管理で対象となるのは sys_file_collection に保存されたフィールドだけであり、コレクションが解決するファイルはバージョン管理されません。
コレクションタイプごとのワークスペースでの安全性
| コレクションタイプ | レコードのバージョン管理 | ファイルの関連付けのバージョン管理 | 物理ファイルのバージョン管理 | ワークスペースで安全か |
|---|---|---|---|---|
| 静的 | はい | はい(sys_file_reference に versioningWS = true が設定されています) | いいえ | 一部安全 |
| フォルダーベース | はい(レコードのみ) | いいえ -- DB 上の関連付けがありません | いいえ | 安全ではありません |
| カテゴリーベース | はい | 一部(カテゴリーの MM は親レコードのオーバーレイで処理) | いいえ | 一部安全 |
フォルダーベースのコレクションでワークスペースの分離が損なわれる理由
フォルダーベースのコレクションでは、コレクションとファイルの間にある「リレーション」はデータベースリレーションではありません。コレクションレコードに保存されるのは folder_identifier 文字列のみです。FolderBasedFileCollection::loadContents() が呼び出されると、TYPO3 は $storage->getFilesInFolder() を呼び出して、ライブストレージドライバーから直接ファイルを一覧表示します。コレクションとファイルの間に、オーバーレイに対応するデータベース行はありません。
その結果:
- フォルダーにファイルを追加すると、直ちにすべてのワークスペースで表示されます
- フォルダーからファイルを削除すると、直ちにすべてのワークスペースから削除されます
- ワークスペースバージョンで
folder_identifierフィールドを変更すると別のフォルダーが指定されますが、フォルダーの内容は常にライブです - フォルダーベースのコレクションを使用する「ファイルリンク」コンテンツ要素(
CType=uploads)では、ワークスペースバージョンの作成後にフォルダーの内容が変更されていると、ワークスペースプレビューで意図とは異なるファイルが表示されます
静的コレクションはより安全です
静的コレクション(type=static)では、sys_file_reference 行を使ってファイルを紐付けます。sys_file_collection と sys_file_reference はどちらも versioningWS = true です。ワークスペース内で静的コレクションにファイルを追加または削除すると、TYPO3 は sys_file_reference 行のワークスペースバージョンを作成します。コレクションとファイルの紐付けはバージョン管理されます。
残る制限として、物理ファイル(sys_file)はバージョン管理されません(セクション 2 を参照)。ファイルを上書きすると、すべての場所で変更されます。
フォルダーベースのコレクションの回避策
1. ワークスペース間の分離が重要な場合は、静的コレクションを優先してください:
type=folder の代わりに type=static を使用してください。ファイルとコレクションの紐付けは sys_file_reference 行であり、ワークスペースのバージョン管理対象です。
2. ワークスペースのバージョンごとに別のフォルダーを使用してください:
フォルダーベースのコレクションでは、ワークスペースでの変更用に新しいフォルダー(例:gallery-v2/)を作成し、コレクションレコードのワークスペースバージョンにある folder_identifier を変更してください。ライブバージョンは引き続き元のフォルダーを参照します。
3. ワークスペースの下書きが参照している共有フォルダーの内容は変更しないでください:
フォルダーベースのコレクションがワークスペースのコンテンツで使用されている場合、ワークスペースが公開されるまで、そのフォルダーへのファイルの追加や削除は避けてください。
4. 公開後に古いフォルダーをクリーンアップしてください:
AfterRecordPublishedEvent を使用して、ワークスペースバージョンの公開後に不要になったフォルダーを削除します:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Resource\StorageRepository;
use TYPO3\CMS\Workspaces\Event\AfterRecordPublishedEvent;
#[AsEventListener]
final class CleanupOldCollectionFolderListener
{
public function __construct(
private readonly StorageRepository $storageRepository,
) {}
public function __invoke(AfterRecordPublishedEvent $event): void
{
if ($event->getTable() !== 'sys_file_collection') {
return;
}
// After publishing a folder-based collection, remove the old folder
// if it is no longer referenced by any collection.
// Implementation depends on your naming convention (e.g. gallery-v1/, gallery-v2/).
}
}
ワークスペースで安全にファイルコレクションを扱うためのルール
- ワークスペースを使用する場合は、フォルダーベースのコレクションよりも静的コレクション(
type=static)を優先してください - 未公開のワークスペース内のフォルダーベースのコレクションから参照されているフォルダーに、ファイルを追加または削除しないでください
- フォルダーベースのコレクションが必要な場合は、ワークスペースのバージョンごとに別のフォルダーを使用してください
- フォルダーベースのコレクションは、ワークスペースの状態にかかわらずライブフォルダーの内容を表示することを、編集者に明示してください
- 編集ワークフローで使用する前に、ワークスペースのプレビューでファイルコレクションの動作をテストしてください
3. インストールとセットアップのチェックリスト
インストール
# Composer (TYPO3 v14)
composer require typo3/cms-workspaces
# Non-Composer: activate in Admin Tools > Extensions
セットアップ完了チェックリスト
このチェックリストを使って、ワークスペースのセットアップが完了していることを確認してください:
拡張機能とシステム
-
typo3/cms-workspacesがインストールされ、有効化されている - データベーススキーマが最新である(
bin/typo3 extension:setupまたはプロジェクトで使用している同等のスキーマ更新ラッパー) -
typo3/cms-schedulerがインストールされている(自動公開に必要) - サーバーで Scheduler の cron ジョブが設定されている
バックエンドユーザーグループ
- ワークスペース専用のバックエンドユーザーグループが作成されている(例:「ワークスペース編集者」)
- グループに明示的な LIVE ワークスペースアクセス権がある(Mounts and Workspaces タブ > 「Live」チェックボックス)
- グループがカスタムワークスペースにアクセスできる(ワークスペースレコードで所有者またはメンバーとして割り当てられている)
- DB マウントが正しく設定されている(グループが編集できるページ)
- ファイルマウントが正しく設定されている(グループがアクセスできるディレクトリ)
- グループに関連するすべてのテーブルの
tables_modify権限がある - グループにワークスペースに含まれるページタイプの権限がある
バックエンドユーザー
- ユーザーがワークスペース用のユーザーグループに割り当てられている
- ユーザーがバックエンドのサイドバーにワークスペースセレクターを表示できる(v14.2 以降。v14 の以前のビルドでは、トップバーに表示される場合があります)
- 非管理者ユーザーに LIVE ワークスペースアクセス権を付与するのは、必要な場合に限る
ワークスペースレコード
- ルートページ(pid=0)にシステムレコードとしてワークスペースレコードが作成されている
- タイトルと説明が設定されている
- 所有者が割り当てられている(個々のユーザーではなく、グループを使用)
- メンバーが割り当てられている(個々のユーザーではなく、グループを使用)
- 必要に応じてカスタムステージが作成されている(「Editing」と「Ready to publish」の間)
- ステージごとに通知設定が構成されている
- 特定のページツリーにワークスペースを制限する場合、マウントポイントが設定されている
- 自動公開を行う場合、公開日が設定されている
- 「Publish access」が設定されている(必要に応じて公開を所有者に制限)
テーブル(TCA)
- すべてのカスタム拡張テーブルで、
$GLOBALS['TCA'][<table>]['ctrl']に'versioningWS' => trueが設定されている - バージョン管理しないテーブルでは、
'versioningWS' => falseが設定されている - ワークスペース内でのライブ編集が必要なテーブルでは、
'versioningWS_alwaysAllowLiveEdit' => trueが設定されている -
t3ver_*データベースカラムが存在する(versioningWS = trueの場合は自動作成)
インライン/IRRE 子テーブル(非推奨化 #106821: 子テーブルに
versioningWSがない場合、Core は非推奨化の警告をログに記録し、TCA の構築時にフラグを自動追加する場合があります。ハードエラーは発生しません。TCA で明示的にフラグを設定してください。v15 では必須要件になります。
スケジューラータスク
- 「Workspaces auto-publication」タスクが作成され、有効になっている
- 「Workspaces cleanup preview links」タスクが作成され、有効になっている
- Cron の実行間隔が適切である(例:15 分ごと)
TSconfig
-
options.workspaces.previewLinkTTLHoursが設定されている(デフォルト:48) - 言語制限が必要な場合、
options.workspaces.allowed_languages.<wsId>が設定されている - プレビューモードを制限する場合、
workspaces.splitPreviewModesが設定されている - カスタムレコードのプレビューページ用に
options.workspaces.previewPageIdが設定されている
詳細リファレンス
タスクで詳細な例、長いテンプレート、トラブルシューティングの一覧表、付録、または上記に含まれていないセクションが必要な場合は、完全ガイドをお読みください。対象を絞ったタスクでは、このファイルを読み込まず、段階的に情報を開示する方法に従ってください。