[TASK] Decouple extension setup from installation 11/44011/5
authorNicole Cordes <typo3@cordes.co>
Mon, 12 Oct 2015 14:04:50 +0000 (16:04 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Wed, 14 Oct 2015 13:00:59 +0000 (15:00 +0200)
This patch introduces an API which does all necessary setup steps for an
extension without activating it or clearing the caches. This is useful
in deployment scenarios as well as enhancing the composer
usage experience.

The patch
* adds an own cache for available extension information in ListUtility
* decouples the function to retrieve basic extension information
* adds an api method to setup an extension

Resolves: #70606
Releases: master
Change-Id: I7b535cf0a17cfa7c6c68ed67486ce04a5cabbfc0
Reviewed-on: http://review.typo3.org/44011
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/InstallUtilityTest.php

index c773169..ee2c5b0 100644 (file)
@@ -14,8 +14,9 @@ namespace TYPO3\CMS\Extensionmanager\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Service\OpcodeCacheService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\PathUtility;
 use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
 use TYPO3\CMS\Impexp\Utility\ImportExportUtility;
@@ -187,13 +188,21 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface
             $this->cacheManager->flushCachesInGroup('system');
         }
         $this->reloadCaches();
+        $this->processExtensionSetup($extensionKey);
+
+        $this->emitAfterExtensionInstallSignal($extensionKey);
+    }
 
+    /**
+     * @param string $extensionKey
+     */
+    public function processExtensionSetup($extensionKey)
+    {
+        $extension = $this->getExtensionArray($extensionKey);
         $this->importInitialFiles($extension['siteRelPath'], $extensionKey);
         $this->processDatabaseUpdates($extension);
         $this->processRuntimeDatabaseUpdates($extensionKey);
-        $this->saveDefaultConfiguration($extension['key']);
-
-        $this->emitAfterExtensionInstallSignal($extensionKey);
+        $this->saveDefaultConfiguration($extensionKey);
     }
 
     /**
@@ -313,12 +322,7 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function enrichExtensionWithDetails($extensionKey)
     {
-        $availableExtensions = $this->listUtility->getAvailableExtensions();
-        if (isset($availableExtensions[$extensionKey])) {
-            $extension = $availableExtensions[$extensionKey];
-        } else {
-            throw new ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1342864081);
-        }
+        $extension = $this->getExtensionArray($extensionKey);
         $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation(array($extensionKey => $extension));
 
         if (!isset($availableAndInstalledExtensions[$extensionKey])) {
@@ -332,6 +336,21 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface
     }
 
     /**
+     * @param string $extensionKey
+     * @return array
+     * @throws ExtensionManagerException
+     */
+    protected function getExtensionArray($extensionKey)
+    {
+        $availableExtensions = $this->listUtility->getAvailableExtensions();
+        if (isset($availableExtensions[$extensionKey])) {
+            return $availableExtensions[$extensionKey];
+        } else {
+            throw new ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1342864081);
+        }
+    }
+
+    /**
      * Creates directories as requested in ext_emconf.php
      *
      * @param array $extension
index 8978b12..59c5789 100644 (file)
@@ -56,6 +56,11 @@ class ListUtility implements \TYPO3\CMS\Core\SingletonInterface
     protected $signalSlotDispatcher;
 
     /**
+     * @var array
+     */
+    protected $availableExtensions = NULL;
+
+    /**
      * @param \TYPO3\CMS\Extensionmanager\Utility\EmConfUtility $emConfUtility
      */
     public function injectEmConfUtility(\TYPO3\CMS\Extensionmanager\Utility\EmConfUtility $emConfUtility)
@@ -102,18 +107,20 @@ class ListUtility implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function getAvailableExtensions()
     {
-        $this->emitPackagesMayHaveChangedSignal();
-        $extensions = array();
-        foreach ($this->packageManager->getAvailablePackages() as $package) {
-            $installationType = $this->getInstallTypeForPackage($package);
-            $extensions[$package->getPackageKey()] = array(
-                'siteRelPath' => str_replace(PATH_site, '', $package->getPackagePath()),
-                'type' => $installationType,
-                'key' => $package->getPackageKey(),
-                'ext_icon' => ExtensionManagementUtility::getExtensionIcon($package->getPackagePath()),
-            );
+        if ($this->availableExtensions === NULL) {
+            $this->emitPackagesMayHaveChangedSignal();
+            foreach ($this->packageManager->getAvailablePackages() as $package) {
+                $installationType = $this->getInstallTypeForPackage($package);
+                $this->availableExtensions[$package->getPackageKey()] = array(
+                    'siteRelPath' => str_replace(PATH_site, '', $package->getPackagePath()),
+                    'type' => $installationType,
+                    'key' => $package->getPackageKey(),
+                    'ext_icon' => ExtensionManagementUtility::getExtensionIcon($package->getPackagePath()),
+                );
+            }
         }
-        return $extensions;
+
+        return $this->availableExtensions;
     }
 
     /**
index caab13c..ede4169 100644 (file)
@@ -59,6 +59,7 @@ class InstallUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
                 'reloadCaches',
                 'processCachingFrameworkUpdates',
                 'saveDefaultConfiguration',
+                'getExtensionArray',
                 'enrichExtensionWithDetails',
                 'ensureConfiguredDirectoriesExist',
                 'importInitialFiles',
@@ -71,6 +72,10 @@ class InstallUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
         $dependencyUtility = $this->getMock(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility::class);
         $this->installMock->_set('dependencyUtility', $dependencyUtility);
         $this->installMock->expects($this->any())
+            ->method('getExtensionArray')
+            ->with($this->extensionKey)
+            ->will($this->returnCallback(array($this, 'getExtensionData')));
+        $this->installMock->expects($this->any())
             ->method('enrichExtensionWithDetails')
             ->with($this->extensionKey)
             ->will($this->returnCallback(array($this, 'getExtensionData')));