Initial commit

This commit is contained in:
2019-11-20 07:44:43 +01:00
commit 5bf49c4a81
41188 changed files with 5459177 additions and 0 deletions

12
web/modules/.htaccess Normal file
View File

@@ -0,0 +1,12 @@
<FilesMatch "\.tpl$">
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>

View File

@@ -0,0 +1,110 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class AbstractLoggerCore
{
public $level;
protected $level_value = array(
0 => 'DEBUG',
1 => 'INFO',
2 => 'WARNING',
3 => 'ERROR',
);
const DEBUG = 0;
const INFO = 1;
const WARNING = 2;
const ERROR = 3;
public function __construct($level = self::INFO)
{
if (array_key_exists((int)$level, $this->level_value))
$this->level = $level;
else
$this->level = self::INFO;
}
/**
* Log the message
*
* @param string message
* @param level
*/
abstract protected function logMessage($message, $level);
/**
* Check the level and log the message if needed
*
* @param string message
* @param level
*/
public function log($message, $level = self::DEBUG)
{
if ($level >= $this->level)
$this->logMessage($message, $level);
}
/**
* Log a debug message
*
* @param string message
*/
public function logDebug($message)
{
$this->log($message, self::DEBUG);
}
/**
* Log an info message
*
* @param string message
*/
public function logInfo($message)
{
$this->log($message, self::INFO);
}
/**
* Log a warning message
*
* @param string message
*/
public function logWarning($message)
{
$this->log($message, self::WARNING);
}
/**
* Log an error message
*
* @param string message
*/
public function logError($message)
{
$this->log($message, self::ERROR);
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

View File

@@ -0,0 +1,448 @@
<?php
/*
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @version Release: $Revision: 11834 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\Module\AutoUpgrade\AjaxResponse;
use PrestaShop\Module\AutoUpgrade\BackupFinder;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\UpgradePage;
use PrestaShop\Module\AutoUpgrade\UpgradeSelfCheck;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
require_once _PS_ROOT_DIR_ . '/modules/autoupgrade/vendor/autoload.php';
class AdminSelfUpgrade extends AdminController
{
public $multishop_context;
public $multishop_context_group = false;
public $_html = '';
// used for translations
public static $l_cache;
// retrocompatibility
public $noTabLink = array();
public $id = -1;
public $ajax = false;
public $standalone = true;
/**
* Initialized in initPath().
*/
public $autoupgradePath;
public $downloadPath;
public $backupPath;
public $latestPath;
public $tmpPath;
/**
* autoupgradeDir.
*
* @var string directory relative to admin dir
*/
public $autoupgradeDir = 'autoupgrade';
public $latestRootDir = '';
public $prodRootDir = '';
public $adminDir = '';
public $keepImages;
public $updateDefaultTheme;
public $changeToDefaultTheme;
public $keepMails;
public $manualMode;
public $deactivateCustomModule;
public static $classes14 = array('Cache', 'CacheFS', 'CarrierModule', 'Db', 'FrontController', 'Helper', 'ImportModule',
'MCached', 'Module', 'ModuleGraph', 'ModuleGraphEngine', 'ModuleGrid', 'ModuleGridEngine',
'MySQL', 'Order', 'OrderDetail', 'OrderDiscount', 'OrderHistory', 'OrderMessage', 'OrderReturn',
'OrderReturnState', 'OrderSlip', 'OrderState', 'PDF', 'RangePrice', 'RangeWeight', 'StockMvt',
'StockMvtReason', 'SubDomain', 'Shop', 'Tax', 'TaxRule', 'TaxRulesGroup', 'WebserviceKey', 'WebserviceRequest', '', );
public static $maxBackupFileSize = 15728640; // 15 Mo
public $_fieldsUpgradeOptions = array();
public $_fieldsBackupOptions = array();
/**
* @var UpgradeContainer
*/
private $upgradeContainer;
public function viewAccess($disable = false)
{
if ($this->ajax) {
return true;
} else {
// simple access : we'll allow only 46admin
global $cookie;
if ($cookie->profile == 1) {
return true;
}
}
return false;
}
public function __construct()
{
parent::__construct();
@set_time_limit(0);
@ini_set('max_execution_time', '0');
@ini_set('magic_quotes_runtime', '0');
@ini_set('magic_quotes_sybase', '0');
$this->init();
$this->db = Db::getInstance();
$this->bootstrap = true;
self::$currentIndex = $_SERVER['SCRIPT_NAME'] . (($controller = Tools14::getValue('controller')) ? '?controller=' . $controller : '');
if (defined('_PS_ADMIN_DIR_')) {
$file_tab = @filemtime($this->autoupgradePath . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php');
$file = @filemtime(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $this->autoupgradeDir . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php');
if ($file_tab < $file) {
@copy(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $this->autoupgradeDir . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php',
$this->autoupgradePath . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php');
}
}
if (!$this->ajax) {
Context::getContext()->smarty->assign('display_header_javascript', true);
}
}
/**
* function to set configuration fields display.
*/
private function _setFields()
{
$this->_fieldsBackupOptions = array(
'PS_AUTOUP_BACKUP' => array(
'title' => $this->trans('Back up my files and database', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool', 'defaultValue' => '1',
'type' => 'bool', 'desc' => $this->trans('Automatically back up your database and files in order to restore your shop if needed. This is experimental: you should still perform your own manual backup for safety.', array(), 'Modules.Autoupgrade.Admin'),
),
'PS_AUTOUP_KEEP_IMAGES' => array(
'title' => $this->trans('Back up my images', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool', 'defaultValue' => '1',
'type' => 'bool', 'desc' => $this->trans('To save time, you can decide not to back your images up. In any case, always make sure you did back them up manually.', array(), 'Modules.Autoupgrade.Admin'),
),
);
$this->_fieldsUpgradeOptions = array(
'PS_AUTOUP_PERFORMANCE' => array(
'title' => $this->trans('Server performance', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isInt', 'defaultValue' => '1',
'type' => 'select', 'desc' => $this->trans('Unless you are using a dedicated server, select "Low".', array(), 'Modules.Autoupgrade.Admin') . '<br />' .
$this->trans('A high value can cause the upgrade to fail if your server is not powerful enough to process the upgrade tasks in a short amount of time.', array(), 'Modules.Autoupgrade.Admin'),
'choices' => array(1 => $this->trans('Low (recommended)', array(), 'Modules.Autoupgrade.Admin'), 2 => $this->trans('Medium', array(), 'Modules.Autoupgrade.Admin'), 3 => $this->trans('High', array(), 'Modules.Autoupgrade.Admin')),
),
'PS_AUTOUP_CUSTOM_MOD_DESACT' => array(
'title' => $this->trans('Disable non-native modules', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool',
'type' => 'bool', 'desc' => $this->trans('As non-native modules can experience some compatibility issues, we recommend to disable them by default.', array(), 'Modules.Autoupgrade.Admin') . '<br />' .
$this->trans('Keeping them enabled might prevent you from loading the "Modules" page properly after the upgrade.', array(), 'Modules.Autoupgrade.Admin'),
),
'PS_AUTOUP_UPDATE_DEFAULT_THEME' => array(
'title' => $this->trans('Upgrade the default theme', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool', 'defaultValue' => '1',
'type' => 'bool', 'desc' => $this->trans('If you customized the default PrestaShop theme in its folder (folder name "classic" in 1.7), enabling this option will lose your modifications.', array(), 'Modules.Autoupgrade.Admin') . '<br />'
. $this->trans('If you are using your own theme, enabling this option will simply update the default theme files, and your own theme will be safe.', array(), 'Modules.Autoupgrade.Admin'),
),
'PS_AUTOUP_CHANGE_DEFAULT_THEME' => array(
'title' => $this->trans('Switch to the default theme', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool', 'defaultValue' => '0',
'type' => 'bool', 'desc' => $this->trans('This will change your theme: your shop will then use the default theme of the version of PrestaShop you are upgrading to.', array(), 'Modules.Autoupgrade.Admin'),
),
'PS_AUTOUP_KEEP_MAILS' => array(
'title' => $this->trans('Keep the customized email templates', array(), 'Modules.Autoupgrade.Admin'), 'cast' => 'intval', 'validation' => 'isBool',
'type' => 'bool', 'desc' => $this->trans('This will not upgrade the default PrestaShop e-mails.', array(), 'Modules.Autoupgrade.Admin') . '<br />'
. $this->trans('If you customized the default PrestaShop e-mail templates, enabling this option will keep your modifications.', array(), 'Modules.Autoupgrade.Admin'),
),
);
}
/**
* init to build informations we need.
*/
public function init()
{
if (!$this->ajax) {
parent::init();
}
// For later use, let's set up prodRootDir and adminDir
// This way it will be easier to upgrade a different path if needed
$this->prodRootDir = _PS_ROOT_DIR_;
$this->adminDir = realpath(_PS_ADMIN_DIR_);
$this->upgradeContainer = new UpgradeContainer($this->prodRootDir, $this->adminDir);
if (!defined('__PS_BASE_URI__')) {
// _PS_DIRECTORY_ replaces __PS_BASE_URI__ in 1.5
if (defined('_PS_DIRECTORY_')) {
define('__PS_BASE_URI__', _PS_DIRECTORY_);
} else {
define('__PS_BASE_URI__', realpath(dirname($_SERVER['SCRIPT_NAME'])) . '/../../');
}
}
// from $_POST or $_GET
$this->action = empty($_REQUEST['action']) ? null : $_REQUEST['action'];
$this->initPath();
$this->upgradeContainer->getState()->importFromArray(
empty($_REQUEST['params']) ? array() : $_REQUEST['params']
);
// If you have defined this somewhere, you know what you do
// load options from configuration if we're not in ajax mode
if (!$this->ajax) {
$upgrader = $this->upgradeContainer->getUpgrader();
$this->upgradeContainer->getCookie()->create(
$this->context->employee->id,
$this->context->language->iso_code
);
$this->upgradeContainer->getState()->initDefault(
$upgrader,
$this->upgradeContainer->getProperty(UpgradeContainer::PS_ROOT_PATH),
$this->upgradeContainer->getProperty(UpgradeContainer::PS_VERSION));
if (isset($_GET['refreshCurrentVersion'])) {
$upgradeConfiguration = $this->upgradeContainer->getUpgradeConfiguration();
// delete the potential xml files we saved in config/xml (from last release and from current)
$upgrader->clearXmlMd5File($this->upgradeContainer->getProperty(UpgradeContainer::PS_VERSION));
$upgrader->clearXmlMd5File($upgrader->version_num);
if ($upgradeConfiguration->get('channel') == 'private' && !$upgradeConfiguration->get('private_allow_major')) {
$upgrader->checkPSVersion(true, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(true, array('minor'));
}
Tools14::redirectAdmin(self::$currentIndex . '&conf=5&token=' . Tools14::getValue('token'));
}
// removing temporary files
$this->upgradeContainer->getFileConfigurationStorage()->cleanAll();
}
$this->keepImages = $this->upgradeContainer->getUpgradeConfiguration()->shouldBackupImages();
$this->updateDefaultTheme = $this->upgradeContainer->getUpgradeConfiguration()->get('PS_AUTOUP_UPDATE_DEFAULT_THEME');
$this->changeToDefaultTheme = $this->upgradeContainer->getUpgradeConfiguration()->get('PS_AUTOUP_CHANGE_DEFAULT_THEME');
$this->keepMails = $this->upgradeContainer->getUpgradeConfiguration()->get('PS_AUTOUP_KEEP_MAILS');
$this->deactivateCustomModule = $this->upgradeContainer->getUpgradeConfiguration()->get('PS_AUTOUP_CUSTOM_MOD_DESACT');
}
/**
* create some required directories if they does not exists.
*/
public function initPath()
{
$this->upgradeContainer->getWorkspace()->createFolders();
// set autoupgradePath, to be used in backupFiles and backupDb config values
$this->autoupgradePath = $this->adminDir . DIRECTORY_SEPARATOR . $this->autoupgradeDir;
$this->backupPath = $this->autoupgradePath . DIRECTORY_SEPARATOR . 'backup';
$this->downloadPath = $this->autoupgradePath . DIRECTORY_SEPARATOR . 'download';
$this->latestPath = $this->autoupgradePath . DIRECTORY_SEPARATOR . 'latest';
$this->tmpPath = $this->autoupgradePath . DIRECTORY_SEPARATOR . 'tmp';
$this->latestRootDir = $this->latestPath . DIRECTORY_SEPARATOR;
if (!file_exists($this->backupPath . DIRECTORY_SEPARATOR . 'index.php')) {
if (!copy(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'index.php', $this->backupPath . DIRECTORY_SEPARATOR . 'index.php')) {
$this->_errors[] = $this->trans('Unable to create file %s', array($this->backupPath . DIRECTORY_SEPARATOR . 'index.php'), 'Modules.Autoupgrade.Admin');
}
}
$tmp = "order deny,allow\ndeny from all";
if (!file_exists($this->backupPath . DIRECTORY_SEPARATOR . '.htaccess')) {
if (!file_put_contents($this->backupPath . DIRECTORY_SEPARATOR . '.htaccess', $tmp)) {
$this->_errors[] = $this->trans('Unable to create file %s', array($this->backupPath . DIRECTORY_SEPARATOR . '.htaccess'), 'Modules.Autoupgrade.Admin');
}
}
}
public function postProcess()
{
$this->_setFields();
if (Tools14::isSubmit('putUnderMaintenance')) {
foreach (Shop::getCompleteListOfShopsID() as $id_shop) {
Configuration::updateValue('PS_SHOP_ENABLE', 0, false, null, (int) $id_shop);
}
Configuration::updateGlobalValue('PS_SHOP_ENABLE', 0);
}
if (Tools14::isSubmit('ignorePsRequirements')) {
Configuration::updateValue('PS_AUTOUP_IGNORE_REQS', 1);
}
if (Tools14::isSubmit('customSubmitAutoUpgrade')) {
$config_keys = array_keys(array_merge($this->_fieldsUpgradeOptions, $this->_fieldsBackupOptions));
$config = array();
foreach ($config_keys as $key) {
if (isset($_POST[$key])) {
$config[$key] = $_POST[$key];
}
}
$UpConfig = $this->upgradeContainer->getUpgradeConfiguration();
$UpConfig->merge($config);
if ($this->upgradeContainer->getUpgradeConfigurationStorage()->save($UpConfig, UpgradeFileNames::CONFIG_FILENAME)) {
Tools14::redirectAdmin(self::$currentIndex . '&conf=6&token=' . Tools14::getValue('token'));
}
}
if (Tools14::isSubmit('deletebackup')) {
$res = false;
$name = Tools14::getValue('name');
$filelist = scandir($this->backupPath);
foreach ($filelist as $filename) {
// the following will match file or dir related to the selected backup
if (!empty($filename) && $filename[0] != '.' && $filename != 'index.php' && $filename != '.htaccess'
&& preg_match('#^(auto-backupfiles_|)' . preg_quote($name) . '(\.zip|)$#', $filename, $matches)) {
if (is_file($this->backupPath . DIRECTORY_SEPARATOR . $filename)) {
$res &= unlink($this->backupPath . DIRECTORY_SEPARATOR . $filename);
} elseif (!empty($name) && is_dir($this->backupPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR)) {
$res = FilesystemAdapter::deleteDirectory($this->backupPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR);
}
}
}
if ($res) {
Tools14::redirectAdmin(self::$currentIndex . '&conf=1&token=' . Tools14::getValue('token'));
} else {
$this->_errors[] = $this->trans('Error when trying to delete backups %s', array($name), 'Modules.Autoupgrade.Admin');
}
}
parent::postProcess();
}
/**
* update module configuration (saved in file UpgradeFiles::configFilename) with $new_config.
*
* @param array $new_config
*
* @return bool true if success
*/
// public function writeConfig($config)
// {
// if (!$this->upgradeContainer->getFileConfigurationStorage()->exists(UpgradeFileNames::configFilename) && !empty($config['channel'])) {
// $this->upgradeContainer->getUpgrader()->channel = $config['channel'];
// $this->upgradeContainer->getUpgrader()->checkPSVersion();
//
// $this->upgradeContainer->getState()->setInstallVersion($this->upgradeContainer->getUpgrader()->version_num);
// }
//
// $this->upgradeContainer->getUpgradeConfiguration()->merge($config);
// $this->upgradeContainer->getLogger()->info($this->trans('Configuration successfully updated.', array(), 'Modules.Autoupgrade.Admin').' <strong>'.$this->trans('This page will now be reloaded and the module will check if a new version is available.', array(), 'Modules.Autoupgrade.Admin').'</strong>');
// return (new UpgradeConfigurationStorage($this->autoupgradePath.DIRECTORY_SEPARATOR))->save($this->upgradeContainer->getUpgradeConfiguration(), UpgradeFileNames::configFilename);
// }
public function display()
{
// Make sure the user has configured the upgrade options, or set default values
$configuration_keys = array(
'PS_AUTOUP_UPDATE_DEFAULT_THEME' => 1,
'PS_AUTOUP_CHANGE_DEFAULT_THEME' => 0,
'PS_AUTOUP_KEEP_MAILS' => 0,
'PS_AUTOUP_CUSTOM_MOD_DESACT' => 1,
'PS_AUTOUP_PERFORMANCE' => 1,
);
foreach ($configuration_keys as $k => $default_value) {
if (Configuration::get($k) == '') {
Configuration::updateValue($k, $default_value);
}
}
// update backup name
$backupFinder = new BackupFinder($this->backupPath);
$availableBackups = $backupFinder->getAvailableBackups();
if (!$this->upgradeContainer->getUpgradeConfiguration()->get('PS_AUTOUP_BACKUP')
&& !empty($availableBackups)
&& !in_array($this->upgradeContainer->getState()->getBackupName(), $availableBackups)
) {
$this->upgradeContainer->getState()->setBackupName(end($availableBackups));
}
$upgrader = $this->upgradeContainer->getUpgrader();
$upgradeSelfCheck = new UpgradeSelfCheck(
$upgrader,
$this->prodRootDir,
$this->adminDir,
$this->autoupgradePath
);
$response = new AjaxResponse($this->upgradeContainer->getState(), $this->upgradeContainer->getLogger());
$this->_html = (new UpgradePage(
$this->upgradeContainer->getUpgradeConfiguration(),
$this->upgradeContainer->getTwig(),
$this->upgradeContainer->getTranslator(),
$upgradeSelfCheck,
$upgrader,
$backupFinder,
$this->autoupgradePath,
$this->prodRootDir,
$this->adminDir,
self::$currentIndex,
$this->token,
$this->upgradeContainer->getState()->getInstallVersion(),
$this->manualMode,
$this->upgradeContainer->getState()->getBackupName(),
$this->downloadPath
))->display(
$response
->setUpgradeConfiguration($this->upgradeContainer->getUpgradeConfiguration())
->getJson()
);
$this->ajax = true;
$this->content = $this->_html;
return parent::display();
}
/**
* @deprecated
* Method allowing errors on very old tabs to be displayed.
* On the next major of this module, use an admin controller and get rid of this.
*
* This method is called by functions.php available in the admin root folder.
*/
public function displayErrors()
{
if (empty($this->_errors)) {
return;
}
echo implode(' - ', $this->_errors);
}
/**
* Adapter for trans calls, existing only on PS 1.7.
* Making them available for PS 1.6 as well.
*
* @param string $id
* @param array $parameters
* @param string $domain
* @param string $locale
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
return (new \PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator(__CLASS__))->trans($id, $parameters, $domain, $locale);
}
}

View File

@@ -0,0 +1,27 @@
2014-04-22 18:56:42 +0200 // Changelog updated
2014-04-17 18:51:39 +0200 [-] Autoupgrade fix bug #PSCSX-1822
2014-04-17 15:03:02 +0200 [-] Autoupgrade, fix bug #PSCSX-1747, class_index badly generated
2014-04-17 11:53:49 +0200 [-] MO : autoupgrade - Fix 1.5 ps_version_compliancy issue
2014-04-17 10:49:39 +0200 [-] MO : Autoupgrade new version
2014-04-14 10:32:20 +0200 [-] MO : Autoupgrade, Fix bug #PSCSX-1788, bad sql query
2014-04-10 16:52:28 +0200 [-] MO : Autoupgrade new version 1.3.7
2014-04-10 16:46:32 +0200 // wording
2014-04-10 15:43:58 +0200 // autoupgrade small fix for .htaccess
2014-04-10 15:32:51 +0200 [-] Autoupgrade, Fix bug during Backup loop
2014-04-09 10:17:35 +0200 // autoupgrade, PHP Fatal error: Class 'Module' not found
2014-04-04 15:42:43 +0200 // autoupgrade remove display erros when not in mode_dev
2014-04-02 14:23:19 +0200 // autoupgrade, updateDefaultTheme on all shops
2014-04-01 12:18:27 +0200 // autoupgrade new version
2014-04-01 11:47:52 +0200 // autoupgrade enable htaccess genaration for 1.6
2014-03-28 18:52:48 +0100 // autoupgrade , #PSCSX-1231 again
2014-03-28 18:43:22 +0100 // autoupgrade new version 1.3.3
2014-03-28 18:41:49 +0100 // autoupgrade generate .htaccess on 1.6
2014-03-28 18:40:46 +0100 // autoupgrade, bad query
2014-03-28 18:33:19 +0100 // autoupgrade remove class_index
2014-03-28 15:02:48 +0100 // autoupgrade #PSCSX-1468, generate .htaccess #PSCSX-1468
2014-03-27 19:14:32 +0100 // delete old theme 1.4 in base if updateDefaultTheme
2014-03-27 12:47:35 +0100 // REPLACE without unique key on configuration
2014-03-27 10:59:45 +0100 // undefined var
2014-03-24 18:11:00 +0100 / MO autoupgrade : ps_versions_compliancy added
2014-03-21 15:12:10 +0100 // autoupgrade new version
2014-03-21 11:35:59 +0100 Initial commit

View File

@@ -0,0 +1,69 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class FileLoggerCore extends AbstractLogger
{
protected $filename = '';
/**
* Write the message in the log file
*
* @param string message
* @param level
*/
protected function logMessage($message, $level)
{
$formatted_message = '*'.$this->level_value[$level].'* '."\t".date('Y/m/d - H:i:s').': '.$message."\r\n";
return (bool)file_put_contents($this->getFilename(), $formatted_message, FILE_APPEND);
}
/**
* Check if the specified filename is writable and set the filename
*
* @param string filename
*/
public function setFilename($filename)
{
if (is_writable(dirname($filename)))
$this->filename = $filename;
else
die('Directory '.dirname($filename).' is not writable');
}
/**
* Log the message
*
* @param string message
* @param level
*/
public function getFilename()
{
if (empty($this->filename))
die('Filename is empty.');
return $this->filename;
}
}

View File

@@ -0,0 +1,101 @@
# 1-Click Upgrade
## About
Provides an automated method to upgrade your shop to the latest version of PrestaShop.
This module is compatible with all PrestaShop 1.6 & 1.7.
# Prerequisites
* PrestaShop 1.6 or 1.7
* PHP 5.6+
For older PHP versions, see previous releases of the module [(ex. v1.6.8)](https://github.com/PrestaShop/autoupgrade/releases/tag/v1.6.8).
Note they are unsupported and we strongly recommend you to upgrade your PHP version.
# Installation
All versions can be found in the [releases list](https://github.com/PrestaShop/autoupgrade/releases).
## Create a module from source code
* Clone (`git clone https://github.com/PrestaShop/autoupgrade.git`) or [download](https://github.com/PrestaShop/autoupgrade/archive/master.zip) the source code. You can also download a release **Source code** ([ex. v4.4.1](https://github.com/PrestaShop/autoupgrade/archive/v4.4.1.zip)). If you download a source code archive, you need extract the file and rename the extracted folder to **autoupgrade**
* Enter into folder **autoupgrade** and run the command `composer install` ([composer](https://getcomposer.org/)).
* Create a new zip file of **autoupgrade** folder
* Now you can upload into your module pages
# Running an upgrade on PrestaShop
Upgrading a shop can be done via:
* the configuration page of the module (access from your BO module page)
* in command line by calling the file *cli-upgrade.php*
## Command line parameters
Upgrade can be automated by calling *cli-upgrade.php*.
The following parameters are mandatory:
* **--dir**: Tells where the admin directory is.
* **--channel**: Selects what upgrade to run (minor, major etc.)
```
$ php cli-upgrade.php --dir=admin-dev --channel=major
```
# Rollback a shop
If an error occurs during the upgrade process, the rollback will be suggested.
In case you lost the page from your backoffice, note it can be triggered via CLI.
## Command line parameters
Rollback can be automated by calling *cli-rollback.php*.
The following parameters are mandatory:
* **--dir**: Tells where the admin directory is.
* **--backup**: Select the backup to restore (this can be found in your folder `<admin>/autoupgrade/backup/`)
```
$ php cli-rollback.php --dir=admin-dev --backup=V1.7.5.1_20190502-191341-22e883bd
```
## Contributing
PrestaShop modules are open-source extensions to the PrestaShop e-commerce solution. Everyone is welcome and even encouraged to contribute with their own improvements.
To contribute on this project, start by cloning the repository.
You must have [composer][4] installed on your computer. Run the following command:
```
$ composer install
```
Your module will be available with development libraries.
### GitHub Requirements
Contributors **must** follow the following rules:
* **Make your Pull Request on the "dev" branch**, NOT the "master" branch.
* Do not update the module's version number.
* Follow [the coding standards][1].
### Process in details
Contributors wishing to edit a module's files should follow the following process:
1. Create your GitHub account, if you do not have one already.
2. Fork the autoupgrade project to your GitHub account.
3. Clone your fork to your local machine in the ```/modules``` directory of your PrestaShop installation.
4. Create a branch in your local clone of the module for your changes.
5. Change the files in your branch. Be sure to follow [the coding standards][1]!
6. Push your changed branch to your fork in your GitHub account.
7. Create a pull request for your changes **on the _'dev'_ branch** of the module's project. Be sure to follow [the commit message norm][2] in your pull request. If you need help to make a pull request, read the [Github help page about creating pull requests][3].
8. Wait for one of the core developers either to include your change in the codebase, or to comment on possible improvements you should make to your code.
That's it: you have contributed to this open-source project! Congratulations!
[1]: http://doc.prestashop.com/display/PS16/Coding+Standards
[2]: http://doc.prestashop.com/display/PS16/How+to+write+a+commit+message
[3]: https://help.github.com/articles/using-pull-requests
[4]: https://getcomposer.org/download/

View File

@@ -0,0 +1,54 @@
<?php
/**
* 2007-2016 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\TaskRepository;
/**
* This file is the entrypoint for all ajax requests during a upgrade, rollback or configuration.
* In order to get the admin context, this file is copied to the admin/autoupgrade folder of your shop when the module configuration is reached.
*
* Calling it from the module/autoupgrade folder will have unwanted consequences on the upgrade and your shop.
*/
require_once realpath(dirname(__FILE__) . '/../../modules/autoupgrade') . '/ajax-upgradetabconfig.php';
$container = autoupgrade_init_container(dirname(__FILE__));
(new \PrestaShop\Module\AutoUpgrade\ErrorHandler($container->getLogger()))->enable();
if (!$container->getCookie()->check($_COOKIE)) {
// If this is an XSS attempt, then we should only display a simple, secure page
if (ob_get_level() && ob_get_length() > 0) {
ob_clean();
}
echo '{wrong token}';
http_response_code(401);
die(1);
}
$controller = TaskRepository::get(Tools14::getValue('action'), $container);
$controller->init();
$controller->run();
echo $controller->getJsonResponse();

View File

@@ -0,0 +1,82 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\Module\AutoUpgrade\Tools14;
if (function_exists('date_default_timezone_set')) {
// date_default_timezone_get calls date_default_timezone_set, which can provide warning
$timezone = @date_default_timezone_get();
date_default_timezone_set($timezone);
}
/**
* Set constants & general values used by the autoupgrade.
*
* @param string $callerFilePath Path to the caller file. Needed as the two files are not in the same folder
*/
function autoupgrade_init_container($callerFilePath)
{
if (PHP_SAPI === 'cli') {
$options = getopt('', array('dir:'));
if (isset($options['dir'])) {
$_POST['dir'] = $options['dir'];
}
}
// the following test confirm the directory exists
if (empty($_POST['dir'])) {
echo 'No admin directory provided (dir). 1-click upgrade cannot proceed.';
exit(1);
}
// defines.inc.php can not exists (1.3.0.1 for example)
// but we need _PS_ROOT_DIR_
if (!defined('_PS_ROOT_DIR_')) {
define('_PS_ROOT_DIR_', realpath($callerFilePath . '/../../'));
}
if (!defined('_PS_MODULE_DIR_')) {
define('_PS_MODULE_DIR_', _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR);
}
define('AUTOUPGRADE_MODULE_DIR', _PS_MODULE_DIR_ . 'autoupgrade' . DIRECTORY_SEPARATOR);
require_once AUTOUPGRADE_MODULE_DIR . 'functions.php';
require_once AUTOUPGRADE_MODULE_DIR . 'vendor/autoload.php';
$dir = Tools14::safeOutput(Tools14::getValue('dir'));
define('_PS_ADMIN_DIR_', _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $dir);
if (_PS_ADMIN_DIR_ !== realpath(_PS_ADMIN_DIR_)) {
echo 'wrong directory: ' . $dir;
exit(1);
}
$container = new \PrestaShop\Module\AutoUpgrade\UpgradeContainer(_PS_ROOT_DIR_, _PS_ADMIN_DIR_);
$container->getState()->importFromArray(empty($_REQUEST['params']) ? array() : $_REQUEST['params']);
return $container;
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
function fd($var)
{
return (Tools14::fd($var));
}
function p($var)
{
return (Tools14::p($var));
}
function d($var)
{
Tools14::d($var);
}
function ppp($var)
{
return (Tools14::p($var));
}
function ddd($var)
{
Tools14::d($var);
}
/**
* Sanitize data which will be injected into SQL query
*
* @param string $string SQL data which will be injected into SQL query
* @param boolean $htmlOK Does data contain HTML code ? (optional)
* @return string Sanitized data
*/
function pSQL($string, $htmlOK = false)
{
return Db::getInstance()->escape($string, $htmlOK);
}
function bqSQL($string)
{
return str_replace('`', '\`', pSQL($string));
}
/**
* @deprecated
*/
function nl2br2($string)
{
return Tools14::nl2br($string);
}

View File

@@ -0,0 +1,211 @@
<?php
/**
* 2007-2016 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class Autoupgrade extends Module
{
public function __construct()
{
$this->name = 'autoupgrade';
$this->tab = 'administration';
$this->author = 'PrestaShop';
$this->version = '4.8.0';
$this->need_instance = 1;
$this->bootstrap = true;
parent::__construct();
$this->multishop_context = Shop::CONTEXT_ALL;
if (!defined('_PS_ADMIN_DIR_')) {
if (defined('PS_ADMIN_DIR')) {
define('_PS_ADMIN_DIR_', PS_ADMIN_DIR);
} else {
$this->_errors[] = $this->trans('This version of PrestaShop cannot be upgraded: the PS_ADMIN_DIR constant is missing.', array(), 'Modules.Autoupgrade.Admin');
}
}
$this->displayName = $this->trans('1-Click Upgrade', array(), 'Modules.Autoupgrade.Admin');
$this->description = $this->trans('Provides an automated method to upgrade your shop to the latest version of PrestaShop.', array(), 'Modules.Autoupgrade.Admin');
$this->ps_versions_compliancy = array('min' => '1.6.0.0', 'max' => _PS_VERSION_);
}
public function install()
{
if (50600 > PHP_VERSION_ID) {
$this->_errors[] = $this->trans('This version of 1-click upgrade requires PHP 5.6 to work properly. Please upgrade your server configuration.', array(), 'Modules.Autoupgrade.Admin');
return false;
}
if (defined('_PS_HOST_MODE_') && _PS_HOST_MODE_) {
return false;
}
// Before creating a new tab "AdminSelfUpgrade" we need to remove any existing "AdminUpgrade" tab (present in v1.4.4.0 and v1.4.4.1)
if ($id_tab = Tab::getIdFromClassName('AdminUpgrade')) {
$tab = new Tab((int) $id_tab);
if (!$tab->delete()) {
$this->_errors[] = $this->trans('Unable to delete outdated "AdminUpgrade" tab (tab ID: %idtab%).', array('%idtab%' => (int) $id_tab), 'Modules.Autoupgrade.Admin');
}
}
// If the "AdminSelfUpgrade" tab does not exist yet, create it
if (!$id_tab = Tab::getIdFromClassName('AdminSelfUpgrade')) {
$tab = new Tab();
$tab->class_name = 'AdminSelfUpgrade';
$tab->module = 'autoupgrade';
$tab->id_parent = (int) Tab::getIdFromClassName('AdminTools');
foreach (Language::getLanguages(false) as $lang) {
$tab->name[(int) $lang['id_lang']] = '1-Click Upgrade';
}
if (!$tab->save()) {
return $this->_abortInstall($this->trans('Unable to create the "AdminSelfUpgrade" tab', array(), 'Modules.Autoupgrade.Admin'));
}
if (!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'logo.gif', _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'img' . DIRECTORY_SEPARATOR . 't' . DIRECTORY_SEPARATOR . 'AdminSelfUpgrade.gif')) {
return $this->_abortInstall($this->trans('Unable to copy logo.gif in %s', array(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'img' . DIRECTORY_SEPARATOR . 't' . DIRECTORY_SEPARATOR), 'Modules.Autoupgrade.Admin'));
}
} else {
$tab = new Tab((int) $id_tab);
}
// Update the "AdminSelfUpgrade" tab id in database or exit
if (Validate::isLoadedObject($tab)) {
Configuration::updateValue('PS_AUTOUPDATE_MODULE_IDTAB', (int) $tab->id);
} else {
return $this->_abortInstall($this->trans('Unable to load the "AdminSelfUpgrade" tab', array(), 'Modules.Autoupgrade.Admin'));
}
// Check that the 1-click upgrade working directory is existing or create it
$autoupgrade_dir = _PS_ADMIN_DIR_ . DIRECTORY_SEPARATOR . 'autoupgrade';
if (!file_exists($autoupgrade_dir) && !@mkdir($autoupgrade_dir)) {
return $this->_abortInstall($this->trans('Unable to create the directory "%s"', array($autoupgrade_dir), 'Modules.Autoupgrade.Admin'));
}
// Make sure that the 1-click upgrade working directory is writeable
if (!is_writable($autoupgrade_dir)) {
return $this->_abortInstall($this->trans('Unable to write in the directory "%s"', array($autoupgrade_dir), 'Modules.Autoupgrade.Admin'));
}
// If a previous version of ajax-upgradetab.php exists, delete it
if (file_exists($autoupgrade_dir . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php')) {
@unlink($autoupgrade_dir . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php');
}
// Then, try to copy the newest version from the module's directory
if (!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php', $autoupgrade_dir . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php')) {
return $this->_abortInstall($this->trans('Unable to copy ajax-upgradetab.php in %s', array($autoupgrade_dir), 'Modules.Autoupgrade.Admin'));
}
// Make sure that the XML config directory exists
if (!file_exists(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml') &&
!@mkdir(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml', 0775)) {
return $this->_abortInstall($this->trans('Unable to create the directory "%s"', array(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml'), 'Modules.Autoupgrade.Admin'));
} else {
@chmod(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml', 0775);
}
// Create a dummy index.php file in the XML config directory to avoid directory listing
if (!file_exists(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'index.php') &&
(file_exists(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'index.php') &&
!@copy(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'index.php', _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'index.php'))) {
return $this->_abortInstall($this->trans('Unable to create the directory "%s"', array(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml'), 'Modules.Autoupgrade.Admin'));
}
return parent::install();
}
public function uninstall()
{
// Delete the 1-click upgrade Back-office tab
if ($id_tab = Tab::getIdFromClassName('AdminSelfUpgrade')) {
$tab = new Tab((int) $id_tab);
$tab->delete();
}
// Remove the 1-click upgrade working directory
self::_removeDirectory(_PS_ADMIN_DIR_ . DIRECTORY_SEPARATOR . 'autoupgrade');
return parent::uninstall();
}
public function getContent()
{
global $cookie;
header('Location: index.php?tab=AdminSelfUpgrade&token=' . md5(pSQL(_COOKIE_KEY_ . 'AdminSelfUpgrade' . (int) Tab::getIdFromClassName('AdminSelfUpgrade') . (int) $cookie->id_employee)));
exit;
}
/**
* Set installation errors and return false.
*
* @param string $error Installation abortion reason
*
* @return bool Always false
*/
protected function _abortInstall($error)
{
$this->_errors[] = $error;
return false;
}
private static function _removeDirectory($dir)
{
if ($handle = @opendir($dir)) {
while (false !== ($entry = @readdir($handle))) {
if ($entry != '.' && $entry != '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $entry) === true) {
self::_removeDirectory($dir . DIRECTORY_SEPARATOR . $entry);
} else {
@unlink($dir . DIRECTORY_SEPARATOR . $entry);
}
}
}
@closedir($handle);
@rmdir($dir);
}
}
/**
* Adapter for trans calls, existing only on PS 1.7.
* Making them available for PS 1.6 as well.
*
* @param string $id
* @param array $parameters
* @param string $domain
* @param string $locale
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
require_once _PS_ROOT_DIR_ . '/modules/autoupgrade/classes/UpgradeTools/Translator.php';
$translator = new \PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator(__CLASS__);
return $translator->trans($id, $parameters, $domain, $locale);
}
}

View File

@@ -0,0 +1,193 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\Logger;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
/**
* Class creating the content to return at an ajax call.
*/
class AjaxResponse
{
/**
* Used during upgrade.
*
* @var bool Supposed to store a boolean in case of error
*/
private $error = false;
/**
* Used during upgrade.
*
* @var bool Inform when the step is completed
*/
private $stepDone = true;
/**
* Used during upgrade. "N/A" as value otherwise.
*
* @var string Next step to call (can be the same as the previous one)
*/
private $next = 'N/A';
/**
* @var array Params to send (upgrade conf, details on the work to do ...)
*/
private $nextParams = array();
/**
* Request format of the data to return.
* Seems to be never modified. Converted as const.
*/
const RESPONSE_FORMAT = 'json';
/**
* @var UpgradeConfiguration
*/
private $upgradeConfiguration;
/**
* @var Logger
*/
private $logger;
/**
* @var State
*/
private $state;
public function __construct(State $state, Logger $logger)
{
$this->state = $state;
$this->logger = $logger;
}
/**
* @return array of data to ready to be returned to caller
*/
public function getResponse()
{
$return = array(
'error' => $this->error,
'stepDone' => $this->stepDone,
'next' => $this->next,
'status' => $this->getStatus(),
'next_desc' => $this->logger->getLastInfo(),
'nextQuickInfo' => $this->logger->getInfos(),
'nextErrors' => $this->logger->getErrors(),
'nextParams' => array_merge(
$this->nextParams,
$this->state->export(),
array(
'typeResult' => self::RESPONSE_FORMAT,
'config' => $this->upgradeConfiguration->toArray(),
)
),
);
return $return;
}
/**
* @return string Json encoded response from $this->getResponse()
*/
public function getJson()
{
return json_encode($this->getResponse());
}
// GETTERS
public function getError()
{
return $this->error;
}
public function getStepDone()
{
return $this->stepDone;
}
public function getNext()
{
return $this->next;
}
public function getStatus()
{
return $this->getNext() == 'error' ? 'error' : 'ok';
}
public function getNextParams()
{
return $this->nextParams;
}
public function getUpgradeConfiguration()
{
return $this->upgradeConfiguration;
}
// SETTERS
public function setError($error)
{
$this->error = (bool) $error;
return $this;
}
public function setStepDone($stepDone)
{
$this->stepDone = $stepDone;
return $this;
}
public function setNext($next)
{
$this->next = $next;
return $this;
}
public function setNextParams($nextParams)
{
$this->nextParams = $nextParams;
return $this;
}
public function setUpgradeConfiguration(UpgradeConfiguration $upgradeConfiguration)
{
$this->upgradeConfiguration = $upgradeConfiguration;
return $this;
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
class BackupFinder
{
/**
* @var string[]
*/
private $availableBackups;
/**
* @var string
*/
private $backupPath;
/**
* BackupFinder constructor.
*
* @param string $backupPath
*/
public function __construct($backupPath)
{
$this->backupPath = $backupPath;
}
/**
* @return array
*/
public function getAvailableBackups()
{
if (null === $this->availableBackups) {
$this->availableBackups = $this->buildBackupList();
}
return $this->availableBackups;
}
/**
* @return array
*/
private function buildBackupList()
{
return array_intersect(
$this->getBackupDbAvailable($this->backupPath),
$this->getBackupFilesAvailable($this->backupPath)
);
}
/**
* @param string $backupPath
*
* @return array
*/
private function getBackupDbAvailable($backupPath)
{
$array = array();
$files = scandir($backupPath);
foreach ($files as $file) {
if ($file[0] == 'V' && is_dir($backupPath . DIRECTORY_SEPARATOR . $file)) {
$array[] = $file;
}
}
return $array;
}
/**
* @param string $backupPath
*
* @return array
*/
private function getBackupFilesAvailable($backupPath)
{
$array = array();
$files = scandir($backupPath);
foreach ($files as $file) {
if ($file[0] != '.' && substr($file, 0, 16) == 'auto-backupfiles') {
$array[] = preg_replace('#^auto-backupfiles_(.*-[0-9a-f]{1,8})\..*$#', '$1', $file);
}
}
return $array;
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
class ChannelInfo
{
private $info = array();
/**
* @var string
*/
private $channel;
/**
* ChannelInfo constructor.
*
* @param Upgrader $upgrader
* @param UpgradeConfiguration $config
* @param string $channel
*/
public function __construct(Upgrader $upgrader, UpgradeConfiguration $config, $channel)
{
$this->channel = $channel;
$publicChannels = array('minor', 'major', 'rc', 'beta', 'alpha');
preg_match('#([0-9]+\.[0-9]+)(?:\.[0-9]+){1,2}#', _PS_VERSION_, $matches);
$upgrader->branch = $matches[1];
$upgrader->channel = $channel;
if (in_array($channel, $publicChannels)) {
if ($channel == 'private' && !$config->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
$this->info = array(
'branch' => $upgrader->branch,
'available' => $upgrader->available,
'version_num' => $upgrader->version_num,
'version_name' => $upgrader->version_name,
'link' => $upgrader->link,
'md5' => $upgrader->md5,
'changelog' => $upgrader->changelog,
);
return;
}
switch ($channel) {
case 'private':
if (!$config->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
$this->info = array(
'available' => $upgrader->available,
'branch' => $upgrader->branch,
'version_num' => $upgrader->version_num,
'version_name' => $upgrader->version_name,
'link' => $config->get('private_release_link'),
'md5' => $config->get('private_release_md5'),
'changelog' => $upgrader->changelog,
);
break;
case 'archive':
case 'directory':
$this->info = array(
'available' => true,
);
break;
}
}
/**
* @return array
*/
public function getInfo()
{
return $this->info;
}
/**
* @return string
*/
public function getChannel()
{
return $this->channel;
}
}

View File

@@ -0,0 +1,248 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class ConfigurationTestCore
{
static function check($tests)
{
$res = array();
foreach ($tests as $key => $test)
$res[$key] = self::run($key, $test);
return $res;
}
static function run($ptr, $arg = 0)
{
if (call_user_func(array('ConfigurationTest', 'test_'.$ptr), $arg))
return 'ok';
return 'fail';
}
// Misc functions
static function test_phpversion()
{
return version_compare(substr(phpversion(), 0, 3), '5.4', '>=');
}
static function test_mysql_support()
{
return function_exists('mysql_connect');
}
static function test_magicquotes()
{
return !get_magic_quotes_gpc();
}
static function test_upload()
{
return ini_get('file_uploads');
}
static function test_fopen()
{
return ini_get('allow_url_fopen');
}
static function test_curl()
{
return function_exists('curl_init');
}
static function test_system($funcs)
{
foreach ($funcs AS $func)
if (!function_exists($func))
return false;
return true;
}
static function test_gd()
{
return function_exists('imagecreatetruecolor');
}
static function test_register_globals()
{
return !ini_get('register_globals');
}
static function test_gz()
{
if (function_exists('gzencode'))
return !(@gzencode('dd') === false);
return false;
}
public static function test_dir($relative_dir, $recursive = false, &$full_report = null)
{
$dir = rtrim(_PS_ROOT_DIR_, '\\/').DIRECTORY_SEPARATOR.trim($relative_dir, '\\/');
if (!file_exists($dir) || !$dh = opendir($dir))
{
$full_report = sprintf('Directory %s does not exists or is not writable', $dir); // sprintf for future translation
return false;
}
$dummy = rtrim($dir, '\\/').DIRECTORY_SEPARATOR.uniqid();
if (@file_put_contents($dummy, 'test'))
{
@unlink($dummy);
if (!$recursive)
{
closedir($dh);
return true;
}
}
elseif (!is_writable($dir))
{
$full_report = sprintf('Directory %s is not writable', $dir); // sprintf for future translation
return false;
}
if ($recursive)
while (($file = readdir($dh)) !== false)
if (is_dir($dir.DIRECTORY_SEPARATOR.$file) && $file != '.' && $file != '..' && $file != '.svn')
if (!ConfigurationTest::test_dir($relative_dir.DIRECTORY_SEPARATOR.$file, $recursive, $full_report))
return false;
closedir($dh);
return true;
}
// is_writable files
static function test_file($file)
{
return file_exists($file) && is_writable($file);
}
static function test_config_dir($dir)
{
return self::test_dir($dir);
}
static function test_sitemap($dir)
{
return self::test_file($dir);
}
static function test_root_dir($dir)
{
return self::test_dir($dir);
}
static function test_log_dir($dir)
{
return self::test_dir($dir);
}
static function test_admin_dir($dir)
{
return self::test_dir($dir);
}
static function test_img_dir($dir)
{
return self::test_dir($dir, true);
}
static function test_module_dir($dir)
{
return self::test_dir($dir, true);
}
static function test_tools_dir($dir)
{
return self::test_dir($dir);
}
static function test_cache_dir($dir)
{
return self::test_dir($dir);
}
static function test_tools_v2_dir($dir)
{
return self::test_dir($dir);
}
static function test_cache_v2_dir($dir)
{
return self::test_dir($dir);
}
static function test_download_dir($dir)
{
return self::test_dir($dir);
}
static function test_mails_dir($dir)
{
return self::test_dir($dir, true);
}
static function test_translations_dir($dir)
{
return self::test_dir($dir, true);
}
static function test_theme_lang_dir($dir)
{
if (!file_exists($dir))
return true;
return self::test_dir($dir, true);
}
static function test_theme_cache_dir($dir)
{
if (!file_exists($dir))
return true;
return self::test_dir($dir, true);
}
static function test_customizable_products_dir($dir)
{
return self::test_dir($dir);
}
static function test_virtual_products_dir($dir)
{
return self::test_dir($dir);
}
static function test_mcrypt()
{
return function_exists('mcrypt_encrypt');
}
static function test_dom()
{
return extension_loaded('Dom');
}
static function test_mobile()
{
return !(int)Module::isInstalled('mobile_theme');
}
}

View File

@@ -0,0 +1,153 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
class Cookie
{
const GENERATED_KEY_FILE = 'key.php';
/**
* @var string Admin subfolder, for cookie restricted use
*/
private $adminDir;
/**
* @var string Path to the tmp folder for key storage
*/
private $keyFilePath;
/**
* @var string Key kept in cache once loaded
*/
private $key;
/**
* @param string $adminDir Admin subfolder
* @param string $tmpDir Storage folder
*/
public function __construct($adminDir, $tmpDir)
{
$this->adminDir = $adminDir;
$this->keyFilePath = $tmpDir . DIRECTORY_SEPARATOR . self::GENERATED_KEY_FILE;
}
/**
* Create the cookie to be verified during the upgrade process,
* because we can't use the classic authentication.
*
* @param int $idEmployee
* @param string $iso_code i.e 'en'
*/
public function create($idEmployee, $iso_code)
{
$this->storeKey(_COOKIE_KEY_);
$cookiePath = __PS_BASE_URI__ . $this->adminDir;
setcookie('id_employee', (string) $idEmployee, 0, $cookiePath);
setcookie('iso_code', $iso_code, 0, $cookiePath);
setcookie('autoupgrade', $this->encrypt((string) $idEmployee), 0, $cookiePath);
}
/**
* From the cookie, check the current employee started the upgrade process.
*
* @param array $cookie
*
* @return bool True if allowed
*/
public function check(array $cookie)
{
if (empty($cookie['id_employee']) || empty($cookie['autoupgrade'])) {
return false;
}
return $cookie['autoupgrade'] == $this->encrypt($cookie['id_employee']);
}
/**
* @param string $string
*
* @return string MD5 hashed string
*/
private function encrypt($string)
{
return md5(md5($this->readKey()) . md5($string));
}
/**
* Generate PHP string to be stored in file.
*
* @param string $key
*
* @return string PHP file content
*
* @internal
*/
public function generateKeyFileContent($key)
{
return '<?php
$key = "' . $key . '";
';
}
/**
* If not loaded, reads the generated file to get the key.
*
* @return string
*
* @internal
*/
public function readKey()
{
if (!empty($this->key)) {
return $this->key;
}
// Variable $key is defined in file
$key = '';
require $this->keyFilePath;
$this->key = $key;
return $this->key;
}
/**
* PrestaShop constants won't be available during the upgrade process
* We store it in a dedicated file.
*
* @param string $key
*
* @return bool True on success
*
* @internal
*/
public function storeKey($key)
{
return (bool) file_put_contents($this->keyFilePath, $this->generateKeyFileContent($key));
}
}

View File

@@ -0,0 +1,178 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\LegacyLogger;
use PrestaShop\Module\AutoUpgrade\Log\Logger;
/**
* In order to improve the debug of the module in case of case, we need to display the missed errors
* directly on the user interface. This will allow a merchant to know what happened, without having to open
* his PHP logs.
*/
class ErrorHandler
{
/**
* @var Logger
*/
private $logger;
/**
* @param Logger $logger
*/
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
/**
* Enable error handlers for critical steps.
* Display hidden errors by PHP config to improve debug process.
*/
public function enable()
{
error_reporting(E_ALL);
set_error_handler(array($this, 'errorHandler'));
set_exception_handler(array($this, 'exceptionHandler'));
register_shutdown_function(array($this, 'fatalHandler'));
}
/**
* Function retrieving uncaught exceptions.
*
* @param \Throwable $e
*/
public function exceptionHandler($e)
{
$message = get_class($e) . ': ' . $e->getMessage();
$this->report($e->getFile(), $e->getLine(), Logger::CRITICAL, $message, $e->getTraceAsString(), true);
}
/**
* Function called by PHP errors, forwarding content to the ajax response.
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
*
* @return bool
*/
public function errorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler
return false;
}
switch ($errno) {
case E_USER_ERROR:
return false; // Will be taken by fatalHandler
case E_USER_WARNING:
case E_WARNING:
$type = Logger::WARNING;
break;
case E_NOTICE:
case E_USER_NOTICE:
$type = Logger::NOTICE;
break;
default:
$type = Logger::DEBUG;
break;
}
$this->report($errfile, $errline, $type, $errstr);
return true;
}
/**
* Fatal error from PHP are not taken by the error_handler. We must check if an error occured
* during the script shutdown.
*/
public function fatalHandler()
{
$lastError = error_get_last();
$trace = isset($lastError['backtrace']) ? var_export($lastError['backtrace'], true) : null;
if ($lastError && in_array($lastError['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR), true)) {
$this->report($lastError['file'], $lastError['line'], Logger::CRITICAL, $lastError['message'], $trace, true);
}
}
/**
* Create a json encoded.
*
* @param string $log
*
* @return string
*/
public function generateJsonLog($log)
{
return json_encode(array(
'nextQuickInfo' => $this->logger->getInfos(),
'nextErrors' => array_merge($this->logger->getErrors(), array($log)),
'error' => true,
'next' => 'error',
));
}
/**
* Forwards message to the main class of the upgrade.
*
* @param string $file
* @param int $line
* @param int $type Level of criticity
* @param string $message
* @param bool $display
*/
protected function report($file, $line, $type, $message, $trace = null, $display = false)
{
if ($type >= Logger::CRITICAL) {
http_response_code(500);
}
$log = "[INTERNAL] $file line $line - $message";
if (!empty($trace)) {
$log .= PHP_EOL . $trace;
}
$jsonResponse = $this->generateJsonLog($log);
try {
$this->logger->log($type, $log);
if ($display && $this->logger instanceof LegacyLogger) {
echo $jsonResponse;
}
} catch (\Exception $e) {
echo $jsonResponse;
$fd = fopen('php://stderr', 'w');
fwrite($fd, $log);
fclose($fd);
}
}
}

View File

@@ -0,0 +1,113 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Log;
/**
* This class reimplement the old properties of the class AdminSelfUpgrade,
* where all the mesages were stored.
*/
class LegacyLogger extends Logger
{
protected $normalMessages = array();
protected $severeMessages = array();
protected $lastInfo = '';
/**
* @var resource|false|null File descriptor of the log file
*/
protected $fd;
public function __construct($fileName = null)
{
if (null !== $fileName) {
$this->fd = fopen($fileName, 'a');
}
}
public function __destruct()
{
if (is_resource($this->fd)) {
fclose($this->fd);
}
}
/**
* {@inheritdoc}
*/
public function getErrors()
{
return $this->severeMessages;
}
/**
* {@inheritdoc}
*/
public function getInfos()
{
return $this->normalMessages;
}
/**
* {@inheritdoc}
*/
public function getLastInfo()
{
return $this->lastInfo;
}
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = array())
{
if (empty($message)) {
return;
}
if (is_resource($this->fd)) {
fwrite($this->fd, '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL);
}
// Specific case for INFO
if ($level === self::INFO) {
// If last info is already defined, move it to the messages list
if (!empty($this->lastInfo)) {
$this->normalMessages[] = $this->lastInfo;
}
$this->lastInfo = $message;
return;
}
if ($level < self::ERROR) {
$this->normalMessages[] = $message;
} else {
$this->severeMessages[] = $message;
}
}
}

View File

@@ -0,0 +1,128 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Log;
/**
* This class retrieves all message to display during the upgrade / rollback tasks.
*/
abstract class Logger implements LoggerInterface
{
const DEBUG = 1;
const INFO = 2;
const NOTICE = 3;
const WARNING = 4;
const ERROR = 5;
const CRITICAL = 6;
const ALERT = 7;
const EMERGENCY = 8;
protected static $levels = array(
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::NOTICE => 'NOTICE',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR',
self::CRITICAL => 'CRITICAL',
self::ALERT => 'ALERT',
self::EMERGENCY => 'EMERGENCY',
);
public function alert($message, array $context = array())
{
$this->log(self::ALERT, $message, $context);
}
public function critical($message, array $context = array())
{
$this->log(self::CRITICAL, $message, $context);
}
public function debug($message, array $context = array())
{
$this->log(self::DEBUG, $message, $context);
}
public function emergency($message, array $context = array())
{
$this->log(self::EMERGENCY, $message, $context);
}
public function error($message, array $context = array())
{
$this->log(self::ERROR, $message, $context);
}
public function info($message, array $context = array())
{
$this->log(self::INFO, $message, $context);
}
public function notice($message, array $context = array())
{
$this->log(self::NOTICE, $message, $context);
}
public function warning($message, array $context = array())
{
$this->log(self::WARNING, $message, $context);
}
/**
* Equivalent of the old $nextErrors
* Used during upgrade. Will be displayed in the top right panel (not visible at the beginning).
*
* @var array Details of error which occured during the request. Verbose levels: ERROR
*/
public function getErrors()
{
return array();
}
/**
* Equivalent of the old $nextQuickInfo
* Used during upgrade. Will be displayed in the lower panel.
*
* @var array Details on what happened during the execution. Verbose levels: DEBUG / INFO / WARNING
*/
public function getInfos()
{
return array();
}
/**
* Return the last message stored with the INFO level.
* Equivalent of the old $next_desc
* Used during upgrade. Will be displayed on the top left panel.
*
* @var string Stores the main information about the current step
*/
public function getLastInfo()
{
return '';
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* IMPORTANT NOTE.
*
* This class is taken from the composer dependency psr/log.
* We copied it here to avoid conflicts with the same file loaded by the core
*/
namespace PrestaShop\Module\AutoUpgrade\Log;
/**
* Describes a logger instance.
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: {foo} where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data. The only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* for the full interface specification.
*/
interface LoggerInterface
{
/**
* System is unusable.
*
* @param string $message
* @param array $context
*/
public function emergency($message, array $context = array());
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
*/
public function alert($message, array $context = array());
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
*/
public function critical($message, array $context = array());
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
*/
public function error($message, array $context = array());
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
*/
public function warning($message, array $context = array());
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
*/
public function notice($message, array $context = array());
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
*/
public function info($message, array $context = array());
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
*/
public function debug($message, array $context = array());
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
*/
public function log($level, $message, array $context = array());
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Log;
/**
* Logger to use when the messages can be seen as soon as they are created.
* For instance, in a CLI context.
*/
class StreamedLogger extends Logger
{
/**
* @var int Minimum criticity of level to display
*/
protected $filter = self::INFO;
/**
* @var resource File handler of standard output
*/
protected $out;
/**
* @var resource File handler of standard error
*/
protected $err;
public function __construct()
{
$this->out = fopen('php://stdout', 'w');
$this->err = fopen('php://stderr', 'w');
}
public function __destruct()
{
fclose($this->out);
fclose($this->err);
}
/**
* Check the verbosity allows the message to be displayed.
*
* @param int $level
*
* @return bool
*/
public function isFiltered($level)
{
return $level < $this->filter;
}
/**
* {@inherit}.
*/
public function log($level, $message, array $context = array())
{
if (empty($message)) {
return;
}
$log = self::$levels[$level] . ' - ' . $message . PHP_EOL;
if ($level > self::ERROR) {
fwrite($this->err, $log);
}
if (!$this->isFiltered($level)) {
fwrite($this->out, $log);
}
}
public function getFilter()
{
return $this->filter;
}
/**
* Set the verbosity of the logger.
*
* @param int $filter
*
* @return $this
*/
public function setFilter($filter)
{
if (!array_key_exists($filter, self::$levels)) {
throw new \Exception('Unknown level ' . $filter);
}
$this->filter = $filter;
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace Composer\Script {
class Event
{
}
}
namespace PrestaShop\Module\AutoUpgrade {
use Composer\Script\Event;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
class LoggedEvent extends Event
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function getIO()
{
return new LoggedEventIo($this->logger);
}
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
class LoggedEventIo
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function write($message)
{
$this->logger->debug($message);
}
}

View File

@@ -0,0 +1,147 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Parameters;
use PrestaShop\Module\AutoUpgrade\Tools14;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
/**
* Class used for management of to do files for upgrade tasks.
* Load / Save / Delete etc.
*/
class FileConfigurationStorage
{
/**
* @var string Location where all the configuration files are stored
*/
private $configPath;
/**
* @var Filesystem
*/
private $filesystem;
public function __construct($path)
{
$this->configPath = $path;
$this->filesystem = new Filesystem();
}
/**
* UpgradeConfiguration loader.
*
* @param string $fileName File name to load
*
* @return mixed or array() as default value
*/
public function load($fileName = '')
{
$configFilePath = $this->configPath . $fileName;
$config = array();
if (file_exists($configFilePath)) {
$config = @unserialize(base64_decode(Tools14::file_get_contents($configFilePath)));
}
return $config;
}
/**
* @param mixed $config
* @param string $fileName Destination name of the config file
*
* @return bool
*/
public function save($config, $fileName)
{
$configFilePath = $this->configPath . $fileName;
try {
$this->filesystem->dumpFile($configFilePath, base64_encode(serialize($config)));
return true;
} catch (IOException $e) {
// TODO: $e needs to be logged
return false;
}
}
/**
* @return array Temporary files path & name
*/
public function getFilesList()
{
$files = array();
foreach (UpgradeFileNames::$tmp_files as $file) {
$files[$file] = $this->getFilePath(constant('PrestaShop\\Module\\AutoUpgrade\\Parameters\\UpgradeFileNames::' . $file));
}
return $files;
}
/**
* Delete all temporary files in the config folder.
*/
public function cleanAll()
{
$this->filesystem->remove(self::getFilesList());
}
/**
* Delete a file from the filesystem.
*
* @param string $fileName
*/
public function clean($fileName)
{
$this->filesystem->remove($this->getFilePath($fileName));
}
/**
* Check if a file exists on the filesystem.
*
* @param string $fileName
*/
public function exists($fileName)
{
return $this->filesystem->exists($this->getFilePath($fileName));
}
/**
* Generate the complete path to a given file.
*
* @param string $file Name
*
* @return string Pgit gui&
* ath
*/
private function getFilePath($file)
{
return $this->configPath . $file;
}
}

View File

@@ -0,0 +1,165 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Parameters;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Contains the module configuration (form params).
*/
class UpgradeConfiguration extends ArrayCollection
{
/**
* Performance settings, if your server has a low memory size, lower these values.
*
* @var array
*/
protected $performanceValues = array(
'loopFiles' => array(400, 800, 1600), // files
'loopTime' => array(6, 12, 25), // seconds
'maxBackupFileSize' => array(15728640, 31457280, 62914560), // bytes
'maxWrittenAllowed' => array(4194304, 8388608, 16777216), // bytes
);
/**
* Get the name of the new release archive.
*
* @return string
*/
public function getArchiveFilename()
{
return $this->get('archive.filename');
}
/**
* Get the version included in the new release.
*
* @return string
*/
public function getArchiveVersion()
{
return $this->get('archive.version_num');
}
/**
* Get channel selected on config panel (Minor, major ...).
*
* @return string
*/
public function getChannel()
{
return $this->get('channel');
}
/**
* @return int Number of files to handle in a single call to avoid timeouts
*/
public function getNumberOfFilesPerCall()
{
return $this->performanceValues['loopFiles'][$this->getPerformanceLevel()];
}
/**
* @return int Number of seconds allowed before having to make another request
*/
public function getTimePerCall()
{
return $this->performanceValues['loopTime'][$this->getPerformanceLevel()];
}
/**
* @return int Kind of reference for SQL file creation, giving a file size before another request is needed
*/
public function getMaxSizeToWritePerCall()
{
return $this->performanceValues['maxWrittenAllowed'][$this->getPerformanceLevel()];
}
/**
* @return int Max file size allowed in backup
*/
public function getMaxFileToBackup()
{
return $this->performanceValues['maxBackupFileSize'][$this->getPerformanceLevel()];
}
/**
* @return int level of performance selected (0 for low, 2 for high)
*/
public function getPerformanceLevel()
{
return $this->get('PS_AUTOUP_PERFORMANCE') - 1;
}
/**
* @return bool True if the autoupgrade module should backup the images as well
*/
public function shouldBackupImages()
{
return (bool) $this->get('PS_AUTOUP_KEEP_IMAGES');
}
/**
* @return bool True if non-native modules must be disabled during upgrade
*/
public function shouldDeactivateCustomModules()
{
return (bool) $this->get('PS_AUTOUP_CUSTOM_MOD_DESACT');
}
/**
* @return bool true if we should keep the merchant emails untouched
*/
public function shouldKeepMails()
{
return (bool) $this->get('PS_AUTOUP_KEEP_MAILS');
}
/**
* @return bool True if we have to set the native theme by default
*/
public function shouldSwitchToDefaultTheme()
{
return (bool) $this->get('PS_AUTOUP_CHANGE_DEFAULT_THEME');
}
/**
* @return bool True if we are allowed to update th default theme files
*/
public function shouldUpdateDefaultTheme()
{
return (bool) $this->get('PS_AUTOUP_UPDATE_DEFAULT_THEME');
}
public function merge(array $array = array())
{
foreach ($array as $key => $value) {
$this->set($key, $value);
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Parameters;
use PrestaShop\Module\AutoUpgrade\Upgrader;
class UpgradeConfigurationStorage extends FileConfigurationStorage
{
/**
* UpgradeConfiguration loader.
*
* @param string $configFileName
*
* @return \PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration
*/
public function load($configFileName = '')
{
$data = array_merge(
$this->getDefaultData(),
parent::load($configFileName)
);
return new UpgradeConfiguration($data);
}
/**
* @param \PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration $config
* @param string $configFileName Destination path of the config file
*
* @return bool
*/
public function save($config, $configFileName)
{
if (!$config instanceof UpgradeConfiguration) {
throw new \InvalidArgumentException('Config is not a instance of UpgradeConfiguration');
}
return parent::save($config->toArray(), $configFileName);
}
public function getDefaultData()
{
return array(
'PS_AUTOUP_PERFORMANCE' => 1,
'PS_AUTOUP_CUSTOM_MOD_DESACT' => 1,
'PS_AUTOUP_UPDATE_DEFAULT_THEME' => 1,
'PS_AUTOUP_CHANGE_DEFAULT_THEME' => 0,
'PS_AUTOUP_KEEP_MAILS' => 0,
'PS_AUTOUP_BACKUP' => 1,
'PS_AUTOUP_KEEP_IMAGES' => 1,
'channel' => Upgrader::DEFAULT_CHANNEL,
'archive.filename' => Upgrader::DEFAULT_FILENAME,
);
}
}

View File

@@ -0,0 +1,158 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Parameters;
/**
* File names where upgrade temporary content is stored.
*/
class UpgradeFileNames
{
/**
* configFilename contains all configuration specific to the autoupgrade module.
*
* @var string
*/
const CONFIG_FILENAME = 'config.var';
/**
* during upgradeFiles process,
* this files contains the list of queries left to upgrade in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const QUERIES_TO_UPGRADE_LIST = 'queriesToUpgrade.list';
/**
* during upgradeFiles process,
* this files contains the list of files left to upgrade in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const FILES_TO_UPGRADE_LIST = 'filesToUpgrade.list';
/**
* during upgradeModules process,
* this files contains the list of modules left to upgrade in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const MODULES_TO_UPGRADE_LIST = 'modulesToUpgrade.list';
/**
* during upgradeFiles process,
* this files contains the list of files left to upgrade in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const FILES_DIFF_LIST = 'filesDiff.list';
/**
* during backupFiles process,
* this files contains the list of files left to save in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const FILES_TO_BACKUP_LIST = 'filesToBackup.list';
/**
* during backupDb process,
* this files contains the list of tables left to save in a serialized array.
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const DB_TABLES_TO_BACKUP_LIST = 'tablesToBackup.list';
/**
* during restoreDb process,
* this file contains a serialized array of queries which left to execute for restoring database
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const QUERIES_TO_RESTORE_LIST = 'queryToRestore.list';
const DB_TABLES_TO_CLEAN_LIST = 'tableToClean.list';
/**
* during restoreFiles process,
* this file contains difference between queryToRestore and queries present in a backupFiles archive
* (this file is deleted in init() method if you reload the page).
*
* @var string
*/
const FILES_TO_REMOVE_LIST = 'filesToRemove.list';
/**
* during restoreFiles process,
* contains list of files present in backupFiles archive.
*
* @var string
*/
const FILES_FROM_ARCHIVE_LIST = 'filesFromArchive.list';
/**
* mailCustomList contains list of mails files which are customized,
* relative to original files for the current PrestaShop version.
*
* @var string
*/
const MAILS_CUSTOM_LIST = 'mails-custom.list';
/**
* tradCustomList contains list of translation files which are customized,
* relative to original files for the current PrestaShop version.
*
* @var string
*/
const TRANSLATION_FILES_CUSTOM_LIST = 'translations-custom.list';
/**
* tmp_files contains an array of filename which will be removed
* at the beginning of the upgrade process.
*
* @var array
*/
public static $tmp_files = array(
'QUERIES_TO_UPGRADE_LIST', // used ?
'FILES_TO_UPGRADE_LIST',
'FILES_DIFF_LIST',
'FILES_TO_BACKUP_LIST',
'DB_TABLES_TO_BACKUP_LIST',
'QUERIES_TO_RESTORE_LIST',
'DB_TABLES_TO_CLEAN_LIST',
'FILES_TO_REMOVE_LIST',
'FILES_FROM_ARCHIVE_LIST',
'MAILS_CUSTOM_LIST',
'TRANSLATION_FILES_CUSTOM_LIST',
);
}

View File

@@ -0,0 +1,140 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use ConfigurationTestCore as ConfigurationTest;
class PrestashopConfiguration
{
// Variables used for cache
private $moduleVersion;
private $allowed_array = array();
// Variables from main class
private $autoupgradeDir;
private $psRootDir;
public function __construct($moduleDir, $psRootDir)
{
$this->autoupgradeDir = $moduleDir;
$this->psRootDir = $psRootDir;
}
/**
* @return string|false Returns the module version if found in the config.xml file, false otherwise.
*/
public function getModuleVersion()
{
if (null !== $this->moduleVersion) {
return $this->moduleVersion;
}
// TODO: to be moved as property class in order to make tests possible
$path = _PS_ROOT_DIR_ . '/modules/autoupgrade/config.xml';
$this->moduleVersion = false;
if (file_exists($path)
&& $xml_module_version = simplexml_load_file($path)
) {
$this->moduleVersion = (string) $xml_module_version->version;
}
return $this->moduleVersion;
}
public function getPrestaShopVersion()
{
if (defined('_PS_VERSION_')) {
return _PS_VERSION_;
}
$files = array(
$this->psRootDir . '/config/settings.inc.php',
$this->psRootDir . '/config/autoload.php',
$this->psRootDir . '/app/AppKernel.php',
);
foreach ($files as $file) {
$version = $this->findPrestaShopVersionInFile(file_get_contents($file));
if ($version) {
return $version;
}
}
throw new \Exception('Can\'t find PrestaShop Version');
}
/**
* Compares the installed module version with the one available on download.
*
* @return bool True is the latest version of the module is currently installed
*/
public function checkAutoupgradeLastVersion($extAutoupgradeLastVersion)
{
$moduleVersion = $this->getModuleVersion();
if ($moduleVersion) {
return version_compare($moduleVersion, $extAutoupgradeLastVersion, '>=');
}
return true;
}
/**
* @return array Details of the filesystem permission check
*/
protected function getRootWritableDetails()
{
$result = array();
// Root directory permissions cannot be checked recursively anymore, it takes too much time
$result['root_writable'] = ConfigurationTest::test_dir('/', false, $report);
$result['root_writable_report'] = $report ? $report : true; // Avoid null in the array as it makes the shop non-compliant
return $result;
}
/**
* @param string $content File content
*
* @return bool|string
*
* @internal Used for test
*/
public function findPrestaShopVersionInFile($content)
{
$matches = array();
// Example: define('_PS_VERSION_', '1.7.3.4');
if (1 === preg_match("/define\([\"']_PS_VERSION_[\"'], [\"'](?<version>[0-9.]+)[\"']\)/", $content, $matches)) {
return $matches['version'];
}
// Example: const VERSION = '1.7.6.0';
if (1 === preg_match("/const VERSION = [\"'](?<version>[0-9.]+)[\"'];/", $content, $matches)) {
return $matches['version'];
}
return false;
}
}

View File

@@ -0,0 +1,341 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
/**
* Class storing the temporary data to keep between 2 ajax requests.
*/
class State
{
private $install_version; // Destination version of PrestaShop
private $backupName;
private $backupFilesFilename;
private $backupDbFilename;
private $restoreName;
private $restoreFilesFilename;
private $restoreDbFilenames = array();
// STEP BackupDb
private $backup_lines;
private $backup_loop_limit;
private $backup_table;
/**
* Int during BackupDb, allowing the script to increent the number of different file names
* String during step RestoreDb, which contains the file to process (Data coming from toRestoreQueryList).
*
* @var string|int Contains the SQL progress
*/
private $dbStep = 0;
/**
* Data filled in upgrade warmup, to avoid risky tasks during the process.
*
* @var array|null File containing sample files to be deleted
*/
private $removeList;
/**
* @var string|null File containing files to be upgraded
*/
private $fileToUpgrade;
/**
* @var string|null File containing modules to be upgraded
*/
private $modulesToUpgrade;
/**
* installedLanguagesIso is an array of iso_code of each installed languages.
*
* @var array
*/
private $installedLanguagesIso = array();
/**
* modules_addons is an array of array(id_addons => name_module).
*
* @var array
*/
private $modules_addons = array();
/**
* @var bool Determining if all steps went totally successfully
*/
private $warning_exists = false;
/**
* @param array $savedState from another request
*/
public function importFromArray(array $savedState)
{
foreach ($savedState as $name => $value) {
if (!empty($value) && property_exists($this, $name)) {
$this->{$name} = $value;
}
}
return $this;
}
/**
* @param string $encodedData
*/
public function importFromEncodedData($encodedData)
{
$decodedData = json_decode(base64_decode($encodedData), true);
if (empty($decodedData['nextParams'])) {
return $this;
}
return $this->importFromArray($decodedData['nextParams']);
}
/**
* @return array of class properties for export
*/
public function export()
{
return get_object_vars($this);
}
public function initDefault(Upgrader $upgrader, $prodRootDir, $version)
{
$postData = http_build_query(array(
'action' => 'native',
'iso_code' => 'all',
'method' => 'listing',
'version' => $this->getInstallVersion(),
));
$xml_local = $prodRootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'modules_native_addons.xml';
$xml = $upgrader->getApiAddons($xml_local, $postData, true);
$modules_addons = array();
if (is_object($xml)) {
foreach ($xml as $mod) {
$modules_addons[(string) $mod->id] = (string) $mod->name;
}
}
$this->setModulesAddons($modules_addons);
// installedLanguagesIso is used to merge translations files
$installedLanguagesIso = array_map(
function ($v) { return $v['iso_code']; },
\Language::getIsoIds(false)
);
$this->setInstalledLanguagesIso($installedLanguagesIso);
$rand = dechex(mt_rand(0, min(0xffffffff, mt_getrandmax())));
$date = date('Ymd-His');
$backupName = 'V' . $version . '_' . $date . '-' . $rand;
// Todo: To be moved in state class? We could only require the backup name here
// I.e = $this->upgradeContainer->getState()->setBackupName($backupName);, which triggers 2 other setters internally
$this->setBackupName($backupName);
}
// GETTERS
public function getInstallVersion()
{
return $this->install_version;
}
public function getBackupName()
{
return $this->backupName;
}
public function getBackupFilesFilename()
{
return $this->backupFilesFilename;
}
public function getBackupDbFilename()
{
return $this->backupDbFilename;
}
public function getBackupLines()
{
return $this->backup_lines;
}
public function getBackupLoopLimit()
{
return $this->backup_loop_limit;
}
public function getBackupTable()
{
return $this->backup_table;
}
public function getDbStep()
{
return $this->dbStep;
}
public function getRemoveList()
{
return $this->removeList;
}
public function getRestoreName()
{
return $this->restoreName;
}
public function getRestoreFilesFilename()
{
return $this->restoreFilesFilename;
}
public function getRestoreDbFilenames()
{
return $this->restoreDbFilenames;
}
public function getInstalledLanguagesIso()
{
return $this->installedLanguagesIso;
}
public function getModules_addons()
{
return $this->modules_addons;
}
public function getWarningExists()
{
return $this->warning_exists;
}
// SETTERS
public function setInstallVersion($install_version)
{
$this->install_version = $install_version;
return $this;
}
public function setBackupName($backupName)
{
$this->backupName = $backupName;
$this->setBackupFilesFilename('auto-backupfiles_' . $backupName . '.zip')
->setBackupDbFilename('auto-backupdb_XXXXXX_' . $backupName . '.sql');
return $this;
}
public function setBackupFilesFilename($backupFilesFilename)
{
$this->backupFilesFilename = $backupFilesFilename;
return $this;
}
public function setBackupDbFilename($backupDbFilename)
{
$this->backupDbFilename = $backupDbFilename;
return $this;
}
public function setBackupLines($backup_lines)
{
$this->backup_lines = $backup_lines;
return $this;
}
public function setBackupLoopLimit($backup_loop_limit)
{
$this->backup_loop_limit = $backup_loop_limit;
return $this;
}
public function setBackupTable($backup_table)
{
$this->backup_table = $backup_table;
return $this;
}
public function setDbStep($dbStep)
{
$this->dbStep = $dbStep;
return $this;
}
public function setRemoveList($removeList)
{
$this->removeList = $removeList;
return $this;
}
public function setRestoreName($restoreName)
{
$this->restoreName = $restoreName;
return $this;
}
public function setRestoreFilesFilename($restoreFilesFilename)
{
$this->restoreFilesFilename = $restoreFilesFilename;
return $this;
}
public function setRestoreDbFilenames($restoreDbFilenames)
{
$this->restoreDbFilenames = $restoreDbFilenames;
return $this;
}
public function setInstalledLanguagesIso($installedLanguagesIso)
{
$this->installedLanguagesIso = $installedLanguagesIso;
return $this;
}
public function setModulesAddons($modules_addons)
{
$this->modules_addons = $modules_addons;
return $this;
}
public function setWarningExists($warning_exists)
{
$this->warning_exists = $warning_exists;
return $this;
}
}

View File

@@ -0,0 +1,124 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner;
use PrestaShop\Module\AutoUpgrade\AjaxResponse;
use PrestaShop\Module\AutoUpgrade\Log\Logger;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
abstract class AbstractTask
{
/* usage : key = the step you want to skip
* value = the next step you want instead
* example : public static $skipAction = array();
*/
public static $skipAction = array();
/**
* @var Logger
*/
protected $logger;
/**
* @var \PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator
*/
protected $translator;
/**
* @var UpgradeContainer
*/
protected $container;
// Task progress details
protected $stepDone;
protected $status;
protected $error;
protected $nextParams = array();
protected $next;
public function __construct(UpgradeContainer $container)
{
$this->container = $container;
$this->logger = $this->container->getLogger();
$this->translator = $this->container->getTranslator();
$this->checkTaskMayRun();
}
/**
* @return string base64 encoded data from AjaxResponse
*/
public function getEncodedResponse()
{
return base64_encode($this->getJsonResponse());
}
/**
* @return string Json encoded data from AjaxResponse
*/
public function getJsonResponse()
{
return $this->getResponse()->getJson();
}
/**
* Get result of the task and data to send to the next request.
*
* @return AjaxResponse
*/
public function getResponse()
{
$response = new AjaxResponse($this->container->getState(), $this->logger);
return $response->setError($this->error)
->setStepDone($this->stepDone)
->setNext($this->next)
->setNextParams($this->nextParams)
->setUpgradeConfiguration($this->container->getUpgradeConfiguration());
}
private function checkTaskMayRun()
{
// PrestaShop demo mode
if (defined('_PS_MODE_DEMO_') && _PS_MODE_DEMO_ == true) {
return;
}
$currentAction = get_class($this);
if (isset(self::$skipAction[$currentAction])) {
$this->next = self::$skipAction[$currentAction];
$this->logger->info($this->translator->trans('Action %s skipped', array($currentAction), 'Modules.Autoupgrade.Admin'));
}
}
public function init()
{
$this->container->initPrestaShopCore();
}
abstract public function run();
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner;
use PrestaShop\Module\AutoUpgrade\AjaxResponse;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\TaskRepository;
/**
* Execute the whole process in a single request, useful in CLI.
*/
abstract class ChainedTasks extends AbstractTask
{
protected $step;
/**
* Execute all the tasks from a specific initial step, until the end (complete or error).
*
* @return int Return code (0 for success, any value otherwise)
*/
public function run()
{
$requireRestart = false;
while ($this->canContinue() && !$requireRestart) {
$this->logger->info('=== Step ' . $this->step);
$controller = TaskRepository::get($this->step, $this->container);
$controller->init();
$controller->run();
$result = $controller->getResponse();
$requireRestart = $this->checkIfRestartRequested($result);
$this->error = $result->getError();
$this->stepDone = $result->getStepDone();
$this->step = $result->getNext();
}
return (int) ($this->error || $this->step === 'error');
}
/**
* Customize the execution context with several options.
*
* @param array $options
*/
abstract public function setOptions(array $options);
/**
* Tell the while loop if it can continue.
*
* @return bool
*/
protected function canContinue()
{
if (empty($this->step)) {
return false;
}
if ($this->error) {
return false;
}
return $this->step !== 'error';
}
/**
* For some steps, we may require a new request to be made.
* Return true for stopping the process.
*/
protected function checkIfRestartRequested(AjaxResponse $response)
{
return false;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
/**
* List the files modified in the current installation regards to the original version.
*/
class CheckFilesVersion extends AbstractTask
{
public function run()
{
// do nothing after this request (see javascript function doAjaxRequest )
$this->next = '';
$upgrader = $this->container->getUpgrader();
$changedFileList = $upgrader->getChangedFilesList();
if ($changedFileList === false) {
$this->nextParams['status'] = 'error';
$this->nextParams['msg'] = $this->translator->trans('Unable to check files for the installed version of PrestaShop.', array(), 'Modules.Autoupgrade.Admin');
return;
}
foreach (array('core', 'translation', 'mail') as $type) {
if (!isset($changedFileList[$type])) {
$changedFileList[$type] = array();
}
}
if ($upgrader->isAuthenticPrestashopVersion() === true) {
$this->nextParams['status'] = 'ok';
$this->nextParams['msg'] = $this->translator->trans('Core files are ok', array(), 'Modules.Autoupgrade.Admin');
} else {
$this->nextParams['status'] = 'warn';
$this->nextParams['msg'] = $this->translator->trans(
'%modificationscount% file modifications have been detected, including %coremodifications% from core and native modules:',
array(
'%modificationscount%' => count(array_merge($changedFileList['core'], $changedFileList['mail'], $changedFileList['translation'])),
'%coremodifications%' => count($changedFileList['core']),
),
'Modules.Autoupgrade.Admin'
);
}
$this->nextParams['result'] = $changedFileList;
$this->container->getFileConfigurationStorage()->save($changedFileList['translation'], UpgradeFileNames::TRANSLATION_FILES_CUSTOM_LIST);
$this->container->getFileConfigurationStorage()->save($changedFileList['mail'], UpgradeFileNames::MAILS_CUSTOM_LIST);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
/**
* get the list of all modified and deleted files between current version
* and target version (according to channel configuration).
*/
class CompareReleases extends AbstractTask
{
public function run()
{
// do nothing after this request (see javascript function doAjaxRequest )
$this->next = '';
$channel = $this->container->getUpgradeConfiguration()->get('channel');
$upgrader = $this->container->getUpgrader();
switch ($channel) {
case 'archive':
$version = $this->container->getUpgradeConfiguration()->get('archive.version_num');
break;
case 'directory':
$version = $this->container->getUpgradeConfiguration()->get('directory.version_num');
break;
default:
preg_match('#([0-9]+\.[0-9]+)(?:\.[0-9]+){1,2}#', _PS_VERSION_, $matches);
$upgrader->branch = $matches[1];
$upgrader->channel = $channel;
if ($this->container->getUpgradeConfiguration()->get('channel') == 'private' && !$this->container->getUpgradeConfiguration()->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
$version = $upgrader->version_num;
}
$diffFileList = $upgrader->getDiffFilesList(_PS_VERSION_, $version);
if (!is_array($diffFileList)) {
$this->nextParams['status'] = 'error';
$this->nextParams['msg'] = sprintf('Unable to generate diff file list between %1$s and %2$s.', _PS_VERSION_, $version);
} else {
$this->container->getFileConfigurationStorage()->save($diffFileList, UpgradeFileNames::FILES_DIFF_LIST);
if (count($diffFileList) > 0) {
$this->nextParams['msg'] = $this->translator->trans(
'%modifiedfiles% files will be modified, %deletedfiles% files will be deleted (if they are found).',
array(
'%modifiedfiles%' => count($diffFileList['modified']),
'%deletedfiles%' => count($diffFileList['deleted']),
),
'Modules.Autoupgrade.Admin');
} else {
$this->nextParams['msg'] = $this->translator->trans('No diff files found.', array(), 'Modules.Autoupgrade.Admin');
}
$this->nextParams['result'] = $diffFileList;
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous;
use PrestaShop\Module\AutoUpgrade\ChannelInfo;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Twig\Block\ChannelInfoBlock;
/**
* display informations related to the selected channel : link/changelog for remote channel,
* or configuration values for special channels.
*/
class GetChannelInfo extends AbstractTask
{
public function run()
{
// do nothing after this request (see javascript function doAjaxRequest )
$this->next = '';
$channel = $this->container->getUpgradeConfiguration()->getChannel();
$channelInfo = (new ChannelInfo($this->container->getUpgrader(), $this->container->getUpgradeConfiguration(), $channel));
$channelInfoArray = $channelInfo->getInfo();
$this->nextParams['result']['available'] = $channelInfoArray['available'];
$this->nextParams['result']['div'] = (new ChannelInfoBlock(
$this->container->getUpgradeConfiguration(),
$channelInfo,
$this->container->getTwig())
)->render();
}
}

View File

@@ -0,0 +1,130 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfigurationStorage;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Upgrader;
/**
* update configuration after validating the new values.
*/
class UpdateConfig extends AbstractTask
{
public function run()
{
// nothing next
$this->next = '';
// Was coming from AdminSelfUpgrade::currentParams before
$request = $this->getRequestParams();
$config = array();
// update channel
if (isset($request['channel'])) {
$config['channel'] = $request['channel'];
$config['archive.filename'] = Upgrader::DEFAULT_FILENAME;
// Switch on default theme if major upgrade (i.e: 1.6 -> 1.7)
$config['PS_AUTOUP_CHANGE_DEFAULT_THEME'] = ($request['channel'] === 'major');
}
if (isset($request['private_release_link'], $request['private_release_md5'])) {
$config['channel'] = 'private';
$config['private_release_link'] = $request['private_release_link'];
$config['private_release_md5'] = $request['private_release_md5'];
$config['private_allow_major'] = $request['private_allow_major'];
}
// if (!empty($request['archive_name']) && !empty($request['archive_num']))
if (!empty($request['archive_prestashop'])) {
$file = $request['archive_prestashop'];
if (!file_exists($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $file)) {
$this->error = true;
$this->logger->info($this->translator->trans('File %s does not exist. Unable to select that channel.', array($file), 'Modules.Autoupgrade.Admin'));
return false;
}
if (empty($request['archive_num'])) {
$this->error = true;
$this->logger->info($this->translator->trans('Version number is missing. Unable to select that channel.', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
$config['channel'] = 'archive';
$config['archive.filename'] = $request['archive_prestashop'];
$config['archive.version_num'] = $request['archive_num'];
// $config['archive_name'] = $request['archive_name'];
$this->logger->info($this->translator->trans('Upgrade process will use archive.', array(), 'Modules.Autoupgrade.Admin'));
}
if (isset($request['directory_num'])) {
$config['channel'] = 'directory';
if (empty($request['directory_num']) || strpos($request['directory_num'], '.') === false) {
$this->error = true;
$this->logger->info($this->translator->trans('Version number is missing. Unable to select that channel.', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
$config['directory.version_num'] = $request['directory_num'];
}
if (isset($request['skip_backup'])) {
$config['skip_backup'] = $request['skip_backup'];
}
if (!$this->writeConfig($config)) {
$this->error = true;
$this->logger->info($this->translator->trans('Error on saving configuration', array(), 'Modules.Autoupgrade.Admin'));
}
}
protected function getRequestParams()
{
return empty($_REQUEST['params']) ? array() : $_REQUEST['params'];
}
/**
* update module configuration (saved in file UpgradeFiles::configFilename) with $new_config.
*
* @param array $config
*
* @return bool true if success
*/
private function writeConfig($config)
{
if (!$this->container->getFileConfigurationStorage()->exists(UpgradeFileNames::CONFIG_FILENAME) && !empty($config['channel'])) {
$this->container->getUpgrader()->channel = $config['channel'];
$this->container->getUpgrader()->checkPSVersion();
$this->container->getState()->setInstallVersion($this->container->getUpgrader()->version_num);
}
$this->container->getUpgradeConfiguration()->merge($config);
$this->logger->info($this->translator->trans('Configuration successfully updated.', array(), 'Modules.Autoupgrade.Admin') . ' <strong>' . $this->translator->trans('This page will now be reloaded and the module will check if a new version is available.', array(), 'Modules.Autoupgrade.Admin') . '</strong>');
return (new UpgradeConfigurationStorage($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR))->save($this->container->getUpgradeConfiguration(), UpgradeFileNames::CONFIG_FILENAME);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner;
class NullTask extends AbstractTask
{
public function run()
{
// Nothing
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\TaskRunner\ChainedTasks;
/**
* Execute the whole upgrade process in a single request.
*/
class AllRollbackTasks extends ChainedTasks
{
const initialTask = 'rollback';
protected $step = self::initialTask;
/**
* Customize the execution context with several options
* > action: Replace the initial step to run
* > channel: Makes a specific upgrade (minor, major etc.)
* > data: Loads an encoded array of data coming from another request.
*
* @param array $options
*/
public function setOptions(array $options)
{
if (!empty($options['backup'])) {
$this->container->getState()->setRestoreName($options['backup']);
}
}
/**
* Set default config on first run.
*/
public function init()
{
// Do nothing
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
class NoRollbackFound extends AbstractTask
{
public function run()
{
$this->logger->info($this->translator->trans('Nothing to restore', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'rollbackComplete';
}
}

View File

@@ -0,0 +1,263 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Database;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
/**
* Restores database from backup file.
*/
class RestoreDb extends AbstractTask
{
public function run()
{
$databaseTools = new Database($this->container->getDb());
$ignore_stats_table = array(
_DB_PREFIX_ . 'connections',
_DB_PREFIX_ . 'connections_page',
_DB_PREFIX_ . 'connections_source',
_DB_PREFIX_ . 'guest',
_DB_PREFIX_ . 'statssearch',
);
$startTime = time();
$listQuery = array();
// deal with running backup rest if exist
if (file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST)) {
$listQuery = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::QUERIES_TO_RESTORE_LIST);
}
// deal with the next files stored in restoreDbFilenames
$restoreDbFilenames = $this->container->getState()->getRestoreDbFilenames();
if (empty($listQuery) && count($restoreDbFilenames) > 0) {
$currentDbFilename = array_shift($restoreDbFilenames);
$this->container->getState()->setRestoreDbFilenames($restoreDbFilenames);
if (!preg_match('#auto-backupdb_([0-9]{6})_#', $currentDbFilename, $match)) {
$this->next = 'error';
$this->error = true;
$this->logger->error($this->translator->trans('%s: File format does not match.', array($currentDbFilename), 'Modules.Autoupgrade.Admin'));
return false;
}
$this->container->getState()->setDbStep($match[1]);
$backupdb_path = $this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getRestoreName();
$dot_pos = strrpos($currentDbFilename, '.');
$fileext = substr($currentDbFilename, $dot_pos + 1);
$requests = array();
$content = '';
$this->logger->debug($this->translator->trans(
'Opening backup database file %filename% in %extension% mode',
array(
'%filename%' => $currentDbFilename,
'%extension%' => $fileext,
),
'Modules.Autoupgrade.Admin'
));
switch ($fileext) {
case 'bz':
case 'bz2':
$fp = bzopen($backupdb_path . DIRECTORY_SEPARATOR . $currentDbFilename, 'r');
if (is_resource($fp)) {
while (!feof($fp)) {
$content .= bzread($fp, 4096);
}
bzclose($fp);
}
break;
case 'gz':
$fp = gzopen($backupdb_path . DIRECTORY_SEPARATOR . $currentDbFilename, 'r');
if (is_resource($fp)) {
while (!feof($fp)) {
$content .= gzread($fp, 4096);
}
gzclose($fp);
}
break;
default:
$fp = fopen($backupdb_path . DIRECTORY_SEPARATOR . $currentDbFilename, 'r');
if (is_resource($fp)) {
while (!feof($fp)) {
$content .= fread($fp, 4096);
}
fclose($fp);
}
}
$currentDbFilename = '';
if (empty($content)) {
$this->logger->error($this->translator->trans('Database backup is empty.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'rollback';
return false;
}
// preg_match_all is better than preg_split (what is used in do Upgrade.php)
// This way we avoid extra blank lines
// option s (PCRE_DOTALL) added
$listQuery = preg_split('/;[\n\r]+/Usm', $content);
unset($content);
// Get tables before backup
if ($this->container->getState()->getDbStep() == '1') {
$tables_after_restore = array();
foreach ($listQuery as $q) {
if (preg_match('/`(?<table>' . _DB_PREFIX_ . '[a-zA-Z0-9_-]+)`/', $q, $matches)) {
if (isset($matches['table'])) {
$tables_after_restore[$matches['table']] = $matches['table'];
}
}
}
$tables_after_restore = array_unique($tables_after_restore);
$tables_before_restore = $databaseTools->getAllTables();
$tablesToRemove = array_diff($tables_before_restore, $tables_after_restore);
if (!empty($tablesToRemove)) {
$this->container->getFileConfigurationStorage()->save($tablesToRemove, UpgradeFileNames::DB_TABLES_TO_CLEAN_LIST);
}
}
}
/** @todo : error if listQuery is not an array (that can happen if toRestoreQueryList is empty for example) */
$time_elapsed = time() - $startTime;
if (is_array($listQuery) && count($listQuery) > 0) {
$this->container->getDb()->execute('SET SESSION sql_mode = \'\'');
$this->container->getDb()->execute('SET FOREIGN_KEY_CHECKS=0');
do {
if (count($listQuery) == 0) {
if (file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST)) {
unlink($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST);
}
$restoreDbFilenamesCount = count($this->container->getState()->getRestoreDbFilenames());
if ($restoreDbFilenamesCount) {
$this->logger->info($this->translator->trans(
'Database restoration file %filename% done. %filescount% file(s) left...',
array(
'%filename%' => $this->container->getState()->getDbStep(),
'%filescount%' => $restoreDbFilenamesCount,
),
'Modules.Autoupgrade.Admin'
));
} else {
$this->logger->info($this->translator->trans('Database restoration file %1$s done.', array($this->container->getState()->getDbStep()), 'Modules.Autoupgrade.Admin'));
}
$this->stepDone = true;
$this->status = 'ok';
$this->next = 'restoreDb';
if ($restoreDbFilenamesCount === 0) {
$this->next = 'rollbackComplete';
$this->logger->info($this->translator->trans('Database has been restored.', array(), 'Modules.Autoupgrade.Admin'));
$databaseTools->cleanTablesAfterBackup($this->container->getFileConfigurationStorage()->load(UpgradeFileNames::DB_TABLES_TO_CLEAN_LIST));
$this->container->getFileConfigurationStorage()->clean(UpgradeFileNames::DB_TABLES_TO_CLEAN_LIST);
}
return true;
}
// filesForBackup already contains all the correct files
if (count($listQuery) == 0) {
continue;
}
$query = trim(array_shift($listQuery));
if (!empty($query)) {
if (!$this->container->getDb()->execute($query, false)) {
if (is_array($listQuery)) {
$listQuery = array_unshift($listQuery, $query);
}
$this->logger->error($this->translator->trans('[SQL ERROR]', array(), 'Modules.Autoupgrade.Admin') . ' ' . $query . ' - ' . $this->container->getDb()->getMsgError());
$this->logger->info($this->translator->trans('Error during database restoration', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
$this->error = true;
unlink($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST);
return false;
}
}
// note : theses queries can be too big and can cause issues for display
// else
// $this->nextQuickInfo[] = '[OK] '.$query;
$time_elapsed = time() - $startTime;
} while ($time_elapsed < $this->container->getUpgradeConfiguration()->getTimePerCall());
$queries_left = count($listQuery);
if ($queries_left > 0) {
$this->container->getFileConfigurationStorage()->save($listQuery, UpgradeFileNames::QUERIES_TO_RESTORE_LIST);
} elseif (file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST)) {
unlink($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::QUERIES_TO_RESTORE_LIST);
}
$this->stepDone = false;
$this->next = 'restoreDb';
$this->logger->info($this->translator->trans(
'%numberqueries% queries left for file %filename%...',
array(
'%numberqueries%' => $queries_left,
'%filename%' => $this->container->getState()->getDbStep(),
),
'Modules.Autoupgrade.Admin'
));
unset($query, $listQuery);
} else {
$this->stepDone = true;
$this->status = 'ok';
$this->next = 'rollbackComplete';
$this->logger->info($this->translator->trans('Database restoration done.', array(), 'Modules.Autoupgrade.Admin'));
$databaseTools->cleanTablesAfterBackup($this->container->getFileConfigurationStorage()->load(UpgradeFileNames::DB_TABLES_TO_CLEAN_LIST));
$this->container->getFileConfigurationStorage()->clean(UpgradeFileNames::DB_TABLES_TO_CLEAN_LIST);
}
return true;
}
public function init()
{
// We don't need the whole core being instanciated, only the autoloader
$this->container->initPrestaShopAutoloader();
// Loads the parameters.php file on PrestaShop 1.7, needed for accessing the database
if (file_exists($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/config/bootstrap.php')) {
require_once $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/config/bootstrap.php';
}
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
/**
* ajaxProcessRestoreFiles restore the previously saved files,
* and delete files that weren't archived.
*/
class RestoreFiles extends AbstractTask
{
public function run()
{
// loop
$this->next = 'restoreFiles';
if (!file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_FROM_ARCHIVE_LIST)
|| !file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_TO_REMOVE_LIST)) {
// cleanup current PS tree
$fromArchive = $this->container->getZipAction()->listContent($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getRestoreFilesFilename());
foreach ($fromArchive as $k => $v) {
$fromArchive[DIRECTORY_SEPARATOR . $v] = DIRECTORY_SEPARATOR . $v;
}
$this->container->getFileConfigurationStorage()->save($fromArchive, UpgradeFileNames::FILES_FROM_ARCHIVE_LIST);
// get list of files to remove
$toRemove = $this->container->getFilesystemAdapter()->listFilesToRemove();
$toRemoveOnly = array();
// let's reverse the array in order to make possible to rmdir
// remove fullpath. This will be added later in the loop.
// we do that for avoiding fullpath to be revealed in a text file
foreach ($toRemove as $k => $v) {
$vfile = str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $v);
$toRemove[] = str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $vfile);
if (!isset($fromArchive[$vfile]) && is_file($v)) {
$toRemoveOnly[$vfile] = str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $vfile);
}
}
$this->logger->debug($this->translator->trans('%s file(s) will be removed before restoring the backup files.', array(count($toRemoveOnly)), 'Modules.Autoupgrade.Admin'));
$this->container->getFileConfigurationStorage()->save($toRemoveOnly, UpgradeFileNames::FILES_TO_REMOVE_LIST);
if ($fromArchive === false || $toRemove === false) {
if (!$fromArchive) {
$this->logger->error($this->translator->trans('[ERROR] Backup file %s does not exist.', array(UpgradeFileNames::FILES_FROM_ARCHIVE_LIST), 'Modules.Autoupgrade.Admin'));
}
if (!$toRemove) {
$this->logger->error($this->translator->trans('[ERROR] File "%s" does not exist.', array(UpgradeFileNames::FILES_TO_REMOVE_LIST), 'Modules.Autoupgrade.Admin'));
}
$this->logger->info($this->translator->trans('Unable to remove upgraded files.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return false;
}
}
if (!empty($fromArchive)) {
$filepath = $this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getRestoreFilesFilename();
$destExtract = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH);
$res = $this->container->getZipAction()->extract($filepath, $destExtract);
if (!$res) {
$this->next = 'error';
$this->logger->error($this->translator->trans(
'Unable to extract file %filename% into directory %directoryname%.',
array(
'%filename%' => $filepath,
'%directoryname%' => $destExtract,
),
'Modules.Autoupgrade.Admin'
));
return false;
}
if (!empty($toRemoveOnly)) {
foreach ($toRemoveOnly as $fileToRemove) {
@unlink($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . $fileToRemove);
}
}
$this->next = 'restoreDb';
$this->logger->debug($this->translator->trans('Files restored.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Files restored. Now restoring database...', array(), 'Modules.Autoupgrade.Admin'));
return true;
}
}
public function init()
{
// Do nothing
}
}

View File

@@ -0,0 +1,98 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
/**
* First step executed during a rollback.
*/
class Rollback extends AbstractTask
{
public function run()
{
// 1st, need to analyse what was wrong.
$restoreName = $this->container->getState()->getRestoreName();
$this->container->getState()->setRestoreFilesFilename($restoreName);
$restoreDbFilenames = $this->container->getState()->getRestoreDbFilenames();
if (empty($restoreName)) {
$this->next = 'noRollbackFound';
return;
}
$files = scandir($this->container->getProperty(UpgradeContainer::BACKUP_PATH));
// find backup filenames, and be sure they exists
foreach ($files as $file) {
if (preg_match('#' . preg_quote('auto-backupfiles_' . $restoreName) . '#', $file)) {
$this->container->getState()->setRestoreFilesFilename($file);
break;
}
}
if (!is_file($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getRestoreFilesFilename())) {
$this->next = 'error';
$this->logger->error($this->translator->trans('[ERROR] File %s is missing: unable to restore files. Operation aborted.', array($this->container->getState()->getRestoreFilesFilename()), 'Modules.Autoupgrade.Admin'));
return false;
}
$files = scandir($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $restoreName);
foreach ($files as $file) {
if (preg_match('#auto-backupdb_[0-9]{6}_' . preg_quote($restoreName) . '#', $file)) {
$restoreDbFilenames[] = $file;
}
}
// order files is important !
sort($restoreDbFilenames);
$this->container->getState()->setRestoreDbFilenames($restoreDbFilenames);
if (count($restoreDbFilenames) == 0) {
$this->next = 'error';
$this->logger->error($this->translator->trans('[ERROR] No backup database files found: it would be impossible to restore the database. Operation aborted.', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
$this->next = 'restoreFiles';
$this->logger->info($this->translator->trans('Restoring files ...', array(), 'Modules.Autoupgrade.Admin'));
// remove tmp files related to restoreFiles
if (file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_FROM_ARCHIVE_LIST)) {
unlink($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_FROM_ARCHIVE_LIST);
}
if (file_exists($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_TO_REMOVE_LIST)) {
unlink($this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_TO_REMOVE_LIST);
}
}
public function init()
{
// Do nothing
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
/**
* Only displays the success message.
*/
class RollbackComplete extends AbstractTask
{
public function run()
{
$this->logger->info($this->translator->trans('Restoration process done. Congratulations! You can now reactivate your shop.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = '';
}
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\AjaxResponse;
use PrestaShop\Module\AutoUpgrade\TaskRunner\ChainedTasks;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
/**
* Execute the whole upgrade process in a single request.
*/
class AllUpgradeTasks extends ChainedTasks
{
const initialTask = 'upgradeNow';
const TASKS_WITH_RESTART = ['upgradeFiles', 'upgradeDb'];
protected $step = self::initialTask;
/**
* Customize the execution context with several options
* > action: Replace the initial step to run
* > channel: Makes a specific upgrade (minor, major etc.)
* > data: Loads an encoded array of data coming from another request.
*
* @param array $options
*/
public function setOptions(array $options)
{
if (!empty($options['action'])) {
$this->step = $options['action'];
}
if (!empty($options['channel'])) {
$this->container->getUpgradeConfiguration()->merge(array(
'channel' => $options['channel'],
// Switch on default theme if major upgrade (i.e: 1.6 -> 1.7)
'PS_AUTOUP_CHANGE_DEFAULT_THEME' => ($options['channel'] === 'major'),
));
$this->container->getUpgrader()->channel = $options['channel'];
$this->container->getUpgrader()->checkPSVersion(true);
}
if (!empty($options['data'])) {
$this->container->getState()->importFromEncodedData($options['data']);
}
}
/**
* For some steps, we may require a new request to be made.
* For instance, in case of obsolete autoloader or loaded classes after a file copy.
*/
protected function checkIfRestartRequested(AjaxResponse $response)
{
if (parent::checkIfRestartRequested($response)) {
return true;
}
if (!$response->getStepDone()) {
return false;
}
if (!in_array($this->step, self::TASKS_WITH_RESTART)) {
return false;
}
$this->logger->info('Restart requested. Please run the following command to continue your upgrade:');
$args = $_SERVER['argv'];
foreach ($args as $key => $arg) {
if (strpos($arg, '--data') === 0) {
unset($args[$key]);
}
}
$this->logger->info('$ ' . implode(' ', $args) . ' --action=' . $response->getNext() . ' --data=' . $this->getEncodedResponse());
return true;
}
/**
* Set default config on first run.
*/
public function init()
{
if ($this->step === self::initialTask) {
parent::init();
$this->container->getState()->initDefault(
$this->container->getUpgrader(),
$this->container->getProperty(UpgradeContainer::PS_ROOT_PATH),
$this->container->getProperty(UpgradeContainer::PS_VERSION));
}
}
}

View File

@@ -0,0 +1,297 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
class BackupDb extends AbstractTask
{
public function run()
{
if (!$this->container->getUpgradeConfiguration()->get('PS_AUTOUP_BACKUP')) {
$this->stepDone = true;
$this->container->getState()->setDbStep(0);
$this->logger->info($this->translator->trans('Database backup skipped. Now upgrading files...', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'upgradeFiles';
return true;
}
$timeAllowed = $this->container->getUpgradeConfiguration()->getNumberOfFilesPerCall();
$relative_backup_path = str_replace(_PS_ROOT_DIR_, '', $this->container->getProperty(UpgradeContainer::BACKUP_PATH));
$report = '';
if (!\ConfigurationTest::test_dir($relative_backup_path, false, $report)) {
$this->logger->error($this->translator->trans('Backup directory is not writable (%path%).', array('%path%' => $this->container->getProperty(UpgradeContainer::BACKUP_PATH)), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
$this->error = true;
return false;
}
$this->stepDone = false;
$this->next = 'backupDb';
$start_time = time();
$time_elapsed = 0;
$ignore_stats_table = array(_DB_PREFIX_ . 'connections',
_DB_PREFIX_ . 'connections_page',
_DB_PREFIX_ . 'connections_source',
_DB_PREFIX_ . 'guest',
_DB_PREFIX_ . 'statssearch', );
// INIT LOOP
if (!$this->container->getFileConfigurationStorage()->exists(UpgradeFileNames::DB_TABLES_TO_BACKUP_LIST)) {
if (!is_dir($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getBackupName())) {
mkdir($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getBackupName());
}
$this->container->getState()->setDbStep(0);
$tablesToBackup = $this->container->getDb()->executeS('SHOW TABLES LIKE "' . _DB_PREFIX_ . '%"', true, false);
$this->container->getFileConfigurationStorage()->save($tablesToBackup, UpgradeFileNames::DB_TABLES_TO_BACKUP_LIST);
}
if (!isset($tablesToBackup)) {
$tablesToBackup = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::DB_TABLES_TO_BACKUP_LIST);
}
$found = 0;
$views = '';
$fp = false;
$backupfile = null;
// MAIN BACKUP LOOP //
$written = 0;
do {
if (null !== $this->container->getState()->getBackupTable()) {
// only insert (schema already done)
$table = $this->container->getState()->getBackupTable();
$lines = $this->container->getState()->getBackupLines();
} else {
if (count($tablesToBackup) == 0) {
break;
}
$table = current(array_shift($tablesToBackup));
$this->container->getState()->setBackupLoopLimit(0);
}
// Skip tables which do not start with _DB_PREFIX_
if (strlen($table) <= strlen(_DB_PREFIX_) || strncmp($table, _DB_PREFIX_, strlen(_DB_PREFIX_)) != 0) {
continue;
}
// Ignore stat tables
if (in_array($table, $ignore_stats_table)) {
continue;
}
if ($written == 0 || $written > $this->container->getUpgradeConfiguration()->getMaxSizeToWritePerCall()) {
// increment dbStep will increment filename each time here
$this->container->getState()->setDbStep($this->container->getState()->getDbStep() + 1);
// new file, new step
$written = 0;
if (is_resource($fp)) {
fclose($fp);
}
$backupfile = $this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $this->container->getState()->getBackupName() . DIRECTORY_SEPARATOR . $this->container->getState()->getBackupDbFilename();
$backupfile = preg_replace('#_XXXXXX_#', '_' . str_pad($this->container->getState()->getDbStep(), 6, '0', STR_PAD_LEFT) . '_', $backupfile);
// start init file
// Figure out what compression is available and open the file
if (file_exists($backupfile)) {
$this->next = 'error';
$this->error = true;
$this->logger->error($this->translator->trans('Backup file %s already exists. Operation aborted.', array($backupfile), 'Modules.Autoupgrade.Admin'));
}
if (function_exists('bzopen')) {
$backupfile .= '.bz2';
$fp = bzopen($backupfile, 'w');
} elseif (function_exists('gzopen')) {
$backupfile .= '.gz';
$fp = gzopen($backupfile, 'w');
} else {
$fp = fopen($backupfile, 'w');
}
if ($fp === false) {
$this->logger->error($this->translator->trans('Unable to create backup database file %s.', array(addslashes($backupfile)), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
$this->error = true;
$this->logger->info($this->translator->trans('Error during database backup.', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
$written += fwrite($fp, '/* Backup ' . $this->container->getState()->getDbStep() . ' for ' . Tools14::getHttpHost(false, false) . __PS_BASE_URI__ . "\n * at " . date('r') . "\n */\n");
$written += fwrite($fp, "\n" . 'SET SESSION sql_mode = \'\';' . "\n\n");
$written += fwrite($fp, "\n" . 'SET NAMES \'utf8\';' . "\n\n");
$written += fwrite($fp, "\n" . 'SET FOREIGN_KEY_CHECKS=0;' . "\n\n");
// end init file
}
// start schema : drop & create table only
if (null === $this->container->getState()->getBackupTable()) {
// Export the table schema
$schema = $this->container->getDb()->executeS('SHOW CREATE TABLE `' . $table . '`', true, false);
if (count($schema) != 1 ||
!(isset($schema[0]['Table'], $schema[0]['Create Table'])
|| isset($schema[0]['View'], $schema[0]['Create View']))) {
fclose($fp);
if (file_exists($backupfile)) {
unlink($backupfile);
}
$this->logger->error($this->translator->trans('An error occurred while backing up. Unable to obtain the schema of %s', array($table), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Error during database backup.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
$this->error = true;
return false;
}
// case view
if (isset($schema[0]['View'])) {
$views .= '/* Scheme for view' . $schema[0]['View'] . " */\n";
// If some *upgrade* transform a table in a view, drop both just in case
$views .= 'DROP VIEW IF EXISTS `' . $schema[0]['View'] . '`;' . "\n";
$views .= 'DROP TABLE IF EXISTS `' . $schema[0]['View'] . '`;' . "\n";
$views .= preg_replace('#DEFINER=[^\s]+\s#', 'DEFINER=CURRENT_USER ', $schema[0]['Create View']) . ";\n\n";
$written += fwrite($fp, "\n" . $views);
$ignore_stats_table[] = $schema[0]['View'];
}
// case table
elseif (isset($schema[0]['Table'])) {
// Case common table
$written += fwrite($fp, '/* Scheme for table ' . $schema[0]['Table'] . " */\n");
if (!in_array($schema[0]['Table'], $ignore_stats_table)) {
// If some *upgrade* transform a table in a view, drop both just in case
$written += fwrite($fp, 'DROP VIEW IF EXISTS `' . $schema[0]['Table'] . '`;' . "\n");
$written += fwrite($fp, 'DROP TABLE IF EXISTS `' . $schema[0]['Table'] . '`;' . "\n");
// CREATE TABLE
$written += fwrite($fp, $schema[0]['Create Table'] . ";\n\n");
}
// schema created, now we need to create the missing vars
$this->container->getState()->setBackupTable($table);
$lines = explode("\n", $schema[0]['Create Table']);
$this->container->getState()->setBackupLines($lines);
}
}
// end of schema
// POPULATE TABLE
if (!in_array($table, $ignore_stats_table)) {
do {
$backup_loop_limit = $this->container->getState()->getBackupLoopLimit();
$data = $this->container->getDb()->executeS('SELECT * FROM `' . $table . '` LIMIT ' . (int) $backup_loop_limit . ',200', false, false);
$this->container->getState()->setBackupLoopLimit($this->container->getState()->getBackupLoopLimit() + 200);
$sizeof = $this->container->getDb()->numRows();
if ($data && ($sizeof > 0)) {
// Export the table data
$written += fwrite($fp, 'INSERT INTO `' . $table . "` VALUES\n");
$i = 1;
while ($row = $this->container->getDb()->nextRow($data)) {
// this starts a row
$s = '(';
foreach ($row as $field => $value) {
if ($value === null) {
$s .= 'NULL,';
} else {
$s .= "'" . $this->container->getDb()->escape($value, true) . "',";
}
}
$s = rtrim($s, ',');
if ($i < $sizeof) {
$s .= "),\n";
} else {
$s .= ");\n";
}
$written += fwrite($fp, $s);
++$i;
}
$time_elapsed = time() - $start_time;
} else {
$this->container->getState()->setBackupTable(null);
break;
}
} while (($time_elapsed < $timeAllowed) && ($written < $this->container->getUpgradeConfiguration()->getMaxSizeToWritePerCall()));
}
++$found;
$time_elapsed = time() - $start_time;
$this->logger->debug($this->translator->trans('%s table has been saved.', array($table), 'Modules.Autoupgrade.Admin'));
} while (($time_elapsed < $timeAllowed) && ($written < $this->container->getUpgradeConfiguration()->getMaxSizeToWritePerCall()));
// end of loop
if (is_resource($fp)) {
$written += fwrite($fp, "\n" . 'SET FOREIGN_KEY_CHECKS=1;' . "\n\n");
fclose($fp);
$fp = null;
}
$this->container->getFileConfigurationStorage()->save($tablesToBackup, UpgradeFileNames::DB_TABLES_TO_BACKUP_LIST);
if (count($tablesToBackup) > 0) {
$this->logger->debug($this->translator->trans('%s tables have been saved.', array($found), 'Modules.Autoupgrade.Admin'));
$this->next = 'backupDb';
$this->stepDone = false;
if (count($tablesToBackup)) {
$this->logger->info($this->translator->trans('Database backup: %s table(s) left...', array(count($tablesToBackup)), 'Modules.Autoupgrade.Admin'));
}
return true;
}
if ($found == 0 && !empty($backupfile)) {
if (file_exists($backupfile)) {
unlink($backupfile);
}
$this->logger->error($this->translator->trans('No valid tables were found to back up. Backup of file %s canceled.', array($backupfile), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Error during database backup for file %s.', array($backupfile), 'Modules.Autoupgrade.Admin'));
$this->error = true;
return false;
} else {
$this->container->getState()
->setBackupLoopLimit(null)
->setBackupLines(null)
->setBackupTable(null);
if ($found) {
$this->logger->info($this->translator->trans('%s tables have been saved.', array($found), 'Modules.Autoupgrade.Admin'));
}
$this->stepDone = true;
// reset dbStep at the end of this step
$this->container->getState()->setDbStep(0);
$this->logger->info($this->translator->trans('Database backup done in filename %s. Now upgrading files...', array($this->container->getState()->getBackupName()), 'Modules.Autoupgrade.Admin'));
$this->next = 'upgradeFiles';
return true;
}
}
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
class BackupFiles extends AbstractTask
{
public function run()
{
if (!$this->container->getUpgradeConfiguration()->get('PS_AUTOUP_BACKUP')) {
$this->stepDone = true;
$this->next = 'backupDb';
$this->logger->info('File backup skipped.');
return true;
}
$this->stepDone = false;
$backupFilesFilename = $this->container->getState()->getBackupFilesFilename();
if (empty($backupFilesFilename)) {
$this->next = 'error';
$this->error = true;
$this->logger->info($this->translator->trans('Error during backupFiles', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->error($this->translator->trans('[ERROR] backupFiles filename has not been set', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
if (!$this->container->getFileConfigurationStorage()->exists(UpgradeFileNames::FILES_TO_BACKUP_LIST)) {
/** @todo : only add files and dir listed in "originalPrestashopVersion" list */
$filesToBackup = $this->container->getFilesystemAdapter()->listFilesInDir($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), 'backup', false);
$this->container->getFileConfigurationStorage()->save($filesToBackup, UpgradeFileNames::FILES_TO_BACKUP_LIST);
if (count($filesToBackup)) {
$this->logger->debug($this->translator->trans('%s Files to backup.', array(count($filesToBackup)), 'Modules.Autoupgrade.Admin'));
}
// delete old backup, create new
if (!empty($backupFilesFilename) && file_exists($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $backupFilesFilename)) {
unlink($this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $backupFilesFilename);
}
$this->logger->debug($this->translator->trans('Backup files initialized in %s', array($backupFilesFilename), 'Modules.Autoupgrade.Admin'));
}
$filesToBackup = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::FILES_TO_BACKUP_LIST);
$this->next = 'backupFiles';
if (is_array($filesToBackup) && count($filesToBackup)) {
$this->logger->info($this->translator->trans('Backup files in progress. %d files left', array(count($filesToBackup)), 'Modules.Autoupgrade.Admin'));
$this->stepDone = false;
$res = $this->container->getZipAction()->compress($filesToBackup, $this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $backupFilesFilename);
if (!$res) {
$this->next = 'error';
$this->logger->info($this->translator->trans('Unable to open archive', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
$this->container->getFileConfigurationStorage()->save($filesToBackup, UpgradeFileNames::FILES_TO_BACKUP_LIST);
}
if (count($filesToBackup) <= 0) {
$this->stepDone = true;
$this->status = 'ok';
$this->next = 'backupDb';
$this->logger->debug($this->translator->trans('All files have been added to archive.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('All files saved. Now backing up database', array(), 'Modules.Autoupgrade.Admin'));
}
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
/**
* Clean the database from unwanted entries.
*/
class CleanDatabase extends AbstractTask
{
public function run()
{
// Clean tabs order
foreach ($this->container->getDb()->ExecuteS('SELECT DISTINCT id_parent FROM ' . _DB_PREFIX_ . 'tab') as $parent) {
$i = 1;
foreach ($this->container->getDb()->ExecuteS('SELECT id_tab FROM ' . _DB_PREFIX_ . 'tab WHERE id_parent = ' . (int) $parent['id_parent'] . ' ORDER BY IF(class_name IN ("AdminHome", "AdminDashboard"), 1, 2), position ASC') as $child) {
$this->container->getDb()->Execute('UPDATE ' . _DB_PREFIX_ . 'tab SET position = ' . (int) ($i++) . ' WHERE id_tab = ' . (int) $child['id_tab'] . ' AND id_parent = ' . (int) $parent['id_parent']);
}
}
$this->status = 'ok';
$this->next = 'upgradeComplete';
$this->logger->info($this->translator->trans('The database has been cleaned.', array(), 'Modules.Autoupgrade.Admin'));
}
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
/**
* Download PrestaShop archive according to the chosen channel.
*/
class Download extends AbstractTask
{
public function run()
{
if (!\ConfigurationTest::test_fopen() && !\ConfigurationTest::test_curl()) {
$this->logger->error($this->translator->trans('You need allow_url_fopen or cURL enabled for automatic download to work. You can also manually upload it in filepath %s.', array($this->container->getFilePath()), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return;
}
$upgrader = $this->container->getUpgrader();
// regex optimization
preg_match('#([0-9]+\.[0-9]+)(?:\.[0-9]+){1,2}#', _PS_VERSION_, $matches);
$upgrader->channel = $this->container->getUpgradeConfiguration()->get('channel');
$upgrader->branch = $matches[1];
if ($this->container->getUpgradeConfiguration()->get('channel') == 'private' && !$this->container->getUpgradeConfiguration()->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
if ($upgrader->channel == 'private') {
$upgrader->link = $this->container->getUpgradeConfiguration()->get('private_release_link');
$upgrader->md5 = $this->container->getUpgradeConfiguration()->get('private_release_md5');
}
$this->logger->debug($this->translator->trans('Downloading from %s', array($upgrader->link), 'Modules.Autoupgrade.Admin'));
$this->logger->debug($this->translator->trans('File will be saved in %s', array($this->container->getFilePath()), 'Modules.Autoupgrade.Admin'));
if (file_exists($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH))) {
FilesystemAdapter::deleteDirectory($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH), false);
$this->logger->debug($this->translator->trans('Download directory has been emptied', array(), 'Modules.Autoupgrade.Admin'));
}
$report = '';
$relative_download_path = str_replace(_PS_ROOT_DIR_, '', $this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH));
if (\ConfigurationTest::test_dir($relative_download_path, false, $report)) {
$res = $upgrader->downloadLast($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH), $this->container->getProperty(UpgradeContainer::ARCHIVE_FILENAME));
if ($res) {
$md5file = md5_file(realpath($this->container->getProperty(UpgradeContainer::ARCHIVE_FILEPATH)));
if ($md5file == $upgrader->md5) {
$this->next = 'unzip';
$this->logger->debug($this->translator->trans('Download complete.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Download complete. Now extracting...', array(), 'Modules.Autoupgrade.Admin'));
} else {
$this->logger->error($this->translator->trans('Download complete but MD5 sum does not match (%s).', array($md5file), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Download complete but MD5 sum does not match (%s). Operation aborted.', array($md5file), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
}
} else {
if ($upgrader->channel == 'private') {
$this->logger->error($this->translator->trans('Error during download. The private key may be incorrect.', array(), 'Modules.Autoupgrade.Admin'));
} else {
$this->logger->error($this->translator->trans('Error during download', array(), 'Modules.Autoupgrade.Admin'));
}
$this->next = 'error';
}
} else {
$this->logger->error($this->translator->trans('Download directory %s is not writable.', array($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH)), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
}
}
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use Symfony\Component\Filesystem\Filesystem;
/**
* Remove all sample files from release archive.
*/
class RemoveSamples extends AbstractTask
{
public function run()
{
$this->stepDone = false;
$this->next = 'removeSamples';
$removeList = $this->container->getState()->getRemoveList();
$latestPath = $this->container->getProperty(UpgradeContainer::LATEST_PATH);
// remove all sample pics in img subdir
// This part runs at the first call of this step
if (null === $removeList) {
if (!$this->container->getFilesystemAdapter()->isReleaseValid($latestPath)) {
$this->logger->error($this->translator->trans('Could not assert the folder %s contains a valid PrestaShop release, exiting.', array($latestPath), 'Modules.Autoupgrade.Admin'));
$this->logger->error($this->translator->trans('A file may be missing, or the release is stored in a subfolder by mistake.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return;
}
$removeList = $this->container->getFilesystemAdapter()->listSampleFilesFromArray(array(
array('path' => $latestPath . '/img/c', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/cms', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/l', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/m', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/os', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/p', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/s', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/scenes', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/st', 'filter' => '.jpg'),
array('path' => $latestPath . '/img/su', 'filter' => '.jpg'),
array('path' => $latestPath . '/img', 'filter' => '404.gif'),
array('path' => $latestPath . '/img', 'filter' => 'favicon.ico'),
array('path' => $latestPath . '/img', 'filter' => 'logo.jpg'),
array('path' => $latestPath . '/img', 'filter' => 'logo_stores.gif'),
array('path' => $latestPath . '/modules/editorial', 'filter' => 'homepage_logo.jpg'),
// remove all override present in the archive
array('path' => $latestPath . '/override', 'filter' => '.php'),
));
$this->container->getState()->setRemoveList($removeList);
if (count($removeList)) {
$this->logger->debug(
$this->translator->trans('Starting to remove %s sample files',
array(count($removeList)), 'Modules.Autoupgrade.Admin'));
}
}
$filesystem = new Filesystem();
for ($i = 0; $i < $this->container->getUpgradeConfiguration()->getNumberOfFilesPerCall() && 0 < count($removeList); ++$i) {
$file = array_shift($removeList);
try {
$filesystem->remove($file);
} catch (\Exception $e) {
$this->next = 'error';
$this->logger->error($this->translator->trans(
'Error while removing item %itemname%, %itemscount% items left.',
array(
'%itemname%' => $file,
'%itemscount%' => count($removeList),
),
'Modules.Autoupgrade.Admin'
));
return false;
}
if (count($removeList)) {
$this->logger->debug($this->translator->trans(
'%itemname% item removed. %itemscount% items left.',
array(
'%itemname%' => $file,
'%itemscount%' => count($removeList),
),
'Modules.Autoupgrade.Admin'
));
}
}
$this->container->getState()->setRemoveList($removeList);
if (0 >= count($removeList)) {
$this->stepDone = true;
$this->next = 'backupFiles';
$this->logger->info(
$this->translator->trans(
'All sample files removed. Now backing up files.',
array(),
'Modules.Autoupgrade.Admin'
));
if ($this->container->getUpgradeConfiguration()->get('skip_backup')) {
$this->next = 'upgradeFiles';
$this->logger->info(
$this->translator->trans(
'All sample files removed. Backup process skipped. Now upgrading files.',
array(),
'Modules.Autoupgrade.Admin'
));
}
}
return true;
}
}

View File

@@ -0,0 +1,125 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use Symfony\Component\Filesystem\Filesystem;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
/**
* extract chosen version into $this->upgradeClass->latestPath directory.
*/
class Unzip extends AbstractTask
{
public function run()
{
$filepath = $this->container->getFilePath();
$destExtract = $this->container->getProperty(UpgradeContainer::LATEST_PATH);
if (file_exists($destExtract)) {
FilesystemAdapter::deleteDirectory($destExtract, false);
$this->logger->debug($this->translator->trans('"/latest" directory has been emptied', array(), 'Modules.Autoupgrade.Admin'));
}
$relative_extract_path = str_replace(_PS_ROOT_DIR_, '', $destExtract);
$report = '';
if (!\ConfigurationTest::test_dir($relative_extract_path, false, $report)) {
$this->logger->error($this->translator->trans('Extraction directory %s is not writable.', array($destExtract), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
$this->error = true;
return false;
}
$res = $this->container->getZipAction()->extract($filepath, $destExtract);
if (!$res) {
$this->next = 'error';
$this->error = true;
$this->logger->info($this->translator->trans(
'Unable to extract %filepath% file into %destination% folder...',
array(
'%filepath%' => $filepath,
'%destination%' => $destExtract,
),
'Modules.Autoupgrade.Admin'
));
return false;
}
// From PrestaShop 1.7, we zip all the files in another package
// which must be unzipped too
$newZip = $destExtract . DIRECTORY_SEPARATOR . 'prestashop.zip';
if (file_exists($newZip)) {
@unlink($destExtract . DIRECTORY_SEPARATOR . '/index.php');
@unlink($destExtract . DIRECTORY_SEPARATOR . '/Install_PrestaShop.html');
$subRes = $this->container->getZipAction()->extract($newZip, $destExtract);
if (!$subRes) {
$this->next = 'error';
$this->logger->info($this->translator->trans(
'Unable to extract %filepath% file into %destination% folder...',
array(
'%filepath%' => $filepath,
'%destination%' => $destExtract,
),
'Modules.Autoupgrade.Admin'
));
return false;
}
} else {
$filesystem = new Filesystem();
$zipSubfolder = $destExtract . '/prestashop/';
if (!is_dir($zipSubfolder)) {
$this->next = 'error';
$this->logger->error(
$this->translator->trans('No prestashop/ folder found in the ZIP file. Aborting.', array(), 'Modules.Autoupgrade.Admin'));
return;
}
// /!\ On PS 1.6, files are unzipped in a subfolder PrestaShop
foreach (scandir($zipSubfolder) as $file) {
if ($file[0] === '.') {
continue;
}
$filesystem->rename($zipSubfolder . $file, $destExtract . '/' . $file);
}
}
// Unsetting to force listing
$this->container->getState()->setRemoveList(null);
$this->next = 'removeSamples';
$this->logger->info($this->translator->trans('File extraction complete. Removing sample files...', array(), 'Modules.Autoupgrade.Admin'));
@unlink($newZip);
return true;
}
}

View File

@@ -0,0 +1,66 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use Configuration;
/**
* Ends the upgrade process and displays the success message.
*/
class UpgradeComplete extends AbstractTask
{
public function run()
{
$this->logger->info($this->container->getState()->getWarningExists() ?
$this->translator->trans('Upgrade process done, but some warnings have been found.', array(), 'Modules.Autoupgrade.Admin') :
$this->translator->trans('Upgrade process done. Congratulations! You can now reactivate your shop.', array(), 'Modules.Autoupgrade.Admin')
);
$this->next = '';
if ($this->container->getUpgradeConfiguration()->get('channel') != 'archive' && file_exists($this->container->getFilePath()) && unlink($this->container->getFilePath())) {
$this->logger->debug($this->translator->trans('%s removed', array($this->container->getFilePath()), 'Modules.Autoupgrade.Admin'));
} elseif (is_file($this->container->getFilePath())) {
$this->logger->debug('<strong>' . $this->translator->trans('Please remove %s by FTP', array($this->container->getFilePath()), 'Modules.Autoupgrade.Admin') . '</strong>');
}
if ($this->container->getUpgradeConfiguration()->get('channel') != 'directory' && file_exists($this->container->getProperty(UpgradeContainer::LATEST_PATH)) && FilesystemAdapter::deleteDirectory($this->container->getProperty(UpgradeContainer::LATEST_PATH))) {
$this->logger->debug($this->translator->trans('%s removed', array($this->container->getProperty(UpgradeContainer::LATEST_PATH)), 'Modules.Autoupgrade.Admin'));
} elseif (is_dir($this->container->getProperty(UpgradeContainer::LATEST_PATH))) {
$this->logger->debug('<strong>' . $this->translator->trans('Please remove %s by FTP', array($this->container->getProperty(UpgradeContainer::LATEST_PATH)), 'Modules.Autoupgrade.Admin') . '</strong>');
}
// Reinit config
Configuration::deleteByName('PS_AUTOUP_IGNORE_REQS');
// removing temporary files
$this->container->getFileConfigurationStorage()->cleanAll();
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\CoreUpgrader\CoreUpgrader16;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\CoreUpgrader\CoreUpgrader17;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\SettingsFileWriter;
class UpgradeDb extends AbstractTask
{
public function run()
{
try {
$this->getCoreUpgrader()->doUpgrade();
} catch (UpgradeException $e) {
$this->next = 'error';
$this->error = true;
foreach ($e->getQuickInfos() as $log) {
$this->logger->debug($log);
}
$this->logger->error($this->translator->trans('Error during database upgrade. You may need to restore your database.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->error($e->getMessage());
return false;
}
$this->next = 'upgradeModules';
$this->logger->info($this->translator->trans('Database upgraded. Now upgrading your Addons modules...', array(), 'Modules.Autoupgrade.Admin'));
return true;
}
public function getCoreUpgrader()
{
if (version_compare($this->container->getState()->getInstallVersion(), '1.7.0.0', '<=')) {
return new CoreUpgrader16($this->container, $this->logger);
}
return new CoreUpgrader17($this->container, $this->logger);
}
public function init()
{
$this->container->getCacheCleaner()->cleanFolders();
// Migrating settings file
$this->container->initPrestaShopAutoloader();
(new SettingsFileWriter($this->translator))->migrateSettingsFile($this->logger);
parent::init();
}
}

View File

@@ -0,0 +1,311 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
class UpgradeFiles extends AbstractTask
{
private $destUpgradePath;
public function run()
{
// The first call must init the list of files be upgraded
if (!$this->container->getFileConfigurationStorage()->exists(UpgradeFileNames::FILES_TO_UPGRADE_LIST)) {
return $this->warmUp();
}
// later we could choose between _PS_ROOT_DIR_ or _PS_TEST_DIR_
$this->destUpgradePath = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH);
$this->next = 'upgradeFiles';
$filesToUpgrade = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::FILES_TO_UPGRADE_LIST);
if (!is_array($filesToUpgrade)) {
$this->next = 'error';
$this->logger->error($this->translator->trans('filesToUpgrade is not an array', array(), 'Modules.Autoupgrade.Admin'));
return false;
}
// @TODO : does not upgrade files in modules, translations if they have not a correct md5 (or crc32, or whatever) from previous version
for ($i = 0; $i < $this->container->getUpgradeConfiguration()->getNumberOfFilesPerCall(); ++$i) {
if (count($filesToUpgrade) <= 0) {
$this->next = 'upgradeDb';
if (file_exists(UpgradeFileNames::FILES_TO_UPGRADE_LIST)) {
unlink(UpgradeFileNames::FILES_TO_UPGRADE_LIST);
}
$this->logger->info($this->translator->trans('All files upgraded. Now upgrading database...', array(), 'Modules.Autoupgrade.Admin'));
$this->stepDone = true;
break;
}
$file = array_shift($filesToUpgrade);
if (!$this->upgradeThisFile($file)) {
// put the file back to the begin of the list
$this->next = 'error';
$this->logger->error($this->translator->trans('Error when trying to upgrade file %s.', array($file), 'Modules.Autoupgrade.Admin'));
break;
}
}
$this->container->getFileConfigurationStorage()->save($filesToUpgrade, UpgradeFileNames::FILES_TO_UPGRADE_LIST);
if (count($filesToUpgrade) > 0) {
$this->logger->info($this->translator->trans('%s files left to upgrade.', array(count($filesToUpgrade)), 'Modules.Autoupgrade.Admin'));
$this->stepDone = false;
}
return true;
}
/**
* list files to upgrade and return it as array
* TODO: This method needs probably to be moved in FilesystemAdapter.
*
* @param string $dir
*
* @return array|false Number of files found, or false if param is not a folder
*/
protected function listFilesToUpgrade($dir)
{
$list = array();
if (!is_dir($dir)) {
$this->logger->error($this->translator->trans('[ERROR] %s does not exist or is not a directory.', array($dir), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Nothing has been extracted. It seems the unzipping step has been skipped.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return false;
}
$allFiles = scandir($dir);
foreach ($allFiles as $file) {
$fullPath = $dir . DIRECTORY_SEPARATOR . $file;
if ($this->container->getFilesystemAdapter()->isFileSkipped(
$file,
$fullPath,
'upgrade',
$this->container->getProperty(UpgradeContainer::LATEST_PATH)
)) {
if (!in_array($file, array('.', '..'))) {
$this->logger->debug($this->translator->trans('File %s is preserved', array($file), 'Modules.Autoupgrade.Admin'));
}
continue;
}
$list[] = str_replace($this->container->getProperty(UpgradeContainer::LATEST_PATH), '', $fullPath);
if (is_dir($fullPath) && strpos($dir . DIRECTORY_SEPARATOR . $file, 'install') === false) {
$list = array_merge($list, $this->listFilesToUpgrade($fullPath));
}
}
return $list;
}
/**
* upgradeThisFile.
*
* @param mixed $file
*/
public function upgradeThisFile($file)
{
// translations_custom and mails_custom list are currently not used
// later, we could handle customization with some kind of diff functions
// for now, just copy $file in str_replace($this->latestRootDir,_PS_ROOT_DIR_)
$orig = $this->container->getProperty(UpgradeContainer::LATEST_PATH) . $file;
$dest = $this->destUpgradePath . $file;
if ($this->container->getFilesystemAdapter()->isFileSkipped($file, $dest, 'upgrade')) {
$this->logger->debug($this->translator->trans('%s ignored', array($file), 'Modules.Autoupgrade.Admin'));
return true;
}
if (is_dir($orig)) {
// if $dest is not a directory (that can happen), just remove that file
if (!is_dir($dest) && file_exists($dest)) {
unlink($dest);
$this->logger->debug($this->translator->trans('[WARNING] File %1$s has been deleted.', array($file), 'Modules.Autoupgrade.Admin'));
}
if (!file_exists($dest)) {
if (mkdir($dest)) {
$this->logger->debug($this->translator->trans('Directory %1$s created.', array($file), 'Modules.Autoupgrade.Admin'));
return true;
} else {
$this->next = 'error';
$this->logger->error($this->translator->trans('Error while creating directory %s.', array($dest), 'Modules.Autoupgrade.Admin'));
return false;
}
} else { // directory already exists
$this->logger->debug($this->translator->trans('Directory %s already exists.', array($file), 'Modules.Autoupgrade.Admin'));
return true;
}
} elseif (is_file($orig)) {
$translationAdapter = $this->container->getTranslationAdapter();
if ($translationAdapter->isTranslationFile($file) && file_exists($dest)) {
$type_trad = $translationAdapter->getTranslationFileType($file);
if ($translationAdapter->mergeTranslationFile($orig, $dest, $type_trad)) {
$this->logger->info($this->translator->trans('[TRANSLATION] The translation files have been merged into file %s.', array($dest), 'Modules.Autoupgrade.Admin'));
return true;
}
$this->logger->warning($this->translator->trans(
'[TRANSLATION] The translation files have not been merged into file %filename%. Switch to copy %filename%.',
array('%filename%' => $dest),
'Modules.Autoupgrade.Admin'
));
}
// upgrade exception were above. This part now process all files that have to be upgraded (means to modify or to remove)
// delete before updating (and this will also remove deprecated files)
if (copy($orig, $dest)) {
$this->logger->debug($this->translator->trans('Copied %1$s.', array($file), 'Modules.Autoupgrade.Admin'));
return true;
} else {
$this->next = 'error';
$this->logger->error($this->translator->trans('Error while copying file %s', array($file), 'Modules.Autoupgrade.Admin'));
return false;
}
} elseif (is_file($dest)) {
if (file_exists($dest)) {
unlink($dest);
}
$this->logger->debug(sprintf('removed file %1$s.', $file));
return true;
} elseif (is_dir($dest)) {
if (strpos($dest, DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR) === false) {
FilesystemAdapter::deleteDirectory($dest, true);
}
$this->logger->debug(sprintf('removed dir %1$s.', $file));
return true;
} else {
return true;
}
}
/**
* First call of this task needs a warmup, where we load the files list to be upgraded.
*
* @return bool
*/
protected function warmUp()
{
$newReleasePath = $this->container->getProperty(UpgradeContainer::LATEST_PATH);
if (!$this->container->getFilesystemAdapter()->isReleaseValid($newReleasePath)) {
$this->logger->error($this->translator->trans('Could not assert the folder %s contains a valid PrestaShop release, exiting.', array($newReleasePath), 'Modules.Autoupgrade.Admin'));
$this->logger->error($this->translator->trans('A file may be missing, or the release is stored in a subfolder by mistake.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return false;
}
$admin_dir = str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . DIRECTORY_SEPARATOR, '', $this->container->getProperty(UpgradeContainer::PS_ADMIN_PATH));
if (file_exists($newReleasePath . DIRECTORY_SEPARATOR . 'admin')) {
rename($newReleasePath . DIRECTORY_SEPARATOR . 'admin', $newReleasePath . DIRECTORY_SEPARATOR . $admin_dir);
} elseif (file_exists($newReleasePath . DIRECTORY_SEPARATOR . 'admin-dev')) {
rename($newReleasePath . DIRECTORY_SEPARATOR . 'admin-dev', $newReleasePath . DIRECTORY_SEPARATOR . $admin_dir);
}
if (file_exists($newReleasePath . DIRECTORY_SEPARATOR . 'install-dev')) {
rename($newReleasePath . DIRECTORY_SEPARATOR . 'install-dev', $newReleasePath . DIRECTORY_SEPARATOR . 'install');
}
// list saved in UpgradeFileNames::toUpgradeFileList
// get files differences (previously generated)
$admin_dir = trim(str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $this->container->getProperty(UpgradeContainer::PS_ADMIN_PATH)), DIRECTORY_SEPARATOR);
$filepath_list_diff = $this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_DIFF_LIST;
$list_files_diff = array();
if (file_exists($filepath_list_diff)) {
$list_files_diff = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::FILES_DIFF_LIST);
// only keep list of files to delete. The modified files will be listed with _listFilesToUpgrade
$list_files_diff = $list_files_diff['deleted'];
foreach ($list_files_diff as $k => $path) {
if (preg_match('#autoupgrade#', $path)) {
unset($list_files_diff[$k]);
} else {
$list_files_diff[$k] = str_replace('/' . 'admin', '/' . $admin_dir, $path);
}
} // do not replace by DIRECTORY_SEPARATOR
}
$list_files_to_upgrade = $this->listFilesToUpgrade($newReleasePath);
if (false === $list_files_to_upgrade) {
return false;
}
// also add files to remove
$list_files_to_upgrade = array_merge($list_files_diff, $list_files_to_upgrade);
$filesToMoveToTheBeginning = array(
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'ClassLoader.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_classmap.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_files.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_namespaces.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_psr4.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_real.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_static.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'include_paths.php',
DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer',
DIRECTORY_SEPARATOR . 'vendor',
);
foreach ($filesToMoveToTheBeginning as $file) {
if ($key = array_search($file, $list_files_to_upgrade)) {
unset($list_files_to_upgrade[$key]);
$list_files_to_upgrade = array_merge(array($file), $list_files_to_upgrade);
}
}
// save in a serialized array in UpgradeFileNames::toUpgradeFileList
$this->container->getFileConfigurationStorage()->save($list_files_to_upgrade, UpgradeFileNames::FILES_TO_UPGRADE_LIST);
$total_files_to_upgrade = count($list_files_to_upgrade);
if ($total_files_to_upgrade == 0) {
$this->logger->error($this->translator->trans('[ERROR] Unable to find files to upgrade.', array(), 'Modules.Autoupgrade.Admin'));
$this->next = 'error';
return false;
}
$this->logger->info($this->translator->trans('%s files will be upgraded.', array($total_files_to_upgrade), 'Modules.Autoupgrade.Admin'));
$this->next = 'upgradeFiles';
$this->stepDone = false;
return true;
}
public function init()
{
// Do nothing. Overrides parent init for avoiding core to be loaded here.
}
}

View File

@@ -0,0 +1,181 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
/**
* Upgrade all partners modules according to the installed prestashop version.
*/
class UpgradeModules extends AbstractTask
{
public function run()
{
$start_time = time();
if (!$this->container->getFileConfigurationStorage()->exists(UpgradeFileNames::MODULES_TO_UPGRADE_LIST)) {
return $this->warmUp();
}
$this->next = 'upgradeModules';
$listModules = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::MODULES_TO_UPGRADE_LIST);
if (!is_array($listModules)) {
$this->next = 'upgradeComplete';
$this->container->getState()->setWarningExists(true);
$this->logger->error($this->translator->trans('listModules is not an array. No module has been updated.', array(), 'Modules.Autoupgrade.Admin'));
return true;
}
$time_elapsed = time() - $start_time;
// module list
if (count($listModules) > 0) {
do {
$module_info = array_shift($listModules);
try {
$this->container->getModuleAdapter()->upgradeModule($module_info['id'], $module_info['name']);
$this->logger->debug($this->translator->trans('The files of module %s have been upgraded.', array($module_info['name']), 'Modules.Autoupgrade.Admin'));
} catch (UpgradeException $e) {
$this->handleException($e);
if ($e->getSeverity() === UpgradeException::SEVERITY_ERROR) {
return false;
}
}
$time_elapsed = time() - $start_time;
} while (($time_elapsed < $this->container->getUpgradeConfiguration()->getTimePerCall()) && count($listModules) > 0);
$modules_left = count($listModules);
$this->container->getFileConfigurationStorage()->save($listModules, UpgradeFileNames::MODULES_TO_UPGRADE_LIST);
unset($listModules);
$this->next = 'upgradeModules';
if ($modules_left) {
$this->logger->info($this->translator->trans('%s modules left to upgrade.', array($modules_left), 'Modules.Autoupgrade.Admin'));
}
$this->stepDone = false;
} else {
$modules_to_delete = array(
'backwardcompatibility' => 'Backward Compatibility',
'dibs' => 'Dibs',
'cloudcache' => 'Cloudcache',
'mobile_theme' => 'The 1.4 mobile_theme',
'trustedshops' => 'Trustedshops',
'dejala' => 'Dejala',
'stripejs' => 'Stripejs',
'blockvariouslinks' => 'Block Various Links',
);
foreach ($modules_to_delete as $key => $module) {
$this->container->getDb()->execute('DELETE ms.*, hm.*
FROM `' . _DB_PREFIX_ . 'module_shop` ms
INNER JOIN `' . _DB_PREFIX_ . 'hook_module` hm USING (`id_module`)
INNER JOIN `' . _DB_PREFIX_ . 'module` m USING (`id_module`)
WHERE m.`name` LIKE \'' . pSQL($key) . '\'');
$this->container->getDb()->execute('UPDATE `' . _DB_PREFIX_ . 'module` SET `active` = 0 WHERE `name` LIKE \'' . pSQL($key) . '\'');
$path = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR;
if (file_exists($path . $key . '.php')) {
if (FilesystemAdapter::deleteDirectory($path)) {
$this->logger->debug($this->translator->trans(
'The %modulename% module is not compatible with version %version%, it will be removed from your FTP.',
array(
'%modulename%' => $module,
'%version%' => $this->container->getState()->getInstallVersion(),
),
'Modules.Autoupgrade.Admin'
));
} else {
$this->logger->error($this->translator->trans(
'The %modulename% module is not compatible with version %version%, please remove it from your FTP.',
array(
'%modulename%' => $module,
'%version%' => $this->container->getState()->getInstallVersion(),
),
'Modules.Autoupgrade.Admin'
));
}
}
}
$this->stepDone = true;
$this->status = 'ok';
$this->next = 'cleanDatabase';
$this->logger->info($this->translator->trans('Addons modules files have been upgraded.', array(), 'Modules.Autoupgrade.Admin'));
return true;
}
return true;
}
public function warmUp()
{
try {
$modulesToUpgrade = $this->container->getModuleAdapter()->listModulesToUpgrade($this->container->getState()->getModules_addons());
$this->container->getFileConfigurationStorage()->save($modulesToUpgrade, UpgradeFileNames::MODULES_TO_UPGRADE_LIST);
} catch (UpgradeException $e) {
$this->handleException($e);
return false;
}
$total_modules_to_upgrade = count($modulesToUpgrade);
if ($total_modules_to_upgrade) {
$this->logger->info($this->translator->trans('%s modules will be upgraded.', array($total_modules_to_upgrade), 'Modules.Autoupgrade.Admin'));
}
// WamUp core side
if (method_exists('\Module', 'getModulesOnDisk')) {
\Module::getModulesOnDisk();
}
$this->stepDone = false;
$this->next = 'upgradeModules';
return true;
}
private function handleException(UpgradeException $e)
{
foreach ($e->getQuickInfos() as $log) {
$this->logger->debug($log);
}
if ($e->getSeverity() === UpgradeException::SEVERITY_ERROR) {
$this->next = 'error';
$this->error = true;
$this->logger->error($e->getMessage());
}
if ($e->getSeverity() === UpgradeException::SEVERITY_WARNING) {
$this->logger->warning($e->getMessage());
}
}
}

View File

@@ -0,0 +1,86 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
/**
* very first step of the upgrade process. The only thing done is the selection
* of the next step.
*/
class UpgradeNow extends AbstractTask
{
public function run()
{
$this->logger->info($this->translator->trans('Starting upgrade...', array(), 'Modules.Autoupgrade.Admin'));
$this->container->getWorkspace()->createFolders();
$channel = $this->container->getUpgradeConfiguration()->get('channel');
$upgrader = $this->container->getUpgrader();
$this->next = 'download';
preg_match('#([0-9]+\.[0-9]+)(?:\.[0-9]+){1,2}#', _PS_VERSION_, $matches);
$upgrader->branch = $matches[1];
$upgrader->channel = $channel;
if ($this->container->getUpgradeConfiguration()->get('channel') == 'private' && !$this->container->getUpgradeConfiguration()->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
if ($upgrader->isLastVersion()) {
$this->next = '';
$this->logger->info($this->translator->trans('You already have the %s version.', array($upgrader->version_name), 'Modules.Autoupgrade.Admin'));
return;
}
switch ($channel) {
case 'directory':
// if channel directory is chosen, we assume it's "ready for use" (samples already removed for example)
$this->next = 'removeSamples';
$this->logger->debug($this->translator->trans('Downloading and unzipping steps have been skipped, upgrade process will now remove sample data.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Shop deactivated. Removing sample files...', array(), 'Modules.Autoupgrade.Admin'));
break;
case 'archive':
$this->next = 'unzip';
$this->logger->debug($this->translator->trans('Downloading step has been skipped, upgrade process will now unzip the local archive.', array(), 'Modules.Autoupgrade.Admin'));
$this->logger->info($this->translator->trans('Shop deactivated. Extracting files...', array(), 'Modules.Autoupgrade.Admin'));
break;
default:
$this->next = 'download';
$this->logger->info($this->translator->trans('Shop deactivated. Now downloading... (this can take a while)', array(), 'Modules.Autoupgrade.Admin'));
if ($upgrader->channel == 'private') {
$upgrader->link = $this->container->getUpgradeConfiguration()->get('private_release_link');
$upgrader->md5 = $this->container->getUpgradeConfiguration()->get('private_release_md5');
}
$this->logger->debug($this->translator->trans('Downloaded archive will come from %s', array($upgrader->link), 'Modules.Autoupgrade.Admin'));
$this->logger->debug($this->translator->trans('MD5 hash will be checked against %s', array($upgrader->md5), 'Modules.Autoupgrade.Admin'));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Block;
use PrestaShop\Module\AutoUpgrade\ChannelInfo;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use Twig_Environment;
class ChannelInfoBlock
{
/**
* @var UpgradeConfiguration
*/
private $config;
/**
* @var ChannelInfo
*/
private $channelInfo;
/**
* @var \Twig_Environment
*/
private $twig;
/**
* ChannelInfoBlock constructor.
*
* @param UpgradeConfiguration $config
* @param ChannelInfo $channelInfo
* @param Twig_Environment $twig
*/
public function __construct(UpgradeConfiguration $config, ChannelInfo $channelInfo, Twig_Environment $twig)
{
$this->config = $config;
$this->channelInfo = $channelInfo;
$this->twig = $twig;
}
/**
* @return string HTML
*/
public function render()
{
$channel = $this->channelInfo->getChannel();
$upgradeInfo = $this->channelInfo->getInfo();
if ($channel == 'private') {
$upgradeInfo['link'] = $this->config->get('private_release_link');
$upgradeInfo['md5'] = $this->config->get('private_release_md5');
}
return $this->twig->render(
'@ModuleAutoUpgrade/block/channelInfo.twig',
array(
'upgradeInfo' => $upgradeInfo,
)
);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Block;
use PrestaShop\Module\AutoUpgrade\BackupFinder;
use Twig_Environment;
class RollbackForm
{
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var BackupFinder
*/
private $backupFinder;
public function __construct(Twig_Environment $twig, BackupFinder $backupFinder)
{
$this->twig = $twig;
$this->backupFinder = $backupFinder;
}
public function render()
{
return $this->twig->render(
'@ModuleAutoUpgrade/block/rollbackForm.twig',
array(
'availableBackups' => $this->backupFinder->getAvailableBackups(),
)
);
}
}

View File

@@ -0,0 +1,224 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Block;
use Configuration;
use PrestaShop\Module\AutoUpgrade\ChannelInfo;
use Twig_Environment;
use PrestaShop\Module\AutoUpgrade\Upgrader;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\TaskRunner\AbstractTask;
use PrestaShop\Module\AutoUpgrade\UpgradeSelfCheck;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
class UpgradeButtonBlock
{
/**
* @var \Twig_Environment
*/
private $twig;
/**
* @var Translator
*/
private $translator;
/**
* @var Upgrader
*/
private $upgrader;
/**
* @var UpgradeConfiguration
*/
private $config;
/**
* @var UpgradeSelfCheck
*/
private $selfCheck;
/**
* @var string
*/
private $downloadPath;
/**
* @var string
*/
private $token;
/**
* @var bool
*/
private $manualMode;
/**
* UpgradeButtonBlock constructor.
*
* @param Twig_Environment $twig
* @param Translator $translator
* @param UpgradeConfiguration $config
* @param Upgrader $upgrader
* @param UpgradeSelfCheck $selfCheck
*/
public function __construct(
Twig_Environment $twig,
Translator $translator,
UpgradeConfiguration $config,
Upgrader $upgrader,
UpgradeSelfCheck $selfCheck,
$downloadPath,
$token,
$manualMode
) {
$this->twig = $twig;
$this->translator = $translator;
$this->upgrader = $upgrader;
$this->config = $config;
$this->selfCheck = $selfCheck;
$this->downloadPath = $downloadPath;
$this->token = $token;
$this->manualMode = $manualMode;
}
/**
* display the summary current version / target version + "Upgrade Now" button with a "more options" button.
*
* @return string HTML
*/
public function render()
{
$translator = $this->translator;
$versionCompare = version_compare(_PS_VERSION_, $this->upgrader->version_num);
$channel = $this->config->get('channel');
if (!in_array($channel, array('archive', 'directory')) && !empty($this->upgrader->version_num)) {
$latestVersion = "{$this->upgrader->version_name} - ({$this->upgrader->version_num})";
} else {
$latestVersion = $translator->trans('N/A', array(), 'Admin.Global');
}
$showUpgradeButton = false;
$showUpgradeLink = false;
$upgradeLink = '';
$changelogLink = '';
$skipActions = array();
// decide to display "Start Upgrade" or not
if ($this->selfCheck->isOkForUpgrade() && $versionCompare < 0) {
$showUpgradeButton = true;
if (!in_array($channel, array('archive', 'directory'))) {
if ($channel == 'private') {
$this->upgrader->link = $this->config->get('private_release_link');
}
$showUpgradeLink = true;
$upgradeLink = $this->upgrader->link;
$changelogLink = $this->upgrader->changelog;
}
// if skipActions property is used, we will handle that in the display :)
$skipActions = AbstractTask::$skipAction;
}
if (empty($channel)) {
$channel = Upgrader::DEFAULT_CHANNEL;
}
$dir = glob($this->downloadPath . DIRECTORY_SEPARATOR . '*.zip');
$data = array(
'versionCompare' => $versionCompare,
'currentPsVersion' => _PS_VERSION_,
'latestChannelVersion' => $latestVersion,
'channel' => $channel,
'showUpgradeButton' => $showUpgradeButton,
'upgradeLink' => $upgradeLink,
'showUpgradeLink' => $showUpgradeLink,
'changelogLink' => $changelogLink,
'skipActions' => $skipActions,
'lastVersionCheck' => Configuration::get('PS_LAST_VERSION_CHECK'),
'token' => $this->token,
'channelOptions' => $this->getOptChannels(),
'channelInfoBlock' => $this->buildChannelInfoBlock($channel),
'privateChannel' => array(
'releaseLink' => $this->config->get('private_release_link'),
'releaseMd5' => $this->config->get('private_release_md5'),
'allowMajor' => $this->config->get('private_allow_major'),
),
'archiveFiles' => $dir,
'archiveFileName' => $this->config->get('archive.filename'),
'archiveVersionNumber' => $this->config->get('archive.version_num'),
'downloadPath' => $this->downloadPath . DIRECTORY_SEPARATOR,
'directoryVersionNumber' => $this->config->get('directory.version_num'),
'manualMode' => $this->manualMode,
);
return $this->twig->render('@ModuleAutoUpgrade/block/upgradeButtonBlock.twig', $data);
}
/**
* @return array
*/
private function getOptChannels()
{
$translator = $this->translator;
return array(
// Hey ! I'm really using a fieldset element to regroup fields ?! !
array('useMajor', 'major', $translator->trans('Major release', array(), 'Modules.Autoupgrade.Admin')),
array('useMinor', 'minor', $translator->trans('Minor release (recommended)', array(), 'Modules.Autoupgrade.Admin')),
array('useRC', 'rc', $translator->trans('Release candidates', array(), 'Modules.Autoupgrade.Admin')),
array('useBeta', 'beta', $translator->trans('Beta releases', array(), 'Modules.Autoupgrade.Admin')),
array('useAlpha', 'alpha', $translator->trans('Alpha releases', array(), 'Modules.Autoupgrade.Admin')),
array('usePrivate', 'private', $translator->trans('Private release (require link and MD5 hash)', array(), 'Modules.Autoupgrade.Admin')),
array('useArchive', 'archive', $translator->trans('Local archive', array(), 'Modules.Autoupgrade.Admin')),
array('useDirectory', 'directory', $translator->trans('Local directory', array(), 'Modules.Autoupgrade.Admin')),
);
}
private function getInfoForChannel($channel)
{
return new ChannelInfo($this->upgrader, $this->config, $channel);
}
/**
* @param string $channel
*
* @return string
*/
private function buildChannelInfoBlock($channel)
{
$channelInfo = $this->getInfoForChannel($channel);
return (new ChannelInfoBlock($this->config, $channelInfo, $this->twig))
->render();
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Block;
use PrestaShop\Module\AutoUpgrade\UpgradeSelfCheck;
use PrestaShop\Module\AutoUpgrade\Tools14;
use Context;
use Twig_Environment;
/**
* Builds the upgrade checklist block.
*/
class UpgradeChecklist
{
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var string
*/
private $prodRootPath;
/**
* @var string
*/
private $adminPath;
/**
* @var string
*/
private $autoupgradePath;
/**
* @var UpgradeSelfCheck
*/
private $selfCheck;
/**
* @var string
*/
private $currentIndex;
/**
* @var string
*/
private $token;
/**
* UpgradeChecklistBlock constructor.
*
* @param Twig_Environment $twig
* @param UpgradeSelfCheck $upgradeSelfCheck
* @param string $prodRootPath
* @param string $adminPath
* @param string $autoupgradePath
* @param string $currentIndex
* @param string $token
*/
public function __construct(
Twig_Environment $twig,
UpgradeSelfCheck $upgradeSelfCheck,
$prodRootPath,
$adminPath,
$autoupgradePath,
$currentIndex,
$token
) {
$this->twig = $twig;
$this->selfCheck = $upgradeSelfCheck;
$this->prodRootPath = $prodRootPath;
$this->adminPath = $adminPath;
$this->autoupgradePath = $autoupgradePath;
$this->currentIndex = $currentIndex;
$this->token = $token;
}
/**
* Returns the block's HTML.
*
* @return string
*/
public function render()
{
$data = array(
'showErrorMessage' => !$this->selfCheck->isOkForUpgrade(),
'moduleVersion' => $this->selfCheck->getModuleVersion(),
'moduleIsUpToDate' => $this->selfCheck->isModuleVersionLatest(),
'versionGreaterThan1_5_3' => version_compare(_PS_VERSION_, '1.5.3.0', '>'),
'adminToken' => Tools14::getAdminTokenLite('AdminModules'),
'informationsLink' => Context::getContext()->link->getAdminLink('AdminInformation'),
'rootDirectoryIsWritable' => $this->selfCheck->isRootDirectoryWritable(),
'rootDirectoryWritableReport' => $this->selfCheck->getRootWritableReport(),
'adminDirectoryIsWritable' => $this->selfCheck->isAdminAutoUpgradeDirectoryWritable(),
'adminDirectoryWritableReport' => $this->selfCheck->getAdminAutoUpgradeDirectoryWritableReport(),
'safeModeIsDisabled' => $this->selfCheck->isSafeModeDisabled(),
'allowUrlFopenOrCurlIsEnabled' => $this->selfCheck->isFOpenOrCurlEnabled(),
'zipIsEnabled' => $this->selfCheck->isZipEnabled(),
'storeIsInMaintenance' => $this->selfCheck->isShopDeactivated(),
'currentIndex' => $this->currentIndex,
'token' => $this->token,
'cachingIsDisabled' => $this->selfCheck->isCacheDisabled(),
'maxExecutionTime' => $this->selfCheck->getMaxExecutionTime(),
'isPrestaShopReady' => $this->selfCheck->isPrestaShopReady(),
);
return $this->twig->render('@ModuleAutoUpgrade/block/checklist.twig', $data);
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Form;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
class BackupOptionsForm
{
/**
* @var array
*/
private $fields;
/**
* @var Translator
*/
private $translator;
/**
* @var FormRenderer
*/
private $formRenderer;
public function __construct(Translator $translator, FormRenderer $formRenderer)
{
$this->translator = $translator;
$this->formRenderer = $formRenderer;
$translationDomain = 'Modules.Autoupgrade.Admin';
$this->fields = array(
'PS_AUTOUP_BACKUP' => array(
'title' => $this->translator->trans(
'Back up my files and database',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'defaultValue' => '1',
'type' => 'bool',
'desc' => $this->translator->trans(
'Automatically back up your database and files in order to restore your shop if needed. This is experimental: you should still perform your own manual backup for safety.',
array(),
$translationDomain
),
),
'PS_AUTOUP_KEEP_IMAGES' => array(
'title' => $this->translator->trans(
'Back up my images',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'defaultValue' => '1',
'type' => 'bool',
'desc' => $this->translator->trans(
'To save time, you can decide not to back your images up. In any case, always make sure you did back them up manually.',
array(),
$translationDomain
),
),
);
}
public function render()
{
return $this->formRenderer->render(
'backupOptions',
$this->fields,
$this->translator->trans(
'Backup Options',
array(),
'Modules.Autoupgrade.Admin'
),
'',
'database_gear'
);
}
}

View File

@@ -0,0 +1,223 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Form;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
use Twig_Environment;
class FormRenderer
{
private $config;
private $translator;
private $twig;
public function __construct(
UpgradeConfiguration $configuration,
Twig_Environment $twig,
Translator $translator
) {
$this->config = $configuration;
$this->twig = $twig;
$this->translator = $translator;
}
public function render($name, $fields, $tabname, $size, $icon)
{
$required = false;
$formFields = array();
foreach ($fields as $key => $field) {
$html = '';
$required = !empty($field['required']);
$disabled = !empty($field['disabled']);
$val = $this->config->get(
$key,
isset($field['defaultValue']) ? $field['defaultValue'] : false
);
if (!in_array($field['type'], array('image', 'radio', 'select', 'container', 'bool', 'container_end')) || isset($field['show'])) {
$html .= '<div style="clear: both; padding-top:15px">'
. ($field['title'] ? '<label >' . $field['title'] . '</label>' : '')
. '<div class="margin-form" style="padding-top:5px">';
}
// Display the appropriate input type for each field
switch ($field['type']) {
case 'disabled':
$html .= $field['disabled'];
break;
case 'bool':
$html .= $this->renderBool($field, $key, $val);
break;
case 'radio':
$html .= $this->renderRadio($field, $key, $val, $disabled);
break;
case 'select':
$html .= $this->renderSelect($field, $key, $val);
break;
case 'textarea':
$html .= $this->renderTextarea($field, $key, $val, $disabled);
break;
case 'container':
$html .= '<div id="' . $key . '">';
break;
case 'container_end':
$html .= (isset($field['content']) ? $field['content'] : '') . '</div>';
break;
case 'text':
default:
$html .= $this->renderTextField($field, $key, $val, $disabled);
}
if ($required && !in_array($field['type'], array('image', 'radio'))) {
$html .= ' <sup>*</sup>';
}
if (isset($field['desc']) && !in_array($field['type'], array('bool', 'select'))) {
$html .= '<p style="clear:both">';
if (!empty($field['thumb']) && $field['thumb']['pos'] == 'after') {
$html .= $this->renderThumb($field);
}
$html .= $field['desc'] . '</p>';
}
if (!in_array($field['type'], array('image', 'radio', 'select', 'container', 'bool', 'container_end')) || isset($field['show'])) {
$html .= '</div></div>';
}
$formFields[] = $html;
}
return $this->twig->render(
'@ModuleAutoUpgrade/form.twig',
array(
'name' => $name,
'tabName' => $tabname,
'fields' => $formFields,
)
);
}
private function renderBool($field, $key, $val)
{
return '<div class="form-group">
<label class="col-lg-3 control-label">' . $field['title'] . '</label>
<div class="col-lg-9">
<span class="switch prestashop-switch fixed-width-lg">
<input type="radio" name="' . $key . '" id="' . $key . '_on" value="1" ' . ($val ? ' checked="checked"' : '') . (isset($field['js']['on']) ? $field['js']['on'] : '') . ' />
<label for="' . $key . '_on" class="radioCheck">
<i class="color_success"></i> '
. $this->translator->trans('Yes', array(), 'Admin.Global') . '
</label>
<input type="radio" name="' . $key . '" id="' . $key . '_off" value="0" ' . (!$val ? 'checked="checked"' : '') . (isset($field['js']['off']) ? $field['js']['off'] : '') . '/>
<label for="' . $key . '_off" class="radioCheck">
<i class="color_danger"></i> ' . $this->translator->trans('No', array(), 'Admin.Global') . '
</label>
<a class="slide-button btn"></a>
</span>
<div class="help-block">' . $field['desc'] . '</div>
</div>
</div>';
}
private function renderRadio($field, $key, $val, $disabled)
{
$html = '';
foreach ($field['choices'] as $cValue => $cKey) {
$html .= '<input ' . ($disabled ? 'disabled="disabled"' : '') . ' type="radio" name="' . $key . '" id="' . $key . $cValue . '_on" value="' . (int) ($cValue) . '"' . (($cValue == $val) ? ' checked="checked"' : '') . (isset($field['js'][$cValue]) ? ' ' . $field['js'][$cValue] : '') . ' /><label class="t" for="' . $key . $cValue . '_on"> ' . $cKey . '</label><br />';
}
$html .= '<br />';
return $html;
}
private function renderSelect($field, $key, $val)
{
$html = '<div class="form-group">
<label class="col-lg-3 control-label">' . $field['title'] . '</label>
<div class="col-lg-9">
<select name="' . $key . '">';
foreach ($field['choices'] as $cValue => $cKey) {
$html .= '<option value="' . (int) $cValue . '"'
. (($cValue == $val) ? ' selected' : '')
. '>'
. $cKey
. '</option>';
}
$html .= '</select>
<div class="help-block">' . $field['desc'] . '</div>
</div>
</div>';
return $html;
}
private function renderTextarea($field, $key, $val, $disabled)
{
return '<textarea '
. ($disabled ? 'disabled="disabled"' : '')
. ' name="' . $key
. '" cols="' . $field['cols']
. '" rows="' . $field['rows']
. '">'
. htmlentities($val, ENT_COMPAT, 'UTF-8')
. '</textarea>';
}
private function renderTextField($field, $key, $val, $disabled)
{
return '<input '
. ($disabled ? 'disabled="disabled"' : '')
. ' type="' . $field['type'] . '"'
. (isset($field['id']) ? ' id="' . $field['id'] . '"' : '')
. ' size="' . (isset($field['size']) ? (int) ($field['size']) : 5)
. '" name="' . $key
. '" value="' . ($field['type'] == 'password' ? '' : htmlentities($val, ENT_COMPAT, 'UTF-8'))
. '" />'
. (isset($field['next']) ? '&nbsp;' . $field['next'] : '');
}
private function renderThumb($field)
{
return "<img src=\"{$field['thumb']['file']}\" alt=\"{$field['title']}\" title=\"{$field['title']}\" style=\"float:left;\">";
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig\Form;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
class UpgradeOptionsForm
{
/**
* @var array
*/
private $fields;
/**
* @var Translator
*/
private $translator;
/**
* @var FormRenderer
*/
private $formRenderer;
public function __construct(Translator $translator, FormRenderer $formRenderer)
{
$this->translator = $translator;
$this->formRenderer = $formRenderer;
// TODO: Class const
$translationDomain = 'Modules.Autoupgrade.Admin';
$this->fields = array(
'PS_AUTOUP_PERFORMANCE' => array(
'title' => $translator->trans(
'Server performance',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isInt',
'defaultValue' => '1',
'type' => 'select', 'desc' => $translator->trans(
'Unless you are using a dedicated server, select "Low".',
array(),
$translationDomain
) . '<br />' .
$translator->trans(
'A high value can cause the upgrade to fail if your server is not powerful enough to process the upgrade tasks in a short amount of time.',
array(),
$translationDomain
),
'choices' => array(
1 => $translator->trans(
'Low (recommended)',
array(),
$translationDomain
),
2 => $translator->trans('Medium', array(), $translationDomain),
3 => $translator->trans(
'High',
array(),
$translationDomain
),
),
),
'PS_AUTOUP_CUSTOM_MOD_DESACT' => array(
'title' => $translator->trans(
'Disable non-native modules',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'type' => 'bool',
'desc' => $translator->trans(
'As non-native modules can experience some compatibility issues, we recommend to disable them by default.',
array(),
$translationDomain
) . '<br />' .
$translator->trans(
'Keeping them enabled might prevent you from loading the "Modules" page properly after the upgrade.',
array(),
$translationDomain
),
),
'PS_AUTOUP_UPDATE_DEFAULT_THEME' => array(
'title' => $translator->trans(
'Upgrade the default theme',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'defaultValue' => '1',
'type' => 'bool',
'desc' => $translator->trans(
'If you customized the default PrestaShop theme in its folder (folder name "classic" in 1.7), enabling this option will lose your modifications.',
array(),
$translationDomain
) . '<br />'
. $translator->trans(
'If you are using your own theme, enabling this option will simply update the default theme files, and your own theme will be safe.',
array(),
$translationDomain
),
),
'PS_AUTOUP_CHANGE_DEFAULT_THEME' => array(
'title' => $translator->trans(
'Switch to the default theme',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'defaultValue' => '0',
'type' => 'bool',
'desc' => $translator->trans(
'This will change your theme: your shop will then use the default theme of the version of PrestaShop you are upgrading to.',
array(),
$translationDomain
),
),
'PS_AUTOUP_KEEP_MAILS' => array(
'title' => $translator->trans(
'Keep the customized email templates',
array(),
$translationDomain
),
'cast' => 'intval',
'validation' => 'isBool',
'type' => 'bool',
'desc' => $translator->trans(
'This will not upgrade the default PrestaShop e-mails.',
array(),
$translationDomain
) . '<br />'
. $translator->trans(
'If you customized the default PrestaShop e-mail templates, enabling this option will keep your modifications.',
array(),
$translationDomain
),
),
);
}
public function render()
{
return $this->formRenderer->render(
'upgradeOptions',
$this->fields,
$this->translator->trans(
'Upgrade Options',
array(),
'Modules.Autoupgrade.Admin'
),
'',
'prefs'
);
}
}

View File

@@ -0,0 +1,55 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\Twig;
use Twig_Extension;
use Twig_SimpleFilter;
class TransFilterExtension extends Twig_Extension
{
const DOMAIN = 'Modules.Autoupgrade.Admin';
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
public function getFilters()
{
return array(
new Twig_SimpleFilter('trans', array($this, 'trans')),
);
}
public function trans($string, $params = array())
{
return $this->translator->trans($string, $params, self::DOMAIN);
}
}

View File

@@ -0,0 +1,504 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\LegacyLogger;
use PrestaShop\Module\AutoUpgrade\Log\Logger;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\CacheCleaner;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FileFilter;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\ModuleAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\SymfonyAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translation;
use PrestaShop\Module\AutoUpgrade\Parameters\FileConfigurationStorage;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfigurationStorage;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\Twig\TransFilterExtension;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
use Twig_Loader_Filesystem;
use Twig_Environment;
/**
* Class responsible of the easy (& Lazy) loading of the different services
* available for the upgrade.
*/
class UpgradeContainer
{
const WORKSPACE_PATH = 'workspace'; // AdminSelfUpgrade::$autoupgradePath
const BACKUP_PATH = 'backup';
const DOWNLOAD_PATH = 'download';
const LATEST_PATH = 'latest'; // AdminSelfUpgrade::$latestRootDir
const LATEST_DIR = 'lastest/';
const TMP_PATH = 'tmp';
const PS_ADMIN_PATH = 'ps_admin';
const PS_ADMIN_SUBDIR = 'ps_admin_subdir';
const PS_ROOT_PATH = 'ps_root'; // AdminSelfUpgrade::$prodRootDir
const ARCHIVE_FILENAME = 'destDownloadFilename';
const ARCHIVE_FILEPATH = 'destDownloadFilepath';
const PS_VERSION = 'version';
/**
* @var CacheCleaner
*/
private $cacheCleaner;
/**
* @var Cookie
*/
private $cookie;
/**
* @var \Db
*/
public $db;
/**
* @var FileConfigurationStorage
*/
private $fileConfigurationStorage;
/**
* @var FileFilter
*/
private $fileFilter;
/**
* @var PrestashopConfiguration
*/
private $prestashopConfiguration;
/**
* @var UpgradeConfiguration
*/
private $upgradeConfiguration;
/**
* @var FilesystemAdapter
*/
private $filesystemAdapter;
/**
* @var Logger
*/
private $logger;
/**
* @var ModuleAdapter
*/
private $moduleAdapter;
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var State
*/
private $state;
/**
* @var SymfonyAdapter
*/
private $symfonyAdapter;
/**
* @var Upgrader
*/
private $upgrader;
/**
* @var Workspace
*/
private $workspace;
/**
* @var ZipAction
*/
private $zipAction;
/**
* AdminSelfUpgrade::$autoupgradePath
* Ex.: /var/www/html/PrestaShop/admin-dev/autoupgrade.
*
* @var string Path to the base folder of the autoupgrade (in admin)
*/
private $autoupgradeWorkDir;
/**
* @var string Absolute path to the admin folder
*/
private $adminDir;
/**
* @var string Absolute path to ps root folder of PS
*/
private $psRootDir;
public function __construct($psRootDir, $adminDir, $moduleSubDir = 'autoupgrade')
{
$this->autoupgradeWorkDir = $adminDir . DIRECTORY_SEPARATOR . $moduleSubDir;
$this->adminDir = $adminDir;
$this->psRootDir = $psRootDir;
}
public function getProperty($property)
{
switch ($property) {
case self::PS_ADMIN_PATH:
return $this->adminDir;
case self::PS_ADMIN_SUBDIR:
return trim(str_replace($this->getProperty(self::PS_ROOT_PATH), '', $this->getProperty(self::PS_ADMIN_PATH)), DIRECTORY_SEPARATOR);
case self::PS_ROOT_PATH:
return $this->psRootDir;
case self::WORKSPACE_PATH:
return $this->autoupgradeWorkDir;
case self::BACKUP_PATH:
return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'backup';
case self::DOWNLOAD_PATH:
return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'download';
case self::LATEST_PATH:
return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'latest';
case self::LATEST_DIR:
return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'latest' . DIRECTORY_SEPARATOR;
case self::TMP_PATH:
return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'tmp';
case self::ARCHIVE_FILENAME:
return $this->getUpgradeConfiguration()->getArchiveFilename();
case self::ARCHIVE_FILEPATH:
return $this->getProperty(self::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $this->getProperty(self::ARCHIVE_FILENAME);
case self::PS_VERSION:
return $this->getPrestaShopConfiguration()->getPrestaShopVersion();
}
}
/**
* Init and return CacheCleaner
*
* @return CacheCleaner
*/
public function getCacheCleaner()
{
if (null !== $this->cacheCleaner) {
return $this->cacheCleaner;
}
return $this->cacheCleaner = new CacheCleaner($this, $this->getLogger());
}
public function getCookie()
{
if (null !== $this->cookie) {
return $this->cookie;
}
$this->cookie = new Cookie(
$this->getProperty(self::PS_ADMIN_SUBDIR),
$this->getProperty(self::TMP_PATH));
return $this->cookie;
}
public function getDb()
{
return \Db::getInstance();
}
/**
* Return the path to the zipfile containing prestashop.
*
* @return string
*/
public function getFilePath()
{
return $this->getProperty(self::ARCHIVE_FILEPATH);
}
public function getFileConfigurationStorage()
{
if (null !== $this->fileConfigurationStorage) {
return $this->fileConfigurationStorage;
}
$this->fileConfigurationStorage = new FileConfigurationStorage($this->getProperty(self::WORKSPACE_PATH) . DIRECTORY_SEPARATOR);
return $this->fileConfigurationStorage;
}
public function getFileFilter()
{
if (null !== $this->fileFilter) {
return $this->fileFilter;
}
$this->fileFilter = new FileFilter($this->getUpgradeConfiguration());
return $this->fileFilter;
}
public function getUpgrader()
{
if (null !== $this->upgrader) {
return $this->upgrader;
}
if (!defined('_PS_ROOT_DIR_')) {
define('_PS_ROOT_DIR_', $this->getProperty(self::PS_ROOT_PATH));
}
// in order to not use Tools class
$upgrader = new Upgrader($this->getProperty(self::PS_VERSION));
preg_match('#([0-9]+\.[0-9]+)(?:\.[0-9]+){1,2}#', $this->getProperty(self::PS_VERSION), $matches);
$upgrader->branch = $matches[1];
$upgradeConfiguration = $this->getUpgradeConfiguration();
$channel = $upgradeConfiguration->get('channel');
switch ($channel) {
case 'archive':
$upgrader->channel = 'archive';
$upgrader->version_num = $upgradeConfiguration->get('archive.version_num');
$upgrader->checkPSVersion(true, array('archive'));
break;
case 'directory':
$upgrader->channel = 'directory';
$upgrader->version_num = $upgradeConfiguration->get('directory.version_num');
$upgrader->checkPSVersion(true, array('directory'));
break;
default:
$upgrader->channel = $channel;
if ($upgradeConfiguration->get('channel') == 'private' && !$upgradeConfiguration->get('private_allow_major')) {
$upgrader->checkPSVersion(false, array('private', 'minor'));
} else {
$upgrader->checkPSVersion(false, array('minor'));
}
}
$this->getState()->setInstallVersion($upgrader->version_num);
$this->upgrader = $upgrader;
return $this->upgrader;
}
public function getFilesystemAdapter()
{
if (null !== $this->filesystemAdapter) {
return $this->filesystemAdapter;
}
$this->filesystemAdapter = new FilesystemAdapter(
$this->getFileFilter(),
$this->getState()->getRestoreFilesFilename(),
$this->getProperty(self::WORKSPACE_PATH),
str_replace($this->getProperty(self::PS_ROOT_PATH), '', $this->getProperty(self::PS_ADMIN_PATH)), $this->getProperty(self::PS_ROOT_PATH));
return $this->filesystemAdapter;
}
/**
* @return Logger
*/
public function getLogger()
{
if (null !== $this->logger) {
return $this->logger;
}
$logFile = null;
if (is_writable($this->getProperty(self::TMP_PATH))) {
$logFile = $this->getProperty(self::TMP_PATH) . DIRECTORY_SEPARATOR . 'log.txt';
}
$this->logger = new LegacyLogger($logFile);
return $this->logger;
}
public function setLogger(Logger $logger)
{
$this->logger = $logger;
}
public function getModuleAdapter()
{
if (null !== $this->moduleAdapter) {
return $this->moduleAdapter;
}
$this->moduleAdapter = new ModuleAdapter(
$this->getDb(),
$this->getTranslator(),
$this->getProperty(self::PS_ROOT_PATH) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR,
$this->getProperty(self::TMP_PATH),
$this->getState()->getInstallVersion(),
$this->getZipAction(),
$this->getSymfonyAdapter()
);
return $this->moduleAdapter;
}
public function getState()
{
if (null !== $this->state) {
return $this->state;
}
$this->state = new State();
return $this->state;
}
public function getTranslationAdapter()
{
return new Translation($this->getTranslator(), $this->getLogger(), $this->getState()->getInstalledLanguagesIso());
}
public function getTranslator()
{
return new Translator('AdminSelfUpgrade');
}
public function getTwig()
{
if (null !== $this->twig) {
return $this->twig;
}
// Using independant template engine for 1.6 & 1.7 compatibility
$loader = new Twig_Loader_Filesystem();
$loader->addPath(realpath(__DIR__ . '/..') . '/views/templates', 'ModuleAutoUpgrade');
$twig = new Twig_Environment($loader);
$twig->addExtension(new TransFilterExtension($this->getTranslator()));
$this->twig = $twig;
return $this->twig;
}
public function getPrestaShopConfiguration()
{
if (null !== $this->prestashopConfiguration) {
return $this->prestashopConfiguration;
}
$this->prestashopConfiguration = new PrestashopConfiguration(
$this->getProperty(self::WORKSPACE_PATH),
$this->getProperty(self::PS_ROOT_PATH)
);
return $this->prestashopConfiguration;
}
/**
* @return SymfonyAdapter
*/
public function getSymfonyAdapter()
{
if (null !== $this->symfonyAdapter) {
return $this->symfonyAdapter;
}
$this->symfonyAdapter = new SymfonyAdapter($this->getState()->getInstallVersion());
return $this->symfonyAdapter;
}
public function getUpgradeConfiguration()
{
if (null !== $this->upgradeConfiguration) {
return $this->upgradeConfiguration;
}
$upgradeConfigurationStorage = new UpgradeConfigurationStorage($this->getProperty(self::WORKSPACE_PATH) . DIRECTORY_SEPARATOR);
$this->upgradeConfiguration = $upgradeConfigurationStorage->load(UpgradeFileNames::CONFIG_FILENAME);
return $this->upgradeConfiguration;
}
public function getUpgradeConfigurationStorage()
{
return new UpgradeConfigurationStorage($this->getProperty(self::WORKSPACE_PATH) . DIRECTORY_SEPARATOR);
}
public function getWorkspace()
{
if (null !== $this->workspace) {
return $this->workspace;
}
$paths = array();
$properties = array(
self::WORKSPACE_PATH, self::BACKUP_PATH,
self::DOWNLOAD_PATH, self::LATEST_PATH,
self::TMP_PATH, );
foreach ($properties as $property) {
$paths[] = $this->getProperty($property);
}
$this->workspace = new Workspace(
$this->getLogger(),
$this->getTranslator(),
$paths
);
return $this->workspace;
}
public function getZipAction()
{
if (null !== $this->zipAction) {
return $this->zipAction;
}
$this->zipAction = new ZipAction(
$this->getTranslator(),
$this->getLogger(),
$this->getUpgradeConfiguration(),
$this->getProperty(self::PS_ROOT_PATH));
return $this->zipAction;
}
/**
* Checks if the composer autoload exists, and loads it.
*/
public function initPrestaShopAutoloader()
{
$autoloader = $this->getProperty(self::PS_ROOT_PATH) . '/vendor/autoload.php';
if (file_exists($autoloader)) {
require_once $autoloader;
}
require_once $this->getProperty(self::PS_ROOT_PATH) . '/config/defines.inc.php';
require_once $this->getProperty(self::PS_ROOT_PATH) . '/config/autoload.php';
}
public function initPrestaShopCore()
{
require_once $this->getProperty(self::PS_ROOT_PATH) . '/config/config.inc.php';
$id_employee = !empty($_COOKIE['id_employee']) ? $_COOKIE['id_employee'] : 1;
\Context::getContext()->employee = new \Employee((int) $id_employee);
}
}

View File

@@ -0,0 +1,72 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
/**
* Todo: Should we create a UpgradeWarning class instead of setting the severity here?
*/
class UpgradeException extends \Exception
{
const SEVERITY_ERROR = 1;
const SEVERITY_WARNING = 2;
private $quickInfos = array();
private $severity = self::SEVERITY_ERROR;
public function getQuickInfos()
{
return $this->quickInfos;
}
public function getSeverity()
{
return $this->severity;
}
public function addQuickInfo($quickInfo)
{
$this->quickInfos[] = $quickInfo;
return $this;
}
public function setQuickInfos(array $quickInfos)
{
$this->quickInfos = $quickInfos;
return $this;
}
public function setSeverity($severity)
{
$this->severity = (int) $severity;
return $this;
}
}

View File

@@ -0,0 +1,431 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Twig\Block\RollbackForm;
use PrestaShop\Module\AutoUpgrade\Twig\Block\UpgradeButtonBlock;
use PrestaShop\Module\AutoUpgrade\Twig\Block\UpgradeChecklist;
use PrestaShop\Module\AutoUpgrade\Twig\Form\BackupOptionsForm;
use PrestaShop\Module\AutoUpgrade\Twig\Form\FormRenderer;
use PrestaShop\Module\AutoUpgrade\Twig\Form\UpgradeOptionsForm;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
use Twig_Environment;
/**
* Constructs the upgrade page.
*/
class UpgradePage
{
const TRANSLATION_DOMAIN = 'Modules.Autoupgrade.Admin';
/**
* @var string
*/
private $moduleDir;
/**
* @var string
*/
private $templatesDir = '/views/templates';
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var UpgradeConfiguration
*/
private $config;
/**
* @var Translator
*/
private $translator;
/**
* @var UpgradeSelfCheck
*/
private $upgradeSelfCheck;
/**
* @var string
*/
private $autoupgradePath;
/**
* @var Upgrader
*/
private $upgrader;
/**
* @var string
*/
private $prodRootPath;
/**
* @var string
*/
private $adminPath;
/**
* @var string
*/
private $currentIndex;
/**
* @var string
*/
private $token;
/**
* @var string
*/
private $installVersion;
/**
* @var bool
*/
private $manualMode;
/**
* @var string
*/
private $backupName;
/**
* @var string
*/
private $downloadPath;
/**
* @var BackupFinder
*/
private $backupFinder;
public function __construct(
UpgradeConfiguration $config,
Twig_Environment $twig,
Translator $translator,
UpgradeSelfCheck $upgradeSelfCheck,
Upgrader $upgrader,
BackupFinder $backupFinder,
$autoupgradePath,
$prodRootPath,
$adminPath,
$currentIndex,
$token,
$installVersion,
$manualMode,
$backupName,
$downloadPath
) {
$this->moduleDir = realpath(__DIR__ . '/../');
$this->config = $config;
$this->translator = $translator;
$this->upgrader = $upgrader;
$this->upgradeSelfCheck = $upgradeSelfCheck;
$this->autoupgradePath = $autoupgradePath;
$this->prodRootPath = $prodRootPath;
$this->adminPath = $adminPath;
$this->currentIndex = $currentIndex;
$this->token = $token;
$this->installVersion = $installVersion;
$this->manualMode = $manualMode;
$this->backupName = $backupName;
$this->twig = $twig;
$this->downloadPath = $downloadPath;
$this->backupFinder = $backupFinder;
}
/**
* Renders the page.
*
* @return string HTML
*/
public function display($ajaxResult)
{
$twig = $this->twig;
$translationDomain = self::TRANSLATION_DOMAIN;
$errMessageData = $this->getErrorMessage();
if (!empty($errMessageData)) {
return $twig
->render('@ModuleAutoUpgrade:error.twig', $errMessageData);
}
$templateData = array(
'psBaseUri' => __PS_BASE_URI__,
'translationDomain' => $translationDomain,
'jsParams' => $this->getJsParams($ajaxResult),
'currentConfig' => $this->getChecklistBlock(),
'upgradeButtonBlock' => $this->getUpgradeButtonBlock(),
'rollbackForm' => $this->getRollbackForm(),
'backupOptions' => $this->getBackupOptionsForm(),
'upgradeOptions' => $this->getUpgradeOptionsForm(),
'currentIndex' => $this->currentIndex,
'token' => $this->token,
);
return $twig->render('@ModuleAutoUpgrade/main.twig', $templateData);
}
/**
* @return string HTML
*/
private function getChecklistBlock()
{
return (new UpgradeChecklist(
$this->twig,
$this->upgradeSelfCheck,
$this->prodRootPath,
$this->adminPath,
$this->autoupgradePath,
$this->currentIndex,
$this->token
))->render();
}
/**
* @return string HTML
*/
private function getUpgradeButtonBlock()
{
return (new UpgradeButtonBlock(
$this->twig,
$this->translator,
$this->config,
$this->upgrader,
$this->upgradeSelfCheck,
$this->downloadPath,
$this->token,
$this->manualMode
))->render();
}
/**
* @return string
*/
private function getRollbackForm()
{
return (new RollbackForm($this->twig, $this->backupFinder))
->render();
}
/**
* @return string
*/
private function getBackupOptionsForm()
{
$formRenderer = new FormRenderer($this->config, $this->twig, $this->translator);
return (new BackupOptionsForm($this->translator, $formRenderer))
->render();
}
/**
* @return string
*/
private function getUpgradeOptionsForm()
{
$formRenderer = new FormRenderer($this->config, $this->twig, $this->translator);
return (new UpgradeOptionsForm($this->translator, $formRenderer))
->render();
}
/**
* @return array|null
*/
private function getErrorMessage()
{
$translator = $this->translator;
// PrestaShop demo mode
if (defined('_PS_MODE_DEMO_') && true == _PS_MODE_DEMO_) {
return array(
'message' => $translator->trans('This functionality has been disabled.', array(), self::TRANSLATION_DOMAIN),
);
}
if (!file_exists($this->autoupgradePath . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php')) {
return array(
'showWarningIcon' => true,
'message' => $translator->trans(
'[TECHNICAL ERROR] ajax-upgradetab.php is missing. Please reinstall or reset the module.',
array(),
self::TRANSLATION_DOMAIN
),
);
}
return array();
}
/**
* @param string $ajaxResult Json encoded response data
*
* @return array
*/
private function getJsParams($ajaxResult)
{
$translationDomain = self::TRANSLATION_DOMAIN;
// relative admin dir
$adminDir = trim(str_replace($this->prodRootPath, '', $this->adminPath), DIRECTORY_SEPARATOR);
$translator = $this->translator;
$jsParams = array(
'manualMode' => (bool) $this->manualMode,
'_PS_MODE_DEV_' => (defined('_PS_MODE_DEV_') && true == _PS_MODE_DEV_),
'PS_AUTOUP_BACKUP' => (bool) $this->config->get('PS_AUTOUP_BACKUP'),
'adminDir' => $adminDir,
'adminUrl' => __PS_BASE_URI__ . $adminDir,
'token' => $this->token,
'txtError' => $this->_getJsErrorMsgs(),
'firstTimeParams' => json_decode($ajaxResult),
'ajaxUpgradeTabExists' => file_exists($this->autoupgradePath . DIRECTORY_SEPARATOR . 'ajax-upgradetab.php'),
'currentIndex' => $this->currentIndex,
'tab' => 'AdminSelfUpgrade',
'channel' => $this->config->get('channel'),
'translation' => array(
'confirmDeleteBackup' => $translator->trans('Are you sure you want to delete this backup?', array(), $translationDomain),
'delete' => $translator->trans('Delete', array(), 'Admin.Actions'),
'updateInProgress' => $translator->trans('An update is currently in progress... Click "OK" to abort.', array(), $translationDomain),
'upgradingPrestaShop' => $translator->trans('Upgrading PrestaShop', array(), $translationDomain),
'upgradeComplete' => $translator->trans('Upgrade complete', array(), $translationDomain),
'upgradeCompleteWithWarnings' => $translator->trans('Upgrade complete, but warning notifications has been found.', array(), $translationDomain),
'todoList' => array(
$translator->trans('Cookies have changed, you will need to log in again once you refreshed the page', array(), $translationDomain),
$translator->trans('Javascript and CSS files have changed, please clear your browser cache with CTRL-F5', array(), $translationDomain),
$translator->trans('Please check that your front-office theme is functional (try to create an account, place an order...)', array(), $translationDomain),
$translator->trans('Product images do not appear in the front-office? Try regenerating the thumbnails in Preferences > Images', array(), $translationDomain),
$translator->trans('Do not forget to reactivate your shop once you have checked everything!', array(), $translationDomain),
),
'todoListTitle' => $translator->trans('ToDo list:', array(), $translationDomain),
'startingRestore' => $translator->trans('Starting restoration...', array(), $translationDomain),
'restoreComplete' => $translator->trans('Restoration complete.', array(), $translationDomain),
'cannotDownloadFile' => $translator->trans('Your server cannot download the file. Please upload it first by ftp in your admin/autoupgrade directory', array(), $translationDomain),
'jsonParseErrorForAction' => $translator->trans('Javascript error (parseJSON) detected for action ', array(), $translationDomain),
'manuallyGoToButton' => $translator->trans('Manually go to %s button', array(), $translationDomain),
'endOfProcess' => $translator->trans('End of process', array(), $translationDomain),
'processCancelledCheckForRestore' => $translator->trans('Operation canceled. Checking for restoration...', array(), $translationDomain),
'confirmRestoreBackup' => $translator->trans('Do you want to restore %s?', array($this->backupName), $translationDomain),
'processCancelledWithError' => $translator->trans('Operation canceled. An error happened.', array(), $translationDomain),
'missingAjaxUpgradeTab' => $translator->trans('[TECHNICAL ERROR] ajax-upgradetab.php is missing. Please reinstall the module.', array(), $translationDomain),
'clickToRefreshAndUseNewConfiguration' => $translator->trans('Click to refresh the page and use the new configuration', array(), $translationDomain),
'errorDetectedDuring' => $translator->trans('Error detected during', array(), $translationDomain),
'downloadTimeout' => $translator->trans('The request exceeded the max_time_limit. Please change your server configuration.', array(), $translationDomain),
'seeOrHideList' => $translator->trans('See or hide the list', array(), $translationDomain),
'coreFiles' => $translator->trans('Core file(s)', array(), $translationDomain),
'mailFiles' => $translator->trans('Mail file(s)', array(), $translationDomain),
'translationFiles' => $translator->trans('Translation file(s)', array(), $translationDomain),
'linkAndMd5CannotBeEmpty' => $translator->trans('Link and MD5 hash cannot be empty', array(), $translationDomain),
'needToEnterArchiveVersionNumber' => $translator->trans('You need to enter the version number associated with the archive.', array(), $translationDomain),
'noArchiveSelected' => $translator->trans('No archive has been selected.', array(), $translationDomain),
'needToEnterDirectoryVersionNumber' => $translator->trans('You need to enter the version number associated with the directory.', array(), $translationDomain),
'confirmSkipBackup' => $translator->trans('Please confirm that you want to skip the backup.', array(), $translationDomain),
'confirmPreserveFileOptions' => $translator->trans('Please confirm that you want to preserve file options.', array(), $translationDomain),
'lessOptions' => $translator->trans('Less options', array(), $translationDomain),
'moreOptions' => $translator->trans('More options (Expert mode)', array(), $translationDomain),
'filesWillBeDeleted' => $translator->trans('These files will be deleted', array(), $translationDomain),
'filesWillBeReplaced' => $translator->trans('These files will be replaced', array(), $translationDomain),
),
);
return $jsParams;
}
/**
* @return array
*/
private function _getJsErrorMsgs()
{
$translationDomain = self::TRANSLATION_DOMAIN;
$translator = $this->translator;
$ret = array(
0 => $translator->trans('Required field', array(), $translationDomain),
1 => $translator->trans('Too long!', array(), $translationDomain),
2 => $translator->trans('Fields are different!', array(), $translationDomain),
3 => $translator->trans('This email address is wrong!', array(), $translationDomain),
4 => $translator->trans('Impossible to send the email!', array(), $translationDomain),
5 => $translator->trans('Cannot create settings file, if /app/config/parameters.php exists, please give the public write permissions to this file, else please create a file named parameters.php in config directory.', array(), $translationDomain),
6 => $translator->trans('Cannot write settings file, please create a file named settings.inc.php in the "config" directory.', array(), $translationDomain),
7 => $translator->trans('Impossible to upload the file!', array(), $translationDomain),
8 => $translator->trans('Data integrity is not valid. Hack attempt?', array(), $translationDomain),
9 => $translator->trans('Impossible to read the content of a MySQL content file.', array(), $translationDomain),
10 => $translator->trans('Cannot access a MySQL content file.', array(), $translationDomain),
11 => $translator->trans('Error while inserting data in the database:', array(), $translationDomain),
12 => $translator->trans('The password is incorrect (must be alphanumeric string with at least 8 characters)', array(), 'Install'),
14 => $translator->trans('At least one table with same prefix was already found, please change your prefix or drop your database', array(), 'Install'),
15 => $translator->trans('This is not a valid file name.', array(), $translationDomain),
16 => $translator->trans('This is not a valid image file.', array(), $translationDomain),
17 => $translator->trans('Error while creating the /app/config/parameters.php file.', array(), $translationDomain),
18 => $translator->trans('Error:', array(), $translationDomain),
19 => $translator->trans('This PrestaShop database already exists. Please revalidate your authentication information to the database.', array(), $translationDomain),
22 => $translator->trans('An error occurred while resizing the picture.', array(), $translationDomain),
23 => $translator->trans('Database connection is available!', array(), $translationDomain),
24 => $translator->trans('Database Server is available but database is not found', array(), $translationDomain),
25 => $translator->trans('Database Server is not found. Please verify the login, password and server fields.', array(), $translationDomain),
26 => $translator->trans('An error occurred while sending email, please verify your parameters.', array(), $translationDomain),
// Upgrader
27 => $translator->trans('This installer is too old.', array(), $translationDomain),
28 => $translator->trans('You already have the %s version.', array($this->installVersion), $translationDomain),
29 => $translator->trans('There is no older version. Did you delete or rename the app/config/parameters.php file?', array(), $translationDomain),
30 => $translator->trans('The app/config/parameters.php file was not found. Did you delete or rename this file?', array(), $translationDomain),
31 => $translator->trans('Cannot find the SQL upgrade files. Please verify that the /install/upgrade/sql folder is not empty.', array(), $translationDomain),
32 => $translator->trans('No upgrade is possible.', array(), $translationDomain),
33 => $translator->trans('Error while loading SQL upgrade file.', array(), $translationDomain),
34 => $translator->trans('Error while inserting content into the database', array(), $translationDomain),
35 => $translator->trans('Unfortunately,', array(), $translationDomain),
36 => $translator->trans('SQL errors have occurred.', array(), $translationDomain),
37 => $translator->trans('The config/defines.inc.php file was not found. Where did you move it?', array(), $translationDomain),
// End of upgrader
38 => $translator->trans('Impossible to write the image /img/logo.jpg. If this image already exists, please delete it.', array(), $translationDomain),
39 => $translator->trans('The uploaded file exceeds the upload_max_filesize directive in php.ini', array(), $translationDomain),
40 => $translator->trans('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', array(), $translationDomain),
41 => $translator->trans('The uploaded file was only partially uploaded', array(), $translationDomain),
42 => $translator->trans('No file was uploaded.', array(), $translationDomain),
43 => $translator->trans('Missing a temporary folder', array(), $translationDomain),
44 => $translator->trans('Failed to write file to disk', array(), $translationDomain),
45 => $translator->trans('File upload stopped by extension', array(), $translationDomain),
46 => $translator->trans('Cannot convert your database\'s data to utf-8.', array(), $translationDomain),
47 => $translator->trans('Invalid shop name', array(), 'Install'),
48 => $translator->trans('Your firstname contains some invalid characters', array(), 'Install'),
49 => $translator->trans('Your lastname contains some invalid characters', array(), $translationDomain),
50 => $translator->trans('Your database server does not support the utf-8 charset.', array(), 'Install'),
51 => $translator->trans('Your MySQL server does not support this engine, please use another one like MyISAM', array(), $translationDomain),
52 => $translator->trans('The file /img/logo.jpg is not writable, please CHMOD 755 this file or CHMOD 777', array(), $translationDomain),
53 => $translator->trans('Invalid catalog mode', array(), $translationDomain),
999 => $translator->trans('No error code available', array(), $translationDomain),
);
return $ret;
}
}

View File

@@ -0,0 +1,357 @@
<?php
/**
* 2007-2017 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use Configuration;
use ConfigurationTest;
class UpgradeSelfCheck
{
/**
* @var bool
*/
private $fOpenOrCurlEnabled;
/**
* @var bool
*/
private $zipEnabled;
/**
* @var bool
*/
private $rootDirectoryWritable;
/**
* @var bool
*/
private $adminAutoUpgradeDirectoryWritable;
/**
* @var string
*/
private $adminAutoUpgradeDirectoryWritableReport = '';
/**
* @var bool
*/
private $shopDeactivated;
/**
* @var bool
*/
private $cacheDisabled;
/**
* @var bool
*/
private $safeModeDisabled;
/**
* @var bool|mixed
*/
private $moduleVersionIsLatest;
/**
* @var string
*/
private $rootWritableReport = '';
/**
* @var false|string
*/
private $moduleVersion;
/**
* @var int
*/
private $maxExecutionTime;
/**
* @var bool
*/
private $prestashopReady;
/**
* @var string
*/
private $configDir = '/modules/autoupgrade/config.xml';
/**
* UpgradeSelfCheck constructor.
*
* @param Upgrader $upgrader
* @param string $prodRootPath
* @param string $adminPath
* @param string $autoUpgradePath
*/
public function __construct(Upgrader $upgrader, $prodRootPath, $adminPath, $autoUpgradePath)
{
$this->moduleVersion = $this->checkModuleVersion();
$this->fOpenOrCurlEnabled = ConfigurationTest::test_fopen() || extension_loaded('curl');
$this->zipEnabled = extension_loaded('zip');
$this->rootDirectoryWritable = $this->checkRootWritable();
$this->adminAutoUpgradeDirectoryWritable = $this->checkAdminDirectoryWritable($prodRootPath, $adminPath, $autoUpgradePath);
$this->shopDeactivated = $this->checkShopIsDeactivated();
$this->cacheDisabled = !(defined('_PS_CACHE_ENABLED_') && false != _PS_CACHE_ENABLED_);
$this->safeModeDisabled = $this->checkSafeModeIsDisabled();
$this->moduleVersionIsLatest = $this->checkModuleVersionIsLastest($upgrader);
$this->maxExecutionTime = $this->checkMaxExecutionTime();
$this->prestashopReady = $this->runPrestaShopCoreChecks();
}
/**
* @return bool
*/
public function isFOpenOrCurlEnabled()
{
return $this->fOpenOrCurlEnabled;
}
/**
* @return bool
*/
public function isZipEnabled()
{
return $this->zipEnabled;
}
/**
* @return bool
*/
public function isRootDirectoryWritable()
{
return $this->rootDirectoryWritable;
}
/**
* @return bool
*/
public function isAdminAutoUpgradeDirectoryWritable()
{
return $this->adminAutoUpgradeDirectoryWritable;
}
/**
* @return string
*/
public function getAdminAutoUpgradeDirectoryWritableReport()
{
return $this->adminAutoUpgradeDirectoryWritableReport;
}
/**
* @return bool
*/
public function isShopDeactivated()
{
return $this->shopDeactivated;
}
/**
* @return bool
*/
public function isCacheDisabled()
{
return $this->cacheDisabled;
}
/**
* @return bool
*/
public function isSafeModeDisabled()
{
return $this->safeModeDisabled;
}
/**
* @return bool
*/
public function isModuleVersionLatest()
{
return $this->moduleVersionIsLatest;
}
/**
* @return string
*/
public function getRootWritableReport()
{
return $this->rootWritableReport;
}
/**
* @return string|false
*/
public function getModuleVersion()
{
return $this->moduleVersion;
}
/**
* @return string
*/
public function getConfigDir()
{
return $this->configDir;
}
/**
* @return int
*/
public function getMaxExecutionTime()
{
return $this->maxExecutionTime;
}
public function isPrestaShopReady()
{
return $this->prestashopReady || 1 === (int) Configuration::get('PS_AUTOUP_IGNORE_REQS');
}
/**
* Indicates if the self check status allows going ahead with the upgrade.
*
* @return bool
*/
public function isOkForUpgrade()
{
return
$this->isFOpenOrCurlEnabled()
&& $this->isZipEnabled()
&& $this->isRootDirectoryWritable()
&& $this->isAdminAutoUpgradeDirectoryWritable()
&& $this->isShopDeactivated()
&& $this->isCacheDisabled()
&& $this->isModuleVersionLatest()
&& $this->isPrestaShopReady();
}
/**
* @return bool
*/
private function checkRootWritable()
{
// Root directory permissions cannot be checked recursively anymore, it takes too much time
return ConfigurationTest::test_dir('/', false, $this->rootWritableReport);
}
/**
* @param Upgrader $upgrader
*
* @return bool
*/
private function checkModuleVersionIsLastest(Upgrader $upgrader)
{
return version_compare($this->moduleVersion, $upgrader->autoupgrade_last_version, '>=');
}
/**
* @return string|false
*/
private function checkModuleVersion()
{
$configFilePath = _PS_ROOT_DIR_ . $this->configDir;
if (file_exists($configFilePath) && $xml_module_version = simplexml_load_file($configFilePath)) {
return (string) $xml_module_version->version;
}
return false;
}
/**
* @return bool
*/
private function checkShopIsDeactivated()
{
return
!Configuration::get('PS_SHOP_ENABLE')
|| (isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], array('127.0.0.1', 'localhost', '[::1]')));
}
/**
* @param string $prodRootPath
* @param string $adminPath
* @param string $adminAutoUpgradePath
*
* @return bool
*/
private function checkAdminDirectoryWritable($prodRootPath, $adminPath, $adminAutoUpgradePath)
{
$relativeDirectory = trim(str_replace($prodRootPath, '', $adminAutoUpgradePath), DIRECTORY_SEPARATOR);
return ConfigurationTest::test_dir(
$relativeDirectory,
false,
$this->adminAutoUpgradeDirectoryWritableReport
);
}
/**
* @return bool
*/
private function checkSafeModeIsDisabled()
{
$safeMode = @ini_get('safe_mode');
if (empty($safeMode)) {
$safeMode = '';
}
return !in_array(strtolower($safeMode), array(1, 'on'));
}
/**
* @return int
*/
private function checkMaxExecutionTime()
{
return (int) @ini_get('max_execution_time');
}
/**
* Ask the core to run its tests, if available.
*
* @return bool
*/
public function runPrestaShopCoreChecks()
{
if (!class_exists('ConfigurationTest')) {
return true;
}
$defaultTests = ConfigurationTest::check(ConfigurationTest::getDefaultTests());
foreach ($defaultTests as $testResult) {
if ($testResult !== 'ok') {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/*
* 2007-2019 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
class CacheCleaner
{
/**
* @var UpgradeContainer
*/
private $container;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(UpgradeContainer $container, LoggerInterface $logger)
{
$this->container = $container;
$this->logger = $logger;
}
public function cleanFolders()
{
$dirsToClean = array(
$this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/app/cache/',
$this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/cache/smarty/cache/',
$this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/cache/smarty/compile/',
$this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/var/cache/',
);
$defaultThemeNames = array(
'default',
'prestashop',
'default-boostrap',
'classic',
);
if (defined('_THEME_NAME_') && $this->container->getUpgradeConfiguration()->shouldUpdateDefaultTheme() && in_array(_THEME_NAME_, $defaultThemeNames)) {
$dirsToClean[] = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/themes/' . _THEME_NAME_ . '/cache/';
}
foreach ($dirsToClean as $dir) {
if (!file_exists($dir)) {
$this->logger->debug($this->container->getTranslator()->trans('[SKIP] directory "%s" does not exist and cannot be emptied.', array(str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $dir)), 'Modules.Autoupgrade.Admin'));
continue;
}
foreach (scandir($dir) as $file) {
if ($file[0] === '.' || $file === 'index.php') {
continue;
}
// ToDo: Use Filesystem instead ?
if (is_file($dir . $file)) {
unlink($dir . $file);
} elseif (is_dir($dir . $file . DIRECTORY_SEPARATOR)) {
FilesystemAdapter::deleteDirectory($dir . $file . DIRECTORY_SEPARATOR);
}
$this->logger->debug($this->container->getTranslator()->trans('[CLEANING CACHE] File %s removed', array($file), 'Modules.Autoupgrade.Admin'));
}
}
}
}

View File

@@ -0,0 +1,691 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools\CoreUpgrader;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\ThemeAdapter;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
/**
* Class used to modify the core of PrestaShop, on the files are copied on the filesystem.
* It will run subtasks such as database upgrade, language upgrade etc.
*/
abstract class CoreUpgrader
{
/**
* @var UpgradeContainer
*/
protected $container;
/**
* @var \Db
*/
protected $db;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* Version PrestaShop is upgraded to.
*
* @var string
*/
protected $destinationUpgradeVersion;
/**
* Path to the temporary install folder, where upgrade files can be found
*
* @var string
*/
protected $pathToInstallFolder;
/**
* Path to the folder containing PHP upgrade files
*
* @var string
*/
protected $pathToPhpUpgradeScripts;
public function __construct(UpgradeContainer $container, LoggerInterface $logger)
{
$this->container = $container;
$this->logger = $logger;
}
public function doUpgrade()
{
$this->initConstants();
$oldversion = $this->getPreUpgradeVersion();
$this->checkVersionIsNewer($oldversion);
//check DB access
error_reporting(E_ALL);
$resultDB = \Db::checkConnection(_DB_SERVER_, _DB_USER_, _DB_PASSWD_, _DB_NAME_);
if ($resultDB !== 0) {
throw new UpgradeException($this->container->getTranslator()->trans('Invalid database configuration', array(), 'Modules.Autoupgrade.Admin'));
}
if ($this->container->getUpgradeConfiguration()->shouldDeactivateCustomModules()) {
$this->disableCustomModules();
}
$this->upgradeDb($oldversion);
// At this point, database upgrade is over.
// Now we need to add all previous missing settings items, and reset cache and compile directories
$this->writeNewSettings();
$this->runRecurrentQueries();
$this->logger->debug($this->container->getTranslator()->trans('Database upgrade OK', array(), 'Modules.Autoupgrade.Admin')); // no error!
$this->upgradeLanguages();
$this->generateHtaccess();
$this->cleanXmlFiles();
if ($this->container->getUpgradeConfiguration()->shouldDeactivateCustomModules()) {
$this->disableOverrides();
}
$this->updateTheme();
$this->runCoreCacheClean();
if ($this->container->getState()->getWarningExists()) {
$this->logger->warning($this->container->getTranslator()->trans('Warning detected during upgrade.', array(), 'Modules.Autoupgrade.Admin'));
} else {
$this->logger->info($this->container->getTranslator()->trans('Database upgrade completed', array(), 'Modules.Autoupgrade.Admin'));
}
}
protected function initConstants()
{
// Initialize
// setting the memory limit to 128M only if current is lower
$memory_limit = ini_get('memory_limit');
if ((substr($memory_limit, -1) != 'G')
&& ((substr($memory_limit, -1) == 'M' && substr($memory_limit, 0, -1) < 512)
|| is_numeric($memory_limit) && ((int) $memory_limit < 131072))
) {
@ini_set('memory_limit', '512M');
}
// Redefine REQUEST_URI if empty (on some webservers...)
if (!isset($_SERVER['REQUEST_URI']) || empty($_SERVER['REQUEST_URI'])) {
if (!isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['SCRIPT_FILENAME'])) {
$_SERVER['SCRIPT_NAME'] = $_SERVER['SCRIPT_FILENAME'];
}
if (isset($_SERVER['SCRIPT_NAME'])) {
if (basename($_SERVER['SCRIPT_NAME']) == 'index.php' && empty($_SERVER['QUERY_STRING'])) {
$_SERVER['REQUEST_URI'] = dirname($_SERVER['SCRIPT_NAME']) . '/';
} else {
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
}
}
}
}
$_SERVER['REQUEST_URI'] = str_replace('//', '/', $_SERVER['REQUEST_URI']);
$this->destinationUpgradeVersion = $this->container->getState()->getInstallVersion();
$this->pathToInstallFolder = realpath($this->container->getProperty(UpgradeContainer::LATEST_PATH) . DIRECTORY_SEPARATOR . 'install');
// Kept for backward compatbility (unknown consequences on old versions of PrestaShop)
define('INSTALL_VERSION', $this->destinationUpgradeVersion);
// 1.4
define('INSTALL_PATH', $this->pathToInstallFolder);
// 1.5 ...
if (!defined('_PS_CORE_DIR_')) {
define('_PS_CORE_DIR_', _PS_ROOT_DIR_);
}
define('PS_INSTALLATION_IN_PROGRESS', true);
define('SETTINGS_FILE_PHP', $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/app/config/parameters.php');
define('SETTINGS_FILE_YML', $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/app/config/parameters.yml');
define('DEFINES_FILE', $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/config/defines.inc.php');
define('INSTALLER__PS_BASE_URI', substr($_SERVER['REQUEST_URI'], 0, -1 * (strlen($_SERVER['REQUEST_URI']) - strrpos($_SERVER['REQUEST_URI'], '/')) - strlen(substr(dirname($_SERVER['REQUEST_URI']), strrpos(dirname($_SERVER['REQUEST_URI']), '/') + 1))));
// define('INSTALLER__PS_BASE_URI_ABSOLUTE', 'http://'.ToolsInstall::getHttpHost(false, true).INSTALLER__PS_BASE_URI);
define('_PS_INSTALL_PATH_', $this->pathToInstallFolder . '/');
define('_PS_INSTALL_DATA_PATH_', _PS_INSTALL_PATH_ . 'data/');
define('_PS_INSTALL_CONTROLLERS_PATH_', _PS_INSTALL_PATH_ . 'controllers/');
define('_PS_INSTALL_MODELS_PATH_', _PS_INSTALL_PATH_ . 'models/');
define('_PS_INSTALL_LANGS_PATH_', _PS_INSTALL_PATH_ . 'langs/');
define('_PS_INSTALL_FIXTURES_PATH_', _PS_INSTALL_PATH_ . 'fixtures/');
if (function_exists('date_default_timezone_set')) {
date_default_timezone_set('Europe/Paris');
}
// if _PS_ROOT_DIR_ is defined, use it instead of "guessing" the module dir.
if (defined('_PS_ROOT_DIR_') && !defined('_PS_MODULE_DIR_')) {
define('_PS_MODULE_DIR_', _PS_ROOT_DIR_ . '/modules/');
} elseif (!defined('_PS_MODULE_DIR_')) {
define('_PS_MODULE_DIR_', $this->pathToInstallFolder . '/../modules/');
}
$upgrade_dir_php = 'upgrade/php';
if (!file_exists($this->pathToInstallFolder . DIRECTORY_SEPARATOR . $upgrade_dir_php)) {
$upgrade_dir_php = 'php';
if (!file_exists($this->pathToInstallFolder . DIRECTORY_SEPARATOR . $upgrade_dir_php)) {
throw new UpgradeException($this->container->getTranslator()->trans('/install/upgrade/php directory is missing in archive or directory', array(), 'Modules.Autoupgrade.Admin'));
}
}
$this->pathToPhpUpgradeScripts = $this->pathToInstallFolder . DIRECTORY_SEPARATOR . $upgrade_dir_php . DIRECTORY_SEPARATOR;
define('_PS_INSTALLER_PHP_UPGRADE_DIR_', $this->pathToPhpUpgradeScripts);
if (!defined('__PS_BASE_URI__')) {
define('__PS_BASE_URI__', realpath(dirname($_SERVER['SCRIPT_NAME'])) . '/../../');
}
if (!defined('_THEMES_DIR_')) {
define('_THEMES_DIR_', __PS_BASE_URI__ . 'themes/');
}
if (file_exists($this->pathToInstallFolder . DIRECTORY_SEPARATOR . 'autoload.php')) {
require_once $this->pathToInstallFolder . DIRECTORY_SEPARATOR . 'autoload.php';
}
$this->db = \Db::getInstance();
}
protected function getPreUpgradeVersion()
{
return $this->normalizeVersion(\Configuration::get('PS_VERSION_DB'));
}
/**
* Add missing levels in version.
* Example: 1.7 will become 1.7.0.0.
*
* @param string $version
*
* @return string
*
* @internal public for tests
*/
public function normalizeVersion($version)
{
$arrayVersion = explode('.', $version);
if (count($arrayVersion) < 4) {
$arrayVersion = array_pad($arrayVersion, 4, '0');
}
return implode('.', $arrayVersion);
}
protected function checkVersionIsNewer($oldVersion)
{
if (strpos($this->destinationUpgradeVersion, '.') === false) {
throw new UpgradeException($this->container->getTranslator()->trans('%s is not a valid version number.', array($this->destinationUpgradeVersion), 'Modules.Autoupgrade.Admin'));
}
$versionCompare = version_compare($this->destinationUpgradeVersion, $oldVersion);
if ($versionCompare === -1) {
throw new UpgradeException(
$this->container->getTranslator()->trans('[ERROR] Version to install is too old.', array(), 'Modules.Autoupgrade.Admin')
. ' ' .
$this->container->getTranslator()->trans(
'Current version: %oldversion%. Version to install: %newversion%.',
array(
'%oldversion%' => $oldVersion,
'%newversion%' => $this->destinationUpgradeVersion,
),
'Modules.Autoupgrade.Admin'
));
} elseif ($versionCompare === 0) {
throw new UpgradeException($this->container->getTranslator()->trans('You already have the %s version.', array($this->destinationUpgradeVersion), 'Modules.Autoupgrade.Admin'));
}
}
/**
* Ask the core to disable the modules not coming from PrestaShop.
*/
protected function disableCustomModules()
{
$this->container->getModuleAdapter()->disableNonNativeModules($this->pathToPhpUpgradeScripts);
}
protected function upgradeDb($oldversion)
{
$upgrade_dir_sql = $this->pathToInstallFolder . '/upgrade/sql';
$sqlContentVersion = $this->applySqlParams(
$this->getUpgradeSqlFilesListToApply($upgrade_dir_sql, $oldversion));
foreach ($sqlContentVersion as $upgrade_file => $sqlContent) {
foreach ($sqlContent as $query) {
$this->runQuery($upgrade_file, $query);
}
}
}
protected function getUpgradeSqlFilesListToApply($upgrade_dir_sql, $oldversion)
{
if (!file_exists($upgrade_dir_sql)) {
throw new UpgradeException($this->container->getTranslator()->trans('Unable to find upgrade directory in the installation path.', array(), 'Modules.Autoupgrade.Admin'));
}
$upgradeFiles = $neededUpgradeFiles = array();
if ($handle = opendir($upgrade_dir_sql)) {
while (false !== ($file = readdir($handle))) {
if ($file[0] === '.') {
continue;
}
if (!is_readable($upgrade_dir_sql . DIRECTORY_SEPARATOR . $file)) {
throw new UpgradeException($this->container->getTranslator()->trans('Error while loading SQL upgrade file "%s".', array($file), 'Modules.Autoupgrade.Admin'));
}
$upgradeFiles[] = str_replace('.sql', '', $file);
}
closedir($handle);
}
if (empty($upgradeFiles)) {
throw new UpgradeException($this->container->getTranslator()->trans('Cannot find the SQL upgrade files. Please check that the %s folder is not empty.', array($upgrade_dir_sql), 'Modules.Autoupgrade.Admin'));
}
natcasesort($upgradeFiles);
foreach ($upgradeFiles as $version) {
if (version_compare($version, $oldversion) == 1 && version_compare($this->destinationUpgradeVersion, $version) != -1) {
$neededUpgradeFiles[$version] = $upgrade_dir_sql . DIRECTORY_SEPARATOR . $version . '.sql';
}
}
return $neededUpgradeFiles;
}
/**
* Replace some placeholders in the SQL upgrade files (prefix, engine...).
*
* @param array $sqlFiles
*
* @return array of SQL requests per version
*/
protected function applySqlParams(array $sqlFiles)
{
$search = array('PREFIX_', 'ENGINE_TYPE');
$replace = array(_DB_PREFIX_, (defined('_MYSQL_ENGINE_') ? _MYSQL_ENGINE_ : 'MyISAM'));
$sqlRequests = array();
foreach ($sqlFiles as $version => $file) {
$sqlContent = file_get_contents($file) . "\n";
$sqlContent = str_replace($search, $replace, $sqlContent);
$sqlContent = preg_split("/;\s*[\r\n]+/", $sqlContent);
$sqlRequests[$version] = $sqlContent;
}
return $sqlRequests;
}
/**
* ToDo, check to move this in a database class.
*
* @param string $upgrade_file File in which the request is stored (for logs)
* @param string $query
*/
protected function runQuery($upgrade_file, $query)
{
$query = trim($query);
if (empty($query)) {
return;
}
// If php code have to be executed
if (strpos($query, '/* PHP:') !== false) {
return $this->runPhpQuery($upgrade_file, $query);
}
$this->runSqlQuery($upgrade_file, $query);
}
protected function runPhpQuery($upgrade_file, $query)
{
// Parsing php code
$pos = strpos($query, '/* PHP:') + strlen('/* PHP:');
$phpString = substr($query, $pos, strlen($query) - $pos - strlen(' */;'));
$php = explode('::', $phpString);
preg_match('/\((.*)\)/', $phpString, $pattern);
$paramsString = trim($pattern[0], '()');
preg_match_all('/([^,]+),? ?/', $paramsString, $parameters);
$parameters = (isset($parameters[1]) && is_array($parameters[1])) ?
$parameters[1] :
array();
foreach ($parameters as &$parameter) {
$parameter = str_replace('\'', '', $parameter);
}
// reset phpRes to a null value
$phpRes = null;
// Call a simple function
if (strpos($phpString, '::') === false) {
$func_name = str_replace($pattern[0], '', $php[0]);
if (!file_exists($this->pathToPhpUpgradeScripts . strtolower($func_name) . '.php')) {
$this->logger->error('[ERROR] ' . $upgrade_file . ' PHP - missing file ' . $query);
$this->container->getState()->setWarningExists(true);
} else {
require_once $this->pathToPhpUpgradeScripts . strtolower($func_name) . '.php';
$phpRes = call_user_func_array($func_name, $parameters);
}
}
// Or an object method
else {
$func_name = array($php[0], str_replace($pattern[0], '', $php[1]));
$this->logger->error('[ERROR] ' . $upgrade_file . ' PHP - Object Method call is forbidden (' . $php[0] . '::' . str_replace($pattern[0], '', $php[1]) . ')');
$this->container->getState()->setWarningExists(true);
}
if (isset($phpRes) && (is_array($phpRes) && !empty($phpRes['error'])) || $phpRes === false) {
$this->logger->error('
[ERROR] PHP ' . $upgrade_file . ' ' . $query . "\n" . '
' . (empty($phpRes['error']) ? '' : $phpRes['error'] . "\n") . '
' . (empty($phpRes['msg']) ? '' : ' - ' . $phpRes['msg'] . "\n"));
$this->container->getState()->setWarningExists(true);
} else {
$this->logger->debug('<div class="upgradeDbOk">[OK] PHP ' . $upgrade_file . ' : ' . $query . '</div>');
}
}
protected function runSqlQuery($upgrade_file, $query)
{
if (strstr($query, 'CREATE TABLE') !== false) {
$pattern = '/CREATE TABLE.*[`]*' . _DB_PREFIX_ . '([^`]*)[`]*\s\(/';
preg_match($pattern, $query, $matches);
if (!empty($matches[1])) {
$drop = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . $matches[1] . '`;';
if ($this->db->execute($drop, false)) {
$this->logger->debug('<div class="upgradeDbOk">' . $this->container->getTranslator()->trans('[DROP] SQL %s table has been dropped.', array('`' . _DB_PREFIX_ . $matches[1] . '`'), 'Modules.Autoupgrade.Admin') . '</div>');
}
}
}
if ($this->db->execute($query, false)) {
$this->logger->debug('<div class="upgradeDbOk">[OK] SQL ' . $upgrade_file . ' ' . $query . '</div>');
return;
}
$error = $this->db->getMsgError();
$error_number = $this->db->getNumberError();
$this->logger->warning('
<div class="upgradeDbError">
[WARNING] SQL ' . $upgrade_file . '
' . $error_number . ' in ' . $query . ': ' . $error . '</div>');
$duplicates = array('1050', '1054', '1060', '1061', '1062', '1091');
if (!in_array($error_number, $duplicates)) {
$this->logger->error('SQL ' . $upgrade_file . ' ' . $error_number . ' in ' . $query . ': ' . $error);
$this->container->getState()->setWarningExists(true);
}
}
public function writeNewSettings()
{
// Do nothing
}
protected function runRecurrentQueries()
{
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `name` = \'PS_LEGACY_IMAGES\' WHERE name LIKE \'0\' AND `value` = 1');
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `value` = 0 WHERE `name` LIKE \'PS_LEGACY_IMAGES\'');
if ($this->db->getValue('SELECT COUNT(id_product_download) FROM `' . _DB_PREFIX_ . 'product_download` WHERE `active` = 1') > 0) {
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `value` = 1 WHERE `name` LIKE \'PS_VIRTUAL_PROD_FEATURE_ACTIVE\'');
}
// Exported from the end of doUpgrade()
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET value="0" WHERE name = "PS_HIDE_OPTIMIZATION_TIS"', false);
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET value="1" WHERE name = "PS_NEED_REBUILD_INDEX"', false);
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET value="' . $this->destinationUpgradeVersion . '" WHERE name = "PS_VERSION_DB"', false);
}
protected function upgradeLanguages()
{
if (!defined('_PS_TOOL_DIR_')) {
define('_PS_TOOL_DIR_', _PS_ROOT_DIR_ . '/tools/');
}
if (!defined('_PS_TRANSLATIONS_DIR_')) {
define('_PS_TRANSLATIONS_DIR_', _PS_ROOT_DIR_ . '/translations/');
}
if (!defined('_PS_MODULES_DIR_')) {
define('_PS_MODULES_DIR_', _PS_ROOT_DIR_ . '/modules/');
}
if (!defined('_PS_MAILS_DIR_')) {
define('_PS_MAILS_DIR_', _PS_ROOT_DIR_ . '/mails/');
}
$langs = $this->db->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'lang` WHERE `active` = 1');
if (!is_array($langs)) {
return;
}
foreach ($langs as $lang) {
$this->upgradeLanguage($lang);
}
}
abstract protected function upgradeLanguage($lang);
protected function generateHtaccess()
{
$this->loadEntityInterface();
if (file_exists(_PS_ROOT_DIR_ . '/classes/Tools.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Tools.php';
}
if (!class_exists('ToolsCore') || !method_exists('ToolsCore', 'generateHtaccess')) {
return;
}
$url_rewrite = (bool) $this->db->getvalue('SELECT `value` FROM `' . _DB_PREFIX_ . 'configuration` WHERE name=\'PS_REWRITING_SETTINGS\'');
if (!defined('_MEDIA_SERVER_1_')) {
define('_MEDIA_SERVER_1_', '');
}
if (!defined('_PS_USE_SQL_SLAVE_')) {
define('_PS_USE_SQL_SLAVE_', false);
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/ObjectModel.php')) {
require_once _PS_ROOT_DIR_ . '/classes/ObjectModel.php';
}
if (!class_exists('ObjectModel', false) && class_exists('ObjectModelCore')) {
eval('abstract class ObjectModel extends ObjectModelCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Configuration.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Configuration.php';
}
if (!class_exists('Configuration', false) && class_exists('ConfigurationCore')) {
eval('class Configuration extends ConfigurationCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/cache/Cache.php')) {
require_once _PS_ROOT_DIR_ . '/classes/cache/Cache.php';
}
if (!class_exists('Cache', false) && class_exists('CacheCore')) {
eval('abstract class Cache extends CacheCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/PrestaShopCollection.php')) {
require_once _PS_ROOT_DIR_ . '/classes/PrestaShopCollection.php';
}
if (!class_exists('PrestaShopCollection', false) && class_exists('PrestaShopCollectionCore')) {
eval('class PrestaShopCollection extends PrestaShopCollectionCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/shop/ShopUrl.php')) {
require_once _PS_ROOT_DIR_ . '/classes/shop/ShopUrl.php';
}
if (!class_exists('ShopUrl', false) && class_exists('ShopUrlCore')) {
eval('class ShopUrl extends ShopUrlCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/shop/Shop.php')) {
require_once _PS_ROOT_DIR_ . '/classes/shop/Shop.php';
}
if (!class_exists('Shop', false) && class_exists('ShopCore')) {
eval('class Shop extends ShopCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Translate.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Translate.php';
}
if (!class_exists('Translate', false) && class_exists('TranslateCore')) {
eval('class Translate extends TranslateCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/module/Module.php')) {
require_once _PS_ROOT_DIR_ . '/classes/module/Module.php';
}
if (!class_exists('Module', false) && class_exists('ModuleCore')) {
eval('class Module extends ModuleCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Validate.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Validate.php';
}
if (!class_exists('Validate', false) && class_exists('ValidateCore')) {
eval('class Validate extends ValidateCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Language.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Language.php';
}
if (!class_exists('Language', false) && class_exists('LanguageCore')) {
eval('class Language extends LanguageCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Tab.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Tab.php';
}
if (!class_exists('Tab', false) && class_exists('TabCore')) {
eval('class Tab extends TabCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Dispatcher.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Dispatcher.php';
}
if (!class_exists('Dispatcher', false) && class_exists('DispatcherCore')) {
eval('class Dispatcher extends DispatcherCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Hook.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Hook.php';
}
if (!class_exists('Hook', false) && class_exists('HookCore')) {
eval('class Hook extends HookCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Context.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Context.php';
}
if (!class_exists('Context', false) && class_exists('ContextCore')) {
eval('class Context extends ContextCore{}');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/Group.php')) {
require_once _PS_ROOT_DIR_ . '/classes/Group.php';
}
if (!class_exists('Group', false) && class_exists('GroupCore')) {
eval('class Group extends GroupCore{}');
}
\ToolsCore::generateHtaccess(null, $url_rewrite);
}
protected function loadEntityInterface()
{
require_once _PS_ROOT_DIR_ . '/src/Core/Foundation/Database/EntityInterface.php';
}
protected function cleanXmlFiles()
{
$files = array(
$this->container->getProperty(UpgradeContainer::PS_ADMIN_PATH) . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'header.tpl',
_PS_ROOT_DIR_ . '/app/cache/dev/class_index.php',
_PS_ROOT_DIR_ . '/app/cache/prod/class_index.php',
_PS_ROOT_DIR_ . '/cache/class_index.php',
_PS_ROOT_DIR_ . '/config/xml/blog-fr.xml',
_PS_ROOT_DIR_ . '/config/xml/default_country_modules_list.xml',
_PS_ROOT_DIR_ . '/config/xml/modules_list.xml',
_PS_ROOT_DIR_ . '/config/xml/modules_native_addons.xml',
_PS_ROOT_DIR_ . '/config/xml/must_have_modules_list.xml',
_PS_ROOT_DIR_ . '/config/xml/tab_modules_list.xml',
_PS_ROOT_DIR_ . '/config/xml/trusted_modules_list.xml',
_PS_ROOT_DIR_ . '/config/xml/untrusted_modules_list.xml',
_PS_ROOT_DIR_ . '/var/cache/dev/class_index.php',
_PS_ROOT_DIR_ . '/var/cache/prod/class_index.php',
);
foreach ($files as $path) {
if (file_exists($path)) {
unlink($path);
}
}
}
protected function disableOverrides()
{
$exist = $this->db->getValue('SELECT `id_configuration` FROM `' . _DB_PREFIX_ . 'configuration` WHERE `name` LIKE \'PS_DISABLE_OVERRIDES\'');
if ($exist) {
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET value = 1 WHERE `name` LIKE \'PS_DISABLE_OVERRIDES\'');
} else {
$this->db->execute('INSERT INTO `' . _DB_PREFIX_ . 'configuration` (name, value, date_add, date_upd) VALUES ("PS_DISABLE_OVERRIDES", 1, NOW(), NOW())');
}
if (file_exists(_PS_ROOT_DIR_ . '/classes/PrestaShopAutoload.php')) {
require_once _PS_ROOT_DIR_ . '/classes/PrestaShopAutoload.php';
}
if (class_exists('PrestaShopAutoload') && method_exists('PrestaShopAutoload', 'generateIndex')) {
\PrestaShopAutoload::getInstance()->_include_override_path = false;
\PrestaShopAutoload::getInstance()->generateIndex();
}
}
protected function updateTheme()
{
$themeAdapter = new ThemeAdapter($this->db, $this->destinationUpgradeVersion);
$themeName = $themeAdapter->getDefaultTheme();
// The merchant can ask for keeping its current theme.
if (!$this->container->getUpgradeConfiguration()->shouldSwitchToDefaultTheme()) {
return;
}
$themeErrors = $themeAdapter->enableTheme($themeName);
if ($themeErrors !== true) {
throw new UpgradeException($themeErrors);
}
}
protected function runCoreCacheClean()
{
\Tools::clearCache();
}
}

View File

@@ -0,0 +1,186 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools\CoreUpgrader;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\FilesystemAdapter;
use PrestaShop\Module\AutoUpgrade\UpgradeTools\SettingsFileWriter;
class CoreUpgrader16 extends CoreUpgrader
{
/**
* Complete path to the settings.inc.php
*
* @var string
*/
private $pathToSettingsFile;
/**
* Generate a new settings file.
*/
public function writeNewSettings()
{
if (!defined('_PS_CACHE_ENABLED_')) {
define('_PS_CACHE_ENABLED_', '0');
}
$caches = array('CacheMemcache', 'CacheApc', 'CacheFs', 'CacheMemcached',
'CacheXcache', );
$datas = array(
'_DB_SERVER_' => _DB_SERVER_,
'_DB_NAME_' => _DB_NAME_,
'_DB_USER_' => _DB_USER_,
'_DB_PASSWD_' => _DB_PASSWD_,
'_DB_PREFIX_' => _DB_PREFIX_,
'_MYSQL_ENGINE_' => _MYSQL_ENGINE_,
'_PS_CACHING_SYSTEM_' => ((defined('_PS_CACHING_SYSTEM_') && in_array(_PS_CACHING_SYSTEM_, $caches)) ? _PS_CACHING_SYSTEM_ : 'CacheMemcache'),
'_PS_CACHE_ENABLED_' => _PS_CACHE_ENABLED_,
'_COOKIE_KEY_' => _COOKIE_KEY_,
'_COOKIE_IV_' => _COOKIE_IV_,
'_PS_CREATION_DATE_' => defined('_PS_CREATION_DATE_') ? _PS_CREATION_DATE_ : date('Y-m-d'),
'_PS_VERSION_' => $this->destinationUpgradeVersion,
'_PS_DIRECTORY_' => __PS_BASE_URI__,
);
if (defined('_RIJNDAEL_KEY_') && defined('_RIJNDAEL_IV_')) {
$datas['_RIJNDAEL_KEY_'] = _RIJNDAEL_KEY_;
$datas['_RIJNDAEL_IV_'] = _RIJNDAEL_IV_;
} elseif (function_exists('openssl_encrypt')) {
$datas['_RIJNDAEL_KEY_'] = Tools14::passwdGen(32);
$datas['_RIJNDAEL_IV_'] = base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES-128-CBC')));
} elseif (function_exists('mcrypt_encrypt')) {
$datas['_RIJNDAEL_KEY_'] = Tools14::passwdGen(mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
$datas['_RIJNDAEL_IV_'] = base64_encode(mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND));
}
$writer = new SettingsFileWriter($this->container->getTranslator());
$writer->writeSettingsFile($this->pathToSettingsFile, $datas);
$this->logger->debug($this->container->getTranslator()->trans('Settings file updated', array(), 'Modules.Autoupgrade.Admin'));
}
protected function initConstants()
{
parent::initConstants();
$this->pathToSettingsFile = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/config/settings.inc.php';
// Kept for potential BC with old PS versions
define('SETTINGS_FILE', $this->pathToSettingsFile);
}
protected function getPreUpgradeVersion()
{
if (!file_exists($this->pathToSettingsFile)) {
throw new UpgradeException($this->container->getTranslator()->trans('The config/settings.inc.php file was not found.', array(), 'Modules.Autoupgrade.Admin'));
}
include_once $this->pathToSettingsFile;
return _PS_VERSION_;
}
protected function upgradeLanguage($lang)
{
require_once _PS_TOOL_DIR_ . 'tar/Archive_Tar.php';
$lang_pack = json_decode(Tools14::file_get_contents('http' . (extension_loaded('openssl')
? 's' : '') . '://www.prestashop.com/download/lang_packs/get_language_pack.php?version=' . $this->destinationUpgradeVersion . '&iso_lang=' . $lang['iso_code']));
if (!$lang_pack) {
return;
}
if ($content = Tools14::file_get_contents('http' . (extension_loaded('openssl')
? 's' : '') . '://translations.prestashop.com/download/lang_packs/gzip/' . $lang_pack->version . '/' . $lang['iso_code'] . '.gzip')) {
$file = _PS_TRANSLATIONS_DIR_ . $lang['iso_code'] . '.gzip';
if ((bool) file_put_contents($file, $content)) {
$gz = new \Archive_Tar($file, 'gz');
$files_list = $gz->listContent();
if (!$this->container->getUpgradeConfiguration()->shouldKeepMails()) {
$files_listing = array();
foreach ($files_list as $i => $file) {
if (preg_match('/^mails\/' . $lang['iso_code'] . '\/.*/', $file['filename'])) {
unset($files_list[$i]);
}
}
foreach ($files_list as $file) {
if (isset($file['filename']) && is_string($file['filename'])) {
$files_listing[] = $file['filename'];
}
}
if (is_array($files_listing)) {
$gz->extractList($files_listing, _PS_TRANSLATIONS_DIR_ . '../', '');
}
} else {
$gz->extract(_PS_TRANSLATIONS_DIR_ . '../', false);
}
}
}
}
protected function loadEntityInterface()
{
require_once _PS_ROOT_DIR_ . '/Core/Foundation/Database/Core_Foundation_Database_EntityInterface.php';
}
protected function runCoreCacheClean()
{
parent::runCoreCacheClean();
// delete cache filesystem if activated
if (defined('_PS_CACHE_ENABLED_') && false != _PS_CACHE_ENABLED_) {
$depth = (int) $this->db->getValue('SELECT value
FROM ' . _DB_PREFIX_ . 'configuration
WHERE name = "PS_CACHEFS_DIRECTORY_DEPTH"');
if ($depth) {
if (!defined('_PS_CACHEFS_DIRECTORY_')) {
define('_PS_CACHEFS_DIRECTORY_', $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/cache/cachefs/');
}
FilesystemAdapter::deleteDirectory(_PS_CACHEFS_DIRECTORY_, false);
if (class_exists('CacheFs', false)) {
$this->createCacheFsDirectories((int) $depth);
}
}
}
}
private function createCacheFsDirectories($level_depth, $directory = false)
{
if (!$directory) {
if (!defined('_PS_CACHEFS_DIRECTORY_')) {
define('_PS_CACHEFS_DIRECTORY_', $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . '/cache/cachefs/');
}
$directory = _PS_CACHEFS_DIRECTORY_;
}
$chars = '0123456789abcdef';
for ($i = 0; $i < strlen($chars); ++$i) {
$new_dir = $directory . $chars[$i] . '/';
if (mkdir($new_dir, 0775) && chmod($new_dir, 0775) && $level_depth - 1 > 0) {
$this->createCacheFsDirectories($level_depth - 1, $new_dir);
}
}
}
}

View File

@@ -0,0 +1,115 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools\CoreUpgrader;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
/**
* Class used to modify the core of PrestaShop, on the files are copied on the filesystem.
* It will run subtasks such as database upgrade, language upgrade etc.
*/
class CoreUpgrader17 extends CoreUpgrader
{
protected function initConstants()
{
parent::initConstants();
/*if (!file_exists(SETTINGS_FILE_PHP)) {
throw new UpgradeException($this->container->getTranslator()->trans('The app/config/parameters.php file was not found.', array(), 'Modules.Autoupgrade.Admin'));
}
if (!file_exists(SETTINGS_FILE_YML)) {
throw new UpgradeException($this->container->getTranslator()->trans('The app/config/parameters.yml file was not found.', array(), 'Modules.Autoupgrade.Admin'));
}*/
// Container may be needed to run upgrade scripts
$this->container->getSymfonyAdapter()->initAppKernel();
}
protected function upgradeDb($oldversion)
{
parent::upgradeDb($oldversion);
$commandResult = $this->container->getSymfonyAdapter()->runSchemaUpgradeCommand();
if (0 !== $commandResult['exitCode']) {
throw (new UpgradeException($this->container->getTranslator()->trans('Error upgrading Doctrine schema', array(), 'Modules.Autoupgrade.Admin')))
->setQuickInfos(explode("\n", $commandResult['output']));
}
}
protected function upgradeLanguage($lang)
{
$isoCode = $lang['iso_code'];
if (!\Validate::isLangIsoCode($isoCode)) {
return;
}
$errorsLanguage = array();
if (!\Language::downloadLanguagePack($isoCode, _PS_VERSION_, $errorsLanguage)) {
throw new UpgradeException(
$this->container->getTranslator()->trans(
'Download of the language pack %lang% failed. %details%',
[
'%lang%' => $isoCode,
'%details%' => implode('; ', $errorsLanguage),
],
'Modules.Autoupgrade.Admin'
)
);
}
$lang_pack = \Language::getLangDetails($isoCode);
\Language::installSfLanguagePack($lang_pack['locale'], $errorsLanguage);
if (!$this->container->getUpgradeConfiguration()->shouldKeepMails()) {
\Language::installEmailsLanguagePack($lang_pack, $errorsLanguage);
}
if (!empty($errorsLanguage)) {
throw new UpgradeException(
$this->container->getTranslator()->trans(
'Error while updating translations for lang %lang%. %details%',
[
'%lang%' => $isoCode,
'%details%' => implode('; ', $errorsLanguage),
],
'Modules.Autoupgrade.Admin'
)
);
}
\Language::loadLanguages();
// TODO: Update AdminTranslationsController::addNewTabs to install tabs translated
// CLDR has been updated on PS 1.7.6.0. From this version, updates are not needed anymore.
if (method_exists('\PrestaShop\PrestaShop\Core\Cldr\Update', 'fetchLocale')) {
$cldrUpdate = new \PrestaShop\PrestaShop\Core\Cldr\Update(_PS_TRANSLATIONS_DIR_);
$cldrUpdate->fetchLocale(\Language::getLocaleByIso($isoCode));
}
}
}

View File

@@ -0,0 +1,65 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use Db;
class Database
{
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
public function getAllTables()
{
$tables = $this->db->executeS('SHOW TABLES LIKE "' . _DB_PREFIX_ . '%"', true, false);
$all_tables = array();
foreach ($tables as $v) {
$table = array_shift($v);
$all_tables[$table] = $table;
}
return $all_tables;
}
/**
* ToDo: Send tables list instead.
*/
public function cleanTablesAfterBackup(array $tablesToClean)
{
foreach ($tablesToClean as $table) {
$this->db->execute('DROP TABLE IF EXISTS `' . bqSql($table) . '`');
$this->db->execute('DROP VIEW IF EXISTS `' . bqSql($table) . '`');
}
$this->db->execute('SET FOREIGN_KEY_CHECKS=1');
}
}

View File

@@ -0,0 +1,150 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
class FileFilter
{
/**
* @var UpgradeConfiguration
*/
protected $configuration;
/**
* @var string Autoupgrade sub directory*
*/
protected $autoupgradeDir;
public function __construct(UpgradeConfiguration $configuration, $autoupgradeDir = 'autoupgrade')
{
$this->configuration = $configuration;
$this->autoupgradeDir = $autoupgradeDir;
}
/**
* AdminSelfUpgrade::backupIgnoreAbsoluteFiles.
*
* @return array
*/
public function getFilesToIgnoreOnBackup()
{
// during backup, do not save
$backupIgnoreAbsoluteFiles = array(
'/app/cache',
'/cache/smarty/compile',
'/cache/smarty/cache',
'/cache/tcpdf',
'/cache/cachefs',
'/var/cache',
// do not care about the two autoupgrade dir we use;
'/modules/autoupgrade',
'/admin/autoupgrade',
);
if (!$this->configuration->shouldBackupImages()) {
$backupIgnoreAbsoluteFiles[] = '/img';
} else {
$backupIgnoreAbsoluteFiles[] = '/img/tmp';
}
return $backupIgnoreAbsoluteFiles;
}
/**
* AdminSelfUpgrade::restoreIgnoreAbsoluteFiles.
*
* @return array
*/
public function getFilesToIgnoreOnRestore()
{
$restoreIgnoreAbsoluteFiles = array(
'/app/config/parameters.php',
'/app/config/parameters.yml',
'/modules/autoupgrade',
'/admin/autoupgrade',
'.',
'..',
);
if (!$this->configuration->shouldBackupImages()) {
$restoreIgnoreAbsoluteFiles[] = '/img';
} else {
$restoreIgnoreAbsoluteFiles[] = '/img/tmp';
}
return $restoreIgnoreAbsoluteFiles;
}
/**
* AdminSelfUpgrade::excludeAbsoluteFilesFromUpgrade.
*
* @return array
*/
public function getFilesToIgnoreOnUpgrade()
{
// do not copy install, neither app/config/parameters.php in case it would be present
$excludeAbsoluteFilesFromUpgrade = array(
'/app/config/parameters.php',
'/app/config/parameters.yml',
'/install',
'/install-dev',
);
// this will exclude autoupgrade dir from admin, and autoupgrade from modules
// If set to false, we need to preserve the default themes
if (!$this->configuration->shouldUpdateDefaultTheme()) {
$excludeAbsoluteFilesFromUpgrade[] = '/themes/classic';
$excludeAbsoluteFilesFromUpgrade[] = '/themes/default-bootstrap';
}
return $excludeAbsoluteFilesFromUpgrade;
}
/**
* AdminSelfUpgrade::backupIgnoreFiles
* AdminSelfUpgrade::excludeFilesFromUpgrade
* AdminSelfUpgrade::restoreIgnoreFiles.
*
* These files are checked in every subfolder of the directory tree and can match
* several time, while the others are only matching a file from the project root.
*
* @return array
*/
public function getExcludeFiles()
{
return array(
'.',
'..',
'.svn',
'.git',
$this->autoupgradeDir,
);
}
}

View File

@@ -0,0 +1,257 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\Tools14;
class FilesystemAdapter
{
private $restoreFilesFilename;
private $fileFilter;
private $autoupgradeDir;
private $adminSubDir;
private $prodRootDir;
/**
* Somes elements to find in a folder.
* If one of them cannot be found, we can consider that the release is invalid.
*
* @var array
*/
private $releaseFileChecks = array(
'files' => array(
'index.php',
'config/defines.inc.php',
),
'folders' => array(
'classes',
'controllers',
),
);
public function __construct(FileFilter $fileFilter, $restoreFilesFilename,
$autoupgradeDir, $adminSubDir, $prodRootDir)
{
$this->fileFilter = $fileFilter;
$this->restoreFilesFilename = $restoreFilesFilename;
$this->autoupgradeDir = $autoupgradeDir;
$this->adminSubDir = $adminSubDir;
$this->prodRootDir = $prodRootDir;
}
/**
* Delete directory and subdirectories.
*
* @param string $dirname Directory name
*/
public static function deleteDirectory($dirname, $delete_self = true)
{
return Tools14::deleteDirectory($dirname, $delete_self);
}
public function listFilesInDir($dir, $way = 'backup', $list_directories = false)
{
$list = array();
$dir = rtrim($dir, '/') . DIRECTORY_SEPARATOR;
$allFiles = false;
if (is_dir($dir) && is_readable($dir)) {
$allFiles = scandir($dir);
}
if (!is_array($allFiles)) {
return $list;
}
foreach ($allFiles as $file) {
$fullPath = $dir . $file;
// skip broken symbolic links
if (is_link($fullPath) && !is_readable($fullPath)) {
continue;
}
if ($this->isFileSkipped($file, $fullPath, $way)) {
continue;
}
if (is_dir($fullPath)) {
$list = array_merge($list, $this->listFilesInDir($fullPath, $way, $list_directories));
if ($list_directories) {
$list[] = $fullPath;
}
} else {
$list[] = $fullPath;
}
}
return $list;
}
/**
* this function list all files that will be remove to retrieve the filesystem states before the upgrade.
*
* @return array of files to delete
*/
public function listFilesToRemove()
{
$prev_version = preg_match('#auto-backupfiles_V([0-9.]*)_#', $this->restoreFilesFilename, $matches);
if ($prev_version) {
$prev_version = $matches[1];
}
// if we can't find the diff file list corresponding to _PS_VERSION_ and prev_version,
// let's assume to remove every files
$toRemove = $this->listFilesInDir($this->prodRootDir, 'restore', true);
// if a file in "ToRemove" has been skipped during backup,
// just keep it
foreach ($toRemove as $key => $file) {
$filename = substr($file, strrpos($file, '/') + 1);
$toRemove[$key] = preg_replace('#^/admin#', $this->adminSubDir, $file);
// this is a really sensitive part, so we add an extra checks: preserve everything that contains "autoupgrade"
if ($this->isFileSkipped($filename, $file, 'backup') || strpos($file, $this->autoupgradeDir)) {
unset($toRemove[$key]);
}
}
return $toRemove;
}
/**
* Retrieve a list of sample files to be deleted from the release.
*
* @param array $directoryList
*
* @return array Files to remove from the release
*/
public function listSampleFilesFromArray(array $directoryList)
{
$res = array();
foreach ($directoryList as $directory) {
$res = array_merge($res, $this->listSampleFiles($directory['path'], $directory['filter']));
}
return $res;
}
/**
* listSampleFiles will make a recursive call to scandir() function
* and list all file which match to the $fileext suffixe (this can be an extension or whole filename).
*
* @param string $dir directory to look in
* @param string $fileext suffixe filename
*
* @return array of files
*/
public function listSampleFiles($dir, $fileext = '.jpg')
{
$res = array();
$dir = rtrim($dir, '/') . DIRECTORY_SEPARATOR;
$toDel = false;
if (is_dir($dir) && is_readable($dir)) {
$toDel = scandir($dir);
}
// copied (and kind of) adapted from AdminImages.php
if (is_array($toDel)) {
foreach ($toDel as $file) {
if ($file[0] != '.') {
if (preg_match('#' . preg_quote($fileext, '#') . '$#i', $file)) {
$res[] = $dir . $file;
} elseif (is_dir($dir . $file)) {
$res = array_merge($res, $this->listSampleFiles($dir . $file, $fileext));
}
}
}
}
return $res;
}
/**
* bool _skipFile : check whether a file is in backup or restore skip list.
*
* @param string $file : current file or directory name eg:'.svn' , 'settings.inc.php'
* @param string $fullpath : current file or directory fullpath eg:'/home/web/www/prestashop/app/config/parameters.php'
* @param string $way : 'backup' , 'upgrade'
* @param string $temporaryWorkspace : If needed, another folder than the shop root can be used (used for releases)
*/
public function isFileSkipped($file, $fullpath, $way = 'backup', $temporaryWorkspace = null)
{
$fullpath = str_replace('\\', '/', $fullpath); // wamp compliant
$rootpath = str_replace(
'\\',
'/',
(null !== $temporaryWorkspace) ? $temporaryWorkspace : $this->prodRootDir
);
if (in_array($file, $this->fileFilter->getExcludeFiles())) {
return true;
}
$ignoreList = array();
if ('backup' === $way) {
$ignoreList = $this->fileFilter->getFilesToIgnoreOnBackup();
} elseif ('restore' === $way) {
$ignoreList = $this->fileFilter->getFilesToIgnoreOnRestore();
} elseif ('upgrade' === $way) {
$ignoreList = $this->fileFilter->getFilesToIgnoreOnUpgrade();
}
foreach ($ignoreList as $path) {
$path = str_replace(DIRECTORY_SEPARATOR . 'admin', DIRECTORY_SEPARATOR . $this->adminSubDir, $path);
if ($fullpath === $rootpath . $path) {
return true;
}
}
// by default, don't skip
return false;
}
/**
* Check a directory has some files available in every release of PrestaShop.
*
* @param string $path Workspace to check
*
* @return bool
*/
public function isReleaseValid($path)
{
foreach ($this->releaseFileChecks as $type => $elements) {
foreach ($elements as $element) {
$fullPath = $path . DIRECTORY_SEPARATOR . $element;
if ('files' === $type && !is_file($fullPath)) {
return false;
}
if ('folders' === $type && !is_dir($fullPath)) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,202 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\ZipAction;
class ModuleAdapter
{
private $db;
private $translator;
// PS version to update
private $upgradeVersion;
private $modulesPath;
private $tempPath;
/**
* @var ZipAction
*/
private $zipAction;
/**
* @var SymfonyAdapter
*/
private $symfonyAdapter;
// Cached instance
private $moduleDataUpdater;
public function __construct($db, $translator, $modulesPath, $tempPath, $upgradeVersion, ZipAction $zipAction, SymfonyAdapter $symfonyAdapter)
{
$this->db = $db;
$this->translator = $translator;
$this->modulesPath = $modulesPath;
$this->tempPath = $tempPath;
$this->upgradeVersion = $upgradeVersion;
$this->zipAction = $zipAction;
$this->symfonyAdapter = $symfonyAdapter;
}
/**
* Available only from 1.7. Can't be called on PS 1.6.
*
* @return \PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater
*/
public function getModuleDataUpdater()
{
if (null === $this->moduleDataUpdater) {
$this->moduleDataUpdater = $this->symfonyAdapter
->initAppKernel()
->getContainer()
->get('prestashop.core.module.updater');
}
return $this->moduleDataUpdater;
}
/**
* Upgrade action, disabling all modules not made by PrestaShop.
*
* It seems the 1.6 version of is the safest, as it does not actually load the modules.
*
* @param string $pathToUpgradeScripts Path to the PHP Upgrade scripts
*/
public function disableNonNativeModules($pathToUpgradeScripts)
{
require_once $pathToUpgradeScripts . 'deactivate_custom_modules.php';
deactivate_custom_modules();
}
/**
* list modules to upgrade and save them in a serialized array in $this->toUpgradeModuleList.
*
* @param array $modulesFromAddons Modules available on the marketplace for download
*
* @return array Module available on the local filesystem and on the marketplace
*/
public function listModulesToUpgrade(array $modulesFromAddons)
{
$list = array();
$dir = $this->modulesPath;
if (!is_dir($dir)) {
throw (new UpgradeException($this->translator->trans('[ERROR] %dir% does not exist or is not a directory.', array('%dir%' => $dir), 'Modules.Autoupgrade.Admin')))
->addQuickInfo($this->translator->trans('[ERROR] %s does not exist or is not a directory.', array($dir), 'Modules.Autoupgrade.Admin'))
->setSeverity(UpgradeException::SEVERITY_ERROR);
// $this->next_desc = $this->trans('Nothing has been extracted. It seems the unzip step has been skipped.', array(), 'Modules.Autoupgrade.Admin');
}
foreach (scandir($dir) as $module_name) {
if (is_file($dir . DIRECTORY_SEPARATOR . $module_name)) {
continue;
}
if (!is_file($dir . $module_name . DIRECTORY_SEPARATOR . $module_name . '.php')) {
continue;
}
$id_addons = array_search($module_name, $modulesFromAddons);
if (false !== $id_addons && $module_name !== 'autoupgrade') {
$list[] = array('id' => $id_addons, 'name' => $module_name);
}
}
return $list;
}
/**
* Upgrade module $name (identified by $id_module on addons server).
*
* @param int $id
* @param string $name
*/
public function upgradeModule($id, $name)
{
$zip_fullpath = $this->tempPath . DIRECTORY_SEPARATOR . $name . '.zip';
$addons_url = 'api.addons.prestashop.com';
$protocolsList = array('https://' => 443, 'http://' => 80);
if (!extension_loaded('openssl')) {
unset($protocolsList['https://']);
} else {
unset($protocolsList['http://']);
}
$postData = 'version=' . $this->upgradeVersion . '&method=module&id_module=' . (int) $id;
// Make the request
$opts = array(
'http' => array(
'method' => 'POST',
'content' => $postData,
'header' => 'Content-type: application/x-www-form-urlencoded',
'timeout' => 10,
),
);
$context = stream_context_create($opts);
foreach ($protocolsList as $protocol => $port) {
// file_get_contents can return false if https is not supported (or warning)
$content = Tools14::file_get_contents($protocol . $addons_url, false, $context);
if ($content == false || substr($content, 5) == '<?xml') {
continue;
}
if ($content === null) {
$msg = '<strong>' . $this->translator->trans('[ERROR] No response from Addons server.', array(), 'Modules.Autoupgrade.Admin') . '</strong>';
throw new UpgradeException($msg);
}
if (false === (bool) file_put_contents($zip_fullpath, $content)) {
$msg = '<strong>' . $this->translator->trans('[ERROR] Unable to write module %s\'s zip file in temporary directory.', array($name), 'Modules.Autoupgrade.Admin') . '</strong>';
throw new UpgradeException($msg);
}
if (filesize($zip_fullpath) <= 300) {
unlink($zip_fullpath);
}
// unzip in modules/[mod name] old files will be conserved
if (!$this->zipAction->extract($zip_fullpath, $this->modulesPath)) {
throw (new UpgradeException('<strong>' . $this->translator->trans('[WARNING] Error when trying to extract module %s.', array($name), 'Modules.Autoupgrade.Admin') . '</strong>'))
->setSeverity(UpgradeException::SEVERITY_WARNING);
}
if (file_exists($zip_fullpath)) {
unlink($zip_fullpath);
}
// Only 1.7 step
if (version_compare($this->upgradeVersion, '1.7.0.0', '>=')
&& !$this->getModuleDataUpdater()->upgrade($name)) {
throw (new UpgradeException('<strong>' . $this->translator->trans('[WARNING] Error when trying to upgrade module %s.', array($name), 'Modules.Autoupgrade.Admin') . '</strong>'))
->setSeverity(UpgradeException::SEVERITY_WARNING)
->setQuickInfos(\Module::getInstanceByName($name)->getErrors());
}
return;
}
}
}

View File

@@ -0,0 +1,89 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\UpgradeException;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
use Symfony\Component\Filesystem\Filesystem;
use PrestaShop\Module\AutoUpgrade\LoggedEvent;
class SettingsFileWriter
{
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
public function migrateSettingsFile(LoggerInterface $logger)
{
if (class_exists('\PrestaShopBundle\Install\Upgrade')) {
\PrestaShopBundle\Install\Upgrade::migrateSettingsFile(new LoggedEvent($logger));
}
}
/**
* @param string $filePath
* @param array $data
*
* @throws UpgradeException
*/
public function writeSettingsFile($filePath, $data)
{
if (!is_writable($filePath)) {
throw new UpgradeException($this->translator->trans('Error when opening settings.inc.php file in write mode', array(), 'Modules.Autoupgrade.Admin'));
}
// Create backup file
$filesystem = new Filesystem();
$filesystem->copy($filePath, $filePath . '.bck');
$fd = fopen($filePath, 'w');
fwrite($fd, '<?php' . PHP_EOL);
foreach ($data as $name => $value) {
if (false === fwrite($fd, "define('$name', '{$this->checkString($value)}');" . PHP_EOL)) {
throw new UpgradeException($this->translator->trans('Error when generating new settings.inc.php file.', array(), 'Modules.Autoupgrade.Admin'));
}
}
fclose($fd);
}
public function checkString($string)
{
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
if (!is_numeric($string)) {
$string = addslashes($string);
$string = str_replace(array("\n", "\r"), '', $string);
}
return $string;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
/**
* TODO: Create a class for 1.7 env and another one for 1.6 ?
*/
class SymfonyAdapter
{
/**
* @var string Version on which PrestaShop is being upgraded
*/
private $destinationPsVersion;
public function __construct($destinationPsVersion)
{
$this->destinationPsVersion = $destinationPsVersion;
}
public function runSchemaUpgradeCommand()
{
if (version_compare($this->destinationPsVersion, '1.7.1.1', '>=')) {
$schemaUpgrade = new \PrestaShopBundle\Service\Database\Upgrade();
$outputCommand = 'prestashop:schema:update-without-foreign';
} else {
$schemaUpgrade = new \PrestaShopBundle\Service\Cache\Refresh();
$outputCommand = 'doctrine:schema:update';
}
$schemaUpgrade->addDoctrineSchemaUpdate();
$output = $schemaUpgrade->execute();
return $output[$outputCommand];
}
/**
* Return the AppKernel, after initialization
*
* @return \AppKernel
*/
public function initAppKernel()
{
global $kernel;
if (!$kernel instanceof \AppKernel) {
require_once _PS_ROOT_DIR_ . '/app/AppKernel.php';
$env = (true == _PS_MODE_DEV_) ? 'dev' : 'prod';
$kernel = new \AppKernel($env, _PS_MODE_DEV_);
$kernel->loadClassCache();
$kernel->boot();
}
return $kernel;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
class TaskRepository
{
public static function get($step, UpgradeContainer $container)
{
switch ($step) {
// MISCELLANEOUS (upgrade configuration, checks etc.)
case 'checkFilesVersion':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous\CheckFilesVersion($container);
case 'compareReleases':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous\CompareReleases($container);
case 'getChannelInfo':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous\GetChannelInfo($container);
case 'updateConfig':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Miscellaneous\UpdateConfig($container);
// ROLLBACK
case 'noRollbackFound':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\NoRollbackFound($container);
case 'restoreDb':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\RestoreDb($container);
case 'restoreFiles':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\RestoreFiles($container);
case 'rollback':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\Rollback($container);
case 'rollbackComplete':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\RollbackComplete($container);
// UPGRADE
case 'backupDb':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\BackupDb($container);
case 'backupFiles':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\BackupFiles($container);
case 'cleanDatabase':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\CleanDatabase($container);
case 'download':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\Download($container);
case 'removeSamples':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\RemoveSamples($container);
case 'upgradeComplete':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\UpgradeComplete($container);
case 'upgradeDb':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\UpgradeDb($container);
case 'upgradeFiles':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\UpgradeFiles($container);
case 'upgradeModules':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\UpgradeModules($container);
case 'upgradeNow':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\UpgradeNow($container);
case 'unzip':
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\Unzip($container);
}
error_log('Unknown step ' . $step);
return new \PrestaShop\Module\AutoUpgrade\TaskRunner\NullTask($container);
}
}

View File

@@ -0,0 +1,106 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
class ThemeAdapter
{
private $db;
private $upgradeVersion;
public function __construct($db, $upgradeVersion)
{
$this->db = $db;
$this->upgradeVersion = $upgradeVersion;
}
/**
* Enable the given theme on the shop.
*
* @param string $themeName
*
* @return mixed
*/
public function enableTheme($themeName)
{
return version_compare($this->upgradeVersion, '1.7.0.0', '>=') ?
$this->enableTheme17($themeName) :
$this->enableTheme16($themeName);
}
/**
* Get the default theme name provided with PrestaShop.
*
* @return string
*/
public function getDefaultTheme()
{
return version_compare($this->upgradeVersion, '1.7.0.0', '>=') ?
'classic' : // 1.7
'default-bootstrap'; // 1.6
}
/**
* Backward compatibility function for theme enabling.
*
* @param string $themeName
*/
private function enableTheme16($themeName)
{
$this->db->execute('UPDATE `' . _DB_PREFIX_ . 'shop`
SET id_theme = (SELECT id_theme FROM `' . _DB_PREFIX_ . 'theme` WHERE name LIKE \'' . $themeName . '\')');
$this->db->execute('DELETE FROM `' . _DB_PREFIX_ . 'theme` WHERE name LIKE \'default\' OR name LIKE \'prestashop\'');
return true;
}
/**
* Use 1.7 theme manager is order to enable the new theme.
*
* @param string $themeName
*
* @return bool|array
*/
private function enableTheme17($themeName)
{
$themeManager = $this->getThemeManager();
$isThemeEnabled = $themeManager->enable($themeName);
if (!$isThemeEnabled) {
$errors = $themeManager->getErrors($themeName);
return $errors ? $errors : 'Unknown error';
}
return true;
}
private function getThemeManager()
{
return (new \PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder(\Context::getContext(), $this->db))->build();
}
}

View File

@@ -0,0 +1,212 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
class Translation
{
private $installedLanguagesIso;
private $logger;
private $translator;
public function __construct($translator, LoggerInterface $logger, $installedLanguagesIso)
{
$this->logger = $logger;
$this->translator = $translator;
$this->installedLanguagesIso = $installedLanguagesIso;
}
/**
* getTranslationFileType.
*
* @param string $file filepath to check
*
* @return string type of translation item
*/
public function getTranslationFileType($file)
{
$type = false;
// line shorter
$separator = addslashes(DIRECTORY_SEPARATOR);
$translation_dir = $separator . 'translations' . $separator;
$regex_module = '#' . $separator . 'modules' . $separator . '.*' . $translation_dir . '(' . implode('|', $this->installedLanguagesIso) . ')\.php#';
if (preg_match($regex_module, $file)) {
$type = 'module';
} elseif (preg_match('#' . $translation_dir . '(' . implode('|', $this->installedLanguagesIso) . ')' . $separator . 'admin\.php#', $file)) {
$type = 'back office';
} elseif (preg_match('#' . $translation_dir . '(' . implode('|', $this->installedLanguagesIso) . ')' . $separator . 'errors\.php#', $file)) {
$type = 'error message';
} elseif (preg_match('#' . $translation_dir . '(' . implode('|', $this->installedLanguagesIso) . ')' . $separator . 'fields\.php#', $file)) {
$type = 'field';
} elseif (preg_match('#' . $translation_dir . '(' . implode('|', $this->installedLanguagesIso) . ')' . $separator . 'pdf\.php#', $file)) {
$type = 'pdf';
} elseif (preg_match('#' . $separator . 'themes' . $separator . '(default|prestashop)' . $separator . 'lang' . $separator . '(' . implode('|', $this->installedLanguagesIso) . ')\.php#', $file)) {
$type = 'front office';
}
return $type;
}
public function isTranslationFile($file)
{
return $this->getTranslationFileType($file) !== false;
}
/**
* merge the translations of $orig into $dest, according to the $type of translation file.
*
* @param string $orig file from upgrade package
* @param string $dest filepath of destination
* @param string $type type of translation file (module, back office, front office, field, pdf, error)
*
* @return bool
*/
public function mergeTranslationFile($orig, $dest, $type)
{
switch ($type) {
case 'front office':
$var_name = '_LANG';
break;
case 'back office':
$var_name = '_LANGADM';
break;
case 'error message':
$var_name = '_ERRORS';
break;
case 'field':
$var_name = '_FIELDS';
break;
case 'module':
$var_name = '_MODULE';
break;
case 'pdf':
$var_name = '_LANGPDF';
break;
case 'mail':
$var_name = '_LANGMAIL';
break;
default:
return false;
}
if (!file_exists($orig)) {
$this->logger->notice($this->translator->trans('[NOTICE] File %s does not exist, merge skipped.', array($orig), 'Modules.Autoupgrade.Admin'));
return true;
}
include $orig;
if (!isset($$var_name)) {
$this->logger->warning($this->translator->trans(
'[WARNING] %variablename% variable missing in file %filename%. Merge skipped.',
array(
'%variablename%' => $var_name,
'%filename%' => $orig,
),
'Modules.Autoupgrade.Admin'
));
return true;
}
$var_orig = $$var_name;
if (!file_exists($dest)) {
$this->logger->notice($this->translator->trans('[NOTICE] File %s does not exist, merge skipped.', array($dest), 'Modules.Autoupgrade.Admin'));
return false;
}
include $dest;
if (!isset($$var_name)) {
// in that particular case : file exists, but variable missing, we need to delete that file
// (if not, this invalid file will be copied in /translations during upgradeDb process)
if ('module' == $type && file_exists($dest)) {
unlink($dest);
}
$this->logger->warning($this->translator->trans(
'[WARNING] %variablename% variable missing in file %filename%. File %filename% deleted and merge skipped.',
array(
'%variablename%' => $var_name,
'%filename%' => $dest,
),
'Modules.Autoupgrade.Admin'
));
return false;
}
$var_dest = $$var_name;
$merge = array_merge($var_orig, $var_dest);
$fd = fopen($dest, 'w');
if ($fd === false) {
return false;
}
fwrite($fd, "<?php\n\nglobal \$" . $var_name . ";\n\$" . $var_name . " = array();\n");
foreach ($merge as $k => $v) {
if (get_magic_quotes_gpc()) {
$v = stripslashes($v);
}
if ('mail' == $type) {
fwrite($fd, '$' . $var_name . '[\'' . $this->escape($k) . '\'] = \'' . $this->escape($v) . '\';' . "\n");
} else {
fwrite($fd, '$' . $var_name . '[\'' . $this->escape($k, true) . '\'] = \'' . $this->escape($v, true) . '\';' . "\n");
}
}
fwrite($fd, "\n?>");
fclose($fd);
return true;
}
/**
* Escapes illegal characters in a string.
* Extracted from DB class, in order to avoid dependancies.
*
* @see DbCore::_escape()
*
* @param string $str
* @param bool $html_ok Does data contain HTML code ? (optional)
*
* @return string
*/
private function escape($str, $html_ok = false)
{
$search = array('\\', "\0", "\n", "\r", "\x1a", "'", '"');
$replace = array('\\\\', '\\0', '\\n', '\\r', "\Z", "\'", '\"');
$str = str_replace($search, $replace, $str);
if (!$html_ok) {
return strip_tags(Tools14::nl2br($str));
}
return $str;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade\UpgradeTools;
class Translator
{
private $caller;
public function __construct($caller)
{
$this->caller = $caller;
}
/**
* Translate a string to the current language.
*
* This methods has the same signature as the 1.7 trans method, but only relies
* on the module translation files.
*
* @param string $id Original text
* @param array $parameters Parameters to apply
* @param string $domain Unused
* @param string $locale Unused
*
* @return string Translated string with parameters applied
*/
public function trans($id, array $parameters = array(), $domain = 'Modules.Autoupgrade.Admin', $locale = null)
{
// If PrestaShop core is not instancied properly, do not try to translate
if (!method_exists('\Context', 'getContext') || null === \Context::getContext()->language) {
return $this->applyParameters($id, $parameters);
}
if (method_exists('\Translate', 'getModuleTranslation')) {
$translated = \Translate::getModuleTranslation('autoupgrade', $id, $this->caller, null);
if (!count($parameters)) {
return $translated;
}
} else {
$translated = $id;
}
return $this->applyParameters($translated, $parameters);
}
/**
* @param string $id
* @param array $parameters
*
* @return string Translated string with parameters applied
*
* @internal Public for tests
*/
public function applyParameters($id, array $parameters = array())
{
// Replace placeholders for non numeric keys
foreach ($parameters as $placeholder => $value) {
if (is_int($placeholder)) {
continue;
}
$id = str_replace($placeholder, $value, $id);
unset($parameters[$placeholder]);
}
return call_user_func_array('sprintf', array_merge(array($id), $parameters));
}
}

View File

@@ -0,0 +1,544 @@
<?php
/**
* 2007-2016 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
use Configuration;
class Upgrader
{
const DEFAULT_CHECK_VERSION_DELAY_HOURS = 12;
const DEFAULT_CHANNEL = 'minor';
const DEFAULT_FILENAME = 'prestashop.zip';
public $addons_api = 'api.addons.prestashop.com';
public $rss_channel_link = 'https://api.prestashop.com/xml/channel.xml';
public $rss_md5file_link_dir = 'https://api.prestashop.com/xml/md5/';
/**
* @var bool contains true if last version is not installed
*/
private $need_upgrade = false;
private $changed_files = array();
private $missing_files = array();
public $version_name;
public $version_num;
public $version_is_modified;
/**
* @var string contains hte url where to download the file
*/
public $link;
public $autoupgrade;
public $autoupgrade_module;
public $autoupgrade_last_version;
public $autoupgrade_module_link;
public $changelog;
public $available;
public $md5;
public static $default_channel = 'minor';
public $channel = '';
public $branch = '';
protected $currentPsVersion;
public function __construct($version, $autoload = false)
{
$this->currentPsVersion = $version;
if ($autoload) {
$matches = array();
preg_match('#([0-9]+\.[0-9]+)\.[0-9]+\.[0-9]+#', $this->currentPsVersion, $matches);
$this->branch = $matches[1];
if (empty($this->channel)) {
$this->channel = self::$default_channel;
}
// checkPSVersion to get need_upgrade
$this->checkPSVersion();
}
if (!extension_loaded('openssl')) {
$this->rss_channel_link = str_replace('https://', 'http://', $this->rss_channel_link);
$this->rss_md5file_link_dir = str_replace('https://', 'http://', $this->rss_md5file_link_dir);
}
}
/**
* downloadLast download the last version of PrestaShop and save it in $dest/$filename.
*
* @param string $dest directory where to save the file
* @param string $filename new filename
*
* @return bool
*
* @TODO ftp if copy is not possible (safe_mode for example)
*/
public function downloadLast($dest, $filename = 'prestashop.zip')
{
if (empty($this->link)) {
$this->checkPSVersion();
}
$destPath = realpath($dest) . DIRECTORY_SEPARATOR . $filename;
try {
$filesystem = new Filesystem();
$filesystem->copy($this->link, $destPath);
} catch (IOException $e) {
// If the Symfony filesystem failed, we can try with
// the legacy method which uses curl.
Tools14::copy($this->link, $destPath);
}
return is_file($destPath);
}
public function isLastVersion()
{
if (empty($this->link)) {
$this->checkPSVersion();
}
return !$this->need_upgrade;
}
/**
* checkPSVersion ask to prestashop.com if there is a new version. return an array if yes, false otherwise.
*
* @param bool $refresh if set to true, will force to download channel.xml
* @param array $array_no_major array of channels which will return only the immediate next version number
*
* @return mixed
*/
public function checkPSVersion($refresh = false, $array_no_major = array('minor'))
{
// if we use the autoupgrade process, we will never refresh it
// except if no check has been done before
$feed = $this->getXmlChannel($refresh);
$branch_name = '';
$channel_name = '';
// channel hierarchy :
// if you follow private, you follow stable release
// if you follow rc, you also follow stable
// if you follow beta, you also follow rc
// et caetera
$followed_channels = array();
$followed_channels[] = $this->channel;
switch ($this->channel) {
case 'alpha':
$followed_channels[] = 'beta';
// no break
case 'beta':
$followed_channels[] = 'rc';
// no break
case 'rc':
$followed_channels[] = 'stable';
// no break
case 'minor':
case 'major':
case 'private':
$followed_channels[] = 'stable';
}
if ($feed) {
$this->autoupgrade_module = (int) $feed->autoupgrade_module;
$this->autoupgrade_last_version = (string) $feed->autoupgrade->last_version;
$this->autoupgrade_module_link = (string) $feed->autoupgrade->download->link;
foreach ($feed->channel as $channel) {
$channel_available = (string) $channel['available'];
$channel_name = (string) $channel['name'];
// stable means major and minor
// boolean algebra
// skip if one of theses props are true:
// - "stable" in xml, "minor" or "major" in configuration
// - channel in xml is not channel in configuration
if (!(in_array($channel_name, $followed_channels))) {
continue;
}
// now we are on the correct channel (minor, major, ...)
foreach ($channel as $branch) {
// branch name = which version
$branch_name = (string) $branch['name'];
// if channel is "minor" in configuration, do not allow something else than current branch
// otherwise, allow superior or equal
if (
(in_array($this->channel, $followed_channels)
&& version_compare($branch_name, $this->branch, '>='))
) {
// skip if $branch->num is inferior to a previous one, skip it
if (version_compare((string) $branch->num, $this->version_num, '<')) {
continue;
}
// also skip if previous loop found an available upgrade and current is not
if ($this->available && !($channel_available && (string) $branch['available'])) {
continue;
}
// also skip if chosen channel is minor, and xml branch name is superior to current
if (in_array($this->channel, $array_no_major) && version_compare($branch_name, $this->branch, '>')) {
continue;
}
$this->version_name = (string) $branch->name;
$this->version_num = (string) $branch->num;
$this->link = (string) $branch->download->link;
$this->md5 = (string) $branch->download->md5;
$this->changelog = (string) $branch->changelog;
if (extension_loaded('openssl')) {
$this->link = str_replace('http://', 'https://', $this->link);
$this->changelog = str_replace('http://', 'https://', $this->changelog);
}
$this->available = $channel_available && (string) $branch['available'];
}
}
}
} else {
return false;
}
// retro-compatibility :
// return array(name,link) if you don't use the last version
// false otherwise
if (version_compare($this->currentPsVersion, $this->version_num, '<')) {
$this->need_upgrade = true;
return array('name' => $this->version_name, 'link' => $this->link);
} else {
return false;
}
}
/**
* delete the file /config/xml/$version.xml if exists.
*
* @param string $version
*
* @return bool true if succeed
*/
public function clearXmlMd5File($version)
{
if (file_exists(_PS_ROOT_DIR_ . '/config/xml/' . $version . '.xml')) {
return unlink(_PS_ROOT_DIR_ . '/config/xml/' . $version . '.xml');
}
return true;
}
/**
* use the addons api to get xml files.
*
* @param mixed $xml_localfile
* @param mixed $postData
* @param mixed $refresh
*/
public function getApiAddons($xml_localfile, $postData, $refresh = false)
{
if (!is_dir(_PS_ROOT_DIR_ . '/config/xml')) {
if (is_file(_PS_ROOT_DIR_ . '/config/xml')) {
unlink(_PS_ROOT_DIR_ . '/config/xml');
}
mkdir(_PS_ROOT_DIR_ . '/config/xml', 0777);
}
if ($refresh || !file_exists($xml_localfile) || @filemtime($xml_localfile) < (time() - (3600 * self::DEFAULT_CHECK_VERSION_DELAY_HOURS))) {
$protocolsList = array('https://' => 443, 'http://' => 80);
if (!extension_loaded('openssl')) {
unset($protocolsList['https://']);
}
// Make the request
$opts = array(
'http' => array(
'method' => 'POST',
'content' => $postData,
'header' => 'Content-type: application/x-www-form-urlencoded',
'timeout' => 10,
), );
$context = stream_context_create($opts);
$xml = false;
foreach ($protocolsList as $protocol => $port) {
$xml_string = Tools14::file_get_contents($protocol . $this->addons_api, false, $context);
if ($xml_string) {
$xml = @simplexml_load_string($xml_string);
break;
}
}
if ($xml !== false) {
file_put_contents($xml_localfile, $xml_string);
}
} else {
$xml = @simplexml_load_file($xml_localfile);
}
return $xml;
}
public function getXmlFile($xml_localfile, $xml_remotefile, $refresh = false)
{
// @TODO : this has to be moved in autoupgrade.php > install method
if (!is_dir(_PS_ROOT_DIR_ . '/config/xml')) {
if (is_file(_PS_ROOT_DIR_ . '/config/xml')) {
unlink(_PS_ROOT_DIR_ . '/config/xml');
}
mkdir(_PS_ROOT_DIR_ . '/config/xml', 0777);
}
if ($refresh || !file_exists($xml_localfile) || @filemtime($xml_localfile) < (time() - (3600 * self::DEFAULT_CHECK_VERSION_DELAY_HOURS))) {
$xml_string = Tools14::file_get_contents($xml_remotefile, false, stream_context_create(array('http' => array('timeout' => 10))));
$xml = @simplexml_load_string($xml_string);
if ($xml !== false) {
file_put_contents($xml_localfile, $xml_string);
}
} else {
$xml = @simplexml_load_file($xml_localfile);
}
return $xml;
}
public function getXmlChannel($refresh = false)
{
$xml = $this->getXmlFile(
_PS_ROOT_DIR_ . '/config/xml/' . pathinfo($this->rss_channel_link, PATHINFO_BASENAME),
$this->rss_channel_link,
$refresh
);
if ($refresh) {
if (class_exists('Configuration', false)) {
Configuration::updateValue('PS_LAST_VERSION_CHECK', time());
}
}
return $xml;
}
/**
* return xml containing the list of all default PrestaShop files for version $version,
* and their respective md5sum.
*
* @param string $version
*
* @return \SimpleXMLElement|false if error
*/
public function getXmlMd5File($version, $refresh = false)
{
return $this->getXmlFIle(_PS_ROOT_DIR_ . '/config/xml/' . $version . '.xml', $this->rss_md5file_link_dir . $version . '.xml', $refresh);
}
/**
* returns an array of files which are present in PrestaShop version $version and has been modified
* in the current filesystem.
*
* @return array of string> array of filepath
*/
public function getChangedFilesList($version = null, $refresh = false)
{
if (empty($version)) {
$version = $this->currentPsVersion;
}
if (is_array($this->changed_files) && count($this->changed_files) == 0) {
$checksum = $this->getXmlMd5File($version, $refresh);
if ($checksum == false) {
$this->changed_files = false;
} else {
$this->browseXmlAndCompare($checksum->ps_root_dir[0]);
}
}
return $this->changed_files;
}
/** populate $this->changed_files with $path
* in sub arrays mail, translation and core items.
*
* @param string $path filepath to add, relative to _PS_ROOT_DIR_
*/
protected function addChangedFile($path)
{
$this->version_is_modified = true;
if (strpos($path, 'mails/') !== false) {
$this->changed_files['mail'][] = $path;
} elseif (strpos($path, '/en.php') !== false || strpos($path, '/fr.php') !== false
|| strpos($path, '/es.php') !== false || strpos($path, '/it.php') !== false
|| strpos($path, '/de.php') !== false || strpos($path, 'translations/') !== false) {
$this->changed_files['translation'][] = $path;
} else {
$this->changed_files['core'][] = $path;
}
}
/** populate $this->missing_files with $path
* @param string $path filepath to add, relative to _PS_ROOT_DIR_
*/
protected function addMissingFile($path)
{
$this->version_is_modified = true;
$this->missing_files[] = $path;
}
public function md5FileAsArray($node, $dir = '/')
{
$array = array();
foreach ($node as $key => $child) {
if (is_object($child) && $child->getName() == 'dir') {
$dir = (string) $child['name'];
/**
* $current_path = $dir.(string)$child['name'];.
*
* @todo : something else than array pop ?
*/
$dir_content = $this->md5FileAsArray($child, $dir);
$array[$dir] = $dir_content;
} elseif (is_object($child) && $child->getName() == 'md5file') {
$array[(string) $child['name']] = (string) $child;
}
}
return $array;
}
/**
* getDiffFilesList.
*
* @param string $version1
* @param string $version2
* @param bool $show_modif
*
* @return array|false array('modified'=>array(...), 'deleted'=>array(...))
*/
public function getDiffFilesList($version1, $version2, $show_modif = true, $refresh = false)
{
$checksum1 = $this->getXmlMd5File($version1, $refresh);
$checksum2 = $this->getXmlMd5File($version2, $refresh);
if ($checksum1) {
$v1 = $this->md5FileAsArray($checksum1->ps_root_dir[0]);
}
if ($checksum2) {
$v2 = $this->md5FileAsArray($checksum2->ps_root_dir[0]);
}
if (empty($v1) || empty($v2)) {
return false;
}
$filesList = $this->compareReleases($v1, $v2, $show_modif);
if (!$show_modif) {
return $filesList['deleted'];
}
return $filesList;
}
/**
* returns an array of files which.
*
* @param array $v1 result of method $this->md5FileAsArray()
* @param array $v2 result of method $this->md5FileAsArray()
* @param bool $show_modif if set to false, the method will only
* list deleted files
* @param string $path
* deleted files in version $v2. Otherwise, only deleted.
*
* @return array('modified' => array(files..), 'deleted' => array(files..)
*/
public function compareReleases($v1, $v2, $show_modif = true, $path = '/')
{
// in that array the list of files present in v1 deleted in v2
static $deletedFiles = array();
// in that array the list of files present in v1 modified in v2
static $modifiedFiles = array();
foreach ($v1 as $file => $md5) {
if (is_array($md5)) {
$subpath = $path . $file;
if (isset($v2[$file]) && is_array($v2[$file])) {
$this->compareReleases($md5, $v2[$file], $show_modif, $path . $file . '/');
} else { // also remove old dir
$deletedFiles[] = $subpath;
}
} else {
if (in_array($file, array_keys($v2))) {
if ($show_modif && ($v1[$file] != $v2[$file])) {
$modifiedFiles[] = $path . $file;
}
$exists = true;
} else {
$deletedFiles[] = $path . $file;
}
}
}
return array('deleted' => $deletedFiles, 'modified' => $modifiedFiles);
}
/**
* Compare the md5sum of the current files with the md5sum of the original.
*
* @param mixed $node
* @param array $current_path
* @param int $level
*/
protected function browseXmlAndCompare($node, &$current_path = array(), $level = 1)
{
foreach ($node as $key => $child) {
if (is_object($child) && $child->getName() == 'dir') {
$current_path[$level] = (string) $child['name'];
$this->browseXmlAndCompare($child, $current_path, $level + 1);
} elseif (is_object($child) && $child->getName() == 'md5file') {
// We will store only relative path.
// absolute path is only used for file_exists and compare
$relative_path = '';
for ($i = 1; $i < $level; ++$i) {
$relative_path .= $current_path[$i] . '/';
}
$relative_path .= (string) $child['name'];
$fullpath = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $relative_path;
$fullpath = str_replace('ps_root_dir', _PS_ROOT_DIR_, $fullpath);
// replace default admin dir by current one
$fullpath = str_replace(_PS_ROOT_DIR_ . '/admin', _PS_ADMIN_DIR_, $fullpath);
$fullpath = str_replace(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'admin', _PS_ADMIN_DIR_, $fullpath);
if (!file_exists($fullpath)) {
$this->addMissingFile($relative_path);
} elseif (!$this->compareChecksum($fullpath, (string) $child) && substr(str_replace(DIRECTORY_SEPARATOR, '-', $relative_path), 0, 19) != 'modules/autoupgrade') {
$this->addChangedFile($relative_path);
}
// else, file is original (and ok)
}
}
}
protected function compareChecksum($filepath, $md5sum)
{
return md5_file($filepath) == $md5sum;
}
public function isAuthenticPrestashopVersion($version = null, $refresh = false)
{
$this->getChangedFilesList($version, $refresh);
return !$this->version_is_modified;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
class Workspace
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var UpgradeTools\Translator
*/
private $translator;
/**
* @var array List of paths used by autoupgrade
*/
private $paths;
public function __construct(LoggerInterface $logger, $translator, array $paths)
{
$this->logger = $logger;
$this->translator = $translator;
$this->paths = $paths;
}
public function createFolders()
{
foreach ($this->paths as $path) {
if (!file_exists($path) && !mkdir($path)) {
$this->logger->error($this->translator->trans('Unable to create directory %s', array($path), 'Modules.Autoupgrade.Admin'));
}
if (!is_writable($path)) {
$this->logger->error($this->translator->trans('Unable to write in the directory "%s"', array($path), 'Modules.Autoupgrade.Admin'));
}
}
}
}

View File

@@ -0,0 +1,259 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\AutoUpgrade;
use PrestaShop\Module\AutoUpgrade\Log\LoggerInterface;
use Symfony\Component\Filesystem\Filesystem;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
class ZipAction
{
/**
* @var int Number of files added in a zip per request
*/
private $configMaxNbFilesCompressedInARow;
/**
* @var int Max file size allowed in a zip file
*/
private $configMaxFileSizeAllowed;
private $logger;
private $translator;
/**
* @var string Path to the shop, in order to remove it from the archived file paths
*/
private $prodRootDir;
public function __construct($translator, LoggerInterface $logger, UpgradeConfiguration $configuration, $prodRootDir)
{
$this->translator = $translator;
$this->logger = $logger;
$this->prodRootDir = $prodRootDir;
$this->configMaxNbFilesCompressedInARow = $configuration->getNumberOfFilesPerCall();
$this->configMaxFileSizeAllowed = $configuration->getMaxFileToBackup();
}
/**
* Add files to an archive.
* Note the number of files added can be limited.
*
* @var array List of files to add
* @var string $toFile
*/
public function compress(&$filesList, $toFile)
{
$zip = $this->open($toFile, \ZipArchive::CREATE);
if ($zip === false) {
return false;
}
for ($i = 0; $i < $this->configMaxNbFilesCompressedInARow && count($filesList); ++$i) {
$file = array_shift($filesList);
$archiveFilename = $this->getFilepathInArchive($file);
if (!$this->isFileWithinFileSizeLimit($file)) {
continue;
}
if (!$zip->addFile($file, $archiveFilename)) {
// if an error occur, it's more safe to delete the corrupted backup
$zip->close();
(new Filesystem())->remove($toFile);
$this->logger->error($this->translator->trans(
'Error when trying to add %filename% to archive %archive%.',
array(
'%filename%' => $file,
'%archive%' => $archiveFilename,
),
'Modules.Autoupgrade.Admin'
));
return false;
}
$this->logger->debug($this->translator->trans(
'%filename% added to archive. %filescount% files left.',
array(
'%filename%' => $archiveFilename,
'%filescount%' => count($filesList),
),
'Modules.Autoupgrade.Admin'
));
}
if (!$zip->close()) {
$this->logger->error($this->translator->trans(
'Could not close the Zip file properly. Check you are allowed to write on the disk and there is available space on it.',
array(),
'Modules.Autoupgrade.Admin'
));
return false;
}
return true;
}
/**
* Extract an archive to the given directory
*
* @return bool success
* we need a copy of it to be able to restore without keeping Tools and Autoload stuff
*/
public function extract($from_file, $to_dir)
{
if (!is_file($from_file)) {
$this->logger->error($this->translator->trans('%s is not a file', array($from_file), 'Modules.Autoupgrade.Admin'));
return false;
}
if (!file_exists($to_dir)) {
// ToDo: Use Filesystem from Symfony
if (!mkdir($to_dir)) {
$this->logger->error($this->translator->trans('Unable to create directory %s.', array($to_dir), 'Modules.Autoupgrade.Admin'));
return false;
}
chmod($to_dir, 0775);
}
$zip = $this->open($from_file);
if ($zip === false) {
return false;
}
for ($i = 0; $i < $zip->numFiles; ++$i) {
if (!$zip->extractTo($to_dir, array($zip->getNameIndex($i)))) {
$this->logger->error(
$this->translator->trans(
'Could not extract %file% from backup, the destination might not be writable.',
['%file%' => $zip->statIndex($i)['name']],
'Modules.Autoupgrade.Admin'
)
);
$zip->close();
return false;
}
}
$zip->close();
$this->logger->debug($this->translator->trans('Archive extracted', array(), 'Modules.Autoupgrade.Admin'));
return true;
}
/**
* Lists the files present in the given archive
*
* @var string Path to the file
*
* @return array
*/
public function listContent($zipfile)
{
if (!file_exists($zipfile)) {
return [];
}
$zip = $this->open($zipfile);
if ($zip === false) {
$this->logger->error($this->translator->trans('[ERROR] Unable to list archived files', array(), 'Modules.Autoupgrade.Admin'));
return [];
}
$files = [];
for ($i = 0; $i < $zip->numFiles; ++$i) {
$files[] = $zip->getNameIndex($i);
}
return $files;
}
/**
* Get the path of a file from the archive root
*
* @var string Path of the file on the filesystem
*
* @return string Path of the file in the backup archive
*/
private function getFilepathInArchive($filepath)
{
return ltrim(str_replace($this->prodRootDir, '', $filepath), DIRECTORY_SEPARATOR);
}
/**
* Checks a file size matches the given limits
*
* @var string Path to a file
*
* @return bool Size is inside the maximum limit
*/
private function isFileWithinFileSizeLimit($filepath)
{
$size = filesize($filepath);
$pass = ($size < $this->configMaxFileSizeAllowed);
if (!$pass) {
$this->logger->debug($this->translator->trans(
'File %filename% (size: %filesize%) has been skipped during backup.',
array(
'%filename%' => $this->getFilepathInArchive($filepath),
'%filesize%' => $size,
),
'Modules.Autoupgrade.Admin'
));
}
return $pass;
}
/**
* Open an archive
*
* @var string Path to the archive
* @var int ZipArchive flags
*
* @return false|\ZipArchive
*/
private function open($zipFile, $flags = null)
{
$this->logger->debug($this->translator->trans('Using class ZipArchive...', array(), 'Modules.Autoupgrade.Admin'));
$zip = new \ZipArchive();
if ($zip->open($zipFile, $flags) !== true || empty($zip->filename)) {
$this->logger->error($this->translator->trans('Unable to open zipFile %s', array($zipFile), 'Modules.Autoupgrade.Admin'));
return false;
}
return $zip;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (PHP_SAPI !== 'cli') {
echo 'This script must be called from CLI';
exit(1);
}
require_once realpath(dirname(__FILE__) . '/../../modules/autoupgrade') . '/ajax-upgradetabconfig.php';
$container = autoupgrade_init_container(dirname(__FILE__));
$container->setLogger(new PrestaShop\Module\AutoUpgrade\Log\StreamedLogger());
$controller = new \PrestaShop\Module\AutoUpgrade\TaskRunner\Rollback\AllRollbackTasks($container);
$controller->setOptions(getopt('', array('backup::')));
$controller->init();
exit($controller->run());

View File

@@ -0,0 +1,40 @@
<?php
/*
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (PHP_SAPI !== 'cli') {
echo 'This script must be called from CLI';
exit(1);
}
require_once realpath(dirname(__FILE__) . '/../../modules/autoupgrade') . '/ajax-upgradetabconfig.php';
$container = autoupgrade_init_container(dirname(__FILE__));
$container->setLogger(new PrestaShop\Module\AutoUpgrade\Log\StreamedLogger());
$controller = new \PrestaShop\Module\AutoUpgrade\TaskRunner\Upgrade\AllUpgradeTasks($container);
$controller->setOptions(getopt('', array('action::', 'channel::', 'data::')));
$controller->init();
exit($controller->run());

View File

@@ -0,0 +1,35 @@
{
"name": "prestashop/autoupgrade",
"description": "PrestaShop module autoupgrade",
"homepage": "https://github.com/PrestaShop/autoupgrade",
"license": "AFL-3.0",
"authors": [
{
"name": "PrestaShop SA",
"email": "contact@prestashop.com"
}
],
"require": {
"php": ">=5.6",
"ext-zip": "*",
"symfony/filesystem": "~2.8",
"doctrine/collections": "~1.3.0",
"twig/twig": "^1.35"
},
"config": {
"preferred-install": "dist",
"platform": {
"php": "5.6"
}
},
"type": "prestashop-module",
"autoload": {
"psr-4": {
"PrestaShop\\Module\\AutoUpgrade\\": "classes/",
"PrestaShop\\Module\\AutoUpgrade\\Temp\\": "templates/"
}
},
"require-dev": {
"phpunit/phpunit": "^5"
}
}

1525
web/modules/autoupgrade/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>autoupgrade</name>
<displayName><![CDATA[1-Click Upgrade]]></displayName>
<version><![CDATA[4.8.0]]></version>
<description><![CDATA[Provides an automated method to upgrade your shop to the latest version of PrestaShop.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[administration]]></tab>
<is_configurable>1</is_configurable>
<need_instance>1</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>autoupgrade</name>
<displayName><![CDATA[1-Click Upgrade]]></displayName>
<version><![CDATA[4.8.0]]></version>
<description><![CDATA[Provides an automated method to upgrade your shop to the latest version of PrestaShop.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[administration]]></tab>
<is_configurable>1</is_configurable>
<need_instance>1</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,19 @@
.upgradestep { margin-right: 5px;padding-left: 10px; padding-right: 5px;}
.processing {border:2px outset gray;margin-top:1px;overflow: auto;}
#infoStep {height:100px;}
#infoError {height:100px;}
#quickInfo {height:200px;}
#errorDuringUpgrade {color: #CC0000}
#checkPrestaShopFilesVersion, #checkPrestaShopModifiedFiles{margin-bottom:20px;}
.changedFileList {margin-left:20px; padding-left:5px;}
.changedNotice li{color:gray;}
.changedImportant li{color:red;font-weight:bold}
.upgradeDbError{background-color:#FEEFB3}
.upgradeDbOk{background-color:#DFF2BF}
.small_label{font-weight:normal;width:300px;float:none;text-align:left;padding:0}
.ocu-feature-list{margin:0;padding:0;list-style:none}
.ocu-feature-list li{background:url(../img/admin/enabled.gif) no-repeat; padding-left:20px;margin:0;}
.label-small {width: 130px;}
.margin-form-small {padding: 0 0 1em 130px;}
.nextStep {font-weight: bold;}
#diffList, #changedList {margin-top: 20px;}

View File

@@ -0,0 +1,730 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class DbCore
{
/**
* Constants used by insert() method
*/
const INSERT = 1;
const INSERT_IGNORE = 2;
const REPLACE = 3;
/**
* @var string Server (eg. localhost)
*/
protected $server;
/**
* @var string Database user (eg. root)
*/
protected $user;
/**
* @var string Database password (eg. can be empty !)
*/
protected $password;
/**
* @var string Database name
*/
protected $database;
/**
* @var bool
*/
protected $is_cache_enabled;
/**
* @var mixed Ressource link
*/
protected $link;
/**
* @var mixed SQL cached result
*/
protected $result;
/**
* @var array List of DB instance
*/
protected static $instance = array();
/**
* @var array Object instance for singleton
*/
protected static $_servers = array(
array('server' => _DB_SERVER_, 'user' => _DB_USER_, 'password' => _DB_PASSWD_, 'database' => _DB_NAME_), /* MySQL Master server */
// Add here your slave(s) server(s)
// array('server' => '192.168.0.15', 'user' => 'rep', 'password' => '123456', 'database' => 'rep'),
// array('server' => '192.168.0.3', 'user' => 'myuser', 'password' => 'mypassword', 'database' => 'mydatabase'),
);
/**
* Store last executed query
*
* @var string
*/
protected $last_query;
/**
* Last cached query
*
* @var string
*/
protected $last_cached;
/**
* Open a connection
*/
abstract public function connect();
/**
* Close a connection
*/
abstract public function disconnect();
/**
* Execute a query and get result resource
*
* @param string $sql
* @return mixed
*/
abstract protected function _query($sql);
/**
* Get number of rows in a result
*
* @param mixed $result
*/
abstract protected function _numRows($result);
/**
* Get the ID generated from the previous INSERT operation
*/
abstract public function Insert_ID();
/**
* Get number of affected rows in previous database operation
*/
abstract public function Affected_Rows();
/**
* Get next row for a query which doesn't return an array
*
* @param mixed $result
*/
abstract public function nextRow($result = false);
/**
* Get database version
*
* @return string
*/
abstract public function getVersion();
/**
* Protect string against SQL injections
*
* @param string $str
* @return string
*/
abstract public function _escape($str);
/**
* Returns the text of the error message from previous database operation
*/
abstract public function getMsgError();
/**
* Returns the number of the error from previous database operation
*/
abstract public function getNumberError();
/* do not remove, useful for some modules */
abstract public function set_db($db_name);
/**
* Get Db object instance
*
* @param bool $master Decides whether the connection to be returned by the master server or the slave server
* @return Db instance
*/
public static function getInstance($master = true)
{
static $id = 0;
$total_servers = count(self::$_servers);
if ($master || $total_servers == 1)
$id_server = 0;
else
{
$id++;
$id_server = ($total_servers > 2 && ($id % $total_servers) != 0) ? $id : 1;
}
if (!isset(self::$instance[$id_server]))
{
$class = Db::getClass();
self::$instance[$id_server] = new $class(
self::$_servers[$id_server]['server'],
self::$_servers[$id_server]['user'],
self::$_servers[$id_server]['password'],
self::$_servers[$id_server]['database']
);
}
return self::$instance[$id_server];
}
/**
* Get child layer class
*
* @return string
*/
public static function getClass()
{
if (!defined('PHP_VERSION_ID'))
{
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
$class = 'MySQL';
if (extension_loaded('mysql') && PHP_VERSION_ID < 50500)
$class = 'MySQL';
elseif (extension_loaded('mysqli') && (PHP_VERSION_ID < 50300 || extension_loaded('mysqlnd')))
$class = 'DbMySQLi';
elseif (PHP_VERSION_ID >= 50200 && extension_loaded('pdo_mysql'))
$class = 'DbPDO';
return $class;
}
/**
* Instantiate database connection
*
* @param string $server Server address
* @param string $user User login
* @param string $password User password
* @param string $database Database name
* @param bool $connect If false, don't connect in constructor (since 1.5.0)
*/
public function __construct($server, $user, $password, $database, $connect = true)
{
$this->server = $server;
$this->user = $user;
$this->password = $password;
$this->database = $database;
$this->is_cache_enabled = (defined('_PS_CACHE_ENABLED_')) ? _PS_CACHE_ENABLED_ : false;
if (!defined('_PS_DEBUG_SQL_'))
define('_PS_DEBUG_SQL_', false);
if (!defined('_PS_MAGIC_QUOTES_GPC_'))
define('_PS_MAGIC_QUOTES_GPC_', get_magic_quotes_gpc());
if ($connect)
$this->connect();
}
/**
* Close connection to database
*/
public function __destruct()
{
if ($this->link)
$this->disconnect();
}
/**
* @deprecated 1.5.0 use insert() or update() method instead
*/
public function autoExecute($table, $data, $type, $where = '', $limit = 0, $use_cache = true, $use_null = false)
{
$type = strtoupper($type);
switch ($type)
{
case 'INSERT' :
return $this->insert($table, $data, $use_null, $use_cache, Db::INSERT, false);
case 'INSERT IGNORE' :
return $this->insert($table, $data, $use_null, $use_cache, Db::INSERT_IGNORE, false);
case 'REPLACE' :
return $this->insert($table, $data, $use_null, $use_cache, Db::REPLACE, false);
case 'UPDATE' :
return $this->update($table, $data, $where, $limit, $use_null, $use_cache, false);
default :
Tools14::displayError('Wrong argument (miss type) in Db::autoExecute()');
exit();
break;
}
}
/**
* Filter SQL query within a blacklist
*
* @param string $table Table where insert/update data
* @param string $values Data to insert/update
* @param string $type INSERT or UPDATE
* @param string $where WHERE clause, only for UPDATE (optional)
* @param int $limit LIMIT clause (optional)
* @return mixed|boolean SQL query result
*/
public function autoExecuteWithNullValues($table, $values, $type, $where = '', $limit = 0)
{
return $this->autoExecute($table, $values, $type, $where, $limit, 0, true);
}
/**
* Execute a query and get result ressource
*
* @param string $sql
* @return mixed
*/
public function query($sql)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
$this->result = $this->_query($sql);
if (_PS_DEBUG_SQL_)
$this->displayError($sql);
return $this->result;
}
/**
* Execute an INSERT query
*
* @param string $table Table name without prefix
* @param array $data Data to insert as associative array. If $data is a list of arrays, multiple insert will be done
* @param bool $null_values If we want to use NULL values instead of empty quotes
* @param bool $use_cache
* @param int $type Must be Db::INSERT or Db::INSERT_IGNORE or Db::REPLACE
* @param bool $add_prefix Add or not _DB_PREFIX_ before table name
* @return bool
*/
public function insert($table, $data, $null_values = false, $use_cache = true, $type = Db::INSERT, $add_prefix = true)
{
if (!$data && !$null_values)
return true;
if ($add_prefix)
$table = _DB_PREFIX_.$table;
if ($type == Db::INSERT)
$insert_keyword = 'INSERT';
else if ($type == Db::INSERT_IGNORE)
$insert_keyword = 'INSERT IGNORE';
else if ($type == Db::REPLACE)
$insert_keyword = 'REPLACE';
else
{
Tools14::displayError('Bad keyword, must be Db::INSERT or Db::INSERT_IGNORE or Db::REPLACE');
exit();
}
// Check if $data is a list of row
$current = current($data);
if (!is_array($current) || isset($current['type']))
$data = array($data);
$keys = array();
$values_stringified = array();
foreach ($data as $row_data)
{
$values = array();
foreach ($row_data as $key => $value)
{
if (isset($keys_stringified))
{
// Check if row array mapping are the same
if (!in_array("`$key`", $keys))
{
Tools14::displayError('Keys form $data subarray don\'t match');
exit();
}
}
else
$keys[] = "`$key`";
if (!is_array($value))
$value = array('type' => 'text', 'value' => $value);
if ($value['type'] == 'sql')
$values[] = $value['value'];
else
$values[] = $null_values && ($value['value'] === '' || is_null($value['value'])) ? 'NULL' : "'{$value['value']}'";
}
$keys_stringified = implode(', ', $keys);
$values_stringified[] = '('.implode(', ', $values).')';
}
$sql = $insert_keyword.' INTO `'.$table.'` ('.$keys_stringified.') VALUES '.implode(', ', $values_stringified);
return (bool)$this->q($sql, $use_cache);
}
/**
* @param string $table Table name without prefix
* @param array $data Data to insert as associative array. If $data is a list of arrays, multiple insert will be done
* @param string $where WHERE condition
* @param int $limit
* @param bool $null_values If we want to use NULL values instead of empty quotes
* @param bool $use_cache
* @param bool $add_prefix Add or not _DB_PREFIX_ before table name
* @return bool
*/
public function update($table, $data, $where = '', $limit = 0, $null_values = false, $use_cache = true, $add_prefix = true)
{
if (!$data)
return true;
if ($add_prefix)
$table = _DB_PREFIX_.$table;
$sql = 'UPDATE `'.$table.'` SET ';
foreach ($data as $key => $value)
{
if (!is_array($value))
$value = array('type' => 'text', 'value' => $value);
if ($value['type'] == 'sql')
$sql .= "`$key` = {$value['value']},";
else
$sql .= ($null_values && ($value['value'] === '' || is_null($value['value']))) ? "`$key` = NULL," : "`$key` = '{$value['value']}',";
}
$sql = rtrim($sql, ',');
if ($where)
$sql .= ' WHERE '.$where;
if ($limit)
$sql .= ' LIMIT '.(int)$limit;
return (bool)$this->q($sql, $use_cache);
}
/**
* Execute a DELETE query
*
* @param string $table Name of the table to delete
* @param string $where WHERE clause on query
* @param int $limit Number max of rows to delete
* @param bool $use_cache Use cache or not
* @param bool $add_prefix Add or not _DB_PREFIX_ before table name
* @return bool
*/
public function delete($table, $where = '', $limit = 0, $use_cache = true, $add_prefix = true)
{
if (_DB_PREFIX_ && !preg_match('#^'._DB_PREFIX_.'#i', $table) && $add_prefix)
$table = _DB_PREFIX_.$table;
$this->result = false;
$sql = 'DELETE FROM `'.bqSQL($table).'`'.($where ? ' WHERE '.$where : '').($limit ? ' LIMIT '.(int)$limit : '');
$res = $this->query($sql);
if ($use_cache && $this->is_cache_enabled)
Cache::getInstance()->deleteQuery($sql);
return (bool)$res;
}
/**
* Execute a query
*
* @param string $sql
* @param bool $use_cache
* @return bool
*/
public function execute($sql, $use_cache = true)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
if (trim($sql) == false)
return ($this->result = true);
$this->result = $this->query($sql);
if ($use_cache && $this->is_cache_enabled)
Cache::getInstance()->deleteQuery($sql);
return (bool)$this->result;
}
/**
* ExecuteS return the result of $sql as array
*
* @param string $sql query to execute
* @param boolean $array return an array instead of a mysql_result object (deprecated since 1.5.0, use query method instead)
* @param bool $use_cache if query has been already executed, use its result
* @return array or result object
*/
public function executeS($sql, $array = true, $use_cache = true)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
// This method must be used only with queries which display results
if (!preg_match('#^\s*\(?\s*(select|show|explain|describe|desc)\s#i', $sql))
{
if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_)
{
Tools14::displayError('Db->executeS() must be used only with select, show, explain or describe queries');
exit();
}
return $this->execute($sql, $use_cache);
}
$this->result = false;
$this->last_query = $sql;
if ($use_cache && $this->is_cache_enabled && $array && ($result = Cache::getInstance()->get(md5($sql))))
{
$this->last_cached = true;
return $result;
}
$this->result = $this->query($sql);
if (!$this->result)
return false;
$this->last_cached = false;
if (!$array)
return $this->result;
$result_array = array();
while ($row = $this->nextRow($this->result))
$result_array[] = $row;
if ($use_cache && $this->is_cache_enabled)
Cache::getInstance()->setQuery($sql, $result_array);
return $result_array;
}
/**
* getRow return an associative array containing the first row of the query
* This function automatically add "limit 1" to the query
*
* @param mixed $sql the select query (without "LIMIT 1")
* @param bool $use_cache find it in cache first
* @return array associative array of (field=>value)
*/
public function getRow($sql, $use_cache = true)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
$sql .= ' LIMIT 1';
$this->result = false;
$this->last_query = $sql;
if ($use_cache && $this->is_cache_enabled && ($result = Cache::getInstance()->get(md5($sql))))
{
$this->last_cached = true;
return $result;
}
$this->result = $this->query($sql);
if (!$this->result)
return false;
$this->last_cached = false;
$result = $this->nextRow($this->result);
if ($use_cache && $this->is_cache_enabled)
Cache::getInstance()->setQuery($sql, $result);
return $result;
}
/**
* getValue return the first item of a select query.
*
* @param mixed $sql
* @param bool $use_cache
* @return mixed
*/
public function getValue($sql, $use_cache = true)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
if (!$result = $this->getRow($sql, $use_cache))
return false;
return array_shift($result);
}
/**
* Get number of rows for last result
*
* @return int
*/
public function numRows()
{
if (!$this->last_cached && $this->result)
{
$nrows = $this->_numRows($this->result);
if ($this->is_cache_enabled)
Cache::getInstance()->set(md5($this->last_query).'_nrows', $nrows);
return $nrows;
}
else if ($this->is_cache_enabled && $this->last_cached)
return Cache::getInstance()->get(md5($this->last_query).'_nrows');
}
/**
*
* Execute a query
*
* @param string $sql
* @param bool $use_cache
* @return mixed $result
*/
protected function q($sql, $use_cache = true)
{
if ($sql instanceof DbQuery)
$sql = $sql->build();
$this->result = false;
$result = $this->query($sql);
if ($use_cache && $this->is_cache_enabled)
Cache::getInstance()->deleteQuery($sql);
return $result;
}
/**
* Display last SQL error
*
* @param bool $sql
*/
public function displayError($sql = false)
{
global $webservice_call;
$errno = $this->getNumberError();
if ($webservice_call && $errno)
{
$dbg = debug_backtrace();
WebserviceRequest::getInstance()->setError(500, '[SQL Error] '.$this->getMsgError().'. From '.(isset($dbg[3]['class']) ? $dbg[3]['class'] : '').'->'.$dbg[3]['function'].'() Query was : '.$sql, 97);
}
else if (_PS_DEBUG_SQL_ && $errno && !defined('PS_INSTALLATION_IN_PROGRESS'))
{
if ($sql)
Tools14::displayError($this->getMsgError().'<br /><br /><pre>'.$sql.'</pre>');
Tools14::displayError($this->getMsgError());
exit();
}
}
/**
* Sanitize data which will be injected into SQL query
*
* @param string $string SQL data which will be injected into SQL query
* @param boolean $html_ok Does data contain HTML code ? (optional)
* @return string Sanitized data
*/
public function escape($string, $html_ok = false)
{
if (_PS_MAGIC_QUOTES_GPC_)
$string = stripslashes($string);
if (!is_numeric($string))
{
$string = $this->_escape($string);
if (!$html_ok)
$string = strip_tags(Tools14::nl2br($string));
}
return $string;
}
/**
* Try a connection to te database
*
* @param string $server Server address
* @param string $user Login for database connection
* @param string $pwd Password for database connection
* @param string $db Database name
* @param bool $new_db_link
* @param bool $engine
* @return int
*/
public static function checkConnection($server, $user, $pwd, $db, $new_db_link = true, $engine = null, $timeout = 5)
{
return call_user_func_array(array(Db::getClass(), 'tryToConnect'), array($server, $user, $pwd, $db, $new_db_link, $engine, $timeout));
}
/**
* Try a connection to te database
*
* @param string $server Server address
* @param string $user Login for database connection
* @param string $pwd Password for database connection
* @return int
*/
public static function checkEncoding($server, $user, $pwd)
{
return call_user_func_array(array(Db::getClass(), 'tryUTF8'), array($server, $user, $pwd));
}
/**
* Try a connection to the database and check if at least one table with same prefix exists
*
* @param string $server Server address
* @param string $user Login for database connection
* @param string $pwd Password for database connection
* @param string $db Database name
* @param string $prefix Tables prefix
* @return bool
*/
public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix)
{
return call_user_func_array(array(Db::getClass(), 'hasTableWithSamePrefix'), array($server, $user, $pwd, $db, $prefix));
}
public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine)
{
return call_user_func_array(array(Db::getClass(), 'checkCreatePrivilege'), array($server, $user, $pwd, $db, $prefix, $engine));
}
/**
* @deprecated 1.5.0
*/
public static function s($sql, $use_cache = true)
{
return Db::getInstance()->executeS($sql, true, $use_cache);
}
/**
* @deprecated 1.5.0
*/
public static function ps($sql, $use_cache = 1)
{
$ret = Db::s($sql, $use_cache);
p($ret);
return $ret;
}
/**
* @deprecated 1.5.0
*/
public static function ds($sql, $use_cache = 1)
{
Db::s($sql, $use_cache);
die();
}
}

View File

@@ -0,0 +1,247 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @since 1.5.0
*/
class DbMySQLiCore extends Db
{
/**
* @see DbCore::connect()
*/
public function connect()
{
$socket = false;
$port = false;
if (strpos($this->server, ':') !== false)
{
list($server, $port) = explode(':', $this->server);
if (is_numeric($port) === false)
{
$socket = $port;
$port = false;
}
}
elseif (strpos($this->server, '/') !== false)
{
$socket = $this->server;
}
if ($socket)
{
$this->link = @new mysqli(null, $this->user, $this->password, $this->database, null, $socket);
}
elseif ($port)
{
$this->link = @new mysqli($server, $this->user, $this->password, $this->database, $port);
}
else
{
$this->link = @new mysqli($this->server, $this->user, $this->password, $this->database);
}
// Do not use object way for error because this work bad before PHP 5.2.9
if (mysqli_connect_error())
{
Tools14::displayError(sprintf(Tools14::displayError('Link to database cannot be established: %s'), mysqli_connect_error()));
exit();
}
// UTF-8 support
if (!$this->link->query('SET NAMES \'utf8\''))
{
Tools14::displayError(Tools14::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.'));
exit();
}
return $this->link;
}
/**
* @see DbCore::disconnect()
*/
public function disconnect()
{
@$this->link->close();
}
/**
* @see DbCore::_query()
*/
protected function _query($sql)
{
return $this->link->query($sql);
}
/**
* @see DbCore::nextRow()
*/
public function nextRow($result = false)
{
if (!$result)
$result = $this->result;
if (!is_object($result))
return false;
return $result->fetch_assoc();
}
/**
* @see DbCore::_numRows()
*/
protected function _numRows($result)
{
return $result->num_rows;
}
/**
* @see DbCore::Insert_ID()
*/
public function Insert_ID()
{
return $this->link->insert_id;
}
/**
* @see DbCore::Affected_Rows()
*/
public function Affected_Rows()
{
return $this->link->affected_rows;
}
/**
* @see DbCore::getMsgError()
*/
public function getMsgError($query = false)
{
return $this->link->error;
}
/**
* @see DbCore::getNumberError()
*/
public function getNumberError()
{
return $this->link->errno;
}
/**
* @see DbCore::getVersion()
*/
public function getVersion()
{
return $this->getValue('SELECT VERSION()');
}
/**
* @see DbCore::_escape()
*/
public function _escape($str)
{
return $this->link->real_escape_string($str);
}
/**
* @see DbCore::set_db()
*/
public function set_db($db_name)
{
return $this->link->query('USE '.pSQL($db_name));
}
/**
* @see Db::hasTableWithSamePrefix()
*/
public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix)
{
$link = @new mysqli($server, $user, $pwd, $db);
if (mysqli_connect_error())
return false;
$sql = 'SHOW TABLES LIKE \''.$prefix.'%\'';
$result = $link->query($sql);
return (bool)$result->fetch_assoc();
}
/**
* @see Db::checkConnection()
*/
public static function tryToConnect($server, $user, $pwd, $db, $newDbLink = true, $engine = null, $timeout = 5)
{
$link = mysqli_init();
if (!$link)
return -1;
if (!$link->options(MYSQLI_OPT_CONNECT_TIMEOUT, $timeout))
return 1;
if (!$link->real_connect($server, $user, $pwd, $db))
return (mysqli_connect_errno() == 1049) ? 2 : 1;
if (strtolower($engine) == 'innodb')
{
$sql = 'SHOW VARIABLES WHERE Variable_name = \'have_innodb\'';
$result = $link->query($sql);
if (!$result)
return 4;
$row = $result->fetch_assoc();
if (!$row || strtolower($row['Value']) != 'yes')
return 4;
}
$link->close();
return 0;
}
public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine)
{
$link = @new mysqli($server, $user, $pwd, $db);
if (mysqli_connect_error())
return false;
$sql = '
CREATE TABLE `'.$prefix.'test` (
`test` tinyint(1) unsigned NOT NULL
) ENGINE=MyISAM';
$result = $link->query($sql);
if (!$result)
return $link->error;
$link->query('DROP TABLE `'.$prefix.'test`');
return true;
}
/**
* @see Db::checkEncoding()
*/
static public function tryUTF8($server, $user, $pwd)
{
$link = @new mysqli($server, $user, $pwd, $db);
$ret = $link->query("SET NAMES 'UTF8'");
$link->close();
return $ret;
}
}

View File

@@ -0,0 +1,245 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* This class is currently only here for tests
*
* @since 1.5.0
*/
class DbPDOCore extends Db
{
protected static function _getPDO($host, $user, $password, $dbname, $timeout = 5)
{
$dsn = 'mysql:';
if ($dbname)
$dsn .= 'dbname='.$dbname.';';
if (preg_match('/^(.*):([0-9]+)$/', $host, $matches))
$dsn .= 'host='.$matches[1].';port='.$matches[2];
elseif (preg_match('#^.*:(/.*)$#', $host, $matches))
$dsn .= 'unix_socket='.$matches[1];
else
$dsn .= 'host='.$host;
return new PDO($dsn, $user, $password, array(PDO::ATTR_TIMEOUT => $timeout, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
}
/**
* @see DbCore::connect()
*/
public function connect()
{
try {
$this->link = $this->_getPDO($this->server, $this->user, $this->password, $this->database, 5);
} catch (PDOException $e) {
die(sprintf(Tools14::displayError('Link to database cannot be established: %s'), $e->getMessage()));
exit();
}
// UTF-8 support
if (!is_object($this->link) || $this->link->exec('SET NAMES \'utf8\'') === false)
{
Tools14::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.');
exit();
}
return $this->link;
}
/**
* @see DbCore::disconnect()
*/
public function disconnect()
{
unset($this->link);
}
/**
* @see DbCore::_query()
*/
protected function _query($sql)
{
return $this->link->query($sql);
}
/**
* @see DbCore::nextRow()
*/
public function nextRow($result = false)
{
if (!$result)
$result = $this->result;
if (!is_object($result))
return false;
return $result->fetch(PDO::FETCH_ASSOC);
}
/**
* @see DbCore::_numRows()
*/
protected function _numRows($result)
{
return $result->rowCount();
}
/**
* @see DbCore::Insert_ID()
*/
public function Insert_ID()
{
return $this->link->lastInsertId();
}
/**
* @see DbCore::Affected_Rows()
*/
public function Affected_Rows()
{
return $this->result->rowCount();
}
/**
* @see DbCore::getMsgError()
*/
public function getMsgError($query = false)
{
$error = $this->link->errorInfo();
return ($error[0] == '00000') ? '' : $error[2];
}
/**
* @see DbCore::getNumberError()
*/
public function getNumberError()
{
$error = $this->link->errorInfo();
return isset($error[1]) ? $error[1] : 0;
}
/**
* @see DbCore::getVersion()
*/
public function getVersion()
{
return $this->getValue('SELECT VERSION()');
}
/**
* @see DbCore::_escape()
*/
public function _escape($str)
{
$search = array("\\", "\0", "\n", "\r", "\x1a", "'", '"');
$replace = array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"');
return str_replace($search, $replace, $str);
}
/**
* @see DbCore::set_db()
*/
public function set_db($db_name)
{
return $this->link->exec('USE '.pSQL($db_name));
}
/**
* @see Db::hasTableWithSamePrefix()
*/
public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix)
{
try {
$link = DbPDO::_getPDO($server, $user, $pwd, $db, 5);
} catch (PDOException $e) {
return false;
}
$sql = 'SHOW TABLES LIKE \''.$prefix.'%\'';
$result = $link->query($sql);
return (bool)$result->fetch();
}
public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine)
{
try {
$link = DbPDO::_getPDO($server, $user, $pwd, $db, 5);
} catch (PDOException $e) {
return false;
}
$sql = '
CREATE TABLE `'.$prefix.'test` (
`test` tinyint(1) unsigned NOT NULL
) ENGINE=MyISAM';
$result = $link->query($sql);
if (!$result)
{
$error = $link->errorInfo();
return $error[2];
}
$link->query('DROP TABLE `'.$prefix.'test`');
return true;
}
/**
* @see Db::checkConnection()
*/
public static function tryToConnect($server, $user, $pwd, $db, $newDbLink = true, $engine = null, $timeout = 5)
{
try {
$link = DbPDO::_getPDO($server, $user, $pwd, $db, $timeout);
} catch (PDOException $e) {
return ($e->getCode() == 1049) ? 2 : 1;
}
if (strtolower($engine) == 'innodb')
{
$sql = 'SHOW VARIABLES WHERE Variable_name = \'have_innodb\'';
$result = $link->query($sql);
if (!$result)
return 4;
$row = $result->fetch();
if (!$row || strtolower($row['Value']) != 'yes')
return 4;
}
unset($link);
return 0;
}
/**
* @see Db::checkEncoding()
*/
public static function tryUTF8($server, $user, $pwd)
{
try {
$link = DbPDO::_getPDO($server, $user, $pwd, false, 5);
} catch (PDOException $e) {
return false;
}
$result = $link->exec('SET NAMES \'utf8\'');
unset($link);
return ($result === false) ? false : true;
}
}

View File

@@ -0,0 +1,254 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* SQL query builder
*
* @since 1.5.0
*/
class DbQueryCore
{
/**
* @var array list of data to build the query
*/
protected $query = array(
'select' => array(),
'from' => array(),
'join' => array(),
'where' => array(),
'group' => array(),
'having' => array(),
'order' => array(),
'limit' => array('offset' => 0, 'limit' => 0),
);
/**
* Add fields in query selection
*
* @param string $fields List of fields to concat to other fields
* @return DbQuery
*/
public function select($fields)
{
if (!empty($fields))
$this->query['select'][] = $fields;
return $this;
}
/**
* Set table for FROM clause
*
* @param string $table Table name
* @return DbQuery
*/
public function from($table, $alias = null)
{
if (!empty($table))
$this->query['from'][] = '`'._DB_PREFIX_.$table.'`'.($alias ? ' '.$alias : '');
return $this;
}
/**
* Add JOIN clause
* E.g. $this->join('RIGHT JOIN '._DB_PREFIX_.'product p ON ...');
*
* @param string $join Complete string
* @return DbQuery
*/
public function join($join)
{
if (!empty($join))
$this->query['join'][] = $join;
return $this;
}
/**
* Add LEFT JOIN clause
*
* @param string $table Table name (without prefix)
* @param string $alias Table alias
* @param string $on ON clause
*/
public function leftJoin($table, $alias = null, $on = null)
{
return $this->join('LEFT JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' `'.pSQL($alias).'`' : '').($on ? ' ON '.$on : ''));
}
/**
* Add INNER JOIN clause
* E.g. $this->innerJoin('product p ON ...')
*
* @param string $table Table name (without prefix)
* @param string $alias Table alias
* @param string $on ON clause
*/
public function innerJoin($table, $alias = null, $on = null)
{
return $this->join('INNER JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' '.pSQL($alias) : '').($on ? ' ON '.$on : ''));
}
/**
* Add LEFT OUTER JOIN clause
*
* @param string $table Table name (without prefix)
* @param string $alias Table alias
* @param string $on ON clause
*/
public function leftOuterJoin($table, $alias = null, $on = null)
{
return $this->join('LEFT OUTER JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' '.pSQL($alias) : '').($on ? ' ON '.$on : ''));
}
/**
* Add NATURAL JOIN clause
*
* @param string $table Table name (without prefix)
* @param string $alias Table alias
*/
public function naturalJoin($table, $alias = null)
{
return $this->join('NATURAL JOIN `'._DB_PREFIX_.bqSQL($table).'`'.($alias ? ' '.pSQL($alias) : ''));
}
/**
* Add a restriction in WHERE clause (each restriction will be separated by AND statement)
*
* @param string $restriction
* @return DbQuery
*/
public function where($restriction)
{
if (!empty($restriction))
$this->query['where'][] = $restriction;
return $this;
}
/**
* Add a restriction in HAVING clause (each restriction will be separated by AND statement)
*
* @param string $restriction
* @return DbQuery
*/
public function having($restriction)
{
if (!empty($restriction))
$this->query['having'][] = $restriction;
return $this;
}
/**
* Add an ORDER B restriction
*
* @param string $fields List of fields to sort. E.g. $this->order('myField, b.mySecondField DESC')
* @return DbQuery
*/
public function orderBy($fields)
{
if (!empty($fields))
$this->query['order'][] = $fields;
return $this;
}
/**
* Add a GROUP BY restriction
*
* @param string $fields List of fields to sort. E.g. $this->group('myField, b.mySecondField DESC')
* @return DbQuery
*/
public function groupBy($fields)
{
if (!empty($fields))
$this->query['group'][] = $fields;
return $this;
}
/**
* Limit results in query
*
* @param string $fields List of fields to sort. E.g. $this->order('myField, b.mySecondField DESC')
* @return DbQuery
*/
public function limit($limit, $offset = 0)
{
$offset = (int)$offset;
if ($offset < 0)
$offset = 0;
$this->query['limit'] = array(
'offset' => $offset,
'limit' => (int)$limit,
);
return $this;
}
/**
* Generate and get the query
*
* @return string
*/
public function build()
{
$sql = 'SELECT '.((($this->query['select'])) ? implode(",\n", $this->query['select']) : '*')."\n";
if (!$this->query['from'])
die('DbQuery->build() missing from clause');
$sql .= 'FROM '.implode(', ', $this->query['from'])."\n";
if ($this->query['join'])
$sql .= implode("\n", $this->query['join'])."\n";
if ($this->query['where'])
$sql .= 'WHERE ('.implode(') AND (', $this->query['where']).")\n";
if ($this->query['group'])
$sql .= 'GROUP BY '.implode(', ', $this->query['group'])."\n";
if ($this->query['having'])
$sql .= 'HAVING ('.implode(') AND (', $this->query['having']).")\n";
if ($this->query['order'])
$sql .= 'ORDER BY '.implode(', ', $this->query['order'])."\n";
if ($this->query['limit']['limit'])
{
$limit = $this->query['limit'];
$sql .= 'LIMIT '.(($limit['offset']) ? $limit['offset'].', '.$limit['limit'] : $limit['limit']);
}
return $sql;
}
public function __toString()
{
return $this->build();
}
}

View File

@@ -0,0 +1,224 @@
<?php
/**
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class MySQLCore extends Db
{
/**
* @see DbCore::connect()
*/
public function connect()
{
if (!defined('_PS_MYSQL_REAL_ESCAPE_STRING_'))
define('_PS_MYSQL_REAL_ESCAPE_STRING_', function_exists('mysql_real_escape_string'));
if (!$this->link = @mysql_connect($this->server, $this->user, $this->password))
{
Tools14::displayError('Link to database cannot be established.');
exit();
}
if (!$this->set_db($this->database))
{
Tools14::displayError('The database selection cannot be made.');
exit();
}
// UTF-8 support
if (!mysql_query('SET NAMES \'utf8\'', $this->link))
Tools14::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.');
return $this->link;
}
/**
* @see DbCore::disconnect()
*/
public function disconnect()
{
mysql_close($this->link);
}
/**
* @see DbCore::_query()
*/
protected function _query($sql)
{
return mysql_query($sql, $this->link);
}
/**
* @see DbCore::nextRow()
*/
public function nextRow($result = false)
{
$return = false;
if(is_resource($result) && $result)
$return = mysql_fetch_assoc($result);
elseif(is_resource($this->result) && $this->result)
$return = mysql_fetch_assoc($this->result);
return $return;
}
/**
* @see DbCore::_numRows()
*/
protected function _numRows($result)
{
return mysql_num_rows($result);
}
/**
* @see DbCore::Insert_ID()
*/
public function Insert_ID()
{
return mysql_insert_id($this->link);
}
/**
* @see DbCore::Affected_Rows()
*/
public function Affected_Rows()
{
return mysql_affected_rows($this->link);
}
/**
* @see DbCore::getMsgError()
*/
public function getMsgError($query = false)
{
return mysql_error($this->link);
}
/**
* @see DbCore::getNumberError()
*/
public function getNumberError()
{
return mysql_errno($this->link);
}
/**
* @see DbCore::getVersion()
*/
public function getVersion()
{
return mysql_get_server_info($this->link);
}
/**
* @see DbCore::_escape()
*/
public function _escape($str)
{
return _PS_MYSQL_REAL_ESCAPE_STRING_ ? mysql_real_escape_string($str, $this->link) : addslashes($str);
}
/**
* @see DbCore::set_db()
*/
public function set_db($db_name)
{
return mysql_select_db($db_name, $this->link);
}
/**
* @see Db::hasTableWithSamePrefix()
*/
public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix)
{
if (!$link = @mysql_connect($server, $user, $pwd, true))
return false;
if (!@mysql_select_db($db, $link))
return false;
$sql = 'SHOW TABLES LIKE \''.$prefix.'%\'';
$result = mysql_query($sql);
return (bool)@mysql_fetch_assoc($result);
}
/**
* @see Db::checkConnection()
*/
public static function tryToConnect($server, $user, $pwd, $db, $newDbLink = true, $engine = null, $timeout = 5)
{
ini_set('mysql.connect_timeout', $timeout);
if (!$link = @mysql_connect($server, $user, $pwd, $newDbLink))
return 1;
if (!@mysql_select_db($db, $link))
return 2;
if (strtolower($engine) == 'innodb')
{
$sql = 'SHOW VARIABLES WHERE Variable_name = \'have_innodb\'';
$result = mysql_query($sql);
if (!$result)
return 4;
$row = mysql_fetch_assoc($result);
if (!$row || strtolower($row['Value']) != 'yes')
return 4;
}
@mysql_close($link);
return 0;
}
public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine)
{
ini_set('mysql.connect_timeout', 5);
if (!$link = @mysql_connect($server, $user, $pwd, true))
return false;
if (!@mysql_select_db($db, $link))
return false;
$sql = '
CREATE TABLE `'.$prefix.'test` (
`test` tinyint(1) unsigned NOT NULL
) ENGINE=MyISAM';
$result = mysql_query($sql, $link);
if (!$result)
return mysql_error($link);
mysql_query('DROP TABLE `'.$prefix.'test`', $link);
return true;
}
/**
* @see Db::checkEncoding()
*/
static public function tryUTF8($server, $user, $pwd)
{
$link = @mysql_connect($server, $user, $pwd);
if (!mysql_query('SET NAMES \'utf8\'', $link))
$ret = false;
else
$ret = true;
@mysql_close($link);
return $ret;
}
}

View File

@@ -0,0 +1,33 @@
version: '2'
services:
mysql:
image: mysql:5.7
ports:
- '3306'
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: psreference
reference-release:
container_name: prestashop_autoupgrade
image: prestashop/prestashop:${VERSION}
volumes:
- ./:/var/www/html/modules/autoupgrade
- temp-ps:/var/www/html # Used for another container which needs PrestaShop content
environment:
DB_SERVER: mysql
DB_PASSWD: root
DB_NAME: psreference
PS_DOMAIN: localhost:8001
PS_INSTALL_AUTO: 1
PS_ERASE_DB: 1
PS_FOLDER_ADMIN: admin-dev
PS_FOLDER_INSTALL: install-dev
depends_on:
- mysql
ports:
- '8001:80'
volumes:
temp-ps:

View File

@@ -0,0 +1,346 @@
<?php
/**
* 2007-2016 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* Generate a new settings file, only transmitted parameters are updated.
*
* @param string $baseUri Base URI
* @param string $theme Theme name (eg. default)
* @param array $arrayDB Parameters in order to connect to database
*/
function rewriteSettingsFile($baseUrls = null, $theme = null, $arrayDB = null)
{
$defines = array();
$defines['__PS_BASE_URI__'] = ($baseUrls && $baseUrls['__PS_BASE_URI__']) ? $baseUrls['__PS_BASE_URI__'] : __PS_BASE_URI__;
$defines['_MEDIA_SERVER_1_'] = ($baseUrls && isset($baseUrls['_MEDIA_SERVER_1_'])) ? $baseUrls['_MEDIA_SERVER_1_'] : _MEDIA_SERVER_1_;
$defines['_PS_CACHING_SYSTEM_'] = _PS_CACHING_SYSTEM_;
$defines['_PS_CACHE_ENABLED_'] = _PS_CACHE_ENABLED_;
$defines['_THEME_NAME_'] = $theme ? $theme : _THEME_NAME_;
$defines['_DB_NAME_'] = (($arrayDB && isset($arrayDB['_DB_NAME_'])) ? $arrayDB['_DB_NAME_'] : _DB_NAME_);
$defines['_MYSQL_ENGINE_'] = (($arrayDB && isset($arrayDB['_MYSQL_ENGINE_'])) ? $arrayDB['_MYSQL_ENGINE_'] : _MYSQL_ENGINE_);
$defines['_DB_SERVER_'] = (($arrayDB && isset($arrayDB['_DB_SERVER_'])) ? $arrayDB['_DB_SERVER_'] : _DB_SERVER_);
$defines['_DB_USER_'] = (($arrayDB && isset($arrayDB['_DB_USER_'])) ? $arrayDB['_DB_USER_'] : _DB_USER_);
$defines['_DB_PREFIX_'] = (($arrayDB && isset($arrayDB['_DB_PREFIX_'])) ? $arrayDB['_DB_PREFIX_'] : _DB_PREFIX_);
$defines['_DB_PASSWD_'] = (($arrayDB && isset($arrayDB['_DB_PASSWD_'])) ? $arrayDB['_DB_PASSWD_'] : _DB_PASSWD_);
$defines['_DB_TYPE_'] = (($arrayDB && isset($arrayDB['_DB_TYPE_'])) ? $arrayDB['_DB_TYPE_'] : _DB_TYPE_);
$defines['_COOKIE_KEY_'] = addslashes(_COOKIE_KEY_);
$defines['_COOKIE_IV_'] = addslashes(_COOKIE_IV_);
if (defined('_RIJNDAEL_KEY_')) {
$defines['_RIJNDAEL_KEY_'] = addslashes(_RIJNDAEL_KEY_);
}
if (defined('_RIJNDAEL_IV_')) {
$defines['_RIJNDAEL_IV_'] = addslashes(_RIJNDAEL_IV_);
}
$defines['_PS_VERSION_'] = addslashes(_PS_VERSION_);
$content = "<?php\n\n";
foreach ($defines as $k => $value) {
$content .= 'define(\'' . $k . '\', \'' . addslashes($value) . '\');' . "\n";
}
$content .= "\n?>";
if ($fd = @fopen(PS_ADMIN_DIR . '/../app/config/parameters.php', 'w')) {
fwrite($fd, $content);
fclose($fd);
return true;
}
return false;
}
/**
* Display SQL date in friendly format.
*
* @param string $sqlDate Date in SQL format (YYYY-MM-DD HH:mm:ss)
* @param bool $withTime Display both date and time
*
* @todo Several formats (french : DD-MM-YYYY)
*/
function displayDate($sqlDate, $withTime = false)
{
return strftime('%Y-%m-%d' . ($withTime ? ' %H:%M:%S' : ''), strtotime($sqlDate));
}
/**
* Return path to a product category.
*
* @param string $urlBase Start URL
* @param int $id_category Start category
* @param string $path Current path
* @param string $highlight String to highlight (in XHTML/CSS)
* @param string $type Category type (products/cms)
*/
function getPath($urlBase, $id_category, $path = '', $highlight = '', $categoryType = 'catalog')
{
global $cookie;
if ($categoryType == 'catalog') {
$category = Db::getInstance()->getRow('
SELECT id_category, level_depth, nleft, nright
FROM ' . _DB_PREFIX_ . 'category
WHERE id_category = ' . (int) $id_category);
if (isset($category['id_category'])) {
$categories = Db::getInstance()->ExecuteS('
SELECT c.id_category, cl.name, cl.link_rewrite
FROM ' . _DB_PREFIX_ . 'category c
LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = c.id_category)
WHERE c.nleft <= ' . (int) $category['nleft'] . ' AND c.nright >= ' . (int) $category['nright'] . ' AND cl.id_lang = ' . (int) ($cookie->id_lang) . '
ORDER BY c.level_depth ASC
LIMIT ' . (int) ($category['level_depth'] + 1));
$fullPath = '';
$n = 1;
$nCategories = (int) sizeof($categories);
foreach ($categories as $category) {
$edit = '<a href="' . $urlBase . '&id_category=' . (int) $category['id_category'] . '&' . ($category['id_category'] == 1 ? 'viewcategory' : 'addcategory') . '&token=' . Tools14::getAdminToken('AdminCatalog' . (int) (Tab::getIdFromClassName('AdminCatalog')) . (int) ($cookie->id_employee)) . '" title="' . ($category['id_category'] == 1 ? 'Home' : 'Modify') . '"><img src="../img/admin/' . ($category['id_category'] == 1 ? 'home' : 'edit') . '.gif" alt="" /></a> ';
$fullPath .= $edit .
($n < $nCategories ? '<a href="' . $urlBase . '&id_category=' . (int) $category['id_category'] . '&viewcategory&token=' . Tools14::getAdminToken('AdminCatalog' . (int) (Tab::getIdFromClassName('AdminCatalog')) . (int) ($cookie->id_employee)) . '" title="' . htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8') . '">' : '') .
(!empty($highlight) ? str_ireplace($highlight, '<span class="highlight">' . htmlentities($highlight, ENT_NOQUOTES, 'UTF-8') . '</span>', $category['name']) : $category['name']) .
($n < $nCategories ? '</a>' : '') .
(($n++ != $nCategories || !empty($path)) ? ' > ' : '');
}
return $fullPath . $path;
}
} elseif ($categoryType == 'cms') {
$category = new CMSCategory($id_category, (int) ($cookie->id_lang));
if (!$category->id) {
return $path;
}
$name = ($highlight != null) ? str_ireplace($highlight, '<span class="highlight">' . $highlight . '</span>', CMSCategory::hideCMSCategoryPosition($category->name)) : CMSCategory::hideCMSCategoryPosition($category->name);
$edit = '<a href="' . $urlBase . '&id_cms_category=' . $category->id . '&addcategory&token=' . Tools14::getAdminToken('AdminCMSContent' . (int) (Tab::getIdFromClassName('AdminCMSContent')) . (int) ($cookie->id_employee)) . '">
<img src="../img/admin/edit.gif" alt="Modify" /></a> ';
if ($category->id == 1) {
$edit = '<a href="' . $urlBase . '&id_cms_category=' . $category->id . '&viewcategory&token=' . Tools14::getAdminToken('AdminCMSContent' . (int) (Tab::getIdFromClassName('AdminCMSContent')) . (int) ($cookie->id_employee)) . '">
<img src="../img/admin/home.gif" alt="Home" /></a> ';
}
$path = $edit . '<a href="' . $urlBase . '&id_cms_category=' . $category->id . '&viewcategory&token=' . Tools14::getAdminToken('AdminCMSContent' . (int) (Tab::getIdFromClassName('AdminCMSContent')) . (int) ($cookie->id_employee)) . '">
' . $name . '</a> > ' . $path;
if ($category->id == 1) {
return substr($path, 0, strlen($path) - 3);
}
return getPath($urlBase, $category->id_parent, $path, '', 'cms');
}
}
function getDirContent($path)
{
$content = array();
if (is_dir($path)) {
$d = dir($path);
while (false !== ($entry = $d->read())) {
if ($entry[0] != '.') {
$content[] = $entry;
}
}
$d->close();
}
return $content;
}
function createDir($path, $rights)
{
if (file_exists($path)) {
return true;
}
return @mkdir($path, $rights);
}
function recursiveTab($id_tab)
{
global $cookie, $tabs;
$adminTab = Tab::getTab((int) $cookie->id_lang, $id_tab);
$tabs[] = $adminTab;
if ($adminTab['id_parent'] > 0) {
recursiveTab($adminTab['id_parent']);
}
}
function checkingTab($tab)
{
global $adminObj, $cookie;
$tab = trim($tab);
if (!Validate::isTabName($tab)) {
return false;
}
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql = 'SELECT id_tab, module FROM `' . _DB_PREFIX_ . 'tab` WHERE class_name = \'' . pSQL($tab) . '\'');
if (!$row['id_tab']) {
if (isset(AdminTab::$tabParenting[$tab])) {
Tools14::redirectAdmin('?tab=' . AdminTab::$tabParenting[$tab] . '&token=' . Tools14::getAdminTokenLite(AdminTab::$tabParenting[$tab]));
}
echo Tools14::displayError('Tab cannot be found.');
return false;
}
if ($row['module'] && file_exists(_PS_MODULE_DIR_ . '/' . $row['module'] . '/' . $tab . '.php')) {
include_once _PS_MODULE_DIR_ . '/' . $row['module'] . '/' . $tab . '.php';
} elseif (file_exists(PS_ADMIN_DIR . '/tabs/' . $tab . '.php')) {
include_once PS_ADMIN_DIR . '/tabs/' . $tab . '.php';
}
if (!class_exists($tab, false) || !$row['id_tab']) {
echo Tools14::displayError('Tab file cannot be found.');
return false;
}
$adminObj = new $tab();
if (!$adminObj->viewAccess()) {
$adminObj->_errors = array(Tools14::displayError('Access denied'));
echo $adminObj->displayErrors();
return false;
}
return $row['id_tab'];
}
function checkTabRights($id_tab)
{
global $cookie;
static $tabAccesses = null;
if ($tabAccesses === null) {
$tabAccesses = Profile::getProfileAccesses($cookie->profile);
}
if (isset($tabAccesses[(int) ($id_tab)]['view'])) {
return $tabAccesses[(int) ($id_tab)]['view'] === '1';
}
return false;
}
/**
* Converts a simpleXML element into an array. Preserves attributes and everything.
* You can choose to get your elements either flattened, or stored in a custom index that
* you define.
* For example, for a given element
* <field name="someName" type="someType"/>
* if you choose to flatten attributes, you would get:
* $array['field']['name'] = 'someName';
* $array['field']['type'] = 'someType';
* If you choose not to flatten, you get:
* $array['field']['@attributes']['name'] = 'someName';
* _____________________________________
* Repeating fields are stored in indexed arrays. so for a markup such as:
* <parent>
* <child>a</child>
* <child>b</child>
* <child>c</child>
* </parent>
* you array would be:
* $array['parent']['child'][0] = 'a';
* $array['parent']['child'][1] = 'b';
* ...And so on.
* _____________________________________.
*
* @param simpleXMLElement $xml the XML to convert
* @param bool $flattenValues Choose wether to flatten values
* or to set them under a particular index.
* defaults to true;
* @param bool $flattenAttributes Choose wether to flatten attributes
* or to set them under a particular index.
* Defaults to true;
* @param bool $flattenChildren Choose wether to flatten children
* or to set them under a particular index.
* Defaults to true;
* @param string $valueKey index for values, in case $flattenValues was set to
* false. Defaults to "@value"
* @param string $attributesKey index for attributes, in case $flattenAttributes was set to
* false. Defaults to "@attributes"
* @param string $childrenKey index for children, in case $flattenChildren was set to
* false. Defaults to "@children"
*
* @return array the resulting array
*/
function simpleXMLToArray($xml, $flattenValues = true, $flattenAttributes = true, $flattenChildren = true, $valueKey = '@value', $attributesKey = '@attributes', $childrenKey = '@children')
{
$return = array();
if (!($xml instanceof SimpleXMLElement)) {
return $return;
}
$name = $xml->getName();
$_value = trim((string) $xml);
if (strlen($_value) == 0) {
$_value = null;
}
if ($_value !== null) {
if (!$flattenValues) {
$return[$valueKey] = $_value;
} else {
$return = $_value;
}
}
$children = array();
$first = true;
foreach ($xml->children() as $elementName => $child) {
$value = simpleXMLToArray($child, $flattenValues, $flattenAttributes, $flattenChildren, $valueKey, $attributesKey, $childrenKey);
if (isset($children[$elementName])) {
if ($first) {
$temp = $children[$elementName];
unset($children[$elementName]);
$children[$elementName][] = $temp;
$first = false;
}
$children[$elementName][] = $value;
} else {
$children[$elementName] = $value;
}
}
if (count($children) > 0) {
if (!$flattenChildren) {
$return[$childrenKey] = $children;
} else {
$return = array_merge($return, $children);
}
}
$attributes = array();
foreach ($xml->attributes() as $name => $value) {
$attributes[$name] = trim($value);
}
if (count($attributes) > 0) {
if (!$flattenAttributes) {
$return[$attributesKey] = $attributes;
} else {
$return = array_merge($return, $attributes);
}
}
return $return;
}

Some files were not shown because too many files have changed in this diff Show More