* @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; } }