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..601689e 100644 --- a/Classes/Hooks/DataHandler.php +++ b/Classes/Hooks/DataHandler.php @@ -41,14 +41,54 @@ public function processDatamap_beforeStart(\TYPO3\CMS\Core\DataHandling\DataHand } } - public function processCmdmap_preProcess($command, $table, $id, $value, $pObj, $pasteUpdate) + /** + * @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): 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'; @@ -60,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..91715cb --- /dev/null +++ b/Classes/Listener/ContentUsedOnPage.php @@ -0,0 +1,52 @@ +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()) { + + /* + 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); + 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/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 | diff --git a/composer.json b/composer.json index cc478d1..26bad25 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,8 @@ "homepage": "https://www.team23.de/", "license": "GPL-2.0-or-later", "require": { - "typo3/cms-core": "^11.5 || ^12.4", - "b13/container": "^2.3.1" + "typo3/cms-core": "^11.5 || ^12.4 || ^13.4", + "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..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.13', + 'version' => '0.0.15', 'constraints' => [ 'depends' => [ - 'typo3' => '11.0.0-12.9.99', - 'container' => '2.3.1-2.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' ], ], ]; 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, + ], +];