Files
2024-10-25 14:16:28 +02:00

677 lines
18 KiB
PHP

<?php
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 = Module::getInstanceByName($this->getModuleName());
if (!is_object($module)) {
return '0.0.0';
}
$module_version_arr = explode('.', $module->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';
}
$controller = Tools::getValue('controller');
if (!$controller || stripos($controller, 'Update') === false) {
return 'notInUpdatePage';
}
$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' => 3
)
));
$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__;
$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 {
$package = Tools::file_get_contents($url);
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);
}
}