TCA中MM表复用问题:News与EventNews扩展关联字段配置
Got it, let's work through this TYPO3 setup where you're using the news and eventnews extensions, and need to add separate relation fields for event news while reusing the same MM table. Here's a step-by-step solution to make this work smoothly:
1. Lock in Your TCA Field Configuration
First, confirm your related_event and related_event_from TCA fields are set up with the right foreign_table_where to target only event news (or normal news for the reverse field). Here's a concrete example:
'related_event' => [ 'label' => 'Related Event News', 'config' => [ 'type' => 'select', 'renderType' => 'selectMultipleSideBySide', 'foreign_table' => 'tx_news_domain_model_news', 'foreign_table_where' => 'AND tx_news_domain_model_news.is_event = 1 AND tx_news_domain_model_news.pid=###CURRENT_PID###', 'MM' => 'tx_news_domain_model_news_related_mm', // Reuse the default news MM table 'MM_opposite_field' => 'related_event_from', 'size' => 10, 'autoSizeMax' => 30, 'maxitems' => 9999, ], ], 'related_event_from' => [ 'config' => [ 'type' => 'select', 'renderType' => 'selectMultipleSideBySide', 'foreign_table' => 'tx_news_domain_model_news', 'foreign_table_where' => 'AND tx_news_domain_model_news.is_event = 0 AND tx_news_domain_model_news.pid=###CURRENT_PID###', 'MM' => 'tx_news_domain_model_news_related_mm', 'MM_opposite_field' => 'related_event', 'size' => 10, 'autoSizeMax' => 30, 'maxitems' => 9999, 'readOnly' => true, // Optional: make reverse relation read-only in backend ], ],
The big catch here: the default MM table only stores uid_local and uid_foreign—we need a way to tell normal relations apart from event relations. That means extending the MM table.
2. Add a Relation Type Column to the MM Table
We’ll add a relation_type column to categorize entries as either normal (for the original related/related_from fields) or event (for your new fields).
2.1 Run the SQL Alter
Create an ext_tables.sql file in your custom extension (or use the TYPO3 install tool’s SQL query box) to add the column:
ALTER TABLE tx_news_domain_model_news_related_mm ADD COLUMN relation_type VARCHAR(20) DEFAULT 'normal' NOT NULL;
2.2 Update TCA to Use This Column
Modify both the original and new relation fields in TCA to use MM_match_fields—this tells TYPO3 which MM entries belong to each field.
For the original related field:
'related' => [ // ... keep your existing config ... 'MM_match_fields' => [ 'relation_type' => 'normal', ], ],
For your new related_event field:
'related_event' => [ // ... keep your existing config ... 'MM_match_fields' => [ 'relation_type' => 'event', ], ],
Repeat this for related_from and related_event_from to ensure reverse relations pull the correct entries.
3. Auto-Set the Relation Type on Save
TYPO3 won’t automatically populate the relation_type column when you save relations, so we’ll add a hook to handle this.
3.1 Register the Hook in ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = \YourVendor\YourExtension\Hooks\NewsRelationHook::class;
3.2 Create the Hook Class
namespace YourVendor\YourExtension\Hooks; use TYPO3\CMS\Core\DataHandling\DataHandler; class NewsRelationHook { public function processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, DataHandler $dataHandler) { // Only act on news records if ($table !== 'tx_news_domain_model_news') { return; } // Update relation type for new event relations if (isset($fieldArray['related_event'])) { $this->setRelationType($dataHandler, 'event', $id); } // Optional: backfill relation type for existing normal relations if (isset($fieldArray['related'])) { $this->setRelationType($dataHandler, 'normal', $id); } } protected function setRelationType(DataHandler $dataHandler, $type, $localUid) { $mmTable = 'tx_news_domain_model_news_related_mm'; // Update entries where the local uid matches and relation type is incorrect $dataHandler->database->exec_UPDATEquery( $mmTable, 'uid_local = ' . (int)$localUid . ' AND relation_type != "' . $dataHandler->database->quote($type) . '"', ['relation_type' => $type] ); // Also update the reverse direction (uid_foreign) $dataHandler->database->exec_UPDATEquery( $mmTable, 'uid_foreign = ' . (int)$localUid . ' AND relation_type != "' . $dataHandler->database->quote($type) . '"', ['relation_type' => $type] ); } }
This hook will automatically set the correct relation_type every time you save a news record with updated relations.
4. Migrate Existing MM Data (If Needed)
If you already have relations in the MM table, run this SQL to backfill the relation_type for existing entries:
// Mark all existing entries as normal (adjust if you have pre-existing event relations) UPDATE tx_news_domain_model_news_related_mm SET relation_type = 'normal' WHERE relation_type = '';
Key Takeaways
MM_match_fieldsis non-negotiable: It ensures TYPO3 doesn’t mix up normal and event relations in the shared MM table.- The hook removes manual work: You won’t have to edit the MM table every time you add a relation.
- Keep your
foreign_table_whereclauses: They prevent users from selecting the wrong news type in each relation field in the backend.
内容的提问来源于stack exchange,提问作者Falk

