Inital commit

This commit is contained in:
2020-11-19 15:36:28 +01:00
parent 71f32f83d3
commit 66ce4ee218
18077 changed files with 2166122 additions and 35184 deletions

View File

@@ -11,12 +11,13 @@
/*************************************************************************************/
namespace Thelia\Install;
use Thelia\Install\Exception\AlreadyInstallException;
/**
* Class BaseInstall
*
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
abstract class BaseInstall
{
@@ -32,7 +33,6 @@ abstract class BaseInstall
*/
public function __construct($verifyInstall = true)
{
// Check if install wizard is launched via CLI
if (php_sapi_name() == 'cli') {
$this->isConsoleMode = true;

View File

@@ -22,7 +22,7 @@ use Thelia\Core\Translation\Translator;
* Take care of integration tests (database connection)
*
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
class CheckDatabaseConnection extends BaseInstall
@@ -80,7 +80,6 @@ class CheckDatabaseConnection extends BaseInstall
*/
public function exec()
{
$dsn = "mysql:host=%s;port=%s";
try {
@@ -90,7 +89,6 @@ class CheckDatabaseConnection extends BaseInstall
$this->password
);
} catch (\PDOException $e) {
$this->validationMessages = 'Wrong connection information';
$this->isValid = false;
@@ -103,5 +101,4 @@ class CheckDatabaseConnection extends BaseInstall
{
return $this->connection;
}
}

View File

@@ -13,7 +13,7 @@
namespace Thelia\Install;
use Symfony\Component\Translation\TranslatorInterface;
use Thelia\Core\Translation\Translator;
use Symfony\Component\Translation\Translator;
/**
* Class CheckPermission
@@ -21,17 +21,17 @@ use Thelia\Core\Translation\Translator;
* Take care of integration tests (files permissions)
*
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
class CheckPermission extends BaseInstall
{
const DIR_CONF = 'local/config';
const DIR_LOG = 'log';
const DIR_CACHE = 'cache';
const DIR_WEB = 'web';
const DIR_SESSION = 'local/session';
const DIR_MEDIA = 'local/media';
/** @var array Directory needed to be writable */
protected $directoriesToBeWritable = array(
@@ -40,6 +40,7 @@ class CheckPermission extends BaseInstall
self::DIR_CACHE,
self::DIR_WEB,
self::DIR_SESSION,
self::DIR_MEDIA
);
/** @var array Minimum server configuration necessary */
@@ -54,8 +55,10 @@ class CheckPermission extends BaseInstall
'fileinfo',
'gd',
'intl',
'mcrypt',
'openssl',
'pdo_mysql',
'dom',
'calendar'
);
protected $validationMessages = array();
@@ -117,7 +120,9 @@ class CheckPermission extends BaseInstall
public function exec()
{
if (version_compare(phpversion(), '5.4', '<')) {
$this->validationMessages['php_version'] = $this->getI18nPhpVersionText('5.4', phpversion(), false);
$this->validationMessages['php_version']['text'] = $this->getI18nPhpVersionText('5.4', phpversion(), false);
$this->validationMessages['php_version']['status'] = false;
$this->validationMessages['php_version']['hint'] = $this->getI18nPhpVersionHint();
}
foreach ($this->directoriesToBeWritable as $directory) {
@@ -128,7 +133,6 @@ class CheckPermission extends BaseInstall
$this->isValid = false;
$this->validationMessages[$directory]['status'] = false;
$this->validationMessages[$directory]['text'] = $this->getI18nDirectoryText($fullDirectory, false);
$this->validationMessages[$directory]['hint'] = $this->getI18nDirectoryHint($fullDirectory);
}
}
}
@@ -138,7 +142,8 @@ class CheckPermission extends BaseInstall
if (!$this->verifyServerMemoryValues($key, $value)) {
$this->isValid = false;
$this->validationMessages[$key]['status'] = false;
$this->validationMessages[$key]['text'] = $this->getI18nConfigText($key, $this->formatBytes($value), ini_get($key), false);;
$this->validationMessages[$key]['text'] = $this->getI18nConfigText($key, $this->formatBytes($value), ini_get($key), false);
;
}
}
@@ -188,9 +193,9 @@ class CheckPermission extends BaseInstall
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your directory %directory% is writable';
$sentence = 'The directory %directory% is writable';
} else {
$sentence = 'Your directory %directory% is not writable';
$sentence = 'The directory %directory% is not writable';
}
$translatedText = $this->translator->trans(
@@ -200,7 +205,7 @@ class CheckPermission extends BaseInstall
)
);
} else {
$translatedText = sprintf('Your directory %s needs to be writable', $directory);
$translatedText = sprintf('The directory %s should be writable', $directory);
}
return $translatedText;
@@ -209,9 +214,9 @@ class CheckPermission extends BaseInstall
protected function getI18nExtensionText($extension, $isValid)
{
if ($isValid) {
$sentence = '%extension% php extension is loaded';
$sentence = '%extension% php extension is loaded.';
} else {
$sentence = '%extension% php extension is not loaded';
$sentence = '%extension% php extension is not loaded.';
}
return $this->translator->trans($sentence, array(
@@ -219,31 +224,6 @@ class CheckPermission extends BaseInstall
));
}
/**
* Get Translated hint about the directory state
*
* @param string $directory Directory being checked
*
* @return string
*/
protected function getI18nDirectoryHint($directory)
{
if ($this->translator !== null) {
$sentence = 'chmod 777 %directory% on your server with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(
'%directory%' => $directory
),
'install-wizard'
);
} else {
$translatedText = sprintf('chmod 777 %s on your server with admin rights could help', $directory);
}
return $translatedText;
}
/**
* Get Translated text about the directory state
* Not usable with CLI
@@ -258,9 +238,9 @@ class CheckPermission extends BaseInstall
protected function getI18nConfigText($key, $expectedValue, $currentValue, $isValid)
{
if ($isValid) {
$sentence = 'Your %key% server configuration (currently %currentValue%) is well enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'The PHP "%key%" configuration value (currently %currentValue%) is correct (%expectedValue% required).';
} else {
$sentence = 'Your %key% server configuration (currently %currentValue%) is not sufficient enough in order to run Thelia2 (%expectedValue% needed)';
$sentence = 'The PHP "%key%" configuration value (currently %currentValue%) is below minimal requirements to run Thelia2 (%expectedValue% required).';
}
$translatedText = $this->translator->trans(
@@ -278,7 +258,7 @@ class CheckPermission extends BaseInstall
protected function getI18nExtensionHint()
{
return $this->translator->trans('This extension must be installed and loaded');
return $this->translator->trans('This PHP extension should be installed and loaded.');
}
/**
@@ -288,7 +268,7 @@ class CheckPermission extends BaseInstall
*/
protected function getI18nConfigHint()
{
$sentence = 'Modifying this value on your server php.ini file with admin rights could help';
$sentence = 'Change this value in the php.ini configuration file.';
$translatedText = $this->translator->trans(
$sentence
);
@@ -309,9 +289,9 @@ class CheckPermission extends BaseInstall
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your PHP version %currentValue% is well enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'PHP version %currentValue% matches the minimum required (PHP %expectedValue%).';
} else {
$sentence = 'Your PHP version %currentValue% is not sufficient enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'The installer detected PHP version %currentValue%, but Thelia 2 requires PHP %expectedValue% or newer.';
}
$translatedText = $this->translator->trans(
@@ -322,7 +302,7 @@ class CheckPermission extends BaseInstall
)
);
} else {
$translatedText = sprintf('Thelia needs at least PHP %s (%s currently)', $expectedValue, $currentValue);
$translatedText = sprintf('Thelia requires PHP %s or newer (%s currently).', $expectedValue, $currentValue);
}
return $translatedText;
@@ -335,7 +315,7 @@ class CheckPermission extends BaseInstall
*/
protected function getI18nPhpVersionHint()
{
$sentence = 'Upgrading your version of PHP with admin rights could help';
$sentence = 'You should upgrade the installed PHP version to continue Thelia 2 installation.';
$translatedText = $this->translator->trans(
$sentence,
array()
@@ -378,11 +358,13 @@ class CheckPermission extends BaseInstall
switch ($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
$val = (int)$val*1024;
// no break
case 'm':
$val *= 1024;
$val = (int)$val*1024;
// no break
case 'k':
$val *= 1024;
$val = (int)$val*1024;
}
return $val;

View File

@@ -12,15 +12,17 @@
namespace Thelia\Install;
use PDO;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Connection\ConnectionWrapper;
use Propel\Runtime\Propel;
use Propel\Runtime\ServiceContainer\ServiceContainerInterface;
use Thelia\Log\Tlog;
/**
* Class Database
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
class Database
{
@@ -49,7 +51,7 @@ class Database
}
if (!$connection instanceof \PDO) {
throw new \InvalidArgumentException("A PDO connection shoud be provided");
throw new \InvalidArgumentException("A PDO connection should be provided");
}
$this->connection = $connection;
@@ -73,8 +75,8 @@ class Database
if (null === $extraSqlFiles) {
$sql = array_merge(
$sql,
$this->prepareSql(file_get_contents(THELIA_ROOT . '/setup/thelia.sql')),
$this->prepareSql(file_get_contents(THELIA_ROOT . '/setup/insert.sql'))
$this->prepareSql(file_get_contents(THELIA_SETUP_DIRECTORY . 'thelia.sql')),
$this->prepareSql(file_get_contents(THELIA_SETUP_DIRECTORY . 'insert.sql'))
);
} else {
foreach ($extraSqlFiles as $fileToInsert) {
@@ -98,6 +100,7 @@ class Database
* @param string $sql SQL query
* @param array $args SQL request parameters (PDO style)
* @throws \RuntimeException|\PDOException if something goes wrong.
* @return \PDOStatement
*/
public function execute($sql, $args = array())
{
@@ -110,8 +113,10 @@ class Database
$success = $stmt->execute($args);
if ($success === false || $stmt->errorCode() != 0) {
throw new \RuntimeException("Failed to execute SQL '$sql', arguments:" . print_r($args,1).", error:".print_r($stmt->errorInfo(), 1));
throw new \RuntimeException("Failed to execute SQL '$sql', arguments:" . print_r($args, 1).", error:".print_r($stmt->errorInfo(), 1));
}
return $stmt;
}
/**
@@ -137,6 +142,110 @@ class Database
return $query;
}
/**
* Backup the db OR just a table
*
* @param string $filename
* @param string $tables
*/
public function backupDb($filename, $tables = '*')
{
$data = [];
// get all of the tables
if ($tables == '*') {
$tables = array();
$result = $this->connection->prepare('SHOW TABLES');
$result->execute();
while ($row = $result->fetch(PDO::FETCH_NUM)) {
$tables[] = $row[0];
}
} else {
$tables = is_array($tables) ? $tables : explode(',', $tables);
}
$data[] = "\n";
$data[] = 'SET foreign_key_checks=0;';
$data[] = "\n\n";
foreach ($tables as $table) {
if (!preg_match("/^[\w_\-]+$/", $table)) {
Tlog::getInstance()->alert(
sprintf(
"Attempt to backup the db with this invalid table name: '%s'",
$table
)
);
continue;
}
$result = $this->execute('SELECT * FROM `' . $table . '`');
$fieldCount = $result->columnCount();
$data[] = 'DROP TABLE `' . $table . '`;';
$resultStruct = $this->execute('SHOW CREATE TABLE `' . $table . '`');
$rowStruct = $resultStruct->fetch(PDO::FETCH_NUM);
$data[] = "\n\n";
$data[] = $rowStruct[1];
$data[] = ";\n\n";
for ($i = 0; $i < $fieldCount; $i++) {
while ($row = $result->fetch(PDO::FETCH_NUM)) {
$data[] = 'INSERT INTO `' . $table . '` VALUES(';
for ($j = 0; $j < $fieldCount; $j++) {
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("\n", "\\n", $row[$j]);
if (isset($row[$j])) {
$data[] = '"' . $row[$j] . '"';
} else {
$data[] = '""';
}
if ($j < ($fieldCount - 1)) {
$data[] = ',';
}
}
$data[] = ");\n";
}
}
$data[] = "\n\n\n";
}
$data[] = 'SET foreign_key_checks=1;';
//save filename
$this->writeFilename($filename, $data);
}
/**
* Restore a file in the current db
*
* @param string $filename the file containing sql queries
*/
public function restoreDb($filename)
{
$this->insertSql(null, [$filename]);
}
/**
* Save an array of data to a filename
*
* @param string $filename
* @param array $data
*/
private function writeFilename($filename, $data)
{
$f = fopen($filename, "w+");
fwrite($f, implode('', $data));
fclose($f);
}
/**
* create database if not exists
*
@@ -151,4 +260,12 @@ class Database
)
);
}
/**
* @return PDO
*/
public function getConnection()
{
return $this->connection;
}
}

View File

@@ -15,9 +15,8 @@ namespace Thelia\Install\Exception;
/**
* Class AlreadyInstallException
* @package Thelia\Install\Exception
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
class AlreadyInstallException extends InstallException
{
}

View File

@@ -14,9 +14,8 @@ namespace Thelia\Install\Exception;
/**
* Class InstallException
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
class InstallException extends \RuntimeException
{
}

View File

@@ -15,9 +15,8 @@ namespace Thelia\Install\Exception;
/**
* Class UpToDateException
* @package Thelia\Install\Exception
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
class UpToDateException extends InstallException
{
}

View File

@@ -0,0 +1,41 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Install\Exception;
/**
* Class UpdateException
* @package Thelia\Install\Exception
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
*/
class UpdateException extends \RuntimeException
{
/** @var string the version that has failed */
protected $version = null;
/**
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* @param string $version
*/
public function setVersion($version)
{
$this->version = $version;
}
}

View File

@@ -11,88 +11,598 @@
/*************************************************************************************/
namespace Thelia\Install;
use Propel\Runtime\Exception\PropelException;
use Propel\Runtime\Propel;
use Michelf\Markdown;
use PDO;
use PDOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
use Thelia\Config\DatabaseConfiguration;
use Thelia\Config\DefinePropel;
use Thelia\Install\Exception\UpdateException;
use Thelia\Install\Exception\UpToDateException;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Map\ProductTableMap;
use Thelia\Tools\Version\Version;
/**
* Class Update
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <manu@raynaud.io>
*/
class Update
{
protected static $version = array(
'0' => '2.0.0-beta1',
'1' => '2.0.0-beta2',
'2' => '2.0.0-beta3',
'3' => '2.0.0-beta4',
'4' => '2.0.0-RC1',
'5' => '2.0.0',
'6' => '2.0.1',
'7' => '2.0.2',
'8' => '2.0.3-beta',
'9' => '2.0.3-beta2',
const SQL_DIR = 'update/sql/';
);
const PHP_DIR = 'update/php/';
protected function isLatestVersion($version)
const INSTRUCTION_DIR = 'update/instruction/';
protected $version = null;
/** @var bool */
protected $usePropel = null;
/** @var null|Tlog */
protected $logger = null;
/** @var array log messages */
protected $logs = [];
/** @var array post instructions */
protected $postInstructions = [];
/** @var array */
protected $updatedVersions = [];
/** @var PDO */
protected $connection = null;
/** @var string|null */
protected $backupFile = null;
/** @var string */
protected $backupDir = 'local/backup/';
/** @var array */
protected $messages = [];
/** @var Translator */
protected $translator;
public function __construct($usePropel = true)
{
$lastEntry = end(self::$version);
$this->usePropel = $usePropel;
if ($this->usePropel) {
$this->logger = Tlog::getInstance();
$this->logger->setLevel(Tlog::DEBUG);
} else {
$this->logs = [];
}
$dbConfig = null;
try {
$dbConfig = $this->getDatabaseConfig();
} catch (ParseException $ex) {
throw new UpdateException("database.yml is not a valid file : " . $ex->getMessage());
}
try {
$this->connection = new \PDO(
$dbConfig['dsn'],
$dbConfig['user'],
$dbConfig['password'],
[PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"]
);
} catch (\PDOException $ex) {
throw new UpdateException('Wrong connection information' . $ex->getMessage());
}
$this->version = $this->getVersionList();
}
/**
* retrieve the database configuration
*
* @return array containing the database
*/
protected function getDatabaseConfig()
{
$configPath = THELIA_CONF_DIR . "database.yml";
if (!file_exists($configPath)) {
throw new UpdateException("Thelia is not installed yet");
}
$definePropel = new DefinePropel(
new DatabaseConfiguration(),
Yaml::parse(file_get_contents($configPath)),
$this->getEnvParameters()
);
return $definePropel->getConfig();
}
/**
* Gets the environment parameters.
*
* Only the parameters starting with "SYMFONY__" are considered.
*
* @return array An array of parameters
*/
protected function getEnvParameters()
{
$parameters = array();
foreach ($_SERVER as $key => $value) {
if (0 === strpos($key, 'SYMFONY__')) {
$parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
}
}
return $parameters;
}
public function isLatestVersion($version = null)
{
if (null === $version) {
$version = $this->getCurrentVersion();
}
$lastEntry = end($this->version);
return $lastEntry == $version;
}
public function process()
{
$this->updatedVersions = array();
$logger = Tlog::getInstance();
$logger->setLevel(Tlog::DEBUG);
$currentVersion = $this->getCurrentVersion();
$this->log('debug', "start update process");
$updatedVersions = array();
$currentVersion = ConfigQuery::read('thelia_version');
$logger->debug("start update process");
if (true === $this->isLatestVersion($currentVersion)) {
$logger->debug("You already have the latest version. No update available");
$this->log('debug', "You already have the latest version. No update available");
throw new UpToDateException('You already have the latest version. No update available');
}
$index = array_search($currentVersion, self::$version);
$con = Propel::getServiceContainer()->getWriteConnection(ProductTableMap::DATABASE_NAME);
$con->beginTransaction();
$logger->debug("begin transaction");
$database = new Database($con->getWrappedConnection());
$index = array_search($currentVersion, $this->version);
$this->connection->beginTransaction();
$database = new Database($this->connection);
$version = null;
try {
$size = count(self::$version);
$size = count($this->version);
for ($i = ++$index; $i < $size; $i++) {
$this->updateToVersion(self::$version[$i], $database, $logger);
$updatedVersions[] = self::$version[$i];
$version = $this->version[$i];
$this->updateToVersion($version, $database);
$this->updatedVersions[] = $version;
}
$con->commit();
$logger->debug('update successfully');
} catch (PropelException $e) {
$con->rollBack();
$logger->error(sprintf('error during update process with message : %s', $e->getMessage()));
throw $e;
$currentVersion = Version::parse();
$this->log('debug', sprintf('setting database configuration to %s', $currentVersion['version']));
$updateConfigVersion = [
'thelia_version' => $currentVersion['version'],
'thelia_major_version' => $currentVersion['major'],
'thelia_minus_version' => $currentVersion['minus'],
'thelia_release_version' => $currentVersion['release'],
'thelia_extra_version' => $currentVersion['extra'],
];
foreach ($updateConfigVersion as $name => $value) {
$stmt = $this->connection->prepare('SELECT * FROM `config` WHERE `name` = ?');
$stmt->execute([$name]);
if ($stmt->rowCount()) {
$stmt = $this->connection->prepare('UPDATE `config` SET `value` = ? WHERE `name` = ?');
$stmt->execute([$version, $value]);
} else {
$stmt = $this->connection->prepare('INSERT INTO `config` (?) VALUES (?)');
$stmt->execute([$version, $value]);
}
}
$this->connection->commit();
$this->log('debug', 'update successfully');
} catch (\Exception $e) {
$this->connection->rollBack();
$this->log('error', sprintf('error during update process with message : %s', $e->getMessage()));
$ex = new UpdateException($e->getMessage(), $e->getCode(), $e->getPrevious());
$ex->setVersion($version);
throw $ex;
}
$this->log('debug', 'end of update processing');
$logger->debug('end of update processing');
return $updatedVersions;
return $this->updatedVersions;
}
protected function updateToVersion($version, Database $database,Tlog $logger)
/**
* Backup current DB to file local/backup/update.sql
* @return bool if it succeeds, false otherwise
* @throws \Exception
*/
public function backupDb()
{
if (file_exists(THELIA_ROOT . '/setup/update/'.$version.'.sql')) {
$logger->debug(sprintf('inserting file %s', $version.'$sql'));
$database->insertSql(null, array(THELIA_ROOT . '/setup/update/'.$version.'.sql'));
$logger->debug(sprintf('end inserting file %s', $version.'$sql'));
$database = new Database($this->connection);
if (! $this->checkBackupIsPossible()) {
$message = 'Your database is too big for an automatic backup';
$this->log('error', $message);
throw new UpdateException($message);
}
ConfigQuery::write('thelia_version', $version);
$this->backupFile = THELIA_ROOT . $this->backupDir . 'update.sql';
$backupDir = THELIA_ROOT . $this->backupDir;
$fs = new Filesystem();
try {
$this->log('debug', sprintf('Backup database to file : %s', $this->backupFile));
// test if backup dir exists
if (!$fs->exists($backupDir)) {
$fs->mkdir($backupDir);
}
if (!is_writable($backupDir)) {
throw new \RuntimeException(sprintf('impossible to write in directory : %s', $backupDir));
}
// test if backup file already exists
if ($fs->exists($this->backupFile)) {
// remove file
$fs->remove($this->backupFile);
}
$database->backupDb($this->backupFile);
} catch (\Exception $ex) {
$this->log('error', sprintf('error during backup process with message : %s', $ex->getMessage()));
throw $ex;
}
}
/**
* Restores file local/backup/update.sql to current DB
*
* @return bool if it succeeds, false otherwise
*/
public function restoreDb()
{
$database = new Database($this->connection);
try {
$this->log('debug', sprintf('Restore database with file : %s', $this->backupFile));
if (!file_exists($this->backupFile)) {
return false;
}
$database->restoreDb($this->backupFile);
} catch (\Exception $ex) {
$this->log('error', sprintf('error during restore process with message : %s', $ex->getMessage()));
print $ex->getMessage();
return false;
}
return true;
}
/**
* @return null|string
*/
public function getBackupFile()
{
return $this->backupFile;
}
public function getLogs()
{
return $this->logs;
}
protected function log($level, $message)
{
if ($this->usePropel) {
switch ($level) {
case 'debug':
$this->logger->debug($message);
break;
case 'info':
$this->logger->info($message);
break;
case 'notice':
$this->logger->notice($message);
break;
case 'warning':
$this->logger->warning($message);
break;
case 'error':
$this->logger->error($message);
break;
case 'critical':
$this->logger->critical($message);
break;
}
} else {
$this->logs[] = [$level, $message];
}
}
protected function updateToVersion($version, Database $database)
{
// sql update
$filename = sprintf(
"%s%s%s",
THELIA_SETUP_DIRECTORY,
str_replace('/', DS, self::SQL_DIR),
$version . '.sql'
);
if (file_exists($filename)) {
$this->log('debug', sprintf('inserting file %s', $version . '.sql'));
$database->insertSql(null, [$filename]);
$this->log('debug', sprintf('end inserting file %s', $version . '.sql'));
}
// php update
$filename = sprintf(
"%s%s%s",
THELIA_SETUP_DIRECTORY,
str_replace('/', DS, self::PHP_DIR),
$version . '.php'
);
if (file_exists($filename)) {
$this->log('debug', sprintf('executing file %s', $version . '.php'));
include_once($filename);
$this->log('debug', sprintf('end executing file %s', $version . '.php'));
}
// instructions
$filename = sprintf(
"%s%s%s",
THELIA_SETUP_DIRECTORY,
str_replace('/', DS, self::INSTRUCTION_DIR),
$version . '.md'
);
if (file_exists($filename)) {
$this->addPostInstructions($version, file_get_contents($filename));
}
$this->setCurrentVersion($version);
}
public function getCurrentVersion()
{
$stmt = $this->connection->query("SELECT `value` FROM `config` WHERE name='thelia_version'");
return $stmt->fetchColumn();
}
public function setCurrentVersion($version)
{
$currentVersion = null;
if (null !== $this->connection) {
try {
$stmt = $this->connection->prepare('UPDATE config set value = ? where name = ?');
$stmt->execute([$version, 'thelia_version']);
} catch (PDOException $e) {
$this->log('error', sprintf('Error setting current version : %s', $e->getMessage()));
throw $e;
}
}
}
/**
* Returns the database size in Mo
* @return float
* @throws \Exception
*/
public function getDataBaseSize()
{
$stmt = $this->connection->query(
"SELECT sum(data_length) / 1024 / 1024 'size' FROM information_schema.TABLES WHERE table_schema = DATABASE() GROUP BY table_schema"
);
if ($stmt->rowCount()) {
return floatval($stmt->fetch(PDO::FETCH_OBJ)->size);
}
throw new \Exception('Impossible to calculate the database size');
}
/**
* Checks whether it is possible to make a data base backup
*
* @return bool
*/
public function checkBackupIsPossible()
{
$size = 0;
if (preg_match('/^(\d+)(.)$/', ini_get('memory_limit'), $matches)) {
switch (strtolower($matches[2])) {
case 'k':
$size = $matches[1] / 1024;
break;
case 'm':
$size = $matches[1];
break;
case 'g':
$size = $matches[1] * 1024;
break;
}
}
if ($this->getDataBaseSize() > ($size - 64) / 8) {
return false;
}
return true;
}
public function getLatestVersion()
{
return end($this->version);
}
public function getVersions()
{
return $this->version;
}
/**
* @return array
*/
public function getUpdatedVersions()
{
return $this->updatedVersions;
}
/**
* @param array $updatedVersions
*/
public function setUpdatedVersions($updatedVersions)
{
$this->updatedVersions = $updatedVersions;
}
/**
* Add a new post update instruction
*
* @param string $instructions content of the instruction un markdown format
*/
protected function addPostInstructions($version, $instructions)
{
if (!isset($this->postInstructions[$version])) {
$this->postInstructions[$version] = [];
}
$this->postInstructions[$version][] = $instructions;
}
/**
* Return the content of all instructions
*
* @param string $format the format of the export : plain (default) or html
* @return string the instructions in plain text or html
*/
public function getPostInstructions($format = 'plain')
{
$content = [];
if (count($this->postInstructions) == 0) {
return null;
}
ksort($this->postInstructions);
foreach ($this->postInstructions as $version => $instructions) {
$content[] = sprintf("## %s", $version);
foreach ($instructions as $instruction) {
$content[] = sprintf("%s", $instruction);
}
}
$content = implode("\n\n", $content);
if ($format === 'html') {
$content = Markdown::defaultTransform($content);
}
return $content;
}
public function hasPostInstructions()
{
return (count($this->postInstructions) !== 0);
}
public function getVersionList()
{
$list = [];
$finder = new Finder();
$path = sprintf("%s%s", THELIA_SETUP_DIRECTORY, str_replace('/', DS, self::SQL_DIR));
$sort = function (\SplFileInfo $a, \SplFileInfo $b) {
$a = strtolower(substr($a->getRelativePathname(), 0, -4));
$b = strtolower(substr($b->getRelativePathname(), 0, -4));
return version_compare($a, $b);
};
$files = $finder->name('*.sql')->in($path)->sort($sort);
foreach ($files as $file) {
$list[] = substr($file->getRelativePathname(), 0, -4);
}
return $list;
}
/**
* @param string $message
* @param string $type
* @return $this
*/
public function setMessage($message, $type = 'info')
{
$this->messages[] = [$message, $type];
return $this;
}
/**
* @return array
*/
public function getMessages()
{
return $this->messages;
}
/**
* @param string $string
* @return string
*/
public function trans($string)
{
return $this->translator ? $this->translator->trans($string) : $string;
}
/**
* @param Translator $translator
* @return $this
*/
public function setTranslator(Translator $translator)
{
$this->translator = $translator;
return $this;
}
public function getWebVersion()
{
$url = "http://thelia.net/version.php";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 5);
$res = curl_exec($curl);
try {
if (Version::parse($res)) {
return trim($res);
}
} catch (\Exception $e) {
return null;
}
}
}