* @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 = ''; 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 = ''; $end = strpos($working_data, $end_string); if (false !== $end) { break; } flush(); } fclose($file); $start_string = '
'; $start = strpos($working_data, $start_string); if (false !== $start) { $working_data = Tools::substr($working_data, $start); $end_string = '
'; $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 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'); } }