‪TYPO3CMS  11.5
ImportExport.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 namespace ‪TYPO3\CMS\Impexp;
19 
21 use TYPO3\CMS\Backend\Utility\BackendUtility;
38 
44 abstract class ‪ImportExport
45 {
51  protected ‪$mode = '';
52 
58  protected ‪$permsClause;
59 
65  protected ‪$pid = -1;
66 
70  protected ?array ‪$pidRecord = null;
71 
77  protected ‪$showStaticRelations = false;
78 
84  protected ‪$update = false;
85 
91  protected ‪$doesImport = false;
92 
99  protected ‪$importMode = [];
100 
106  protected ‪$globalIgnorePid = false;
107 
113  protected ‪$forceAllUids = false;
114 
120  protected ‪$showDiff = false;
121 
127  protected ‪$softrefInputValues = [];
128 
134  protected ‪$fileIdMap = [];
135 
142  protected ‪$relStaticTables = [];
143 
149  protected ‪$excludeMap = [];
150 
156  protected ‪$softrefCfg = [];
157 
163  protected ‪$extensionDependencies = [];
164 
170  protected ‪$importMapId = [];
171 
177  protected ‪$errorLog = [];
178 
184  protected ‪$cacheGetRecordPath = [];
185 
191  protected ‪$dat = [];
192 
198  protected ‪$fileProcObj;
199 
203  protected ‪$diffUtility;
204 
208  protected ‪$remainHeader = [];
209 
213  protected ‪$lang;
214 
218  protected ‪$iconFactory;
219 
225  protected ‪$fileadminFolderName = '';
226 
227  protected ?string ‪$temporaryFolderName = null;
228  protected ?‪Folder ‪$defaultImportExportFolder = null;
229 
236  protected ‪$excludeDisabledRecords = false;
237 
243  protected ‪$storages = [];
244 
250  protected ‪$storagesAvailableForImport = [];
251 
255  protected ?‪ResourceStorage ‪$defaultStorage = null;
256 
260  protected ‪$storageRepository;
261 
265  public function ‪__construct()
266  {
267  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
268  $this->lang = $this->‪getLanguageService();
269  $this->lang->includeLLFile('EXT:impexp/Resources/Private/Language/locallang.xlf');
270  $this->permsClause = $this->‪getBackendUser()->‪getPagePermsClause(‪Permission::PAGE_SHOW);
271 
272  $this->‪fetchStorages();
273  }
274 
281  protected function ‪fetchStorages(): void
282  {
283  $this->storages = [];
284  $this->storagesAvailableForImport = [];
285  $this->defaultStorage = null;
286 
287  $this->‪getStorageRepository()->‪flush();
288 
289  $storages = $this->‪getStorageRepository()->‪findAll();
290  // @todo: Why by reference here? Test ImagesWithStoragesTest::importMultipleImagesWithMultipleStorages fails otherwise
291  foreach ($storages as &$storage) {
292  $this->storages[$storage->getUid()] = $storage;
293  if ($storage->isOnline() && $storage->isWritable() && $storage->getDriverType() === 'Local') {
294  $this->storagesAvailableForImport[$storage->getUid()] = $storage;
295  }
296  if ($this->defaultStorage === null && $storage->isDefault()) {
297  $this->defaultStorage = $storage;
298  }
299  }
300  }
301 
302  /********************************************************
303  * Visual rendering of import/export memory, $this->dat
304  ********************************************************/
305 
311  public function ‪renderPreview(): array
312  {
313  // @todo: Why is this done?
314  unset($this->dat['files']);
315 
316  $previewData = [
317  'update' => ‪$this->update,
318  'showDiff' => ‪$this->showDiff,
319  'insidePageTree' => [],
320  'outsidePageTree' => [],
321  ];
322 
323  if (!isset($this->dat['header']['pagetree']) && !isset($this->dat['header']['records'])) {
324  return $previewData;
325  }
326 
327  // Traverse header:
328  $this->remainHeader = $this->dat['header'];
329 
330  // Preview of the page tree to be exported
331  if (is_array($this->dat['header']['pagetree'] ?? null)) {
332  $this->‪traversePageTree($this->dat['header']['pagetree'], $previewData['insidePageTree']);
333  foreach ($previewData['insidePageTree'] as &$line) {
334  $line['controls'] = $this->‪renderControls($line);
335  $line['message'] = (($line['msg'] ?? '') && !$this->doesImport ? '<span class="text-danger">' . htmlspecialchars($line['msg']) . '</span>' : '');
336  }
337  }
338 
339  // Preview the remaining records that were not included in the page tree
340  if (is_array($this->remainHeader['records'] ?? null)) {
341  if (is_array($this->remainHeader['records']['pages'] ?? null)) {
342  $this->‪traversePageRecords($this->remainHeader['records']['pages'], $previewData['outsidePageTree']);
343  }
344  $this->‪traverseAllRecords($this->remainHeader['records'], $previewData['outsidePageTree']);
345  foreach ($previewData['outsidePageTree'] as &$line) {
346  $line['controls'] = $this->‪renderControls($line);
347  $line['message'] = (($line['msg'] ?? '') && !$this->doesImport ? '<span class="text-danger">' . htmlspecialchars($line['msg']) . '</span>' : '');
348  }
349  }
350 
351  return $previewData;
352  }
353 
361  protected function ‪traversePageTree(array $pageTree, array &$lines, int $indent = 0): void
362  {
363  foreach ($pageTree as $pageUid => $page) {
364  if ($this->excludeDisabledRecords === true && $this->‪isRecordDisabled('pages', $pageUid)) {
365  $this->‪excludePageAndRecords($pageUid, $page);
366  continue;
367  }
368 
369  // Add page
370  $this->‪addRecord('pages', $pageUid, $lines, $indent);
371 
372  // Add records
373  if (is_array($this->dat['header']['pid_lookup'][$pageUid] ?? null)) {
374  foreach ($this->dat['header']['pid_lookup'][$pageUid] as $table => $records) {
375  $table = (string)$table;
376  if ($table !== 'pages') {
377  foreach (array_keys($records) as $uid) {
378  $this->‪addRecord($table, (int)$uid, $lines, $indent + 2);
379  }
380  }
381  }
382  unset($this->remainHeader['pid_lookup'][$pageUid]);
383  }
384 
385  // Add subtree
386  if (is_array($page['subrow'] ?? null)) {
387  $this->‪traversePageTree($page['subrow'], $lines, $indent + 2);
388  }
389  }
390  }
391 
399  protected function ‪isRecordDisabled(string $table, int $uid): bool
400  {
401  return (bool)($this->dat['records'][$table . ':' . $uid]['data'][
402  ‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] ?? ''
403  ] ?? false);
404  }
405 
412  protected function ‪excludePageAndRecords(int $pageUid, array $page): void
413  {
414  // Exclude page
415  unset($this->remainHeader['records']['pages'][$pageUid]);
416 
417  // Exclude records
418  if (is_array($this->dat['header']['pid_lookup'][$pageUid] ?? null)) {
419  foreach ($this->dat['header']['pid_lookup'][$pageUid] as $table => $records) {
420  if ($table !== 'pages') {
421  foreach (array_keys($records) as $uid) {
422  unset($this->remainHeader['records'][$table][$uid]);
423  }
424  }
425  }
426  unset($this->remainHeader['pid_lookup'][$pageUid]);
427  }
428 
429  // Exclude subtree
430  if (is_array($page['subrow'] ?? null)) {
431  foreach ($page['subrow'] as $subPageUid => $subPage) {
432  $this->‪excludePageAndRecords($subPageUid, $subPage);
433  }
434  }
435  }
436 
443  protected function ‪traversePageRecords(array $pageTree, array &$lines): void
444  {
445  foreach ($pageTree as $pageUid => $_) {
446  // Add page
447  $this->‪addRecord('pages', (int)$pageUid, $lines, 0, true);
448 
449  // Add records
450  if (is_array($this->dat['header']['pid_lookup'][$pageUid] ?? null)) {
451  foreach ($this->dat['header']['pid_lookup'][$pageUid] as $table => $records) {
452  if ($table !== 'pages') {
453  foreach (array_keys($records) as $uid) {
454  $this->‪addRecord((string)$table, (int)$uid, $lines, 2);
455  }
456  }
457  }
458  unset($this->remainHeader['pid_lookup'][$pageUid]);
459  }
460  }
461  }
462 
469  protected function ‪traverseAllRecords(array $pageTree, array &$lines): void
470  {
471  foreach ($pageTree as $table => $records) {
472  $this->‪addGeneralErrorsByTable($table);
473  if ($table !== 'pages') {
474  foreach (array_keys($records) as $uid) {
475  $this->‪addRecord((string)$table, (int)$uid, $lines, 0, true);
476  }
477  }
478  }
479  }
480 
486  protected function ‪addGeneralErrorsByTable(string $table): void
487  {
488  if ($this->update && $table === 'sys_file') {
489  $this->‪addError('Updating sys_file records is not supported! They will be imported as new records!');
490  }
491  if ($this->forceAllUids && $table === 'sys_file') {
492  $this->‪addError('Forcing uids of sys_file records is not supported! They will be imported as new records!');
493  }
494  }
495 
505  protected function ‪addRecord(string $table, int $uid, array &$lines, int $indent, bool $checkImportInPidRecord = false): void
506  {
507  $record = $this->dat['header']['records'][$table][$uid] ?? null;
508  unset($this->remainHeader['records'][$table][$uid]);
509  if (!is_array($record) && !($table === 'pages' && $uid === 0)) {
510  $this->‪addError('MISSING RECORD: ' . $table . ':' . $uid);
511  }
512 
513  // Create record information for preview
514  $line = [];
515  $line['ref'] = $table . ':' . $uid;
516  $line['type'] = 'record';
517  $line['msg'] = '';
518  if ($table === '_SOFTREF_') {
519  // Record is a soft reference
520  $line['preCode'] = $this->‪renderIndent($indent);
521  $line['title'] = '<em>' . htmlspecialchars($this->lang->getLL('impexpcore_singlereco_softReferencesFiles')) . '</em>';
522  } elseif (!isset(‪$GLOBALS['TCA'][$table])) {
523  // Record is of unknown table
524  $line['preCode'] = $this->‪renderIndent($indent);
525  $line['title'] = '<em>' . htmlspecialchars((string)$record['title']) . '</em>';
526  $line['msg'] = 'UNKNOWN TABLE "' . $line['ref'] . '"';
527  } else {
528  ‪$pidRecord = $this->‪getPidRecord();
529  $icon = $this->iconFactory->getIconForRecord(
530  $table,
531  (array)($this->dat['records'][$table . ':' . $uid]['data'] ?? []),
533  )->render();
534  $line['preCode'] = sprintf(
535  '%s<span title="%s">%s</span>',
536  $this->‪renderIndent($indent),
537  htmlspecialchars($line['ref']),
538  $icon
539  );
540  $line['title'] = htmlspecialchars($record['title'] ?? '');
541  // Link to page view
542  if ($table === 'pages') {
543  $viewID = $this->mode === 'export' ? $uid : ($this->doesImport ? ($this->importMapId['pages'][$uid] ?? 0) : 0);
544  if ($viewID) {
545  $attributes = ‪PreviewUriBuilder::create($viewID)->serializeDispatcherAttributes();
546  $line['title'] = sprintf('<a href="#" %s>%s</a>', $attributes, $line['title']);
547  }
548  }
549  $line['active'] = !$this->‪isRecordDisabled($table, $uid) ? 'active' : 'hidden';
550  if ($this->mode === 'import' && ‪$pidRecord !== null) {
551  if ($checkImportInPidRecord) {
552  if (!$this->‪getBackendUser()->doesUserHaveAccess(‪$pidRecord, ($table === 'pages' ? 8 : 16))) {
553  $line['msg'] .= '"' . $line['ref'] . '" cannot be INSERTED on this page! ';
554  }
555  if ($this->pid > 0 && !$this->‪checkDokType($table, ‪$pidRecord['doktype']) && !‪$GLOBALS['TCA'][$table]['ctrl']['rootLevel']) {
556  $line['msg'] .= '"' . $table . '" cannot be INSERTED on this page type (change page type to "Folder".) ';
557  }
558  }
559  if (!$this->‪getBackendUser()->check('tables_modify', $table)) {
560  $line['msg'] .= 'You are not allowed to CREATE "' . $table . '" tables! ';
561  }
562  if (‪$GLOBALS['TCA'][$table]['ctrl']['readOnly'] ?? false) {
563  $line['msg'] .= 'TABLE "' . $table . '" is READ ONLY! ';
564  }
565  if ((‪$GLOBALS['TCA'][$table]['ctrl']['adminOnly'] ?? false) && !$this->‪getBackendUser()->isAdmin()) {
566  $line['msg'] .= 'TABLE "' . $table . '" is ADMIN ONLY! ';
567  }
568  if (‪$GLOBALS['TCA'][$table]['ctrl']['is_static'] ?? false) {
569  $line['msg'] .= 'TABLE "' . $table . '" is a STATIC TABLE! ';
570  }
571  if ((int)(‪$GLOBALS['TCA'][$table]['ctrl']['rootLevel'] ?? 0) === 1) {
572  $line['msg'] .= 'TABLE "' . $table . '" will be inserted on ROOT LEVEL! ';
573  }
574  $databaseRecord = null;
575  if ($this->update) {
576  $databaseRecord = $this->‪getRecordFromDatabase($table, $uid, $this->showDiff ? '*' : 'uid,pid');
577  if ($databaseRecord === null) {
578  $line['updatePath'] = '<strong>NEW!</strong>';
579  } else {
580  $line['updatePath'] = htmlspecialchars($this->‪getRecordPath((int)($databaseRecord['pid'] ?? 0)));
581  }
582  if ($table === 'sys_file') {
583  $line['updateMode'] = '';
584  } else {
585  $line['updateMode'] = $this->‪renderImportModeSelector(
586  $table,
587  $uid,
588  $databaseRecord !== null
589  );
590  }
591  }
592  // Diff view
593  if ($this->showDiff) {
594  $diffInverse = $this->update ? true : false;
595  // For imports, get new id:
596  if (isset($this->importMapId[$table][$uid]) && $newUid = $this->importMapId[$table][$uid]) {
597  $diffInverse = false;
598  $databaseRecord = $this->‪getRecordFromDatabase($table, $newUid, '*');
599  BackendUtility::workspaceOL($table, $databaseRecord);
600  }
601  $importRecord = $this->dat['records'][$table . ':' . $uid]['data'] ?? null;
602  if (is_array($databaseRecord) && is_array($importRecord)) {
603  $line['showDiffContent'] = $this->‪compareRecords($databaseRecord, $importRecord, $table, $diffInverse);
604  } else {
605  $line['showDiffContent'] = 'ERROR: One of the inputs were not an array!';
606  }
607  }
608  }
609  }
610  $lines[] = $line;
611 
612  // File relations
613  if (is_array($record['filerefs'] ?? null)) {
614  $this->‪addFiles($record['filerefs'], $lines, $indent);
615  }
616  // Database relations
617  if (is_array($record['rels'] ?? null)) {
618  $this->‪addRelations($record['rels'], $lines, $indent);
619  }
620  // Soft references
621  if (is_array($record['softrefs'] ?? null)) {
622  $this->‪addSoftRefs($record['softrefs'], $lines, $indent);
623  }
624  }
625 
636  protected function ‪addRelations(array $relations, array &$lines, int $indent, array $recursionCheck = []): void
637  {
638  foreach ($relations as $relation) {
639  $table = $relation['table'];
640  $uid = $relation['id'];
641  $line = [];
642  $line['ref'] = $table . ':' . $uid;
643  $line['type'] = 'rel';
644  $line['msg'] = '';
645  if (in_array($line['ref'], $recursionCheck, true)) {
646  continue;
647  }
648  $iconName = 'status-status-checked';
649  $iconClass = '';
650  $staticFixed = false;
651  $record = null;
652  if ($uid > 0) {
653  $record = $this->dat['header']['records'][$table][$uid] ?? null;
654  if (!is_array($record)) {
655  if ($this->‪isTableStatic($table) || $this->‪isRecordExcluded($table, (int)$uid)
656  || ($relation['tokenID'] ?? '') && !$this->‪isSoftRefIncluded($relation['tokenID'] ?? '')) {
657  $line['title'] = htmlspecialchars('STATIC: ' . $line['ref']);
658  $iconClass = 'text-info';
659  $staticFixed = true;
660  } else {
661  $databaseRecord = $this->‪getRecordFromDatabase($table, (int)$uid);
662  $recordPath = $this->‪getRecordPath($databaseRecord === null ? 0 : ($table === 'pages' ? (int)$databaseRecord['uid'] : (int)$databaseRecord['pid']));
663  $line['title'] = sprintf(
664  '<span title="%s">%s</span>',
665  htmlspecialchars($recordPath),
666  htmlspecialchars($line['ref'])
667  );
668  $line['msg'] = 'LOST RELATION' . ($databaseRecord === null ? ' (Record not found!)' : ' (Path: ' . $recordPath . ')');
669  $iconClass = 'text-danger';
670  $iconName = 'status-dialog-warning';
671  }
672  } else {
673  $recordPath = $this->‪getRecordPath($table === 'pages' ? (int)$record['uid'] : (int)$record['pid']);
674  $line['title'] = sprintf(
675  '<span title="%s">%s</span>',
676  htmlspecialchars($recordPath),
677  htmlspecialchars((string)$record['title'])
678  );
679  }
680  } else {
681  // Negative values in relation fields. These are typically fields of sys_language, fe_users etc.
682  // They are static values. They CAN theoretically be negative pointers to uids in other tables,
683  // but this is so rarely used that it is not supported.
684  $line['title'] = htmlspecialchars('FIXED: ' . $line['ref']);
685  $staticFixed = true;
686  }
687 
688  $icon = $this->iconFactory->getIcon($iconName, ‪Icon::SIZE_SMALL)->render();
689  $line['preCode'] = sprintf(
690  '%s<span class="%s" title="%s">%s</span>',
691  $this->‪renderIndent($indent + 2),
692  $iconClass,
693  htmlspecialchars($line['ref']),
694  $icon
695  );
696  if (!$staticFixed || $this->showStaticRelations) {
697  $lines[] = $line;
698  if (is_array($record) && is_array($record['rels'] ?? null)) {
699  $this->‪addRelations($record['rels'], $lines, $indent + 1, array_merge($recursionCheck, [$line['ref']]));
700  }
701  }
702  }
703  }
704 
717  public function ‪addFiles(array $relations, array &$lines, int $indent, string $tokenID = ''): void
718  {
719  foreach ($relations as $ID) {
720  $line = [];
721  $line['msg'] = '';
722  $fileInfo = $this->dat['header']['files'][$ID];
723  if (!is_array($fileInfo)) {
724  if ($tokenID !== '' || $this->‪isSoftRefIncluded($tokenID)) {
725  $line['msg'] = 'MISSING FILE: ' . $ID;
726  $this->‪addError('MISSING FILE: ' . $ID);
727  } else {
728  return;
729  }
730  }
731  $line['ref'] = 'FILE';
732  $line['type'] = 'file';
733  $line['preCode'] = sprintf(
734  '%s<span title="%s">%s</span>',
735  $this->‪renderIndent($indent + 2),
736  htmlspecialchars($line['ref']),
737  $this->iconFactory->getIcon('status-reference-hard', ‪Icon::SIZE_SMALL)->render()
738  );
739  $line['title'] = htmlspecialchars($fileInfo['filename']);
740  $line['showDiffContent'] = ‪PathUtility::stripPathSitePrefix((string)($this->fileIdMap[$ID] ?? ''));
741  // If import mode and there is a non-RTE soft reference, check the destination directory.
742  if ($this->mode === 'import' && $tokenID !== '' && !($fileInfo['RTE_ORIG_ID'] ?? false)) {
743  // Check folder existence
744  if (isset($fileInfo['parentRelFileName'])) {
745  $line['msg'] = 'Seems like this file is already referenced from within an HTML/CSS file. That takes precedence. ';
746  } else {
747  $origDirPrefix = ‪PathUtility::dirname($fileInfo['relFileName']) . '/';
748  $dirPrefix = $this->‪resolveStoragePath($origDirPrefix);
749  if ($dirPrefix === null) {
750  $line['msg'] = 'ERROR: There are no available file mounts to write file in! ';
751  } elseif ($origDirPrefix !== $dirPrefix) {
752  $line['msg'] = 'File will be attempted written to "' . $dirPrefix . '". ';
753  }
754  }
755  // Check file existence
756  if (file_exists(‪Environment::getPublicPath() . '/' . $fileInfo['relFileName'])) {
757  if ($this->update) {
758  $line['updatePath'] .= 'File exists.';
759  } else {
760  $line['msg'] .= 'File already exists! ';
761  }
762  }
763  // Check file extension
765  if ($fileProcObj->actionPerms['addFile']) {
766  $pathInfo = GeneralUtility::split_fileref(‪Environment::getPublicPath() . '/' . $fileInfo['relFileName']);
767  if (!GeneralUtility::makeInstance(FileNameValidator::class)->isValid($pathInfo['file'])) {
768  $line['msg'] .= 'File extension was not allowed!';
769  }
770  } else {
771  $line['msg'] = 'Your user profile does not allow you to create files on the server!';
772  }
773  }
774  $lines[] = $line;
775  unset($this->remainHeader['files'][$ID]);
776 
777  // RTE originals
778  if ($fileInfo['RTE_ORIG_ID'] ?? false) {
779  $ID = $fileInfo['RTE_ORIG_ID'];
780  $line = [];
781  $fileInfo = $this->dat['header']['files'][$ID];
782  if (!is_array($fileInfo)) {
783  $line['msg'] = 'MISSING RTE original FILE: ' . $ID;
784  $this->‪addError('MISSING RTE original FILE: ' . $ID);
785  }
786  $line['ref'] = 'FILE';
787  $line['type'] = 'file';
788  $line['preCode'] = sprintf(
789  '%s<span title="%s">%s</span>',
790  $this->‪renderIndent($indent + 4),
791  htmlspecialchars($line['ref']),
792  $this->iconFactory->getIcon('status-reference-hard', ‪Icon::SIZE_SMALL)->render()
793  );
794  $line['title'] = htmlspecialchars($fileInfo['filename']) . ' <em>(Original)</em>';
795  $line['showDiffContent'] = ‪PathUtility::stripPathSitePrefix($this->fileIdMap[$ID]);
796  $lines[] = $line;
797  unset($this->remainHeader['files'][$ID]);
798  }
799 
800  // External resources
801  if (is_array($fileInfo['EXT_RES_ID'] ?? null)) {
802  foreach ($fileInfo['EXT_RES_ID'] as $extID) {
803  $line = [];
804  $fileInfo = $this->dat['header']['files'][$extID];
805  if (!is_array($fileInfo)) {
806  $line['msg'] = 'MISSING External Resource FILE: ' . $extID;
807  $this->‪addError('MISSING External Resource FILE: ' . $extID);
808  } else {
809  $line['updatePath'] = $fileInfo['parentRelFileName'];
810  }
811  $line['ref'] = 'FILE';
812  $line['type'] = 'file';
813  $line['preCode'] = sprintf(
814  '%s<span title="%s">%s</span>',
815  $this->‪renderIndent($indent + 4),
816  htmlspecialchars($line['ref']),
817  $this->iconFactory->getIcon('actions-insert-reference', ‪Icon::SIZE_SMALL)->render()
818  );
819  $line['title'] = htmlspecialchars($fileInfo['filename']) . ' <em>(Resource)</em>';
820  $line['showDiffContent'] = ‪PathUtility::stripPathSitePrefix($this->fileIdMap[$extID]);
821  $lines[] = $line;
822  unset($this->remainHeader['files'][$extID]);
823  }
824  }
825  }
826  }
827 
837  protected function ‪addSoftRefs(array $softrefs, array &$lines, int $indent): void
838  {
839  foreach ($softrefs as $softref) {
840  $line = [];
841  $line['ref'] = 'SOFTREF';
842  $line['type'] = 'softref';
843  $line['msg'] = '';
844  $line['preCode'] = sprintf(
845  '%s<span title="%s">%s</span>',
846  $this->‪renderIndent($indent + 2),
847  htmlspecialchars($line['ref']),
848  $this->iconFactory->getIcon('status-reference-soft', ‪Icon::SIZE_SMALL)->render()
849  );
850  $line['title'] = sprintf(
851  '<em>%s, "%s"</em> : <span title="%s">%s</span>',
852  $softref['field'],
853  $softref['spKey'],
854  htmlspecialchars($softref['matchString'] ?? ''),
855  htmlspecialchars(GeneralUtility::fixed_lgd_cs($softref['matchString'] ?? '', 60))
856  );
857  if ($softref['subst']['type'] ?? false) {
858  if ($softref['subst']['title'] ?? false) {
859  $line['title'] .= sprintf(
860  '<br/>%s<strong>%s</strong> %s',
861  $this->‪renderIndent($indent + 4),
862  htmlspecialchars($this->lang->getLL('impexpcore_singlereco_title')),
863  htmlspecialchars(GeneralUtility::fixed_lgd_cs($softref['subst']['title'], 60))
864  );
865  }
866  if ($softref['subst']['description'] ?? false) {
867  $line['title'] .= sprintf(
868  '<br/>%s<strong>%s</strong> %s',
869  $this->‪renderIndent($indent + 4),
870  htmlspecialchars($this->lang->getLL('impexpcore_singlereco_descr')),
871  htmlspecialchars(GeneralUtility::fixed_lgd_cs($softref['subst']['description'], 60))
872  );
873  }
874  if ($softref['subst']['type'] === 'db') {
875  $line['title'] .= sprintf(
876  '<br/>%s%s <strong>%s</strong>',
877  $this->‪renderIndent($indent + 4),
878  htmlspecialchars($this->lang->getLL('impexpcore_softrefsel_record')),
879  $softref['subst']['recordRef']
880  );
881  } elseif ($softref['subst']['type'] === 'file') {
882  $line['title'] .= sprintf(
883  '<br/>%s%s <strong>%s</strong>',
884  $this->‪renderIndent($indent + 4),
885  htmlspecialchars($this->lang->getLL('impexpcore_singlereco_filename')),
886  $softref['subst']['relFileName']
887  );
888  } elseif ($softref['subst']['type'] === 'string') {
889  $line['title'] .= sprintf(
890  '<br/>%s%s <strong>%s</strong>',
891  $this->‪renderIndent($indent + 4),
892  htmlspecialchars($this->lang->getLL('impexpcore_singlereco_value')),
893  $softref['subst']['tokenValue']
894  );
895  }
896  }
897  $line['_softRefInfo'] = $softref;
898  ‪$mode = $this->softrefCfg[$softref['subst']['tokenID'] ?? null]['mode'] ?? '';
900  $line['msg'] .= $softref['error'];
901  }
902  $lines[] = $line;
903 
904  // Add database relations
905  if (($softref['subst']['type'] ?? '') === 'db') {
906  [$referencedTable, $referencedUid] = explode(':', $softref['subst']['recordRef']);
907  $relations = [['table' => $referencedTable, 'id' => $referencedUid, 'tokenID' => $softref['subst']['tokenID']]];
908  $this->‪addRelations($relations, $lines, $indent + 4);
909  }
910  // Add files relations
911  if (($softref['subst']['type'] ?? '') === 'file') {
912  $relations = [$softref['file_ID']];
913  $this->‪addFiles($relations, $lines, $indent + 4, $softref['subst']['tokenID']);
914  }
915  }
916  }
917 
918  protected function ‪renderIndent(int $indent): string
919  {
920  return str_repeat('&nbsp;&nbsp;', $indent);
921  }
922 
930  protected function ‪checkDokType(string $table, int $dokType): bool
931  {
932  $allowedTableList = ‪$GLOBALS['PAGES_TYPES'][$dokType]['allowedTables'] ?? ‪$GLOBALS['PAGES_TYPES']['default']['allowedTables'];
933  $allowedArray = ‪GeneralUtility::trimExplode(',', $allowedTableList, true);
934  if (str_contains($allowedTableList, '*') || in_array($table, $allowedArray, true)) {
935  return true;
936  }
937  return false;
938  }
939 
946  protected function ‪renderControls(array $line): string
947  {
948  if ($this->mode === 'export') {
949  if ($line['type'] === 'record') {
950  return $this->‪renderRecordExcludeCheckbox($line['ref']);
951  }
952  if ($line['type'] === 'softref') {
953  return $this->‪renderSoftRefExportSelector($line['_softRefInfo']);
954  }
955  } elseif ($this->mode === 'import') {
956  if ($line['type'] === 'softref') {
957  return $this->‪renderSoftRefImportTextField($line['_softRefInfo']);
958  }
959  }
960  return '';
961  }
962 
969  protected function ‪renderRecordExcludeCheckbox(string $recordRef): string
970  {
971  return sprintf(
972  '
973  <input type="checkbox" class="t3js-exclude-checkbox" name="tx_impexp[exclude][%1$s]" id="checkExclude%1$s" value="1" />
974  <label for="checkExclude%1$s">%2$s</label>',
975  $recordRef,
976  htmlspecialchars($this->lang->getLL('impexpcore_singlereco_exclude'))
977  );
978  }
979 
986  protected function ‪renderSoftRefImportTextField(array $softref): string
987  {
988  if (isset($softref['subst']['tokenID'])) {
989  $tokenID = $softref['subst']['tokenID'];
990  $cfg = $this->softrefCfg[$tokenID] ?? [];
991  if (($cfg['mode'] ?? '') === ‪Import::SOFTREF_IMPORT_MODE_EDITABLE) {
992  $html = '';
993  if ($cfg['title'] ?? false) {
994  $html .= '<strong>' . htmlspecialchars((string)$cfg['title']) . '</strong><br/>';
995  }
996  $html .= htmlspecialchars((string)$cfg['description']) . '<br/>';
997  $html .= sprintf(
998  '<input type="text" name="tx_impexp[softrefInputValues][%s]" value="%s" />',
999  $tokenID,
1000  htmlspecialchars($this->softrefInputValues[$tokenID] ?? $cfg['defValue'])
1001  );
1002  return $html;
1003  }
1004  }
1005 
1006  return '';
1007  }
1008 
1016  protected function ‪renderSoftRefExportSelector(array $softref): string
1017  {
1018  $fileInfo = isset($softref['file_ID']) ? $this->dat['header']['files'][$softref['file_ID']] : [];
1019  // Substitution scheme has to be around and RTE images MUST be exported.
1020  if (isset($softref['subst']['tokenID']) && !isset($fileInfo['RTE_ORIG_ID'])) {
1021  $options = [];
1022  $options[''] = '';
1023  $options[‪Import::SOFTREF_IMPORT_MODE_EDITABLE] = $this->lang->getLL('impexpcore_softrefsel_editable');
1024  $options[‪Import::SOFTREF_IMPORT_MODE_EXCLUDE] = $this->lang->getLL('impexpcore_softrefsel_exclude');
1025  $value = $this->softrefCfg[$softref['subst']['tokenID']]['mode'] ?? '';
1026  $selectHtml = $this->‪renderSelectBox(
1027  'tx_impexp[softrefCfg][' . $softref['subst']['tokenID'] . '][mode]',
1028  $value,
1029  $options
1030  ) . '<br/>';
1031  $textFieldHtml = '';
1032  if ($value === ‪Import::SOFTREF_IMPORT_MODE_EDITABLE) {
1033  if ($softref['subst']['title'] ?? false) {
1034  $textFieldHtml .= sprintf(
1035  '
1036  <input type="hidden" name="tx_impexp[softrefCfg][%1$s][title]" value="%2$s" />
1037  <strong>%2$s</strong><br/>',
1038  $softref['subst']['tokenID'],
1039  htmlspecialchars($softref['subst']['title'])
1040  );
1041  }
1042  if (!($softref['subst']['description'] ?? false)) {
1043  $textFieldHtml .= sprintf(
1044  '
1045  %s<br/>
1046  <input type="text" name="tx_impexp[softrefCfg][%s][description]" value="%s" />',
1047  htmlspecialchars($this->lang->getLL('impexpcore_printerror_description')),
1048  $softref['subst']['tokenID'],
1049  htmlspecialchars($this->softrefCfg[$softref['subst']['tokenID']]['description'] ?? '')
1050  );
1051  } else {
1052  $textFieldHtml .= sprintf(
1053  '
1054  <input type="hidden" name="tx_impexp[softrefCfg][%1$s][description]" value="%2$s" />%2$s',
1055  $softref['subst']['tokenID'],
1056  htmlspecialchars($softref['subst']['description'])
1057  );
1058  }
1059  $textFieldHtml .= sprintf(
1060  '
1061  <input type="hidden" name="tx_impexp[softrefCfg][%s][defValue]" value="%s" />',
1062  $softref['subst']['tokenID'],
1063  htmlspecialchars($softref['subst']['tokenValue'])
1064  );
1065  }
1066  return $selectHtml . $textFieldHtml;
1067  }
1068  return '';
1069  }
1070 
1079  protected function ‪renderImportModeSelector(string $table, int $uid, bool $doesRecordExist): string
1080  {
1081  $options = [];
1082  if (!$doesRecordExist) {
1083  $options[] = $this->lang->getLL('impexpcore_singlereco_insert');
1084  if ($this->‪getBackendUser()->isAdmin()) {
1085  $options[‪Import::IMPORT_MODE_FORCE_UID] = sprintf($this->lang->getLL('impexpcore_singlereco_forceUidSAdmin'), $uid);
1086  }
1087  } else {
1088  $options[] = $this->lang->getLL('impexpcore_singlereco_update');
1089  $options[‪Import::IMPORT_MODE_AS_NEW] = $this->lang->getLL('impexpcore_singlereco_importAsNew');
1090  if (!$this->globalIgnorePid) {
1091  $options[‪Import::IMPORT_MODE_IGNORE_PID] = $this->lang->getLL('impexpcore_singlereco_ignorePid');
1092  } else {
1093  $options[‪Import::IMPORT_MODE_RESPECT_PID] = $this->lang->getLL('impexpcore_singlereco_respectPid');
1094  }
1095  }
1096  $options[‪Import::IMPORT_MODE_EXCLUDE] = $this->lang->getLL('impexpcore_singlereco_exclude');
1097  return $this->‪renderSelectBox(
1098  'tx_impexp[import_mode][' . $table . ':' . $uid . ']',
1099  (string)($this->importMode[$table . ':' . $uid] ?? ''),
1100  $options
1101  );
1102  }
1103 
1112  protected function ‪renderSelectBox(string $name, string $value, array $options): string
1113  {
1114  $optionsHtml = '';
1115  $isValueInOptions = false;
1116 
1117  foreach ($options as $k => $v) {
1118  if ((string)$k === $value) {
1119  $isValueInOptions = true;
1120  $selectedHtml = ' selected="selected"';
1121  } else {
1122  $selectedHtml = '';
1123  }
1124  $optionsHtml .= sprintf(
1125  '<option value="%s"%s>%s</option>',
1126  htmlspecialchars((string)$k),
1127  $selectedHtml,
1128  htmlspecialchars((string)$v)
1129  );
1130  }
1131 
1132  // Append and select the current value as an option of the form "[value]"
1133  // if it is not available in the options.
1134  if (!$isValueInOptions && $value !== '') {
1135  $optionsHtml .= sprintf(
1136  '<option value="%s" selected="selected">%s</option>',
1137  htmlspecialchars($value),
1138  htmlspecialchars('[\'' . $value . '\']')
1139  );
1140  }
1141 
1142  return '<select name="' . $name . '">' . $optionsHtml . '</select>';
1143  }
1144 
1145  /*****************************
1146  * Helper functions of kinds
1147  *****************************/
1148 
1152  public function getFileadminFolderName(): string
1153  {
1154  if (empty($this->fileadminFolderName)) {
1155  if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'])) {
1156  $this->fileadminFolderName = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/');
1157  } else {
1158  $this->fileadminFolderName = 'fileadmin';
1159  }
1160  }
1161  return $this->fileadminFolderName;
1162  }
1163 
1167  public function getOrCreateTemporaryFolderName(): string
1168  {
1169  if (empty($this->temporaryFolderName)) {
1170  $this->temporaryFolderName = $this->createTemporaryFolderName();
1171  }
1172  return $this->temporaryFolderName;
1173  }
1175  protected function createTemporaryFolderName(): string
1176  {
1177  $temporaryPath = Environment::getVarPath() . '/transient';
1178  do {
1179  $temporaryFolderName = sprintf(
1180  '%s/impexp_%s_files_%d',
1181  $temporaryPath,
1182  $this->mode,
1183  random_int(1, PHP_INT_MAX)
1184  );
1185  } while (is_dir($temporaryFolderName));
1186  GeneralUtility::mkdir_deep($temporaryFolderName);
1187  return $temporaryFolderName;
1188  }
1189 
1190  public function removeTemporaryFolderName(): void
1191  {
1192  if (!empty($this->temporaryFolderName)) {
1193  GeneralUtility::rmdir($this->temporaryFolderName, true);
1194  $this->temporaryFolderName = null;
1195  }
1196  }
1197 
1204  public function getOrCreateDefaultImportExportFolder(): ?Folder
1205  {
1206  if (empty($this->defaultImportExportFolder)) {
1207  $this->createDefaultImportExportFolder();
1208  }
1209  return $this->defaultImportExportFolder;
1210  }
1211 
1216  protected function createDefaultImportExportFolder(): void
1217  {
1218  $defaultTemporaryFolder = $this->getBackendUser()->getDefaultUploadTemporaryFolder();
1219  $defaultImportExportFolder = null;
1220  $importExportFolderName = 'importexport';
1221 
1222  if ($defaultTemporaryFolder !== null) {
1223  if ($defaultTemporaryFolder->hasFolder($importExportFolderName) === false) {
1224  $defaultImportExportFolder = $defaultTemporaryFolder->createFolder($importExportFolderName);
1225  } else {
1226  $defaultImportExportFolder = $defaultTemporaryFolder->getSubfolder($importExportFolderName);
1227  }
1228  }
1229  $this->defaultImportExportFolder = $defaultImportExportFolder;
1230  }
1231 
1232  public function removeDefaultImportExportFolder(): void
1233  {
1234  if (!empty($this->defaultImportExportFolder)) {
1235  $this->defaultImportExportFolder->delete(true);
1236  $this->defaultImportExportFolder = null;
1237  }
1238  }
1239 
1249  protected function resolveStoragePath(string $dirPrefix, bool $checkAlternatives = true): ?string
1250  {
1251  try {
1252  GeneralUtility::makeInstance(ResourceFactory::class)->getFolderObjectFromCombinedIdentifier($dirPrefix);
1253  return $dirPrefix;
1254  } catch (InsufficientFolderAccessPermissionsException $e) {
1255  if ($checkAlternatives) {
1256  $storagesByUser = $this->getBackendUser()->getFileStorages();
1257  foreach ($storagesByUser as $storage) {
1258  try {
1259  $folder = $storage->getFolder(rtrim($dirPrefix, '/'));
1260  return $folder->getPublicUrl();
1261  } catch (InsufficientFolderAccessPermissionsException $e) {
1262  }
1263  }
1264  }
1265  }
1266  return null;
1267  }
1268 
1276  protected function flatInversePageTree(array $pageTree, array &$list, int $pid = -1): void
1277  {
1278  // @todo: return $list instead of by-reference?!
1279  $pageTreeInverse = array_reverse($pageTree);
1280  foreach ($pageTreeInverse as $page) {
1281  $list[$page['uid']] = $pid;
1282  if (is_array($page['subrow'] ?? null)) {
1283  $this->flatInversePageTree($page['subrow'], $list, (int)$page['uid']);
1284  }
1285  }
1286  }
1287 
1294  protected function isTableStatic(string $table): bool
1295  {
1296  if (is_array($GLOBALS['TCA'][$table] ?? null)) {
1297  return ($GLOBALS['TCA'][$table]['ctrl']['is_static'] ?? false)
1298  || in_array($table, $this->relStaticTables, true)
1299  || in_array('_ALL', $this->relStaticTables, true);
1300  }
1301  return false;
1302  }
1303 
1311  protected function isRecordExcluded(string $table, int $uid): bool
1312  {
1313  return (bool)($this->excludeMap[$table . ':' . $uid] ?? false);
1314  }
1315 
1322  protected function isSoftRefIncluded(string $tokenID): bool
1323  {
1324  $mode = $this->softrefCfg[$tokenID]['mode'] ?? '';
1325  return $tokenID && $mode !== Import::SOFTREF_IMPORT_MODE_EXCLUDE && $mode !== Import::SOFTREF_IMPORT_MODE_EDITABLE;
1326  }
1327 
1336  protected function getRecordFromDatabase(string $table, int $uid, string $fields = 'uid,pid'): ?array
1337  {
1338  return BackendUtility::getRecord($table, $uid, $fields);
1339  }
1340 
1347  protected function getRecordPath(int $pid): string
1348  {
1349  if (!isset($this->cacheGetRecordPath[$pid])) {
1350  $this->cacheGetRecordPath[$pid] = (string)BackendUtility::getRecordPath($pid, $this->permsClause, 20);
1351  }
1352  return $this->cacheGetRecordPath[$pid];
1353  }
1354 
1365  protected function compareRecords(array $databaseRecord, array $importRecord, string $table, bool $inverse = false): string
1366  {
1367  $diffHtml = '';
1368 
1369  // Updated fields
1370  foreach ($databaseRecord as $fieldName => $_) {
1371  if (is_array($GLOBALS['TCA'][$table]['columns'][$fieldName] ?? null)
1372  && $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['type'] !== 'passthrough'
1373  ) {
1374  if (isset($importRecord[$fieldName])) {
1375  if (trim((string)$databaseRecord[$fieldName]) !== trim((string)$importRecord[$fieldName])) {
1376  $diffFieldHtml = $this->getDiffUtility()->makeDiffDisplay(
1377  BackendUtility::getProcessedValue(
1378  $table,
1379  $fieldName,
1380  !$inverse ? $importRecord[$fieldName] : $databaseRecord[$fieldName],
1381  0,
1382  true,
1383  true
1384  ),
1385  BackendUtility::getProcessedValue(
1386  $table,
1387  $fieldName,
1388  !$inverse ? $databaseRecord[$fieldName] : $importRecord[$fieldName],
1389  0,
1390  true,
1391  true
1392  )
1393  );
1394  $diffHtml .= sprintf(
1395  '<tr><td>%s (%s)</td><td>%s</td></tr>' . PHP_EOL,
1396  htmlspecialchars($this->lang->sL($GLOBALS['TCA'][$table]['columns'][$fieldName]['label'])),
1397  htmlspecialchars((string)$fieldName),
1398  $diffFieldHtml
1399  );
1400  }
1401  unset($importRecord[$fieldName]);
1402  }
1403  }
1404  }
1405 
1406  // New fields
1407  foreach ($importRecord as $fieldName => $_) {
1408  if (is_array($GLOBALS['TCA'][$table]['columns'][$fieldName] ?? null)
1409  && $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['type'] !== 'passthrough'
1410  ) {
1411  $diffFieldHtml = '<strong>Field missing</strong> in database';
1412  $diffHtml .= sprintf(
1413  '<tr><td>%s (%s)</td><td>%s</td></tr>' . PHP_EOL,
1414  htmlspecialchars($this->lang->sL($GLOBALS['TCA'][$table]['columns'][$fieldName]['label'])),
1415  htmlspecialchars((string)$fieldName),
1416  $diffFieldHtml
1417  );
1418  }
1419  }
1420 
1421  if ($diffHtml !== '') {
1422  $diffHtml = '<table class="table table-striped table-hover">' . PHP_EOL . $diffHtml . '</table>';
1423  } else {
1424  $diffHtml = 'Match';
1425  }
1426 
1427  return sprintf(
1428  '<strong class="text-nowrap">[%s]:</strong>' . PHP_EOL . '%s',
1429  htmlspecialchars($table . ':' . $importRecord['uid'] . ' => ' . $databaseRecord['uid']),
1430  $diffHtml
1431  );
1432  }
1433 
1439  protected function getDiffUtility(): DiffUtility
1440  {
1441  if ($this->diffUtility === null) {
1442  $this->diffUtility = GeneralUtility::makeInstance(DiffUtility::class);
1443  }
1444  return $this->diffUtility;
1445  }
1446 
1452  protected function getFileProcObj(): ExtendedFileUtility
1453  {
1454  if ($this->fileProcObj === null) {
1455  $this->fileProcObj = GeneralUtility::makeInstance(ExtendedFileUtility::class);
1456  $this->fileProcObj->setActionPermissions();
1457  }
1458  return $this->fileProcObj;
1459  }
1460 
1466  protected function getStorageRepository(): StorageRepository
1467  {
1468  if ($this->storageRepository === null) {
1469  $this->storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
1470  }
1471  return $this->storageRepository;
1472  }
1473 
1474  /*****************************
1475  * Error handling
1476  *****************************/
1477 
1483  protected function addError(string $message): void
1484  {
1485  $this->errorLog[] = $message;
1486  }
1487 
1488  public function hasErrors(): bool
1489  {
1490  return empty($this->errorLog) === false;
1491  }
1492 
1496  protected function getBackendUser(): BackendUserAuthentication
1497  {
1498  return $GLOBALS['BE_USER'];
1499  }
1500 
1504  protected function getLanguageService(): LanguageService
1505  {
1506  return $GLOBALS['LANG'];
1507  }
1508 
1509  /**************************
1510  * Getters and Setters
1511  *************************/
1512 
1516  public function getPid(): int
1517  {
1518  return $this->pid;
1519  }
1520 
1524  public function setPid(int $pid): void
1525  {
1526  $this->pid = $pid;
1527  $this->pidRecord = null;
1528  }
1529 
1539  protected function getPidRecord(): ?array
1540  {
1541  if ($this->pidRecord === null && $this->pid >= 0) {
1542  $pidRecord = BackendUtility::readPageAccess($this->pid, $this->permsClause);
1543 
1544  if (is_array($pidRecord)) {
1545  if ($this->pid === 0) {
1546  $pidRecord += ['title' => '[root-level]', 'uid' => 0, 'pid' => 0];
1547  }
1548  $this->pidRecord = $pidRecord;
1549  }
1550  }
1551 
1552  return $this->pidRecord;
1553  }
1554 
1561  public function setExcludeDisabledRecords(bool $excludeDisabledRecords): void
1562  {
1563  $this->excludeDisabledRecords = $excludeDisabledRecords;
1564  }
1565 
1569  public function isExcludeDisabledRecords(): bool
1570  {
1571  return $this->excludeDisabledRecords;
1572  }
1573 
1577  public function getExcludeMap(): array
1578  {
1579  return $this->excludeMap;
1580  }
1581 
1585  public function setExcludeMap(array $excludeMap): void
1586  {
1587  $this->excludeMap = $excludeMap;
1588  }
1589 
1593  public function getSoftrefCfg(): array
1594  {
1595  return $this->softrefCfg;
1596  }
1597 
1601  public function setSoftrefCfg(array $softrefCfg): void
1602  {
1603  $this->softrefCfg = $softrefCfg;
1604  }
1605 
1609  public function getExtensionDependencies(): array
1610  {
1611  return $this->extensionDependencies;
1612  }
1613 
1617  public function setExtensionDependencies(array $extensionDependencies): void
1618  {
1619  $this->extensionDependencies = $extensionDependencies;
1620  }
1621 
1625  public function isShowStaticRelations(): bool
1626  {
1627  return $this->showStaticRelations;
1628  }
1629 
1633  public function setShowStaticRelations(bool $showStaticRelations): void
1634  {
1635  $this->showStaticRelations = $showStaticRelations;
1636  }
1637 
1641  public function getRelStaticTables(): array
1642  {
1643  return $this->relStaticTables;
1644  }
1645 
1649  public function setRelStaticTables(array $relStaticTables): void
1650  {
1651  $this->relStaticTables = $relStaticTables;
1652  }
1653 
1657  public function getErrorLog(): array
1658  {
1659  return $this->errorLog;
1660  }
1661 
1665  public function setErrorLog(array $errorLog): void
1666  {
1667  $this->errorLog = $errorLog;
1668  }
1669 
1673  public function isUpdate(): bool
1674  {
1675  return $this->update;
1676  }
1677 
1681  public function setUpdate(bool $update): void
1682  {
1683  $this->update = $update;
1684  }
1685 
1689  public function getImportMode(): array
1690  {
1691  return $this->importMode;
1692  }
1693 
1697  public function setImportMode(array $importMode): void
1698  {
1699  $this->importMode = $importMode;
1700  }
1701 
1705  public function isGlobalIgnorePid(): bool
1706  {
1707  return $this->globalIgnorePid;
1708  }
1709 
1713  public function setGlobalIgnorePid(bool $globalIgnorePid): void
1714  {
1715  $this->globalIgnorePid = $globalIgnorePid;
1716  }
1717 
1721  public function isForceAllUids(): bool
1722  {
1723  return $this->forceAllUids;
1724  }
1725 
1729  public function setForceAllUids(bool $forceAllUids): void
1730  {
1731  $this->forceAllUids = $forceAllUids;
1732  }
1733 
1737  public function isShowDiff(): bool
1738  {
1739  return $this->showDiff;
1740  }
1741 
1745  public function setShowDiff(bool $showDiff): void
1746  {
1747  $this->showDiff = $showDiff;
1748  }
1749 
1753  public function getSoftrefInputValues(): array
1754  {
1755  return $this->softrefInputValues;
1756  }
1757 
1761  public function setSoftrefInputValues(array $softrefInputValues): void
1762  {
1763  $this->softrefInputValues = $softrefInputValues;
1764  }
1765 
1769  public function getMode(): string
1770  {
1771  return $this->mode;
1772  }
1773 
1777  public function setMode(string $mode): void
1778  {
1779  $this->mode = $mode;
1780  }
1781 
1785  public function getImportMapId(): array
1786  {
1787  return $this->importMapId;
1788  }
1789 
1793  public function setImportMapId(array $importMapId): void
1794  {
1795  $this->importMapId = $importMapId;
1796  }
1797 
1801  public function getDat(): array
1802  {
1803  return $this->dat;
1804  }
1805 }
‪TYPO3\CMS\Core\Utility\DiffUtility
Definition: DiffUtility.php:25
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Impexp\ImportExport\$extensionDependencies
‪array $extensionDependencies
Definition: ImportExport.php:147
‪TYPO3\CMS\Impexp\ImportExport\$iconFactory
‪IconFactory $iconFactory
Definition: ImportExport.php:193
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Impexp\ImportExport\$pidRecord
‪array $pidRecord
Definition: ImportExport.php:67
‪TYPO3\CMS\Impexp\ImportExport\$showStaticRelations
‪bool $showStaticRelations
Definition: ImportExport.php:73
‪TYPO3\CMS\Impexp\ImportExport\$mode
‪string $mode
Definition: ImportExport.php:50
‪TYPO3\CMS\Impexp\ImportExport\$storageRepository
‪StorageRepository $storageRepository
Definition: ImportExport.php:230
‪TYPO3\CMS\Impexp\ImportExport\addGeneralErrorsByTable
‪addGeneralErrorsByTable(string $table)
Definition: ImportExport.php:456
‪TYPO3\CMS\Impexp\ImportExport\$errorLog
‪array $errorLog
Definition: ImportExport.php:159
‪TYPO3\CMS\Impexp\ImportExport\addError
‪addError(string $message)
Definition: ImportExport.php:1453
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:206
‪TYPO3\CMS\Impexp\ImportExport\$forceAllUids
‪bool $forceAllUids
Definition: ImportExport.php:104
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_AS_NEW
‪const IMPORT_MODE_AS_NEW
Definition: Import.php:52
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
Definition: InsufficientFolderAccessPermissionsException.php:23
‪TYPO3\CMS\Impexp\ImportExport\traversePageRecords
‪traversePageRecords(array $pageTree, array &$lines)
Definition: ImportExport.php:413
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getPagePermsClause
‪string getPagePermsClause($perms)
Definition: BackendUserAuthentication.php:460
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:251
‪TYPO3\CMS\Impexp\ImportExport\traversePageTree
‪traversePageTree(array $pageTree, array &$lines, int $indent=0)
Definition: ImportExport.php:331
‪TYPO3\CMS\Core\Resource\Security\FileNameValidator
Definition: FileNameValidator.php:25
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId, string $alternativeUri=null)
Definition: PreviewUriBuilder.php:75
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Impexp\ImportExport\getStorageRepository
‪StorageRepository getStorageRepository()
Definition: ImportExport.php:1436
‪TYPO3\CMS\Impexp\ImportExport\renderSoftRefImportTextField
‪string renderSoftRefImportTextField(array $softref)
Definition: ImportExport.php:956
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:445
‪TYPO3\CMS\Impexp\ImportExport\$globalIgnorePid
‪bool $globalIgnorePid
Definition: ImportExport.php:98
‪TYPO3\CMS\Impexp\ImportExport\fetchStorages
‪fetchStorages()
Definition: ImportExport.php:251
‪TYPO3\CMS\Impexp\ImportExport\addFiles
‪addFiles(array $relations, array &$lines, int $indent, string $tokenID='')
Definition: ImportExport.php:687
‪TYPO3\CMS\Impexp\ImportExport\$pid
‪int $pid
Definition: ImportExport.php:62
‪TYPO3\CMS\Impexp\ImportExport\isTableStatic
‪bool isTableStatic(string $table)
Definition: ImportExport.php:1264
‪TYPO3\CMS\Impexp\ImportExport\$diffUtility
‪DiffUtility $diffUtility
Definition: ImportExport.php:181
‪TYPO3\CMS\Impexp\ImportExport\$showDiff
‪bool $showDiff
Definition: ImportExport.php:110
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Impexp\ImportExport\renderImportModeSelector
‪string renderImportModeSelector(string $table, int $uid, bool $doesRecordExist)
Definition: ImportExport.php:1049
‪TYPO3\CMS\Impexp\ImportExport\getRecordPath
‪string getRecordPath(int $pid)
Definition: ImportExport.php:1317
‪TYPO3\CMS\Impexp\ImportExport\renderIndent
‪renderIndent(int $indent)
Definition: ImportExport.php:888
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_FORCE_UID
‪const IMPORT_MODE_FORCE_UID
Definition: Import.php:51
‪TYPO3\CMS\Impexp\ImportExport\excludePageAndRecords
‪excludePageAndRecords(int $pageUid, array $page)
Definition: ImportExport.php:382
‪TYPO3\CMS\Impexp\ImportExport\$lang
‪LanguageService $lang
Definition: ImportExport.php:189
‪TYPO3\CMS\Impexp\ImportExport\$softrefCfg
‪array $softrefCfg
Definition: ImportExport.php:141
‪TYPO3\CMS\Impexp\ImportExport\isRecordDisabled
‪bool isRecordDisabled(string $table, int $uid)
Definition: ImportExport.php:369
‪TYPO3\CMS\Impexp\ImportExport\addSoftRefs
‪addSoftRefs(array $softrefs, array &$lines, int $indent)
Definition: ImportExport.php:807
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Impexp\ImportExport\compareRecords
‪string compareRecords(array $databaseRecord, array $importRecord, string $table, bool $inverse=false)
Definition: ImportExport.php:1335
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_EXCLUDE
‪const IMPORT_MODE_EXCLUDE
Definition: Import.php:53
‪TYPO3\CMS\Impexp\ImportExport\getPidRecord
‪array null getPidRecord()
Definition: ImportExport.php:1509
‪TYPO3\CMS\Impexp\ImportExport\getRecordFromDatabase
‪array null getRecordFromDatabase(string $table, int $uid, string $fields='uid, pid')
Definition: ImportExport.php:1306
‪TYPO3\CMS\Core\Utility\File\ExtendedFileUtility
Definition: ExtendedFileUtility.php:73
‪TYPO3\CMS\Impexp\ImportExport\$fileadminFolderName
‪string $fileadminFolderName
Definition: ImportExport.php:199
‪TYPO3\CMS\Impexp\ImportExport\$doesImport
‪bool $doesImport
Definition: ImportExport.php:85
‪TYPO3\CMS\Impexp\ImportExport\$fileProcObj
‪ExtendedFileUtility $fileProcObj
Definition: ImportExport.php:177
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Impexp\ImportExport\$importMapId
‪array $importMapId
Definition: ImportExport.php:153
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:38
‪TYPO3\CMS\Impexp\ImportExport\addRelations
‪addRelations(array $relations, array &$lines, int $indent, array $recursionCheck=[])
Definition: ImportExport.php:606
‪TYPO3\CMS\Impexp\ImportExport\getLanguageService
‪LanguageService getLanguageService()
Definition: ImportExport.php:1474
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_RESPECT_PID
‪const IMPORT_MODE_RESPECT_PID
Definition: Import.php:55
‪TYPO3\CMS\Impexp\ImportExport\$storagesAvailableForImport
‪ResourceStorage[] $storagesAvailableForImport
Definition: ImportExport.php:221
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Impexp\ImportExport\__construct
‪__construct()
Definition: ImportExport.php:235
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_IGNORE_PID
‪const IMPORT_MODE_IGNORE_PID
Definition: Import.php:54
‪TYPO3\CMS\Impexp\ImportExport\$defaultStorage
‪ResourceStorage $defaultStorage
Definition: ImportExport.php:226
‪TYPO3\CMS\Impexp\ImportExport
Definition: ImportExport.php:45
‪TYPO3\CMS\Impexp\ImportExport\$fileIdMap
‪array $fileIdMap
Definition: ImportExport.php:122
‪TYPO3\CMS\Impexp\Import\SOFTREF_IMPORT_MODE_EDITABLE
‪const SOFTREF_IMPORT_MODE_EDITABLE
Definition: Import.php:58
‪TYPO3\CMS\Impexp\ImportExport\renderSelectBox
‪string renderSelectBox(string $name, string $value, array $options)
Definition: ImportExport.php:1082
‪TYPO3\CMS\Impexp\ImportExport\$update
‪bool $update
Definition: ImportExport.php:79
‪TYPO3\CMS\Impexp\ImportExport\$permsClause
‪string $permsClause
Definition: ImportExport.php:56
‪TYPO3\CMS\Impexp\ImportExport\$relStaticTables
‪array $relStaticTables
Definition: ImportExport.php:129
‪TYPO3\CMS\Impexp\Import\SOFTREF_IMPORT_MODE_EXCLUDE
‪const SOFTREF_IMPORT_MODE_EXCLUDE
Definition: Import.php:57
‪TYPO3\CMS\Impexp\ImportExport\$defaultImportExportFolder
‪Folder $defaultImportExportFolder
Definition: ImportExport.php:202
‪TYPO3\CMS\Impexp\ImportExport\$excludeDisabledRecords
‪bool $excludeDisabledRecords
Definition: ImportExport.php:209
‪TYPO3\CMS\Impexp\ImportExport\$remainHeader
‪array $remainHeader
Definition: ImportExport.php:185
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪TYPO3\CMS\Impexp\ImportExport\$temporaryFolderName
‪string $temporaryFolderName
Definition: ImportExport.php:201
‪TYPO3\CMS\Impexp\ImportExport\isSoftRefIncluded
‪bool isSoftRefIncluded(string $tokenID)
Definition: ImportExport.php:1292
‪TYPO3\CMS\Core\Resource\StorageRepository\flush
‪flush()
Definition: StorageRepository.php:183
‪TYPO3\CMS\Impexp\ImportExport\addRecord
‪addRecord(string $table, int $uid, array &$lines, int $indent, bool $checkImportInPidRecord=false)
Definition: ImportExport.php:475
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Impexp\ImportExport\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: ImportExport.php:1466
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:32
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Impexp\ImportExport\resolveStoragePath
‪string resolveStoragePath(string $dirPrefix, bool $checkAlternatives=true)
Definition: ImportExport.php:1219
‪TYPO3\CMS\Impexp\ImportExport\$importMode
‪array $importMode
Definition: ImportExport.php:92
‪TYPO3\CMS\Impexp\ImportExport\$cacheGetRecordPath
‪array $cacheGetRecordPath
Definition: ImportExport.php:165
‪TYPO3\CMS\Impexp\ImportExport\checkDokType
‪bool checkDokType(string $table, int $dokType)
Definition: ImportExport.php:900
‪TYPO3\CMS\Impexp\ImportExport\$excludeMap
‪array $excludeMap
Definition: ImportExport.php:135
‪TYPO3\CMS\Impexp\ImportExport\renderControls
‪string renderControls(array $line)
Definition: ImportExport.php:916
‪TYPO3\CMS\Impexp\ImportExport\getFileProcObj
‪ExtendedFileUtility getFileProcObj()
Definition: ImportExport.php:1422
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Impexp\ImportExport\$dat
‪array $dat
Definition: ImportExport.php:171
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Impexp\ImportExport\renderRecordExcludeCheckbox
‪string renderRecordExcludeCheckbox(string $recordRef)
Definition: ImportExport.php:939
‪TYPO3\CMS\Impexp\ImportExport\renderSoftRefExportSelector
‪string renderSoftRefExportSelector(array $softref)
Definition: ImportExport.php:986
‪TYPO3\CMS\Impexp\ImportExport\isRecordExcluded
‪bool isRecordExcluded(string $table, int $uid)
Definition: ImportExport.php:1281
‪TYPO3\CMS\Impexp
‪TYPO3\CMS\Core\Resource\StorageRepository\findAll
‪ResourceStorage[] findAll()
Definition: StorageRepository.php:220
‪TYPO3\CMS\Impexp\ImportExport\$storages
‪ResourceStorage[] $storages
Definition: ImportExport.php:215
‪TYPO3\CMS\Impexp\ImportExport\traverseAllRecords
‪traverseAllRecords(array $pageTree, array &$lines)
Definition: ImportExport.php:439
‪TYPO3\CMS\Impexp\ImportExport\$softrefInputValues
‪array $softrefInputValues
Definition: ImportExport.php:116
‪TYPO3\CMS\Impexp\ImportExport\renderPreview
‪array renderPreview()
Definition: ImportExport.php:281