[!!!][FEATURE] FormEngine element level refactoring
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Database / ReferenceIndex.php
index 31016c5..abc5a0b 100644 (file)
@@ -14,11 +14,13 @@ namespace TYPO3\CMS\Core\Database;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\DBALException;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Registry;
 use TYPO3\CMS\Core\Resource\File;
 use TYPO3\CMS\Core\Resource\Folder;
@@ -55,11 +57,11 @@ class ReferenceIndex
      * @see updateRefIndexTable()
      * @todo #65461 Create configuration for tables to exclude from ReferenceIndex
      */
-    protected static $nonRelationTables = array(
+    protected static $nonRelationTables = [
         'sys_log' => true,
         'sys_history' => true,
         'tx_extensionmanager_domain_model_extension' => true
-    );
+    ];
 
     /**
      * Definition of fields to exclude from searching for relations
@@ -72,7 +74,7 @@ class ReferenceIndex
      * @see fetchTableRelationFields()
      * @todo #65460 Create configuration for fields to exclude from ReferenceIndex
      */
-    protected static $nonRelationFields = array(
+    protected static $nonRelationFields = [
         'uid' => true,
         'perms_userid' => true,
         'perms_groupid' => true,
@@ -80,7 +82,7 @@ class ReferenceIndex
         'perms_group' => true,
         'perms_everybody' => true,
         'pid' => true
-    );
+    ];
 
     /**
      * Fields of tables that could contain relations are cached per table. This is the prefix for the cache entries since
@@ -96,16 +98,7 @@ class ReferenceIndex
      * @var array
      * @see getRelations(),FlexFormTools::traverseFlexFormXMLData(),getRelations_flexFormCallBack()
      */
-    public $temp_flexRelations = array();
-
-    /**
-     * Unused log for errors in ReferenceIndex
-     *
-     * @var array
-     * @see error()
-     * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
-     */
-    public $errorLog = array();
+    public $temp_flexRelations = [];
 
     /**
      * This variable used to indicate whether referencing should take workspace overlays into account
@@ -122,7 +115,7 @@ class ReferenceIndex
      * @var array
      * @see createEntryData(),generateRefIndexData()
      */
