[BUGFIX] Streamline package management in PackageManager 87/55687/42
authorNicole Cordes <typo3@cordes.co>
Mon, 12 Feb 2018 20:30:43 +0000 (21:30 +0100)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Mon, 12 Mar 2018 14:03:25 +0000 (15:03 +0100)
This bugfix resolves an issue that all available Packages
are scanned at each request. At the same time, it fixes
an issue related to runtimeActivatedPackages.

We now
- resolve package key with api usage
- distinguish between registered and available packages
- remove superfluous exception annotations
- prevent superfluous scans on getPackage() and isPackageAvailable() calls

Releases: master, 8.7
Resolves: #83820
Change-Id: I2b8bff3d4bb5287fd76418217653477c77467a8e
Reviewed-on: https://review.typo3.org/55687
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
typo3/sysext/core/Classes/Package/PackageManager.php

index f63139f..d9556d0 100644 (file)
@@ -396,7 +396,7 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
     protected function registerPackagesFromConfiguration(array $packages, $registerOnlyNewPackages = false, $packageStatesHasChanged = false)
     {
         foreach ($packages as $packageKey => $stateConfiguration) {
-            if ($registerOnlyNewPackages && $this->isPackageAvailable($packageKey)) {
+            if ($registerOnlyNewPackages && $this->isPackageRegistered($packageKey)) {
                 continue;
             }
 
@@ -436,12 +436,11 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      * @param PackageInterface $package The Package to be registered
      * @return PackageInterface
      * @throws Exception\InvalidPackageStateException
-     * @throws Exception\PackageStatesFileNotWritableException
      */
     public function registerPackage(PackageInterface $package)
     {
         $packageKey = $package->getPackageKey();
-        if ($this->isPackageAvailable($packageKey)) {
+        if ($this->isPackageRegistered($packageKey)) {
             throw new Exception\InvalidPackageStateException('Package "' . $packageKey . '" is already registered.', 1338996122);
         }
 
@@ -483,10 +482,10 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function getPackageKeyFromComposerName($composerName)
     {
-        if (isset($this->packageAliasMap[$composerName])) {
-            return $this->packageAliasMap[$composerName];
-        }
         $lowercasedComposerName = strtolower($composerName);
+        if (isset($this->packageAliasMap[$lowercasedComposerName])) {
+            return $this->packageAliasMap[$lowercasedComposerName];
+        }
         if (isset($this->composerNameToPackageKeyMap[$lowercasedComposerName])) {
             return $this->composerNameToPackageKeyMap[$lowercasedComposerName];
         }
@@ -504,10 +503,7 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function getPackage($packageKey)
     {
-        if (isset($this->packageAliasMap[$lowercasedPackageKey = strtolower($packageKey)])) {
-            $packageKey = $this->packageAliasMap[$lowercasedPackageKey];
-        }
-        if (!$this->isPackageAvailable($packageKey)) {
+        if (!$this->isPackageRegistered($packageKey) && !$this->isPackageAvailable($packageKey)) {
             throw new Exception\UnknownPackageException('Package "' . $packageKey . '" is not available. Please check if the package exists and that the package key is correct (package keys are case sensitive).', 1166546734);
         }
         return $this->packages[$packageKey];
@@ -523,15 +519,17 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function isPackageAvailable($packageKey)
     {
+        if ($this->isPackageRegistered($packageKey)) {
+            return true;
+        }
+
         // If activePackages is empty, the PackageManager is currently initializing
         // thus packages should not be scanned
         if (!$this->availablePackagesScanned && !empty($this->activePackages)) {
             $this->scanAvailablePackages();
         }
-        if (isset($this->packageAliasMap[$lowercasedPackageKey = strtolower($packageKey)])) {
-            $packageKey = $this->packageAliasMap[$lowercasedPackageKey];
-        }
-        return isset($this->packages[$packageKey]);
+
+        return $this->isPackageRegistered($packageKey);
     }
 
     /**
@@ -543,6 +541,8 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      */
     public function isPackageActive($packageKey)
     {
+        $packageKey = $this->getPackageKeyFromComposerName($packageKey);
+
         return isset($this->runtimeActivatedPackages[$packageKey]) || isset($this->packageStatesConfiguration['packages'][$packageKey]);
     }
 
@@ -631,7 +631,6 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      *
      * @param string $packageKey
      * @throws Exception
-     * @throws Exception\InvalidPackageStateException
      * @throws Exception\ProtectedPackageKeyException
      * @throws Exception\UnknownPackageException
      */
@@ -681,6 +680,19 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
     }
 
     /**
+     * Returns TRUE if a package was already registered or FALSE if it's not.
+     *
+     * @param string $packageKey
+     * @return bool
+     */
+    protected function isPackageRegistered($packageKey)
+    {
+        $packageKey = $this->getPackageKeyFromComposerName($packageKey);
+
+        return isset($this->packages[$packageKey]);
+    }
+
+    /**
      * Orders all active packages by comparing their dependencies. By this, the packages
      * and package configurations arrays holds all packages in the correct
      * initialization order.
@@ -819,7 +831,7 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
     public function unregisterPackage(PackageInterface $package)
     {
         $packageKey = $package->getPackageKey();
-        if (!$this->isPackageAvailable($packageKey)) {
+        if (!$this->isPackageRegistered($packageKey)) {
             throw new Exception\InvalidPackageStateException('Package "' . $packageKey . '" is not registered.', 1338996142);
         }
         $this->unregisterPackageByPackageKey($packageKey);
@@ -830,13 +842,10 @@ class PackageManager implements \TYPO3\CMS\Core\SingletonInterface
      *
      * @param string $packageKey
      * @throws Exception\InvalidPackageStateException if the package isn't available
-     * @throws Exception\InvalidPackageKeyException if an invalid package key was passed
-     * @throws Exception\InvalidPackagePathException if an invalid package path was passed
-     * @throws Exception\InvalidPackageManifestException if no extension configuration file could be found
      */
     public function reloadPackageInformation($packageKey)
     {
-        if (!$this->isPackageAvailable($packageKey)) {
+        if (!$this->isPackageRegistered($packageKey)) {
             throw new Exception\InvalidPackageStateException('Package "' . $packageKey . '" is not registered.', 1436201329);
         }