[FEATURE] Enable automatic file import for extensions 27/23427/3
authorSusanne Moog <typo3@susannemoog.de>
Wed, 28 Aug 2013 15:14:41 +0000 (17:14 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 29 Aug 2013 12:01:49 +0000 (14:01 +0200)
As preparation for the new distribution (introduction package ...)
handling extensions should be able to provide initial file imports.
These are then imported to fileadmin/<extensionname>
upon installing the extension.

The files have to be located in <extension>/Initialisation/Files/*.

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

Resolves: #51466
Releases: 6.2
Change-Id: Icbf63227aa8bbb9fcfb0335bfa5ae92b549a94ba
Reviewed-on: https://review.typo3.org/23427
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/core/Classes/Utility/GeneralUtility.php
typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/InstallUtilityTest.php

index cc3444b..6765ae4 100644 (file)
@@ -3594,6 +3594,31 @@ Connection: close
                return TRUE;
        }
 
+
+       /**
+        * Low level utility function to copy directories and content recursive
+        *
+        * @param string $source Path to source directory, relative to document root
+        * @param string $destination Path to destination directory, relative to document root
+        */
+       public static function copyDirectory($source, $destination) {
+               $source = PATH_site . $source;
+               $destination = PATH_site . $destination;
+               if (static::isAllowedAbsPath($source) && static::isAllowedAbsPath($destination)) {
+                       $iterator = new \RecursiveIteratorIterator(
+                               new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS),
+                               \RecursiveIteratorIterator::SELF_FIRST
+                       );
+                       foreach ($iterator as $item) {
+                               if ($item->isDir()) {
+                                       @mkdir($destination . '/' . $iterator->getSubPathName());
+                               } else {
+                                       @copy($item, $destination . '/' . $iterator->getSubPathName());
+                               }
+                       }
+               }
+       }
+
        /**
         * Checks if a given string is a valid frame URL to be loaded in the
         * backend.
index 50f5c0f..d88df8f 100644 (file)
@@ -3832,6 +3832,35 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertFalse(Utility\GeneralUtility::verifyFilenameAgainstDenyPattern('image\0.gif'));
        }
 
+
+       /////////////////////////////////////////////////////////////////////////////////////
+       // Tests concerning copyDirectory
+       /////////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * @test
+        */
+       public function copyDirectoryCopiesFilesAndDirectories() {
+               $sourceDirectory = 'typo3temp/' . uniqid('test_') . '/';
+               $absoluteSourceDirectory = PATH_site . $sourceDirectory;
+               $this->testFilesToDelete[] = $absoluteSourceDirectory;
+               Utility\GeneralUtility::mkdir($absoluteSourceDirectory);
+
+               $targetDirectory = 'typo3temp/' . uniqid('test_') . '/';
+               $absoluteTargetDirectory = PATH_site . $targetDirectory;
+               $this->testFilesToDelete[] = $absoluteTargetDirectory;
+               Utility\GeneralUtility::mkdir($absoluteTargetDirectory);
+
+               Utility\GeneralUtility::writeFileToTypo3tempDir($absoluteSourceDirectory . 'file', '42');
+               Utility\GeneralUtility::mkdir($absoluteSourceDirectory . 'foo');
+               Utility\GeneralUtility::writeFileToTypo3tempDir($absoluteSourceDirectory . 'foo/file', '42');
+
+               Utility\GeneralUtility::copyDirectory($sourceDirectory, $targetDirectory);
+
+               $this->assertFileExists($absoluteTargetDirectory . 'file');
+               $this->assertFileExists($absoluteTargetDirectory . 'foo/file');
+       }
+
        /////////////////////////////////////////////////////////////////////////////////////
        // Tests concerning sysLog
        /////////////////////////////////////////////////////////////////////////////////////
index b070ec8..991e8d8 100644 (file)
@@ -109,6 +109,7 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
                $extension = $this->enrichExtensionWithDetails($extensionKey);
                $this->processDatabaseUpdates($extension);
                $this->ensureConfiguredDirectoriesExist($extension);
+               $this->importInitialFiles($extension['siteRelPath'], $extensionKey);
                if ($extension['clearcacheonload']) {
                        $GLOBALS['typo3CacheManager']->flushCaches();
                }
@@ -435,6 +436,32 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
                        $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionStaticSqlImport', array($extTablesStaticSqlRelFile, $this));
                }
        }
+
+       /**
+        * Imports files from Initialisation/Files to fileadmin
+        * via lowlevel copy directory method
+        *
+        * @param string $extensionSiteRelPath relative path to extension dir
+        * @param string $extensionKey
+        */
+       protected function importInitialFiles($extensionSiteRelPath, $extensionKey) {
+               $importRelFolder = $extensionSiteRelPath . '/Initialisation/Files';
+               if (!$this->registry->get('extensionDataImport', $importRelFolder)) {
+                       $importFolder = PATH_site . $importRelFolder;
+                       if (file_exists($importFolder)) {
+                               $destinationRelPath = $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . $extensionKey;
+                               $destinationAbsolutePath = PATH_site . $destinationRelPath;
+                               if (!file_exists($destinationAbsolutePath) &&
+                                       \TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($destinationAbsolutePath)
+                               ) {
+                                       \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($destinationAbsolutePath);
+                               }
+                               \TYPO3\CMS\Core\Utility\GeneralUtility::copyDirectory($importRelFolder, $destinationRelPath);
+                               $this->registry->set('extensionDataImport', $importRelFolder, 1);
+                               $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionFileImport', array($destinationAbsolutePath, $this));
+                       }
+               }
+       }
 }
 
 
index 4a90bae..3f6371c 100644 (file)
@@ -66,6 +66,7 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'saveDefaultConfiguration',
                        'enrichExtensionWithDetails',
                        'ensureConfiguredDirectoriesExist',
+                       'importInitialFiles'
                ));
                $this->installMock->expects($this->any())
                                ->method('enrichExtensionWithDetails')