-    public $relations = array();
+    public $relations = [];
 
     /**
      * Number which we can increase if a change in the code means we will have to force a re-generation of the index.
@@ -195,11 +188,11 @@ class ReferenceIndex
         $this->WSOL = false;
 
         // Init:
-        $result = array(
+        $result = [
             'keptNodes' => 0,
             'deletedNodes' => 0,
             'addedNodes' => 0
-        );
+        ];
 
         // If this table cannot contain relations, skip it
         if (isset(static::$nonRelationTables[$tableName])) {
@@ -215,16 +208,24 @@ class ReferenceIndex
             $tableRelationFields = $this->runtimeCache->get($cacheId);
         }
 
-        $databaseConnection = $this->getDatabaseConnection();
+        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_refindex');
 
         // Get current index from Database with hash as index using $uidIndexField
-        $currentRelations = $databaseConnection->exec_SELECTgetRows(
-            '*',
-            'sys_refindex',
-            'tablename=' . $databaseConnection->fullQuoteStr($tableName, 'sys_refindex')
-            . ' AND recuid=' . (int)$uid . ' AND workspace=' . $this->getWorkspaceId(),
-            '', '', '', 'hash'
-        );
+        // no restrictions are needed, since sys_refindex is not a TCA table
+        $queryBuilder = $connection->createQueryBuilder();
+        $queryBuilder->getRestrictions()->removeAll();
+        $queryResult = $queryBuilder->select('*')->from('sys_refindex')->where(
+            $queryBuilder->expr()->eq('tablename', $queryBuilder->createNamedParameter($tableName, \PDO::PARAM_STR)),
+            $queryBuilder->expr()->eq('recuid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)),
+            $queryBuilder->expr()->eq(
+                'workspace',
+                $queryBuilder->createNamedParameter($this->getWorkspaceId(), \PDO::PARAM_INT)
+            )
+        )->execute();
+        $currentRelations = [];
+        while ($relation = $queryResult->fetch()) {
+            $currentRelations[$relation['hash']] = $currentRelations;
+        }
 
         // If the table has fields which could contain relations and the record does exist (including deleted-flagged)
         if ($tableRelationFields !== '' && BackendUtility::getRecordRaw($tableName, 'uid=' . (int)$uid, 'uid')) {
@@ -245,7 +246,7 @@ class ReferenceIndex
                     } else {
                         // If new, add it:
                         if (!$testOnly) {
-                            $databaseConnection->exec_INSERTquery('sys_refindex', $relation);
+                            $connection->insert('sys_refindex', $relation);
                         }
                         $result['addedNodes']++;
                         $relation['_ACTION'] = 'ADDED';
@@ -264,9 +265,16 @@ class ReferenceIndex
                 $result['deletedNodes'] = count($hashList);
                 $result['deletedNodes_hashList'] = implode(',', $hashList);
                 if (!$testOnly) {
-                    $databaseConnection->exec_DELETEquery(
-                        'sys_refindex', 'hash IN (' . implode(',', $databaseConnection->fullQuoteArray($hashList, 'sys_refindex')) . ')'
-                    );
+                    $queryBuilder = $connection->createQueryBuilder();
+                    $queryBuilder
+                        ->delete('sys_refindex')
+                        ->where(
+                            $queryBuilder->expr()->in(
+                                'hash',
+                                $queryBuilder->createNamedParameter($hashList, Connection::PARAM_STR_ARRAY)
+                            )
+                        )
+                        ->execute();
                 }
             }
         }
@@ -288,7 +296,7 @@ class ReferenceIndex
             return null;
         }
 
-        $this->relations = array();
+        $this->relations = [];
 
         // Fetch tableRelationFields and save them in cache if not there yet
         $cacheId = static::$cachePrefixTableRelationFields . $tableName;
@@ -307,15 +315,16 @@ class ReferenceIndex
         $deleteField = $GLOBALS['TCA'][$tableName]['ctrl']['delete'];
 
         if ($tableRelationFields === '*') {
-            // If one field of a record is of type flex, all fields have to be fetched to be passed to BackendUtility::getFlexFormDS
+            // If one field of a record is of type flex, all fields have to be fetched
+            // to be passed to FlexFormTools->getDataStructureIdentifier()
             $selectFields = '*';
         } else {
             // otherwise only fields that might contain relations are fetched
             $selectFields = 'uid,' . $tableRelationFields . ($deleteField ? ',' . $deleteField : '');
         }
 
-        // Get raw record from DB:
-        $record = $this->getDatabaseConnection()->exec_SELECTgetSingleRow($selectFields, $tableName, 'uid=' . (int)$uid);
+        // Get raw record from DB
+        $record = BackendUtility::getRecordRaw($tableName, 'uid=' . (int)$uid, $selectFields);
         if (!is_array($record)) {
             return null;
         }
@@ -396,7 +405,7 @@ class ReferenceIndex
                 return false;
             }
         }
-        return array(
+        return [
             'tablename' => $table,
             'recuid' => $uid,
             'field' => $field,
@@ -408,8 +417,8 @@ class ReferenceIndex
             'workspace' => $this->getWorkspaceId(),
             'ref_table' => $ref_table,
             'ref_uid' => $ref_uid,
-            'ref_string' => $ref_string
-        );
+            'ref_string' => mb_substr($ref_string, 0, 1024)
+        ];
     }
 
     /**
@@ -512,7 +521,7 @@ class ReferenceIndex
     {
         // Initialize:
         $uid = $row['uid'];
-        $outRow = array();
+        $outRow = [];
         foreach ($row as $field => $value) {
             if (!isset(static::$nonRelationFields[$field]) && is_array($GLOBALS['TCA'][$table]['columns'][$field]) && (!$onlyField || $onlyField === $field)) {
                 $conf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
@@ -523,8 +532,8 @@ class ReferenceIndex
                     // internal_type file is still a relation of type file and
                     // since http://forge.typo3.org/issues/49538 internal_type file_reference
                     // is a database relation to a sys_file record
-                    $fileResultsFromFiles = array();
-                    $dbResultsFromFiles = array();
+                    $fileResultsFromFiles = [];
+                    $dbResultsFromFiles = [];
                     foreach ($resultsFromFiles as $resultFromFiles) {
                         if (isset($resultFromFiles['table']) && $resultFromFiles['table'] === 'sys_file') {
                             $dbResultsFromFiles[] = $resultFromFiles;
@@ -534,51 +543,52 @@ class ReferenceIndex
                         }
                     }
                     if (!empty($fileResultsFromFiles)) {
-                        $outRow[$field] = array(
+                        $outRow[$field] = [
                             'type' => 'file',
                             'newValueFiles' => $fileResultsFromFiles
-                        );
+                        ];
                     }
                     if (!empty($dbResultsFromFiles)) {
-                        $outRow[$field] = array(
+                        $outRow[$field] = [
                             'type' => 'db',
                             'itemArray' => $dbResultsFromFiles
-                        );
+                        ];
                     }
                 }
                 // Add a softref definition for link fields if the TCA does not specify one already
-                if ($conf['type'] === 'input' && isset($conf['wizards']['link']) && empty($conf['softref'])) {
+                if ($conf['type'] === 'input' && $conf['renderType'] === 'inputLink' && empty($conf['softref'])) {
                     $conf['softref'] = 'typolink';
                 }
                 // Add DB:
                 $resultsFromDatabase = $this->getRelations_procDB($value, $conf, $uid, $table, $field);
                 if (!empty($resultsFromDatabase)) {
                     // Create an entry for the field with all DB relations:
-                    $outRow[$field] = array(
+                    $outRow[$field] = [
                         'type' => 'db',
                         'itemArray' => $resultsFromDatabase
-                    );
+                    ];
                 }
                 // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
                 if ($conf['type'] === 'flex') {
                     // Get current value array:
-                    // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up the note in the JavaDoc documentation for the function \TYPO3\CMS\Backend\Utility\BackendUtility::getFlexFormDS()
+                    // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up
+                    // the note in the JavaDoc documentation for the function FlexFormTools->getDataStructureIdentifier()
                     $currentValueArray = GeneralUtility::xml2array($value);
                     // Traversing the XML structure, processing files:
                     if (is_array($currentValueArray)) {
-                        $this->temp_flexRelations = array(
-                            'db' => array(),
-                            'file' => array(),
-                            'softrefs' => array()
-                        );
+                        $this->temp_flexRelations = [
+                            'db' => [],
+                            'file' => [],
+                            'softrefs' => []
+                        ];
                         // Create and call iterator object:
                         $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
                         $flexFormTools->traverseFlexFormXMLData($table, $field, $row, $this, 'getRelations_flexFormCallBack');
                         // Create an entry for the field:
-                        $outRow[$field] = array(
+                        $outRow[$field] = [
                             'type' => 'flex',
                             'flexFormRels' => $this->temp_flexRelations
-                        );
+                        ];
                     }
                 }
                 // Soft References:
@@ -625,11 +635,11 @@ class ReferenceIndex
         $structurePath = substr($structurePath, 5) . '/';
         $dsConf = $dsArr['TCEforms']['config'];
         // Implode parameter values:
-        list($table, $uid, $field) = array(
+        list($table, $uid, $field) = [
             $PA['table'],
             $PA['uid'],
             $PA['field']
-        );
+        ];
         // Add files
         $resultsFromFiles = $this->getRelations_procFiles($dataValue, $dsConf, $uid);
         if (!empty($resultsFromFiles)) {
@@ -637,8 +647,8 @@ class ReferenceIndex
             // internal_type file is still a relation of type file and
             // since http://forge.typo3.org/issues/49538 internal_type file_reference
             // is a database relation to a sys_file record
-            $fileResultsFromFiles = array();
-            $dbResultsFromFiles = array();
+            $fileResultsFromFiles = [];
+            $dbResultsFromFiles = [];
             foreach ($resultsFromFiles as $resultFromFiles) {
                 if (isset($resultFromFiles['table']) && $resultFromFiles['table'] === 'sys_file') {
                     $dbResultsFromFiles[] = $resultFromFiles;
@@ -654,7 +664,7 @@ class ReferenceIndex
             }
         }
         // Add a softref definition for link fields if the TCA does not specify one already
-        if ($dsConf['type'] === 'input' && isset($dsConf['wizards']['link']) && empty($dsConf['softref'])) {
+        if ($dsConf['type'] === 'input' && $dsConf['renderType'] === 'inputLink' && empty($dsConf['softref'])) {
             $dsConf['softref'] = 'typolink';
         }
         // Add DB:
@@ -703,7 +713,7 @@ class ReferenceIndex
 
         // Collect file values in array:
         if ($conf['MM']) {
-            $theFileValues = array();
+            $theFileValues = [];
             $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
             $dbAnalysis->start('', 'files', $conf['MM'], $uid);
             foreach ($dbAnalysis->itemArray as $someval) {
@@ -717,15 +727,15 @@ class ReferenceIndex
         // Traverse the files and add them:
         $uploadFolder = $conf['internal_type'] === 'file' ? $conf['uploadfolder'] : '';
         $destinationFolder = $this->destPathFromUploadFolder($uploadFolder);
-        $newValueFiles = array();
+        $newValueFiles = [];
         foreach ($theFileValues as $file) {
             if (trim($file)) {
                 $realFile = $destinationFolder . '/' . trim($file);
-                $newValueFile = array(
+                $newValueFile = [
                     'filename' => basename($file),
                     'ID' => md5($realFile),
                     'ID_absFile' => $realFile
-                );
+                ];
                 // Set sys_file and id for referenced files
                 if ($conf['internal_type'] === 'file_reference') {
                     try {
@@ -733,10 +743,10 @@ class ReferenceIndex
                         if ($file instanceof File || $file instanceof Folder) {
                             // For setting this as sys_file relation later, the keys filename, ID and ID_absFile
                             // have not to be included, because the are not evaluated for db relations.
-                            $newValueFile = array(
+                            $newValueFile = [
                                 'table' => 'sys_file',
                                 'id' => $file->getUid()
-                            );
+                            ];
                         }
                     } catch (\Exception $e) {
                     }
@@ -771,28 +781,11 @@ class ReferenceIndex
         } elseif ($this->isDbReferenceField($conf)) {
             $allowedTables = $conf['type'] === 'group' ? $conf['allowed'] : $conf['foreign_table'];
             if ($conf['MM_opposite_field']) {
-                return array();
+                return [];
             }
             $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
             $dbAnalysis->start($value, $allowedTables, $conf['MM'], $uid, $table, $conf);
             return $dbAnalysis->itemArray;
-        } elseif ($conf['type'] === 'inline' && $conf['foreign_table'] === 'sys_file_reference') {
-            // @todo It looks like this was never called before since isDbReferenceField also checks for type 'inline' and any 'foreign_table'
-            $files = $this->getDatabaseConnection()->exec_SELECTgetRows(
-                'uid_local',
-                'sys_file_reference',
-                'tablenames=\'' . $table . '\' AND fieldname=\'' . $field . '\' AND uid_foreign=' . $uid . ' AND deleted=0'
-            );
-            $fileArray = array();
-            if (!empty($files)) {
-                foreach ($files as $fileUid) {
-                    $fileArray[] = array(
-                        'table' => 'sys_file',
-                        'id' => $fileUid['uid_local']
-                    );
-                }
-            }
-            return $fileArray;
         }
         return false;
     }
@@ -826,10 +819,20 @@ class ReferenceIndex
     {
         $backendUser = $this->getBackendUser();
         if ($backendUser->workspace === 0 && $backendUser->isAdmin() || $bypassWorkspaceAdminCheck) {
-            $databaseConnection = $this->getDatabaseConnection();
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
+            $queryBuilder->getRestrictions()->removeAll();
+
+            // Get current index from Database
+            $referenceRecord = $queryBuilder
+                ->select('*')
+                ->from('sys_refindex')
+                ->where(
+                    $queryBuilder->expr()->eq('hash', $queryBuilder->createNamedParameter($hash, \PDO::PARAM_STR))
+                )
+                ->setMaxResults(1)
+                ->execute()
+                ->fetch();
 
-            // Get current index from Database:
-            $referenceRecord = $databaseConnection->exec_SELECTgetSingleRow('*', 'sys_refindex', 'hash=' . $databaseConnection->fullQuoteStr($hash, 'sys_refindex'));
             // Check if reference existed.
             if (!is_array($referenceRecord)) {
                 return 'ERROR: No reference record with hash="' . $hash . '" was found!';
@@ -839,14 +842,29 @@ class ReferenceIndex
                 return 'ERROR: Table "' . $referenceRecord['tablename'] . '" was not in TCA!';
             }
 
-            // Get that record from database:
-            $record = $databaseConnection->exec_SELECTgetSingleRow('*', $referenceRecord['tablename'], 'uid=' . (int)$referenceRecord['recuid']);
+            // Get that record from database
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                ->getQueryBuilderForTable($referenceRecord['tablename']);
+            $queryBuilder->getRestrictions()->removeAll();
+            $record = $queryBuilder
+                ->select('*')
+                ->from($referenceRecord['tablename'])
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'uid',
+                        $queryBuilder->createNamedParameter($referenceRecord['recuid'], \PDO::PARAM_INT)
+                    )
+                )
+                ->setMaxResults(1)
+                ->execute()
+                ->fetch();
+
             if (is_array($record)) {
                 // Get relation for single field from record
                 $recordRelations = $this->getRelations($referenceRecord['tablename'], $record, $referenceRecord['field']);
                 if ($fieldRelation = $recordRelations[$referenceRecord['field']]) {
                     // Initialize data array that is to be sent to DataHandler afterwards:
-                    $dataArray = array();
+                    $dataArray = [];
                     // Based on type
                     switch ((string)$fieldRelation['type']) {
                         case 'db':
@@ -900,14 +918,13 @@ class ReferenceIndex
                     } else {
                         // Execute CMD array:
                         $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
-                        $dataHandler->stripslashes_values = false;
                         $dataHandler->dontProcessTransformations = true;
                         $dataHandler->bypassWorkspaceRestrictions = true;
                         $dataHandler->bypassFileHandling = true;
                         // Otherwise this cannot update things in deleted records...
                         $dataHandler->bypassAccessCheckForRecords = true;
                         // Check has been done previously that there is a backend user which is Admin and also in live workspace
-                        $dataHandler->start($dataArray, array());
+                        $dataHandler->start($dataArray, []);
                         $dataHandler->process_datamap();
                         // Return errors if any:
                         if (!empty($dataHandler->errorLog)) {
@@ -944,14 +961,14 @@ class ReferenceIndex
                 list($itemArray[$refRec['sorting']]['table'], $itemArray[$refRec['sorting']]['id']) = explode(':', $newValue);
             }
             // Traverse and compile new list of records:
-            $saveValue = array();
+            $saveValue = [];
             foreach ($itemArray as $pair) {
                 $saveValue[] = $pair['table'] . '_' . $pair['id'];
             }
             // Set in data array:
             if ($flexPointer) {
                 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
-                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array();
+                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = [];
                 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'], implode(',', $saveValue));
             } else {
                 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = implode(',', $saveValue);
@@ -985,14 +1002,14 @@ class ReferenceIndex
                 $itemArray[$refRec['sorting']]['filename'] = $newValue;
             }
             // Traverse and compile new list of records:
-            $saveValue = array();
+            $saveValue = [];
             foreach ($itemArray as $fileInfo) {
                 $saveValue[] = $fileInfo['filename'];
             }
             // Set in data array:
             if ($flexPointer) {
                 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
-                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array();
+                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = [];
                 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'], implode(',', $saveValue));
             } else {
                 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = implode(',', $saveValue);
@@ -1032,7 +1049,7 @@ class ReferenceIndex
         if (!strstr($softref['tokenizedContent'], '{softref:')) {
             if ($flexPointer) {
                 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
-                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array();
+                $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = [];
                 $flexFormTools->setArrayValueByPath(substr($flexPointer, 0, -1), $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'], $softref['tokenizedContent']);
             } else {
                 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = $softref['tokenizedContent'];
@@ -1058,13 +1075,13 @@ class ReferenceIndex
      */
     protected function isDbReferenceField(array $configuration)
     {
-        return (
+        return
             ($configuration['type'] === 'group' && $configuration['internal_type'] === 'db')
             || (
                 ($configuration['type'] === 'select' || $configuration['type'] === 'inline')
                 && !empty($configuration['foreign_table'])
             )
-        );
+            ;
     }
 
     /**
@@ -1075,23 +1092,17 @@ class ReferenceIndex
      */
     public function isReferenceField(array $configuration)
     {
-        return (
+        return
             $this->isDbReferenceField($configuration)
             ||
             ($configuration['type'] === 'group' && ($configuration['internal_type'] === 'file' || $configuration['internal_type'] === 'file_reference')) // getRelations_procFiles
             ||
-            ($configuration['type'] === 'input' && isset($configuration['wizards']['link'])) // getRelations_procDB
+            ($configuration['type'] === 'input' && $configuration['renderType'] === 'inputLink') // getRelations_procDB
             ||
             $configuration['type'] === 'flex'
             ||
             isset($configuration['softref'])
-            ||
-            (
-                // @deprecated global soft reference parsers are deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8
-                is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'])
-                && !empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'])
-            )
-        );
+            ;
     }
 
     /**
@@ -1102,18 +1113,18 @@ class ReferenceIndex
      */
     protected function fetchTableRelationFields($tableName)
     {
-        if (!isset($GLOBALS['TCA'][$tableName])) {
+        if (!isset($GLOBALS['TCA'][$tableName]['columns'])) {
             return '';
         }
 
-        $fields = array();
+        $fields = [];
 
         foreach ($GLOBALS['TCA'][$tableName]['columns'] as $field => $fieldDefinition) {
             if (is_array($fieldDefinition['config'])) {
                 // Check for flex field
                 if (isset($fieldDefinition['config']['type']) && $fieldDefinition['config']['type'] === 'flex') {
                     // Fetch all fields if the is a field of type flex in the table definition because the complete row is passed to
-                    // BackendUtility::getFlexFormDS in the end and might be needed in ds_pointerField or $hookObj->getFlexFormDS_postProcessDS
+                    // FlexFormTools->getDataStructureIdentifier() in the end and might be needed in ds_pointerField or a hook
                     return '*';
                 }
                 // Only fetch this field if it can contain a reference
@@ -1141,19 +1152,6 @@ class ReferenceIndex
     }
 
     /**
-     * Sets error message in the internal error log
-     *
-     * @param string $msg Error message
-     * @return void
-     * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
-     */
-    public function error($msg)
-    {
-        GeneralUtility::logDeprecatedFunction();
-        $this->errorLog[] = $msg;
-    }
-
-    /**
      * Updating Index (External API)
      *
      * @param bool $testOnly If set, only a test
@@ -1162,39 +1160,55 @@ class ReferenceIndex
      */
     public function updateIndex($testOnly, $cli_echo = false)
     {
-        $databaseConnection = $this->getDatabaseConnection();
-        $errors = array();
-        $tableNames = array();
+        $errors = [];
+        $tableNames = [];
         $recCount = 0;
         $tableCount = 0;
-        $headerContent = $testOnly ? 'Reference Index being TESTED (nothing written, use "--refindex update" to update)' : 'Reference Index being Updated';
+        $headerContent = $testOnly ? 'Reference Index being TESTED (nothing written, remove the "--check" argument)' : 'Reference Index being Updated';
         if ($cli_echo) {
             echo '*******************************************' . LF . $headerContent . LF . '*******************************************' . LF;
         }
         // Traverse all tables:
+        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+        $refIndexConnectionName = empty($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping']['sys_refindex'])
+                ? ConnectionPool::DEFAULT_CONNECTION_NAME
+                : $GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping']['sys_refindex'];
+
         foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
             if (isset(static::$nonRelationTables[$tableName])) {
                 continue;
             }
-            // Traverse all records in tables, including deleted records:
-            $fieldNames = (BackendUtility::isTableWorkspaceEnabled($tableName) ? 'uid,t3ver_wsid' : 'uid');
-            $res = $databaseConnection->exec_SELECTquery($fieldNames, $tableName, '1=1');
-            if ($databaseConnection->sql_error()) {
+            $tableConnectionName = empty($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName])
+                ? ConnectionPool::DEFAULT_CONNECTION_NAME
+                : $GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName];
+
+            $fields = ['uid'];
+            if (BackendUtility::isTableWorkspaceEnabled($tableName)) {
+                $fields[] = 't3ver_wsid';
+            }
+            // Traverse all records in tables, including deleted records
+            $queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
+            $queryBuilder->getRestrictions()->removeAll();
+            try {
+                $queryResult = $queryBuilder
+                    ->select(...$fields)
+                    ->from($tableName)
+                    ->execute();
+            } catch (DBALException $e) {
                 // Table exists in $TCA but does not exist in the database
+                // @todo: improve / change message and add actual sql error?
                 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);
                 continue;
             }
+
             $tableNames[] = $tableName;
             $tableCount++;
-            $uidList = array(0);
-            while ($record = $databaseConnection->sql_fetch_assoc($res)) {
-                /** @var $refIndexObj ReferenceIndex */
-                $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
+            while ($record = $queryResult->fetch()) {
+                $refIndexObj = GeneralUtility::makeInstance(self::class);
                 if (isset($record['t3ver_wsid'])) {
                     $refIndexObj->setWorkspaceId($record['t3ver_wsid']);
                 }
                 $result = $refIndexObj->updateRefIndexTable($tableName, $record['uid'], $testOnly);
-                $uidList[] = $record['uid'];
                 $recCount++;
                 if ($result['addedNodes'] || $result['deletedNodes']) {
                     $error = 'Record ' . $tableName . ':' . $record['uid'] . ' had ' . $result['addedNodes'] . ' added indexes and ' . $result['deletedNodes'] . ' deleted indexes';
@@ -1204,35 +1218,100 @@ class ReferenceIndex
                     }
                 }
             }
-            $databaseConnection->sql_free_result($res);
-
-            // Searching lost indexes for this table:
-            $where = 'tablename=' . $databaseConnection->fullQuoteStr($tableName, 'sys_refindex') . ' AND recuid NOT IN (' . implode(',', $uidList) . ')';
-            $lostIndexes = $databaseConnection->exec_SELECTgetRows('hash', 'sys_refindex', $where);
-            $lostIndexesCount = count($lostIndexes);
-            if ($lostIndexesCount) {
-                $error = 'Table ' . $tableName . ' has ' . $lostIndexesCount . ' lost indexes which are now deleted';
+
+            // Subselect based queries only work on the same connection
+            if ($refIndexConnectionName !== $tableConnectionName) {
+                GeneralUtility::sysLog(
+                    sprintf(
+                        'Not checking table "%s" for lost indexes, "sys_refindex" table uses a different connection',
+                        $tableName
+                    ),
+                    'core',
+                    GeneralUtility::SYSLOG_SEVERITY_ERROR
+                );
+                continue;
+            }
+
+            // Searching for lost indexes for this table
+            // Build sub-query to find lost records
+            $subQueryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
+            $subQueryBuilder->getRestrictions()->removeAll();
+            $subQueryBuilder
+                ->select('uid')
+                ->from($tableName, 'sub_' . $tableName)
+                ->where(
+                    $subQueryBuilder->expr()->eq(
+                        'sub_' . $tableName . '.uid',
+                        $queryBuilder->quoteIdentifier('sys_refindex.recuid')
+                    )
+                );
+
+            // Main query to find lost records
+            $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_refindex');
+            $queryBuilder->getRestrictions()->removeAll();
+            $lostIndexes = $queryBuilder
+                ->count('hash')
+                ->from('sys_refindex')
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'tablename',
+                        $queryBuilder->createNamedParameter($tableName, \PDO::PARAM_STR)
+                    ),
+                    'NOT EXISTS (' . $subQueryBuilder->getSQL() . ')'
+                )
+                ->execute()
+                ->fetchColumn(0);
+
+            if ($lostIndexes > 0) {
+                $error = 'Table ' . $tableName . ' has ' . $lostIndexes . ' lost indexes which are now deleted';
                 $errors[] = $error;
                 if ($cli_echo) {
                     echo $error . LF;
                 }
                 if (!$testOnly) {
-                    $databaseConnection->exec_DELETEquery('sys_refindex', $where);
+                    $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_refindex');
+                    $queryBuilder->delete('sys_refindex')
+                        ->where(
+                            $queryBuilder->expr()->eq(
+                                'tablename',
+                                $queryBuilder->createNamedParameter($tableName, \PDO::PARAM_STR)
+                            ),
+                            'NOT EXISTS (' . $subQueryBuilder->getSQL() . ')'
+                        )
+                        ->execute();
                 }
             }
         }
-        // Searching lost indexes for non-existing tables:
-        $where = 'tablename NOT IN (' . implode(',', $databaseConnection->fullQuoteArray($tableNames, 'sys_refindex')) . ')';
-        $lostTables = $databaseConnection->exec_SELECTgetRows('hash', 'sys_refindex', $where);
-        $lostTablesCount = count($lostTables);
-        if ($lostTablesCount) {
-            $error = 'Index table hosted ' . $lostTablesCount . ' indexes for non-existing tables, now removed';
+
+        // Searching lost indexes for non-existing tables
+        $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_refindex');
+        $queryBuilder->getRestrictions()->removeAll();
+        $lostTables = $queryBuilder
+            ->count('hash')
+            ->from('sys_refindex')
+            ->where(
+                $queryBuilder->expr()->notIn(
+                    'tablename',
+                    $queryBuilder->createNamedParameter($tableNames, Connection::PARAM_STR_ARRAY)
+                )
+            )->execute()
+            ->fetchColumn(0);
+
+        if ($lostTables > 0) {
+            $error = 'Index table hosted ' . $lostTables . ' indexes for non-existing tables, now removed';
             $errors[] = $error;
             if ($cli_echo) {
                 echo $error . LF;
             }
             if (!$testOnly) {
-                $databaseConnection->exec_DELETEquery('sys_refindex', $where);
+                $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_refindex');
+                $queryBuilder->delete('sys_refindex')
+                    ->where(
+                        $queryBuilder->expr()->notIn(
+                            'tablename',
+                            $queryBuilder->createNamedParameter($tableNames, Connection::PARAM_STR_ARRAY)
+                        )
+                    )->execute();
             }
         }
         $errorCount = count($errors);
@@ -1243,7 +1322,12 @@ class ReferenceIndex
             $recordsCheckedString,
             $errorCount ? FlashMessage::ERROR : FlashMessage::OK
         );
-        $bodyContent = $flashMessage->render();
+        /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
+        $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
+        /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
+        $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
+        $defaultFlashMessageQueue->enqueue($flashMessage);
+        $bodyContent = $defaultFlashMessageQueue->renderFlashMessages();
         if ($cli_echo) {
             echo $recordsCheckedString . ($errorCount ? 'Updates: ' . $errorCount : 'Index Integrity was perfect!') . LF;
         }
@@ -1251,17 +1335,7 @@ class ReferenceIndex
             $registry = GeneralUtility::makeInstance(Registry::class);
             $registry->set('core', 'sys_refindex_lastUpdate', $GLOBALS['EXEC_TIME']);
         }
-        return array($headerContent, $bodyContent, $errorCount);
-    }
-
-    /**
-     * Return DatabaseConnection
-     *
-     * @return \TYPO3\CMS\Core\Database\DatabaseConnection
-     */
-    protected function getDatabaseConnection()
-    {
-        return $GLOBALS['TYPO3_DB'];
+        return [$headerContent, $bodyContent, $errorCount];
     }
 
     /**