From 4b622db1babee0142cd14f81bbda79b1a71f335d Mon Sep 17 00:00:00 2001
From: Marc Wessels <mwessels@me.com>
Date: Wed, 29 Mar 2017 11:07:33 +0200
Subject: [PATCH] [TASK] Install tool dump autoload information with ajax

The 'Dump Autoload Information' buttons used a controller
action, improve usability by switching to an ajax call.

Resolves: #80543
Releases: master
Change-Id: I27e5cd65e611108692680d09e7710f0e1d1b3133
Reviewed-on: https://review.typo3.org/52230
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
---
 .../Controller/Action/Ajax/DumpAutoload.php   |  73 +++++++++
 .../Action/Tool/ImportantActions.php          |  22 ---
 .../Classes/Controller/AjaxController.php     |   1 +
 .../Tool/ImportantActions/DumpAutoload.html   |   6 +-
 .../Resources/Public/JavaScript/Install.js    | 153 +++++++++++++++++-
 5 files changed, 225 insertions(+), 30 deletions(-)
 create mode 100644 typo3/sysext/install/Classes/Controller/Action/Ajax/DumpAutoload.php

diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/DumpAutoload.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/DumpAutoload.php
new file mode 100644
index 000000000000..e43ee7d7595a
--- /dev/null
+++ b/typo3/sysext/install/Classes/Controller/Action/Ajax/DumpAutoload.php
@@ -0,0 +1,73 @@
+<?php
+namespace TYPO3\CMS\Install\Controller\Action\Ajax;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\ClassLoadingInformation;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Install\Status\NoticeStatus;
+use TYPO3\CMS\Install\Status\OkStatus;
+use TYPO3\CMS\Install\View\JsonView;
+
+/**
+ * Ajax wrapper for dumping autoload.
+ */
+class DumpAutoload extends AbstractAjaxAction
+{
+    /**
+     * @var \TYPO3\CMS\Install\View\JsonView
+     */
+    protected $view;
+
+    /**
+     * @param JsonView $view
+     */
+    public function __construct(JsonView $view = null)
+    {
+        $this->view = $view ?: GeneralUtility::makeInstance(JsonView::class);
+    }
+
+    /**
+     * Initialize the handle action, sets up fluid stuff and assigns default variables.
+     * @ToDo Refactor View Initialization for all Ajax Controllers
+     */
+    protected function initializeHandle()
+    {
+        // empty on purpose because AbstractAjaxAction still overwrites $this->view with StandaloneView
+    }
+
+    /**
+     * Executes the action
+     *
+     * @return array Rendered content
+     */
+    protected function executeAction()
+    {
+        if (Bootstrap::usesComposerClassLoading()) {
+            $message = GeneralUtility::makeInstance(NoticeStatus::class);
+            $message->setTitle('Skipped generating additional class loading information in composer mode.');
+        } else {
+            ClassLoadingInformation::dumpClassLoadingInformation();
+            $message = GeneralUtility::makeInstance(OkStatus::class);
+            $message->setTitle('Successfully dumped class loading information for extensions.');
+        }
+
+        $this->view->assignMultiple([
+            'success' => true,
+            'status' => [ $message ],
+        ]);
+        return $this->view->render();
+    }
+}
diff --git a/typo3/sysext/install/Classes/Controller/Action/Tool/ImportantActions.php b/typo3/sysext/install/Classes/Controller/Action/Tool/ImportantActions.php
index f52010ae1c2c..7831cb599b97 100644
--- a/typo3/sysext/install/Classes/Controller/Action/Tool/ImportantActions.php
+++ b/typo3/sysext/install/Classes/Controller/Action/Tool/ImportantActions.php
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Install\Controller\Action\Tool;
  */
 
 use TYPO3\CMS\Core\Core\Bootstrap;
-use TYPO3\CMS\Core\Core\ClassLoadingInformation;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
 use TYPO3\CMS\Core\Database\Schema\SqlReader;
@@ -42,9 +41,6 @@ class ImportantActions extends Action\AbstractAction
         if (isset($this->postValues['set']['createAdministrator'])) {
             $actionMessages[] = $this->createAdministrator();
         }
-        if (isset($this->postValues['set']['dumpAutoload'])) {
-            $actionMessages[] = $this->dumpAutoload();
-        }
 
         // Database analyzer handling
         if (isset($this->postValues['set']['databaseAnalyzerExecute'])
@@ -153,24 +149,6 @@ class ImportantActions extends Action\AbstractAction
         return $message;
     }
 
