Files
interblue.pl/modules/pshowimporter/system/emergency_update.php
2024-10-25 14:16:28 +02:00

874 lines
23 KiB
PHP

<?php
/**
* File from http://PrestaShow.pl
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade this module to newer
* versions in the future.
*
* @authors PrestaShow.pl <kontakt@prestashow.pl>
* @copyright 2015 PrestaShow.pl
* @license http://PrestaShow.pl/license
*
* Emergency update.
*
* Use when you are not able to log into the admin panel.
*/
// enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 'On');
class PShowUpdateNew
{
/**
* @deprecated since version 58
* do not use this !
*/
public static $modulename;
public static $customercode;
public static $prestaversion;
public static $tmppath;
public static $reportbugurl = 'http://modules.prestashow.pl/bug_report.php';
public static $updateurl = 'http://modules.prestashow.pl';
public static $modulepath = null;
/**
* @var array of \PShowUpdateNew
*/
private static $instance = array();
/**
* @var string
*/
private $filepath;
/**
* Get singleton instance
*
* @param string $_filepath
* @return \PShowUpdateNew
*/
public static function getInstance($_filepath)
{
$filepath = self::findRealFilePathFromBacktrace($_filepath);
$md5 = md5($filepath);
if (!array_key_exists($md5, self::$instance)) {
self::$instance[$md5] = new self($filepath);
}
return self::$instance[$md5];
}
/**
*
* @param string $filepath
* @return string
*/
public static function findRealFilePathFromBacktrace($filepath)
{
$backtrace = debug_backtrace();
foreach ($backtrace as $call) {
if (array_key_exists('file', $call) && stripos($call['file'], '/system/') === false && stripos($call['file'], '/modules/') !== false) {
return $call['file'];
}
}
// this should not happen !
return $filepath;
}
/**
* Get recommended product
*
* @return string
*/
public static function getRecommendedProduct()
{
if (!defined('PS_ADMIN_DIR')) {
return array(
'name' => 'PrestaShow.pl',
'description' => '',
'image' => '',
'url' => 'http://prestashow.pl'
);
}
// if (_PS_CACHE_ENABLED_ && Cache::getInstance()->exists('pshow_recommended')) {
// return Cache::getInstance()->get('pshow_recommended');
// }
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'timeout' => 1
)
));
$products = @unserialize(file_get_contents('http://modules.prestashow.pl/recommended_products/1', false, $context));
if (!$products) {
$products = array(array('name' => 'PrestaShow.pl', 'description' => '', 'image' => '', 'url' => 'http://prestashow.pl'));
}
// Cache::getInstance()->set('pshow_recommended', reset($products), 60);
return reset($products);
}
/**
* Constructor
*
* @param string $filepath
*/
private function __construct($filepath)
{
$this->filepath = $filepath;
}
/**
* Get module name
*
* @return string
*/
public function getModuleName()
{
$module_path = $this->getModulePath();
$module_path_arr = explode(DIRECTORY_SEPARATOR, $module_path);
return $module_path_arr[count($module_path_arr) - 2];
}
/**
* Get module path
*
* @return string
*/
public function getModulePath()
{
$filepath = $this->filepath;
if (Tools::getValue('controller') && stripos(Tools::getValue('controller'), 'PShow')) {
$controller = strtolower(Tools::getValue('controller'));
$bestpath = false;
for ($i = 0; $i <= strlen($controller); ++$i) {
$tmp = _PS_MODULE_DIR_ . substr($controller, 0, $i);
$bestpath = is_dir($tmp) ? $tmp : $bestpath;
}
return $bestpath . '/';
}
if (Tools::substr($filepath, -1, 1) == DIRECTORY_SEPARATOR) {
$filepath = Tools::substr($filepath, 0, Tools::strlen($filepath) - 1);
}
$explode = explode(DIRECTORY_SEPARATOR, dirname($filepath));
$stay = array_search('modules', $explode) + 1;
if (!array_key_exists($stay, $explode)) {
return $filepath . DIRECTORY_SEPARATOR;
}
$newpath_ = array();
for ($i = 0; $i <= $stay; ++$i) {
$newpath_[] = $explode[$i];
}
$newpath = implode(DIRECTORY_SEPARATOR, $newpath_);
return $newpath . DIRECTORY_SEPARATOR;
}
/**
* Get license key
*
* @return string
*/
public function getCustomerCode()
{
$customercode = 'no-license';
$customercode_file = $this->getModulePath($this->filepath) . "license";
// to protect license -> move code to php file
if (file_exists($customercode_file) && !file_exists($customercode_file . ".php")) {
$key = file_get_contents($customercode_file);
$key = preg_replace('/\s+/', '', $key);
file_put_contents($customercode_file . ".php", "<?php return '" . $key . "';");
}
if (file_exists($customercode_file . ".php")) {
$customercode_ = require($customercode_file . ".php");
if (is_string($customercode_)) {
$customercode = $customercode_;
}
if (file_exists($customercode_file)) {
unlink($customercode_file);
}
}
return $customercode;
}
/**
* Get module display name
*
* @return string
*/
public function getModuleDisplayName()
{
$module_file = Tools::file_get_contents($this->getModulePath() . $this->getModuleName() . '.php');
$matches = array();
preg_match_all('~class ([a-zA-Z0-9]+) extends~', $module_file, $matches);
$_matches = end($matches);
return end($_matches);
}
/**
* Get module version number
*
* @return string
*/
public function getModuleVersionNumber()
{
$path = $this->getModulePath() . $this->getModuleName() . '.php';
if (stripos($path, 'modules') === false || !file_exists($path)) {
return $path;
}
$module_file = Tools::file_get_contents($this->getModulePath() . $this->getModuleName() . '.php');
preg_match_all('~version([\s]+)\= (\'|\")([0-9]+).([0-9]+).([0-9]+)(\'|\")~', $module_file, $_matches);
preg_match_all('~([0-9]+).([0-9]+).([0-9]+)~', implode(reset($_matches)), $matches);
$_version = reset($matches);
$version = reset($_version);
$module_version_arr = explode('.', $version);
if (file_exists($this->getModulePath() . 'system/version')) {
$skeleton_version = (int) Tools::file_get_contents($this->getModulePath() . 'system/version');
} else {
$skeleton_version = 0;
}
return ((int) $module_version_arr[0]) . '.' . ((int) $module_version_arr[1]) . '.' . ((int) $skeleton_version + (int) $module_version_arr[2]);
}
/**
* Get newest module version
*
* @return string
*/
public function getNewestVersionNumber()
{
if (!defined('PS_ADMIN_DIR')) {
return 'notInAdmin';
}
$url = 'http://modules.prestashow.pl';
$url .= '/' . $this->getPrestashopVersion();
$url .= '/' . $this->getModuleName();
$url .= '/' . $this->getModuleVersionNumber();
$url .= '/' . $this->getCustomerCode();
$url .= '/' . gethostbyname(gethostname());
$url .= '/' . $_SERVER["HTTP_HOST"];
// try to get version by curl
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$newestVersionNumber = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
return $newestVersionNumber;
}
}
$headers = get_headers($url);
if (!strpos($headers[0], '200')) {
return 'Unable to check. Try again later...';
}
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'timeout' => 1
)
));
$newestVersionNumber = @file_get_contents($url, false, $context);
if (!$newestVersionNumber || $newestVersionNumber == '0.0.0') {
return 'Unable to check. Try again later...';
}
return $newestVersionNumber;
}
/**
* Get prestashop version
*
* @return string
*/
public function getPrestashopVersion()
{
return _PS_VERSION_;
}
/**
* Compare current module version with newest version
*
* @return mixed
*/
public function compareModuleAndNewestVersion()
{
return version_compare(
$this->getModuleVersionNumber(), $this->getNewestVersionNumber(), '>='
);
}
/**
* Download update package
*
* @return boolean | string
*/
public function downloadUpdate()
{
$url = 'http://modules.prestashow.pl';
$url .= '/download';
$url .= '/' . $this->getPrestashopVersion();
$url .= '/' . $this->getModuleName();
$url .= '/' . $this->getModuleVersionNumber();
$url .= '/' . $this->getCustomerCode();
$url .= '/' . gethostbyname(gethostname());
$url .= '/http://' . $_SERVER["HTTP_HOST"] . __PS_BASE_URI__;
$httpCode = false;
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
}
if ($httpCode != 200) {
$headers = get_headers($url);
if (!strpos($headers[0], '200 OK')) {
echo '<span style="display: none;">' . $url . ' | ' . var_export($headers, true) . '</span>brak połączenia z serwerem (' . $this->getCustomerCode() . ')';
return false;
}
}
$tmppath = $this->getTmpPath();
if (!is_dir($tmppath)) {
@mkdir($tmppath);
if (!is_dir($tmppath)) {
echo 'brak katalogu ' . $tmppath;
return false;
}
}
if (!is_writable($this->getTmpPath())) {
echo 'brak uprawnień, ustaw uprawnienia zapisu dla katalogu ' . $tmppath;
return false;
}
if (function_exists('curl_init')) {
set_time_limit(0);
$fp = fopen($tmppath . $this->getNewestVersionNumber() . '.zip', 'w+');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
} else {
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'timeout' => 60
)
));
$package = file_get_contents($url, false, $context);
file_put_contents($tmppath . $this->getNewestVersionNumber() . '.zip', $package);
}
return (file_exists($tmppath . $this->getNewestVersionNumber() . '.zip'));
}
/**
* Get path to the temporary fir
*
* @return string
*/
public function getTmpPath()
{
return $this->getModulePath() . 'update/tmp/';
}
/**
* Extract update package
*
* @return boolean
*/
public function extractUpdate()
{
$version = $this->getNewestVersionNumber();
if (!file_exists($this->getTmpPath() . $version . '.zip')) {
return false;
}
$zip = new ZipArchive();
$res = $zip->open($this->getTmpPath() . $version . '.zip');
if ($res === true) {
$zip->extractTo($this->getTmpPath());
$zip->close();
return true;
} else {
return false;
}
}
/**
* Recursively copy directory
*
* @param string $src
* @param string $dst
* @return boolean
*/
public function recurseCopy($src, $dst)
{
$dir = opendir($src);
@mkdir($dst);
while (false !== ( $file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' ) && ( $file != 'license' )) {
if (is_dir($src . '/' . $file)) {
$this->recurseCopy($src . '/' . $file, $dst . '/' . $file);
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
}
closedir($dir);
return true;
}
/**
* Clear temporary dir
*
* @return boolean
*/
public function clearTmpDir()
{
$this->recurseRemoveDir($this->getTmpPath());
return true;
}
/**
* Introduce new update into module
*
* @return boolean
*/
public function moveUpdateToModule()
{
$from = $this->getTmpPath() . $this->getModuleName() . "/";
$to = $this->getModulePath();
$this->recurseCopy($from, $to);
return true;
}
/**
* Recursively remove dir
*
* @param string $_path
* @param boolean $removePath
* @return boolean
*/
public function recurseRemoveDir($_path, $removePath = false)
{
if (!is_dir($_path)) {
return false;
}
$path = str_replace('//', '/', $_path);
if (Tools::substr($path, -1, 1) == DIRECTORY_SEPARATOR) {
$path = Tools::substr($path, 0, Tools::strlen($path) - 1);
}
$files = glob($path . '/*');
foreach ($files as $file) {
if (is_dir($file)) {
$this->recurseRemoveDir($file, true);
continue;
}
unlink($file);
}
if ($removePath === true) {
@rmdir($path);
}
}
/**
* Create module backup package
*
* @return boolean|string
*/
public function makeModuleBackup()
{
$path = $this->getModulePath() . "update/backups/";
$destPath = $path . $this->getModuleName() . "_" . $this->getModuleVersionNumber() . "_" . date('H.i_d.m.Y') . ".zip";
$zip = new ZipArchive();
if (!is_dir($path)) {
@mkdir($path);
if (!is_dir($path)) {
return 'brak katalogu ' . $path;
}
}
if (!$zip->open($destPath, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
return false;
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($this->getModulePath()), RecursiveIteratorIterator::LEAVES_ONLY
);
try {
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = Tools::substr($filePath, Tools::strlen($this->getModulePath()));
if (preg_match('~update~', $filePath)) {
continue;
}
if (preg_match('~.git~', $filePath)) {
continue;
}
if (preg_match('~license~', $filePath)) {
continue;
}
if (preg_match('~' . $this->getModuleName() . '_~', $filePath)) {
continue;
}
$zip->addFile($filePath, $relativePath);
}
}
} catch (UnexpectedValueException $e) {
}
$zip->close();
return (file_exists($destPath));
}
/**
* Move backup package to temporary dir
*
* @param string $file
* @return boolean
*/
public function moveBackupToTmp($file)
{
if (!file_exists($this->getModulePath() . "update/backups/" . $file)) {
return false;
}
copy($this->getModulePath() . "update/backups/" . $file, $this->getTmpPath() . $file);
if (!file_exists($this->getTmpPath() . $file)) {
return false;
}
return true;
}
/**
* Extract backup package
*
* @param string $file
* @return boolean
*/
public function extractBackup($file)
{
if (!file_exists($this->getTmpPath() . $file)) {
return false;
}
$zip = new ZipArchive();
$res = $zip->open($this->getTmpPath() . $file);
if (!file_exists($this->getTmpPath() . 'backup/')) {
mkdir($this->getTmpPath() . 'backup/', 0777);
}
if ($res === TRUE) {
$zip->extractTo($this->getTmpPath() . 'backup/');
$zip->close();
return true;
} else {
return false;
}
}
/**
* Introduce backup to the module
*
* @return boolean
*/
public function moveBackupToModule()
{
$from = $this->getTmpPath() . 'backup/';
$to = $this->getModulePath();
$this->recurseCopy($from, $to);
return true;
}
/**
* Execute updates
*
* @param string $from_ver
* @return boolean
*/
public function execUpdate($from_ver)
{
$ver_expl = explode('.', $from_ver);
$from_ver = $ver_expl[0] . '.' . $ver_expl[1];
$modulename = $this->getModuleName();
require_once $this->getModulePath() . $modulename . '.php';
$instance = new $modulename();
if (!isset($instance->moduleVersionPath)) {
$instance->moduleVersionPath = array();
}
foreach ($instance->moduleVersionPath as $ver) {
$funcName = str_replace('.', '_', $from_ver);
if (version_compare($instance->version, $from_ver . '.0') == 1 && method_exists($instance, $funcName)) {
$instance->funcName();
}
}
//if (method_exists($instance, 'reinstallControllers')) $instance->reinstallControllers();
return false;
}
/**
* Format version to display
*
* @param string $version
* @return string
*/
public function formatVersionToDisplay($version)
{
return preg_replace('/([0-9]+).([0-9]+).([0-9]+)/i', '$1.$2-$3', $version);
}
}
?>
<hr>
<p><strong>This script will update your module.</strong> <small>Use this only for emergency updates.</small></p>
<hr>
<?php
if (file_exists('./emergency_self_update.php')):
?>
<small>You can update this script using this: <a href="<?php echo str_replace('_update', '_self_update', $_SERVER['PHP_SELF']); ?>">click to self update</a></small>
<hr>
<?php
endif;
?>
<form method="post" action="">
<p>
<label for="path">Enter absolute path to anyone file in the module which you want to update:</label><br>
<input type="text" name="path" id="path" value="<?php echo __FILE__; ?>" size="100">
</p>
<p>
<label for="email">Enter employee email:</label><br>
<input type="email" name="email" id="email" size="100">
</p>
<p>
<label for="password">Enter employee password:</label><br>
<input type="password" name="password" id="password" size="100">
</p>
<p>
<input type="submit" value="START UPDATE">
</p>
</form>
<?php
session_start();
define('WAITING_TIME', 15 * 60);
define('MAX_TRIES', 10);
if (isset($_SESSION['loginTries']) && $_SESSION['loginTries'] > MAX_TRIES) {
if ($_SESSION['loginLastTryTime'] > (time() - WAITING_TIME)) {
die('<u>You have reached the limit login attempts. Wait 15 minutes and try again...</u>');
} else {
$_SESSION['loginTries'] = 0;
}
}
require_once "../../../config/config.inc.php";
if (!Tools::getValue('password') || !Tools::getValue('password')) {
die();
}
// enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 'On');
/**
* If employee not exists
*/
function employeeNotFound()
{
if (!isset($_SESSION['loginTries'])) {
$_SESSION['loginTries'] = 0;
}
++$_SESSION['loginTries'];
$_SESSION['loginLastTryTime'] = time();
die('<u>Employee not found or wrong password!</u>');
}
// get email
$email = pSQL(Tools::getValue('email'));
// check password
if (version_compare(_PS_VERSION_, '1.7') >= 0) {
$sql = new DbQuery();
$sql->select('e.*');
$sql->from('employee', 'e');
$sql->where('e.`email` = \'' . pSQL($email) . '\'');
$sql->where('e.`active` = 1');
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
if (!$result) {
die('<u>Employee not found!</u>');
}
$crypto = \PrestaShop\PrestaShop\Adapter\ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\Crypto\\Hashing');
if (!$crypto->checkHash(Tools::getValue('password'), $result['passwd'])) {
employeeNotFound();
}
} else {
$password = Tools::encrypt(Tools::getValue('password'));
$q = "SELECT COUNT(*) "
. "FROM " . _DB_PREFIX_ . "employee "
. "WHERE `email` = '" . $email . "' AND `passwd` = '" . $password . "'; ";
$foundEmployee = Db::getInstance()->getValue($q);
if (!$foundEmployee) {
employeeNotFound();
}
}
$path = Tools::getValue('path');
if (empty($path)) {
die('<u>Module not found in path: ' . $path . '</u>');
}
$moduleName = PShowUpdateNew::getInstance($path)->getModuleName();
echo '<p>Updating module `' . $moduleName . '`...</p>';
$from_ver = PShowUpdateNew::getInstance($path)->getModuleVersionNumber();
if (!PShowUpdateNew::getInstance($path)->makeModuleBackup()) {
echo '<p>Module backup error!</p>';
} else {
echo '<p>Module backup completed</p>';
}
PShowUpdateNew::getInstance($path)->clearTmpDir();
if (!PShowUpdateNew::getInstance($path)->downloadUpdate()) {
echo '<p>Download error!</p>';
die();
} else {
echo '<p>Update downloaded</p>';
}
if (!PShowUpdateNew::getInstance($path)->extractUpdate()) {
echo '<p>Update package extract error!</p>';
die();
} else {
echo '<p>Update package extracted</p>';
}
if (!PShowUpdateNew::getInstance($path)->moveUpdateToModule()) {
echo '<p>Module update error!';
die();
} else {
echo '<p>Module updated</p>';
}
if (PShowUpdateNew::getInstance($path)->execUpdate($from_ver)) {
echo '<p>Module update script executed</p>';
}
PShowUpdateNew::getInstance($path)->clearTmpDir();
echo '<p>Cleaned after update</p>';
echo '<p style="color: green;font-weight: bold;">All done!</p>';