From 76d868d97ee01138c72243eaa16e6d28428773c5 Mon Sep 17 00:00:00 2001
From: Benjamin Kott <benjamin.kott@outlook.com>
Date: Thu, 6 Jul 2023 10:14:02 +0200
Subject: [PATCH] [BUGFIX] Allow import module to also access distributions

This patch streamlines the import module with the import command.
While the CLI commands can import data from extensions, the interface
has no option to perform this action. We are now listing available
datasets from distributions in the import module.

Resolves: #101256
Releases: main, 12.4
Change-Id: I6fac0d22bbb42a6ff8b682b6c3415a3d7e4982d6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/79863
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../Classes/Controller/ImportController.php   | 28 ++++++++++++++++++-
 typo3/sysext/impexp/Classes/ImportExport.php  |  5 +++-
 ...ewImportPageAndRecordsByUpdateWithDiff.php | 10 +++----
 ...derPreviewImportPageAndRecordsWithDiff.php | 14 +++++-----
 4 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/typo3/sysext/impexp/Classes/Controller/ImportController.php b/typo3/sysext/impexp/Classes/Controller/ImportController.php
index aefc4615b720..5b09b139e6eb 100644
--- a/typo3/sysext/impexp/Classes/Controller/ImportController.php
+++ b/typo3/sysext/impexp/Classes/Controller/ImportController.php
@@ -27,6 +27,7 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Package\PackageManager;
 use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\File;
 use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
@@ -36,6 +37,7 @@ use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
 use TYPO3\CMS\Core\Utility\File\ExtendedFileUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\PathUtility;
 use TYPO3\CMS\Impexp\Import;
 
 /**
@@ -176,7 +178,11 @@ class ImportController
         $import->setShowDiff(!(bool)($inputData['notShowDiff'] ?? false));
         $import->setSoftrefInputValues((array)($inputData['softrefInputValues'] ?? null));
         if (!empty($inputData['file'])) {
-            $filePath = $this->getFilePathWithinFileMountBoundaries((string)$inputData['file']);
+            if (PathUtility::isExtensionPath($inputData['file'])) {
+                $filePath = $inputData['file'];
+            } else {
+                $filePath = $this->getFilePathWithinFileMountBoundaries((string)$inputData['file']);
+            }
             try {
                 $import->loadFile($filePath, true);
                 $import->checkImportPrerequisites();
@@ -204,6 +210,8 @@ class ImportController
     protected function getSelectableFileList(Import $import): array
     {
         $exportFiles = [];
+
+        // Fileadmin
         $folder = $import->getOrCreateDefaultImportExportFolder();
         if ($folder !== null) {
             $filter = GeneralUtility::makeInstance(FileExtensionFilter::class);
@@ -215,6 +223,24 @@ class ImportController
         foreach ($exportFiles as $file) {
             $selectableFiles[$file->getCombinedIdentifier()] = $file->getPublicUrl();
         }
+
+        // Extension Distribution
+        if ($this->getBackendUser()->isAdmin()) {
+            $possibleImportFiles = [
+                'Initialisation/data.t3d',
+                'Initialisation/data.xml',
+            ];
+            $activePackages = GeneralUtility::makeInstance(PackageManager::class)->getActivePackages();
+            foreach ($activePackages as $package) {
+                foreach ($possibleImportFiles as $possibleImportFile) {
+                    if (!file_exists($package->getPackagePath() . $possibleImportFile)) {
+                        continue;
+                    }
+                    $selectableFiles['EXT:' . $package->getPackageKey() . '/' . $possibleImportFile] = 'EXT:' . $package->getPackageKey() . '/' . $possibleImportFile;
+                }
+            }
+        }
+
         return $selectableFiles;
     }
 
diff --git a/typo3/sysext/impexp/Classes/ImportExport.php b/typo3/sysext/impexp/Classes/ImportExport.php
index 310419c68590..cbbbbc3ccf42 100644
--- a/typo3/sysext/impexp/Classes/ImportExport.php
+++ b/typo3/sysext/impexp/Classes/ImportExport.php
@@ -597,8 +597,11 @@ abstract class ImportExport
                         $databaseRecord = $this->getRecordFromDatabase($table, $newUid, '*');
                         BackendUtility::workspaceOL($table, $databaseRecord);
                     }
+                    /** @var array|null $importRecord */
                     $importRecord = $this->dat['records'][$table . ':' . $uid]['data'] ?? null;