-    /**
-     * Dumps Extension Autoload Information
-     *
-     * @return \TYPO3\CMS\Install\Status\StatusInterface
-     */
-    protected function dumpAutoload(): \TYPO3\CMS\Install\Status\StatusInterface
-    {
-        if (Bootstrap::usesComposerClassLoading()) {
-            $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\NoticeStatus::class);
-            $message->setTitle('Skipped generating additional class loading information in composer mode.');
-        } else {
-            ClassLoadingInformation::dumpClassLoadingInformation();
-            $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
-            $message->setTitle('Successfully dumped class loading information for extensions.');
-        }
-        return $message;
-    }
-
     /**
      * Create administrator user
      *
diff --git a/typo3/sysext/install/Classes/Controller/AjaxController.php b/typo3/sysext/install/Classes/Controller/AjaxController.php
index cdd426dd3120..aa0696fced01 100644
--- a/typo3/sysext/install/Classes/Controller/AjaxController.php
+++ b/typo3/sysext/install/Classes/Controller/AjaxController.php
@@ -34,6 +34,7 @@ class AjaxController extends AbstractController
         'uninstallExtension',
         'clearCache',
         'clearAllCache',
+        'dumpAutoload',
         'coreUpdateUpdateVersionMatrix',
         'coreUpdateIsUpdateAvailable',
         'coreUpdateCheckPreConditions',
diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/DumpAutoload.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/DumpAutoload.html
index d7a9225c24ab..c715afb4d3be 100644
--- a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/DumpAutoload.html
+++ b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/DumpAutoload.html
@@ -5,5 +5,7 @@
 
 <form method="post">
 	<f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" />
-	<f:render partial="Action/Common/SubmitButton" arguments="{name:'dumpAutoload', text:'Create autoload information for extensions'}"/>
-</form>
+	<div class="t3js-dumpAutoload">
+		<f:render partial="Action/Common/SubmitButton" arguments="{name:'dumpAutoload', text:'Create autoload information for extensions'}"/>
+	</div>
+</form>
\ No newline at end of file
diff --git a/typo3/sysext/install/Resources/Public/JavaScript/Install.js b/typo3/sysext/install/Resources/Public/JavaScript/Install.js
index 27b96b81ef92..05ebe24a9445 100644
--- a/typo3/sysext/install/Resources/Public/JavaScript/Install.js
+++ b/typo3/sysext/install/Resources/Public/JavaScript/Install.js
@@ -72,6 +72,137 @@ TYPO3.Install.FlashMessage = {
 	}
 };
 
+TYPO3.Install.DumpAutoload = {
+	/**
+	 * output DOM Container
+	 */
+	outputContainer: {},
+
+	/**
+	 * Clone of the DOM object that contains the submit button
+	 */
+	submitButton: {},
+
+	/**
+	 * Default output messages
+	 */
+	outputMessages: {
+		dumpAutoload: {
+			fatalTitle: 'Something went wrong',
+			fatalMessage: '',
+			loadingTitle: 'Loading...',
+			loadingMessage: ''
+		}
+	},
+
+	/**
+	 * Fetching the templates out of the DOM
+	 *
+	 * @param dumpAutoloadContainer DOM element id with all needed HTML in it
+	 * @return boolean DOM container could be found and initialization finished
+	 */
+	initialize: function(dumpAutoloadContainer) {
+		this.outputContainer[dumpAutoloadContainer] = $('.t3js-' + dumpAutoloadContainer);
+
+		if (this.outputContainer[dumpAutoloadContainer]) {
+			// submit button: save and delete
+			if(!this.submitButton[dumpAutoloadContainer]) {
+				var submitButton = this.outputContainer[dumpAutoloadContainer].find('button[type="submit"]');
+				this.submitButton[dumpAutoloadContainer] = submitButton.clone();
+			}
+
+			// clear all messages from the run before
+			this.outputContainer[dumpAutoloadContainer].find('.typo3-message:visible ').remove();
+
+			return true;
+		}
+		return false;
+	},
+
+	/**
+	 * Ajax call to dump Autoload Information
+	 * @param actionName
+	 */
+	dumpAutoload: function(actionName) {
+		var self = this;
+		var url = location.href + '&install[controller]=ajax&install[action]=' + actionName;
+		var isInitialized = self.initialize(actionName);
+		if (isInitialized) {
+			self.addMessage(
+				TYPO3.Install.Severity.loading,
+				self.outputMessages[actionName].loadingTitle,
+				self.outputMessages[actionName].loadingMessage,
+				actionName
+			);
+			$.ajax({
+				url: url,
+				cache: false,
+				success: function(data) {
+					if (data.success === true && Array.isArray(data.status)) {
+						if (data.status.length > 0) {
+							self.outputContainer[actionName].find('.alert-loading').hide();
+							data.status.forEach((function (element) {
+								//noinspection JSUnresolvedVariable
+								self.addMessage(
+									element.severity,
+									element.title,
+									element.message,
+									actionName
+								);
+							}));
+						} else {
+							self.outputContainer[actionName].find('.alert-loading').hide();
+							self.addMessage(
+								TYPO3.Install.Severity.ok,
+								self.outputMessages[actionName].successTitle,
+								self.outputMessages[actionName].successMessage,
+								actionName
+							);
+						}
+					} else if (data === 'unauthorized') {
+						location.reload();
+					}
+				},
+				error: function() {
+					self.outputContainer[actionName].find('.alert-loading').hide();
+					self.addMessage(
+						TYPO3.Install.Severity.error,
+						self.outputMessages[actionName].fatalTitle,
+						self.outputMessages[actionName].fatalMessage,
+						actionName
+					);
+				}
+			});
+		}
+	},
+
+	/**
+	 * Move the submit button to the end of the box
+	 *
+	 * @param dumpAutoloadContainer DOM container name
+	 */
+	moveSubmitButtonFurtherDown: function(dumpAutoloadContainer) {
+		// first remove the currently visible button
+		this.outputContainer[dumpAutoloadContainer].find('button[type="submit"]').remove();
+		// then append the cloned template to the end
+		this.outputContainer[dumpAutoloadContainer].append(this.submitButton[dumpAutoloadContainer]);
+	},
+
+	/**
+	 * Show a status message
+	 *
+	 * @param severity
+	 * @param title
+	 * @param message
+	 * @param dumpAutoloadContainer DOM container name
+	 */
+	addMessage: function(severity, title, message, dumpAutoloadContainer) {
+		var domMessage = TYPO3.Install.FlashMessage.render(severity, title, message);
+		this.outputContainer[dumpAutoloadContainer].append(domMessage);
+		this.moveSubmitButtonFurtherDown(dumpAutoloadContainer);
+	}
+};
+
 TYPO3.Install.Cache = {
 	/**
 	 * output DOM Container
@@ -90,7 +221,7 @@ TYPO3.Install.Cache = {
 		clearAllCache: {
 			fatalTitle: 'Something went wrong',
 			fatalMessage: '',
-			loadingTitle: 'Loading…',
+			loadingTitle: 'Loading...',
 			loadingMessage: ''
 		}
 	},
@@ -102,7 +233,6 @@ TYPO3.Install.Cache = {
 	* @return boolean DOM container could be found and initialization finished
 	*/
 	initialize: function(cacheCheckContainer) {
-		var success = false;
 		this.outputContainer[cacheCheckContainer] = $('#' + cacheCheckContainer);
 
 		if (this.outputContainer[cacheCheckContainer]) {
@@ -115,9 +245,9 @@ TYPO3.Install.Cache = {
 			// clear all messages from the run before
 			this.outputContainer[cacheCheckContainer].find('.typo3-message:visible ').remove();
 
-			success = true;
+			return true;
 		}
-		return success;
+		return false;
 	},
 
 	/**
@@ -391,7 +521,7 @@ TYPO3.Install.TcaIntegrityChecker = {
 		tcaMigrationsCheck: {
 			fatalTitle: 'Something went wrong',
 			fatalMessage: 'Use "Check for broken extensions!"',
-			loadingTitle: 'Loading…',
+			loadingTitle: 'Loading...',
 			loadingMessage: '',
 			successTitle: 'No TCA migrations need to be applied',
 			successMessage: 'Your TCA looks good.',
@@ -401,7 +531,7 @@ TYPO3.Install.TcaIntegrityChecker = {
 		tcaExtTablesCheck: {
 			fatalTitle: 'Something went wrong',
 			fatalMessage: 'Use "Check for broken extensions!"',
-			loadingTitle: 'Loading…',
+			loadingTitle: 'Loading...',
 			loadingMessage: '',
 			successTitle: 'No TCA changes in ext_tables.php files. Good job!',
 			successMessage: '',
@@ -916,6 +1046,17 @@ $(function () {
 			return false;
 		}));
 	}
+
+	// Handle dumpAutoload
+	var $clearAllCacheSection = $('.t3js-dumpAutoload');
+	if ($clearAllCacheSection) {
+		$clearAllCacheSection.on('click', 'button', (function(e) {
+			TYPO3.Install.DumpAutoload.dumpAutoload('dumpAutoload');
+			e.preventDefault();
+			return false;
+		}));
+	}
+
 	// Handle TCA ext_tables check
 	var $tcaExtTablesCheckSection = $('#tcaExtTablesCheck');
 	if ($tcaExtTablesCheckSection) {
-- 
GitLab