140 $this->mode =
'export';
153 if (is_array($this->softrefCfg)) {
154 foreach ($this->softrefCfg as $key => $value) {
155 if (!strlen($value[
'mode'])) {
156 unset($this->softrefCfg[$key]);
162 $this->dat[
'header'][
'XMLversion'] =
'1.0';
164 $this->dat[
'header'][
'meta'] = [];
173 $this->dat[
'header'][
'charset'] =
'utf-8';
183 $this->dat[
'header'][
'charset'] = $charset;
196 public function setMetaData($title, $description, $notes, $packager_username, $packager_name, $packager_email)
198 $this->dat[
'header'][
'meta'] = [
200 'description' => $description,
202 'packager_username' => $packager_username,
203 'packager_name' => $packager_name,
204 'packager_email' => $packager_email,
205 'TYPO3_version' => TYPO3_version,
206 'created' => strftime(
'%A %e. %B %Y',
$GLOBALS[
'EXEC_TIME'])
248 if (is_array($idH)) {
249 foreach ($idH as $k => $v) {
250 if ($this->excludeMap[
'pages:' . $idH[$k][
'uid']]) {
252 } elseif (is_array($idH[$k][
'subrow'])) {
274 throw new Exception(
'The include fields for record type ' . htmlspecialchars($table) .
' are not defined by an array.', 1391440658);
288 $this->recordTypesIncludeFields[$table] =
$fields;
302 if ($this->excludeDisabledRecords && !$this->
isActive($table, $row[
'uid'])) {
305 if ((
string)$table !==
'' && is_array($row) && $row[
'uid'] > 0 && !$this->excludeMap[$table .
':' . $row[
'uid']]) {
306 if ($this->
checkPID($table ===
'pages' ? $row[
'uid'] : $row[
'pid'])) {
307 if (!isset($this->dat[
'records'][$table .
':' . $row[
'uid']])) {
311 $headerInfo[
'uid'] = $row[
'uid'];
312 $headerInfo[
'pid'] = $row[
'pid'];
314 if ($relationLevel) {
315 $headerInfo[
'relationLevel'] = $relationLevel;
318 $this->dat[
'header'][
'records'][$table][$row[
'uid']] = $headerInfo;
320 $this->dat[
'header'][
'pid_lookup'][$row[
'pid']][$table][$row[
'uid']] = 1;
322 $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
323 $refIndexObj->enableRuntimeCache();
325 $refIndexObj->WSOL =
true;
326 $relations = $refIndexObj->getRelations($table, $row);
330 $this->dat[
'records'][$table .
':' . $row[
'uid']] = [];
331 $this->dat[
'records'][$table .
':' . $row[
'uid']][
'data'] = $row;
332 $this->dat[
'records'][$table .
':' . $row[
'uid']][
'rels'] = $relations;
334 $this->dat[
'header'][
'records'][$table][$row[
'uid']][
'rels'] = $this->
flatDBrels($this->dat[
'records'][$table .
':' . $row[
'uid']][
'rels']);
336 $this->dat[
'header'][
'records'][$table][$row[
'uid']][
'softrefs'] = $this->
flatSoftRefs($this->dat[
'records'][$table .
':' . $row[
'uid']][
'rels']);
338 $this->
error(
'Record ' . $table .
':' . $row[
'uid'] .
' already added.');
341 $this->
error(
'Record ' . $table .
':' . $row[
'uid'] .
' was outside your DB mounts!');
355 foreach ($relations as $field => $relation) {
356 if (isset($relation[
'type']) && $relation[
'type'] ===
'file') {
357 foreach ($relation[
'newValueFiles'] as $key => $fileRelationData) {
358 $absoluteFilePath = $fileRelationData[
'ID_absFile'];
361 $relations[$field][
'newValueFiles'][$key][
'ID'] = md5($relatedFilePath);
365 if ($relation[
'type'] ===
'flex') {
366 if (is_array($relation[
'flexFormRels'][
'file'])) {
367 foreach ($relation[
'flexFormRels'][
'file'] as $key => $subList) {
368 foreach ($subList as $subKey => $fileRelationData) {
369 $absoluteFilePath = $fileRelationData[
'ID_absFile'];
372 $relations[$field][
'flexFormRels'][
'file'][$key][$subKey][
'ID'] = md5($relatedFilePath);
393 $fixedRelations = [];
394 foreach ($relations as $field => $relation) {
395 $newRelation = $relation;
396 if (isset($newRelation[
'type']) && $newRelation[
'type'] ===
'db') {
397 foreach ($newRelation[
'itemArray'] as $key => $dbRelationData) {
398 if ($dbRelationData[
'table'] ===
'sys_file') {
399 if (isset($newRelation[
'softrefs'][
'keys'][
'typolink'])) {
400 foreach ($newRelation[
'softrefs'][
'keys'][
'typolink'] as $softrefKey => $softRefData) {
401 if ($softRefData[
'subst'][
'type'] ===
'file') {
403 if ($file instanceof
File) {
404 if ($file->getUid() == $dbRelationData[
'id']) {
405 unset($newRelation[
'softrefs'][
'keys'][
'typolink'][$softrefKey]);
410 if (empty($newRelation[
'softrefs'][
'keys'][
'typolink'])) {
411 unset($newRelation[
'softrefs']);
417 $fixedRelations[$field] = $newRelation;
419 return $fixedRelations;
435 if (!is_array($this->dat[
'records'])) {
436 $this->
error(
'There were no records available.');
440 foreach ($this->dat[
'records'] as $k => $value) {
441 if (!is_array($this->dat[
'records'][$k])) {
444 foreach ($this->dat[
'records'][$k][
'rels'] as $fieldname => $vR) {
446 if ($vR[
'type'] ===
'db') {
447 foreach ($vR[
'itemArray'] as $fI) {
452 if ($vR[
'type'] ===
'flex') {
454 if (is_array($vR[
'flexFormRels'][
'db'])) {
455 foreach ($vR[
'flexFormRels'][
'db'] as $subList) {
456 foreach ($subList as $fI) {
462 if (is_array($vR[
'flexFormRels'][
'softrefs'])) {
463 foreach ($vR[
'flexFormRels'][
'softrefs'] as $subList) {
464 foreach ($subList[
'keys'] as $spKey => $elements) {
465 foreach ($elements as $el) {
466 if ($el[
'subst'][
'type'] ===
'db' && $this->
includeSoftref($el[
'subst'][
'tokenID'])) {
467 list($tempTable, $tempUid) = explode(
':', $el[
'subst'][
'recordRef']);
469 'table' => $tempTable,
480 if (is_array($vR[
'softrefs'][
'keys'])) {
481 foreach ($vR[
'softrefs'][
'keys'] as $spKey => $elements) {
482 foreach ($elements as $el) {
483 if ($el[
'subst'][
'type'] ===
'db' && $this->
includeSoftref($el[
'subst'][
'tokenID'])) {
484 list($tempTable, $tempUid) = explode(
':', $el[
'subst'][
'recordRef']);
486 'table' => $tempTable,
499 foreach ($addR as $fI) {
504 foreach ($row as $fieldName => $value) {
506 $row[$fieldName] = $value ===
null ? $value : (string)$value;
509 if (is_array($row)) {
516 $rId = $fI[
'table'] .
':' . $fI[
'id'];
517 if (!isset($this->dat[
'records'][$rId])) {
518 $this->dat[
'records'][$rId] =
'NOT_FOUND';
519 $this->
error(
'Relation record ' . $rId .
' was not found!');
538 $rId = $fI[
'table'] .
':' . $fI[
'id'];
543 if (!isset($this->dat[
'records'][$rId])) {
559 if (!is_array($this->dat[
'records'])) {
560 $this->
error(
'There were no records available.');
563 foreach ($this->dat[
'records'] as $k => $value) {
564 if (!isset($this->dat[
'records'][$k][
'rels']) || !is_array($this->dat[
'records'][$k][
'rels'])) {
567 foreach ($this->dat[
'records'][$k][
'rels'] as $fieldname => $vR) {
569 if ($vR[
'type'] ===
'file') {
570 foreach ($vR[
'newValueFiles'] as $key => $fI) {
573 unset($this->dat[
'records'][$k][
'rels'][$fieldname][
'newValueFiles'][$key][
'ID_absFile']);
577 if ($vR[
'type'] ===
'flex') {
578 if (is_array($vR[
'flexFormRels'][
'file'])) {
579 foreach ($vR[
'flexFormRels'][
'file'] as $key => $subList) {
580 foreach ($subList as $subKey => $fI) {
583 unset($this->dat[
'records'][$k][
'rels'][$fieldname][
'flexFormRels'][
'file'][$key][$subKey][
'ID_absFile']);
588 if (is_array($vR[
'flexFormRels'][
'softrefs'])) {
589 foreach ($vR[
'flexFormRels'][
'softrefs'] as $key => $subList) {
590 foreach ($subList[
'keys'] as $spKey => $elements) {
591 foreach ($elements as $subKey => $el) {
592 if ($el[
'subst'][
'type'] ===
'file' && $this->
includeSoftref($el[
'subst'][
'tokenID'])) {
595 $ID = md5($el[
'subst'][
'relFileName']);
597 if (!$this->dat[
'files'][$ID]) {
600 'ID_absFile' => $ID_absFile,
602 'relFileName' => $el[
'subst'][
'relFileName']
606 $this->dat[
'records'][$k][
'rels'][$fieldname][
'flexFormRels'][
'softrefs'][$key][
'keys'][$spKey][$subKey][
'file_ID'] = $ID;
615 if (is_array($vR[
'softrefs'][
'keys'])) {
616 foreach ($vR[
'softrefs'][
'keys'] as $spKey => $elements) {
617 foreach ($elements as $subKey => $el) {
618 if ($el[
'subst'][
'type'] ===
'file' && $this->
includeSoftref($el[
'subst'][
'tokenID'])) {
621 $ID = md5($el[
'subst'][
'relFileName']);
623 if (!$this->dat[
'files'][$ID]) {
626 'ID_absFile' => $ID_absFile,
628 'relFileName' => $el[
'subst'][
'relFileName']
632 $this->dat[
'records'][$k][
'rels'][$fieldname][
'softrefs'][
'keys'][$spKey][$subKey][
'file_ID'] = $ID;
647 if (!isset($this->dat[
'header'][
'records'][
'sys_file']) || !is_array($this->dat[
'header'][
'records'][
'sys_file'])) {
650 foreach ($this->dat[
'header'][
'records'][
'sys_file'] as $sysFileUid => $_) {
651 $recordData = $this->dat[
'records'][
'sys_file:' . $sysFileUid][
'data'];
666 if (!$this->saveFilesOutsideExportFile) {
667 $fileContent = $file->getContents();
669 $file->checkActionPermission(
'read');
671 }
catch (\Exception $e) {
672 $this->
error(
'Error when trying to add file ' . $file->getCombinedIdentifier() .
': ' . $e->getMessage());
675 $fileUid = $file->getUid();
676 $fileSha1 = $file->getStorage()->hashFile($file,
'sha1');
677 if ($fileSha1 !== $file->getProperty(
'sha1')) {
678 $this->
error(
'File sha1 hash of ' . $file->getCombinedIdentifier() .
' is not up-to-date in index! File added on current sha1.');
679 $this->dat[
'records'][
'sys_file:' . $fileUid][
'data'][
'sha1'] = $fileSha1;
683 $fileRec[
'filename'] = $file->getProperty(
'name');
684 $fileRec[
'filemtime'] = $file->getProperty(
'modification_date');
687 $fileId = md5($file->getStorage()->getUid() .
':' . $file->getProperty(
'identifier_hash'));
690 $this->dat[
'header'][
'files_fal'][$fileId] = $fileRec;
692 if (!$this->saveFilesOutsideExportFile) {
694 $fileRec[
'content'] = $fileContent;
696 GeneralUtility::upload_copy_move($file->getForLocalProcessing(
false), $this->getTemporaryFilesPathForExport() . $file->getProperty(
'sha1'));
698 $fileRec[
'content_sha1'] = $fileSha1;
700 $this->dat[
'files_fal'][$fileId] = $fileRec;
712 if (!@is_file($fI[
'ID_absFile'])) {
713 $this->
error($fI[
'ID_absFile'] .
' was not a file! Skipping.');
716 $fileInfo = stat($fI[
'ID_absFile']);
719 $fileRec[
'filemtime'] = $fileInfo[
'mtime'];
723 $fileRec[
'record_ref'] = $recordRef .
'/' . $fieldname;
725 if ($fI[
'relFileName']) {
726 $fileRec[
'relFileName'] = $fI[
'relFileName'];
729 $this->dat[
'header'][
'files'][$fI[
'ID']] = $fileRec;
731 if ($recordRef && $recordRef !==
'_SOFTREF_') {
732 $refParts = explode(
':', $recordRef, 2);
733 if (!is_array($this->dat[
'header'][
'records'][$refParts[0]][$refParts[1]][
'filerefs'])) {
734 $this->dat[
'header'][
'records'][$refParts[0]][$refParts[1]][
'filerefs'] = [];
736 $this->dat[
'header'][
'records'][$refParts[0]][$refParts[1]][
'filerefs'][] = $fI[
'ID'];
738 $fileMd5 = md5_file($fI[
'ID_absFile']);
739 if (!$this->saveFilesOutsideExportFile) {
741 $fileRec[
'content'] = file_get_contents($fI[
'ID_absFile']);
745 $fileRec[
'content_md5'] = $fileMd5;
746 $this->dat[
'files'][$fI[
'ID']] = $fileRec;
748 if ($recordRef ===
'_SOFTREF_') {
752 if (@is_file($RTEoriginal_absPath)) {
753 $RTEoriginal_ID = md5($RTEoriginal_absPath);
754 $fileInfo = stat($RTEoriginal_absPath);
757 $fileRec[
'filemtime'] = $fileInfo[
'mtime'];
758 $fileRec[
'record_ref'] =
'_RTE_COPY_ID:' . $fI[
'ID'];
759 $this->dat[
'header'][
'files'][$fI[
'ID']][
'RTE_ORIG_ID'] = $RTEoriginal_ID;
761 $this->dat[
'header'][
'files'][$RTEoriginal_ID] = $fileRec;
762 $fileMd5 = md5_file($RTEoriginal_absPath);
763 if (!$this->saveFilesOutsideExportFile) {
765 $fileRec[
'content'] = file_get_contents($RTEoriginal_absPath);
769 $fileRec[
'content_md5'] = $fileMd5;
770 $this->dat[
'files'][$RTEoriginal_ID] = $fileRec;
778 if ($this->includeExtFileResources && GeneralUtility::inList($this->extFileResourceExtensions, strtolower($html_fI[
'extension']))) {
779 $uniquePrefix =
'###' . md5(
$GLOBALS[
'EXEC_TIME']) .
'###';
780 if (strtolower($html_fI[
'extension']) ===
'css') {
781 $prefixedMedias = explode($uniquePrefix, preg_replace(
'/(url[[:space:]]*\\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\\))/i',
'\\1' . $uniquePrefix .
'\\2' . $uniquePrefix .
'\\3', $fileRec[
'content']));
784 $htmlParser = GeneralUtility::makeInstance(HtmlParser::class);
785 $prefixedMedias = explode($uniquePrefix, $htmlParser->prefixResourcePath($uniquePrefix, $fileRec[
'content'], [], $uniquePrefix));
787 $htmlResourceCaptured =
false;
788 foreach ($prefixedMedias as $k => $v) {
790 $EXTres_absPath = GeneralUtility::resolveBackPath(
PathUtility::dirname($fI[
'ID_absFile']) .
'/' . $v);
791 $EXTres_absPath = GeneralUtility::getFileAbsFileName($EXTres_absPath);
792 if ($EXTres_absPath && GeneralUtility::isFirstPartOfStr($EXTres_absPath,
Environment::getPublicPath() .
'/' . $this->fileadminFolderName .
'/') && @is_file($EXTres_absPath)) {
793 $htmlResourceCaptured =
true;
794 $EXTres_ID = md5($EXTres_absPath);
795 $this->dat[
'header'][
'files'][$fI[
'ID']][
'EXT_RES_ID'][] = $EXTres_ID;
796 $prefixedMedias[$k] =
'{EXT_RES_ID:' . $EXTres_ID .
'}';
798 if (!isset($this->dat[
'header'][
'files'][$EXTres_ID])) {
799 $fileInfo = stat($EXTres_absPath);
802 $fileRec[
'filemtime'] = $fileInfo[
'mtime'];
803 $fileRec[
'record_ref'] =
'_EXT_PARENT_:' . $fI[
'ID'];
805 $fileRec[
'parentRelFileName'] = $v;
807 $this->dat[
'header'][
'files'][$EXTres_ID] = $fileRec;
809 $fileRec[
'content'] = file_get_contents($EXTres_absPath);
810 $fileRec[
'content_md5'] = md5($fileRec[
'content']);
811 $this->dat[
'files'][$EXTres_ID] = $fileRec;
816 if ($htmlResourceCaptured) {
817 $this->dat[
'files'][$fI[
'ID']][
'tokenizedContent'] = implode(
'', $prefixedMedias);
833 if (!$this->saveFilesOutsideExportFile) {
834 throw new \RuntimeException(
'You need to set saveFilesOutsideExportFile to TRUE before you want to get the temporary files path for export.', 1401205213);
836 if ($this->temporaryFilesPathForExport ===
null) {
838 $this->temporaryFilesPathForExport = $temporaryFolderName .
'/';
853 foreach ($dbrels as
$dat) {
854 if (
$dat[
'type'] ===
'db') {
855 foreach (
$dat[
'itemArray'] as $i) {
856 $list[$i[
'table'] .
':' . $i[
'id']] = $i;
859 if (
$dat[
'type'] ===
'flex' && is_array(
$dat[
'flexFormRels'][
'db'])) {
860 foreach (
$dat[
'flexFormRels'][
'db'] as $subList) {
861 foreach ($subList as $i) {
862 $list[$i[
'table'] .
':' . $i[
'id']] = $i;
879 foreach ($dbrels as $field =>
$dat) {
880 if (is_array(
$dat[
'softrefs'][
'keys'])) {
881 foreach (
$dat[
'softrefs'][
'keys'] as $spKey => $elements) {
882 if (is_array($elements)) {
883 foreach ($elements as $subKey => $el) {
884 $lKey = $field .
':' . $spKey .
':' . $subKey;
885 $list[$lKey] = array_merge([
'field' => $field,
'spKey' => $spKey], $el);
888 if ($el[
'subst'] && $el[
'subst'][
'relFileName']) {
895 if (
$dat[
'type'] ===
'flex' && is_array(
$dat[
'flexFormRels'][
'softrefs'])) {
896 foreach (
$dat[
'flexFormRels'][
'softrefs'] as $structurePath => $subSoftrefs) {
897 if (is_array($subSoftrefs[
'keys'])) {
898 foreach ($subSoftrefs[
'keys'] as $spKey => $elements) {
899 foreach ($elements as $subKey => $el) {
900 $lKey = $field .
':' . $structurePath .
':' . $spKey .
':' . $subKey;
901 $list[$lKey] = array_merge([
'field' => $field,
'spKey' => $spKey,
'structurePath' => $structurePath], $el);
904 if ($el[
'subst'] && $el[
'subst'][
'relFileName']) {
926 if (isset($this->recordTypesIncludeFields[$table])) {
927 $includeFields = array_unique(array_merge(
928 $this->recordTypesIncludeFields[$table],
929 $this->defaultRecordIncludeFields
932 foreach ($row as $key => $value) {
933 if (in_array($key, $includeFields)) {
934 $newRow[$key] = $value;
955 if ($type ===
'xml') {
983 'disableTypeAttrib' =>
true,
984 'clearStackPath' =>
true,
987 'files_fal' =>
'file',
988 'records' =>
'table',
990 'rec:rels' =>
'relations',
991 'relations' =>
'element',
992 'filerefs' =>
'file',
993 'pid_lookup' =>
'page_contents',
994 'header:relStaticTables' =>
'static_tables',
995 'static_tables' =>
'tablename',
996 'excludeMap' =>
'item',
997 'softrefCfg' =>
'softrefExportMode',
998 'extensionDependencies' =>
'extkey',
999 'softrefs' =>
'softref_element'
1003 'disableTypeAttrib' =>
true,
1004 'useIndexTagForNum' =>
'node',
1006 'node:subrow' =>
'node'
1009 '/pid_lookup/page_contents' => [
1010 'disableTypeAttrib' =>
true,
1012 'page_contents' =>
'table'
1014 'grandParentTagMap' => [
1015 'page_contents/table' =>
'item'
1021 'disableTypeAttrib' =>
true,
1023 'records' =>
'tablerow',
1024 'tablerow:data' =>
'fieldlist',
1025 'tablerow:rels' =>
'related',
1026 'related' =>
'field',
1027 'field:itemArray' =>
'relations',
1028 'field:newValueFiles' =>
'filerefs',
1029 'field:flexFormRels' =>
'flexform',
1030 'relations' =>
'element',
1031 'filerefs' =>
'file',
1032 'flexform:db' =>
'db_relations',
1033 'flexform:file' =>
'file_relations',
1034 'flexform:softrefs' =>
'softref_relations',
1035 'softref_relations' =>
'structurePath',
1036 'db_relations' =>
'path',
1037 'file_relations' =>
'path',
1038 'path' =>
'element',
1039 'keys' =>
'softref_key',
1040 'softref_key' =>
'softref_element'
1043 '/records/tablerow/fieldlist' => [
1044 'useIndexTagForAssoc' =>
'field'
1049 'disableTypeAttrib' =>
true,
1055 'disableTypeAttrib' =>
true,
1057 'files_fal' =>
'file'
1063 $charset = $this->dat[
'header'][
'charset'] ?:
'utf-8';
1064 $XML =
'<?xml version="1.0" encoding="' . $charset .
'" standalone="yes" ?>' . LF;
1065 $XML .= GeneralUtility::array2xml($this->dat,
'', 0,
'T3RecordDocument', 0, $options);
1089 $data = gzcompress($data);
1091 return md5($data) .
':' . (
$compress ?
'1' :
'0') .
':' . str_pad(strlen($data), 10,
'0', STR_PAD_LEFT) .
':' . $data .
':';