diff --git a/admin-dev/themes/default/css/modules.css b/admin-dev/themes/default/css/modules.css index 37ae9a315..589db9aad 100644 --- a/admin-dev/themes/default/css/modules.css +++ b/admin-dev/themes/default/css/modules.css @@ -235,7 +235,10 @@ form#product, form#access_form{ background-color:#ebedf4; border:1px solid #cc #moduleContainer .row-actions-module span { padding-right:5px;} #moduleContainer .row-actions-module span a { font-size:12px;} #moduleContainer .button.uninstalled, -#moduleContainer .button.installed { float:right; clear:both; margin-top:15px; font-size:12px;} +#moduleContainer .button.installed { float:right; display: inline-block; margin-top:15px; font-size:12px;} +#moduleContainer .button.updated { margin-top:15px; display: inline-block; font-size:12px;} +#list-action-button{width:175px} +#list-action-button li{margin-left:10px;display: inline;float: left;} /*FOOTER*/ diff --git a/admin-dev/themes/default/template/controllers/modules/list.tpl b/admin-dev/themes/default/template/controllers/modules/list.tpl index bb5b8b7b1..aca0c3502 100644 --- a/admin-dev/themes/default/template/controllers/modules/list.tpl +++ b/admin-dev/themes/default/template/controllers/modules/list.tpl @@ -56,7 +56,9 @@ {/if}
{l s='Version'} :
-
{$module->version} {if isset($module->version_addons)}({l s='Update'} {$module->version_addons} {l s='available on PrestaShop Addons'}){/if}
| +
{$module->version} + {if isset($module->version_addons)}({l s='Update'} {$module->version_addons} {l s='available on PrestaShop Addons'}){/if} +
|
{l s='Category'} :
@@ -70,7 +72,15 @@ - id) && $module->id gt 0 && !empty($module->options.uninstall_onclick)}onclick="{$module->options.uninstall_onclick}"{/if} href="{if isset($module->id) && $module->id gt 0}{$module->options.uninstall_url}{else}{$module->options.install_url}{/if}" class="button installed">{if isset($module->id) && $module->id gt 0}{l s='Uninstall'}{else}{l s='Install'}{/if} + + + {/foreach} diff --git a/classes/Module.php b/classes/Module.php index dda744540..5fa4f0d2c 100644 --- a/classes/Module.php +++ b/classes/Module.php @@ -307,7 +307,8 @@ abstract class ModuleCore ); // Need Upgrade will check and load upgrade file to the moduleCache upgrade case detail - return Module::isInstalled($module_name) && Module::needUpgrade($module_name, $module_version); + $ret = Module::isInstalled($module_name) && Module::needUpgrade($module_name, $module_version); + return $ret; } /** @@ -350,17 +351,29 @@ abstract class ModuleCore } $upgrade['number_upgrade_left'] = count($upgrade['upgrade_file_left']); - // Update module version in DB with the last succeed upgrade if ($upgrade['upgraded_to']) - Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'module` m - SET m.version = \''.bqSQL($upgrade['upgraded_to']).'\' - WHERE m.name = \''.bqSQL($this->name).'\''); + Module::upgradeModuleVersion($this->name, $upgrade['upgraded_to']); $this->setUpgradeMessage($upgrade); return $upgrade; } + /** + * Upgrade the registered version to a new one + * + * @static + * @param $name + * @param $version + * @return bool + */ + public static function upgradeModuleVersion($name, $version) + { + return Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'module` m + SET m.version = \''.bqSQL($version).'\' + WHERE m.name = \''.bqSQL($name).'\''); + } + /** * Check if a module need to be upgraded. * This method modify the module_cache adding an upgrade list file @@ -377,6 +390,7 @@ abstract class ModuleCore WHERE m.`name` = \''.bqSQL($module_name).'\''); self::$modules_cache[$module_name]['upgrade']['upgraded_from'] = $registered_version; + Tools::alignVersionNumber($module_version, $registered_version); // Check the version of the module with the registered one and look if any upgrade file exist return version_compare($module_version, $registered_version, '>') && Module::loadUpgradeVersionList($module_name, $module_version, $registered_version); @@ -388,6 +402,7 @@ abstract class ModuleCore * * @static * @param $module_name + * @param $module_version * @param $registered_version * @return bool to know directly if any files have been found */ @@ -402,10 +417,12 @@ abstract class ModuleCore { // Read each file name foreach ($files as $file) - if (!in_array($file, array('.', '..', '.svn'))) + if (!in_array($file, array('.', '..', '.svn', 'index.php'))) { $tab = explode('-', $file); $file_version = basename($tab[1], '.php'); + Tools::alignVersionNumber($file_version, $module_version); + Tools::alignVersionNumber($file_version, $registered_version); // Compare version, if minor than actual, we need to upgrade the module if (count($tab) == 2 && (version_compare($file_version, $module_version, '<=') && @@ -417,7 +434,14 @@ abstract class ModuleCore 'upgrade_function' => 'upgrade_module_'.str_replace('.', '_', $file_version)); } } - } + } + + // No files upgrade, then upgrade succeed + if (count($list) == 0) + { + self::$modules_cache[$module_name]['upgrade']['success'] = true; + Module::upgradeModuleVersion($module_name, $module_version); + } // Set the list to module cache self::$modules_cache[$module_name]['upgrade']['upgrade_file_left'] = $list; @@ -425,6 +449,19 @@ abstract class ModuleCore return (bool)count($list); } + /** + * Return the status of the upgraded module + * + * @static + * @param $module_name + * @return bool + */ + public static function getUpgradeStatus($module_name) + { + return (isset(self::$modules_cache[$module_name]) && + self::$modules_cache[$module_name]['upgrade']['success']); + } + /** * Delete module from datable * diff --git a/classes/Tools.php b/classes/Tools.php index baa084cd5..7241d530b 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -2191,6 +2191,36 @@ FileETag INode MTime Size $filtered_files[] = $dir.'/'.$file; return $filtered_files; } + + /** + * Align 2 version with the same number of sub version + * version_compare will work better for its comparison :) + * (Means: '1.8' to '1.9.3' will change '1.8' to '1.8.0') + * @static + * @param $v1 + * @param $v2 + */ + public static function alignVersionNumber(&$v1, &$v2) + { + $len1 = count(explode('.', trim($v1, '.'))); + $len2 = count(explode('.', trim($v2, '.'))); + $len = 0; + $str = ''; + + if ($len1 > $len2) + { + $len = $len1 - $len2; + $str = &$v2; + } + else if ($len2 > $len1) + { + $len = $len2 - $len1; + $str = &$v1; + } + + for ($len; $len > 0; $len--) + $str .= '.0'; + } } /** @@ -2217,4 +2247,4 @@ function cmpPriceDesc($a, $b) elseif ((float)($a['price_tmp']) > (float)($b['price_tmp'])) return (-1); return (0); -} +} \ No newline at end of file diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php index a575e0527..5cdfa3d0e 100644 --- a/classes/controller/AdminController.php +++ b/classes/controller/AdminController.php @@ -290,6 +290,7 @@ class AdminControllerCore extends Controller 26 => $this->l('Cover selection saved'), 27 => $this->l('Image shop association modified'), 28 => $this->l('Zone affected to the selection successfully'), + 29 => $this->l('Upgrade succeed') ); if (!$this->identifier) $this->identifier = 'id_'.$this->table; if (!$this->_defaultOrderBy) $this->_defaultOrderBy = $this->identifier; diff --git a/controllers/admin/AdminModulesController.php b/controllers/admin/AdminModulesController.php index e61819063..22c58cee9 100644 --- a/controllers/admin/AdminModulesController.php +++ b/controllers/admin/AdminModulesController.php @@ -35,6 +35,7 @@ class AdminModulesControllerCore extends AdminController 'install' => 'install', 'uninstall' => 'uninstall', 'configure' => 'getContent', + 'update' => 'update', 'delete' => 'delete' ); @@ -585,6 +586,9 @@ class AdminModulesControllerCore extends AdminController if ($modules) foreach ($modules as $name) { + if ($key == 'update') + Tools::deleteDirectory('../modules/'.$name.'/'); + // If Addons module, download and unzip it before installing it if (!is_dir('../modules/'.$name.'/')) { @@ -624,6 +628,8 @@ class AdminModulesControllerCore extends AdminController $this->errors[] = Tools::displayError('This module is already installed:').' '.$module->name; elseif ($key == 'uninstall' && !Module::isInstalled($module->name)) $this->errors[] = Tools::displayError('This module is already uninstalled:').' '.$module->name; + else if ($key == 'update' && !Module::isInstalled($module->name)) + $this->errors[] = Tools::displayError('This module need to be installed to be updated:').' '.$module->name; else { // If we install a module, force temporary global context for multishop @@ -643,12 +649,16 @@ class AdminModulesControllerCore extends AdminController if (Tools::getValue('controller') != '') $_POST['tab'] = Tools::safeOutput(Tools::getValue('controller')); + $echo = ''; + if ($key != 'update') + { // We check if method of module exists - if (!method_exists($module, $method)) - throw new PrestaShopException('Method of module can\'t be found'); - - // Get the return value of current method - $echo = $module->{$method}(); + if (!method_exists($module, $method)) + throw new PrestaShopException('Method of module can\'t be found'); + + // Get the return value of current method + $echo = $module->{$method}(); + } // If the method called is "configure" (getContent method), we show the html code of configure page if ($key == 'configure' && Module::isInstalled($module->name)) @@ -970,6 +980,7 @@ class AdminModulesControllerCore extends AdminController { // Upgrade Module process, init check if a module could be upgraded if (Module::initUpgradeModule($module->name, $module->version)) + { if ($object = new $module->name()) { $object->runUpgradeModule(); @@ -977,7 +988,20 @@ class AdminModulesControllerCore extends AdminController $module_errors[] = array('name' => $module->name, 'message' => $errors_module_list); else if ((count($conf_module_list = $object->getConfirmations()))) $module_success[] = array('name' => $module->name, 'message' => $conf_module_list); + unset($object); } + } + // Module can't be upgraded if not file exist but can change the database version... + // User has to be prevented + else if (Module::getUpgradeStatus($module->name)) + { + $object = new $module->name(); + $module_success[] = array('name' => $module->name, 'message' => array( + 0 => $this->l('Current version: ').$object->version, + 1 => $this->l('No files upgrade applied (none exist)')) + ); + unset($object); + } // Make modules stats $this->makeModulesStats($module); @@ -1010,6 +1034,7 @@ class AdminModulesControllerCore extends AdminController $modules[$km]->optionsHtml = $this->displayModuleOptions($module); $modules[$km]->categoryName = (isset($this->list_modules_categories[$module->tab]['name']) ? $this->list_modules_categories[$module->tab]['name'] : $this->list_modules_categories['others']['name']); $modules[$km]->options['install_url'] = self::$currentIndex.'&install='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name); + $modules[$km]->options['update_url'] = self::$currentIndex.'&update='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name); $modules[$km]->options['uninstall_url'] = self::$currentIndex.'&uninstall='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name); $modules[$km]->options['uninstall_onclick'] = ((!method_exists($module, 'onclickOption')) ? ((empty($module->confirmUninstall)) ? '' : 'return confirm(\''.addslashes($module->confirmUninstall).'\');') : $module->onclickOption('uninstall', $modules[$km]->options['uninstall_url'])); if (Tools::getValue('module_name') == $module->name && (int)Tools::getValue('conf') > 0)