17 use Doctrine\DBAL\DBALException;
56 $table = $result[
'tableName'];
57 $config = $result[
'processedTca'][
'columns'][$fieldName][
'config'];
59 $pageTsProcessorParameters =
null;
60 if (!empty($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'itemsProcFunc.'])) {
61 $pageTsProcessorParameters = $result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'itemsProcFunc.'];
63 $processorParameters = [
67 'TSconfig' => $pageTsProcessorParameters,
69 'row' => $result[
'databaseRow'],
70 'field' => $fieldName,
72 if (!empty($result[
'flexParentDatabaseRow'])) {
73 $processorParameters[
'flexParentDatabaseRow'] = $result[
'flexParentDatabaseRow'];
77 GeneralUtility::callUserFunction($config[
'itemsProcFunc'], $processorParameters, $this);
81 $fieldLabel = $fieldName;
82 if (!empty($result[
'processedTca'][
'columns'][$fieldName][
'label'])) {
83 $fieldLabel = $languageService->sL($result[
'processedTca'][
'columns'][$fieldName][
'label']);
86 $languageService->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.items_proc_func_error'),
88 $exception->getMessage()
91 $flashMessage = GeneralUtility::makeInstance(
99 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
100 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
101 $defaultFlashMessageQueue->enqueue($flashMessage);
122 $table = $result[
'tableName'];
123 if (!empty($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'addItems.'])
124 && is_array($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'addItems.'])
126 $addItemsArray = $result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'addItems.'];
127 foreach ($addItemsArray as $value => $label) {
129 if (substr($value, -1) ===
'.') {
133 $iconIdentifier =
null;
134 if (isset($addItemsArray[$value .
'.'])
135 && is_array($addItemsArray[$value .
'.'])
136 && !empty($addItemsArray[$value .
'.'][
'icon'])
138 $iconIdentifier = $addItemsArray[$value .
'.'][
'icon'];
140 $items[] = [$label, $value, $iconIdentifier];
160 if (empty($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'special'])
161 || !is_string($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'special'])
167 $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
168 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
170 $special = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'special'];
172 case $special ===
'tables':
173 foreach (
$GLOBALS[
'TCA'] as $currentTable => $_) {
174 if (!empty(
$GLOBALS[
'TCA'][$currentTable][
'ctrl'][
'adminOnly'])) {
178 $label = !empty(
$GLOBALS[
'TCA'][$currentTable][
'ctrl'][
'title']) ?
$GLOBALS[
'TCA'][$currentTable][
'ctrl'][
'title'] :
'';
179 $icon = $iconFactory->mapRecordTypeToIconIdentifier($currentTable, []);
181 $languageService->loadSingleTableDescription($currentTable);
183 $helpTextArray =
$GLOBALS[
'TCA_DESCR'][$currentTable][
'columns'][
''];
184 if (!empty($helpTextArray[
'description'])) {
185 $helpText[
'description'] = $helpTextArray[
'description'];
187 $items[] = [$label, $currentTable, $icon, $helpText];
190 case $special ===
'pagetypes':
191 if (isset(
$GLOBALS[
'TCA'][
'pages'][
'columns'][
'doktype'][
'config'][
'items'])
192 && is_array(
$GLOBALS[
'TCA'][
'pages'][
'columns'][
'doktype'][
'config'][
'items'])
194 $specialItems =
$GLOBALS[
'TCA'][
'pages'][
'columns'][
'doktype'][
'config'][
'items'];
195 foreach ($specialItems as $specialItem) {
196 if (!is_array($specialItem) || $specialItem[1] ===
'--div--') {
200 $label = $specialItem[0];
201 $value = $specialItem[1];
202 $icon = $iconFactory->mapRecordTypeToIconIdentifier(
'pages', [
'doktype' => $specialItem[1]]);
203 $items[] = [$label, $value, $icon];
207 case $special ===
'exclude':
209 foreach ($excludeArrays as $excludeArray) {
211 if ($excludeArray[
'origin'] ===
'flexForm') {
214 if (!isset($items[$excludeArray[
'sectionHeader']])) {
216 $icon = $iconFactory->mapRecordTypeToIconIdentifier($excludeArray[
'table'], []);
217 $items[$excludeArray[
'sectionHeader']] = [
218 $excludeArray[
'sectionHeader'],
225 if (!isset($items[$excludeArray[
'table']])) {
226 $icon = $iconFactory->mapRecordTypeToIconIdentifier($excludeArray[
'table'], []);
227 $items[$excludeArray[
'table']] = [
228 $GLOBALS[
'TCA'][$excludeArray[
'table']][
'ctrl'][
'title'],
236 $languageService->loadSingleTableDescription($excludeArray[
'table']);
237 $helpTextArray =
$GLOBALS[
'TCA_DESCR'][$excludeArray[
'table']][
'columns'][$excludeArray[
'table']] ?? [];
238 if (!empty($helpTextArray[
'description'])) {
239 $helpText[
'description'] = $helpTextArray[
'description'];
243 rtrim($excludeArray[
'origin'] ===
'flexForm' ? $excludeArray[
'fieldLabel'] : $languageService->sL(
$GLOBALS[
'TCA'][$excludeArray[
'table']][
'columns'][$excludeArray[
'fieldName']][
'label']),
':') .
' (' . $excludeArray[
'fieldName'] .
')',
244 $excludeArray[
'table'] .
':' . $excludeArray[
'fullField'],
250 case $special ===
'explicitValues':
253 'ALLOW' =>
'status-status-permission-granted',
254 'DENY' =>
'status-status-permission-denied'
257 foreach ($theTypes as $tableFieldKey => $theTypeArrays) {
258 if (!empty($theTypeArrays[
'items'])) {
261 $theTypeArrays[
'tableFieldLabel'],
265 foreach ($theTypeArrays[
'items'] as $itemValue => $itemContent) {
268 '[' . $itemContent[2] .
'] ' . $itemContent[1],
269 $tableFieldKey .
':' . preg_replace(
'/[:|,]/',
'', $itemValue) .
':' . $itemContent[0],
276 case $special ===
'languages':
277 foreach ($result[
'systemLanguageRows'] as $language) {
278 if ($language[
'uid'] !== -1) {
280 0 => $language[
'title'],
281 1 => $language[
'uid'],
282 2 => $language[
'flagIconIdentifier']
287 case $special ===
'custom':
288 $customOptions =
$GLOBALS[
'TYPO3_CONF_VARS'][
'BE'][
'customPermOptions'];
289 if (is_array($customOptions)) {
290 foreach ($customOptions as $coKey => $coValue) {
291 if (is_array($coValue[
'items'])) {
294 $languageService->sL($coValue[
'header']),
298 foreach ($coValue[
'items'] as $itemKey => $itemCfg) {
299 $icon =
'empty-empty';
301 if (!empty($itemCfg[1])) {
307 if (!empty($itemCfg[2])) {
308 $helpText[
'description'] = $languageService->sL($itemCfg[2]);
311 $languageService->sL($itemCfg[0]),
312 $coKey .
':' . preg_replace(
'/[:|,]/',
'', $itemKey),
321 case $special ===
'modListGroup' || $special ===
'modListUser':
323 $loadModules = GeneralUtility::makeInstance(ModuleLoader::class);
324 $loadModules->load(
$GLOBALS[
'TBE_MODULES']);
325 $modList = $special ===
'modListUser' ? $loadModules->modListUser : $loadModules->modListGroup;
326 if (is_array($modList)) {
327 foreach ($modList as $theMod) {
328 $moduleLabels = $loadModules->getLabelsForModule($theMod);
329 $moduleArray = GeneralUtility::trimExplode(
'_', $theMod,
true);
330 $mainModule = $moduleArray[0] ??
'';
331 $subModule = $moduleArray[1] ??
'';
333 if (!empty($subModule)) {
334 $icon = $loadModules->modules[$mainModule][
'sub'][$subModule][
'iconIdentifier'];
336 $icon = $loadModules->modules[$theMod][
'iconIdentifier'];
340 'title' => $languageService->sL($moduleLabels[
'shortdescription']),
341 'description' => $languageService->sL($moduleLabels[
'description'])
346 if (!empty($subModule)) {
347 $mainModuleLabels = $loadModules->getLabelsForModule($mainModule);
348 $label .= $languageService->sL($mainModuleLabels[
'title']) .
'>';
351 $label .= $languageService->sL($moduleLabels[
'title']);
354 $items[] = [$label, $theMod, $icon, $helpText];
359 throw new \UnexpectedValueException(
360 'Unknown special value ' . $special .
' for field ' . $fieldName .
' of table ' . $result[
'tableName'],
380 if (empty($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder'])
381 || !is_string($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder'])
386 $fileFolderRaw = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder'];
387 $fileFolder = GeneralUtility::getFileAbsFileName($fileFolderRaw);
388 if ($fileFolder ===
'') {
389 throw new \RuntimeException(
390 'Invalid folder given for item processing: ' . $fileFolderRaw .
' for table ' . $result[
'tableName'] .
', field ' . $fieldName,
394 $fileFolder = rtrim($fileFolder,
'/') .
'/';
396 if (@is_dir($fileFolder)) {
397 $fileExtensionList =
'';
398 if (!empty($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder_extList'])
399 && is_string($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder_extList'])
401 $fileExtensionList = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder_extList'];
403 $recursionLevels = isset($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'fileFolder_recursions'])
406 $fileArray = GeneralUtility::getAllFilesAndFoldersInPath([], $fileFolder, $fileExtensionList, 0, $recursionLevels);
407 $fileArray = GeneralUtility::removePrefixPathFromList($fileArray, $fileFolder);
408 foreach ($fileArray as $fileReference) {
409 $fileInformation = pathinfo($fileReference);
410 $icon = GeneralUtility::inList(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'imagefile_ext'], strtolower($fileInformation[
'extension']))
411 ? $fileFolder . $fileReference
438 if (empty($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table'])
439 || !is_string($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table'])
446 $foreignTable = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table'];
448 if (!isset(
$GLOBALS[
'TCA'][$foreignTable]) || !is_array(
$GLOBALS[
'TCA'][$foreignTable])) {
449 throw new \UnexpectedValueException(
450 'Field ' . $fieldName .
' of table ' . $result[
'tableName'] .
' reference to foreign table '
451 . $foreignTable .
', but this table is not defined in TCA',
458 $queryResult = $queryBuilder->execute();
459 }
catch (DBALException $e) {
460 $databaseError = $e->getPrevious()->getMessage();
464 if (!empty($databaseError)) {
465 $msg = $databaseError .
'. ';
466 $msg .= $languageService->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.database_schema_mismatch');
467 $msgTitle = $languageService->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.database_schema_mismatch_title');
469 $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $msg, $msgTitle,
FlashMessage::ERROR,
true);
471 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
473 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
474 $defaultFlashMessageQueue->enqueue($flashMessage);
479 if (!empty($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table_prefix'])) {
480 $labelPrefix = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table_prefix'];
481 $labelPrefix = $languageService->sL($labelPrefix);
484 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
485 $fileRepository = GeneralUtility::makeInstance(FileRepository::class);
487 while ($foreignRow = $queryResult->fetch()) {
489 if (is_array($foreignRow)) {
493 $isReferenceField =
false;
494 if (!empty(
$GLOBALS[
'TCA'][$foreignTable][
'ctrl'][
'selicon_field'])) {
495 $iconFieldName =
$GLOBALS[
'TCA'][$foreignTable][
'ctrl'][
'selicon_field'];
496 if (isset(
$GLOBALS[
'TCA'][$foreignTable][
'columns'][$iconFieldName][
'config'][
'type'])
497 &&
$GLOBALS[
'TCA'][$foreignTable][
'columns'][$iconFieldName][
'config'][
'type'] ===
'inline'
498 &&
$GLOBALS[
'TCA'][$foreignTable][
'columns'][$iconFieldName][
'config'][
'foreign_table'] ===
'sys_file_reference'
500 $isReferenceField =
true;
504 if ($isReferenceField) {
505 $references = $fileRepository->findByRelation($foreignTable, $iconFieldName, $foreignRow[
'uid']);
506 if (is_array($references) && !empty($references)) {
507 $icon = reset($references);
508 $icon = $icon->getPublicUrl();
512 if (!empty(
$GLOBALS[
'TCA'][$foreignTable][
'ctrl'][
'selicon_field_path'])) {
513 $iconPath =
$GLOBALS[
'TCA'][$foreignTable][
'ctrl'][
'selicon_field_path'];
515 if ($iconFieldName && $iconPath && $foreignRow[$iconFieldName]) {
517 $iParts = GeneralUtility::trimExplode(
',', $foreignRow[$iconFieldName],
true);
518 $icon = $iconPath .
'/' . trim($iParts[0]);
521 $icon = $iconFactory->mapRecordTypeToIconIdentifier($foreignTable, $foreignRow);
548 $table = $result[
'tableName'];
549 if (!isset($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'keepItems'])
550 || !is_string($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'keepItems'])
556 if ($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'keepItems'] ===
'') {
562 $result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'keepItems'],
581 $table = $result[
'tableName'];
582 if (!isset($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'removeItems'])
583 || !is_string($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'removeItems'])
584 || $result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'removeItems'] ===
''
589 $removeItems = array_flip(GeneralUtility::trimExplode(
591 $result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'removeItems'],
594 foreach ($items as $key => $itemValues) {
595 if (isset($removeItems[$itemValues[1]])) {
616 if (empty($result[
'processedTca'][
'ctrl'][
'languageField'])
617 || $result[
'processedTca'][
'ctrl'][
'languageField'] !== $fieldName
623 foreach ($items as $key => $itemValues) {
624 if (!$backendUser->checkLanguageAccess($itemValues[1])) {
645 if (!isset($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'authMode'])
646 || !is_string($result[
'processedTca'][
'columns'][$fieldName][
'config'][
'authMode'])
652 $authMode = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'authMode'];
653 foreach ($items as $key => $itemValues) {
655 if (!$backendUser->checkAuthMode($result[
'tableName'], $fieldName, $itemValues[1], $authMode)) {
675 $table = $result[
'tableName'];
678 if ($table !==
'pages' || $fieldName !==
'doktype' || $backendUser->isAdmin()
683 $allowedPageTypes = $backendUser->groupData[
'pagetypes_select'];
684 foreach ($items as $key => $itemValues) {
685 if (!GeneralUtility::inList($allowedPageTypes, $itemValues[1])) {
705 $referencedTableName = $result[
'processedTca'][
'columns'][$fieldName][
'config'][
'foreign_table'] ??
null;
706 if ($referencedTableName !==
'sys_file_storage') {
710 $allowedStorageIds = array_map(
711 function (\
TYPO3\CMS\Core\Resource\ResourceStorage $storage) {
712 return $storage->getUid();
719 function (array $item) use ($allowedStorageIds) {
720 $itemValue = $item[1] ??
null;
721 return empty($itemValue)
722 || in_array((
int)$itemValue, $allowedStorageIds,
true);
737 $finalExcludeArray = [];
740 $tableToTranslation = [];
742 foreach (
$GLOBALS[
'TCA'] as $table => $conf) {
743 $tableToTranslation[$table] = $languageService->sL($conf[
'ctrl'][
'title']);
746 asort($tableToTranslation);
747 foreach ($tableToTranslation as $table => $translatedTable) {
748 $excludeArrayTable = [];
751 if (is_array(
$GLOBALS[
'TCA'][$table][
'columns'])
752 && empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'adminOnly'])
753 && (empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'rootLevel']) || !empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'security'][
'ignoreRootLevelRestriction']))
755 foreach (
$GLOBALS[
'TCA'][$table][
'columns'] as $field => $_) {
756 if (isset(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'exclude']) && (
bool)
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'exclude']) {
758 $translatedField = $languageService->sL(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'label']);
760 $excludeArrayTable[] = [
761 'labels' => $translatedTable .
':' . $translatedField,
762 'sectionHeader' => $translatedTable,
764 'tableField' => $field,
765 'fieldName' => $field,
766 'fullField' => $field,
767 'fieldLabel' => $translatedField,
775 foreach ($flexFormArray as $tableField => $flexForms) {
778 if (!empty(
$GLOBALS[
'TCA'][$table][
'columns'][$tableField][
'label'])) {
779 $labelPrefix = $languageService->sL(
$GLOBALS[
'TCA'][$table][
'columns'][$tableField][
'label']);
782 foreach ($flexForms as $extIdent =>
$extConf) {
784 foreach (
$extConf[
'sheets'] as $sheetName => $sheet) {
785 if (empty($sheet[
'ROOT'][
'el']) || !is_array($sheet[
'ROOT'][
'el'])) {
788 foreach ($sheet[
'ROOT'][
'el'] as $pluginFieldName => $field) {
790 if (empty($field[
'TCEforms'][
'exclude'])) {
793 $fieldLabel = !empty($field[
'TCEforms'][
'label'])
794 ? $languageService->sL($field[
'TCEforms'][
'label'])
796 $excludeArrayTable[] = [
797 'labels' => trim($translatedTable .
' ' . $labelPrefix .
' ' . $extIdent,
': ') .
':' . $fieldLabel,
798 'sectionHeader' => trim($translatedTable .
' ' . $labelPrefix .
' ' . $extIdent,
':'),
800 'tableField' => $tableField,
801 'extIdent' => $extIdent,
802 'fieldName' => $pluginFieldName,
803 'fullField' => $tableField .
';' . $extIdent .
';' . $sheetName .
';' . $pluginFieldName,
804 'fieldLabel' => $fieldLabel,
805 'origin' =>
'flexForm',
812 if (!empty($excludeArrayTable)) {
813 usort($excludeArrayTable,
function (array $array1, array $array2) {
814 $array1 = reset($array1);
815 $array2 = reset($array2);
816 if (is_string($array1) && is_string($array2)) {
817 return strcasecmp($array1, $array2);
821 $finalExcludeArray = array_merge($finalExcludeArray, $excludeArrayTable);
825 return $finalExcludeArray;
848 if (empty($table) || empty(
$GLOBALS[
'TCA'][$table][
'columns'])) {
851 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
853 foreach (
$GLOBALS[
'TCA'][$table][
'columns'] as $tableField => $fieldConf) {
854 if (!empty($fieldConf[
'config'][
'type']) && !empty($fieldConf[
'config'][
'ds']) && $fieldConf[
'config'][
'type'] ===
'flex') {
855 $flexForms[$tableField] = [];
856 foreach (array_keys($fieldConf[
'config'][
'ds']) as $flexFormKey) {
858 $identFields = GeneralUtility::trimExplode(
',', $flexFormKey);
859 $extIdent = $identFields[0];
860 if (!empty($identFields[1]) && $identFields[1] !==
'list' && $identFields[1] !==
'*') {
861 $extIdent = $identFields[1];
863 $flexFormDataStructureIdentifier = json_encode([
865 'tableName' => $table,
866 'fieldName' => $tableField,
867 'dataStructureKey' => $flexFormKey,
870 $dataStructure = $flexFormTools->parseDataStructureByIdentifier($flexFormDataStructureIdentifier);
871 $flexForms[$tableField][$extIdent] = $dataStructure;
891 $languageService = static::getLanguageService();
893 'ALLOW' => $languageService->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.allow'),
894 'DENY' => $languageService->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.deny')
896 $allowDenyOptions = [];
897 foreach (
$GLOBALS[
'TCA'] as $table => $_) {
899 if (is_array(
$GLOBALS[
'TCA'][$table][
'columns'])) {
900 foreach (
$GLOBALS[
'TCA'][$table][
'columns'] as $field => $__) {
901 $fieldConfig =
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'];
902 if ($fieldConfig[
'type'] ===
'select' && $fieldConfig[
'authMode']) {
904 if (is_array($fieldConfig[
'items'])) {
906 $allowDenyOptions[$table .
':' . $field][
'tableFieldLabel'] =
907 $languageService->sL(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'title']) .
': '
908 . $languageService->sL(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'label']);
909 foreach ($fieldConfig[
'items'] as $iVal) {
910 $itemIdentifier = (string)$iVal[1];
912 if ($itemIdentifier ===
'' || $itemIdentifier ===
'--div--') {
917 switch ((
string)$fieldConfig[
'authMode']) {
918 case 'explicitAllow':
925 if (isset($iVal[4]) && $iVal[4] ===
'EXPL_ALLOW') {
927 } elseif (isset($iVal[4]) && $iVal[4] ===
'EXPL_DENY') {
934 $allowDenyOptions[$table .
':' . $field][
'items'][$itemIdentifier] = [
936 $languageService->sL($iVal[0]),
946 return $allowDenyOptions;
961 $foreignTableName = $result[
'processedTca'][
'columns'][$localFieldName][
'config'][
'foreign_table'];
966 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
967 ->getQueryBuilderForTable($foreignTableName);
969 $queryBuilder->getRestrictions()
971 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
974 ->select(...GeneralUtility::trimExplode(
',', $fieldList,
true))
975 ->from($foreignTableName)
976 ->where($foreignTableClauseArray[
'WHERE']);
978 if (!empty($foreignTableClauseArray[
'GROUPBY'])) {
979 $queryBuilder->groupBy(...$foreignTableClauseArray[
'GROUPBY']);
982 if (!empty($foreignTableClauseArray[
'ORDERBY'])) {
983 foreach ($foreignTableClauseArray[
'ORDERBY'] as $orderPair) {
984 list($fieldName, $order) = $orderPair;
985 $queryBuilder->addOrderBy($fieldName, $order);
987 } elseif (!empty(
$GLOBALS[
'TCA'][$foreignTableName][
'ctrl'][
'default_sortby'])) {
989 foreach ($orderByClauses as $orderByClause) {
990 if (!empty($orderByClause[0])) {
991 $queryBuilder->addOrderBy($foreignTableName .
'.' . $orderByClause[0], $orderByClause[1]);
996 if (!empty($foreignTableClauseArray[
'LIMIT'])) {
997 if (!empty($foreignTableClauseArray[
'LIMIT'][1])) {
998 $queryBuilder->setMaxResults($foreignTableClauseArray[
'LIMIT'][1]);
999 $queryBuilder->setFirstResult($foreignTableClauseArray[
'LIMIT'][0]);
1000 } elseif (!empty($foreignTableClauseArray[
'LIMIT'][0])) {
1001 $queryBuilder->setMaxResults($foreignTableClauseArray[
'LIMIT'][0]);
1009 if (isset(
$GLOBALS[
'TCA'][$foreignTableName][
'ctrl'][
'rootLevel'])) {
1010 $rootLevel = (int)
$GLOBALS[
'TCA'][$foreignTableName][
'ctrl'][
'rootLevel'];
1013 if ($rootLevel === -1) {
1014 $queryBuilder->andWhere(
1015 $queryBuilder->expr()->neq(
1016 $foreignTableName .
'.pid',
1017 $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
1020 } elseif ($rootLevel === 1) {
1021 $queryBuilder->andWhere(
1022 $queryBuilder->expr()->eq(
1023 $foreignTableName .
'.pid',
1024 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
1029 if ($foreignTableName !==
'pages') {
1033 $queryBuilder->expr()->eq(
1035 $queryBuilder->quoteIdentifier($foreignTableName .
'.pid')
1041 return $queryBuilder;
1062 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($foreignTableName);
1063 $localTable = $result[
'tableName'];
1064 $effectivePid = $result[
'effectivePid'];
1066 $foreignTableClause =
'';
1067 if (!empty($result[
'processedTca'][
'columns'][$localFieldName][
'config'][
'foreign_table_where'])
1068 && is_string($result[
'processedTca'][
'columns'][$localFieldName][
'config'][
'foreign_table_where'])
1070 $foreignTableClause = $result[
'processedTca'][
'columns'][$localFieldName][
'config'][
'foreign_table_where'];
1072 if (strstr($foreignTableClause,
'###REC_FIELD_')) {
1074 $whereClauseParts = explode(
'###REC_FIELD_', $foreignTableClause);
1075 foreach ($whereClauseParts as $key => $value) {
1078 $whereClauseSubParts = explode(
'###', $value, 2);
1080 $databaseRowKey = empty($result[
'flexParentDatabaseRow']) ?
'databaseRow' :
'flexParentDatabaseRow';
1081 $rowFieldValue = $result[$databaseRowKey][$whereClauseSubParts[0]] ??
'';
1082 if (is_array($rowFieldValue)) {
1087 $rowFieldValue = $rowFieldValue[0][
'uid'] ?? $rowFieldValue[0];
1089 if (substr($whereClauseParts[0], -1) ===
'\'' && $whereClauseSubParts[1][0] ===
'\'') {
1090 $whereClauseParts[0] = substr($whereClauseParts[0], 0, -1);
1091 $whereClauseSubParts[1] = substr($whereClauseSubParts[1], 1);
1093 $whereClauseParts[$key] = $connection->quote($rowFieldValue) . $whereClauseSubParts[1];
1096 $foreignTableClause = implode(
'', $whereClauseParts);
1098 if (strpos($foreignTableClause,
'###CURRENT_PID###') !==
false) {
1100 if (!empty($result[
'flexParentDatabaseRow'][
'pid'])) {
1101 $effectivePid = $result[
'flexParentDatabaseRow'][
'pid'];
1102 } elseif (!$effectivePid && !empty($result[
'databaseRow'][
'pid'])) {
1104 $effectivePid = $result[
'databaseRow'][
'pid'];
1109 foreach ($result[
'rootline'] as $rootlinePage) {
1110 if (!empty($rootlinePage[
'is_siteroot'])) {
1111 $siteRootUid = (int)$rootlinePage[
'uid'];
1116 $pageTsConfigId = 0;
1117 if (isset($result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_ID'])
1118 && $result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_ID']
1120 $pageTsConfigId = (int)$result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_ID'];
1123 $pageTsConfigIdList = 0;
1124 if (isset($result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_IDLIST'])
1125 && $result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_IDLIST']
1127 $pageTsConfigIdList = $result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_IDLIST'];
1129 $pageTsConfigIdListArray = GeneralUtility::trimExplode(
',', $pageTsConfigIdList,
true);
1130 $pageTsConfigIdList = [];
1131 foreach ($pageTsConfigIdListArray as $pageTsConfigIdListElement) {
1133 $pageTsConfigIdList[] = (int)$pageTsConfigIdListElement;
1136 $pageTsConfigIdList = implode(
',', $pageTsConfigIdList);
1138 $pageTsConfigString =
'';
1139 if (isset($result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_STR'])
1140 && $result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_STR']
1142 $pageTsConfigString = $result[
'pageTsConfig'][
'TCEFORM.'][$localTable .
'.'][$localFieldName .
'.'][
'PAGE_TSCONFIG_STR'];
1143 $pageTsConfigString = $connection->quote($pageTsConfigString);
1146 $foreignTableClause = str_replace(
1148 '###CURRENT_PID###',
1151 '###PAGE_TSCONFIG_ID###',
1152 '###PAGE_TSCONFIG_IDLIST###',
1153 '\'###PAGE_TSCONFIG_STR###\
'',
1154 '###PAGE_TSCONFIG_STR###'
1158 (
int)$result[
'databaseRow'][
'uid'],
1161 $pageTsConfigIdList,
1162 $pageTsConfigString,
1171 $foreignTableClause =
' ' . $foreignTableClause;
1172 $foreignTableClauseArray = [
1180 if (preg_match(
'/^(.*)[[:space:]]+LIMIT[[:space:]]+([[:alnum:][:space:],._]+)$/is', $foreignTableClause, $reg)) {
1181 $foreignTableClauseArray[
'LIMIT'] = GeneralUtility::intExplode(
',', trim($reg[2]),
true);
1182 $foreignTableClause = $reg[1];
1186 if (preg_match(
'/^(.*)[[:space:]]+ORDER[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._()"]+)$/is', $foreignTableClause, $reg)) {
1188 $foreignTableClause = $reg[1];
1192 if (preg_match(
'/^(.*)[[:space:]]+GROUP[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._()"]+)$/is', $foreignTableClause, $reg)) {
1194 $foreignTableClause = $reg[1];
1199 return $foreignTableClauseArray;
1211 $currentDatabaseValues = array_key_exists($fieldName, $row)
1214 if (!is_array($currentDatabaseValues)) {
1215 $currentDatabaseValues = GeneralUtility::trimExplode(
',', $currentDatabaseValues,
true);
1217 return $currentDatabaseValues;
1233 $fieldConfig = $result[
'processedTca'][
'columns'][$fieldName];
1235 $currentDatabaseValueArray = array_key_exists($fieldName, $result[
'databaseRow']) ? $result[
'databaseRow'][$fieldName] : [];
1236 $newDatabaseValueArray = [];
1240 foreach ($currentDatabaseValueArray as $value) {
1241 if (isset($staticValues[$value])) {
1242 $newDatabaseValueArray[] = $value;
1246 if (isset($fieldConfig[
'config'][
'foreign_table']) && !empty($fieldConfig[
'config'][
'foreign_table'])) {
1248 $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
1249 $relationHandler->registerNonTableValues = !empty($fieldConfig[
'config'][
'allowNonIdValues']);
1250 if (!empty($fieldConfig[
'config'][
'MM']) && $result[
'command'] !==
'new') {
1252 $relationHandler->start(
1253 implode(
',', $currentDatabaseValueArray),
1254 $fieldConfig[
'config'][
'foreign_table'],
1255 $fieldConfig[
'config'][
'MM'],
1256 $result[
'databaseRow'][
'uid'],
1257 $result[
'tableName'],
1258 $fieldConfig[
'config']
1260 $newDatabaseValueArray = array_merge($newDatabaseValueArray, $relationHandler->getValueArray());
1264 $relationHandler->start(
1265 implode(
',', $currentDatabaseValueArray),
1266 $fieldConfig[
'config'][
'foreign_table'],
1269 $result[
'tableName'],
1270 $fieldConfig[
'config']
1272 $databaseIds = array_merge($newDatabaseValueArray, $relationHandler->getValueArray());
1274 $newDatabaseValueArray = array_values(array_intersect($currentDatabaseValueArray, $databaseIds));
1278 if ($fieldConfig[
'config'][
'multiple'] ??
false) {
1279 return $newDatabaseValueArray;
1281 return array_unique($newDatabaseValueArray);
1299 foreach ($itemArray as $key => $item) {
1300 if (!isset($dynamicItems[$key])) {
1301 $staticValues[$item[1]] = $item;
1303 if (isset($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'altLabels.'][$item[1]])
1304 && !empty($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'altLabels.'][$item[1]])
1306 $label = $languageService->sL($result[
'pageTsConfig'][
'TCEFORM.'][$table .
'.'][$fieldName .
'.'][
'altLabels.'][$item[1]]);
1308 $label = $languageService->sL(trim($item[0]));
1310 $value = strlen((
string)$item[1]) > 0 ? $item[1] :
'';
1311 $icon = !empty($item[2]) ? $item[2] :
null;
1313 if (!empty($item[3])) {
1314 if (\is_string($item[3])) {
1315 $helpText = $languageService->sL($item[3]);
1317 $helpText = $item[3];
1320 $itemArray[$key] = [
1344 if (!is_array($itemArray)) {
1347 foreach ($itemArray as $item) {
1348 if (!is_array($item)) {
1349 throw new \UnexpectedValueException(
1350 'An item in field ' . $fieldName .
' of table ' . $tableName .
' is not an array as expected',
1369 $table = $result[
'tableName'];
1370 $row = $result[
'databaseRow'];
1372 if (!empty($result[
'processedTca'][
'ctrl'][
'versioningWS'])
1373 && $result[
'pid'] === -1
1375 if (empty($row[
't3ver_oid'])) {
1376 throw new \UnexpectedValueException(
1377 'No t3ver_oid found for record ' . $row[
'uid'] .
' on table ' . $table,
1381 $uid = $row[
't3ver_oid'];