‪TYPO3CMS  ‪main
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;
26 use TYPO3\CMS\Core\Imaging\IconSize;
39 
45 abstract class ‪ImportExport
46 {
52  protected string ‪$mode = '';
53 
57  protected string ‪$permsClause;
58 
62  protected int ‪$pid = -1;
63 
67  protected ?array ‪$pidRecord = null;
68 
72  protected bool ‪$showStaticRelations = false;
73 
77  protected bool ‪$update = false;
78 
82  protected bool ‪$doesImport = false;
83 
88  protected array ‪$importMode = [];
89 
93  protected bool ‪$globalIgnorePid = false;
94 
98  protected bool ‪$forceAllUids = false;
99 
103  protected bool ‪$showDiff = false;
104 
108  protected array ‪$softrefInputValues = [];
109 
113  protected array ‪$fileIdMap = [];
114 
119  protected array ‪$relStaticTables = [];
120 
124  protected array ‪$excludeMap = [];
125 
129  protected array ‪$softrefCfg = [];
130 
134  protected array ‪$extensionDependencies = [];
135 
139  protected array ‪$importMapId = [];
140 
144  protected array ‪$errorLog = [];
145 
149  protected array ‪$cacheGetRecordPath = [];
150 
154  protected array ‪$dat = [];
155 
160  protected ?‪DiffUtility ‪$diffUtility = null;
161 
162  protected array ‪$remainHeader = [];
165 
166  protected ?string ‪$temporaryFolderName = null;
168 
173  protected bool ‪$excludeDisabledRecords = false;
174 
175  public function ‪__construct()
176  {
177  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
178  $this->lang = $this->‪getLanguageService();
179  $this->permsClause = $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW);
180  }
181 
182  /********************************************************
183  * Visual rendering of import/export memory, $this->dat
184  ********************************************************/
185 
191  public function ‪renderPreview(): array
192  {
193  // @todo: Why is this done?
194  unset($this->dat['files']);
195 
196  $previewData = [
197  'update' => ‪$this->update,
198  'showDiff' => ‪$this->showDiff,
199  'insidePageTree' => [],
200  'outsidePageTree' => [],
201  ];
202 
203  if (!isset($this->dat['header']['pagetree']) && !isset($this->dat['header']['records'])) {
204  return $previewData;
205  }
206 
207  // Traverse header:
208  $this->remainHeader = $this->dat['header'];
209 
210  // Preview of the page tree to be exported
211  if (is_array($this->dat['header']['pagetree'] ?? null)) {
212  $this->‪traversePageTree($this->dat['header']['pagetree'], $previewData['insidePageTree']);
213  foreach ($previewData['insidePageTree'] as &$line) {
214  $line['controls'] = $this->‪renderControls($line);
215  $line['message'] = (!empty($line['msg']) && !$this->doesImport ? '<span class="text-danger">' . htmlspecialchars($line['msg']) . '</span>' : '');
216  }
217  }
218 
219  // Preview the remaining records that were not included in the page tree
220  if (is_array($this->remainHeader['records'] ?? null)) {
221  if (is_array($this->remainHeader['records']['pages'] ?? null)) {
222  $this->‪traversePageRecords($this->remainHeader['records']['pages'], $previewData['outsidePageTree']);
223  }
224  $this->‪traverseAllRecords($this->remainHeader['records'], $previewData['outsidePageTree']);
225  foreach ($previewData['outsidePageTree'] as &$line) {
226  $line['controls'] = $this->‪renderControls($line);
227  $line['message'] = (!empty($line['msg']) && !$this->doesImport ? '<span class="text-danger">' . htmlspecialchars($line['msg']) . '</span>' : '');
228  }
229  }
230 
231  return $previewData;
232  }
233 
241  protected function ‪traversePageTree(array $pageTree, array &$lines, int $indent = 0): void
242  {
243  foreach ($pageTree as $pageUid => $page) {
244  if ($this->excludeDisabledRecords === true && $this->‪isRecordDisabled('pages', $pageUid)) {
245  $this->‪excludePageAndRecords($pageUid, $page);
246  continue;
247  }
248 
249  // Add page
250  $this->‪addRecord('pages', $pageUid, $lines, $indent);
251 
252  // Add records
253  foreach ($this->dat['header']['pid_lookup'][$pageUid] ?? [] as $table => $records) {
254  $table = (string)$table;
255  if ($table !== 'pages') {
256  foreach (array_keys($records) as ‪$uid) {
257  $this->‪addRecord($table, (int)‪$uid, $lines, $indent + 1);
258  }
259  }
260  }
261  unset($this->remainHeader['pid_lookup'][$pageUid]);
262 
263  // Add subtree
264  if (is_array($page['subrow'] ?? null)) {
265  $this->‪traversePageTree($page['subrow'], $lines, $indent + 1);
266  }
267  }
268  }
269 
277  protected function ‪isRecordDisabled(string $table, int ‪$uid): bool
278  {
279  return (bool)($this->dat['records'][$table . ':' . ‪$uid]['data'][
280  ‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] ?? ''
281  ] ?? false);
282  }
283 
290  protected function ‪excludePageAndRecords(int $pageUid, array $page): void
291  {
292  // Exclude page
293  unset($this->remainHeader['records']['pages'][$pageUid]);
294 
295  // Exclude records
296  foreach ($this->dat['header']['pid_lookup'][$pageUid] ?? [] as $table => $records) {
297  if ($table !== 'pages') {
298  foreach (array_keys($records) as ‪$uid) {
299  unset($this->remainHeader['records'][$table][‪$uid]);
300  }
301  }
302  }
303  unset($this->remainHeader['pid_lookup'][$pageUid]);
304 
305  // Exclude subtree
306  foreach ($page['subrow'] ?? [] as $subPageUid => $subPage) {
307  $this->‪excludePageAndRecords($subPageUid, $subPage);
308  }
309  }
310 
317  protected function ‪traversePageRecords(array $pageTree, array &$lines): void
318  {
319  foreach ($pageTree as $pageUid => $_) {
320  // Add page
321  $this->‪addRecord('pages', (int)$pageUid, $lines, 0, true);
322 
323  // Add records
324  foreach ($this->dat['header']['pid_lookup'][$pageUid] ?? [] as $table => $records) {
325  if ($table !== 'pages') {
326  foreach (array_keys($records) as ‪$uid) {
327  $this->‪addRecord((string)$table, (int)‪$uid, $lines, 2);
328  }
329  }
330  }
331  unset($this->remainHeader['pid_lookup'][$pageUid]);
332  }
333  }
334 
341  protected function ‪traverseAllRecords(array $pageTree, array &$lines): void
342  {
343  foreach ($pageTree as $table => $records) {
344  $this->‪addGeneralErrorsByTable($table);
345  if ($table !== 'pages') {
346  foreach (array_keys($records) as ‪$uid) {
347  $this->‪addRecord((string)$table, (int)‪$uid, $lines, 0, true);
348  }
349  }
350  }
351  }
352 
358  protected function ‪addGeneralErrorsByTable(string $table): void
359  {
360  if ($this->update && $table === 'sys_file') {
361  $this->‪addError('Updating sys_file records is not supported! They will be imported as new records!');
362  }
363  if ($this->forceAllUids && $table === 'sys_file') {
364  $this->‪addError('Forcing uids of sys_file records is not supported! They will be imported as new records!');
365  }
366  }
367 
377  protected function ‪addRecord(string $table, int ‪$uid, array &$lines, int $indent, bool $checkImportInPidRecord = false): void
378  {
379  ‪$record = $this->dat['header']['records'][$table][‪$uid] ?? null;
380  unset($this->remainHeader['records'][$table][‪$uid]);
381  if (!is_array(‪$record) && !($table === 'pages' && ‪$uid === 0)) {
382  $this->‪addError('MISSING RECORD: ' . $table . ':' . ‪$uid);
383  }
384 
385  // Create record information for preview
386  $line = [];
387  $line['ref'] = $table . ':' . ‪$uid;
388  $line['type'] = 'record';
389  $line['msg'] = '';
390  if ($table === '_SOFTREF_') {
391  // Record is a soft reference
392  $line['preCode'] = $this->‪renderIndent($indent);
393  $line['title'] = '<em>' . htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_softReferencesFiles')) . '</em>';
394  } elseif (!isset(‪$GLOBALS['TCA'][$table])) {
395  // Record is of unknown table
396  $line['preCode'] = $this->‪renderIndent($indent);
397  $line['title'] = '<em>' . htmlspecialchars((string)‪$record['title']) . '</em>';
398  $line['msg'] = 'UNKNOWN TABLE "' . $line['ref'] . '"';
399  } else {
400  ‪$pidRecord = $this->‪getPidRecord();
401  $line['preCode'] = ''
402  . $this->‪renderIndent($indent)
403  . $this->iconFactory
404  ->getIconForRecord(
405  $table,
406  (array)($this->dat['records'][$table . ':' . ‪$uid]['data'] ?? []),
407  IconSize::SMALL
408  )
409  ->setTitle($line['ref'])
410  ->render();
411  $line['title'] = htmlspecialchars(‪$record['title'] ?? '');
412  // Link to page view
413  if ($table === 'pages') {
414  $viewID = $this->mode === 'export' ? ‪$uid : ($this->doesImport ? ($this->importMapId['pages'][‪$uid] ?? 0) : 0);
415  if ($viewID) {
416  $attributes = ‪PreviewUriBuilder::create($viewID)->serializeDispatcherAttributes();
417  if ($attributes) {
418  $line['title'] = sprintf('<a href="#" %s>%s</a>', $attributes, $line['title']);
419  }
420  }
421  }
422  $line['active'] = !$this->‪isRecordDisabled($table, ‪$uid) ? 'active' : 'hidden';
423  if ($this->mode === 'import' && ‪$pidRecord !== null) {
424  if ($checkImportInPidRecord) {
425  if (!$this->‪getBackendUser()->doesUserHaveAccess(‪$pidRecord, ($table === 'pages' ? 8 : 16))) {
426  $line['msg'] .= '"' . $line['ref'] . '" cannot be INSERTED on this page! ';
427  }
428  if ($this->pid > 0 && !$this->‪checkDokType($table, ‪$pidRecord['doktype']) && !‪$GLOBALS['TCA'][$table]['ctrl']['rootLevel']) {
429  $line['msg'] .= '"' . $table . '" cannot be INSERTED on this page type (change page type to "Folder".) ';
430  }
431  }
432  if (!$this->‪getBackendUser()->check('tables_modify', $table)) {
433  $line['msg'] .= 'You are not allowed to CREATE "' . $table . '" tables! ';
434  }
435  if (‪$GLOBALS['TCA'][$table]['ctrl']['readOnly'] ?? false) {
436  $line['msg'] .= 'TABLE "' . $table . '" is READ ONLY! ';
437  }
438  if ((‪$GLOBALS['TCA'][$table]['ctrl']['adminOnly'] ?? false) && !$this->‪getBackendUser()->isAdmin()) {
439  $line['msg'] .= 'TABLE "' . $table . '" is ADMIN ONLY! ';
440  }
441  if (‪$GLOBALS['TCA'][$table]['ctrl']['is_static'] ?? false) {
442  $line['msg'] .= 'TABLE "' . $table . '" is a STATIC TABLE! ';
443  }
444  if ((int)(‪$GLOBALS['TCA'][$table]['ctrl']['rootLevel'] ?? 0) === 1) {
445  $line['msg'] .= 'TABLE "' . $table . '" will be inserted on ROOT LEVEL! ';
446  }
447  $databaseRecord = null;
448  if ($this->update) {
449  $databaseRecord = $this->‪getRecordFromDatabase($table, ‪$uid, $this->showDiff ? '*' : 'uid,pid');
450  if ($databaseRecord === null) {
451  $line['updatePath'] = '<strong>NEW!</strong>';
452  } else {
453  $line['updatePath'] = htmlspecialchars($this->‪getRecordPath((int)($databaseRecord['pid'] ?? 0)));
454  }
455  if ($table === 'sys_file') {
456  $line['updateMode'] = '';
457  } else {
458  $line['updateMode'] = $this->‪renderImportModeSelector(
459  $table,
460  ‪$uid,
461  $databaseRecord !== null
462  );
463  }
464  }
465  // Diff view
466  if ($this->showDiff) {
467  $diffInverse = ‪$this->update;
468  // For imports, get new id:
469  if (isset($this->importMapId[$table][‪$uid]) && $newUid = $this->importMapId[$table][‪$uid]) {
470  $diffInverse = false;
471  $databaseRecord = $this->‪getRecordFromDatabase($table, $newUid, '*');
472  BackendUtility::workspaceOL($table, $databaseRecord);
473  }
475  $importRecord = $this->dat['records'][$table . ':' . ‪$uid]['data'] ?? null;
476  if ($databaseRecord === null) {
477  $line['showDiffContent'] = '';
478  } elseif (is_array($databaseRecord) && is_array($importRecord)) {
479  $line['showDiffContent'] = $this->‪compareRecords($databaseRecord, $importRecord, $table, $diffInverse);
480  } else {
481  $line['showDiffContent'] = 'ERROR: One of the inputs were not an array!';
482  }
483  }
484  }
485  }
486  $lines[] = $line;
487 
488  // File relations
489  if (is_array(‪$record['filerefs'] ?? null)) {
490  $this->‪addFiles(‪$record['filerefs'], $lines, $indent);
491  }
492  // Database relations
493  if (is_array(‪$record['rels'] ?? null)) {
494  $this->‪addRelations(‪$record['rels'], $lines, $indent);
495  }
496  // Soft references
497  if (is_array(‪$record['softrefs'] ?? null)) {
498  $this->‪addSoftRefs(‪$record['softrefs'], $lines, $indent);
499  }
500  }
501 
512  protected function ‪addRelations(array $relations, array &$lines, int $indent, array $recursionCheck = []): void
513  {
514  foreach ($relations as $relation) {
515  $table = $relation['table'];
516  ‪$uid = $relation['id'];
517  $line = [];
518  $line['ref'] = $table . ':' . ‪$uid;
519  $line['type'] = 'rel';
520  $line['msg'] = '';
521  if (in_array($line['ref'], $recursionCheck, true)) {
522  continue;
523  }
524  $iconName = 'status-status-checked';
525  $staticFixed = false;
526  ‪$record = null;
527  if (‪$uid > 0) {
528  ‪$record = $this->dat['header']['records'][$table][‪$uid] ?? null;
529  if (!is_array(‪$record)) {
530  if ($this->‪isTableStatic($table) || $this->‪isRecordExcluded($table, (int)‪$uid)
531  || ($relation['tokenID'] ?? '') && !$this->‪isSoftRefIncluded($relation['tokenID'] ?? '')) {
532  $line['title'] = htmlspecialchars('STATIC: ' . $line['ref']);
533  $staticFixed = true;
534  } else {
535  $databaseRecord = $this->‪getRecordFromDatabase($table, (int)‪$uid);
536  $recordPath = $this->‪getRecordPath($databaseRecord === null ? 0 : ($table === 'pages' ? (int)$databaseRecord['uid'] : (int)$databaseRecord['pid']));
537  $line['title'] = sprintf(
538  '<span title="%s">%s</span>',
539  htmlspecialchars($recordPath),
540  htmlspecialchars($line['ref'])
541  );
542  $line['msg'] = 'LOST RELATION' . ($databaseRecord === null ? ' (Record not found!)' : ' (Path: ' . $recordPath . ')');
543  $iconName = 'status-dialog-warning';
544  }
545  } else {
546  $recordPath = $this->‪getRecordPath($table === 'pages' ? (int)‪$record['uid'] : (int)‪$record['pid']);
547  $line['title'] = sprintf(
548  '<span title="%s">%s</span>',
549  htmlspecialchars($recordPath),
550  htmlspecialchars((string)‪$record['title'])
551  );
552  }
553  } else {
554  // Negative values in relation fields. These are typically fields of e.g. fe_users.
555  // They are static values. They CAN theoretically be negative pointers to uids in other tables,
556  // but this is so rarely used that it is not supported.
557  $line['title'] = htmlspecialchars('FIXED: ' . $line['ref']);
558  $staticFixed = true;
559  }
560 
561  $line['preCode'] = ''
562  . $this->‪renderIndent($indent + 1)
563  . $this->iconFactory
564  ->getIcon($iconName, IconSize::SMALL)
565  ->setTitle($line['ref'])
566  ->render();
567  if (!$staticFixed || $this->showStaticRelations) {
568  $lines[] = $line;
569  if (is_array(‪$record) && is_array(‪$record['rels'] ?? null)) {
570  $this->‪addRelations(‪$record['rels'], $lines, $indent + 1, array_merge($recursionCheck, [$line['ref']]));
571  }
572  }
573  }
574  }
575 
588  public function ‪addFiles(array $relations, array &$lines, int $indent, string $tokenID = ''): void
589  {
590  foreach ($relations as $ID) {
591  $line = [];
592  $line['msg'] = '';
593  $fileInfo = $this->dat['header']['files'][$ID] ?? null;
594  if (!is_array($fileInfo)) {
595  if ($tokenID !== '' || $this->‪isSoftRefIncluded($tokenID)) {
596  $line['msg'] = 'MISSING FILE: ' . $ID;
597  $this->‪addError('MISSING FILE: ' . $ID);
598 
599  // In case of an error, this relation shall be unset,
600  // so that no follow-up errors on the missing file
601  // softref can occur.
602  unset($this->remainHeader['files'][$ID]);
603  $line['type'] = '';
604  $lines[] = $line;
605  continue;
606  }
607  return;
608  }
609  $line['ref'] = 'FILE';
610  $line['type'] = 'file';
611  $line['preCode'] = ''
612  . $this->‪renderIndent($indent + 1)
613  . $this->iconFactory
614  ->getIcon('status-reference-hard', IconSize::SMALL)
615  ->setTitle($line['ref'])
616  ->render();
617  $line['title'] = htmlspecialchars($fileInfo['filename'] ?? 'Missing filename');
618  $line['showDiffContent'] = ‪PathUtility::stripPathSitePrefix((string)($this->fileIdMap[$ID] ?? ''));
619  // If import mode and there is a soft reference, check the destination directory.
620  if ($this->mode === 'import' && $tokenID !== '') {
621  // Check folder existence
622  if (isset($fileInfo['parentRelFileName'])) {
623  $line['msg'] = 'Seems like this file is already referenced from within an HTML/CSS file. That takes precedence. ';
624  } elseif (isset($fileInfo['relFileName'])) {
625  $origDirPrefix = ‪PathUtility::dirname($fileInfo['relFileName']) . '/';
626  $dirPrefix = $this->‪resolveStoragePath($origDirPrefix);
627  if ($dirPrefix === null) {
628  $line['msg'] = 'ERROR: There are no available file mounts to write file in!';
629  } elseif ($origDirPrefix !== $dirPrefix) {
630  $line['msg'] = 'File will be attempted written to "' . $dirPrefix . '". ';
631  }
632  }
633  // Check file existence
634  if (file_exists(‪Environment::getPublicPath() . '/' . $fileInfo['relFileName'])) {
635  if ($this->update) {
636  $line['updatePath'] = 'File exists.';
637  } else {
638  $line['msg'] .= 'File already exists! ';
639  }
640  }
641  // Check file extension
643  if ($fileProcObj->actionPerms['addFile']) {
644  $pathInfo = GeneralUtility::split_fileref(‪Environment::getPublicPath() . '/' . $fileInfo['relFileName']);
645  if (!GeneralUtility::makeInstance(FileNameValidator::class)->isValid($pathInfo['file'])) {
646  $line['msg'] .= 'File extension was not allowed!';
647  }
648  } else {
649  $line['msg'] = 'Your user profile does not allow you to create files on the server!';
650  }
651  }
652  $lines[] = $line;
653  unset($this->remainHeader['files'][$ID]);
654 
655  // External resources
656  foreach ($fileInfo['EXT_RES_ID'] ?? [] as $extID) {
657  $line = [];
658  $fileInfo = $this->dat['header']['files'][$extID];
659  if (!is_array($fileInfo)) {
660  $line['msg'] = 'MISSING External Resource FILE: ' . $extID;
661  $this->‪addError('MISSING External Resource FILE: ' . $extID);
662  } else {
663  $line['updatePath'] = $fileInfo['parentRelFileName'];
664  }
665  $line['ref'] = 'FILE';
666  $line['type'] = 'file';
667  $line['preCode'] = ''
668  . $this->‪renderIndent($indent + 1)
669  . $this->iconFactory
670  ->getIcon('actions-insert-reference', IconSize::SMALL)
671  ->setTitle($line['ref'])
672  ->render();
673  $line['title'] = htmlspecialchars($fileInfo['filename']) . ' <em>(Resource)</em>';
674  $line['showDiffContent'] = ‪PathUtility::stripPathSitePrefix($this->fileIdMap[$extID]);
675  $lines[] = $line;
676  unset($this->remainHeader['files'][$extID]);
677  }
678  }
679  }
680 
690  protected function ‪addSoftRefs(array $softrefs, array &$lines, int $indent): void
691  {
692  foreach ($softrefs as $softref) {
693  $line = [];
694  $line['ref'] = 'SOFTREF';
695  $line['type'] = 'softref';
696  $line['msg'] = '';
697  $line['preCode'] = ''
698  . $this->‪renderIndent($indent)
699  . $this->iconFactory
700  ->getIcon('status-reference-soft', IconSize::SMALL)
701  ->setTitle($line['ref'])
702  ->render();
703  $line['title'] = sprintf(
704  '<em>%s, "%s"</em>: <span title="%s">%s</span>',
705  $softref['field'],
706  $softref['spKey'],
707  htmlspecialchars($softref['matchString'] ?? ''),
708  htmlspecialchars(‪GeneralUtility::fixed_lgd_cs($softref['matchString'] ?? '', 60))
709  );
710  if ($softref['subst']['type'] ?? false) {
711  if ($softref['subst']['title'] ?? false) {
712  $line['title'] .= sprintf(
713  '<br>%s <strong>%s</strong> %s',
714  $this->‪renderIndent($indent + 1),
715  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_title')),
716  htmlspecialchars(‪GeneralUtility::fixed_lgd_cs($softref['subst']['title'], 60))
717  );
718  }
719  if ($softref['subst']['description'] ?? false) {
720  $line['title'] .= sprintf(
721  '<br>%s <strong>%s</strong> %s',
722  $this->‪renderIndent($indent + 1),
723  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_descr')),
724  htmlspecialchars(‪GeneralUtility::fixed_lgd_cs($softref['subst']['description'], 60))
725  );
726  }
727  if ($softref['subst']['type'] === 'db') {
728  $line['title'] .= sprintf(
729  '<br>%s <strong>%s</strong> %s',
730  $this->‪renderIndent($indent + 1),
731  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_softrefsel_record')),
732  $softref['subst']['recordRef']
733  );
734  } elseif ($softref['subst']['type'] === 'file') {
735  $line['title'] .= sprintf(
736  '<br>%s <strong>%s</strong> %s',
737  $this->‪renderIndent($indent + 1),
738  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_filename')),
739  $softref['subst']['relFileName']
740  );
741  } elseif ($softref['subst']['type'] === 'string') {
742  $line['title'] .= sprintf(
743  '<br>%s <strong>%s</strong> %s',
744  $this->‪renderIndent($indent + 1),
745  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_value')),
746  $softref['subst']['tokenValue']
747  );
748  }
749  }
750  $line['_softRefInfo'] = $softref;
751  ‪$mode = $this->softrefCfg[$softref['subst']['tokenID'] ?? null]['mode'] ?? '';
753  $line['msg'] .= $softref['error'];
754  }
755  $lines[] = $line;
756 
757  // Add database relations
758  if (($softref['subst']['type'] ?? '') === 'db') {
759  [$referencedTable, $referencedUid] = explode(':', $softref['subst']['recordRef']);
760  $relations = [['table' => $referencedTable, 'id' => $referencedUid, 'tokenID' => $softref['subst']['tokenID']]];
761  $this->‪addRelations($relations, $lines, $indent + 1);
762  }
763  // Add files relations
764  if (($softref['subst']['type'] ?? '') === 'file') {
765  $relations = [$softref['file_ID']];
766  $this->‪addFiles($relations, $lines, $indent + 1, $softref['subst']['tokenID']);
767  }
768  }
769  }
770 
771  protected function ‪renderIndent(int $indent): string
772  {
773  return $indent > 0 ? '<span class="indent indent-inline-block" style="--indent-level: ' . $indent . '"></span>' : '';
774  }
775 
783  protected function ‪checkDokType(string $table, int $dokType): bool
784  {
785  return GeneralUtility::makeInstance(PageDoktypeRegistry::class)->isRecordTypeAllowedForDoktype($table, $dokType);
786  }
787 
794  protected function ‪renderControls(array $line): string
795  {
796  if ($this->mode === 'export') {
797  if ($line['type'] === 'record') {
798  return $this->‪renderRecordExcludeCheckbox($line['ref']);
799  }
800  if ($line['type'] === 'softref') {
801  return $this->‪renderSoftRefExportSelector($line['_softRefInfo']);
802  }
803  } elseif ($this->mode === 'import') {
804  if ($line['type'] === 'softref') {
805  return $this->‪renderSoftRefImportTextField($line['_softRefInfo']);
806  }
807  }
808  return '';
809  }
810 
817  protected function ‪renderRecordExcludeCheckbox(string $recordRef): string
818  {
819  return ''
820  . '<div class="form-check mb-0">'
821  . '<input class="form-check-input t3js-exclude-checkbox" type="checkbox" name="tx_impexp[exclude][' . $recordRef . ']" id="checkExclude' . $recordRef . '" value="1" />'
822  . '<label class="form-check-label" for="checkExclude' . $recordRef . '">' . htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_exclude')) . '</label>'
823  . '</div>';
824  }
825 
832  protected function ‪renderSoftRefImportTextField(array $softref): string
833  {
834  if (isset($softref['subst']['tokenID'])) {
835  $tokenID = $softref['subst']['tokenID'];
836  $cfg = $this->softrefCfg[$tokenID] ?? [];
837  if (($cfg['mode'] ?? '') === ‪Import::SOFTREF_IMPORT_MODE_EDITABLE) {
838  $html = '';
839  if ($cfg['title'] ?? false) {
840  $html .= '<strong>' . htmlspecialchars((string)$cfg['title']) . '</strong><br>';
841  }
842  $html .= htmlspecialchars((string)$cfg['description']) . '<br>';
843  $html .= sprintf(
844  '<input type="text" name="tx_impexp[softrefInputValues][%s]" value="%s" />',
845  $tokenID,
846  htmlspecialchars($this->softrefInputValues[$tokenID] ?? $cfg['defValue'])
847  );
848  return $html;
849  }
850  }
851 
852  return '';
853  }
854 
862  protected function ‪renderSoftRefExportSelector(array $softref): string
863  {
864  // Substitution scheme has to be around.
865  if (isset($softref['subst']['tokenID'])) {
866  $options = [];
867  $options[''] = '';
868  $options[‪Import::SOFTREF_IMPORT_MODE_EDITABLE] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_softrefsel_editable');
869  $options[‪Import::SOFTREF_IMPORT_MODE_EXCLUDE] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_softrefsel_exclude');
870  $value = $this->softrefCfg[$softref['subst']['tokenID']]['mode'] ?? '';
871  $selectHtml = $this->‪renderSelectBox(
872  'tx_impexp[softrefCfg][' . $softref['subst']['tokenID'] . '][mode]',
873  $value,
874  $options
875  );
876  $textFieldHtml = '';
878  if ($softref['subst']['title'] ?? false) {
879  $textFieldHtml .= sprintf(
880  '
881  <input type="hidden" name="tx_impexp[softrefCfg][%1$s][title]" value="%2$s" />
882  <strong>%2$s</strong><br>',
883  $softref['subst']['tokenID'],
884  htmlspecialchars($softref['subst']['title'])
885  );
886  }
887  if (!($softref['subst']['description'] ?? false)) {
888  $textFieldHtml .= sprintf(
889  '
890  %s<br>
891  <input type="text" name="tx_impexp[softrefCfg][%s][description]" value="%s" />',
892  htmlspecialchars($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_printerror_description')),
893  $softref['subst']['tokenID'],
894  htmlspecialchars($this->softrefCfg[$softref['subst']['tokenID']]['description'] ?? '')
895  );
896  } else {
897  $textFieldHtml .= sprintf(
898  '
899  <input type="hidden" name="tx_impexp[softrefCfg][%1$s][description]" value="%2$s" />%2$s',
900  $softref['subst']['tokenID'],
901  htmlspecialchars($softref['subst']['description'])
902  );
903  }
904  $textFieldHtml .= sprintf(
905  '
906  <input type="hidden" name="tx_impexp[softrefCfg][%s][defValue]" value="%s" />',
907  $softref['subst']['tokenID'],
908  htmlspecialchars($softref['subst']['tokenValue'])
909  );
910  }
911  return $selectHtml . $textFieldHtml;
912  }
913  return '';
914  }
915 
924  protected function ‪renderImportModeSelector(string $table, int ‪$uid, bool $doesRecordExist): string
925  {
926  $options = [];
927  if (!$doesRecordExist) {
928  $options[] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_insert');
929  if ($this->‪getBackendUser()->isAdmin()) {
930  $options[‪Import::IMPORT_MODE_FORCE_UID] = sprintf($this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_forceUidSAdmin'), ‪$uid);
931  }
932  } else {
933  $options[] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_update');
934  $options[‪Import::IMPORT_MODE_AS_NEW] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_importAsNew');
935  if (!$this->globalIgnorePid) {
936  $options[‪Import::IMPORT_MODE_IGNORE_PID] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_ignorePid');
937  } else {
938  $options[‪Import::IMPORT_MODE_RESPECT_PID] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_respectPid');
939  }
940  }
941  $options[‪Import::IMPORT_MODE_EXCLUDE] = $this->lang->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:impexpcore_singlereco_exclude');
942  return $this->‪renderSelectBox(
943  'tx_impexp[import_mode][' . $table . ':' . ‪$uid . ']',
944  (string)($this->importMode[$table . ':' . ‪$uid] ?? ''),
945  $options
946  );
947  }
948 
957  protected function ‪renderSelectBox(string $name, string $value, array $options): string
958  {
959  $optionsHtml = '';
960  $isValueInOptions = false;
961 
962  foreach ($options as $k => $v) {
963  if ((string)$k === $value) {
964  $isValueInOptions = true;
965  $selectedHtml = ' selected="selected"';
966  } else {
967  $selectedHtml = '';
968  }
969  $optionsHtml .= sprintf(
970  '<option value="%s"%s>%s</option>',
971  htmlspecialchars((string)$k),
972  $selectedHtml,
973  htmlspecialchars((string)$v)
974  );
975  }
976 
977  // Append and select the current value as an option of the form "[value]"
978  // if it is not available in the options.
979  if (!$isValueInOptions && $value !== '') {
980  $optionsHtml .= sprintf(
981  '<option value="%s" selected="selected">%s</option>',
982  htmlspecialchars($value),
983  htmlspecialchars('[\'' . $value . '\']')
984  );
985  }
986 
987  return '<select class="form-select form-select-sm" name="' . $name . '" style="width: 100px">' . $optionsHtml . '</select>';
988  }
989 
990  public function getOrCreateTemporaryFolderName(): string
991  {
992  if (empty($this->temporaryFolderName)) {
993  $this->temporaryFolderName = $this->createTemporaryFolderName();
994  }
995  return $this->temporaryFolderName;
996  }
997 
998  protected function createTemporaryFolderName(): string
999  {
1000  $temporaryPath = Environment::getVarPath() . '/transient';
1001  do {
1002  $temporaryFolderName = sprintf(
1003  '%s/impexp_%s_files_%d',
1004  $temporaryPath,
1005  $this->mode,
1006  random_int(1, PHP_INT_MAX)
1007  );
1008  } while (is_dir($temporaryFolderName));
1009  GeneralUtility::mkdir_deep($temporaryFolderName);
1010  return $temporaryFolderName;
1011  }
1012 
1013  public function removeTemporaryFolderName(): void
1014  {
1015  if (!empty($this->temporaryFolderName)) {
1016  GeneralUtility::rmdir($this->temporaryFolderName, true);
1017  $this->temporaryFolderName = null;
1018  }
1019  }
1020 
1025  public function getOrCreateDefaultImportExportFolder(): ?Folder
1026  {
1027  if (empty($this->defaultImportExportFolder)) {
1028  $this->createDefaultImportExportFolder();
1029  }
1030  return $this->defaultImportExportFolder;
1031  }
1032 
1037  protected function createDefaultImportExportFolder(): void
1038  {
1039  $defaultTemporaryFolder = $this->getDefaultUploadTemporaryFolder();
1040  $defaultImportExportFolder = null;
1041  if ($defaultTemporaryFolder !== null) {
1042  $importExportFolderName = 'importexport';
1043  if ($defaultTemporaryFolder->hasFolder($importExportFolderName) === false) {
1044  $defaultImportExportFolder = $defaultTemporaryFolder->createFolder($importExportFolderName);
1045  } else {
1046  $defaultImportExportFolder = $defaultTemporaryFolder->getSubfolder($importExportFolderName);
1047  }
1048  }
1049  $this->defaultImportExportFolder = $defaultImportExportFolder;
1050  }
1051 
1057  protected function getDefaultUploadTemporaryFolder(): ?Folder
1058  {
1059  $defaultFolder = GeneralUtility::makeInstance(DefaultUploadFolderResolver::class)->resolve($this->getBackendUser());
1060 
1061  if ($defaultFolder !== false) {
1062  $tempFolderName = '_temp_';
1063  $createFolder = !$defaultFolder->hasFolder($tempFolderName);
1064  if ($createFolder === true) {
1065  try {
1066  return $defaultFolder->createFolder($tempFolderName);
1067  } catch (Exception $folderAccessException) {
1068  }
1069  } else {
1070  return $defaultFolder->getSubfolder($tempFolderName);
1071  }
1072  }
1073  return null;
1074  }
1075 
1076  public function removeDefaultImportExportFolder(): void
1077  {
1078  if (!empty($this->defaultImportExportFolder)) {
1079  $this->defaultImportExportFolder->delete(true);
1080  $this->defaultImportExportFolder = null;
1081  }
1082  }
1083 
1093  protected function resolveStoragePath(string $dirPrefix, bool $checkAlternatives = true): ?string
1094  {
1095  try {
1096  GeneralUtility::makeInstance(ResourceFactory::class)->getFolderObjectFromCombinedIdentifier($dirPrefix);
1097  return $dirPrefix;
1098  } catch (InsufficientFolderAccessPermissionsException $e) {
1099  if ($checkAlternatives) {
1100  $storagesByUser = $this->getBackendUser()->getFileStorages();
1101  foreach ($storagesByUser as $storage) {
1102  try {
1103  $folder = $storage->getFolder(rtrim($dirPrefix, '/'));
1104  return $folder->getPublicUrl();
1105  } catch (InsufficientFolderAccessPermissionsException $e) {
1106  }
1107  }
1108  }
1109  }
1110  return null;
1111  }
1112 
1120  protected function flatInversePageTree(array $pageTree, array &$list, int $pid = -1): void
1121  {
1122  // @todo: return $list instead of by-reference?!
1123  $pageTreeInverse = array_reverse($pageTree);
1124  foreach ($pageTreeInverse as $page) {
1125  $list[$page['uid']] = $pid;
1126  if (is_array($page['subrow'] ?? null)) {
1127  $this->flatInversePageTree($page['subrow'], $list, (int)$page['uid']);
1128  }
1129  }
1130  }
1131 
1138  protected function isTableStatic(string $table): bool
1139  {
1140  if (is_array($GLOBALS['TCA'][$table] ?? null)) {
1141  return ($GLOBALS['TCA'][$table]['ctrl']['is_static'] ?? false)
1142  || in_array($table, $this->relStaticTables, true)
1143  || in_array('_ALL', $this->relStaticTables, true);
1144  }
1145  return false;
1146  }
1147 
1155  protected function isRecordExcluded(string $table, int $uid): bool
1156  {
1157  return (bool)($this->excludeMap[$table . ':' . $uid] ?? false);
1158  }
1159 
1166  protected function isSoftRefIncluded(string $tokenID): bool
1167  {
1168  $mode = $this->softrefCfg[$tokenID]['mode'] ?? '';
1169  return $tokenID && $mode !== Import::SOFTREF_IMPORT_MODE_EXCLUDE && $mode !== Import::SOFTREF_IMPORT_MODE_EDITABLE;
1170  }
1171 
1180  protected function getRecordFromDatabase(string $table, int $uid, string $fields = 'uid,pid'): ?array
1181  {
1182  return BackendUtility::getRecord($table, $uid, $fields);
1183  }
1184 
1191  protected function getRecordPath(int $pid): string
1192  {
1193  if (!isset($this->cacheGetRecordPath[$pid])) {
1194  $this->cacheGetRecordPath[$pid] = (string)BackendUtility::getRecordPath($pid, $this->permsClause, 20);
1195  }
1196  return $this->cacheGetRecordPath[$pid];
1197  }
1198 
1209  protected function compareRecords(array $databaseRecord, array $importRecord, string $table, bool $inverse = false): string
1210  {
1211  $diffHtml = '';
1212 
1213  // Updated fields
1214  foreach ($databaseRecord as $fieldName => $_) {
1215  if (is_array($GLOBALS['TCA'][$table]['columns'][$fieldName] ?? null)
1216  && $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['type'] !== 'passthrough'
1217  ) {
1218  if (isset($importRecord[$fieldName])) {
1219  if (trim((string)$databaseRecord[$fieldName]) !== trim((string)$importRecord[$fieldName])) {
1220  $diffFieldHtml = $this->getDiffUtility()->makeDiffDisplay(
1221  (string)BackendUtility::getProcessedValue(
1222  $table,
1223  $fieldName,
1224  !$inverse ? $importRecord[$fieldName] : $databaseRecord[$fieldName],
1225  0,
1226  true,
1227  true
1228  ),
1229  (string)BackendUtility::getProcessedValue(
1230  $table,
1231  $fieldName,
1232  !$inverse ? $databaseRecord[$fieldName] : $importRecord[$fieldName],
1233  0,
1234  true,
1235  true
1236  )
1237  );
1238  $diffHtml .= sprintf(
1239  '<tr><td>%s (%s)</td><td>%s</td></tr>' . PHP_EOL,
1240  htmlspecialchars($this->lang->sL($GLOBALS['TCA'][$table]['columns'][$fieldName]['label'])),
1241  htmlspecialchars((string)$fieldName),
1242  $diffFieldHtml
1243  );
1244  }
1245  unset($importRecord[$fieldName]);
1246  }
1247  }
1248  }
1249 
1250  // New fields
1251  foreach ($importRecord as $fieldName => $_) {
1252  if (is_array($GLOBALS['TCA'][$table]['columns'][$fieldName] ?? null)
1253  && $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['type'] !== 'passthrough'
1254  ) {
1255  $diffFieldHtml = '<strong>Field missing</strong> in database';
1256  $diffHtml .= sprintf(
1257  '<tr><td>%s (%s)</td><td>%s</td></tr>' . PHP_EOL,
1258  htmlspecialchars($this->lang->sL($GLOBALS['TCA'][$table]['columns'][$fieldName]['label'])),
1259  htmlspecialchars((string)$fieldName),
1260  $diffFieldHtml
1261  );
1262  }
1263  }
1264 
1265  if ($diffHtml !== '') {
1266  $diffHtml = '<table class="table table-striped table-hover">' . PHP_EOL . $diffHtml . '</table>';
1267  } else {
1268  $diffHtml = 'Match';
1269  }
1270 
1271  return sprintf(
1272  '<strong class="text-nowrap">[%s]:</strong>' . PHP_EOL . '%s',
1273  htmlspecialchars($table . ':' . $importRecord['uid'] . ' => ' . $databaseRecord['uid']),
1274  $diffHtml
1275  );
1276  }
1277 
1283  protected function getDiffUtility(): DiffUtility
1284  {
1285  if ($this->diffUtility === null) {
1286  $this->diffUtility = GeneralUtility::makeInstance(DiffUtility::class);
1287  }
1288  return $this->diffUtility;
1289  }
1290 
1296  protected function getFileProcObj(): ExtendedFileUtility
1297  {
1298  if ($this->fileProcObj === null) {
1299  $this->fileProcObj = GeneralUtility::makeInstance(ExtendedFileUtility::class);
1300  $this->fileProcObj->setActionPermissions();
1301  }
1302  return $this->fileProcObj;
1303  }
1304 
1305  /*****************************
1306  * Error handling
1307  *****************************/
1308 
1314  protected function addError(string $message): void
1315  {
1316  $this->errorLog[] = $message;
1317  }
1318 
1319  public function hasErrors(): bool
1320  {
1321  return empty($this->errorLog) === false;
1322  }
1323 
1324  protected function getBackendUser(): BackendUserAuthentication
1325  {
1326  return $GLOBALS['BE_USER'];
1327  }
1328 
1329  protected function getLanguageService(): LanguageService
1330  {
1331  return $GLOBALS['LANG'];
1332  }
1333 
1334  public function getPid(): int
1335  {
1336  return $this->pid;
1337  }
1338 
1339  public function setPid(int $pid): void
1340  {
1341  $this->pid = $pid;
1342  $this->pidRecord = null;
1343  }
1344 
1352  protected function getPidRecord(): ?array
1353  {
1354  if ($this->pidRecord === null && $this->pid >= 0) {
1355  $pidRecord = BackendUtility::readPageAccess($this->pid, $this->permsClause);
1356 
1357  if (is_array($pidRecord)) {
1358  if ($this->pid === 0) {
1359  $pidRecord += ['title' => '[root-level]', 'uid' => 0, 'pid' => 0];
1360  }
1361  $this->pidRecord = $pidRecord;
1362  }
1363  }
1364 
1365  return $this->pidRecord;
1366  }
1367 
1374  public function setExcludeDisabledRecords(bool $excludeDisabledRecords): void
1375  {
1376  $this->excludeDisabledRecords = $excludeDisabledRecords;
1377  }
1378 
1379  public function isExcludeDisabledRecords(): bool
1380  {
1381  return $this->excludeDisabledRecords;
1382  }
1383 
1384  public function getExcludeMap(): array
1385  {
1386  return $this->excludeMap;
1387  }
1388 
1389  public function setExcludeMap(array $excludeMap): void
1390  {
1391  $this->excludeMap = $excludeMap;
1392  }
1393 
1394  public function getSoftrefCfg(): array
1395  {
1396  return $this->softrefCfg;
1397  }
1398 
1399  public function setSoftrefCfg(array $softrefCfg): void
1400  {
1401  $this->softrefCfg = $softrefCfg;
1402  }
1403 
1404  public function getExtensionDependencies(): array
1405  {
1406  return $this->extensionDependencies;
1407  }
1408 
1409  public function setExtensionDependencies(array $extensionDependencies): void
1410  {
1411  $this->extensionDependencies = $extensionDependencies;
1412  }
1413 
1414  public function isShowStaticRelations(): bool
1415  {
1416  return $this->showStaticRelations;
1417  }
1418 
1419  public function setShowStaticRelations(bool $showStaticRelations): void
1420  {
1421  $this->showStaticRelations = $showStaticRelations;
1422  }
1423 
1424  public function getRelStaticTables(): array
1425  {
1426  return $this->relStaticTables;
1427  }
1428 
1429  public function setRelStaticTables(array $relStaticTables): void
1430  {
1431  $this->relStaticTables = $relStaticTables;
1432  }
1433 
1434  public function getErrorLog(): array
1435  {
1436  return $this->errorLog;
1437  }
1438 
1439  public function setErrorLog(array $errorLog): void
1440  {
1441  $this->errorLog = $errorLog;
1442  }
1443 
1444  public function isUpdate(): bool
1445  {
1446  return $this->update;
1447  }
1448 
1449  public function setUpdate(bool $update): void
1450  {
1451  $this->update = $update;
1452  }
1453 
1454  public function getImportMode(): array
1455  {
1456  return $this->importMode;
1457  }
1458 
1459  public function setImportMode(array $importMode): void
1460  {
1461  $this->importMode = $importMode;
1462  }
1463 
1464  public function isGlobalIgnorePid(): bool
1465  {
1466  return $this->globalIgnorePid;
1467  }
1468 
1469  public function setGlobalIgnorePid(bool $globalIgnorePid): void
1470  {
1471  $this->globalIgnorePid = $globalIgnorePid;
1472  }
1473 
1474  public function isForceAllUids(): bool
1475  {
1476  return $this->forceAllUids;
1477  }
1478 
1479  public function setForceAllUids(bool $forceAllUids): void
1480  {
1481  $this->forceAllUids = $forceAllUids;
1482  }
1483 
1484  public function isShowDiff(): bool
1485  {
1486  return $this->showDiff;
1487  }
1488 
1489  public function setShowDiff(bool $showDiff): void
1490  {
1491  $this->showDiff = $showDiff;
1492  }
1493 
1494  public function getSoftrefInputValues(): array
1495  {
1496  return $this->softrefInputValues;
1497  }
1498 
1499  public function setSoftrefInputValues(array $softrefInputValues): void
1500  {
1501  $this->softrefInputValues = $softrefInputValues;
1502  }
1503 
1504  public function getMode(): string
1505  {
1506  return $this->mode;
1507  }
1508 
1509  public function setMode(string $mode): void
1510  {
1511  $this->mode = $mode;
1512  }
1513 
1514  public function getImportMapId(): array
1515  {
1516  return $this->importMapId;
1517  }
1518 
1519  public function setImportMapId(array $importMapId): void
1520  {
1521  $this->importMapId = $importMapId;
1522  }
1523 
1524  public function getDat(): array
1525  {
1526  return $this->dat;
1527  }
1528 }
‪TYPO3\CMS\Core\Utility\DiffUtility
Definition: DiffUtility.php:28
‪TYPO3\CMS\Impexp\ImportExport\$extensionDependencies
‪array $extensionDependencies
Definition: ImportExport.php:134
‪TYPO3\CMS\Core\DataHandling\PageDoktypeRegistry
Definition: PageDoktypeRegistry.php:35
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static stripPathSitePrefix(string $path)
Definition: PathUtility.php:428
‪TYPO3\CMS\Impexp\ImportExport\$iconFactory
‪IconFactory $iconFactory
Definition: ImportExport.php:164
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Impexp\ImportExport\$pidRecord
‪array $pidRecord
Definition: ImportExport.php:67
‪TYPO3\CMS\Impexp\ImportExport\$showStaticRelations
‪bool $showStaticRelations
Definition: ImportExport.php:72
‪TYPO3\CMS\Impexp\ImportExport\$mode
‪string $mode
Definition: ImportExport.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixed_lgd_cs
‪static string fixed_lgd_cs(string $string, int $chars, string $appendString='...')
Definition: GeneralUtility.php:92
‪TYPO3\CMS\Impexp\ImportExport\addGeneralErrorsByTable
‪addGeneralErrorsByTable(string $table)
Definition: ImportExport.php:358
‪TYPO3\CMS\Impexp\ImportExport\$errorLog
‪array $errorLog
Definition: ImportExport.php:144
‪TYPO3\CMS\Impexp\ImportExport\addError
‪addError(string $message)
Definition: ImportExport.php:1314
‪TYPO3\CMS\Impexp\ImportExport\$forceAllUids
‪bool $forceAllUids
Definition: ImportExport.php:98
‪TYPO3\CMS\Impexp\ImportExport\getLanguageService
‪getLanguageService()
Definition: ImportExport.php:1329
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_AS_NEW
‪const IMPORT_MODE_AS_NEW
Definition: Import.php:53
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
Definition: InsufficientFolderAccessPermissionsException.php:23
‪TYPO3\CMS\Impexp\ImportExport\traversePageRecords
‪traversePageRecords(array $pageTree, array &$lines)
Definition: ImportExport.php:317
‪TYPO3\CMS\Impexp\ImportExport\traversePageTree
‪traversePageTree(array $pageTree, array &$lines, int $indent=0)
Definition: ImportExport.php:241
‪TYPO3\CMS\Core\Resource\Security\FileNameValidator
Definition: FileNameValidator.php:25
‪TYPO3\CMS\Impexp\ImportExport\renderSoftRefImportTextField
‪string renderSoftRefImportTextField(array $softref)
Definition: ImportExport.php:832
‪TYPO3\CMS\Impexp\ImportExport\$globalIgnorePid
‪bool $globalIgnorePid
Definition: ImportExport.php:93
‪TYPO3\CMS\Impexp\ImportExport\addFiles
‪addFiles(array $relations, array &$lines, int $indent, string $tokenID='')
Definition: ImportExport.php:588
‪TYPO3\CMS\Impexp\ImportExport\$pid
‪int $pid
Definition: ImportExport.php:62
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Impexp\ImportExport\isTableStatic
‪bool isTableStatic(string $table)
Definition: ImportExport.php:1138
‪TYPO3\CMS\Impexp\ImportExport\$diffUtility
‪DiffUtility $diffUtility
Definition: ImportExport.php:160
‪TYPO3\CMS\Impexp\ImportExport\$showDiff
‪bool $showDiff
Definition: ImportExport.php:103
‪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:924
‪TYPO3\CMS\Impexp\ImportExport\getRecordPath
‪string getRecordPath(int $pid)
Definition: ImportExport.php:1191
‪TYPO3\CMS\Impexp\ImportExport\renderIndent
‪renderIndent(int $indent)
Definition: ImportExport.php:771
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_FORCE_UID
‪const IMPORT_MODE_FORCE_UID
Definition: Import.php:52
‪TYPO3\CMS\Impexp\ImportExport\excludePageAndRecords
‪excludePageAndRecords(int $pageUid, array $page)
Definition: ImportExport.php:290
‪TYPO3\CMS\Impexp\ImportExport\$lang
‪LanguageService $lang
Definition: ImportExport.php:163
‪TYPO3\CMS\Impexp\ImportExport\$softrefCfg
‪array $softrefCfg
Definition: ImportExport.php:129
‪TYPO3\CMS\Impexp\ImportExport\isRecordDisabled
‪bool isRecordDisabled(string $table, int $uid)
Definition: ImportExport.php:277
‪TYPO3\CMS\Impexp\ImportExport\addSoftRefs
‪addSoftRefs(array $softrefs, array &$lines, int $indent)
Definition: ImportExport.php:690
‪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:1209
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_EXCLUDE
‪const IMPORT_MODE_EXCLUDE
Definition: Import.php:54
‪TYPO3\CMS\Impexp\ImportExport\getRecordFromDatabase
‪array null getRecordFromDatabase(string $table, int $uid, string $fields='uid, pid')
Definition: ImportExport.php:1180
‪TYPO3\CMS\Core\Utility\File\ExtendedFileUtility
Definition: ExtendedFileUtility.php:76
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static dirname(string $path)
Definition: PathUtility.php:243
‪TYPO3\CMS\Impexp\ImportExport\$doesImport
‪bool $doesImport
Definition: ImportExport.php:82
‪TYPO3\CMS\Impexp\ImportExport\$fileProcObj
‪ExtendedFileUtility $fileProcObj
Definition: ImportExport.php:159
‪TYPO3\CMS\Core\Resource\DefaultUploadFolderResolver
Definition: DefaultUploadFolderResolver.php:31
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:42
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId)
Definition: PreviewUriBuilder.php:65
‪TYPO3\CMS\Impexp\ImportExport\$importMapId
‪array $importMapId
Definition: ImportExport.php:139
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Impexp\ImportExport\addRelations
‪addRelations(array $relations, array &$lines, int $indent, array $recursionCheck=[])
Definition: ImportExport.php:512
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_RESPECT_PID
‪const IMPORT_MODE_RESPECT_PID
Definition: Import.php:56
‪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:175
‪TYPO3\CMS\Impexp\Import\IMPORT_MODE_IGNORE_PID
‪const IMPORT_MODE_IGNORE_PID
Definition: Import.php:55
‪TYPO3\CMS\Impexp\ImportExport
Definition: ImportExport.php:46
‪TYPO3\CMS\Impexp\ImportExport\$fileIdMap
‪array $fileIdMap
Definition: ImportExport.php:113
‪TYPO3\CMS\Impexp\Import\SOFTREF_IMPORT_MODE_EDITABLE
‪const SOFTREF_IMPORT_MODE_EDITABLE
Definition: Import.php:59
‪TYPO3\CMS\Impexp\ImportExport\renderSelectBox
‪string renderSelectBox(string $name, string $value, array $options)
Definition: ImportExport.php:957
‪TYPO3\CMS\Impexp\ImportExport\$update
‪bool $update
Definition: ImportExport.php:77
‪TYPO3\CMS\Impexp\ImportExport\$permsClause
‪string $permsClause
Definition: ImportExport.php:57
‪TYPO3\CMS\Impexp\ImportExport\$relStaticTables
‪array $relStaticTables
Definition: ImportExport.php:119
‪TYPO3\CMS\Impexp\Import\SOFTREF_IMPORT_MODE_EXCLUDE
‪const SOFTREF_IMPORT_MODE_EXCLUDE
Definition: Import.php:58
‪TYPO3\CMS\Impexp\ImportExport\$defaultImportExportFolder
‪Folder $defaultImportExportFolder
Definition: ImportExport.php:167
‪TYPO3\CMS\Impexp\ImportExport\getPidRecord
‪getPidRecord()
Definition: ImportExport.php:1352
‪TYPO3\CMS\Impexp\ImportExport\$excludeDisabledRecords
‪bool $excludeDisabledRecords
Definition: ImportExport.php:173
‪TYPO3\CMS\Impexp\ImportExport\$remainHeader
‪array $remainHeader
Definition: ImportExport.php:162
‪TYPO3\CMS\Impexp\ImportExport\$temporaryFolderName
‪string $temporaryFolderName
Definition: ImportExport.php:166
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪TYPO3\CMS\Impexp\ImportExport\isSoftRefIncluded
‪bool isSoftRefIncluded(string $tokenID)
Definition: ImportExport.php:1166
‪TYPO3\CMS\Impexp\ImportExport\addRecord
‪addRecord(string $table, int $uid, array &$lines, int $indent, bool $checkImportInPidRecord=false)
Definition: ImportExport.php:377
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Impexp\ImportExport\resolveStoragePath
‪string null resolveStoragePath(string $dirPrefix, bool $checkAlternatives=true)
Definition: ImportExport.php:1093
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:44
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Impexp\ImportExport\$importMode
‪array $importMode
Definition: ImportExport.php:88
‪TYPO3\CMS\Impexp\ImportExport\$cacheGetRecordPath
‪array $cacheGetRecordPath
Definition: ImportExport.php:149
‪TYPO3\CMS\Impexp\ImportExport\checkDokType
‪bool checkDokType(string $table, int $dokType)
Definition: ImportExport.php:783
‪TYPO3\CMS\Impexp\ImportExport\$excludeMap
‪array $excludeMap
Definition: ImportExport.php:124
‪TYPO3\CMS\Impexp\ImportExport\renderControls
‪string renderControls(array $line)
Definition: ImportExport.php:794
‪TYPO3\CMS\Impexp\ImportExport\getFileProcObj
‪ExtendedFileUtility getFileProcObj()
Definition: ImportExport.php:1296
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Impexp\ImportExport\$dat
‪array $dat
Definition: ImportExport.php:154
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Impexp\ImportExport\renderRecordExcludeCheckbox
‪string renderRecordExcludeCheckbox(string $recordRef)
Definition: ImportExport.php:817
‪TYPO3\CMS\Impexp\ImportExport\renderSoftRefExportSelector
‪string renderSoftRefExportSelector(array $softref)
Definition: ImportExport.php:862
‪TYPO3\CMS\Impexp\ImportExport\isRecordExcluded
‪bool isRecordExcluded(string $table, int $uid)
Definition: ImportExport.php:1155
‪TYPO3\CMS\Core\Resource\Exception
Definition: AbstractFileOperationException.php:16
‪TYPO3\CMS\Impexp
‪TYPO3\CMS\Impexp\ImportExport\getBackendUser
‪getBackendUser()
Definition: ImportExport.php:1324
‪TYPO3\CMS\Impexp\ImportExport\traverseAllRecords
‪traverseAllRecords(array $pageTree, array &$lines)
Definition: ImportExport.php:341
‪TYPO3\CMS\Impexp\ImportExport\$softrefInputValues
‪array $softrefInputValues
Definition: ImportExport.php:108
‪TYPO3\CMS\Impexp\ImportExport\renderPreview
‪array renderPreview()
Definition: ImportExport.php:191