/**
  * @throws \PHPUnit_Framework_Exception
  */
 protected function setUp()
 {
     $this->storageMock = $this->getMock(ResourceStorage::class, array(), array(), '', FALSE);
     $this->storageMock->expects($this->any())->method('getUid')->will($this->returnValue(5));
     $this->folderMock = $this->getMock(Folder::class, array(), array(), '', FALSE);
     $this->folderMock->expects($this->any())->method('getStorage')->willReturn($this->storageMock);
     $this->storageMock->expects($this->any())->method('getProcessingFolder')->willReturn($this->folderMock);
     $this->databaseRow = array('uid' => '1234567', 'identifier' => 'dummy.txt', 'name' => $this->getUniqueId('dummy_'), 'storage' => $this->storageMock->getUid());
 }
Beispiel #2
0
 /**
  * Return duplicates file records
  *
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storage
  * @return array
  */
 public function searchForDuplicateSha1(ResourceStorage $storage)
 {
     // Detect duplicate records.
     $query = "SELECT sha1 FROM sys_file WHERE storage = {$storage->getUid()} GROUP BY sha1, storage Having COUNT(*) > 1";
     $resource = $this->getDatabaseConnection()->sql_query($query);
     $duplicates = array();
     while ($row = $this->getDatabaseConnection()->sql_fetch_assoc($resource)) {
         $clause = sprintf('sha1 = "%s" AND storage = %s', $row['sha1'], $storage->getUid());
         $records = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'sys_file', $clause);
         $duplicates[$row['sha1']] = $records;
     }
     return $duplicates;
 }
    /**
     * Processes the actual transformation from CSV to sys_file_references
     *
     * @param array $record
     * @return void
     */
    protected function migrateRecord(array $record)
    {
        $collections = array();
        if (trim($record['select_key'])) {
            $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_file_collection', array('pid' => $record['pid'], 'title' => $record['select_key'], 'storage' => $this->storage->getUid(), 'folder' => ltrim('fileadmin/', $record['select_key'])));
            $collections[] = $GLOBALS['TYPO3_DB']->sql_insert_id();
        }
        $files = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $record['media'], TRUE);
        $descriptions = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('
', $record['imagecaption']);
        $titleText = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('
', $record['titleText']);
        $i = 0;
        foreach ($files as $file) {
            if (file_exists(PATH_site . 'uploads/media/' . $file)) {
                \TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move(PATH_site . 'uploads/media/' . $file, $this->targetDirectory . $file);
                $fileObject = $this->storage->getFile(self::FOLDER_ContentUploads . '/' . $file);
                $this->fileRepository->addToIndex($fileObject);
                $dataArray = array('uid_local' => $fileObject->getUid(), 'tablenames' => 'tt_content', 'uid_foreign' => $record['uid'], 'fieldname' => 'media', 'sorting_foreign' => $i);
                if (isset($descriptions[$i])) {
                    $dataArray['description'] = $descriptions[$i];
                }
                if (isset($titleText[$i])) {
                    $dataArray['alternative'] = $titleText[$i];
                }
                $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_file_reference', $dataArray);
                unlink(PATH_site . 'uploads/media/' . $file);
            }
            $i++;
        }
        $this->cleanRecord($record, $i, $collections);
    }
 /**
  * Relative filemounts are transformed to relate to our fileadmin/ storage
  * and their path is modified to be a valid resource location
  */
 protected function migrateRelativeFilemounts()
 {
     $relativeFilemounts = $this->db->exec_SELECTgetRows('*', 'sys_filemounts', 'base = 1' . \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause('sys_filemounts'));
     foreach ($relativeFilemounts as $filemount) {
         $this->db->exec_UPDATEquery('sys_filemounts', 'uid=' . intval($filemount['uid']), array('base' => $this->storage->getUid(), 'path' => '/' . ltrim($filemount['path'], '/')));
         $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;
     }
 }
Beispiel #5
0
 /**
  * @return int
  */
 public function getTotalNumberOfFiles()
 {
     $clause = 'storage > 0';
     if ($this->storage) {
         $clause = 'storage = ' . $this->storage->getUid();
     }
     $record = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('count(*) AS totalNumberOfFiles', 'sys_file', $clause);
     return (int) $record['totalNumberOfFiles'];
 }
 /**
  * @param ResourceStorage $storage
  * @param string $identifier
  *
  * @return null|ProcessedFile
  */
 public function findByStorageAndIdentifier(ResourceStorage $storage, $identifier)
 {
     $processedFileObject = null;
     if ($storage->hasFile($identifier)) {
         $databaseRow = $this->databaseConnection->exec_SELECTgetSingleRow('*', $this->table, 'storage = ' . (int) $storage->getUid() . ' AND identifier = ' . $this->databaseConnection->fullQuoteStr($identifier, $this->table));
         if ($databaseRow) {
             $processedFileObject = $this->createDomainObject($databaseRow);
         }
     }
     return $processedFileObject;
 }
Beispiel #7
0
 /**
  * @param ResourceStorage $storage
  * @param string $identifier
  *
  * @return null|ProcessedFile
  */
 public function findByStorageAndIdentifier(ResourceStorage $storage, $identifier)
 {
     $processedFileObject = null;
     if ($storage->hasFile($identifier)) {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
         $databaseRow = $queryBuilder->select('*')->from($this->table)->where($queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storage->getUid(), \PDO::PARAM_INT)), $queryBuilder->expr()->eq('identifier', $queryBuilder->createNamedParameter($identifier, \PDO::PARAM_STR)))->execute()->fetch();
         if ($databaseRow) {
             $processedFileObject = $this->createDomainObject($databaseRow);
         }
     }
     return $processedFileObject;
 }
