444 lines
13 KiB
PHP
444 lines
13 KiB
PHP
<?php
|
|
/**
|
|
* Since 2013 Ovidiu Cimpean.
|
|
*
|
|
* Ovidiu Cimpean - Newsletter Pro © All rights reserved.
|
|
*
|
|
* DISCLAIMER
|
|
*
|
|
* Do not edit, modify or copy this file.
|
|
* If you wish to customize it, contact us at addons4prestashop@gmail.com.
|
|
*
|
|
* @author Ovidiu Cimpean <addons4prestashop@gmail.com>
|
|
* @copyright Since 2013 Ovidiu Cimpean
|
|
* @license Do not edit, modify or copy this file
|
|
*
|
|
* @version Release: 4
|
|
*/
|
|
|
|
use PQNP\Config;
|
|
|
|
class NewsletterProBackupXml
|
|
{
|
|
public $load_configuration;
|
|
|
|
public $load_configuration_campaign;
|
|
|
|
public $load_configuration_shop;
|
|
|
|
public $load_hooks;
|
|
|
|
public $load_tables;
|
|
|
|
public $load_data;
|
|
|
|
public $load_xml;
|
|
|
|
public $module;
|
|
|
|
public $headers;
|
|
|
|
public $tables;
|
|
|
|
public $hex;
|
|
|
|
public $default_path;
|
|
|
|
const PHP_HEADER = '<?php exit; ?>';
|
|
|
|
public function __construct($default_path = null)
|
|
{
|
|
$this->module = NewsletterPro::getInstance();
|
|
$this->headers = [];
|
|
|
|
if (!isset($default_path)) {
|
|
$this->default_path = self::path();
|
|
} else {
|
|
$this->default_path = $default_path;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the backup folder dirname.
|
|
*
|
|
* @return string Folder dirname
|
|
*/
|
|
public static function path()
|
|
{
|
|
return realpath(dirname(__FILE__).'/../backup');
|
|
}
|
|
|
|
/**
|
|
* Format pathname
|
|
* Ex: subscription/file name 123 -> subscription/file_name_123.php.
|
|
*
|
|
* @param string $path_name Pathname
|
|
* @param bool $timestamp Append a timestamp at the end of the filename
|
|
*
|
|
* @return string Formated path name
|
|
*/
|
|
public static function formatName($path_name, $timestamp = false)
|
|
{
|
|
return preg_replace('/\s+/', '_', trim(Tools::strtolower($path_name))).($timestamp ? '_'.time() : '').'.php';
|
|
}
|
|
|
|
/**
|
|
* Check if the path name exists.
|
|
*
|
|
* @param string $path_name Pathname
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function pathNameExists($path_name, $md5 = false)
|
|
{
|
|
if ($md5) {
|
|
$path_name = self::formatMD5($path_name);
|
|
}
|
|
|
|
return file_exists(self::path().'/'.$path_name);
|
|
}
|
|
|
|
/**
|
|
* Get the path dirname.
|
|
*
|
|
* @param string $path_name Pathname
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function pathName($path_name)
|
|
{
|
|
return self::path().'/'.$path_name;
|
|
}
|
|
|
|
/**
|
|
* Setup the backup header information.
|
|
*
|
|
* @param string $name Header hey
|
|
* @param string $value Header value
|
|
*/
|
|
public function addHeader($name, $value)
|
|
{
|
|
$this->headers[$name] = $value;
|
|
}
|
|
|
|
/**
|
|
* Add tables for backup creation.
|
|
*
|
|
* @param array $tables Tables without the prefix
|
|
*/
|
|
public function create(array $tables, $hex = false)
|
|
{
|
|
$this->hex = $hex;
|
|
$this->tables = $tables;
|
|
$tables_header = [];
|
|
foreach ($this->tables as $table_name) {
|
|
$tables_header[] = _DB_PREFIX_.$table_name;
|
|
}
|
|
|
|
$this->addHeader('tables', implode(',', $tables_header));
|
|
}
|
|
|
|
public static function formatMD5($path_name)
|
|
{
|
|
$info_name = pathinfo($path_name, PATHINFO_FILENAME);
|
|
$info_extension = pathinfo($path_name, PATHINFO_EXTENSION);
|
|
$info_dirname = pathinfo($path_name, PATHINFO_DIRNAME);
|
|
|
|
$name = md5($info_name).($info_extension ? '.'.$info_extension : '');
|
|
$path_name = $info_dirname.'/'.$name;
|
|
|
|
return $path_name;
|
|
}
|
|
|
|
/**
|
|
* Save the backup xml.
|
|
*
|
|
* @param string $path_name Pathname
|
|
* @param bool $format Format the name
|
|
* @param bool $md5 Md5 format
|
|
*
|
|
* @return bool Success
|
|
*/
|
|
public function save($path_name, $format = true, $md5 = true)
|
|
{
|
|
$name = basename($path_name);
|
|
$name_display = $name;
|
|
|
|
if ($md5) {
|
|
$path_name = self::formatMD5($path_name);
|
|
}
|
|
|
|
if ($format) {
|
|
$path_filename = self::formatName($path_name);
|
|
} else {
|
|
$path_filename = $path_name;
|
|
}
|
|
|
|
$filename = basename($path_filename);
|
|
|
|
$this->addHeader('filename', $filename);
|
|
$this->addHeader('date', date('Y-m-d H:i:s', time()));
|
|
$this->addHeader('module_version', $this->module->version);
|
|
$this->addHeader('name', $name_display);
|
|
|
|
if (!isset($this->headers['configuration_shop'])) {
|
|
$this->addHeader('configuration_shop', serialize([]));
|
|
}
|
|
|
|
if (!isset($this->headers['configuration'])) {
|
|
$this->addHeader('configuration', serialize([]));
|
|
}
|
|
|
|
if (!isset($this->headers['configuration_campaign'])) {
|
|
$this->addHeader('configuration_campaign', null);
|
|
}
|
|
|
|
if (!isset($this->headers['hooks'])) {
|
|
$this->addHeader('hooks', serialize([]));
|
|
}
|
|
|
|
$mysql = new NewsletterProMySQLDumpXml($this->hex);
|
|
$mysql->prependString(self::PHP_HEADER."\n");
|
|
$mysql->addTables($this->tables);
|
|
$mysql->setHeader($this->headers);
|
|
|
|
return $mysql->save($this->default_path.'/'.$path_filename);
|
|
}
|
|
|
|
/**
|
|
* Det the backup files list.
|
|
*
|
|
* @param string $path Backup path
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getList($path = '')
|
|
{
|
|
$dirs = new DirectoryIterator(self::path().'/'.$path);
|
|
$files = new RegexIterator($dirs, '/.php$/', RecursiveRegexIterator::MATCH);
|
|
$results = [];
|
|
|
|
foreach ($files as $file) {
|
|
$file_basename = '';
|
|
if (method_exists($file, 'getBasename')) {
|
|
$file_basename = $file->getBasename();
|
|
} else {
|
|
$file_basename = basename($file->getFilename());
|
|
}
|
|
|
|
if ('index.php' !== $file_basename) {
|
|
$header = self::getHeaderFromFilename($file->getPathname());
|
|
|
|
$header_name = 'Undefined';
|
|
if (isset($header['name'])) {
|
|
$header_name = $header['name'];
|
|
}
|
|
|
|
$item = [];
|
|
$item['m_date'] = date('Y-m-d H:i:s', $file->getMTime());
|
|
$item['name'] = $file_basename;
|
|
$item['name_display'] = Tools::ucfirst(str_replace('_', ' ', preg_replace('/\.php$/', '', $header_name)));
|
|
$item['filename'] = $file->getPathname();
|
|
$item['module_version'] = (isset($header['module_version']) ? $header['module_version'] : '0.00');
|
|
$results[] = $item;
|
|
}
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Cet the header as array from a file.
|
|
*
|
|
* @param string $filename Filename path
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getHeaderFromFilename($filename)
|
|
{
|
|
$header = [];
|
|
if (file_exists($filename)) {
|
|
if ($file = fopen($filename, 'r')) {
|
|
$working_data = '';
|
|
while (!feof($file) && (0 == connection_status())) {
|
|
$working_data_temp = fread($file, 1024);
|
|
$working_data .= $working_data_temp;
|
|
$end_string = '</header>';
|
|
$end = strpos($working_data, $end_string);
|
|
|
|
if (false !== $end) {
|
|
break;
|
|
}
|
|
|
|
flush();
|
|
}
|
|
fclose($file);
|
|
|
|
$start_string = '<header>';
|
|
$start = strpos($working_data, $start_string);
|
|
if (false !== $start) {
|
|
$working_data = Tools::substr($working_data, $start);
|
|
|
|
$end_string = '</header>';
|
|
$end = strpos($working_data, $end_string);
|
|
if (false !== $end) {
|
|
$header_xml = Tools::substr($working_data, 0, $end + Tools::strlen($end_string));
|
|
|
|
libxml_use_internal_errors(true);
|
|
$xml_obj = simplexml_load_string($header_xml);
|
|
|
|
if (false === $xml_obj) {
|
|
$xml_errors = '';
|
|
foreach (libxml_get_errors() as $error) {
|
|
$xml_errors .= NewsletterProTools::displayXMLError($error, $xml_obj)."\n";
|
|
}
|
|
libxml_clear_errors();
|
|
// skip error if exits
|
|
} else {
|
|
foreach ($xml_obj as $header_name => $value) {
|
|
$header[$header_name] = trim((string) $value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $header;
|
|
}
|
|
|
|
/**
|
|
* Load the backup from a file.
|
|
*
|
|
* @param string $path_name Pathname
|
|
*/
|
|
public function load($path_name, $is_file = true)
|
|
{
|
|
if ($is_file) {
|
|
$full_path = isset($this->default_path) ? $this->default_path.'/'.$path_name : self::pathName($path_name);
|
|
|
|
if (!file_exists($full_path) || !is_file($full_path)) {
|
|
throw new Exception(sprintf($this->module->l('The filename "%s" does not exists anymore.'), basename($path_name)));
|
|
}
|
|
|
|
$this->load_data = @Tools::file_get_contents($full_path);
|
|
|
|
if (false === $this->load_data) {
|
|
throw new Exception(sprintf($this->module->l('The filename "%s" is not readable. Please check the CHMOD permissions.'), basename($path_name)));
|
|
}
|
|
|
|
libxml_use_internal_errors(true);
|
|
$this->load_xml = simplexml_load_file($full_path);
|
|
} else {
|
|
$this->load_data = $path_name; // is this case the $path_name is a string content
|
|
// remove the php exit
|
|
$this->removePHPHeader();
|
|
libxml_use_internal_errors(true);
|
|
$this->load_xml = simplexml_load_string($this->load_data);
|
|
}
|
|
|
|
if (false === $this->load_xml) {
|
|
$xml_errors = '';
|
|
foreach (libxml_get_errors() as $error) {
|
|
$xml_errors .= NewsletterProTools::displayXMLError($error, $this->load_xml)."\n";
|
|
}
|
|
libxml_clear_errors();
|
|
|
|
throw new Exception($xml_errors);
|
|
}
|
|
|
|
$header_xml = $this->load_xml->header;
|
|
|
|
$this->load_tables = [];
|
|
if (isset($header_xml->tables)) {
|
|
$this->load_tables = explode(',', (string) $header_xml->tables);
|
|
}
|
|
|
|
$this->load_configuration = [];
|
|
if (isset($header_xml->configuration)) {
|
|
$this->load_configuration = NewsletterProTools::unSerialize(trim((string) $header_xml->configuration));
|
|
}
|
|
|
|
$this->load_configuration_campaign = null;
|
|
if (isset($header_xml->configuration_campaign)) {
|
|
$this->load_configuration_campaign = $header_xml->configuration_campaign;
|
|
}
|
|
|
|
$this->load_configuration_shop = [];
|
|
if (isset($header_xml->configuration_shop)) {
|
|
$this->load_configuration_shop = NewsletterProTools::unSerialize(trim((string) $header_xml->configuration_shop));
|
|
}
|
|
|
|
$this->load_hooks = [];
|
|
if (isset($header_xml->hooks)) {
|
|
$this->load_hooks = NewsletterProTools::unSerialize(trim((string) $header_xml->hooks));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove the <?php exit; ?> from the begining of the line from the load_data.
|
|
*/
|
|
private function removePHPHeader()
|
|
{
|
|
$start = strpos($this->load_data, self::PHP_HEADER);
|
|
if (false !== $start) {
|
|
$this->load_data = trim(Tools::substr($this->load_data, Tools::strlen(self::PHP_HEADER)));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute a backup after is loaded.
|
|
*
|
|
* @return bool Reutrn true if success
|
|
*/
|
|
public function execute()
|
|
{
|
|
$success = [];
|
|
|
|
$success[] = NewsletterPro::executeHooksByInfo($this->load_hooks);
|
|
|
|
$configuration = array_merge(Config::get(), $this->load_configuration);
|
|
$success[] = Configuration::updateValue(Config::NAME, json_encode($configuration), false, 0, 0);
|
|
|
|
$success[] = Configuration::updateValue('NEWSLETTER_PRO_CAMPAIGN', $this->load_configuration_campaign, false, 0, 0);
|
|
|
|
$success[] = NewsletterProConfigurationShop::replaceShopsCondiguration($this->load_configuration_shop);
|
|
|
|
$xml_to_sql = new NewsletterProXMLToSQL($this->load_xml);
|
|
foreach ($xml_to_sql->getSQL() as $table_name => $sql_array) {
|
|
$success[] = $this->emptyTable($table_name);
|
|
|
|
foreach ($sql_array as $sql) {
|
|
$success[] = @Db::getInstance()->execute($sql);
|
|
}
|
|
}
|
|
|
|
return !in_array(false, $success);
|
|
}
|
|
|
|
/**
|
|
* Get the loaded xml.
|
|
*
|
|
* @return object
|
|
*/
|
|
public function getXML()
|
|
{
|
|
return $this->load_xml;
|
|
}
|
|
|
|
/**
|
|
* Set the load xml object.
|
|
*
|
|
* @param object $xml
|
|
*/
|
|
public function setXML($xml)
|
|
{
|
|
$this->load_xml = $xml;
|
|
}
|
|
|
|
public function emptyTable($table_name)
|
|
{
|
|
return Db::getInstance()->execute('DELETE FROM `'.pSQL($table_name).'` WHERE 1');
|
|
}
|
|
}
|