[FEATURE] Add "processed files" cleanup tool to Install Tool 56/39656/10
authorMarkus Klein <markus.klein@typo3.org>
Fri, 22 May 2015 00:27:39 +0000 (02:27 +0200)
committerFrank Nägler <typo3@naegler.net>
Fri, 29 May 2015 07:15:02 +0000 (09:15 +0200)
Resolves: #67071
Releases: master, 6.2
Change-Id: I1320833f0f7cfd852ca8ba458fa9367cb3b16ea0
Reviewed-on: http://review.typo3.org/39656
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Frank Nägler <typo3@naegler.net>
Tested-by: Frank Nägler <typo3@naegler.net>
typo3/sysext/core/Classes/Resource/ProcessedFileRepository.php
typo3/sysext/core/Documentation/Changelog/master/Feature-67071-ProcessedFilesCleanupToolAddedInInstallTool.rst [new file with mode: 0644]
typo3/sysext/install/Classes/Controller/Action/Tool/CleanUp.php
typo3/sysext/install/Resources/Private/Partials/Action/Tool/CleanUp/ProcessedFiles.html [new file with mode: 0644]
typo3/sysext/install/Resources/Private/Templates/Action/Tool/CleanUp.html

index 8123113..6a77390 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Resource;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Log\LogManager;
 use TYPO3\CMS\Core\Utility;
 
 /**
@@ -32,7 +33,7 @@ class ProcessedFileRepository extends AbstractRepository {
         *
         * @var string
         */
-       protected $objectType = \TYPO3\CMS\Core\Resource\ProcessedFile::class;
+       protected $objectType = ProcessedFile::class;
 
        /**
         * Main File object storage table. Note that this repository also works on
@@ -56,7 +57,7 @@ class ProcessedFileRepository extends AbstractRepository {
         * Creates this object.
         */
        public function __construct() {
-               $this->resourceFactory = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class);
+               $this->resourceFactory = Utility\GeneralUtility::makeInstance(ResourceFactory::class);
                $this->databaseConnection = $GLOBALS['TYPO3_DB'];
        }
 
@@ -197,6 +198,40 @@ class ProcessedFileRepository extends AbstractRepository {
                return $itemList;
        }
 
+       /**
+        * Removes all processed files and also deletes the associated physical files
+        *
+        * @param int|NULL $storageUid If not NULL, only the processed files of the given storage are removed
+        * @return int Number of failed deletions
+        */
+       public function removeAll($storageUid = NULL) {
+               $res = $this->databaseConnection->exec_SELECTquery('*', $this->table, 'identifier <> \'\'');
+               $logger = $this->getLogger();
+               $errorCount = 0;
+               while ($row = $this->databaseConnection->sql_fetch_assoc($res)) {
+                       if ($storageUid && (int)$storageUid !== (int)$row['storage']) {
+                               continue;
+                       }
+                       try {
+                               $file = $this->createDomainObject($row);
+                               $file->getStorage()->setEvaluatePermissions(FALSE);
+                               $file->delete(TRUE);
+                       } catch (\Exception $e) {
+                               $logger->error(
+                                       'Failed to delete file "' . $row['identifier'] . '" in storage uid ' . $row['storage'] . '.',
+                                       array(
+                                               'exception' => $e
+                                       )
+                               );
+                               ++$errorCount;
+                       }
+               }
+
+               $this->databaseConnection->exec_TRUNCATEquery($this->table);
+
+               return $errorCount;
+       }
+
 
        /**
         * Removes all array keys which cannot be persisted
@@ -209,4 +244,11 @@ class ProcessedFileRepository extends AbstractRepository {
                return array_intersect_key($data, $this->databaseConnection->admin_get_fields($this->table));
        }
 
-}
\ No newline at end of file
+       /**
+        * @return \TYPO3\CMS\Core\Log\Logger
+        */
+       protected function getLogger() {
+               return Utility\GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
+       }
+
+}
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-67071-ProcessedFilesCleanupToolAddedInInstallTool.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-67071-ProcessedFilesCleanupToolAddedInInstallTool.rst
new file mode 100644 (file)
index 0000000..5fed659
--- /dev/null
@@ -0,0 +1,10 @@
+====================================================================
+Feature: #67071 - Processed files cleanup tool added in Install Tool
+====================================================================
+
+Description
+===========
+
+The Install Tool now provides a new tool to remove processed files (e.g. image thumbnails) from FAL in its "Clean up" section.
+
+The tool is useful if you change graphic-related settings or after updating GraphicsMagick/ImageMagick on the server and you want all files to be regenerated.
index 83959f6..45426ae 100644 (file)
@@ -14,8 +14,13 @@ namespace TYPO3\CMS\Install\Controller\Action\Tool;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
+use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Install\Controller\Action;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Install\Status\ErrorStatus;
+use TYPO3\CMS\Install\Status\InfoStatus;
+use TYPO3\CMS\Install\Status\OkStatus;
 
 /**
  * Clean up page
@@ -41,6 +46,9 @@ class CleanUp extends Action\AbstractAction {
                if (isset($this->postValues['set']['resetBackendUserUc'])) {
                        $this->actionMessages[] = $this->resetBackendUserUc();
                }
+               if (isset($this->postValues['set']['clearProcessedFiles'])) {
+                       $this->actionMessages[] = $this->clearProcessedFiles();
+               }
 
                $this->view->assign('cleanableTables', $this->getCleanableTableList());
 
@@ -126,13 +134,13 @@ class CleanUp extends Action\AbstractAction {
                        }
                }
                if (count($clearedTables)) {
-                       /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
-                       $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
+                       /** @var OkStatus $message */
+                       $message = $this->objectManager->get(OkStatus::class);
                        $message->setTitle('Cleared tables');
                        $message->setMessage('List of cleared tables: ' . implode(', ', $clearedTables));
                } else {
-                       /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
-                       $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\InfoStatus::class);
+                       /** @var InfoStatus $message */
+                       $message = $this->objectManager->get(InfoStatus::class);
                        $message->setTitle('No tables selected to clear');
                }
                return $message;