Beispiel #8
0
 /**
  * Adds file mounts from the user's file mount records
  *
  * @param ResourceStorage $storage
  * @return void
  */
 protected function addFileMountsToStorage(ResourceStorage $storage)
 {
     foreach ($this->backendUserAuthentication->getFileMountRecords() as $fileMountRow) {
         if ((int) $fileMountRow['base'] === (int) $storage->getUid()) {
             try {
                 $storage->addFileMount($fileMountRow['path'], $fileMountRow);
             } catch (FolderDoesNotExistException $e) {
                 // That file mount does not seem to be valid, fail silently
             }
         }
     }
 }
 /**
  * Relative filemounts are transformed to relate to our fileadmin/ storage
  * and their path is modified to be a valid resource location
  *
  * @return void
  */
 protected function migrateRelativeFilemounts()
 {
     $relativeFilemounts = $this->db->exec_SELECTgetRows('*', 'sys_filemounts', 'base = 1' . BackendUtility::deleteClause('sys_filemounts'));
     foreach ($relativeFilemounts as $filemount) {
         $storagePath = trim($filemount['path'], '/') . '/';
         if ($storagePath !== '/') {
             $storagePath = '/' . $storagePath;
         }
         $this->db->exec_UPDATEquery('sys_filemounts', 'uid=' . (int) $filemount['uid'], array('base' => $this->storage->getUid(), 'path' => $storagePath));
         $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;
     }
 }
Beispiel #10
0
 /**
  * Adds updated files to the processing queue
  *
  * @param array $fileIdentifierArray
  * @return void
  */
 protected function detectChangedFilesInStorage(array $fileIdentifierArray)
 {
     foreach ($fileIdentifierArray as $fileIdentifier) {
         // skip processed files
         if ($this->storage->isWithinProcessingFolder($fileIdentifier)) {
             continue;
         }
         // Get the modification time for file-identifier from the storage
         $modificationTime = $this->storage->getFileInfoByIdentifier($fileIdentifier, array('mtime'));
         // Look if the the modification time in FS is higher than the one in database (key needed on timestamps)
         $indexRecord = $this->getFileIndexRepository()->findOneByStorageUidAndIdentifier($this->storage->getUid(), $fileIdentifier);
         if ($indexRecord !== FALSE) {
             $this->identifiedFileUids[] = $indexRecord['uid'];
             if ($indexRecord['modification_date'] < $modificationTime['mtime'] || $indexRecord['missing']) {
                 $this->filesToUpdate[$fileIdentifier] = $indexRecord;
             }
         } else {
             $this->filesToUpdate[$fileIdentifier] = NULL;
         }
     }
 }
 /**
  * Updates the properties of a file object with some that are freshly
  * fetched from the driver.
  *
  * @param \TYPO3\CMS\Core\Resource\AbstractFile $file
  * @param string $identifier The identifier of the file. If set, this will overwrite the file object's identifier (use e.g. after moving a file)
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storage
  * @return void
  */
 protected function updateFile(\TYPO3\CMS\Core\Resource\AbstractFile $file, $identifier = '', $storage = NULL)
 {
     if ($identifier === '') {
         $identifier = $file->getIdentifier();
     }
     $fileInfo = $this->driver->getFileInfoByIdentifier($identifier);
     // TODO extend mapping
     $newProperties = array('storage' => $fileInfo['storage'], 'identifier' => $fileInfo['identifier'], 'tstamp' => $fileInfo['mtime'], 'crdate' => $fileInfo['ctime'], 'mime_type' => $fileInfo['mimetype'], 'size' => $fileInfo['size'], 'name' => $fileInfo['name']);
     if ($storage !== NULL) {
         $newProperties['storage'] = $storage->getUid();
     }
     $file->updateProperties($newProperties);
     /** @var $fileRepository \TYPO3\CMS\Core\Resource\FileRepository */
     $fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
     $fileRepository->update($file);
 }
 /**
  * Gets the file permissions for a storage
  * by merging any storage-specific permissions for a
  * storage with the default settings.
  * Admin users will always get the default settings.
  *
  * @api
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
  * @return array
  */
 public function getFilePermissionsForStorage(\TYPO3\CMS\Core\Resource\ResourceStorage $storageObject)
 {
     $finalUserPermissions = $this->getFilePermissions();
     if (!$this->isAdmin()) {
         $storageFilePermissions = $this->getTSConfigProp('permissions.file.storage.' . $storageObject->getUid());
         if (!empty($storageFilePermissions)) {
             array_walk($storageFilePermissions, function ($value, $permission) use(&$finalUserPermissions) {
                 $finalUserPermissions[$permission] = (bool) $value;
             });
         }
     }
     return $finalUserPermissions;
 }
