diff --git a/administrator/components/com_joomlaupdate/controller.php b/administrator/components/com_joomlaupdate/controller.php index c2a94b12bd3aa..cd7eb690cc4ff 100644 --- a/administrator/components/com_joomlaupdate/controller.php +++ b/administrator/components/com_joomlaupdate/controller.php @@ -43,7 +43,7 @@ public function display($cachable = false, $urlparams = false) $view->ftp = &$ftp; // Get the model for the view. - $model = $this->getModel($vName); + $model = $this->getModel('default'); // Perform update source preference check and refresh update information. $model->applyUpdateSite(); diff --git a/administrator/components/com_joomlaupdate/controllers/update.php b/administrator/components/com_joomlaupdate/controllers/update.php index 7da3e52e5ad61..4182588e6e24a 100644 --- a/administrator/components/com_joomlaupdate/controllers/update.php +++ b/administrator/components/com_joomlaupdate/controllers/update.php @@ -121,7 +121,7 @@ public function cleanup() $model->cleanUp(); - $url = 'index.php?option=com_joomlaupdate&layout=complete'; + $url = 'index.php?option=com_joomlaupdate&view=default&layout=complete'; $this->setRedirect($url); JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE', JVERSION), JLog::INFO, 'Update'); } diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default.php index 900544959799c..0656db2d43c11 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default.php @@ -43,8 +43,9 @@ $updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT'); } +JHtml::_('jquery.framework'); JHtml::_('formbehavior.chosen', 'select'); - +JHtml::script('com_joomlaupdate/default.js', false, true, false); ?>
diff --git a/administrator/components/com_joomlaupdate/views/default/view.html.php b/administrator/components/com_joomlaupdate/views/default/view.html.php index aaa8a955ea606..103f38458cac4 100644 --- a/administrator/components/com_joomlaupdate/views/default/view.html.php +++ b/administrator/components/com_joomlaupdate/views/default/view.html.php @@ -54,17 +54,6 @@ public function display($tpl = null) JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); - // Load mooTools. - JHtml::_('behavior.framework', true); - - // Include jQuery. - JHtml::_('jquery.framework'); - - // Load our Javascript. - $document = JFactory::getDocument(); - $document->addScript('../media/com_joomlaupdate/default.js'); - JHtml::_('stylesheet', 'media/mediamanager.css', array(), true); - if (!is_null($this->updateInfo['object'])) { // Show the message if a update is found. diff --git a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php b/administrator/components/com_joomlaupdate/views/update/tmpl/default.php index 074c8fa18c42f..7079ed5229b04 100644 --- a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php +++ b/administrator/components/com_joomlaupdate/views/update/tmpl/default.php @@ -9,19 +9,39 @@ defined('_JEXEC') or die; +// Include jQuery. +JHtml::_('jquery.framework'); + +// Load the scripts +JHtml::script('com_joomlaupdate/json2.js', false, true, false); +JHtml::script('com_joomlaupdate/encryption.js', false, true, false); +JHtml::script('com_joomlaupdate/update.js', false, true, false); + +$password = JFactory::getApplication()->getUserState('com_joomlaupdate.password', null); +$filesize = JFactory::getApplication()->getUserState('com_joomlaupdate.filesize', null); +$ajaxUrl = JUri::base() . 'components/com_joomlaupdate/restore.php'; +$returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise'; + +JFactory::getDocument()->addScriptDeclaration( + " + var joomlaupdate_password = '$password'; + var joomlaupdate_totalsize = '$filesize'; + var joomlaupdate_ajax_url = '$ajaxUrl'; + var joomlaupdate_return_url = '$returnUrl'; + + jQuery(document).ready(function(){ + window.pingExtract(); + }); + " +); ?>

