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

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'));
}
}
}