[FEATURE] Add a clear all cache button to install tool 33/22633/2
authorChristian Kuhn <lolli@schwarzbu.ch>
Sat, 27 Jul 2013 21:09:58 +0000 (23:09 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Sun, 28 Jul 2013 12:00:33 +0000 (14:00 +0200)
This implements a clear all cache functionality to the install tool.

The implementation is different from the existing backend solution
so that it at least partly clears caches even if some broken
extension is loaded that would kill the operation.

To achieve that, first a low level removal of typo3temp/Cache is
performed, then all table names starting with "cf_" are truncated
with direct database calls. After that ext_localconf and ext_tables
of extension are loaded (this may fatal) and the final cache
configuration is then feeded to the cache manager that executes
the usual flushCaches() call.

Change-Id: Ibd717b0d34bd5b8737a73acebf4632fed38c4d8c
Resolves: #50495
Releases: 6.2
Reviewed-on: https://review.typo3.org/22633
Reviewed-by: Susanne Moog
Tested-by: Susanne Moog
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
typo3/sysext/install/Classes/Controller/Action/Tool/ImportantActions.php
typo3/sysext/install/Classes/Service/ClearCacheService.php [new file with mode: 0644]
typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/ClearAllCache.html [new file with mode: 0644]
typo3/sysext/install/Resources/Private/Templates/Action/Tool/ImportantActions.html

index 198ba86..2ce7f4c 100644 (file)
@@ -54,6 +54,9 @@ class ImportantActions extends Action\AbstractAction implements Action\ActionInt
                if (isset($this->postValues['set']['createAdministrator'])) {
                        $actionMessages[] = $this->createAdministrator();
                }
+               if (isset($this->postValues['set']['clearAllCache'])) {
+                       $actionMessages[] = $this->clearAllCache();
+               }
 
                // Database analyzer handling
                if (isset($this->postValues['set']['databaseAnalyzerExecute'])
@@ -141,6 +144,20 @@ class ImportantActions extends Action\AbstractAction implements Action\ActionInt
        }
 
        /**
+        * Clear all caches
+        *
+        * @return \TYPO3\CMS\Install\Status\StatusInterface
+        */
+       protected function clearAllCache() {
+               /** @var \TYPO3\CMS\Install\Service\ClearCacheService $clearCacheService */
+               $clearCacheService = $this->objectManager->get('TYPO3\\CMS\\Install\\Service\\ClearCacheService');
+               $clearCacheService->clearAll();
+               $message = $this->objectManager->get('TYPO3\\CMS\\Install\\Status\\OkStatus');
+               $message->setTitle('Successfully cleared all caches');
+               return $message;
+       }
+
+       /**
         * Set new encryption key
         *
         * @return void
diff --git a/typo3/sysext/install/Classes/Service/ClearCacheService.php b/typo3/sysext/install/Classes/Service/ClearCacheService.php
new file mode 100644 (file)
index 0000000..04da499
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+namespace TYPO3\CMS\Install\Service;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Christian Kuhn <lolli@schwarzbu.ch>
+ *  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!
+ ***************************************************************/
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Basic service to clear caches within the install tool.
+ * This is NOT an API class, it is for internal use in the install tool only.
+ */
+class ClearCacheService {
+
+       /**
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManager
+        * @inject
+        */
+       protected $objectManager = NULL;
+
+       /**
+        * This clear cache implementation follows a pretty brutal approach.
+        * Goal is to reliably get rid of cache entries, even if some broken
+        * extension is loaded that would kill the backend 'clear cache' action.
+        *
+        * Therefor this method "knows" implementation details of the cache
+        * framework and uses them to clear all file based cache (typo3temp/Cache)
+        * and database caches (tables prefixed with cf_) manually.
+        *
+        * After that ext_tables and ext_localconf of extensions are loaded, those
+        * may register additional caches in the caching framework with different
+        * backend, and will then clear them with the usual flush() method.
+        *
+        * @return void
+        */
+       public function clearAll() {
+               // Delete typo3temp/Cache
+               GeneralUtility::rmdir(PATH_site . 'typo3temp/Cache', TRUE);
+
+               // Get all table names starting with 'cf_' and truncate them
+               $database = $this->getDatabaseInstance();
+               $tables = $database->admin_get_tables();
+               foreach ($tables as $table) {
+                       $tableName = $table['Name'];
+                       if (substr($tableName, 0, 3) === 'cf_') {
+                               $database->exec_TRUNCATEquery($tableName);
+                       }
+               }
+
+               // From this point on, the code may fatal, if some broken extension is loaded.
+
+               // Use bootstrap to load all ext_localconf and ext_tables
+               \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
+                       ->loadTypo3LoadedExtAndExtLocalconf(FALSE)
+                       ->applyAdditionalConfigurationSettings()
+                       ->initializeTypo3DbGlobal()
+                       ->loadExtensionTables(FALSE);
+
+               // $GLOBALS['typo3CacheManager'] is already instantiated in the install tool
+               // with some hacked settings to disable caching of extbase and fluid.
+               // We want a "fresh" object here to operate on a different cache setup.
+               // cacheManager implements SingletonInterface, so the only way to get a "fresh"
+               // instance is by circumventing makeInstance and/or the objectManager and
+               // using new directly!
+               $cacheManager = new \TYPO3\CMS\Core\Cache\CacheManager();
+               $cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
+               // Cache manager needs cache factory. cache factory injects itself to manager in __construct()
+               new \TYPO3\CMS\Core\Cache\CacheFactory('production', $cacheManager);
+
+               $cacheManager->flushCaches();
+       }
+
+       /**
+        * Get a database instance.
+        *
+        * @TODO: This method is a copy from AbstractAction. Review them and extract to service
+        * @return \TYPO3\CMS\Core\Database\DatabaseConnection
+        */
+       protected function getDatabaseInstance() {
+               static $database;
+               if (!is_object($database)) {
+                       /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+                       $database = $this->objectManager->get('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
+                       $database->setDatabaseUsername($GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
+                       $database->setDatabasePassword($GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
+                       $database->setDatabaseHost($GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
+                       $database->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
+                       $database->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
+                       $database->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
+                       $database->connectDB();
+               }
+               return $database;
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/ClearAllCache.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/ClearAllCache.html
new file mode 100644 (file)
index 0000000..6da3816
--- /dev/null
@@ -0,0 +1,13 @@
+<h4>Clear all cache</h4>
+<p>
+       This clear all cache function works similar to the cache clearing in the backend but follows a
+       more straight ahead approach and the according backend hooks are not executed.
+</p>
+<p>
+       This method can throw a fatal error if some broken extension is loaded. If you get a white page
+       or a PHP error message, check your system with the broken extension test below.
+</p>
+<form method="post">
+       <f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" />
+       <f:render partial="Action/Common/SubmitButton" arguments="{name:'clearAllCache', text:'Clear all cache'}"/>
+</form>
\ No newline at end of file
index c7e574d..51a4a41 100644 (file)
@@ -22,6 +22,9 @@
        </f:if>
        <hr />
 
+       <f:render partial="Action/Tool/ImportantActions/ClearAllCache" arguments="{_all}"/>
+       <hr />
+
        <f:render partial="Action/Tool/ImportantActions/NewInstallToolPassword" arguments="{_all}"/>
        <hr />