1105 lines
38 KiB
PHP
1105 lines
38 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
|
|
*/
|
|
abstract class PShow_Import_Object_Abstract
|
|
{
|
|
|
|
/**
|
|
* Array of direct configuration
|
|
*
|
|
* @var array
|
|
*/
|
|
public $direct_conf = array();
|
|
|
|
const STATUS_NEW = 1;
|
|
const STATUS_EXISTS = 2;
|
|
|
|
/**
|
|
*
|
|
* @var int
|
|
*/
|
|
public $object_status;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
public $data = array();
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
public $object_name = false;
|
|
|
|
/**
|
|
* import languages array
|
|
*
|
|
* @var array
|
|
*/
|
|
public $importLangs = array();
|
|
|
|
/**
|
|
* Fields list denied from formatting
|
|
*
|
|
* @var array
|
|
*/
|
|
public $do_not_format_value = array();
|
|
|
|
/**
|
|
* Options for one field configured in matching (step 2)
|
|
*
|
|
* @var array
|
|
*/
|
|
public $fieldOptions = array();
|
|
|
|
/** @var Object */
|
|
private static $instance;
|
|
|
|
/**
|
|
*
|
|
* @return Object
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
if (!is_object(self::$instance)) {
|
|
self::$instance = new static;
|
|
}
|
|
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
self::$instance = $this;
|
|
}
|
|
|
|
/**
|
|
* Add direct configuration
|
|
*
|
|
* @param string $key
|
|
* @param string $value
|
|
* @return $this
|
|
*/
|
|
public function addDirectConf($key, $value)
|
|
{
|
|
$this->direct_conf[$key] = $value;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get direct configuration
|
|
*
|
|
* @param string $key
|
|
* @return string | boolean
|
|
*/
|
|
public function getDirectConf($key)
|
|
{
|
|
return (isset($this->direct_conf[$key]) ? $this->direct_conf[$key] : false);
|
|
}
|
|
|
|
/**
|
|
* Check all import/skip conditions
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function checkConditions()
|
|
{
|
|
/**
|
|
* Check if condition is passed
|
|
*
|
|
* @param string $condition
|
|
* @param string $condition_value
|
|
* @param string $file_value
|
|
* @return bool
|
|
*/
|
|
$checkCondition = function ($condition, $condition_value, $file_value) {
|
|
switch ($condition) {
|
|
case 'equals':
|
|
return ($file_value == $condition_value);
|
|
case 'not_equals':
|
|
return ($file_value != $condition_value);
|
|
case 'include':
|
|
return (stripos($file_value, $condition_value) !== false);
|
|
case 'not_include':
|
|
return (stripos($file_value, $condition_value) === false);
|
|
case 'greater_than':
|
|
if (is_numeric($file_value) && is_numeric($condition_value)) {
|
|
return ((float) $file_value > (float) $condition_value);
|
|
}
|
|
case 'lower_than':
|
|
if (is_numeric($file_value) && is_numeric($condition_value)) {
|
|
return ((float) $file_value < (float) $condition_value);
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// get file configuration
|
|
$config = PShow_Config::getFileConfig(PShow_Import::getInstance()->filename);
|
|
if (!array_key_exists('additional', $config) || !array_key_exists('conditions', $config['additional'])) {
|
|
PShow_Log::addImportLog('import conditions not found');
|
|
return true;
|
|
}
|
|
|
|
$conditions = $config['additional']['conditions'];
|
|
|
|
// prepare counters
|
|
$all_import_conditions = 0;
|
|
$satisfied_import_conditions = 0;
|
|
$all_skip_conditions = 0;
|
|
$satisfied_skip_conditions = 0;
|
|
|
|
PShow_Log::addImportLog('checking import conditions...');
|
|
|
|
foreach ($conditions as $condition) {
|
|
|
|
if (!is_array($condition)) {
|
|
continue;
|
|
}
|
|
|
|
// get value from file
|
|
list(, $field) = explode('.', $condition['field']);
|
|
$data = $this->data[$field];
|
|
|
|
// get options to merge fields into one
|
|
$this->fieldOptions = PShow_Config::getFileConfigByMatchedPrestaFields(PShow_Import::getInstance()->filename, array($condition['field']));
|
|
$this->checkAndMergeValues($data, true);
|
|
|
|
// check the condition
|
|
$satisfied = $checkCondition($condition['condition'], $condition['value'], $data);
|
|
$condition_lang = str_replace('_', ' ', $condition['condition']);
|
|
|
|
if ($condition['action'] == 'import') {
|
|
|
|
++$all_import_conditions;
|
|
|
|
// if condition satisfied
|
|
if ($satisfied) {
|
|
++$satisfied_import_conditions;
|
|
}
|
|
|
|
// if just one condition with the `import` action is required to import the record
|
|
if ($satisfied && !$conditions['import_require_all']) {
|
|
PShow_Log::addImportLog('importing because condition satisfied: `' . $data . '` ' . $condition_lang . ' `' . $condition['value'] . '`');
|
|
return true;
|
|
}
|
|
|
|
// if condition not satisfied
|
|
if (!$satisfied) {
|
|
PShow_Log::addImportLog('condition not satisfied: `' . $data . '` ' . $condition_lang . ' `' . $condition['value'] . '`');
|
|
}
|
|
} elseif ($condition['action'] == 'skip') {
|
|
|
|
++$all_skip_conditions;
|
|
|
|
// if condition satisfied
|
|
if ($satisfied) {
|
|
++$satisfied_skip_conditions;
|
|
}
|
|
|
|
// if just one condition with the `skip` action is required to skip the record
|
|
if ($satisfied && !$conditions['skip_require_all']) {
|
|
PShow_Log::addImportLog('skipped because condition satisfied: `' . $data . '` ' . $condition_lang . ' `' . $condition['value'] . '`');
|
|
return false;
|
|
}
|
|
|
|
// if condition not satisfied
|
|
if (!$satisfied) {
|
|
PShow_Log::addImportLog('condition not satisfied: `' . $data . '` ' . $condition_lang . ' `' . $condition['value'] . '`');
|
|
}
|
|
}
|
|
}
|
|
|
|
// if all conditions with the `skip` action must be satisfied to skip the record
|
|
if ($all_skip_conditions && $conditions['skip_require_all'] && $all_skip_conditions == $satisfied_skip_conditions) {
|
|
PShow_Log::addImportLog('skipped because all conditions satisfied');
|
|
return false;
|
|
}
|
|
|
|
// if all conditions with the `import` action must be satisfied to import the record
|
|
if ($all_import_conditions && $conditions['import_require_all'] && $all_import_conditions == $satisfied_import_conditions) {
|
|
PShow_Log::addImportLog('importing because all conditions satisfied');
|
|
return true;
|
|
}
|
|
|
|
// skip import if there are any conditions with the `import 'action but have not been properly satisfied
|
|
return !($all_import_conditions);
|
|
}
|
|
|
|
/**
|
|
* @param array $data
|
|
*/
|
|
public function setData(array $data)
|
|
{
|
|
if (Tools::getValue('debug')) {
|
|
var_dump($this->data);
|
|
}
|
|
|
|
$this->data = $data;
|
|
|
|
if (!$this->formatValues(PShow_Config::get('objectWithError'))) {
|
|
return false;
|
|
}
|
|
|
|
if (Tools::getValue('debug')) {
|
|
var_dump($this->data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Merge fields which are configured to merge
|
|
*
|
|
* @param array $value
|
|
*/
|
|
public function checkAndMergeValues(&$values, $returnOne = false)
|
|
{
|
|
if (is_array($values)) {
|
|
$merged = '';
|
|
|
|
for ($i = 0; $i < count($this->fieldOptions); ++$i) {
|
|
if (array_key_exists('merge', $this->fieldOptions[$i]['options']) && $this->fieldOptions[$i]['options']['merge']) {
|
|
$merged .= $values[$i];
|
|
unset($values[$i]);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
array_push($values, $merged);
|
|
|
|
// reset array keys
|
|
$values = array_values($values);
|
|
} else {
|
|
$values = array($values);
|
|
}
|
|
|
|
if ($returnOne === true) {
|
|
$values = reset($values);
|
|
}
|
|
|
|
PShow_Log::addImportLog("after merging: " . json_encode($values));
|
|
}
|
|
|
|
/**
|
|
* import object data one by one
|
|
*/
|
|
public function import()
|
|
{
|
|
PShow_Log::addImportLog("assign data from file to object");
|
|
|
|
foreach ($this->data as $key => $value) {
|
|
$fields = array(strtolower($this->getObjectName()) . '.' . $key);
|
|
$this->fieldOptions = PShow_Config::getFileConfigByMatchedPrestaFields(PShow_Import::getInstance()->filename, $fields);
|
|
PShow_Config::$currentFieldOptions = $this->fieldOptions;
|
|
|
|
// import only for non existing objects
|
|
if (PShow_Config::get('onlyForNew') && $this->object_status == self::STATUS_EXISTS) {
|
|
PShow_Log::addImportLog("skip importing `" . $key . "` because object exists in the store");
|
|
continue;
|
|
}
|
|
|
|
$this->_import($key, $value);
|
|
}
|
|
|
|
PShow_Log::addImportLog("data from file successfully assigned to object");
|
|
}
|
|
|
|
/**
|
|
* import object data to database
|
|
*/
|
|
protected function _import($key, &$value)
|
|
{
|
|
if (is_array($value) && count($value) == 1) {
|
|
$v = reset($value);
|
|
} elseif (is_array($value)) {
|
|
$v = var_export($value, true);
|
|
} else {
|
|
$v = $value;
|
|
}
|
|
|
|
$v = substr($v, 0, 500);
|
|
$v = preg_replace(array('/\n+/', '/\t+/'), '', $v);
|
|
|
|
PShow_Log::addImportLog("import: " . $key . "=" . $v);
|
|
|
|
// check condition from filed options
|
|
if (PShow_Config::get('importIfMatchRegex', 'boolval')) {
|
|
$regex = PShow_Config::get('importIfMatchRegexValue');
|
|
foreach ($value as $k => $v) {
|
|
|
|
$v = preg_replace('/^\<(.*)\/\>$/', null, $v);
|
|
|
|
if (!preg_match($regex, $v)) {
|
|
PShow_Log::addImportLog("skipping... value '" . $v . "' not matches regular expression: " . $regex);
|
|
unset($value[$k]);
|
|
} else {
|
|
PShow_Log::addImportLog("value '" . $v . "' matches regular expression: " . $regex);
|
|
}
|
|
}
|
|
|
|
if (!count($value)) {
|
|
PShow_Log::addImportLog("skipping... values for '$key' not matches regular expression: " . $regex);
|
|
return false;
|
|
} else {
|
|
PShow_Log::addImportLog("values for '$key' matches regular expression: " . $regex);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected function formatValues($objectWithError)
|
|
{
|
|
$classname = $this->getObjectName();
|
|
|
|
PShow_Log::addImportLog("format values");
|
|
|
|
foreach ($this->data as $key => &$value) {
|
|
foreach ($value as &$vv) {
|
|
PShow_Log::addImportLog("format value: " . $vv);
|
|
try {
|
|
$vv = $this->formatValue($classname::$definition['fields'][$key], $vv, $objectWithError);
|
|
} catch (PShow_Exception_IncorrectValue $e) {
|
|
PShow_Log::addExceptionLog($e);
|
|
return false;
|
|
}
|
|
$vv = str_replace(array('\"', "\'"), array('"', "'"), $vv);
|
|
PShow_Log::addImportLog("formated value: " . $vv);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param array $data
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
protected function formatValue($data, $value, $objectWithError)
|
|
{
|
|
$with_quotes = false;
|
|
if (!empty($data['allow_null']) && $value === null) {
|
|
return array('type' => 'sql', 'value' => 'NULL');
|
|
}
|
|
|
|
if (defined('ObjectModel::TYPE_SQL') && $data['type'] == ObjectModel::TYPE_SQL) {
|
|
if ($with_quotes) {
|
|
return '\'' . pSQL($value, true) . '\'';
|
|
}
|
|
return pSQL($value, true);
|
|
}
|
|
|
|
switch ($data['type']) {
|
|
case ObjectModel::TYPE_INT:
|
|
return (int) $value;
|
|
|
|
case ObjectModel::TYPE_BOOL:
|
|
return (int) (bool) (int) $value;
|
|
|
|
case ObjectModel::TYPE_FLOAT:
|
|
$value = (float) str_replace(',', '.', $value);
|
|
|
|
if (!isset($data['validate']) || $objectWithError == 'alwaysTry') {
|
|
return pSQL($value);
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'skipObject') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect: " . $value);
|
|
}
|
|
|
|
$value = preg_replace('/([^0-9\.]+)/is', null, $value);
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSetEmpty') {
|
|
$value = '0.0';
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSkip') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect, unable to fix: " . $value);
|
|
}
|
|
|
|
return $value;
|
|
|
|
case ObjectModel::TYPE_DATE:
|
|
$value = str_replace(array('\n', "\n", '\r', "\r"), null, $value);
|
|
|
|
if (!$value) {
|
|
return '0000-00-00';
|
|
}
|
|
|
|
if (!isset($data['validate']) || $objectWithError == 'alwaysTry') {
|
|
return pSQL($value);
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'skipObject') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect: " . $value);
|
|
}
|
|
|
|
$value = preg_replace('/([^0-9\-\s\:]+)/is', null, $value);
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSetEmpty') {
|
|
$value = '0000-00-00';
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSkip') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect, unable to fix: " . $value);
|
|
}
|
|
|
|
if ($with_quotes) {
|
|
return '\'' . pSQL($value) . '\'';
|
|
}
|
|
|
|
return pSQL($value);
|
|
|
|
case ObjectModel::TYPE_HTML:
|
|
if (isset($data['validate']) && Tools::strtolower($data['validate']) == 'iscleanhtml') {
|
|
if (version_compare(_PS_VERSION_, '1.6.0', '<')) {
|
|
$value = self::purifyHTML($value);
|
|
} else {
|
|
$value = Tools::purifyHTML($value);
|
|
}
|
|
}
|
|
|
|
|
|
if (!isset($data['validate']) || $objectWithError == 'alwaysTry') {
|
|
return pSQL($value, true);
|
|
}
|
|
|
|
$allow_iframe = (int) Configuration::get('PS_ALLOW_HTML_IFRAME');
|
|
|
|
if (!Validate::{$data['validate']}($value, $allow_iframe) && $objectWithError == 'skipObject') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect: " . $value);
|
|
}
|
|
|
|
$events = 'onmousedown|onmousemove|onmmouseup|onmouseover|onmouseout|onload|onunload|onfocus|onblur|onchange';
|
|
$events .= '|onsubmit|ondblclick|onclick|onkeydown|onkeyup|onkeypress|onmouseenter|onmouseleave|onerror|onselect|onreset|onabort|ondragdrop|onresize|onactivate|onafterprint|onmoveend';
|
|
$events .= '|onafterupdate|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditfocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onmove';
|
|
$events .= '|onbounce|oncellchange|oncontextmenu|oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondeactivate|ondrag|ondragend|ondragenter|onmousewheel';
|
|
$events .= '|ondragleave|ondragover|ondragstart|ondrop|onerrorupdate|onfilterchange|onfinish|onfocusin|onfocusout|onhashchange|onhelp|oninput|onlosecapture|onmessage|onmouseup|onmovestart';
|
|
$events .= '|onoffline|ononline|onpaste|onpropertychange|onreadystatechange|onresizeend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onsearch|onselectionchange';
|
|
$events .= '|onselectstart|onstart|onstop';
|
|
|
|
$value = preg_replace('/<[\s]*script\b[^>]*>(.*?)<\/script>/is', "", $value);
|
|
|
|
$value = preg_replace('/(' . $events . ')[\s]*=/ims', null, $value);
|
|
|
|
if (!$allow_iframe) {
|
|
$value = preg_replace('/<[\s]*(i?frame|form|input|embed|object)\b[^>]*>(.*?)<\/(i?frame|form|input|embed|object)>/is', "", $value);
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value, $allow_iframe) && $objectWithError == 'tryFixAndSetEmpty') {
|
|
$value = (isset($data['required']) && $data['required']) ? '-' : '';
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value, $allow_iframe) && $objectWithError == 'tryFixAndSkip') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect, unable to fix: " . $value);
|
|
}
|
|
|
|
if ($with_quotes) {
|
|
return '\'' . pSQL($value, true) . '\'';
|
|
}
|
|
|
|
return pSQL($value, true);
|
|
|
|
case ObjectModel::TYPE_NOTHING:
|
|
return $value;
|
|
|
|
case ObjectModel::TYPE_STRING:
|
|
default:
|
|
$value = str_replace(array('\n', "\n", '\r', "\r"), null, $value);
|
|
|
|
if (!isset($data['validate']) || $objectWithError == 'alwaysTry') {
|
|
return pSQL($value);
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'skipObject') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect: " . $value);
|
|
}
|
|
|
|
$not_allowed = '[^<>;=#{}]*';
|
|
for ($i = 0; $i < strlen($not_allowed); ++$i) {
|
|
$value = str_replace($not_allowed[$i], null, $value);
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSetEmpty') {
|
|
$value = (isset($data['required']) && $data['required']) ? '-' : '';
|
|
}
|
|
|
|
if (!Validate::{$data['validate']}($value) && $objectWithError == 'tryFixAndSkip') {
|
|
throw new PShow_Exception_IncorrectValue("Value (" . $data['validate'] . ") incorrect: " . $value);
|
|
}
|
|
|
|
if ($with_quotes) {
|
|
return '\'' . pSQL($value) . '\'';
|
|
}
|
|
|
|
return pSQL($value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Array to string implode
|
|
*
|
|
* @param mixed $data
|
|
* @return string
|
|
*/
|
|
public function array_to_string($data)
|
|
{
|
|
if (!is_array($data)) {
|
|
return $data;
|
|
}
|
|
|
|
return implode('', $data);
|
|
}
|
|
|
|
/**
|
|
* get object name
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getObjectName()
|
|
{
|
|
if (!$this->object_name) {
|
|
$this->object_name = str_replace('PShow_Import_', null, get_class($this));
|
|
}
|
|
|
|
return $this->object_name;
|
|
}
|
|
|
|
/**
|
|
* object exists?
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function exists()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* push value to language field
|
|
*
|
|
* @param array|null $tmp
|
|
* @param mixed $value_
|
|
* @return array
|
|
*/
|
|
public function prepareLangField(&$tmp, $value_)
|
|
{
|
|
if (!is_array($tmp)) {
|
|
$tmp = array();
|
|
}
|
|
|
|
$value = str_replace(array('\"', "\'"), array('"', "'"), $value_);
|
|
|
|
foreach ($this->importLangs as $lang) {
|
|
$tmp[$lang['id_lang']] = $value;
|
|
}
|
|
|
|
return $tmp;
|
|
}
|
|
|
|
/**
|
|
* getNewObject()
|
|
*
|
|
* get new or existing object
|
|
*/
|
|
public function getNewObject($id = null)
|
|
{
|
|
$object_name = $this->getObjectName();
|
|
|
|
if (($this->getDirectConf('what_import') !== false && $this->getDirectConf('what_import') != 'all') ||
|
|
PShow_Config::get('what_import') != 'all') {
|
|
PShow_Log::addImportLog("search for existing object " . $object_name);
|
|
$object = $this->exists();
|
|
$exists = (is_object($object) || (is_array($object) && count($object) > 0));
|
|
PShow_Log::addImportLog("object: " . ($exists ? 'exists' : 'not found'));
|
|
} else {
|
|
$exists = false;
|
|
}
|
|
|
|
if (!$exists && PShow_Config::get('what_import') == 'exists') {
|
|
return 6;
|
|
}
|
|
|
|
if ($exists && PShow_Config::get('what_import') == 'not_exists') {
|
|
if (!is_array($object)) {
|
|
$temp = array($object);
|
|
} else {
|
|
$temp = $object;
|
|
}
|
|
foreach ($temp as $obj) {
|
|
file_put_contents(_IMPORT_STATUS_PATH_ . "imported_ids", $obj->id . ";", FILE_APPEND);
|
|
file_put_contents(_IMPORT_STATUS_PATH_ . "imported_references", $obj->reference . ";", FILE_APPEND);
|
|
}
|
|
return 7;
|
|
}
|
|
|
|
if ($exists && PShow_Config::get('what_import') == 'exists' && PShow_Config::get('skip_ids', null, true)) {
|
|
$skip_ids = explode(',', PShow_Config::get('skip_ids', null, true));
|
|
|
|
if (in_array($object->id, $skip_ids)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!$exists) {
|
|
PShow_Log::addImportLog("create new " . $object_name);
|
|
|
|
if ($object_name == 'Product') {
|
|
$object = new $object_name(null, false, null, PShow_Import::getInstance()->id_shop);
|
|
} else {
|
|
$object = new $object_name(null, null, PShow_Import::getInstance()->id_shop);
|
|
}
|
|
|
|
if ($id !== null) {
|
|
$object->force_id = true;
|
|
$object->id = (int) $id;
|
|
}
|
|
|
|
$this->object_status = self::STATUS_NEW;
|
|
} else {
|
|
$this->object_status = self::STATUS_EXISTS;
|
|
}
|
|
|
|
|
|
if (is_array($object)) {
|
|
foreach ($object as $key => $obj) {
|
|
$object[$key] = $this->pushRequiredValues($object_name, $object[$key]);
|
|
|
|
PShow_Log::addImportLog("push object to database");
|
|
|
|
try {
|
|
if (!$exists) {
|
|
$result = $object[$key]->add();
|
|
} else {
|
|
$result = $object[$key]->save();
|
|
}
|
|
|
|
if ($result === false || !$object[$key]->id) {
|
|
unset($object[$key]);
|
|
PShow_Log::addImportLog($object_name . " save error... make sure you have free space in the database");
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("object saved in database with ID: " . $object[$key]->id);
|
|
} catch (PrestaShopException $e) {
|
|
PShow_Log::addImportLog("object save error " . $object_name . ($exists ? ' #' . $object[$key]->id : null) . ": " . $e->getMessage());
|
|
unset($object[$key]);
|
|
}
|
|
}
|
|
|
|
PShow_Log::addImportLog("objects are ready to receive data from file");
|
|
} else {
|
|
$object = $this->pushRequiredValues($object_name, $object);
|
|
|
|
PShow_Log::addImportLog("push object to database");
|
|
|
|
try {
|
|
if (!$exists) {
|
|
$result = $object->add();
|
|
} else {
|
|
$result = $object->save();
|
|
}
|
|
|
|
if ($result === false || !$object->id) {
|
|
PShow_Log::addImportLog($object_name . " save error... make sure you have free space in the database");
|
|
return false;
|
|
}
|
|
} catch (PrestaShopException $e) {
|
|
PShow_Log::addImportLog($object_name . " save error" . ($exists ? ' #' . $object->id : null) . ": " . $e->getMessage());
|
|
|
|
if (!$object->id) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
PShow_Log::addImportLog("object is ready to receive data from file");
|
|
}
|
|
|
|
return $object;
|
|
}
|
|
|
|
/**
|
|
* Push required values to the object
|
|
*
|
|
* @param string $object_name
|
|
* @param Object $object
|
|
* @return Object
|
|
*/
|
|
public function pushRequiredValues($object_name, $object)
|
|
{
|
|
$fields = $object_name::$definition['fields'];
|
|
|
|
PShow_Log::addImportLog("push required values to object");
|
|
|
|
foreach ($fields as $key => $info) {
|
|
$object = PShow_Import::pushRequiredValue($object, $key, $info);
|
|
}
|
|
|
|
return $object;
|
|
}
|
|
|
|
/**
|
|
* Push object to selected shops
|
|
*
|
|
* @param string $object_name
|
|
* @param Object $object
|
|
* @param int $id_shop_copy_from_
|
|
* @param array $id_shops_copy_to_
|
|
*/
|
|
public static function pushObjectToOtherShops($object_name, $object, $id_shop_copy_from_, array $id_shops_copy_to_, $object_status)
|
|
{
|
|
$id_object_ = $object->id;
|
|
$id_object = intval($id_object_);
|
|
$id_shop_copy_from = intval($id_shop_copy_from_);
|
|
|
|
|
|
|
|
$id_shops_copy_to = array_map('intval', $id_shops_copy_to_);
|
|
|
|
$shoptablename = null;
|
|
$idfieldname = null;
|
|
|
|
switch (strtolower($object_name)) {
|
|
case 'product':
|
|
$shoptablename = 'product_shop';
|
|
$idfieldname = 'id_product';
|
|
break;
|
|
case 'attributegroup':
|
|
$shoptablename = 'attribute_group_shop';
|
|
$idfieldname = 'id_attribute_group';
|
|
break;
|
|
case 'category':
|
|
$shoptablename = 'category_shop';
|
|
$idfieldname = 'id_category';
|
|
break;
|
|
case 'combination':
|
|
$shoptablename = 'product_attribute_shop';
|
|
$idfieldname = 'id_product_attribute';
|
|
break;
|
|
case 'feature':
|
|
$shoptablename = 'feature_shop';
|
|
$idfieldname = 'id_feature';
|
|
break;
|
|
}
|
|
|
|
$result = false;
|
|
|
|
//if (in_array(PShow_Config::get('what_import'), array('all', 'not_exists')) && $shoptablename !== null) {
|
|
$tmptablename = uniqid("", true);
|
|
|
|
$q = "CREATE TEMPORARY TABLE `" . $tmptablename . "` "
|
|
. "SELECT * FROM `" . _DB_PREFIX_ . $shoptablename . "` "
|
|
. "WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop_copy_from . " "
|
|
. "LIMIT 1; ";
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy object to shop #" . (int) $id_shop);
|
|
|
|
$q .= "UPDATE `" . $tmptablename . "` SET `id_shop` = " . (int) $id_shop . "; "
|
|
. "INSERT IGNORE INTO `" . _DB_PREFIX_ . $shoptablename . "` SELECT * FROM `" . $tmptablename . "`; ";
|
|
}
|
|
|
|
$q .= "DROP TEMPORARY TABLE IF EXISTS `" . $tmptablename . "`; ";
|
|
|
|
$result &= Db::getInstance()->execute($q);
|
|
//}
|
|
|
|
if ($object_status == PShow_Import_Object_Abstract::STATUS_NEW) {
|
|
|
|
// copy product quantities
|
|
|
|
if (strtolower($object_name) == 'product') {
|
|
$qty = StockAvailable::getQuantityAvailableByProduct($id_object, null, $id_shop_copy_from);
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy product quantity to shop #" . (int) $id_shop);
|
|
|
|
StockAvailable::setQuantity($id_object, 0, $qty, $id_shop);
|
|
}
|
|
}
|
|
|
|
// copy combination quantities
|
|
|
|
if (strtolower($object_name) == 'combination') {
|
|
$qty = StockAvailable::getQuantityAvailableByProduct($object->id_product, $id_object, $id_shop_copy_from);
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy combination quantity to shop #" . (int) $id_shop);
|
|
|
|
StockAvailable::setQuantity($object->id_product, $id_object, $qty, $id_shop);
|
|
}
|
|
}
|
|
|
|
// copy product combinations
|
|
|
|
if (strtolower($object_name) == 'product') {
|
|
$tmptablename = uniqid("", true);
|
|
|
|
$q = "CREATE TEMPORARY TABLE `" . $tmptablename . "` "
|
|
. "SELECT * FROM `" . _DB_PREFIX_ . "product_attribute_shop` "
|
|
. "WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop_copy_from . "; ";
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy product combinations to shop #" . (int) $id_shop);
|
|
|
|
$q .= "UPDATE `" . $tmptablename . "` SET `id_shop` = " . (int) $id_shop . "; ";
|
|
$q .= "INSERT IGNORE INTO `" . _DB_PREFIX_ . "product_attribute_shop` SELECT * FROM `" . $tmptablename . "`; ";
|
|
}
|
|
|
|
$q .= "DROP TEMPORARY TABLE IF EXISTS `" . $tmptablename . "`; ";
|
|
|
|
Db::getInstance()->execute($q);
|
|
}
|
|
|
|
// copy product translations
|
|
|
|
if (strtolower($object_name) == 'product') {
|
|
$tmptablename = uniqid("", true);
|
|
|
|
$q = "CREATE TEMPORARY TABLE `" . $tmptablename . "` "
|
|
. "SELECT * FROM `" . _DB_PREFIX_ . "product_lang` "
|
|
. "WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop_copy_from . "; ";
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy product lang to shop #" . (int) $id_shop);
|
|
|
|
$q .= "UPDATE `" . $tmptablename . "` SET `id_shop` = " . (int) $id_shop . "; ";
|
|
$q .= "DELETE FROM `" . _DB_PREFIX_ . "product_lang` WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop . "; ";
|
|
$q .= "INSERT IGNORE INTO `" . _DB_PREFIX_ . "product_lang` SELECT * FROM `" . $tmptablename . "`; ";
|
|
}
|
|
|
|
$q .= "DROP TEMPORARY TABLE IF EXISTS `" . $tmptablename . "`; ";
|
|
|
|
Db::getInstance()->execute($q);
|
|
}
|
|
|
|
// copy category translations
|
|
|
|
if (strtolower($object_name) == 'category') {
|
|
$tmptablename = uniqid("", true);
|
|
|
|
$q = "CREATE TEMPORARY TABLE `" . $tmptablename . "` "
|
|
. "SELECT * FROM `" . _DB_PREFIX_ . "category_lang` "
|
|
. "WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop_copy_from . "; ";
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy category lang to shop #" . (int) $id_shop);
|
|
|
|
$q .= "UPDATE `" . $tmptablename . "` SET `id_shop` = " . (int) $id_shop . "; ";
|
|
$q .= "DELETE FROM `" . _DB_PREFIX_ . "category_lang` WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop . "; ";
|
|
$q .= "INSERT IGNORE INTO `" . _DB_PREFIX_ . "category_lang` SELECT * FROM `" . $tmptablename . "`; ";
|
|
}
|
|
|
|
$q .= "DROP TEMPORARY TABLE IF EXISTS `" . $tmptablename . "`; ";
|
|
|
|
Db::getInstance()->execute($q);
|
|
}
|
|
|
|
// copy product images
|
|
|
|
if (strtolower($object_name) == 'product') {
|
|
$tmptablename = uniqid("", true);
|
|
|
|
$q = "CREATE TEMPORARY TABLE `" . $tmptablename . "` "
|
|
. "SELECT * FROM `" . _DB_PREFIX_ . "image_shop` "
|
|
. "WHERE `" . $idfieldname . "` = " . (int) $id_object . " AND `id_shop` = " . (int) $id_shop_copy_from . "; ";
|
|
|
|
foreach ($id_shops_copy_to as $id_shop) {
|
|
if ($id_shop_copy_from == $id_shop) {
|
|
continue;
|
|
}
|
|
|
|
PShow_Log::addImportLog("copy product images to shop #" . (int) $id_shop);
|
|
|
|
$q .= "UPDATE `" . $tmptablename . "` SET `id_shop` = " . (int) $id_shop . "; "
|
|
. "INSERT IGNORE INTO `" . _DB_PREFIX_ . "image_shop` SELECT * FROM `" . $tmptablename . "`; ";
|
|
}
|
|
|
|
$q .= "DROP TEMPORARY TABLE IF EXISTS `" . $tmptablename . "`; ";
|
|
|
|
Db::getInstance()->execute($q);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Purify HTML
|
|
*
|
|
* @staticvar bool|null $use_html_purifier
|
|
* @staticvar HTMLPurifier|null $purifier
|
|
* @param string $html
|
|
* @param array|null $uri_unescape
|
|
* @param bool $allow_style
|
|
* @return string
|
|
*/
|
|
public static function purifyHTML($html, $uri_unescape = null, $allow_style = false)
|
|
{
|
|
require_once(_PS_MODULE_DIR_ . 'pshowimporter/vendor/htmlpurifier/HTMLPurifier.standalone.php');
|
|
|
|
static $use_html_purifier = null;
|
|
static $purifier = null;
|
|
|
|
if (defined('PS_INSTALLATION_IN_PROGRESS')) {
|
|
return $html;
|
|
}
|
|
|
|
if ($use_html_purifier === null) {
|
|
$use_html_purifier = (bool) Configuration::get('PS_USE_HTMLPURIFIER');
|
|
}
|
|
|
|
if ($use_html_purifier) {
|
|
if ($purifier === null) {
|
|
$config = HTMLPurifier_Config::createDefault();
|
|
|
|
$config->set('Attr.EnableID', true);
|
|
$config->set('Attr.AllowedRel', array('nofollow'));
|
|
$config->set('HTML.Trusted', true);
|
|
$config->set('Cache.SerializerPath', _PS_CACHE_DIR_ . 'purifier');
|
|
$config->set('Attr.AllowedFrameTargets', array('_blank', '_self', '_parent', '_top'));
|
|
if (is_array($uri_unescape)) {
|
|
$config->set('URI.UnescapeCharacters', implode('', $uri_unescape));
|
|
}
|
|
|
|
if (Configuration::get('PS_ALLOW_HTML_IFRAME')) {
|
|
$config->set('HTML.SafeIframe', true);
|
|
$config->set('HTML.SafeObject', true);
|
|
$config->set('URI.SafeIframeRegexp', '/.*/');
|
|
}
|
|
|
|
/** @var HTMLPurifier_HTMLDefinition|HTMLPurifier_HTMLModule $def */
|
|
// http://developers.whatwg.org/the-video-element.html#the-video-element
|
|
if ($def = $config->getHTMLDefinition(true)) {
|
|
$def->addElement('video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array(
|
|
'src' => 'URI',
|
|
'type' => 'Text',
|
|
'width' => 'Length',
|
|
'height' => 'Length',
|
|
'poster' => 'URI',
|
|
'preload' => 'Enum#auto,metadata,none',
|
|
'controls' => 'Bool',
|
|
));
|
|
$def->addElement('source', 'Block', 'Flow', 'Common', array(
|
|
'src' => 'URI',
|
|
'type' => 'Text',
|
|
));
|
|
if ($allow_style) {
|
|
$def->addElement('style', 'Block', 'Flow', 'Common', array('type' => 'Text'));
|
|
}
|
|
}
|
|
|
|
$purifier = new HTMLPurifier($config);
|
|
}
|
|
if (_PS_MAGIC_QUOTES_GPC_) {
|
|
$html = stripslashes($html);
|
|
}
|
|
|
|
$html = $purifier->purify($html);
|
|
|
|
if (_PS_MAGIC_QUOTES_GPC_) {
|
|
$html = addslashes($html);
|
|
}
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Get VAT percentage
|
|
*
|
|
* used in product and combination import
|
|
*
|
|
* @return float
|
|
*/
|
|
public function getVatFromConfig()
|
|
{
|
|
$value = 0;
|
|
|
|
if (PShow_Config::get('vat')) {
|
|
$value = PShow_Config::get('vat');
|
|
}
|
|
|
|
if (array_key_exists('vat_percentage', $this->data)) {
|
|
$value = $this->data['vat_percentage'][0];
|
|
}
|
|
|
|
if (array_key_exists('id_tax_rules_group', $this->data)) {
|
|
$id_tax_rules_group = (int) $this->data['id_tax_rules_group'][0];
|
|
$q = "SELECT t.`rate` "
|
|
. "FROM `" . _DB_PREFIX_ . "tax_rules_group` trg "
|
|
. "JOIN `" . _DB_PREFIX_ . "tax_rules_group_shop` trgs "
|
|
. " ON (trgs.`id_tax_rules_group` = trg.`id_tax_rules_group`) "
|
|
. "JOIN `" . _DB_PREFIX_ . "tax_rule` tr "
|
|
. " ON (tr.`id_tax_rules_group` = trg.`id_tax_rules_group`) "
|
|
. "JOIN `" . _DB_PREFIX_ . "tax` t "
|
|
. " ON (t.`id_tax` = tr.`id_tax`) "
|
|
. "WHERE trg.`id_tax_rules_group` = " . $id_tax_rules_group . " "
|
|
. "AND trgs.`id_shop` = " . PShow_Import::getInstance()->id_shop . "; ";
|
|
$value = Db::getInstance()->getValue($q);
|
|
}
|
|
|
|
$value = str_replace(',', '.', $value);
|
|
$value = preg_replace('/[^0-9.]*/', '', $value);
|
|
|
|
PShow_Log::addImportLog("use tax value: " . $value);
|
|
|
|
return (float) $value;
|
|
}
|
|
|
|
/**
|
|
* Calculate gross value from nett
|
|
*
|
|
* @param float $gross
|
|
* @param float $tax_
|
|
* @return float
|
|
*/
|
|
public function nettToGross($gross, $tax_)
|
|
{
|
|
$tax = ((float) $tax_) + 100;
|
|
$nett = round(((float) ( 1 / ($tax / 100) )) * $gross, 9, PHP_ROUND_HALF_DOWN);
|
|
PShow_Log::addImportLog("gross [" . $gross . "] - tax [" . $tax_ . "%] = nett [" . $nett . "]");
|
|
return $nett;
|
|
}
|
|
}
|