@@ -146,8 +154,8 @@ class CleanUp extends Action\AbstractAction {
        protected function resetBackendUserUc() {
                $database = $this->getDatabaseConnection();
                $database->exec_UPDATEquery('be_users', '', array('uc' => ''));
-               /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
-               $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
+               /** @var OkStatus $message */
+               $message = $this->objectManager->get(OkStatus::class);
                $message->setTitle('Reset all backend users preferences');
                return $message;
        }
@@ -188,7 +196,7 @@ class CleanUp extends Action\AbstractAction {
                                        $ok = FALSE;
                                        $fileCounter++;
                                        if ($condition) {
-                                               if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($condition)) {
+                                               if (MathUtility::canBeInterpretedAsInteger($condition)) {
                                                        if (filesize($absoluteFile) > $condition * 1024) {
                                                                $ok = TRUE;
                                                        }
@@ -228,7 +236,7 @@ class CleanUp extends Action\AbstractAction {
                $data['numberOfDeletedFiles'] = $deleteCounter;
 
                if ($deleteCounter > 0) {
-                       $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
+                       $message = $this->objectManager->get(OkStatus::class);
                        $message->setTitle('Deleted ' . $deleteCounter . ' files from typo3temp/' . $subDirectory . '/');
                        $this->actionMessages[] = $message;
                }
@@ -262,4 +270,30 @@ class CleanUp extends Action\AbstractAction {
                return $data;
        }
 
+       /**
+        * Clear processed files
+        *
+        * The sys_file_processedfile table is truncated and the physical files of local storages are deleted.
+        *
+        * @return \TYPO3\CMS\Install\Status\StatusInterface
+        */
+       protected function clearProcessedFiles() {
+               // make the DB available
+               $GLOBALS['TYPO3_DB'] = $this->getDatabaseConnection();
+
+               $repository = GeneralUtility::makeInstance(ProcessedFileRepository::class);
+               $failedDeletions = $repository->removeAll();
+               if ($failedDeletions) {
+                       /** @var ErrorStatus $message */
+                       $message = $this->objectManager->get(ErrorStatus::class);
+                       $message->setTitle('Failed to delete ' . $failedDeletions . ' processed files. See TYPO3 log (by default typo3temp/logs/typo3.log)');
+               } else {
+                       /** @var OkStatus $message */
+                       $message = $this->objectManager->get(OkStatus::class);
+                       $message->setTitle('Cleared processed files');
+               }
+
+               return $message;
+       }
+
 }
diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/CleanUp/ProcessedFiles.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/CleanUp/ProcessedFiles.html
new file mode 100644 (file)
index 0000000..079dd60
--- /dev/null
@@ -0,0 +1,17 @@
+<h4>Clear processed files</h4>
+
+<p>
+       The File Abstraction Layer stores a database record for every file it needs to process. (e.g. image thumbnails)
+       In case you modified some graphics settings (All Configuration [GFX]) and you need all processed files to get
+       regenerated, you can use this tool to remove the existing ones. The new processed files are created once they are
+       needed.
+</p>
+
+<form method="post">
+       <f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" />
+
+       <f:render
+               partial="Action/Common/SubmitButton"
+               arguments="{name:'clearProcessedFiles', text:'Clear processed files'}"
+       />
+</form>
index 364d3c7..e605130 100644 (file)
        <f:render partial="Action/Tool/CleanUp/Typo3TempFiles" arguments="{_all}" />
        <hr />
 
+       <f:render partial="Action/Tool/CleanUp/ProcessedFiles" arguments="{_all}" />
+       <hr />
+
        <f:render partial="Action/Tool/CleanUp/ClearTables" arguments="{_all}" />
        <hr />
 
        <f:render partial="Action/Tool/CleanUp/ResetBackendUserUc" arguments="{_all}" />
        <hr />
 
-</f:section>
\ No newline at end of file
+</f:section>