2 namespace TYPO3\CMS\Core\Database;
60 'sys_history' =>
true,
61 'tx_extensionmanager_domain_model_extension' =>
true
77 'perms_userid' =>
true,
78 'perms_groupid' =>
true,
80 'perms_group' =>
true,
81 'perms_everybody' =>
true,
205 if (isset(static::$nonRelationTables[$tableName])) {
210 $cacheId = static::$cachePrefixTableRelationFields . $tableName;
211 if (!$this->runtimeCache->has($cacheId)) {
213 $this->runtimeCache->set($cacheId, $tableRelationFields);
215 $tableRelationFields = $this->runtimeCache->get($cacheId);
221 $currentRelations = $databaseConnection->exec_SELECTgetRows(
224 'tablename=' . $databaseConnection->fullQuoteStr($tableName,
'sys_refindex')
225 .
' AND recuid=' . (int)$uid .
' AND workspace=' . $this->
getWorkspaceId(),
236 if (!is_array($relation)) {
239 $relation[
'hash'] = md5(implode(
'
240 // First, check if already indexed and if so, unset that row (so in the end we know which rows to remove!)
241 if (isset($currentRelations[$relation['hash
']])) {
242 unset($currentRelations[$relation['hash
']]);
243 $result['keptNodes
']++;
244 $relation['_ACTION
'] = 'KEPT
';
248 $databaseConnection->exec_INSERTquery('sys_refindex
', $relation);
250 $result['addedNodes
']++;
251 $relation['_ACTION
'] = 'ADDED
';
254 $result['relations
'] = $relations;
260 // If any old are left, remove them:
261 if (!empty($currentRelations)) {
262 $hashList = array_keys($currentRelations);
263 if (!empty($hashList)) {
264 $result['deletedNodes
'] = count($hashList);
265 $result['deletedNodes_hashList
'] = implode(',
', $hashList);
267 $databaseConnection->exec_DELETEquery(
268 'sys_refindex
', 'hash IN (
' . implode(',
', $databaseConnection->fullQuoteArray($hashList, 'sys_refindex
')) . ')
'
285 public function generateRefIndexData($tableName, $uid)
287 if (!isset($GLOBALS['TCA
'][$tableName])) {
291 $this->relations = array();
293 // Fetch tableRelationFields and save them in cache if not there yet
294 $cacheId = static::$cachePrefixTableRelationFields . $tableName;
295 if (!$this->runtimeCache->has($cacheId)) {
296 $tableRelationFields = $this->fetchTableRelationFields($tableName);
297 $this->runtimeCache->set($cacheId, $tableRelationFields);
299 $tableRelationFields = $this->runtimeCache->get($cacheId);
302 // Return if there are no fields which could contain relations
303 if ($tableRelationFields === '') {
304 return $this->relations;
307 $deleteField = $GLOBALS['TCA
'][$tableName]['ctrl
']['delete'];
309 if ($tableRelationFields === '*
') {
310 // If one field of a record is of type flex, all fields have to be fetched to be passed to BackendUtility::getFlexFormDS
313 // otherwise only fields that might contain relations are fetched
314 $selectFields = 'uid,
' . $tableRelationFields . ($deleteField ? ',
' . $deleteField : '');
317 // Get raw record from DB:
318 $record = $this->getDatabaseConnection()->exec_SELECTgetSingleRow($selectFields, $tableName, 'uid=
' . (int)$uid);
319 if (!is_array($record)) {
324 $deleted = $deleteField && $record[$deleteField] ? 1 : 0;
326 // Get all relations from record:
327 $recordRelations = $this->getRelations($tableName, $record);
328 // Traverse those relations, compile records to insert in table:
329 foreach ($recordRelations as $fieldName => $fieldRelations) {
331 switch ((string)$fieldRelations['type
']) {
333 $this->createEntryData_dbRels($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['itemArray
']);
335 case 'file_reference
':
336 // not used (see getRelations()), but fallback to file
338 $this->createEntryData_fileRels($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['newValueFiles
']);
341 // DB references in FlexForms
342 if (is_array($fieldRelations['flexFormRels
']['db
'])) {
343 foreach ($fieldRelations['flexFormRels
']['db
'] as $flexPointer => $subList) {
344 $this->createEntryData_dbRels($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList);
347 // File references in FlexForms
348 // @todo #65463 Test correct handling of file references in FlexForms
349 if (is_array($fieldRelations['flexFormRels
']['file
'])) {
350 foreach ($fieldRelations['flexFormRels
']['file
'] as $flexPointer => $subList) {
351 $this->createEntryData_fileRels($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList);
354 // Soft references in FlexForms
355 // @todo #65464 Test correct handling of soft references in FlexForms
356 if (is_array($fieldRelations['flexFormRels
']['softrefs
'])) {
357 foreach ($fieldRelations['flexFormRels
']['softrefs
'] as $flexPointer => $subList) {
358 $this->createEntryData_softreferences($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList['keys
']);
363 // Soft references in the field
364 if (is_array($fieldRelations['softrefs
'])) {
365 $this->createEntryData_softreferences($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['softrefs
']['keys
']);
369 return $this->relations;
389 public function createEntryData($table, $uid, $field, $flexPointer, $deleted, $ref_table, $ref_uid, $ref_string = '', $sort = -1, $softref_key = '', $softref_id = '')
391 if (BackendUtility::isTableWorkspaceEnabled($table)) {
392 $element = BackendUtility::getRecord($table, $uid, 't3ver_wsid
');
393 if ($element !== null && isset($element['t3ver_wsid
']) && (int)$element['t3ver_wsid
'] !== $this->getWorkspaceId()) {
394 //The given Element is ws-enabled but doesn't live in the selected workspace
400 'tablename' => $table,
403 'flexpointer' => $flexPointer,
404 'softref_key' => $softref_key,
405 'softref_id' => $softref_id,
407 'deleted' => $deleted,
409 'ref_table' => $ref_table,
410 'ref_uid' => $ref_uid,
411 'ref_string' => $ref_string
428 foreach ($items as $sort => $i) {
429 $this->relations[] = $this->
createEntryData($table, $uid, $fieldName, $flexPointer, $deleted, $i[
'table'], $i[
'id'],
'', $sort);
446 foreach ($items as $sort => $i) {
447 $filePath = $i[
'ID_absFile'];
451 $this->relations[] = $this->
createEntryData($table, $uid, $fieldName, $flexPointer, $deleted,
'_FILE', 0, $filePath, $sort);
468 if (is_array($keys)) {
469 foreach ($keys as $spKey => $elements) {
470 if (is_array($elements)) {
471 foreach ($elements as $subKey => $el) {
472 if (is_array($el[
'subst'])) {
473 switch ((
string)$el[
'subst'][
'type']) {
475 list($tableName, $recordId) = explode(
':', $el[
'subst'][
'recordRef']);
476 $this->relations[] = $this->
createEntryData($table, $uid, $fieldName, $flexPointer, $deleted, $tableName, $recordId,
'', -1, $spKey, $subKey);
478 case 'file_reference':
481 $this->relations[] = $this->
createEntryData($table, $uid, $fieldName, $flexPointer, $deleted,
'_FILE', 0, $el[
'subst'][
'relFileName'], -1, $spKey, $subKey);
484 $this->relations[] = $this->
createEntryData($table, $uid, $fieldName, $flexPointer, $deleted,
'_STRING', 0, $el[
'subst'][
'tokenValue'], -1, $spKey, $subKey);
516 foreach ($row as $field => $value) {
517 if (!isset(static::$nonRelationFields[$field]) && is_array(
$GLOBALS[
'TCA'][$table][
'columns'][$field]) && (!$onlyField || $onlyField === $field)) {
518 $conf =
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'];
521 if (!empty($resultsFromFiles)) {
526 $fileResultsFromFiles = array();
527 $dbResultsFromFiles = array();
528 foreach ($resultsFromFiles as $resultFromFiles) {
529 if (isset($resultFromFiles[
'table']) && $resultFromFiles[
'table'] ===
'sys_file') {
530 $dbResultsFromFiles[] = $resultFromFiles;
533 $fileResultsFromFiles[] = $resultFromFiles;
536 if (!empty($fileResultsFromFiles)) {
537 $outRow[$field] = array(
539 'newValueFiles' => $fileResultsFromFiles
542 if (!empty($dbResultsFromFiles)) {
543 $outRow[$field] = array(
545 'itemArray' => $dbResultsFromFiles
550 if ($conf[
'type'] ===
'input' && isset($conf[
'wizards'][
'link']) && empty($conf[
'softref'])) {
551 $conf[
'softref'] =
'typolink';
555 if (!empty($resultsFromDatabase)) {
557 $outRow[$field] = array(
559 'itemArray' => $resultsFromDatabase
563 if ($conf[
'type'] ===
'flex') {
568 if (is_array($currentValueArray)) {
569 $this->temp_flexRelations = array(
572 'softrefs' => array()
576 $flexFormTools->traverseFlexFormXMLData($table, $field, $row, $this,
'getRelations_flexFormCallBack');
578 $outRow[$field] = array(
580 'flexFormRels' => $this->temp_flexRelations
585 if ((
string)$value !==
'') {
586 $softRefValue = $value;
588 if ($softRefs !==
false) {
589 foreach ($softRefs as $spKey => $spParams) {
591 if (is_object($softRefObj)) {
592 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);
593 if (is_array($resultArray)) {
594 $outRow[$field][
'softrefs'][
'keys'][$spKey] = $resultArray[
'elements'];
595 if ((
string)$resultArray[
'content'] !==
'') {
596 $softRefValue = $resultArray[
'content'];
602 if (!empty($outRow[$field][
'softrefs']) && (
string)$value !== (
string)$softRefValue && strpos($softRefValue,
'{softref:') !==
false) {
603 $outRow[$field][
'softrefs'][
'tokenizedContent'] = $softRefValue;
625 $structurePath = substr($structurePath, 5) .
'/';
626 $dsConf = $dsArr[
'TCEforms'][
'config'];
628 list($table, $uid, $field) = array(
635 if (!empty($resultsFromFiles)) {
640 $fileResultsFromFiles = array();
641 $dbResultsFromFiles = array();
642 foreach ($resultsFromFiles as $resultFromFiles) {
643 if (isset($resultFromFiles[
'table']) && $resultFromFiles[
'table'] ===
'sys_file') {
644 $dbResultsFromFiles[] = $resultFromFiles;
646 $fileResultsFromFiles[] = $resultFromFiles;
649 if (!empty($fileResultsFromFiles)) {
650 $this->temp_flexRelations[
'file'][$structurePath] = $fileResultsFromFiles;
652 if (!empty($dbResultsFromFiles)) {
653 $this->temp_flexRelations[
'db'][$structurePath] = $dbResultsFromFiles;
657 if ($dsConf[
'type'] ===
'input' && isset($dsConf[
'wizards'][
'link']) && empty($dsConf[
'softref'])) {
658 $dsConf[
'softref'] =
'typolink';
661 $resultsFromDatabase = $this->
getRelations_procDB($dataValue, $dsConf, $uid, $table, $field);
662 if (!empty($resultsFromDatabase)) {
664 $this->temp_flexRelations[
'db'][$structurePath] = $resultsFromDatabase;
667 if (is_array($dataValue) || (
string)$dataValue !==
'') {
668 $softRefValue = $dataValue;
670 if ($softRefs !==
false) {
671 foreach ($softRefs as $spKey => $spParams) {
673 if (is_object($softRefObj)) {
674 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams, $structurePath);
675 if (is_array($resultArray) && is_array($resultArray[
'elements'])) {
676 $this->temp_flexRelations[
'softrefs'][$structurePath][
'keys'][$spKey] = $resultArray[
'elements'];
677 if ((
string)$resultArray[
'content'] !==
'') {
678 $softRefValue = $resultArray[
'content'];
684 if (!empty($this->temp_flexRelations[
'softrefs']) && (
string)$dataValue !== (
string)$softRefValue) {
685 $this->temp_flexRelations[
'softrefs'][$structurePath][
'tokenizedContent'] = $softRefValue;
700 if ($conf[
'type'] !==
'group' || ($conf[
'internal_type'] !==
'file' && $conf[
'internal_type'] !==
'file_reference')) {
706 $theFileValues = array();
708 $dbAnalysis->start(
'',
'files', $conf[
'MM'], $uid);
709 foreach ($dbAnalysis->itemArray as $someval) {
710 if ($someval[
'id']) {
711 $theFileValues[] = $someval[
'id'];
715 $theFileValues = explode(
',', $value);
718 $uploadFolder = $conf[
'internal_type'] ===
'file' ? $conf[
'uploadfolder'] :
'';
720 $newValueFiles = array();
721 foreach ($theFileValues as $file) {
723 $realFile = $destinationFolder .
'/' . trim($file);
724 $newValueFile = array(
725 'filename' => basename($file),
726 'ID' => md5($realFile),
727 'ID_absFile' => $realFile
730 if ($conf[
'internal_type'] ===
'file_reference') {
733 if ($file instanceof
File || $file instanceof
Folder) {
736 $newValueFile = array(
737 'table' =>
'sys_file',
738 'id' => $file->getUid()
744 $newValueFiles[] = $newValueFile;
747 return $newValueFiles;
765 }
elseif ($conf[
'type'] ===
'inline' && !empty($conf[
'foreign_table']) && empty($conf[
'MM'])) {
767 $dbAnalysis->setUseLiveReferenceIds(
false);
768 $dbAnalysis->start($value, $conf[
'foreign_table'],
'', $uid, $table, $conf);
769 return $dbAnalysis->itemArray;
772 $allowedTables = $conf[
'type'] ===
'group' ? $conf[
'allowed'] : $conf[
'foreign_table'];
773 if ($conf[
'MM_opposite_field']) {
777 $dbAnalysis->start($value, $allowedTables, $conf[
'MM'], $uid, $table, $conf);
778 return $dbAnalysis->itemArray;
779 }
elseif ($conf[
'type'] ===
'inline' && $conf[
'foreign_table'] ===
'sys_file_reference') {
783 'sys_file_reference',
784 'tablenames=\'' . $table .
'\' AND fieldname=\
'' . $field .
'\' AND uid_foreign=
' . $uid . ' AND deleted=0
'
786 $fileArray = array();
787 if (!empty($files)) {
788 foreach ($files as $fileUid) {
789 $fileArray[] = array(
790 'table
' => 'sys_file
',
791 'id' => $fileUid['uid_local
']
800 /*******************************
804 *******************************/
825 public function setReferenceValue($hash, $newValue, $returnDataArray = false, $bypassWorkspaceAdminCheck = false)
827 $backendUser = $this->getBackendUser();
828 if ($backendUser->workspace === 0 && $backendUser->isAdmin() || $bypassWorkspaceAdminCheck) {
829 $databaseConnection = $this->getDatabaseConnection();
831 // Get current index from Database:
832 $referenceRecord = $databaseConnection->exec_SELECTgetSingleRow('*
', 'sys_refindex
', 'hash=
' . $databaseConnection->fullQuoteStr($hash, 'sys_refindex
'));
833 // Check if reference existed.
834 if (!is_array($referenceRecord)) {
835 return 'ERROR: No reference record with hash=
"' . $hash . '" was found!
';
838 if (empty($GLOBALS['TCA
'][$referenceRecord['tablename
']])) {
839 return 'ERROR: Table
"' . $referenceRecord['tablename'] . '" was not in TCA!
';
842 // Get that record from database:
843 $record = $databaseConnection->exec_SELECTgetSingleRow('*
', $referenceRecord['tablename
'], 'uid=
' . (int)$referenceRecord['recuid
']);
844 if (is_array($record)) {
845 // Get relation for single field from record
846 $recordRelations = $this->getRelations($referenceRecord['tablename
'], $record, $referenceRecord['field
']);
847 if ($fieldRelation = $recordRelations[$referenceRecord['field
']]) {
848 // Initialize data array that is to be sent to DataHandler afterwards:
849 $dataArray = array();
851 switch ((string)$fieldRelation['type
']) {
853 $error = $this->setReferenceValue_dbRels($referenceRecord, $fieldRelation['itemArray
'], $newValue, $dataArray);
858 case 'file_reference
':
859 // not used (see getRelations()), but fallback to file
861 $error = $this->setReferenceValue_fileRels($referenceRecord, $fieldRelation['newValueFiles
'], $newValue, $dataArray);
867 // DB references in FlexForms
868 if (is_array($fieldRelation['flexFormRels
']['db
'][$referenceRecord['flexpointer
']])) {
869 $error = $this->setReferenceValue_dbRels($referenceRecord, $fieldRelation['flexFormRels
']['db
'][$referenceRecord['flexpointer
']], $newValue, $dataArray, $referenceRecord['flexpointer
']);
874 // File references in FlexForms
875 if (is_array($fieldRelation['flexFormRels
']['file
'][$referenceRecord['flexpointer
']])) {
876 $error = $this->setReferenceValue_fileRels($referenceRecord, $fieldRelation['flexFormRels
']['file
'][$referenceRecord['flexpointer
']], $newValue, $dataArray, $referenceRecord['flexpointer
']);
881 // Soft references in FlexForms
882 if ($referenceRecord['softref_key
'] && is_array($fieldRelation['flexFormRels
']['softrefs
'][$referenceRecord['flexpointer
']]['keys
'][$referenceRecord['softref_key
']])) {
883 $error = $this->setReferenceValue_softreferences($referenceRecord, $fieldRelation['flexFormRels
']['softrefs
'][$referenceRecord['flexpointer
']], $newValue, $dataArray, $referenceRecord['flexpointer
']);
890 // Soft references in the field:
891 if ($referenceRecord['softref_key
'] && is_array($fieldRelation['softrefs
']['keys
'][$referenceRecord['softref_key
']])) {
892 $error = $this->setReferenceValue_softreferences($referenceRecord, $fieldRelation['softrefs
'], $newValue, $dataArray);
897 // Data Array, now ready to be sent to DataHandler
898 if ($returnDataArray) {
901 // Execute CMD array:
902 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
903 $dataHandler->stripslashes_values = false;
904 $dataHandler->dontProcessTransformations = true;
905 $dataHandler->bypassWorkspaceRestrictions = true;
906 $dataHandler->bypassFileHandling = true;
907 // Otherwise this cannot update things in deleted records...
908 $dataHandler->bypassAccessCheckForRecords = true;
909 // Check has been done previously that there is a backend user which is Admin and also in live workspace
910 $dataHandler->start($dataArray, array());
911 $dataHandler->process_datamap();
912 // Return errors if any:
913 if (!empty($dataHandler->errorLog)) {
920 return 'ERROR: BE_USER
object is not admin OR not in workspace 0 (Live)
';
936 public function setReferenceValue_dbRels($refRec, $itemArray, $newValue, &$dataArray, $flexPointer = '')
938 if ((int)$itemArray[$refRec['sorting
']]['id'] === (int)$refRec['ref_uid
'] && (string)$itemArray[$refRec['sorting
']]['table
'] === (string)$refRec['ref_table
']) {
939 // Setting or removing value:
941 if ($newValue === null) {
942 unset($itemArray[$refRec['sorting
']]);
944 list($itemArray[$refRec['sorting
']]['table
'], $itemArray[$refRec['sorting
']]['id']) = explode(':
', $newValue);
946 // Traverse and compile new list of records:
947 $saveValue = array();
948 foreach ($itemArray as $pair) {
949 $saveValue[] = $pair['table
'] . '_
' . $pair['id'];
951 // Set in data array:
953 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
954 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'] = array();
955 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'], implode(',
', $saveValue));
957 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']] = implode(',
', $saveValue);
960 return 'ERROR: table:
id pair
"' . $refRec['ref_table'] . ':' . $refRec['ref_uid'] . '" did not match that of the record (
"' . $itemArray[$refRec['sorting']]['table'] . ':' . $itemArray[$refRec['sorting']]['id'] . '") in sorting index
"' . $refRec['sorting'] . '"';
976 public function setReferenceValue_fileRels($refRec, $itemArray, $newValue, &$dataArray, $flexPointer = '')
978 $ID_absFile = PathUtility::stripPathSitePrefix($itemArray[$refRec['sorting
']]['ID_absFile
']);
979 if ($ID_absFile === (string)$refRec['ref_string
'] && $refRec['ref_table
'] === '_FILE
') {
980 // Setting or removing value:
982 if ($newValue === null) {
983 unset($itemArray[$refRec['sorting
']]);
985 $itemArray[$refRec['sorting
']]['filename
'] = $newValue;
987 // Traverse and compile new list of records:
988 $saveValue = array();
989 foreach ($itemArray as $fileInfo) {
990 $saveValue[] = $fileInfo['filename
'];
992 // Set in data array:
994 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
995 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'] = array();
996 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'], implode(',
', $saveValue));
998 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']] = implode(',
', $saveValue);
1001 return 'ERROR: either
"' . $refRec['ref_table'] . '" was not
"_FILE" or file PATH_site+
"' . $refRec['ref_string'] . '" did not match that of the record (
"' . $itemArray[$refRec['sorting']]['ID_absFile'] . '") in sorting index
"' . $refRec['sorting'] . '"';
1017 public function setReferenceValue_softreferences($refRec, $softref, $newValue, &$dataArray, $flexPointer = '')
1019 if (!is_array($softref['keys
'][$refRec['softref_key
']][$refRec['softref_id
']])) {
1020 return 'ERROR: Soft reference parser key
"' . $refRec['softref_key'] . '" or the index
"' . $refRec['softref_id'] . '" was not found.
';
1024 $softref['keys
'][$refRec['softref_key
']][$refRec['softref_id
']]['subst
']['tokenValue
'] = '' . $newValue;
1025 // Traverse softreferences and replace in tokenized content to rebuild it with new value inside:
1026 foreach ($softref['keys
'] as $sfIndexes) {
1027 foreach ($sfIndexes as $data) {
1028 $softref['tokenizedContent
'] = str_replace('{softref:
' . $data['subst
']['tokenID
'] . '}
', $data['subst
']['tokenValue
'], $softref['tokenizedContent
']);
1031 // Set in data array:
1032 if (!strstr($softref['tokenizedContent
'], '{softref:
')) {
1034 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
1035 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'] = array();
1036 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']]['data
'], $softref['tokenizedContent
']);
1038 $dataArray[$refRec['tablename
']][$refRec['recuid
']][$refRec['field
']] = $softref['tokenizedContent
'];
1041 return 'ERROR: After substituting all found soft references there were still soft reference tokens in the text. (theoretically
this does not have to be an
error if the
string "{softref:" happens to be in the field
for another reason.)
';
1047 /*******************************
1051 *******************************/
1059 protected function isDbReferenceField(array $configuration)
1062 ($configuration['type
'] === 'group
' && $configuration['internal_type
'] === 'db
')
1064 ($configuration['type
'] === 'select
' || $configuration['type
'] === 'inline')
1065 && !empty($configuration['foreign_table
'])
1076 public function isReferenceField(array $configuration)
1079 $this->isDbReferenceField($configuration)
1081 ($configuration['type
'] === 'group
' && ($configuration['internal_type
'] === 'file
' || $configuration['internal_type
'] === 'file_reference
')) // getRelations_procFiles
1083 ($configuration['type
'] === 'input
' && isset($configuration['wizards
']['link
'])) // getRelations_procDB
1085 $configuration['type
'] === 'flex
'
1087 isset($configuration['softref
'])
1090 // @deprecated global soft reference parsers are deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8
1091 is_array($GLOBALS['TYPO3_CONF_VARS
']['SC_OPTIONS
']['GLOBAL
']['softRefParser_GL
'])
1092 && !empty($GLOBALS['TYPO3_CONF_VARS
']['SC_OPTIONS
']['GLOBAL
']['softRefParser_GL
'])
1103 protected function fetchTableRelationFields($tableName)
1105 if (!isset($GLOBALS['TCA
'][$tableName])) {
1111 foreach ($GLOBALS['TCA
'][$tableName]['columns
'] as $field => $fieldDefinition) {
1112 if (is_array($fieldDefinition['config
'])) {
1113 // Check for flex field
1114 if (isset($fieldDefinition['config
']['type
']) && $fieldDefinition['config
']['type
'] === 'flex
') {
1115 // Fetch all fields if the is a field of type flex in the table definition because the complete row is passed to
1116 // BackendUtility::getFlexFormDS in the end and might be needed in ds_pointerField or $hookObj->getFlexFormDS_postProcessDS
1119 // Only fetch this field if it can contain a reference
1120 if ($this->isReferenceField($fieldDefinition['config
'])) {
1126 return implode(',
', $fields);
1135 public function destPathFromUploadFolder($folder)
1138 return substr(PATH_site, 0, -1);
1140 return PATH_site . $folder;
1150 public function error($msg)
1152 GeneralUtility::logDeprecatedFunction();
1153 $this->errorLog[] = $msg;
1163 public function updateIndex($testOnly, $cli_echo = false)
1165 $databaseConnection = $this->getDatabaseConnection();
1167 $tableNames = array();
1170 $headerContent = $testOnly ? 'Reference Index being TESTED (nothing written, use
"--refindex update" to update)
' : 'Reference Index being Updated
';
1172 echo '*******************************************
' . LF . $headerContent . LF . '*******************************************
' . LF;
1174 // Traverse all tables:
1175 foreach ($GLOBALS['TCA
'] as $tableName => $cfg) {
1176 if (isset(static::$nonRelationTables[$tableName])) {
1179 // Traverse all records in tables, including deleted records:
1180 $fieldNames = (BackendUtility::isTableWorkspaceEnabled($tableName) ? 'uid,t3ver_wsid
' : 'uid
');
1181 $res = $databaseConnection->exec_SELECTquery($fieldNames, $tableName, '1=1
');
1182 if ($databaseConnection->sql_error()) {
1183 // Table exists in $TCA but does not exist in the database
1184 GeneralUtility::sysLog(sprintf('Table
"%s" exists in $TCA but does not exist in the database. You should run the Database Analyzer in the Install Tool to fix this.
', $tableName), 'core
', GeneralUtility::SYSLOG_SEVERITY_ERROR);
1187 $tableNames[] = $tableName;
1189 $uidList = array(0);
1190 while ($record = $databaseConnection->sql_fetch_assoc($res)) {
1192 $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
1193 if (isset($record['t3ver_wsid
'])) {
1194 $refIndexObj->setWorkspaceId($record['t3ver_wsid
']);
1196 $result = $refIndexObj->updateRefIndexTable($tableName, $record['uid
'], $testOnly);
1197 $uidList[] = $record['uid
'];
1199 if ($result['addedNodes
'] || $result['deletedNodes
']) {
1200 $error = 'Record
' . $tableName . ':
' . $record['uid
'] . ' had
' . $result['addedNodes
'] . ' added indexes and
' . $result['deletedNodes
'] . ' deleted indexes
';
1207 $databaseConnection->sql_free_result($res);
1209 // Searching lost indexes for this table:
1210 $where = 'tablename=
' . $databaseConnection->fullQuoteStr($tableName, 'sys_refindex
') . ' AND recuid NOT IN (
' . implode(',
', $uidList) . ')
';
1211 $lostIndexes = $databaseConnection->exec_SELECTgetRows('hash
', 'sys_refindex
', $where);
1212 $lostIndexesCount = count($lostIndexes);
1213 if ($lostIndexesCount) {
1214 $error = 'Table
' . $tableName . ' has
' . $lostIndexesCount . ' lost indexes which are now deleted
';
1220 $databaseConnection->exec_DELETEquery('sys_refindex
', $where);
1224 // Searching lost indexes for non-existing tables:
1225 $where = 'tablename NOT IN (
' . implode(',
', $databaseConnection->fullQuoteArray($tableNames, 'sys_refindex
')) . ')
';
1226 $lostTables = $databaseConnection->exec_SELECTgetRows('hash
', 'sys_refindex
', $where);
1227 $lostTablesCount = count($lostTables);
1228 if ($lostTablesCount) {
1229 $error = 'Index table hosted
' . $lostTablesCount . ' indexes
for non-existing tables, now removed
';
1235 $databaseConnection->exec_DELETEquery('sys_refindex
', $where);
1238 $errorCount = count($errors);
1239 $recordsCheckedString = $recCount . ' records from
' . $tableCount . ' tables were checked/updated.
' . LF;
1240 $flashMessage = GeneralUtility::makeInstance(
1241 FlashMessage::class,
1242 $errorCount ? implode('##LF##
', $errors) : 'Index Integrity was perfect!
',
1243 $recordsCheckedString,
1244 $errorCount ? FlashMessage::ERROR : FlashMessage::OK
1246 $bodyContent = $flashMessage->render();
1248 echo $recordsCheckedString . ($errorCount ? 'Updates:
' . $errorCount : 'Index Integrity was perfect!
') . LF;
1251 $registry = GeneralUtility::makeInstance(Registry::class);
1252 $registry->set('core
', 'sys_refindex_lastUpdate
', $GLOBALS['EXEC_TIME
']);
1254 return array($headerContent, $bodyContent, $errorCount);
1262 protected function getDatabaseConnection()
1264 return $GLOBALS['TYPO3_DB
'];
1272 protected function getBackendUser()
1274 return $GLOBALS['BE_USER
'];