Beispiel #13
0
 /**
  * Helper method to map md5-hash to shorter number
  *
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
  * @param \TYPO3\CMS\Core\Resource\Folder $startingPointFolder
  * @return int
  */
 protected function getShortHashNumberForStorage(\TYPO3\CMS\Core\Resource\ResourceStorage $storageObject = NULL, \TYPO3\CMS\Core\Resource\Folder $startingPointFolder = NULL)
 {
     if (!$this->storageHashNumbers) {
         $this->storageHashNumbers = array();
         // Mapping md5-hash to shorter number:
         $hashMap = array();
         foreach ($this->storages as $storageUid => $storage) {
             $fileMounts = $storage->getFileMounts();
             if (count($fileMounts)) {
                 foreach ($fileMounts as $fileMount) {
                     $nkey = hexdec(substr(GeneralUtility::md5int($fileMount['folder']->getCombinedIdentifier()), 0, 4));
                     $this->storageHashNumbers[$storageUid . $fileMount['folder']->getCombinedIdentifier()] = $nkey;
                 }
             } else {
                 $folder = $storage->getRootLevelFolder();
                 $nkey = hexdec(substr(GeneralUtility::md5int($folder->getCombinedIdentifier()), 0, 4));
                 $this->storageHashNumbers[$storageUid . $folder->getCombinedIdentifier()] = $nkey;
             }
         }
     }
     if ($storageObject) {
         if ($startingPointFolder) {
             return $this->storageHashNumbers[$storageObject->getUid() . $startingPointFolder->getCombinedIdentifier()];
         } else {
             return $this->storageHashNumbers[$storageObject->getUid()];
         }
     } else {
         return NULL;
     }
 }
