2b0a454bea3ab33b1cd8482265e364c8ff952421
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Resources / Public / JavaScript / Modules / CoreUpdate.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Install/CoreUpdate
16 */
17 define([
18 'jquery',
19 'TYPO3/CMS/Install/Router',
20 'TYPO3/CMS/Install/FlashMessage',
21 'TYPO3/CMS/Install/Severity',
22 'TYPO3/CMS/Backend/Notification'
23 ], function($, Router, FlashMessage, Severity, Notification) {
24 'use strict';
25
26 return {
27 /**
28 * The action queue defines what actions are called in which order
29 */
30 actionQueue: {
31 coreUpdateIsUpdateAvailable: {
32 loadingMessage: 'Checking for possible regular or security update',
33 finishMessage: undefined,
34 nextActionName: undefined
35 },
36 coreUpdateCheckPreConditions: {
37 loadingMessage: 'Checking if update is possible',
38 finishMessage: 'System can be updated',
39 nextActionName: 'coreUpdateDownload'
40 },
41 coreUpdateDownload: {
42 loadingMessage: 'Downloading new core',
43 finishMessage: undefined,
44 nextActionName: 'coreUpdateVerifyChecksum'
45 },
46 coreUpdateVerifyChecksum: {
47 loadingMessage: 'Verifying checksum of downloaded core',
48 finishMessage: undefined,
49 nextActionName: 'coreUpdateUnpack'
50 },
51 coreUpdateUnpack: {
52 loadingMessage: 'Unpacking core',
53 finishMessage: undefined,
54 nextActionName: 'coreUpdateMove'
55 },
56 coreUpdateMove: {
57 loadingMessage: 'Moving core',
58 finishMessage: undefined,
59 nextActionName: 'coreUpdateClearAllCache'
60 },
61 clearAllCache: {
62 loadingMessage: 'Clearing caches',
63 finishMessage: 'Caches cleared',
64 nextActionName: 'coreUpdateActivate'
65 },
66 coreUpdateActivate: {
67 loadingMessage: 'Activating core',
68 finishMessage: 'Core updated - please reload your browser',
69 nextActionName: undefined
70 }
71 },
72
73 selectorModalBody: '.t3js-modal-body',
74 selectorOutput: '.t3js-coreUpdate-output',
75 selectorTemplate: '.t3js-coreUpdate-buttonTemplate',
76
77 /**
78 * Clone of a DOM object acts as button template
79 */
80 buttonTemplate: null,
81
82 /**
83 * Fetching the templates out of the DOM
84 */
85 initialize: function(currentModal) {
86 var self = this;
87 this.currentModal = currentModal;
88 this.getData();
89
90 var buttonTemplateSection = $(this.selectorTemplate);
91 this.buttonTemplate = buttonTemplateSection.children().clone();
92
93 $(document).on('click', '.t3js-coreUpdate-init', function(e) {
94 e.preventDefault();
95 var action = $(e.target).data('action');
96 $(document).find(self.selectorOutput).empty();
97 self[action]();
98 });
99 },
100
101 getData: function() {
102 var modalContent = this.currentModal.find(this.selectorModalBody);
103 $.ajax({
104 url: Router.getUrl('coreUpdateGetData'),
105 cache: false,
106 success: function(data) {
107 if (data.success === true) {
108 modalContent.empty().append(data.html);
109 } else {
110 Notification.error('Something went wrong');
111 }
112 },
113 error: function(xhr) {
114 Router.handleAjaxError(xhr, modalContent);
115 }
116 });
117 },
118
119 /**
120 * Public method checkForUpdate
121 */
122 checkForUpdate: function() {
123 this.callAction('coreUpdateIsUpdateAvailable');
124 },
125
126 /**
127 * Public method updateDevelopment
128 */
129 updateDevelopment: function() {
130 this.update('development');
131 },
132
133 updateRegular: function() {
134 this.update('regular');
135 },
136
137 /**
138 * Execute core update.
139 *
140 * @param type Either 'development' or 'regular'
141 */
142 update: function(type) {
143 if (type !== "development") {
144 type = 'regular';
145 }
146 this.callAction('coreUpdateCheckPreConditions', type);
147 },
148
149 /**
150 * Generic method to call actions from the queue
151 *
152 * @param actionName Name of the action to be called
153 * @param type Update type (optional)
154 */
155 callAction: function(actionName, type) {
156 var self = this;
157 var data = {
158 install: {
159 action: actionName
160 }
161 };
162 if (type !== undefined) {
163 data.install["type"] = type;
164 }
165 this.addLoadingMessage(this.actionQueue[actionName].loadingMessage);
166 $.ajax({
167 url: Router.getUrl(),
168 data: data,
169 cache: false,
170 success: function(result) {
171 var canContinue = self.handleResult(result, self.actionQueue[actionName].finishMessage);
172 if (canContinue === true && (self.actionQueue[actionName].nextActionName !== undefined)) {
173 self.callAction(self.actionQueue[actionName].nextActionName, type);
174 }
175 },
176 error: function(result) {
177 self.handleResult(result);
178 }
179 });
180 },
181
182 /**
183 * Handle ajax result of core update step.
184 *
185 * @param data
186 * @param successMessage Optional success message
187 */
188 handleResult: function(data, successMessage) {
189 var canContinue = false;
190 var modalContent = this.currentModal.find(this.selectorModalBody);
191 this.removeLoadingMessage();
192 if (data.success === true) {
193 canContinue = true;
194 if (data.status && typeof(data.status) === 'object') {
195 this.showStatusMessages(data.status);
196 }
197 if (data.action && typeof(data.action) === 'object') {
198 this.showActionButton(data.action);
199 }
200 if (successMessage) {
201 this.addMessage(Severity.ok, successMessage);
202 }
203 } else {
204 Router.handleAjaxError(xhr, modalContent);
205 }
206 return canContinue;
207 },
208
209 /**
210 * Add a loading message with some text.
211 *
212 * @param messageTitle
213 */
214 addLoadingMessage: function(messageTitle) {
215 var domMessage = FlashMessage.render(Severity.loading, messageTitle);
216 $(this.selectorOutput).append(domMessage);
217 },
218
219 /**
220 * Remove an enabled loading message
221 */
222 removeLoadingMessage: function() {
223 $(this.selectorOutput).find('.alert-loading').remove();
224 },
225
226 /**
227 * Show a list of status messages
228 *
229 * @param messages
230 */
231 showStatusMessages: function(messages) {
232 var self = this;
233 $.each(messages, function(index, element) {
234 var title = false;
235 var message = false;
236 var severity = element.severity;
237 if (element.title) {
238 title = element.title;
239 }
240 if (element.message) {
241 message = element.message;
242 }
243 self.addMessage(severity, title, message);
244 });
245 },
246
247 /**
248 * Show an action button
249 *
250 * @param button
251 */
252 showActionButton: function(button) {
253 var title = false;
254 var action = false;
255 if (button.title) {
256 title = button.title;
257 }
258 if (button.action) {
259 action = button.action;
260 }
261 var domButton = this.buttonTemplate;
262 if (action) {
263 domButton.find('button').data('action', action);
264 }
265 if (title) {
266 domButton.find('button').text(title);
267 }
268 $(this.selectorOutput).append(domButton);
269 },
270
271 /**
272 * Show a status message
273 *
274 * @param severity
275 * @param title
276 * @param message
277 */
278 addMessage: function(severity, title, message) {
279 var domMessage = FlashMessage.render(severity, title, message);
280 $(this.selectorOutput).append(domMessage);
281 }
282 };
283 });