-                    if (is_array($databaseRecord) && is_array($importRecord)) {
+                    if ($databaseRecord === null) {
+                        $line['showDiffContent'] = '';
+                    } elseif (is_array($databaseRecord) && is_array($importRecord)) {
                         $line['showDiffContent'] = $this->compareRecords($databaseRecord, $importRecord, $table, $diffInverse);
                     } else {
                         $line['showDiffContent'] = 'ERROR: One of the inputs were not an array!';
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdateWithDiff.php b/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdateWithDiff.php
index f43bf5b5098f..95ae71a84ba0 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdateWithDiff.php
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdateWithDiff.php
@@ -33,7 +33,7 @@ return [
       'active' => 'active',
       'updatePath' => '<strong>NEW!</strong>',
       'updateMode' => sprintf('<select class="form-select form-select-sm" name="tx_impexp[import_mode][pages:0]" style="width: 100px"><option value="0">Insert</option><option value="%s">Force UID [0] (Admin)</option><option value="%s">Exclude</option></select>', \TYPO3\CMS\Impexp\Import::IMPORT_MODE_FORCE_UID, \TYPO3\CMS\Impexp\Import::IMPORT_MODE_EXCLUDE),
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -310,7 +310,7 @@ return [
       'active' => 'active',
       'updatePath' => '<strong>NEW!</strong>',
       'updateMode' => sprintf('<select class="form-select form-select-sm" name="tx_impexp[import_mode][tt_content:3]" style="width: 100px"><option value="0">Insert</option><option value="%s">Force UID [3] (Admin)</option><option value="%s">Exclude</option></select>', \TYPO3\CMS\Impexp\Import::IMPORT_MODE_FORCE_UID, \TYPO3\CMS\Impexp\Import::IMPORT_MODE_EXCLUDE),
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -374,7 +374,7 @@ return [
       'active' => 'active',
       'updatePath' => '<strong>NEW!</strong>',
       'updateMode' => sprintf('<select class="form-select form-select-sm" name="tx_impexp[import_mode][sys_file_reference:1]" style="width: 100px"><option value="0">Insert</option><option value="%s">Force UID [1] (Admin)</option><option value="%s">Exclude</option></select>', \TYPO3\CMS\Impexp\Import::IMPORT_MODE_FORCE_UID, \TYPO3\CMS\Impexp\Import::IMPORT_MODE_EXCLUDE),
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -423,7 +423,7 @@ return [
       'active' => 'active',
       'updatePath' => '<strong>NEW!</strong>',
       'updateMode' => sprintf('<select class="form-select form-select-sm" name="tx_impexp[import_mode][sys_file_reference:2]" style="width: 100px"><option value="0">Insert</option><option value="%s">Force UID [2] (Admin)</option><option value="%s">Exclude</option></select>', \TYPO3\CMS\Impexp\Import::IMPORT_MODE_FORCE_UID, \TYPO3\CMS\Impexp\Import::IMPORT_MODE_EXCLUDE),
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -472,7 +472,7 @@ return [
       'active' => 'active',
       'updatePath' => '<strong>NEW!</strong>',
       'updateMode' => sprintf('<select class="form-select form-select-sm" name="tx_impexp[import_mode][sys_file_reference:3]" style="width: 100px"><option value="0">Insert</option><option value="%s">Force UID [3] (Admin)</option><option value="%s">Exclude</option></select>', \TYPO3\CMS\Impexp\Import::IMPORT_MODE_FORCE_UID, \TYPO3\CMS\Impexp\Import::IMPORT_MODE_EXCLUDE),
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithDiff.php b/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithDiff.php
index 7bdf277bafe8..d3ce6c98bad6 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithDiff.php
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithDiff.php
@@ -31,7 +31,7 @@ return [
 </span>',
       'title' => '',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -48,7 +48,7 @@ return [
 </span>',
       'title' => 'used-1.jpg',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -118,7 +118,7 @@ return [
 </span>',
       'title' => 'fileadmin',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -269,7 +269,7 @@ return [
 </span>',
       'title' => 'CE 3 second image',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -331,7 +331,7 @@ return [
 </span>',
       'title' => 'used-1.jpg',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -378,7 +378,7 @@ return [
 </span>',
       'title' => 'used-2.jpg',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
@@ -425,7 +425,7 @@ return [
 </span>',
       'title' => 'used-2.jpg',
       'active' => 'active',
-      'showDiffContent' => 'ERROR: One of the inputs were not an array!',
+      'showDiffContent' => '',
       'controls' => '',
       'message' => '',
     ],
-- 
GitLab