Beispiel #14
0
 /**
  * Helper method to map md5-hash to shorter number
  *
  * @param ResourceStorage $storageObject
  * @param Folder $startingPointFolder
  *
  * @return int
  */
 protected function getShortHashNumberForStorage(ResourceStorage $storageObject = null, Folder $startingPointFolder = null)
 {
     if (!$this->storageHashNumbers) {
         $this->storageHashNumbers = [];
         foreach ($this->storages as $storageUid => $storage) {
             $fileMounts = $storage->getFileMounts();
             if (!empty($fileMounts)) {
                 foreach ($fileMounts as $fileMount) {
                     $nkey = hexdec(substr(GeneralUtility::md5int($fileMount['folder']->getCombinedIdentifier()), 0, 4));
                     $this->storageHashNumbers[$storageUid . $fileMount['folder']->getCombinedIdentifier()] = $nkey;
                 }
             } else {
                 $folder = $storage->getRootLevelFolder();
                 $nkey = hexdec(substr(GeneralUtility::md5int($folder->getCombinedIdentifier()), 0, 4));
                 $this->storageHashNumbers[$storageUid . $folder->getCombinedIdentifier()] = $nkey;
             }
         }
     }
     if ($storageObject) {
         if ($startingPointFolder) {
             return $this->storageHashNumbers[$storageObject->getUid() . $startingPointFolder->getCombinedIdentifier()];
         } else {
             return $this->storageHashNumbers[$storageObject->getUid()];
         }
     } else {
         return null;
     }
 }
 /**
  * Helper function for the Indexer to detect missing files
  *
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storage
  * @param array $uidList
  * @return array
  */
 public function findInStorageAndNotInUidList(\TYPO3\CMS\Core\Resource\ResourceStorage $storage, array $uidList)
 {
     $where = 'storage = ' . (int) $storage->getUid();
     if (!empty($uidList)) {
         $where .= ' AND uid NOT IN (' . implode(',', $this->getDatabaseConnection()->cleanIntArray($uidList)) . ')';
     }
     return $this->getDatabaseConnection()->exec_SELECTgetRows(implode(',', $this->fields), $this->table, $where);
 }
 /**
  * Creates file identifier hashes for a single storage.
  *
  * @param ResourceStorage $storage The storage to update
  * @return array The executed database queries
  */
 protected function updateIdentifierHashesForStorage(ResourceStorage $storage)
 {
     $queries = array();
     if (!ExtensionManagementUtility::isLoaded('dbal')) {
         // if DBAL is not loaded, we're using MySQL and can thus use their
         // SHA1() function
         if ($storage->usesCaseSensitiveIdentifiers()) {
             $updateCall = 'SHA1(identifier)';
         } else {
             $updateCall = 'SHA1(LOWER(identifier))';
         }
         $queries[] = $query = sprintf('UPDATE sys_file SET identifier_hash = %s WHERE storage=%d', $updateCall, $storage->getUid());
         $this->db->sql_query($query);
         // folder hashes cannot be done with one call: so do it manually
         $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file', sprintf('storage=%d AND folder_hash=""', $storage->getUid()));
         foreach ($files as $file) {
             $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier']));
             $queries[] = $query = $this->db->UPDATEquery('sys_file', 'uid=' . $file['uid'], array('folder_hash' => $folderHash));
             $this->db->sql_query($query);
         }
     } else {
         // manually hash the identifiers when using DBAL
         $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file', sprintf('storage=%d AND identifier_hash=""', $storage->getUid()));
         foreach ($files as $file) {
             $hash = $storage->hashFileIdentifier($file['identifier']);
             $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier']));
             $queries[] = $query = $this->db->UPDATEquery('sys_file', 'uid=' . $file['uid'], array('identifier_hash' => $hash, 'folder_hash' => $folderHash));
             $this->db->sql_query($query);
         }
     }
     return $queries;
 }
 /**
  * Migrates a single field.
  *
  * @param string $table
  * @param array $row
  * @param string $fieldname
  * @param array $fieldConfiguration
  * @param string $customMessages
  * @return array A list of performed database queries
  * @throws \Exception
  */
 protected function migrateField($table, $row, $fieldname, $fieldConfiguration, &$customMessages)
 {
     $titleTextContents = [];
     $alternativeTextContents = [];
     $captionContents = [];
     $linkContents = [];
     $fieldItems = GeneralUtility::trimExplode(',', $row[$fieldname], true);
     if (empty($fieldItems) || is_numeric($row[$fieldname])) {
         return [];
     }
     if (isset($fieldConfiguration['titleTexts'])) {
         $titleTextField = $fieldConfiguration['titleTexts'];
         $titleTextContents = explode(LF, $row[$titleTextField]);
     }
     if (isset($fieldConfiguration['alternativeTexts'])) {
         $alternativeTextField = $fieldConfiguration['alternativeTexts'];
         $alternativeTextContents = explode(LF, $row[$alternativeTextField]);
     }
     if (isset($fieldConfiguration['captions'])) {
         $captionField = $fieldConfiguration['captions'];
         $captionContents = explode(LF, $row[$captionField]);
     }
     if (isset($fieldConfiguration['links'])) {
         $linkField = $fieldConfiguration['links'];
         $linkContents = explode(LF, $row[$linkField]);
     }
     $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/';
     $queries = [];
     $i = 0;
     if (!PATH_site) {
         throw new \Exception('PATH_site was undefined.');
     }
     $storageUid = (int) $this->storage->getUid();
     foreach ($fieldItems as $item) {
         $fileUid = null;
         $sourcePath = PATH_site . $fieldConfiguration['sourcePath'] . $item;
         $targetDirectory = PATH_site . $fileadminDirectory . $fieldConfiguration['targetPath'];
         $targetPath = $targetDirectory . basename($item);
         // maybe the file was already moved, so check if the original file still exists
         if (file_exists($sourcePath)) {
             if (!is_dir($targetDirectory)) {
                 GeneralUtility::mkdir_deep($targetDirectory);
             }
             // see if the file already exists in the storage
             $fileSha1 = sha1_file($sourcePath);
             $existingFileRecord = $this->database->exec_SELECTgetSingleRow('uid', 'sys_file', 'sha1=' . $this->database->fullQuoteStr($fileSha1, 'sys_file') . ' AND storage=' . $storageUid);
             // the file exists, the file does not have to be moved again
             if (is_array($existingFileRecord)) {
                 $fileUid = $existingFileRecord['uid'];
             } else {
                 // just move the file (no duplicate)
                 rename($sourcePath, $targetPath);
             }
         }
         if ($fileUid === null) {
             // get the File object if it hasn't been fetched before
             try {
                 // if the source file does not exist, we should just continue, but leave a message in the docs;
                 // ideally, the user would be informed after the update as well.
                 /** @var File $file */
                 $file = $this->storage->getFile($fieldConfiguration['targetPath'] . $item);
                 $fileUid = $file->getUid();
             } catch (\InvalidArgumentException $e) {
                 // no file found, no reference can be set
                 $this->logger->notice('File ' . $fieldConfiguration['sourcePath'] . $item . ' does not exist. Reference was not migrated.', ['table' => $table, 'record' => $row, 'field' => $fieldname]);
                 $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
                 $message = sprintf($format, $fieldConfiguration['sourcePath'] . $item, $table, $row['uid'], $fieldname);
                 $customMessages .= PHP_EOL . $message;
                 continue;
             }
         }
         if ($fileUid > 0) {
             $fields = ['fieldname' => $fieldname, 'table_local' => 'sys_file', 'pid' => $table === 'pages' ? $row['uid'] : $row['pid'], 'uid_foreign' => $row['uid'], 'uid_local' => $fileUid, 'tablenames' => $table, 'crdate' => time(), 'tstamp' => time(), 'sorting' => $i + 256, 'sorting_foreign' => $i];
             if (isset($titleTextField)) {
                 $fields['title'] = trim($titleTextContents[$i]);
             }
             if (isset($alternativeTextField)) {
                 $fields['alternative'] = trim($alternativeTextContents[$i]);
             }
             if (isset($captionField)) {
                 $fields['description'] = trim($captionContents[$i]);
             }
             if (isset($linkField)) {
                 $fields['link'] = trim($linkContents[$i]);
             }
             $this->database->exec_INSERTquery('sys_file_reference', $fields);
             $queries[] = str_replace(LF, ' ', $this->database->debug_lastBuiltQuery);
             ++$i;
         }
     }
     // Update referencing table's original field to now contain the count of references,
     // but only if all new references could be set
     if ($i === count($fieldItems)) {
         $this->database->exec_UPDATEquery($table, 'uid=' . $row['uid'], [$fieldname => $i]);
         $queries[] = str_replace(LF, ' ', $this->database->debug_lastBuiltQuery);
     } else {
         $this->recordOffset[$table]++;
     }
     return $queries;
 }
 /**
  * Gets the file permissions for a storage
  * by merging any storage-specific permissions for a
  * storage with the default settings
  *
  * @api
  * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
  * @return array
  */
 public function getFilePermissionsForStorage(\TYPO3\CMS\Core\Resource\ResourceStorage $storageObject)
 {
     $defaultFilePermissions = $this->getFilePermissions();
     $storageFilePermissions = $this->getTSConfig('permissions.file.storage.' . $storageObject->getUid());
     if (is_array($storageFilePermissions) && count($storageFilePermissions)) {
         return array_merge($storageFilePermissions, $defaultFilePermissions);
     } else {
         return $defaultFilePermissions;
     }
 }
 /**
  * Sets the storage this file is located in. This is only meant for
  * \TYPO3\CMS\Core\Resource-internal usage; don't use it to move files.
  *
  * @internal Should only be used by other parts of the File API (e.g. drivers after moving a file)
  * @param ResourceStorage $storage
  * @return File
  */
 public function setStorage(ResourceStorage $storage)
 {
     $this->storage = $storage;
     $this->properties['storage'] = $storage->getUid();
     return $this;
 }
