From 1692b7a69dcf62a9dc9ce1fe04ca794644220a8c Mon Sep 17 00:00:00 2001 From: "timo.klinge" Date: Thu, 30 Oct 2025 10:03:29 +0100 Subject: [PATCH 1/5] [TASK] compatibility with b13/container version 3 --- composer.json | 2 +- ext_emconf.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index cc478d1..81eeecd 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "license": "GPL-2.0-or-later", "require": { "typo3/cms-core": "^11.5 || ^12.4", - "b13/container": "^2.3.1" + "b13/container": "^2.3 || ^3.1" }, "suggest": { "georgringer/news": "Most usefull application of this extension." diff --git a/ext_emconf.php b/ext_emconf.php index bf9390d..bf9902c 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -20,7 +20,7 @@ 'constraints' => [ 'depends' => [ 'typo3' => '11.0.0-12.9.99', - 'container' => '2.3.1-2.9.99', + 'container' => '2.3.1-3.9.99', ], 'conflicts' => [ ], From 45977c466985da244801cb44ce63f126fddb4744 Mon Sep 17 00:00:00 2001 From: "timo.klinge" Date: Thu, 30 Oct 2025 10:05:05 +0100 Subject: [PATCH 2/5] [BUGFIX] display inline elements in correct language - hide translated inline elements in original language - show inline elements in correct language - fixes #19 --- ...drenLanguageCorrectionFormDataProvider.php | 64 +++++++++++++++++++ Classes/Hooks/DataHandler.php | 40 ++++++++++++ ext_emconf.php | 2 +- ext_localconf.php | 9 ++- 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 Classes/Backend/FormDataProvider/ContainerChildrenLanguageCorrectionFormDataProvider.php diff --git a/Classes/Backend/FormDataProvider/ContainerChildrenLanguageCorrectionFormDataProvider.php b/Classes/Backend/FormDataProvider/ContainerChildrenLanguageCorrectionFormDataProvider.php new file mode 100644 index 0000000..2449803 --- /dev/null +++ b/Classes/Backend/FormDataProvider/ContainerChildrenLanguageCorrectionFormDataProvider.php @@ -0,0 +1,64 @@ +getRegisteredCTypes(); + $cType = $result['databaseRow']['CType'][0] ?? ''; + if (!in_array($cType, $registeredCTypes, true)) { + return $result; + } + + $parentLanguageUid = (int)$result['databaseRow']['sys_language_uid'] ?? 0; + + $children =& $result['processedTca']['columns']['tx_t23inlinecontainer_elements']['children']; + $translationsExistFor = []; + + // store ids of original language elements that have a translation + foreach ($children as &$child) { + $lang = (int)$child['databaseRow']['sys_language_uid'] ?? 0; + $origUid = (int)($child['databaseRow']['l18n_parent'][0] ?? 0); + if ($parentLanguageUid === 0 && $lang > 0) { + continue; + } + if ($parentLanguageUid > 0 && $lang === $parentLanguageUid && $origUid > 0) { + $translationsExistFor[] = $origUid; + } + // if child language differs from parents language, grey out child in backend + $child['isInlineDefaultLanguageRecordInLocalizedParentContext'] = ($lang !== $parentLanguageUid); + } + + $filteredChildren = []; + + foreach ($children as $i => &$child) { + $lang = (int)$child['databaseRow']['sys_language_uid'] ?? 0; + //$child['defaultLanguageDiffRow'] = null; + + // hide translated elements from default language view + if ($parentLanguageUid === 0 && $lang > 0) { + continue; + } + + // hide original language children when they have a translated element + $childUid = (int)($child['databaseRow']['uid'] ?? 0); + if (in_array($childUid, $translationsExistFor, true)) { + continue; + } + + $filteredChildren[] = $child; + } + $children = array_values($filteredChildren); + + return $result; + } +} diff --git a/Classes/Hooks/DataHandler.php b/Classes/Hooks/DataHandler.php index a5743a9..f021eca 100644 --- a/Classes/Hooks/DataHandler.php +++ b/Classes/Hooks/DataHandler.php @@ -41,6 +41,46 @@ public function processDatamap_beforeStart(\TYPO3\CMS\Core\DataHandling\DataHand } } + /** + * @param array $incomingFieldArray + * @param string $table + * @param int|string $id + * @param \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler + * @return void + */ + public function processDatamap_preProcessFieldArray( + array &$incomingFieldArray, + string $table, + $id, + \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler + ): void { + // Only handle content elements + if ($table !== 'tt_content') { + return; + } + + // Only relevant if this is a translated record + $languageUid = (int)($incomingFieldArray['sys_language_uid'] ?? 0); + if ($languageUid <= 0) { + return; + } + + // If this record has a container parent, check if it's a localized one + $txContainerParent = (int)($incomingFieldArray['tx_container_parent'] ?? 0); + if ($txContainerParent > 0) { + // Fetch the parent record + $parentRecord = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('tt_content', $txContainerParent); + + // If parent exists and is a localized record, resolve its default language UID + if (!empty($parentRecord['l18n_parent'])) { + $defaultParentUid = (int)$parentRecord['l18n_parent']; + + // Rewrite to the default-language container + $incomingFieldArray['tx_container_parent'] = $defaultParentUid; + } + } + } + public function processCmdmap_preProcess($command, $table, $id, $value, $pObj, $pasteUpdate) { if (in_array($command, ['copy', 'localize']) && $table === 'tt_content') { diff --git a/ext_emconf.php b/ext_emconf.php index bf9902c..8e0e5de 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -16,7 +16,7 @@ 'author_company' => 'TEAM23', 'state' => 'beta', 'clearCacheOnLoad' => true, - 'version' => '0.0.13', + 'version' => '0.0.14', 'constraints' => [ 'depends' => [ 'typo3' => '11.0.0-12.9.99', diff --git a/ext_localconf.php b/ext_localconf.php index bc439a5..6e0ff66 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -9,7 +9,7 @@ * LICENSE.txt file that was distributed with this source code. */ -$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['tx-t23inlinecontainer'] = 'Team23\T23InlineContainer\Hooks\DataHandler'; +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['tx-t23inlinecontainer'] = 'Team23\T23InlineContainer\Hooks\DataHandler'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['tx-t23inlinecontainer'] = 'Team23\T23InlineContainer\Hooks\DataHandler'; $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord'][\Team23\T23InlineContainer\Backend\FormDataProvider\ContainerChildrenFormDataProvider::class] = [ @@ -19,4 +19,9 @@ 'before' => [ \TYPO3\CMS\Backend\Form\FormDataProvider\InlineOverrideChildTca::class, ] -]; \ No newline at end of file +]; +$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord'][\Team23\T23InlineContainer\Backend\FormDataProvider\ContainerChildrenLanguageCorrectionFormDataProvider::class] = [ + 'depends' => [ + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineData::class, + ], +]; From 57c7bff446bf068dadb79b3d6adab0543bc5c9de Mon Sep 17 00:00:00 2001 From: Sigala Mbigha Date: Fri, 3 Jan 2025 15:06:36 +0100 Subject: [PATCH 3/5] [FEAT] TYPO3 13 compatibility --- Classes/Hooks/DataHandler.php | 6 +-- Classes/Integrity/Sorting.php | 2 +- Classes/Listener/AddFieldToAllContainers.php | 2 +- Classes/Listener/ContentUsedOnPage.php | 47 ++++++++++++++++++++ Configuration/Services.yaml | 8 +++- Configuration/TCA/Overrides/tt_content.php | 1 - composer.json | 2 +- ext_emconf.php | 7 ++- 8 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 Classes/Listener/ContentUsedOnPage.php diff --git a/Classes/Hooks/DataHandler.php b/Classes/Hooks/DataHandler.php index f021eca..601689e 100644 --- a/Classes/Hooks/DataHandler.php +++ b/Classes/Hooks/DataHandler.php @@ -81,14 +81,14 @@ public function processDatamap_preProcessFieldArray( } } - public function processCmdmap_preProcess($command, $table, $id, $value, $pObj, $pasteUpdate) + public function processCmdmap_preProcess($command, $table, $id, $value, $pObj, $pasteUpdate): void { if (in_array($command, ['copy', 'localize']) && $table === 'tt_content') { $GLOBALS['TCA']['tt_content']['columns']['tx_t23inlinecontainer_elements']['config']['type'] = 'none'; } } - public function processCmdmap_postProcess($command, $table, $id, $value, $pObj, $pasteUpdate, $pasteDatamap) + public function processCmdmap_postProcess($command, $table, $id, $value, $pObj, $pasteUpdate, $pasteDatamap): void { if (in_array($command, ['copy', 'localize']) && $table === 'tt_content') { $GLOBALS['TCA']['tt_content']['columns']['tx_t23inlinecontainer_elements']['config']['type'] = 'tx_t23inlinecontainer_elements'; @@ -100,7 +100,7 @@ public function processCmdmap_postProcess($command, $table, $id, $value, $pObj, * @param \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler * @return void */ - public function processDatamap_afterAllOperations(\TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler) + public function processDatamap_afterAllOperations(\TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler): void { // Make sure that container sorting is only update once per container element // => Only run sorting update after all operations have been finished diff --git a/Classes/Integrity/Sorting.php b/Classes/Integrity/Sorting.php index 81dd37d..834a6d6 100644 --- a/Classes/Integrity/Sorting.php +++ b/Classes/Integrity/Sorting.php @@ -10,7 +10,7 @@ class Sorting extends \B13\Container\Integrity\Sorting { - public function runForSingleContainer($containerRecord, $cType) + public function runForSingleContainer($containerRecord, $cType): void { $columns = $this->tcaRegistry->getAvailableColumns($cType); $colPosByCType[$cType] = []; diff --git a/Classes/Listener/AddFieldToAllContainers.php b/Classes/Listener/AddFieldToAllContainers.php index 9cae455..df57948 100644 --- a/Classes/Listener/AddFieldToAllContainers.php +++ b/Classes/Listener/AddFieldToAllContainers.php @@ -16,7 +16,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; class AddFieldToAllContainers { - public function __invoke(AfterTcaCompilationEvent $event) + public function __invoke(AfterTcaCompilationEvent $event): void { $containerRegistry = GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class); diff --git a/Classes/Listener/ContentUsedOnPage.php b/Classes/Listener/ContentUsedOnPage.php new file mode 100644 index 0000000..1ec06ba --- /dev/null +++ b/Classes/Listener/ContentUsedOnPage.php @@ -0,0 +1,47 @@ +containerFactory = $containerFactory; + $this->tcaRegistry = $tcaRegistry; + } + + public function __invoke(IsContentUsedOnPageLayoutEvent $event): void + { + $record = $event->getRecord(); + if ($record['tx_container_parent'] > 0) { + try { + $container = $this->containerFactory->buildContainer((int)$record['tx_container_parent']); + $columns = $this->tcaRegistry->getAvailableColumns($container->getCType()); + foreach ($columns as $column) { + if ($column['colPos'] === (int)$record['colPos']) { + if ($record['sys_language_uid'] > 0 && $container->isConnectedMode()) { + $used = ($container->hasChildInColPos((int)$record['colPos'], (int)$record['l18n_parent']) + || $container->hasChildInColPos((int)$record['colPos'], (int)$record['uid'])); + $event->setUsed($used); + return; + } + $used = $container->hasChildInColPos((int)$record['colPos'], (int)$record['uid']); + $event->setUsed($used); + return; + } + } + } catch (Exception $e) { + } + } + } +} \ No newline at end of file diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 1e6f076..a364d62 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -15,4 +15,10 @@ services: tags: - name: event.listener identifier: 'addFieldToAllContainers' - event: TYPO3\CMS\Core\Configuration\Event\AfterTcaCompilationEvent \ No newline at end of file + event: TYPO3\CMS\Core\Configuration\Event\AfterTcaCompilationEvent + + Team23\T23InlineContainer\Listener\ContentUsedOnPage: + tags: + - name: event.listener + identifier: 't23-inline-container-content-used-on-page' + after: 'tx-container-content-used-on-page' \ No newline at end of file diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 81534d0..c2d180d 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -27,7 +27,6 @@ 'levelLinksPosition' => 'bottom', 'useSortable' => true, 'showPossibleLocalizationRecords' => true, - 'showRemovedLocalizationRecords' => true, 'showAllLocalizationLink' => true, 'showSynchronizationLink' => true, 'enabledControls' => [ diff --git a/composer.json b/composer.json index 81eeecd..26bad25 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "https://www.team23.de/", "license": "GPL-2.0-or-later", "require": { - "typo3/cms-core": "^11.5 || ^12.4", + "typo3/cms-core": "^11.5 || ^12.4 || ^13.4", "b13/container": "^2.3 || ^3.1" }, "suggest": { diff --git a/ext_emconf.php b/ext_emconf.php index 8e0e5de..9fc63d0 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -15,17 +15,16 @@ 'author_email' => 'dreier@team23.de', 'author_company' => 'TEAM23', 'state' => 'beta', - 'clearCacheOnLoad' => true, - 'version' => '0.0.14', + 'version' => '0.0.15', 'constraints' => [ 'depends' => [ - 'typo3' => '11.0.0-12.9.99', + 'typo3' => '12.4.0-13.4.99', 'container' => '2.3.1-3.9.99', ], 'conflicts' => [ ], 'suggests' => [ - 'news' => '9.0.0-10.9.9' + 'news' => '9.0.0-12.9.9' ], ], ]; From defa2621bdffe9d052137b7f7573019ed5ee6bc1 Mon Sep 17 00:00:00 2001 From: Sigala Mbigha Date: Fri, 3 Jan 2025 15:18:00 +0100 Subject: [PATCH 4/5] [FEAT] TYPO3 13 compatibility --- Classes/Listener/ContentUsedOnPage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Classes/Listener/ContentUsedOnPage.php b/Classes/Listener/ContentUsedOnPage.php index 1ec06ba..91715cb 100644 --- a/Classes/Listener/ContentUsedOnPage.php +++ b/Classes/Listener/ContentUsedOnPage.php @@ -30,6 +30,11 @@ public function __invoke(IsContentUsedOnPageLayoutEvent $event): void foreach ($columns as $column) { if ($column['colPos'] === (int)$record['colPos']) { if ($record['sys_language_uid'] > 0 && $container->isConnectedMode()) { + + /* + Prevents displaying of "Unused elements detected on this page" in the Page module in Backend when + container element is translated in "Connected Mode" + */ $used = ($container->hasChildInColPos((int)$record['colPos'], (int)$record['l18n_parent']) || $container->hasChildInColPos((int)$record['colPos'], (int)$record['uid'])); $event->setUsed($used); From 372ea45985fca2ea20ed588e72304750c1bfca15 Mon Sep 17 00:00:00 2001 From: "timo.klinge" Date: Tue, 4 Nov 2025 11:10:41 +0100 Subject: [PATCH 5/5] [FEAT] TYPO3 13 compatibility - adjust Readme.md --- Readme.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index c3a7913..63171b4 100644 --- a/Readme.md +++ b/Readme.md @@ -24,9 +24,29 @@ Adds a field "Content elements" to all container to make contained elements edit There is no configuration needed, just install with `composer req team23/t23-inline-container`. The field will be added automatically to every registered container. +### Hint: Consistent use of maxitems in container column definitions +When defining container columns in your TCA, make sure you handle the maxitems setting consistently across all columns: +either define maxitems for every column, or omit it for all columns. + +Inconsistent usage (e.g., setting maxitems on only some columns) can lead to unexpected behavior when TYPO3 or the container extension calculates overall limits. + +For Example: +````php +[ + ['name' => 'left side', 'colPos' => 201, 'maxitems' => 2], + ['name' => 'right side', 'colPos' => 202, 'maxitems' => 2] +] +# or +[ + ['name' => 'left side', 'colPos' => 201], + ['name' => 'right side', 'colPos' => 202] +] +```` + ## Compatibility | `t23_inline_container` | TYPO3 | |------------------------|-------| -| 0.x | 11 | -| 0.x | 12 | \ No newline at end of file +| \>= 0.0.1 | 11 | +| \>= 0.0.10 | 12 | +| \>= 0.0.15 | 13 |