[BUGFIX] Do not turn storages automatically offline 98/49798/7
authorSascha Egerer <sascha@sascha-egerer.de>
Fri, 2 Sep 2016 17:53:00 +0000 (19:53 +0200)
committerSascha Egerer <sascha@sascha-egerer.de>
Tue, 20 Sep 2016 06:29:24 +0000 (08:29 +0200)
Storages should not be taken offline automatically.
Currently the storage turns offline if a configuration error is
detected.
But depending on the driver a configuration error can be a temporary
problem that just exists for seconds (like local filemount is
not available).

A storage should only be turned offline if you are in the backend
context
and the initialization fails.

Resolves: #75184
Releases: master, 7.6
Change-Id: Iddb18305f96df1a116a5d209bae41a73f5bb0ad2
Reviewed-on: https://review.typo3.org/49798
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frans Saris <franssaris@gmail.com>
Tested-by: Frans Saris <franssaris@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Sascha Egerer <sascha@sascha-egerer.de>
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index 3509901..8797b5e 100644 (file)
@@ -16,7 +16,7 @@ namespace TYPO3\CMS\Core\Resource;
 
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
-use TYPO3\CMS\Core\Registry;
+use TYPO3\CMS\Core\Log\LogManager;
 use TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException;
 use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
 use TYPO3\CMS\Core\Resource\Index\Indexer;
@@ -141,7 +141,7 @@ class ResourceStorage implements ResourceStorageInterface
      *
      * @var bool
      */
-    protected $isOnline = null;
+    protected $isOnline = false;
 
     /**
      * @var bool
@@ -161,6 +161,11 @@ class ResourceStorage implements ResourceStorageInterface
     const PROCESSING_FOLDER_LEVELS = 2;
 
     /**
+     * @var \TYPO3\CMS\Core\Log\Logger
+     */
+    protected $logger;
+
+    /**
      * Constructor for a storage object.
      *
      * @param Driver\DriverInterface $driver
@@ -168,6 +173,9 @@ class ResourceStorage implements ResourceStorageInterface
      */
     public function __construct(Driver\DriverInterface $driver, array $storageRecord)
     {
+        $logManager = GeneralUtility::makeInstance(LogManager::class);
+        $this->logger = $logManager->getLogger(__CLASS__);
+
         $this->storageRecord = $storageRecord;
         $this->configuration = ResourceFactory::getInstance()->convertFlexFormDataToConfigurationArray($storageRecord['configuration']);
         $this->capabilities =
@@ -175,6 +183,13 @@ class ResourceStorage implements ResourceStorageInterface
             ($this->storageRecord['is_public'] ? self::CAPABILITY_PUBLIC : 0) |
             ($this->storageRecord['is_writable'] ? self::CAPABILITY_WRITABLE : 0);
 
+        if ($this->getUid() === 0) {
+            // Legacy storage is always online
+            $this->isOnline = true;
+        } else {
+            $this->isOnline = (bool)$this->storageRecord['is_online'];
+        }
+
         $this->driver = $driver;
         $this->driver->setStorageUid($storageRecord['uid']);
         $this->driver->mergeConfigurationCapabilities($this->capabilities);
@@ -182,8 +197,16 @@ class ResourceStorage implements ResourceStorageInterface
             $this->driver->processConfiguration();
         } catch (Exception\InvalidConfigurationException $e) {
             // configuration error
-            // mark this storage as permanently unusable
-            $this->markAsPermanentlyOffline();
+            // mark this storage as offline
+            $this->isOnline = false;
+
+            if (TYPO3_REQUESTTYPE === TYPO3_REQUESTTYPE_BE) {
+                $this->logger->error(
+                    'The storage "%s" has been turned offline due to a configuration error.',
+                    [$this->storageRecord['name']]
+                );
+                $this->markAsPermanentlyOffline();
+            }
         }
         $this->driver->initialize();
         $this->capabilities = $this->driver->getCapabilities();
@@ -350,29 +373,8 @@ class ResourceStorage implements ResourceStorageInterface
      */
     public function isOnline()
     {
-        if ($this->isOnline === null) {
-            if ($this->getUid() === 0) {
-                $this->isOnline = true;
-            }
-            // the storage is not marked as online for a longer time
-            if ($this->storageRecord['is_online'] == 0) {
-                $this->isOnline = false;
-            }
-            if ($this->isOnline !== false) {
-                // all files are ALWAYS available in the frontend
-                if (TYPO3_MODE === 'FE') {
-                    $this->isOnline = true;
-                } else {
-                    // check if the storage is disabled temporary for now
-                    $registryObject = GeneralUtility::makeInstance(Registry::class);
-                    $offlineUntil = $registryObject->get('core', 'sys_file_storage-' . $this->getUid() . '-offline-until');
-                    if ($offlineUntil && $offlineUntil > time()) {
-                        $this->isOnline = false;
-                    } else {
-                        $this->isOnline = true;
-                    }
-                }
-            }
+        if (TYPO3_REQUESTTYPE !== TYPO3_REQUESTTYPE_BE) {
+            return true;
         }
         return $this->isOnline;
     }
@@ -412,22 +414,6 @@ class ResourceStorage implements ResourceStorageInterface
         $this->isOnline = false;
     }
 
-    /**
-     * Marks this storage as offline for the next 5 minutes.
-     *
-     * Non-permanent: This typically happens for remote storages
-     * that are "flaky" and not available all the time.
-     *
-     * @return void
-     */
-    public function markAsTemporaryOffline()
-    {
-        $registryObject = GeneralUtility::makeInstance(Registry::class);
-        $registryObject->set('core', 'sys_file_storage-' . $this->getUid() . '-offline-until', time() + 60 * 5);
-        $this->storageRecord['is_online'] = 0;
-        $this->isOnline = false;
-    }
-
     /*********************************
      * User Permissions / File Mounts
      ********************************/