Beispiel #20
0
 /**
  * Creates a file object from an array of file data. Requires a database
  * row to be fetched.
  *
  * @param array $fileData
  * @param ResourceStorage $storage
  * @return File
  */
 public function createFileObject(array $fileData, ResourceStorage $storage = NULL)
 {
     /** @var File $fileObject */
     if (array_key_exists('storage', $fileData) && MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
         $storageObject = $this->getStorageObject((int) $fileData['storage']);
     } elseif ($storage !== NULL) {
         $storageObject = $storage;
         $fileData['storage'] = $storage->getUid();
     } else {
         throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
     }
     $fileObject = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\File', $fileData, $storageObject);
     return $fileObject;
 }
Beispiel #21
0
 /**
  * Migrates a single field.
  *
  * @param array $row
  * @param string $customMessages
  * @param array $dbQueries
  *
  * @throws \Exception
  */
 protected function migrateField($row, &$customMessages, &$dbQueries)
 {
     $fieldItems = GeneralUtility::trimExplode(',', $row[$this->fieldToMigrate], true);
     if (empty($fieldItems) || is_numeric($row[$this->fieldToMigrate])) {
         return;
     }
     $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/';
     $i = 0;
     if (!PATH_site) {
         throw new \Exception('PATH_site was undefined.', 1476107387);
     }
     $storageUid = (int) $this->storage->getUid();
     $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
     foreach ($fieldItems as $item) {
         $fileUid = null;
         $sourcePath = PATH_site . $this->sourcePath . $item;
         $targetDirectory = PATH_site . $fileadminDirectory . $this->targetPath;
         $targetPath = $targetDirectory . basename($item);
         // maybe the file was already moved, so check if the original file still exists
         if (file_exists($sourcePath)) {
             if (!is_dir($targetDirectory)) {
                 GeneralUtility::mkdir_deep($targetDirectory);
             }
             // see if the file already exists in the storage
             $fileSha1 = sha1_file($sourcePath);
             $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file');
             $queryBuilder->getRestrictions()->removeAll();
             $existingFileRecord = $queryBuilder->select('uid')->from('sys_file')->where($queryBuilder->expr()->eq('sha1', $queryBuilder->createNamedParameter($fileSha1, \PDO::PARAM_STR)), $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storageUid, \PDO::PARAM_INT)))->execute()->fetch();
             // the file exists, the file does not have to be moved again
             if (is_array($existingFileRecord)) {
                 $fileUid = $existingFileRecord['uid'];
             } else {
                 // just move the file (no duplicate)
                 rename($sourcePath, $targetPath);
             }
         }
         if ($fileUid === null) {
             // get the File object if it hasn't been fetched before
             try {
                 // if the source file does not exist, we should just continue, but leave a message in the docs;
                 // ideally, the user would be informed after the update as well.
                 $file = $this->storage->getFile($this->targetPath . $item);
                 $fileUid = $file->getUid();
             } catch (\InvalidArgumentException $e) {
                 // no file found, no reference can be set
                 $this->logger->notice('File ' . $this->sourcePath . $item . ' does not exist. Reference was not migrated.', ['table' => $this->table, 'record' => $row, 'field' => $this->fieldToMigrate]);
                 $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
                 $message = sprintf($format, $this->sourcePath . $item, $this->table, $row['uid'], $this->fieldToMigrate);
                 $customMessages .= PHP_EOL . $message;
                 continue;
             }
         }
         if ($fileUid > 0) {
             $fields = ['fieldname' => $this->fieldToMigrate, 'table_local' => 'sys_file', 'pid' => $this->table === 'pages' ? $row['uid'] : $row['pid'], 'uid_foreign' => $row['uid'], 'uid_local' => $fileUid, 'tablenames' => $this->table, 'crdate' => time(), 'tstamp' => time(), 'sorting' => $i + 256, 'sorting_foreign' => $i];
             $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file_reference');
             $queryBuilder->insert('sys_file_reference')->values($fields)->execute();
             $dbQueries[] = str_replace(LF, ' ', $queryBuilder->getSQL());
             ++$i;
         }
     }
     // Update referencing table's original field to now contain the count of references,
     // but only if all new references could be set
     if ($i === count($fieldItems)) {
         $queryBuilder = $connectionPool->getQueryBuilderForTable($this->table);
         $queryBuilder->update($this->table)->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($row['uid'], \PDO::PARAM_INT)))->set($this->fieldToMigrate, $i)->execute();
         $dbQueries[] = str_replace(LF, ' ', $queryBuilder->getSQL());
     } else {
         $this->recordOffset[$this->table]++;
     }
 }