-
-
- 'progress', 'id' => 'progress'), true - ); ?> +
+
diff --git a/administrator/components/com_joomlaupdate/views/update/view.html.php b/administrator/components/com_joomlaupdate/views/update/view.html.php index 014be8739430e..4d99ad5432402 100644 --- a/administrator/components/com_joomlaupdate/views/update/view.html.php +++ b/administrator/components/com_joomlaupdate/views/update/view.html.php @@ -25,11 +25,6 @@ class JoomlaupdateViewUpdate extends JViewLegacy */ public function display($tpl=null) { - $password = JFactory::getApplication()->getUserState('com_joomlaupdate.password', null); - $filesize = JFactory::getApplication()->getUserState('com_joomlaupdate.filesize', null); - $ajaxUrl = JUri::base() . 'components/com_joomlaupdate/restore.php'; - $returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise'; - // Set the toolbar information. JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'arrow-up-2 install'); JToolBarHelper::divider(); @@ -43,30 +38,6 @@ public function display($tpl=null) JToolbarHelper::preferences('com_joomlaupdate'); } - // Load mooTools. - JHtml::_('behavior.framework', true); - - // Include jQuery. - JHtml::_('jquery.framework'); - - $updateScript = <<addScript('../media/com_joomlaupdate/json2.js'); - $document->addScript('../media/com_joomlaupdate/encryption.js'); - $document->addScript('../media/com_joomlaupdate/update.js'); - JHtml::_('jquery.framework'); - JHtml::_('script', 'system/progressbar.js', true, true); - JHtml::_('stylesheet', 'media/mediamanager.css', array(), true); - $document->addScriptDeclaration($updateScript); - // Render the view. parent::display($tpl); } diff --git a/media/com_joomlaupdate/default.js b/media/com_joomlaupdate/js/default.js similarity index 89% rename from media/com_joomlaupdate/default.js rename to media/com_joomlaupdate/js/default.js index a4e39e0bf51bb..caf896f70165c 100644 --- a/media/com_joomlaupdate/default.js +++ b/media/com_joomlaupdate/js/default.js @@ -20,8 +20,5 @@ jQuery(function ($) { $('button.submit').on('click', function() { $('div.download_message').show(); - var $el = $('div.joomlaupdate_spinner'); - $el.attr('spinner', {class: 'joomlaupdate_spinner'}); - $el.get(0).spin(); }) }); diff --git a/media/com_joomlaupdate/encryption.js b/media/com_joomlaupdate/js/encryption.js similarity index 100% rename from media/com_joomlaupdate/encryption.js rename to media/com_joomlaupdate/js/encryption.js diff --git a/media/com_joomlaupdate/json2.js b/media/com_joomlaupdate/js/json2.js similarity index 100% rename from media/com_joomlaupdate/json2.js rename to media/com_joomlaupdate/js/json2.js diff --git a/media/com_joomlaupdate/js/update.js b/media/com_joomlaupdate/js/update.js new file mode 100644 index 0000000000000..196a05b90330a --- /dev/null +++ b/media/com_joomlaupdate/js/update.js @@ -0,0 +1,393 @@ +/** + * @package AkeebaCMSUpdate + * @copyright Copyright (c)2010-2014 Nicholas K. Dionysopoulos + * @license GNU General Public License version 3, or later + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +var stat_total = 0; +var stat_files = 0; +var stat_inbytes = 0; +var stat_outbytes = 0; + +/** + * An extremely simple error handler, dumping error messages to screen + * + * @param error The error message string + */ +function error_callback(error) +{ + alert("ERROR:\n"+error); +} + +/** + * Performs an encrypted AJAX request and returns the parsed JSON output. + * The window.ajax_url is used as the AJAX proxy URL. + * If there is no errorCallback, the window.error_callback is used. + * + * @param object data An object with the query data, e.g. a serialized form + * @param function successCallback A function accepting a single object parameter, called on success + * @param function errorCallback A function accepting a single string parameter, called on failure + */ +doEncryptedAjax = function(data, successCallback, errorCallback) +{ + var json = JSON.stringify(data); + if( joomlaupdate_password.length > 0 ) + { + json = AesCtr.encrypt( json, joomlaupdate_password, 128 ); + } + var post_data = { + 'json': json + }; + + var structure = + { + type: "POST", + url: joomlaupdate_ajax_url, + cache: false, + data: post_data, + timeout: 600000, + + success: function(msg, responseXML) + { + // Initialize + var junk = null; + var message = ""; + + // Get rid of junk before the data + var valid_pos = msg.indexOf('###'); + + if( valid_pos == -1 ) + { + // Valid data not found in the response + msg = 'Invalid AJAX data:\n' + msg; + + if (errorCallback == null) + { + if(error_callback != null) + { + error_callback(msg); + } + } + else + { + errorCallback(msg); + } + + return; + } + else if( valid_pos != 0 ) + { + // Data is prefixed with junk + junk = msg.substr(0, valid_pos); + message = msg.substr(valid_pos); + } + else + { + message = msg; + } + + message = message.substr(3); // Remove triple hash in the beginning + + // Get of rid of junk after the data + var valid_pos = message.lastIndexOf('###'); + + message = message.substr(0, valid_pos); // Remove triple hash in the end + + // Decrypt if required + var data = null; + if( joomlaupdate_password.length > 0 ) + { + try + { + var data = JSON.parse(message); + } + catch(err) + { + message = AesCtr.decrypt(message, joomlaupdate_password, 128); + } + } + + try + { + if (empty(data)) + { + data = JSON.parse(message); + } + } + catch(err) + { + var msg = err.message + "\n
\n
\n" + message + "\n
"; + + if (errorCallback == null) + { + if (error_callback != null) + { + error_callback(msg); + } + } + else + { + errorCallback(msg); + } + + return; + } + + // Call the callback function + successCallback(data); + }, + + error: function(req) + { + var message = 'AJAX Loading Error: ' + req.statusText; + + if(errorCallback == null) + { + if (error_callback != null) + { + error_callback(message); + } + } + else + { + errorCallback(message); + } + } + }; + + jQuery.ajax( structure ); +}; + +/** + * Pings the update script (making sure its executable) + */ +pingExtract = function() +{ + // Reset variables + this.stat_files = 0; + this.stat_inbytes = 0; + this.stat_outbytes = 0; + + // Do AJAX post + var post = {task : 'ping'}; + + this.doEncryptedAjax(post, + function(data) { + startExtract(data); + }); +}; + +startExtract = function() +{ + console.log("started"); + // Reset variables + this.stat_files = 0; + this.stat_inbytes = 0; + this.stat_outbytes = 0; + + var post = { task : 'startRestore' }; + + this.doEncryptedAjax(post, function(data){ + stepExtract(data); + }); +}; + +stepExtract = function(data) +{ + if(data.status == false) + { + // handle failure + error_callback(data.message); + + return; + } + + if( !empty(data.Warnings) ) + { + // @todo Handle warnings + /** + $.each(data.Warnings, function(i, item){ + $('#warnings').append( + $(document.createElement('div')) + .html(item) + ); + $('#warningsBox').show('fast'); + }); + /**/ + } + + if (!empty(data.factory)) + { + extract_factory = data.factory; + } + + if(data.done) + { + finalizeUpdate(); + } + else + { + // Add data to variables + stat_inbytes += data.bytesIn; + stat_percent = (stat_inbytes * 100) / joomlaupdate_totalsize; + + // Update GUI + stat_inbytes += data.bytesIn; + stat_outbytes += data.bytesOut; + stat_files += data.files; + + if (stat_percent < 100) + { + jQuery('#progress-bar').css('width', stat_percent + '%').attr('aria-valuenow', stat_percent); + } + else if (stat_percent > 100) + { + stat_percent = 100; + jQuery('#progress-bar').css('width', stat_percent + '%').attr('aria-valuenow', stat_percent); + } + else + { + jQuery('#progress-bar').removeClass('bar-success'); + } + + jQuery('#extpercent').text(stat_percent.toFixed(1)); + jQuery('#extbytesin').text(stat_inbytes); + jQuery('#extbytesout').text(stat_outbytes); + jQuery('#extfiles').text(data.lastfile); + + // Do AJAX post + post = { + task: 'stepRestore', + factory: data.factory + }; + doEncryptedAjax(post, function(data){ + stepExtract(data); + }); + } +}; + +finalizeUpdate = function () +{ + // Do AJAX post + var post = { task : 'finalizeRestore', factory: window.factory }; + doEncryptedAjax(post, function(data){ + window.location = joomlaupdate_return_url; + }); +}; + + +/** + * Is a variable empty? + * + * Part of php.js + * + * @see http://phpjs.org/ + * + * @param mixed mixed_var The variable + * + * @returns boolean True if empty + */ +function empty (mixed_var) +{ + var key; + + if (mixed_var === "" || + mixed_var === 0 || + mixed_var === "0" || + mixed_var === null || + mixed_var === false || + typeof mixed_var === 'undefined' + ){ + return true; + } + + if (typeof mixed_var == 'object') + { + for (key in mixed_var) + { + return false; + } + + return true; + } + + return false; +} + +/** + * Is the variable an array? + * + * Part of php.js + * + * @see http://phpjs.org/ + * + * @param mixed mixed_var The variable + * + * @returns boolean True if it is an array or an object + */ +function is_array (mixed_var) +{ + var key = ''; + var getFuncName = function (fn) { + var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn); + + if (!name) { + return '(Anonymous)'; + } + + return name[1]; + }; + + if (!mixed_var) + { + return false; + } + + // BEGIN REDUNDANT + this.php_js = this.php_js || {}; + this.php_js.ini = this.php_js.ini || {}; + // END REDUNDANT + + if (typeof mixed_var === 'object') + { + if (this.php_js.ini['phpjs.objectsAsArrays'] && // Strict checking for being a JavaScript array (only check this way if call ini_set('phpjs.objectsAsArrays', 0) to disallow objects as arrays) + ( + (this.php_js.ini['phpjs.objectsAsArrays'].local_value.toLowerCase && + this.php_js.ini['phpjs.objectsAsArrays'].local_value.toLowerCase() === 'off') || + parseInt(this.php_js.ini['phpjs.objectsAsArrays'].local_value, 10) === 0) + ) { + return mixed_var.hasOwnProperty('length') && // Not non-enumerable because of being on parent class + !mixed_var.propertyIsEnumerable('length') && // Since is own property, if not enumerable, it must be a built-in function + getFuncName(mixed_var.constructor) !== 'String'; // exclude String() + } + + if (mixed_var.hasOwnProperty) + { + for (key in mixed_var) { + // Checks whether the object has the specified property + // if not, we figure it's not an object in the sense of a php-associative-array. + if (false === mixed_var.hasOwnProperty(key)) { + return false; + } + } + } + + // Read discussion at: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_is_array/ + return true; + } + + return false; +} diff --git a/media/com_joomlaupdate/update.js b/media/com_joomlaupdate/update.js deleted file mode 100644 index 2a0318309ef5e..0000000000000 --- a/media/com_joomlaupdate/update.js +++ /dev/null @@ -1,201 +0,0 @@ -var joomlaupdate_error_callback = dummy_error_handler; -var joomlaupdate_stat_inbytes = 0; -var joomlaupdate_stat_outbytes = 0; -var joomlaupdate_stat_files = 0; -var joomlaupdate_stat_percent = 0; -var joomlaupdate_factory = null; -var joomlaupdate_progress_bar = null; - -/** - * An extremely simple error handler, dumping error messages to screen - * - * @param error The error message string - */ -function dummy_error_handler(error) -{ - alert("ERROR:\n"+error); -} - -/** - * Performs an AJAX request and returns the parsed JSON output. - * - * @param data An object with the query data, e.g. a serialized form - * @param successCallback A function accepting a single object parameter, called on success - * @param errorCallback A function accepting a single string parameter, called on failure - */ -function doAjax(data, successCallback, errorCallback) -{ - var json = JSON.stringify(data); - if ( joomlaupdate_password.length > 0 ) - { - json = AesCtr.encrypt( json, joomlaupdate_password, 128 ); - } - var post_data = 'json='+encodeURIComponent(json); - - - var structure = - { - onSuccess: function(msg, responseXML) - { - // Initialize - var junk = null; - var message = ""; - - // Get rid of junk before the data - var valid_pos = msg.indexOf('###'); - if ( valid_pos == -1 ) { - // Valid data not found in the response - msg = 'Invalid AJAX data:\n' + msg; - if (joomlaupdate_error_callback != null) - { - joomlaupdate_error_callback(msg); - } - return; - } else if( valid_pos != 0 ) { - // Data is prefixed with junk - junk = msg.substr(0, valid_pos); - message = msg.substr(valid_pos); - } - else - { - message = msg; - } - message = message.substr(3); // Remove triple hash in the beginning - - // Get of rid of junk after the data - var valid_pos = message.lastIndexOf('###'); - message = message.substr(0, valid_pos); // Remove triple hash in the end - // Decrypt if required - if ( joomlaupdate_password.length > 0 ) - { - try { - var data = JSON.parse(message); - } catch(err) { - message = AesCtr.decrypt(message, joomlaupdate_password, 128); - } - } - - try { - var data = JSON.parse(message); - } catch(err) { - var msg = err.message + "\n
\n
\n" + message + "\n
"; - if (joomlaupdate_error_callback != null) - { - joomlaupdate_error_callback(msg); - } - return; - } - - // Call the callback function - successCallback(data); - }, - onFailure: function(req) { - var message = 'AJAX Loading Error: '+req.statusText; - if (joomlaupdate_error_callback != null) - { - joomlaupdate_error_callback(message); - } - } - }; - - var ajax_object = null; - structure.url = joomlaupdate_ajax_url; - ajax_object = new Request(structure); - ajax_object.send(post_data); -} - -/** - * Pings the update script (making sure its executable!!) - * @return - */ -function pingUpdate() -{ - // Reset variables - joomlaupdate_stat_files = 0; - joomlaupdate_stat_inbytes = 0; - joomlaupdate_stat_outbytes = 0; - - // Do AJAX post - var post = {task : 'ping'}; - doAjax(post, function(data){ - startUpdate(data); - }); -} - -/** - * Starts the update - * @return - */ -function startUpdate() -{ - // Reset variables - joomlaupdate_stat_files = 0; - joomlaupdate_stat_inbytes = 0; - joomlaupdate_stat_outbytes = 0; - - var post = { task : 'startRestore' }; - doAjax(post, function(data){ - processUpdateStep(data); - }); -} - -/** - * Steps through the update - * @param data - * @return - */ -function processUpdateStep(data) -{ - if (data.status == false) - { - if (joomlaupdate_error_callback != null) - { - joomlaupdate_error_callback(data.message); - } - } - else - { - if (data.done) - { - joomlaupdate_factory = data.factory; - window.location = joomlaupdate_return_url; - } - else - { - // Add data to variables - joomlaupdate_stat_inbytes += data.bytesIn; - joomlaupdate_stat_percent = (joomlaupdate_stat_inbytes * 100) / joomlaupdate_totalsize; - - // Create progress bar once - if (joomlaupdate_progress_bar == null) - { - joomlaupdate_progress_bar = new Fx.ProgressBar(document.getElementById('progress')); - } - joomlaupdate_progress_bar.set(joomlaupdate_stat_percent); - joomlaupdate_stat_outbytes += data.bytesOut; - joomlaupdate_stat_files += data.files; - - // Display data - document.getElementById('extpercent').innerHTML = new Number(joomlaupdate_stat_percent).formatPercentage(1); - document.getElementById('extbytesin').innerHTML = new Number(joomlaupdate_stat_inbytes).format(); - document.getElementById('extbytesout').innerHTML = new Number(joomlaupdate_stat_outbytes).format(); - document.getElementById('extfiles').innerHTML = new Number(joomlaupdate_stat_files).format(); - - // Do AJAX post - post = { - task: 'stepRestore', - factory: data.factory - }; - doAjax(post, function(data){ - processUpdateStep(data); - }); - } - } -} - -jQuery(function($) { - pingUpdate(); - var $el = $('div.joomlaupdate_spinner'); - $el.attr('spinner', {class: 'joomlaupdate_spinner'}); - $el.get(0).spin(); -});