[FEATURE] Enable automatic t3d import for extensions 97/23397/3
authorSusanne Moog <typo3@susannemoog.de>
Wed, 28 Aug 2013 10:36:45 +0000 (12:36 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Wed, 28 Aug 2013 14:31:16 +0000 (16:31 +0200)
As preparation for the new distribution (introduction package ...)
handling extensions should be able to provide initial t3d imports.
These are then imported on the root level upon installing the extension.

The t3d file has to be called data.t3d and located in
<extension>/Initialisation/data.t3d.

The data is imported only once (even if you reinstall the extension),
execution state is saved via the core registry.

Resolves: #51437
Releases: 6.2
Change-Id: Ibfe631d173b962781018c6c9e929f4f020e48aa5
Reviewed-on: https://review.typo3.org/23397
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/InstallUtilityTest.php
typo3/sysext/impexp/Classes/Utility/ImportExportUtility.php [new file with mode: 0644]

index fda64d7..b070ec8 100644 (file)
@@ -76,6 +76,18 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
        public $extensionRepository;
 
        /**
+        * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
+        * @inject
+        */
+       protected $signalSlotDispatcher;
+
+       /**
+        * @var \TYPO3\CMS\Core\Registry
+        * @inject
+        */
+       protected $registry;
+
+       /**
         * __construct
         */
        public function __construct() {
@@ -215,11 +227,9 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
                if ($extTablesSqlContent !== '') {
                        $this->updateDbWithExtTablesSql($extTablesSqlContent);
                }
-               $extTablesStaticSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables_static+adt.sql';
-               if (file_exists($extTablesStaticSqlFile)) {
-                       $extTablesStaticSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesStaticSqlFile);
-                       $this->importStaticSql($extTablesStaticSqlContent);
-               }
+
+               $this->importStaticSqlFile($extension['siteRelPath']);
+               $this->importT3DFile($extension['siteRelPath']);
        }
 
        /**
@@ -380,6 +390,51 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
                return FALSE;
        }
 
+       /**
+        * Uses the export import extension to import a T3DFile to PID 0
+        * Execution state is saved in the this->registry, so it only happens once
+        *
+        * @param string $extensionSiteRelPath
+        * @return void
+        */
+       protected function importT3DFile($extensionSiteRelPath) {
+               $t3dImportRelFile = $extensionSiteRelPath . '/Initialisation/data.t3d';
+               if (!$this->registry->get('extensionDataImport', $t3dImportRelFile)) {
+                       $t3dImportFile = PATH_site . $t3dImportRelFile;
+                       if (file_exists($t3dImportFile)) {
+                               $importExportUtility = $this->objectManager->get('TYPO3\\CMS\\Impexp\\Utility\\ImportExportUtility');
+                               try {
+                                       $importResult = $importExportUtility->importT3DFile($t3dImportFile, 0);
+                                       $this->registry->set('extensionDataImport', $t3dImportRelFile, 1);
+                                       $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionT3DImport', array($t3dImportRelFile, $importResult, $this));
+                               } catch (\ErrorException $e) {
+                                       /** @var \TYPO3\CMS\Core\Log\Logger $logger */
+                                       $logger = $this->objectManager->get('TYPO3\\CMS\\Core\\Log\\LogManager')->getLogger(__CLASS__);
+                                       $logger->log(\TYPO3\CMS\Core\Log\LogLevel::WARNING, $e->getMessage());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Imports a static tables SQL File (ext_tables_static+adt)
+        * Execution state is saved in the this->registry, so it only happens once
+        *
+        * @param string $extensionSiteRelPath
+        * @return void
+        */
+       protected function importStaticSqlFile($extensionSiteRelPath) {
+               $extTablesStaticSqlRelFile = $extensionSiteRelPath . '/ext_tables_static+adt.sql';
+               if (!$this->registry->get('extensionDataImport', $extTablesStaticSqlRelFile)) {
+                       $extTablesStaticSqlFile = PATH_site . $extTablesStaticSqlRelFile;
+                       if (file_exists($extTablesStaticSqlFile)) {
+                               $extTablesStaticSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesStaticSqlFile);
+                               $this->importStaticSql($extTablesStaticSqlContent);
+                       }
+                       $this->registry->set('extensionDataImport', $extTablesStaticSqlRelFile, 1);
+                       $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionStaticSqlImport', array($extTablesStaticSqlRelFile, $this));
+               }
+       }
 }
 
 
index bdb9f10..4a90bae 100644 (file)
@@ -97,8 +97,8 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         */
        protected function createFakeExtension() {
                $extKey = strtolower(uniqid('testing'));
-               $absExtPath = PATH_site . 'typo3temp/' . $extKey . '/';
-               $relPath = 'typo3temp/' . $extKey . '/';
+               $absExtPath = PATH_site . 'typo3temp/' . $extKey;
+               $relPath = 'typo3temp/' . $extKey;
                \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($absExtPath);
                $this->fakedExtensions[$extKey] = array(
                        'siteRelPath' => $relPath
@@ -186,7 +186,10 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                $extTablesFile = $extPath . 'ext_tables.sql';
                $fileContent = 'DUMMY TEXT TO COMPARE';
                file_put_contents($extTablesFile, $fileContent);
-               $installMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility', array('updateDbWithExtTablesSql'));
+               $installMock = $this->getMock(
+                       'TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility',
+                       array('updateDbWithExtTablesSql', 'importStaticSqlFile', 'importT3DFile')
+               );
                $installMock->expects($this->once())->method('updateDbWithExtTablesSql')->with($this->stringStartsWith($fileContent));
                $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
        }
@@ -194,39 +197,56 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         */
-       public function processDatabaseUpdatesCallsImportStaticSql() {
+       public function processDatabaseUpdatesCallsImportStaticSqlFile() {
                $extKey = $this->createFakeExtension();
-               $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
-               $extTablesFile = $extPath . 'ext_tables_static+adt.sql';
-               $fileContent = 'DUMMY TEXT TO COMPARE';
-               file_put_contents($extTablesFile, $fileContent);
-               $installMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility', array('importStaticSql'));
-               $installMock->expects($this->once())->method('importStaticSql')->with($fileContent);
+               $extRelPath = 'typo3temp/' . $extKey;
+               $installMock = $this->getMock(
+                       'TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility',
+                       array('importStaticSqlFile', 'updateDbWithExtTablesSql', 'importT3DFile')
+               );
+               $installMock->expects($this->once())->method('importStaticSqlFile')->with($extRelPath);
                $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
        }
 
        /**
         * @test
         */
-       public function InstallCallsUpdateDbWithCachingFrameworkTables() {
+       public function processDatabaseUpdatesCallsImportT3DFile() {
                $extKey = $this->createFakeExtension();
+               $absPath = PATH_site . $this->fakedExtensions[$extKey]['siteRelPath'];
+               \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($absPath . '/Initialisation');
+               file_put_contents($absPath . '/Initialisation/data.t3d', 'DUMMY');
                $installMock = $this->getMock(
                        'TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility',
-                       array(
-                               'enrichExtensionWithDetails',
-                               'ensureConfiguredDirectoriesExist',
-                               'updateDbWithExtTablesSql'
-                       )
+                       array('updateDbWithExtTablesSql', 'importStaticSqlFile', 'importT3DFile')
                );
-               $installMock->expects($this->any())
-                       ->method('enrichExtensionWithDetails')
-                       ->with($extKey)
-                       ->will($this->returnValue(array('key' => $extKey)));
-               $installMock->expects($this->at(2))
-                       ->method('updateDbWithExtTablesSql')
-                       ->with($this->stringContains('CREATE TABLE cf_cache_hash'));
+               $installMock->expects($this->once())->method('importT3DFile')->with($this->fakedExtensions[$extKey]['siteRelPath']);
+               $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
+       }
 
-               $installMock->install($extKey);
+       /**
+        * @test
+        */
+       public function importT3DFileDoesNotImportFileIfAlreadyImported() {
+               $extKey = $this->createFakeExtension();
+               $absPath = PATH_site . $this->fakedExtensions[$extKey]['siteRelPath'];
+               \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($absPath . 'Initialisation');
+               file_put_contents($absPath . 'Initialisation/data.t3d', 'DUMMY');
+               $registryMock = $this->getMock('\\TYPO3\\CMS\\Core\\Registry', array('get', 'set'));
+               $registryMock
+                       ->expects($this->once())
+                       ->method('get')
+                       ->with('extensionDataImport', $this->fakedExtensions[$extKey]['siteRelPath'] . '/Initialisation/data.t3d')
+                       ->will($this->returnValue(TRUE)
+               );
+               $installMock = $this->getAccessibleMock(
+                       'TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility',
+                       array('getRegistry', 'getImportExportUtility')
+               );
+               $installMock->_set('registry', $registryMock);
+               $installMock->expects($this->never())->method('getImportExportUtility');
+               $installMock->_call('importT3DFile', $this->fakedExtensions[$extKey]['siteRelPath']);
        }
+
 }
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/impexp/Classes/Utility/ImportExportUtility.php b/typo3/sysext/impexp/Classes/Utility/ImportExportUtility.php
new file mode 100644 (file)
index 0000000..f396fcd
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+namespace TYPO3\CMS\Impexp\Utility;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Susanne Moog <susanne.moog@typo3.org>
+ *  (c) 2013 Oliver Hader <oliver.hader@typo3.org>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Utility for import / export
+ * Can be used for API access for simple importing of files
+ *
+ */
+class ImportExportUtility {
+
+       /**
+        * Import a T3D file directly
+        *
+        * @param string $file The full absolute path to the file
+        * @param int $pid The pid under which the t3d file should be imported
+        * @throws \ErrorException
+        * @throws \InvalidArgumentException
+        * @return array
+        */
+       public function importT3DFile($file, $pid) {
+               $importResponse = array();
+               if (!is_string($file)) {
+                       throw new \InvalidArgumentException('Input parameter $file has to be of type string', 1377625645);
+               }
+               if (!is_int($pid)) {
+                       throw new \InvalidArgumentException('Input parameter $int has to be of type integer', 1377625646);
+               }
+               /** @var $import \TYPO3\CMS\Impexp\ImportExport */
+               $import = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Impexp\\ImportExport');
+               $import->init(0, 'import');
+
+               if ($file && @is_file($file)) {
+                       if ($import->loadFile($file, 1)) {
+                               // Import to root page:
+                               $import->importData($pid);
+                               // Get id of container page:
+                               $newPages = $import->import_mapId['pages'];
+                               reset($newPages);
+                               $importResponse = current($newPages);
+                       }
+               }
+
+               // Check for errors during the import process:
+               if (empty($importResponse) && $errors = $import->printErrorLog()) {
+                       throw new \ErrorException($errors, 1377625537);
+               } else {
+                       return $importResponse;
+               }
+       }
+}
+
+?>
\ No newline at end of file