diff --git a/Classes/Form/FormDataProvider/TcaCTypeItems.php b/Classes/Form/FormDataProvider/TcaCTypeItems.php index 63d20d9..cf15d9f 100644 --- a/Classes/Form/FormDataProvider/TcaCTypeItems.php +++ b/Classes/Form/FormDataProvider/TcaCTypeItems.php @@ -19,6 +19,7 @@ use IchHabRecht\ContentDefender\BackendLayout\BackendLayoutConfiguration; use TYPO3\CMS\Backend\Form\FormDataProviderInterface; +use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; class TcaCTypeItems implements FormDataProviderInterface @@ -50,26 +51,70 @@ public function addData(array $result) $allowedConfiguration = array_intersect_key($columnConfiguration['allowed.'] ?? [], $result['processedTca']['columns']); foreach ($allowedConfiguration as $field => $value) { + $currentRecordValue = is_array($result['databaseRow'][$field]) ? $result['databaseRow'][$field][0] : $result['databaseRow'][$field]; $allowedValues = GeneralUtility::trimExplode(',', $value); - $result['processedTca']['columns'][$field]['config']['items'] = array_filter( + $result['processedTca']['columns'][$field]['config']['items'] = $this->filterAllowedItems( $result['processedTca']['columns'][$field]['config']['items'], - function ($item) use ($allowedValues) { - return in_array($item['value'] ?? $item[1], $allowedValues); - } + $allowedValues, + false, + $currentRecordValue ); } $disallowedConfiguration = array_intersect_key($columnConfiguration['disallowed.'] ?? [], $result['processedTca']['columns']); foreach ($disallowedConfiguration as $field => $value) { + $currentRecordValue = is_array($result['databaseRow'][$field]) ? $result['databaseRow'][$field][0] : $result['databaseRow'][$field]; $disallowedValues = GeneralUtility::trimExplode(',', $value); - $result['processedTca']['columns'][$field]['config']['items'] = array_filter( + $result['processedTca']['columns'][$field]['config']['items'] = $this->filterAllowedItems( $result['processedTca']['columns'][$field]['config']['items'], - function ($item) use ($disallowedValues) { - return !in_array($item['value'] ?? $item[1], $disallowedValues); - } + $disallowedValues, + true, + $currentRecordValue ); } return $result; } + + /** + * Remove items not in filter list, unless it matches the current record value, then label it as 'invalid value' + * Remove items in filter list if $disallow=true + * + * @param $items + * @param $filterItems + * @param $disallow + * @param $currentRecordValue + * @return array + */ + protected function filterAllowedItems($items, $filterItems, $disallow, $currentRecordValue) + { + foreach ($items as $key => $item) { + // Associative array since TYPO3 v12.3 + $value = $item['value'] ?? $item[1]; + if ($disallow ? in_array($value, $filterItems) : !in_array($value, $filterItems)) { + if ($value !== $currentRecordValue) { + unset($items[$key]); + } else { + if (array_key_exists('label', $item)) { + $items[$key]['label'] = sprintf( + $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), + $item['label'] + ); + } else { + $items[$key][0] = sprintf( + $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), + $item[0] + ); + } + } + } + } + + return $items; + } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } } diff --git a/Classes/Form/FormDataProvider/TcaColPosItems.php b/Classes/Form/FormDataProvider/TcaColPosItems.php index ab527e1..6e3995d 100644 --- a/Classes/Form/FormDataProvider/TcaColPosItems.php +++ b/Classes/Form/FormDataProvider/TcaColPosItems.php @@ -21,6 +21,7 @@ use IchHabRecht\ContentDefender\Form\Exception\AccessDeniedColPosException; use IchHabRecht\ContentDefender\Repository\ContentRepository; use TYPO3\CMS\Backend\Form\FormDataProviderInterface; +use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; class TcaColPosItems implements FormDataProviderInterface @@ -57,6 +58,7 @@ public function addData(array $result) $record = $result['databaseRow']; $record['pid'] = $pageId; + $originalRecordColPos = $record['colPos'][0]; foreach ($result['processedTca']['columns']['colPos']['config']['items'] as $key => $item) { $colPos = (int)($item['value'] ?? $item[1]); @@ -75,7 +77,11 @@ public function addData(array $result) $allowedValues = GeneralUtility::trimExplode(',', $value); if ($this->fieldContainsDisallowedValues($record[$field], $allowedValues)) { - unset($result['processedTca']['columns']['colPos']['config']['items'][$key]); + $result['processedTca']['columns']['colPos']['config']['items'] = $this->unsetIfNotCurrent( + $result['processedTca']['columns']['colPos']['config']['items'], + $key, + $originalRecordColPos + ); } } @@ -87,7 +93,11 @@ public function addData(array $result) $disallowedValues = GeneralUtility::trimExplode(',', $value); if ($this->fieldContainsDisallowedValues($record[$field], $disallowedValues, false)) { - unset($result['processedTca']['columns']['colPos']['config']['items'][$key]); + $result['processedTca']['columns']['colPos']['config']['items'] = $this->unsetIfNotCurrent( + $result['processedTca']['columns']['colPos']['config']['items'], + $key, + $originalRecordColPos + ); } } @@ -101,7 +111,11 @@ public function addData(array $result) 1494605357 ); } elseif (!$isCurrentColPos) { - unset($result['processedTca']['columns']['colPos']['config']['items'][$key]); + $result['processedTca']['columns']['colPos']['config']['items'] = $this->unsetIfNotCurrent( + $result['processedTca']['columns']['colPos']['config']['items'], + $key, + $originalRecordColPos + ); } } } @@ -127,4 +141,38 @@ protected function fieldContainsDisallowedValues($fieldValue, array $values, $al return false; } + + /** + * Unset array item $items[$key] if colPos doesn't match current records colPos, otherwise add 'invalid' label + * + * @param $items + * @param $key + * @param $recordColPos + * @return array + */ + protected function unsetIfNotCurrent($items, $key, $recordColPos) + { + if (array_key_exists($key, $items)) { + if (array_key_exists('value', $items[$key]) && $recordColPos === $items[$key]['value']) { + $items[$key]['label'] = sprintf( + $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), + $items[$key]['label'] + ); + } elseif (array_key_exists(1, $items[$key]) && $recordColPos === $items[$key][1]) { + $items[$key][0] = sprintf( + $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), + $items[$key][0] + ); + } else { + unset($items[$key]); + } + } + + return $items; + } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } }