/**
  * Performs the database update.
  *
  * @param array $dbQueries queries done in this update
  * @param mixed $customMessages custom messages
  * @return boolean TRUE on success, FALSE on error
  */
 public function performUpdate(array &$dbQueries, &$customMessages)
 {
     $this->init();
     if (!PATH_site) {
         throw new \Exception('PATH_site was undefined.');
     }
     $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/');
     $targetDirectory = '/_migrated/RTE/';
     $fullTargetDirectory = PATH_site . $fileadminDirectory . $targetDirectory;
     // Create the directory, if necessary
     if (!is_dir($fullTargetDirectory)) {
         \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($fullTargetDirectory);
     }
     $oldRecords = $this->findMagicImagesInOldLocation();
     foreach ($oldRecords as $refRecord) {
         // Is usually uploads/RTE_magicC_123423324.png.png
         $sourceFileName = $refRecord['ref_string'];
         // Absolute path/filename
         $fullSourceFileName = PATH_site . $refRecord['ref_string'];
         $targetFileName = $targetDirectory . \TYPO3\CMS\Core\Utility\PathUtility::basename($refRecord['ref_string']);
         // Full directory
         $fullTargetFileName = $fullTargetDirectory . \TYPO3\CMS\Core\Utility\PathUtility::basename($refRecord['ref_string']);
         // maybe the file has been moved previously
         if (!file_exists($fullTargetFileName)) {
             // 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.
             if (!file_exists(PATH_site . $sourceFileName)) {
                 $this->logger->notice('File ' . $sourceFileName . ' does not exist. Reference was not migrated.', array());
                 $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
                 $message = sprintf($format, $sourceFileName, $refRecord['tablename'], $refRecord['recuid'], $refRecord['field']);
                 $customMessages .= PHP_EOL . $message;
                 continue;
             }
             rename($fullSourceFileName, $fullTargetFileName);
         }
         // Get the File object
         $file = $this->storage->getFile($targetFileName);
         if ($file instanceof \TYPO3\CMS\Core\Resource\File) {
             // And now update the referencing field
             $targetFieldName = $refRecord['field'];
             $targetRecord = $this->db->exec_SELECTgetSingleRow('uid, ' . $targetFieldName, $refRecord['tablename'], 'uid=' . (int) $refRecord['recuid']);
             if ($targetRecord) {
                 // Replace the old filename with the new one, and add data-* attributes used by the RTE
                 $searchString = 'src="' . $sourceFileName . '"';
                 $replacementString = 'src="' . $fileadminDirectory . $targetFileName . '"';
                 $replacementString .= ' data-htmlarea-file-uid="' . $file->getUid() . '"';
                 $replacementString .= ' data-htmlarea-file-table="sys_file"';
                 $targetRecord[$targetFieldName] = str_replace($searchString, $replacementString, $targetRecord[$targetFieldName]);
                 // Update the record
                 $this->db->exec_UPDATEquery($refRecord['tablename'], 'uid=' . (int) $refRecord['recuid'], array($targetFieldName => $targetRecord[$targetFieldName]));
                 $queries[] = str_replace(LF, ' ', $this->db->debug_lastBuiltQuery);
                 // Finally, update the sys_refindex table as well
                 $this->db->exec_UPDATEquery('sys_refindex', 'hash=' . $this->db->fullQuoteStr($refRecord['hash'], 'sys_refindex'), array('ref_table' => 'sys_file', 'softref_key' => 'rtehtmlarea_images', 'ref_uid' => $file->getUid(), 'ref_string' => $fileadminDirectory . $targetFileName));
                 $queries[] = str_replace(LF, ' ', $this->db->debug_lastBuiltQuery);
             }
         }
     }
     return TRUE;
 }
 /**
  * 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;
 }
Example #3
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]++;
     }
 }