118 public function init()
121 $this->mode =
'import';
134 $this->doesImport = 1;
137 $this->import_mapId = [];
138 $this->import_newId = [];
139 $this->import_newId_pids = [];
141 $this->unlinkFiles = [];
142 $this->alternativeFileName = [];
143 $this->alternativeFilePath = [];
154 $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
155 $this->storageObjects = $storageRepository->findAll();
191 if (!isset($this->dat[
'header'][
'records'][
'sys_file_storage'])) {
194 $sysFileStorageUidsToBeResetToDefaultStorage = [];
195 foreach ($this->dat[
'header'][
'records'][
'sys_file_storage'] as $sysFileStorageUid => $_) {
196 $storageRecord = $this->dat[
'records'][
'sys_file_storage:' . $sysFileStorageUid][
'data'];
198 if ($storageRecord[
'driver'] ===
'Local' && $storageRecord[
'is_writable'] && $storageRecord[
'is_online']) {
199 foreach ($this->storageObjects as $localStorage) {
201 $this->import_mapId[
'sys_file_storage'][$sysFileStorageUid] = $localStorage->getUid();
206 if (!isset($this->import_mapId[
'sys_file_storage'][$sysFileStorageUid])) {
209 $this->
addSingle(
'sys_file_storage', $sysFileStorageUid, 0);
216 $this->
addSingle(
'sys_file_storage', $sysFileStorageUid, 0);
217 $sysFileStorageUidsToBeResetToDefaultStorage[] = $sysFileStorageUid;
224 $tce->reverseOrder = 1;
225 $tce->isImporting =
true;
226 $tce->start($this->import_data, []);
227 $tce->process_datamap();
230 $defaultStorageUid =
null;
233 if ($defaultStorage !==
null) {
234 $defaultStorageUid = $defaultStorage->
getUid();
236 foreach ($sysFileStorageUidsToBeResetToDefaultStorage as $sysFileStorageUidToBeResetToDefaultStorage) {
237 $this->import_mapId[
'sys_file_storage'][$sysFileStorageUidToBeResetToDefaultStorage] = $defaultStorageUid;
241 unset($this->dat[
'header'][
'records'][
'sys_file_storage']);
256 && (
bool)$storageObject->
isWritable() === (
bool)$storageRecord[
'is_writable']
257 && (
bool)$storageObject->
isOnline() === (
bool)$storageRecord[
'is_online']
262 if ($storageRecordConfiguration[
'pathType'] === $storageObjectConfiguration[
'pathType']
263 && $storageRecordConfiguration[
'basePath'] === $storageObjectConfiguration[
'basePath']
281 $extKeysToInstall = [];
282 foreach ($this->dat[
'header'][
'extensionDependencies'] as $extKey) {
284 $extKeysToInstall[] = $extKey;
287 if (!empty($extKeysToInstall)) {
288 $messages[
'missingExtensions'] =
'Before you can install this T3D file you need to install the extensions "'
289 . implode(
'", "', $extKeysToInstall) .
'".';
294 if (!empty($this->dat[
'header'][
'records'][
'sys_file_storage'])) {
295 foreach ($this->dat[
'header'][
'records'][
'sys_file_storage'] as $sysFileStorageUid => $_) {
296 $storageRecord = $this->dat[
'records'][
'sys_file_storage:' . $sysFileStorageUid][
'data'];
298 if ($storageRecord[
'driver'] ===
'Local'
299 && $storageRecord[
'is_writable']
300 && $storageRecord[
'is_online']
302 foreach ($this->storageObjects as $localStorage) {
312 $storageRecordUid = $storageRecord[
'uid'];
317 $storageRecord[
'uid'] = 0;
319 if (!$resourceStorage->isOnline()) {
321 $messages[
'resourceStorageFolderMissing_' . $storageRecordUid] =
322 'The resource storage "'
323 . $resourceStorage->getName()
324 . $configuration[
'basePath']
325 .
'" does not exist. Please create the directory prior to starting the import!';
340 if (!isset($this->dat[
'header'][
'records'][
'sys_file'])) {
350 $sanitizedFolderMappings = [];
352 foreach ($this->dat[
'header'][
'records'][
'sys_file'] as $sysFileUid => $_) {
353 $fileRecord = $this->dat[
'records'][
'sys_file:' . $sysFileUid][
'data'];
355 $temporaryFile =
null;
357 if ($this->filesPathForImport !==
null) {
358 if (is_file($this->filesPathForImport .
'/' . $fileRecord[
'sha1']) && sha1_file($this->filesPathForImport .
'/' . $fileRecord[
'sha1']) === $fileRecord[
'sha1']) {
359 $temporaryFile = $this->filesPathForImport .
'/' . $fileRecord[
'sha1'];
364 if ($temporaryFile ===
null) {
365 $fileId = md5($fileRecord[
'storage'] .
':' . $fileRecord[
'identifier_hash']);
367 if ($temporaryFile ===
null) {
373 $originalStorageUid = $fileRecord[
'storage'];
374 $useStorageFromStorageRecords =
false;
377 if (isset($this->import_mapId[
'sys_file_storage'][$fileRecord[
'storage']])) {
378 $fileRecord[
'storage'] = $this->import_mapId[
'sys_file_storage'][$fileRecord[
'storage']];
379 $useStorageFromStorageRecords =
true;
382 if (empty($fileRecord[
'storage']) && !$this->
isFallbackStorage($fileRecord[
'storage'])) {
384 $this->
error(
'Error: No storage for the file "' . $fileRecord[
'identifier'] .
'" with storage uid "' . $originalStorageUid .
'"');
390 if ($useStorageFromStorageRecords && isset($storageRecords[$fileRecord[
'storage']])) {
395 } elseif ($defaultStorage !==
null) {
396 $storage = $defaultStorage;
398 $this->
error(
'Error: No storage available for the file "' . $fileRecord[
'identifier'] .
'" with storage uid "' . $fileRecord[
'storage'] .
'"');
406 if ($storage->hasFile($fileRecord[
'identifier'])) {
407 $file = $storage->getFile($fileRecord[
'identifier']);
408 if ($file->getSha1() === $fileRecord[
'sha1']) {
412 }
catch (Exception $e) {
415 if ($newFile ===
null) {
417 if (in_array($folderName, $sanitizedFolderMappings)) {
418 $folderName = $sanitizedFolderMappings[$folderName];
420 if (!$storage->hasFolder($folderName)) {
422 $importFolder = $storage->createFolder($folderName);
423 if ($importFolder->getIdentifier() !== $folderName && !in_array($folderName, $sanitizedFolderMappings)) {
424 $sanitizedFolderMappings[$folderName] = $importFolder->getIdentifier();
426 }
catch (Exception $e) {
427 $this->
error(
'Error: Folder "' . $folderName .
'" could not be created for file "' . $fileRecord[
'identifier'] .
'" with storage uid "' . $fileRecord[
'storage'] .
'"');
431 $importFolder = $storage->getFolder($folderName);
434 $this->
callHook(
'before_addSysFileRecord', [
435 'fileRecord' => $fileRecord,
436 'importFolder' => $importFolder,
437 'temporaryFile' => $temporaryFile
442 $newFile = $storage->addFile($temporaryFile, $importFolder, $fileRecord[
'name']);
443 }
catch (Exception $e) {
444 $this->
error(
'Error: File could not be added to the storage: "' . $fileRecord[
'identifier'] .
'" with storage uid "' . $fileRecord[
'storage'] .
'"');
448 if ($newFile->getSha1() !== $fileRecord[
'sha1']) {
449 $this->
error(
'Error: The hash of the written file is not identical to the import data! File could be corrupted! File: "' . $fileRecord[
'identifier'] .
'" with storage uid "' . $fileRecord[
'storage'] .
'"');
454 $this->import_mapId[
'sys_file'][$fileRecord[
'uid']] = $newFile->getUid();
459 unset($this->dat[
'header'][
'records'][
'sys_file']);
471 if (!isset($this->dat[
'header'][
'records'][
'sys_file_reference'])) {
475 foreach ($this->dat[
'header'][
'records'][
'sys_file_reference'] as $sysFileReferenceUid => $_) {
476 $fileReferenceRecord = $this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid][
'data'];
477 if (!in_array($fileReferenceRecord[
'uid_local'], $this->import_mapId[
'sys_file'])) {
478 unset($this->dat[
'header'][
'records'][
'sys_file_reference'][$sysFileReferenceUid]);
479 unset($this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid]);
481 'Error: sys_file_reference record ' . (
int)$sysFileReferenceUid
482 .
' with relation to sys_file record ' . (
int)$fileReferenceRecord[
'uid_local']
483 .
', which is not part of the import data, was not imported.'
497 return $storageId === 0 || $storageId ===
'0';
517 if (!isset($this->dat[
'header'][
'records'][
'sys_file_reference'])) {
521 foreach ($this->dat[
'header'][
'records'][
'sys_file_reference'] as $sysFileReferenceUid => $_) {
522 if (!isset($this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid][
'hasBeenMapped'])
523 && $this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid][
'data'][
'uid_local'] == $oldFileUid
525 $this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid][
'hasBeenMapped'] =
true;
526 $this->dat[
'records'][
'sys_file_reference:' . $sysFileReferenceUid][
'data'][
'uid_local'] = $newFileUid;
539 $result = GeneralUtility::makeInstance(ConnectionPool::class)
540 ->getQueryBuilderForTable(
'sys_file_storage')
542 ->from(
'sys_file_storage')
546 while ($row = $result->fetch()) {
547 $rows[$row[
'uid']] = $row;
561 $temporaryFilePath =
null;
562 if (is_array($this->dat[$dataKey][$fileId])) {
563 $temporaryFilePathInternal = GeneralUtility::tempnam(
'import_temp_');
564 GeneralUtility::writeFile($temporaryFilePathInternal, $this->dat[$dataKey][$fileId][
'content']);
566 if (@is_file($temporaryFilePathInternal)) {
567 $this->unlinkFiles[] = $temporaryFilePathInternal;
568 $temporaryFilePath = $temporaryFilePathInternal;
570 $this->
error(
'Error: temporary file ' . $temporaryFilePathInternal .
' was not written as it should have been!');
573 $this->
error(
'Error: No file found for ID ' . $fileId);
575 return $temporaryFilePath;
587 if (is_array($this->dat[
'header'][
'records'][
'pages'])) {
590 $pageRecords = $this->dat[
'header'][
'records'][
'pages'];
591 $this->import_data = [];
593 if (is_array($this->dat[
'header'][
'pagetree'])) {
595 foreach ($pagesFromTree as $uid) {
596 $thisRec = $this->dat[
'header'][
'records'][
'pages'][$uid];
598 $setPid = $this->import_newId_pids[$thisRec[
'pid']] ?? $pid;
600 unset($pageRecords[$uid]);
604 if (!empty($pageRecords)) {
605 $remainingPageUids = array_keys($pageRecords);
606 foreach ($remainingPageUids as $pUid) {
612 $tce->isImporting =
true;
613 $this->
callHook(
'before_writeRecordsPages', [
615 'data' => &$this->import_data
618 $tce->start($this->import_data, []);
619 $tce->process_datamap();
620 $this->
callHook(
'after_writeRecordsPages', [
626 if ($this->update && is_array($this->dat[
'header'][
'pagetree'])) {
644 foreach ($pidsFromTree as $origPid => $newPid) {
647 if (strpos($this->import_newId_pids[$origPid],
'NEW') === 0) {
648 if ($this->import_mapId[
'pages'][$origPid]) {
649 $mappedPid = $this->import_mapId[
'pages'][$origPid];
650 $cmd_data[
'pages'][$mappedPid][
'move'] = $newPid;
653 $cmd_data[
'pages'][$origPid][
'move'] = $newPid;
658 if (!empty($cmd_data)) {
660 $this->
callHook(
'before_writeRecordsPagesOrder', [
664 $tce->start([], $cmd_data);
665 $tce->process_cmdmap();
666 $this->
callHook(
'after_writeRecordsPagesOrder', [
683 if (is_array($idH)) {
684 $idH = array_reverse($idH);
685 foreach ($idH as $v) {
686 $a[$v[
'uid']] = $pid;
687 if (is_array($v[
'subrow'])) {
704 $this->import_data = [];
705 if (is_array($this->dat[
'header'][
'records'])) {
706 foreach ($this->dat[
'header'][
'records'] as $table => $recs) {
708 if ($table !==
'pages') {
709 foreach ($recs as $uid => $thisRec) {
711 $setPid = isset($this->import_mapId[
'pages'][$thisRec[
'pid']])
712 ? (int)$this->import_mapId[
'pages'][$thisRec[
'pid']]
714 if (is_array(
$GLOBALS[
'TCA'][$table]) && isset(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'rootLevel'])) {
715 $rootLevelSetting = (int)
$GLOBALS[
'TCA'][$table][
'ctrl'][
'rootLevel'];
716 if ($rootLevelSetting === 1) {
718 } elseif ($rootLevelSetting === 0 && $setPid === 0) {
719 $this->
error(
'Error: Record type ' . $table .
' is not allowed on pid 0');
729 $this->
error(
'Error: No records defined in internal data array.');
733 $this->
callHook(
'before_writeRecordsRecords', [
735 'data' => &$this->import_data
739 $tce->reverseOrder = 1;
740 $tce->isImporting =
true;
741 $tce->start($this->import_data, []);
742 $tce->process_datamap();
743 $this->
callHook(
'after_writeRecordsRecords', [
765 if (is_array($this->dat[
'header'][
'pagetree'])) {
770 if (is_array($this->dat[
'header'][
'pid_lookup'])) {
771 foreach ($this->dat[
'header'][
'pid_lookup'] as $pid => $recList) {
772 $newPid = $this->import_mapId[
'pages'][$pid] ?? $mainPid;
774 foreach ($recList as $tableName => $uidList) {
777 if (($tableName !==
'pages' || !$pagesFromTree[$pid]) && is_array($uidList)) {
778 $uidList = array_reverse(array_keys($uidList));
779 foreach ($uidList as $uid) {
781 $cmd_data[$tableName][$uid][
'move'] = $newPid;
790 if (!empty($cmd_data)) {
792 $this->
callHook(
'before_writeRecordsRecordsOrder', [
796 $tce->start([], $cmd_data);
797 $tce->process_cmdmap();
798 $this->
callHook(
'after_writeRecordsRecordsOrder', [
814 public function addSingle($table, $uid, $pid)
816 if ($this->import_mode[$table .
':' . $uid] ===
'exclude') {
819 $record = $this->dat[
'records'][$table .
':' . $uid][
'data'];
820 if (is_array($record)) {
821 if ($this->update && $this->
doesRecordExist($table, $uid) && $this->import_mode[$table .
':' . $uid] !==
'as_new') {
823 } elseif ($table ===
'sys_file_metadata' && $record[
'sys_language_uid'] ==
'0' && $this->import_mapId[
'sys_file'][$record[
'file']]) {
826 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
827 ->getQueryBuilderForTable(
'sys_file_metadata');
828 $recordInDatabase = $queryBuilder->select(
'uid')
829 ->from(
'sys_file_metadata')
831 $queryBuilder->expr()->eq(
833 $queryBuilder->createNamedParameter(
834 $this->import_mapId[
'sys_file'][$record[
'file']],
838 $queryBuilder->expr()->eq(
840 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
842 $queryBuilder->expr()->eq(
844 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
851 if (is_array($recordInDatabase)) {
852 $this->import_mapId[
'sys_file_metadata'][$record[
'uid']] = $recordInDatabase[
'uid'];
853 $ID = $recordInDatabase[
'uid'];
860 $this->import_newId[$table .
':' . $ID] = [
'table' => $table,
'uid' => $uid];
861 if ($table ===
'pages') {
862 $this->import_newId_pids[$uid] = $ID;
865 $this->import_data[$table][$ID] = $record;
866 $this->import_data[$table][$ID][
'tx_impexp_origuid'] = $this->import_data[$table][$ID][
'uid'];
868 if ($table ===
'pages') {
870 unset($this->import_data[$table][$ID][
'perms_userid']);
871 unset($this->import_data[$table][$ID][
'perms_groupid']);
874 unset($this->import_data[$table][$ID][
'uid']);
877 unset($this->import_data[$table][$ID][
'pid']);
880 $this->import_data[$table][$ID][
'pid'] = $pid;
881 if (($this->import_mode[$table .
':' . $uid] ===
'force_uid' && $this->update || $this->force_all_UIDS) && $this->
getBackendUser()->isAdmin()) {
882 $this->import_data[$table][$ID][
'uid'] = $uid;
883 $this->suggestedInsertUids[$table .
':' . $uid] =
'DELETE';
887 foreach ($this->dat[
'records'][$table .
':' . $uid][
'rels'] as $field => $config) {
888 switch ((
string)$config[
'type']) {
900 if ($table !==
'sys_file_reference' && $field !==
'uid_local') {
901 $this->import_data[$table][$ID][$field] =
'';
909 $this->import_data[$table][$ID][$field] =
'';
913 } elseif ($table .
':' . $uid !=
'pages:0') {
915 $this->
error(
'Error: no record was found in data array!');
927 foreach ($this->import_data as $table => $recs) {
928 foreach ($recs as $id => $value) {
929 $old_uid = $this->import_newId[$table .
':' . $id][
'uid'];
930 if (isset($substNEWwithIDs[$id])) {
931 $this->import_mapId[$table][$old_uid] = $substNEWwithIDs[$id];
932 } elseif ($this->update) {
934 $this->import_mapId[$table][$old_uid] = $id;
938 if (!($table ===
'sys_file_metadata' && isset($this->import_mapId[$table][$old_uid]) && $this->import_mapId[$table][$old_uid] == $id)) {
939 $this->
error(
'Possible error: ' . $table .
':' . $old_uid .
' had no new id assigned to it. This indicates that the record was not added to database during import. Please check changelog!');
953 $tce = GeneralUtility::makeInstance(DataHandler::class);
954 $tce->dontProcessTransformations = 1;
966 foreach ($this->unlinkFiles as $fileName) {
967 GeneralUtility::unlink_tempfile($fileName);
969 if (is_file($fileName)) {
970 $this->
error(
'Error: ' . $fileName .
' was NOT unlinked as it should have been!');
973 $this->unlinkFiles = [];
991 foreach ($this->import_newId as $nId =>
$dat) {
992 $table =
$dat[
'table'];
996 if (is_array($this->import_mapId[$table]) && isset($this->import_mapId[$table][$uid])) {
998 if (is_array($this->dat[
'records'][$table .
':' . $uid][
'rels'])) {
1000 foreach ($this->dat[
'records'][$table .
':' . $uid][
'rels'] as $field => $config) {
1003 if ($table ===
'sys_file_reference' && $field ===
'uid_local') {
1006 switch ((
string)$config[
'type']) {
1008 if (is_array($config[
'itemArray']) && !empty($config[
'itemArray'])) {
1009 $itemConfig =
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'];
1011 $updateData[$table][$thisNewUid][$field] = implode(
',', $valArray);
1015 if (is_array($config[
'newValueFiles']) && !empty($config[
'newValueFiles'])) {
1017 foreach ($config[
'newValueFiles'] as $fI) {
1020 $updateData[$table][$thisNewUid][$field] = implode(
',', $valArr);
1026 $this->
error(
'Error: no record was found in data array!');
1029 $this->
error(
'Error: this records is NOT created it seems! (' . $table .
':' . $uid .
')');
1032 if (!empty($updateData)) {
1034 $tce->isImporting =
true;
1035 $this->
callHook(
'before_setRelation', [
1037 'data' => &$updateData
1039 $tce->start($updateData, []);
1040 $tce->process_datamap();
1041 $this->
callHook(
'after_setRelations', [
1057 foreach ($itemArray as $relDat) {
1058 if (is_array($this->import_mapId[$relDat[
'table']]) && isset($this->import_mapId[$relDat[
'table']][$relDat[
'id']])) {
1061 if ($itemConfig[
'type'] ===
'group' && $itemConfig[
'internal_type'] ===
'file_reference') {
1062 $value = $this->import_mapId[$relDat[
'table']][$relDat[
'id']];
1063 } elseif ($itemConfig[
'type'] ===
'input' && isset($itemConfig[
'wizards'][
'link'])) {
1066 $fileUid = $this->import_mapId[$relDat[
'table']][$relDat[
'id']];
1068 $value =
'file:' . $fileUid;
1071 }
catch (\Exception $e) {
1074 if ($file instanceof FileInterface) {
1078 $value = $relDat[
'table'] .
'_' . $this->import_mapId[$relDat[
'table']][$relDat[
'id']];
1080 $valArray[] = $value;
1081 } elseif ($this->
isTableStatic($relDat[
'table']) || $this->
isExcluded($relDat[
'table'], $relDat[
'id']) || $relDat[
'id'] < 0) {
1084 $valArray[] = $relDat[
'table'] .
'_' . $relDat[
'id'];
1086 $this->
error(
'Lost relation: ' . $relDat[
'table'] .
':' . $relDat[
'id']);
1100 if (is_array($this->dat[
'files'][$fI[
'ID']])) {
1103 if ($this->filesPathForImport !==
null) {
1104 if (is_file($this->filesPathForImport .
'/' . $this->dat[
'files'][$fI[
'ID']][
'content_md5']) &&
1105 md5_file($this->filesPathForImport .
'/' . $this->dat[
'files'][$fI[
'ID']][
'content_md5']) === $this->dat[
'files'][$fI[
'ID']][
'content_md5']) {
1106 $tmpFile = $this->filesPathForImport .
'/' . $this->dat[
'files'][$fI[
'ID']][
'content_md5'];
1109 if ($tmpFile ===
null) {
1110 $tmpFile = GeneralUtility::tempnam(
'import_temp_');
1111 GeneralUtility::writeFile($tmpFile, $this->dat[
'files'][$fI[
'ID']][
'content']);
1114 if (@is_file($tmpFile)) {
1115 $this->unlinkFiles[] = $tmpFile;
1116 $this->alternativeFileName[$tmpFile] = $fI[
'filename'];
1117 $this->alternativeFilePath[$tmpFile] = $this->dat[
'files'][$fI[
'ID']][
'relFileRef'];
1120 $this->
error(
'Error: temporary file ' . $tmpFile .
' was not written as it should have been!');
1122 $this->
error(
'Error: No file found for ID ' . $fI[
'ID']);
1137 foreach ($this->import_newId as $nId =>
$dat) {
1138 $table =
$dat[
'table'];
1139 $uid =
$dat[
'uid'];
1142 if (!isset($this->import_mapId[$table][$uid])) {
1143 $this->
error(
'Error: this records is NOT created it seems! (' . $table .
':' . $uid .
')');
1147 if (!is_array($this->dat[
'records'][$table .
':' . $uid][
'rels'])) {
1148 $this->
error(
'Error: no record was found in data array!');
1153 foreach ($this->dat[
'records'][$table .
':' . $uid][
'rels'] as $field => $config) {
1154 switch ((
string)$config[
'type']) {
1157 $updateData[$table][$thisNewUid][$field] = $this->dat[
'records'][$table .
':' . $uid][
'data'][$field];
1159 if (!empty($config[
'flexFormRels'][
'db']) || !empty($config[
'flexFormRels'][
'file'])) {
1162 $fieldTca =
$GLOBALS[
'TCA'][$table][
'columns'][$field];
1163 if (is_array($origRecordRow) && is_array($fieldTca[
'config']) && $fieldTca[
'config'][
'type'] ===
'flex') {
1165 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
1166 $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier(
1172 $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
1173 $currentValueArray = GeneralUtility::xml2array($updateData[$table][$thisNewUid][$field]);
1175 $iteratorObj = GeneralUtility::makeInstance(DataHandler::class);
1176 $iteratorObj->callBackObj = $this;
1177 $currentValueArray[
'data'] = $iteratorObj->checkValue_flex_procInData(
1178 $currentValueArray[
'data'],
1181 $dataStructureArray,
1182 [$table, $thisNewUid, $field, $config],
1183 'remapListedDBRecords_flexFormCallBack'
1186 if (is_array($currentValueArray[
'data'])) {
1187 $updateData[$table][$thisNewUid][$field] = $currentValueArray;
1195 if (!empty($updateData)) {
1197 $tce->isImporting =
true;
1198 $this->
callHook(
'before_setFlexFormRelations', [
1200 'data' => &$updateData
1202 $tce->start($updateData, []);
1203 $tce->process_datamap();
1204 $this->
callHook(
'after_setFlexFormRelations', [
1225 list(, , , $config) = $pParams;
1227 if (!is_array($config[
'flexFormRels'][
'db'][$path]) && is_array($config[
'flexFormRels'][
'db'][rtrim($path,
'/')])) {
1228 $path = rtrim($path,
'/');
1230 if (is_array($config[
'flexFormRels'][
'db'][$path])) {
1231 $valArray = $this->
setRelations_db($config[
'flexFormRels'][
'db'][$path], $dsConf);
1232 $dataValue = implode(
',', $valArray);
1234 if (is_array($config[
'flexFormRels'][
'file'][$path])) {
1236 foreach ($config[
'flexFormRels'][
'file'][$path] as $fI) {
1239 $dataValue = implode(
',', $valArr);
1241 return [
'value' => $dataValue];
1256 if (is_array($this->dat[
'header'][
'records'])) {
1257 foreach ($this->dat[
'header'][
'records'] as $table => $recs) {
1258 foreach ($recs as $uid => $thisRec) {
1260 if (isset(
$GLOBALS[
'TCA'][$table]) && is_array($thisRec[
'softrefs'])) {
1264 foreach ($thisRec[
'softrefs'] as $softrefDef) {
1266 if ($softrefDef[
'field'] && is_array($softrefDef[
'subst']) && $softrefDef[
'subst'][
'tokenID']) {
1267 $fieldsIndex[$softrefDef[
'field']][$softrefDef[
'subst'][
'tokenID']] = $softrefDef;
1273 foreach ($fieldsIndex as $field => $softRefCfgs) {
1274 if (is_array(
$GLOBALS[
'TCA'][$table][
'columns'][$field])) {
1275 if (
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'type'] ===
'flex') {
1278 if (is_array($origRecordRow)) {
1280 $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
1281 $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier(
1282 $GLOBALS[
'TCA'][$table][
'columns'][$field],
1287 $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
1288 $currentValueArray = GeneralUtility::xml2array($origRecordRow[$field]);
1291 $iteratorObj = GeneralUtility::makeInstance(DataHandler::class);
1292 $iteratorObj->callBackObj = $this;
1293 $currentValueArray[
'data'] = $iteratorObj->checkValue_flex_procInData($currentValueArray[
'data'], [], [], $dataStructureArray, [$table, $uid, $field, $softRefCfgs],
'processSoftReferences_flexFormCallBack');
1295 if (is_array($currentValueArray[
'data'])) {
1296 $inData[$table][$thisNewUid][$field] = $currentValueArray;
1301 $tokenizedContent = $this->dat[
'records'][$table .
':' . $uid][
'rels'][$field][
'softrefs'][
'tokenizedContent'];
1302 if (strlen($tokenizedContent) && is_array($softRefCfgs)) {
1314 $tce->isImporting =
true;
1315 $this->
callHook(
'before_processSoftReferences', [
1319 $tce->enableLogging =
true;
1320 $tce->start($inData, []);
1321 $tce->process_datamap();
1322 $this->
callHook(
'after_processSoftReferences', [
1342 list($table, $origUid, $field, $softRefCfgs) = $pParams;
1343 if (is_array($softRefCfgs)) {
1345 $thisSoftRefCfgList = [];
1346 foreach ($softRefCfgs as $sK => $sV) {
1347 if ($sV[
'structurePath'] === $path) {
1348 $thisSoftRefCfgList[$sK] = $sV;
1352 if (!empty($thisSoftRefCfgList)) {
1354 $tokenizedContent = $this->dat[
'records'][$table .
':' . $origUid][
'rels'][$field][
'flexFormRels'][
'softrefs'][$path][
'tokenizedContent'];
1355 if (strlen($tokenizedContent)) {
1361 return [
'value' => $dataValue];
1376 foreach ($softRefCfgs as $cfg) {
1378 $tokenID = $cfg[
'subst'][
'tokenID'];
1380 $insertValue = $cfg[
'subst'][
'tokenValue'];
1382 switch ((
string)$this->softrefCfg[$tokenID][
'mode']) {
1388 $insertValue = $this->softrefInputValues[$tokenID];
1392 switch ((
string)$cfg[
'subst'][
'type']) {
1400 list($tempTable, $tempUid) = explode(
':', $cfg[
'subst'][
'recordRef']);
1401 if (isset($this->import_mapId[$tempTable][$tempUid])) {
1406 if ($recWithUniqueValue[
'alias']) {
1407 $insertValue = $recWithUniqueValue[
'alias'];
1409 } elseif (strpos($cfg[
'subst'][
'tokenValue'],
':') !==
false) {
1410 list($tokenKey) = explode(
':', $cfg[
'subst'][
'tokenValue']);
1411 $insertValue = $tokenKey .
':' . $insertValue;
1417 $tokenizedContent = str_replace(
'{softref:' . $tokenID .
'}', $insertValue, $tokenizedContent);
1419 return $tokenizedContent;
1433 if ($fileHeaderInfo = $this->dat[
'header'][
'files'][$cfg[
'file_ID']]) {
1438 if ($rteOrigName && GeneralUtility::isFirstPartOfStr($dirPrefix,
'uploads/')) {
1447 $pI = pathinfo($relFileName);
1450 !@is_file($copyDestName) && !@is_file($origDestName)
1451 && $origDestName === GeneralUtility::getFileAbsFileName($origDestName)
1452 && $copyDestName === GeneralUtility::getFileAbsFileName($copyDestName)
1454 if ($this->dat[
'header'][
'files'][$fileHeaderInfo[
'RTE_ORIG_ID']]) {
1457 $this->
writeFileVerify($origDestName, $fileHeaderInfo[
'RTE_ORIG_ID'],
true);
1461 $this->
error(
'ERROR: Could not find original file ID');
1463 $this->
error(
'ERROR: The destination filenames "' . $copyDestName .
'" and "' . $origDestName .
'" either existed or have non-valid names');
1468 } elseif (GeneralUtility::isFirstPartOfStr($dirPrefix, $this->fileadminFolderName .
'/')) {
1472 if (strlen($newFileName)) {
1473 $relFileName = $newFileName;
1475 $this->
error(
'ERROR: No new file created for "' . $relFileName .
'"');
1478 $this->
error(
'ERROR: Sorry, cannot operate on non-RTE files which are outside the fileadmin folder.');
1481 $this->
error(
'ERROR: Could not find file ID in header.');
1484 return $relFileName;
1501 if (isset($this->fileIDMap[$fileID])) {
1506 if ($dirPrefix && (!$this->update || $origDirPrefix === $dirPrefix) && $this->
checkOrCreateDir($dirPrefix)) {
1507 $fileHeaderInfo = $this->dat[
'header'][
'files'][$fileID];
1508 $updMode = $this->update && $this->import_mapId[$table][$uid] === $uid && $this->import_mode[$table .
':' . $uid] !==
'as_new';
1522 if (is_array($fileHeaderInfo[
'EXT_RES_ID'])) {
1523 $tokenizedContent = $this->dat[
'files'][$fileID][
'tokenizedContent'];
1524 $tokenSubstituted =
false;
1527 foreach ($fileHeaderInfo[
'EXT_RES_ID'] as $res_fileID) {
1528 if ($this->dat[
'files'][$res_fileID][
'filename']) {
1530 $relResourceFileName = $this->dat[
'files'][$res_fileID][
'parentRelFileName'];
1531 $absResourceFileName = GeneralUtility::resolveBackPath(
Environment::getPublicPath() .
'/' . $origDirPrefix . $relResourceFileName);
1532 $absResourceFileName = GeneralUtility::getFileAbsFileName($absResourceFileName);
1533 if ($absResourceFileName && GeneralUtility::isFirstPartOfStr($absResourceFileName,
Environment::getPublicPath() .
'/' . $this->fileadminFolderName .
'/')) {
1538 $this->
error(
'ERROR: Could not create file in directory "' . $destDir .
'"');
1541 $this->
error(
'ERROR: Could not resolve path for "' . $relResourceFileName .
'"');
1543 $tokenizedContent = str_replace(
'{EXT_RES_ID:' . $res_fileID .
'}', $relResourceFileName, $tokenizedContent);
1544 $tokenSubstituted =
true;
1550 if (GeneralUtility::mkdir($resourceDir)) {
1551 foreach ($fileHeaderInfo[
'EXT_RES_ID'] as $res_fileID) {
1552 if ($this->dat[
'files'][$res_fileID][
'filename']) {
1554 $relResourceFileName = substr($absResourceFileName, strlen(
PathUtility::dirname($resourceDir)) + 1);
1556 $tokenizedContent = str_replace(
'{EXT_RES_ID:' . $res_fileID .
'}', $relResourceFileName, $tokenizedContent);
1557 $tokenSubstituted =
true;
1563 if ($tokenSubstituted) {
1564 GeneralUtility::writeFile($newName, $tokenizedContent);
1581 public function writeFileVerify($fileName, $fileID, $bypassMountCheck =
false)
1585 $this->
error(
'ERROR: You did not have sufficient permissions to write the file "' . $fileName .
'"');
1589 if (!$bypassMountCheck) {
1592 }
catch (InsufficientFolderAccessPermissionsException $e) {
1593 $this->
error(
'ERROR: Filename "' . $fileName .
'" was not allowed in destination path!');
1597 $fI = GeneralUtility::split_fileref($fileName);
1598 if (!
$fileProcObj->
checkIfAllowed($fI[
'fileext'], $fI[
'path'], $fI[
'file']) && (!$this->allowPHPScripts || !$this->getBackendUser()->isAdmin())) {
1599 $this->
error(
'ERROR: Filename "' . $fileName .
'" failed against extension check or deny-pattern!');
1602 if (!GeneralUtility::getFileAbsFileName($fileName)) {
1603 $this->
error(
'ERROR: Filename "' . $fileName .
'" was not a valid relative file path!');
1606 if (!$this->dat[
'files'][$fileID]) {
1607 $this->
error(
'ERROR: File ID "' . $fileID .
'" could not be found');
1610 GeneralUtility::writeFile($fileName, $this->dat[
'files'][$fileID][
'content']);
1611 $this->fileIDMap[$fileID] = $fileName;
1612 if (hash_equals(md5(file_get_contents($fileName)), $this->dat[
'files'][$fileID][
'content_md5'])) {
1615 $this->
error(
'ERROR: File content "' . $fileName .
'" was corrupted');
1628 $filePathParts = explode(
'/', $dirPrefix);
1629 $firstDir = array_shift($filePathParts);
1630 if ($firstDir === $this->fileadminFolderName && GeneralUtility::getFileAbsFileName($dirPrefix)) {
1632 foreach ($filePathParts as $dirname) {
1633 $pathAcc .=
'/' . $dirname;
1634 if (strlen($dirname)) {
1637 $this->
error(
'ERROR: Directory could not be created....B');
1641 } elseif ($dirPrefix === $this->fileadminFolderName . $pathAcc) {
1644 $this->
error(
'ERROR: Directory could not be created....A');
1662 public function loadFile($filename, $all =
false)
1664 if (!@is_file($filename)) {
1665 $this->
error(
'Filename not found: ' . $filename);
1668 $fI = pathinfo($filename);
1669 if (@is_dir($filename .
'.files')) {
1670 if (GeneralUtility::isAllowedAbsPath($filename .
'.files')) {
1673 GeneralUtility::copyDirectory($filename .
'.files', $temporaryFolderName);
1674 $this->filesPathForImport = $temporaryFolderName;
1676 $this->
error(
'External import files for the given import source is currently not supported.');
1679 if (strtolower($fI[
'extension']) ===
'xml') {
1681 $xmlContent = file_get_contents($filename);
1682 if (strlen($xmlContent)) {
1683 $this->dat = GeneralUtility::xml2array($xmlContent,
'',
true);
1684 if (is_array($this->dat)) {
1685 if ($this->dat[
'_DOCUMENT_TAG'] ===
'T3RecordDocument' && is_array($this->dat[
'header']) && is_array($this->dat[
'records'])) {
1689 $this->
error(
'XML file did not contain proper XML for TYPO3 Import');
1691 $this->
error(
'XML could not be parsed: ' . $this->dat);
1694 $this->
error(
'Error opening file: ' . $filename);
1698 if ($fd = fopen($filename,
'rb')) {
1708 $this->
error(
'Error opening file: ' . $filename);
1727 $initStrLen = 32 + 1 + 1 + 1 + 10 + 1;
1729 $initStr = fread($fd, $initStrLen);
1730 if (empty($initStr)) {
1731 $this->
error(
'File does not contain data for "' . $name .
'"');
1734 $initStrDat = explode(
':', $initStr);
1735 if (strstr($initStrDat[0],
'Warning')) {
1736 $this->
error(
'File read error: Warning message in file. (' . $initStr . fgets($fd) .
')');
1739 if ((
string)$initStrDat[3] !==
'') {
1740 $this->
error(
'File read error: InitString had a wrong length. (' . $name .
')');
1743 $datString = fread($fd, (
int)$initStrDat[2]);
1745 if (hash_equals($initStrDat[0], md5($datString))) {
1746 if ($initStrDat[1]) {
1747 if ($this->compress) {
1748 $datString = gzuncompress($datString);
1750 $this->
error(
'Content read error: This file requires decompression, but this server does not offer gzcompress()/gzuncompress() functions.');
1754 return $unserialize ? unserialize($datString, [
'allowed_classes' =>
false]) : $datString;
1756 $this->
error(
'MD5 check failed (' . $name .
')');
1785 public function getNextContentPart($filecontent, &$pointer, $unserialize =
false, $name =
'')
1787 $initStrLen = 32 + 1 + 1 + 1 + 10 + 1;
1789 $initStr = substr($filecontent, $pointer, $initStrLen);
1790 $pointer += $initStrLen;
1791 $initStrDat = explode(
':', $initStr);
1792 if ((
string)$initStrDat[3] !==
'') {
1793 $this->
error(
'Content read error: InitString had a wrong length. (' . $name .
')');
1796 $datString = substr($filecontent, $pointer, (
int)$initStrDat[2]);
1797 $pointer += (int)$initStrDat[2] + 1;
1798 if (hash_equals($initStrDat[0], md5($datString))) {
1799 if ($initStrDat[1]) {
1800 if ($this->compress) {
1801 $datString = gzuncompress($datString);
1802 return $unserialize ? unserialize($datString, [
'allowed_classes' =>
false]) : $datString;
1804 $this->
error(
'Content read error: This file requires decompression, but this server does not offer gzcompress()/gzuncompress() functions.');
1807 $this->
error(
'MD5 check failed (' . $name .
')');
1817 $this->relStaticTables = (array)$this->dat[
'header'][
'relStaticTables'];
1818 $this->excludeMap = (array)$this->dat[
'header'][
'excludeMap'];
1819 $this->softrefCfg = (array)$this->dat[
'header'][
'softrefCfg'];