568 lines
22 KiB
PHP
568 lines
22 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
|
|
*/
|
|
class PShow_Import_Combination extends PShow_Import_Object_Abstract
|
|
{
|
|
|
|
public function exists()
|
|
{
|
|
if (($this->getDirectConf('unique_data') == 'reference' || PShow_Config::get('unique_data') == 'reference') &&
|
|
array_key_exists('reference', $this->data)) {
|
|
$key = pSQL($this->data['reference'][0]);
|
|
if (!empty($key)) {
|
|
$q = 'SELECT `id_product_attribute`
|
|
FROM `' . _DB_PREFIX_ . 'product_attribute`
|
|
WHERE `reference` = \'' . $key . '\'';
|
|
|
|
if (is_numeric($this->getDirectConf('pro_id'))) {
|
|
$q .= ' AND `id_product` = ' . (int) $this->getDirectConf('pro_id');
|
|
} elseif (array_key_exists('pro_id', $this->data) && is_numeric($this->data['pro_id'][0])) {
|
|
$q .= ' AND `id_product` = ' . (int) $this->data['pro_id'][0];
|
|
}
|
|
|
|
$rows = Db::getInstance()->executeS($q);
|
|
|
|
$results = array();
|
|
|
|
foreach ($rows as $row) {
|
|
$results[] = new Combination((int) $row['id_product_attribute'], null, PShow_Import::getInstance()->id_shop);
|
|
}
|
|
|
|
if (count($results) > 0) {
|
|
return $results;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($this->getDirectConf('unique_data') == 'ean13' || PShow_Config::get('unique_data') == 'ean13') &&
|
|
array_key_exists('ean13', $this->data)) {
|
|
$key = pSQL($this->data['ean13'][0]);
|
|
if (!empty($key)) {
|
|
$q = 'SELECT `id_product_attribute`
|
|
FROM `' . _DB_PREFIX_ . 'product_attribute`
|
|
WHERE `ean13` = \'' . $key . '\'';
|
|
|
|
if (is_numeric($this->getDirectConf('pro_id'))) {
|
|
$q .= ' AND `id_product` = ' . (int) $this->getDirectConf('pro_id');
|
|
} elseif (array_key_exists('pro_id', $this->data) && is_numeric($this->data['pro_id'][0])) {
|
|
$q .= ' AND `id_product` = ' . (int) $this->data['pro_id'][0];
|
|
}
|
|
|
|
$rows = Db::getInstance()->executeS($q);
|
|
|
|
$results = array();
|
|
|
|
foreach ($rows as $row) {
|
|
$results[] = new Combination((int) $row['id_product_attribute'], null, PShow_Import::getInstance()->id_shop);
|
|
}
|
|
|
|
if (count($results) > 0) {
|
|
return $results;
|
|
}
|
|
}
|
|
}
|
|
|
|
return parent::exists();
|
|
}
|
|
|
|
/**
|
|
* Get new object
|
|
*
|
|
* @param int $id
|
|
* @return int
|
|
*/
|
|
public function getNewObject($id = null)
|
|
{
|
|
$p_exists = false;
|
|
if (array_key_exists('pro_id', $this->data) && ($id_product = (int) reset($this->data['pro_id']))) {
|
|
$q = "SELECT COUNT(`id_product`) "
|
|
. "FROM `" . _DB_PREFIX_ . "product_shop` "
|
|
. "WHERE `id_product` = %d AND `id_shop` = " . (int) PShow_Import::getInstance()->id_shop;
|
|
$p_exists = (int) Db::getInstance()->getValue(sprintf($q, $id_product));
|
|
if (!$p_exists) {
|
|
PShow_Log::addImportLog("product with ID '" . $id_product . "' not found...");
|
|
return 12;
|
|
}
|
|
} elseif (array_key_exists('pro_reference', $this->data) && ($reference = reset($this->data['pro_reference']))) {
|
|
$q = "SELECT COUNT(ps.`id_product`) "
|
|
. "FROM `" . _DB_PREFIX_ . "product_shop` ps "
|
|
. "JOIN `" . _DB_PREFIX_ . "product` p ON (p.`id_product` = ps.`id_product`)"
|
|
. "WHERE p.`reference` = '%s' AND ps.`id_shop` = " . (int) PShow_Import::getInstance()->id_shop;
|
|
$p_exists = (int) Db::getInstance()->getValue(sprintf($q, $reference));
|
|
if (!$p_exists) {
|
|
PShow_Log::addImportLog("product with reference '" . $reference . "' not found...");
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
$combinations = parent::getNewObject($id);
|
|
|
|
if ($this->object_status == self::STATUS_NEW && !is_array($combinations) && !$p_exists) {
|
|
PShow_Log::addImportLog("you cannot import new combination without product reference or id...");
|
|
$combinations->delete();
|
|
return 12;
|
|
}
|
|
|
|
return $combinations;
|
|
}
|
|
|
|
public function import()
|
|
{
|
|
parent::import();
|
|
|
|
$id_product = (int) PShow_Import::$objects[$this->getObjectName()]->id_product;
|
|
$id_combination = (int) PShow_Import::$objects[$this->getObjectName()]->id;
|
|
$this->removeFromAssignedProduct($id_product, $id_combination);
|
|
|
|
$this->setAsDefault(PShow_Import::$objects[$this->getObjectName()]);
|
|
}
|
|
|
|
/**
|
|
* Remove product images and combinations
|
|
*
|
|
* @param integer $id_product
|
|
* @param integer $id_combination
|
|
*/
|
|
protected function removeFromAssignedProduct($id_product, $id_combination)
|
|
{
|
|
$imported_products = array();
|
|
|
|
if (file_exists(_IMPORT_STATUS_PATH_ . 'imported_products')) {
|
|
$imported_products = file_get_contents(_IMPORT_STATUS_PATH_ . 'imported_products');
|
|
$imported_products = explode(',', $imported_products);
|
|
$imported_products = array_map('intval', $imported_products);
|
|
}
|
|
|
|
if (!in_array($id_product, $imported_products)) {
|
|
// if product assigned to combination first time
|
|
|
|
if (PShow_Config::get('remove_product_images')) {
|
|
//remove product images
|
|
PShow_Import_Product::removeProductCombinationImages($id_product, $this->new_images);
|
|
}
|
|
|
|
if (PShow_Config::get('remove_old_combinations')) {
|
|
// remove old combinations
|
|
$combinations = Db::getInstance()->executeS(
|
|
'SELECT `id_product_attribute` FROM `' . _DB_PREFIX_ . 'product_attribute` '
|
|
. 'WHERE `id_product` = ' . (int) $id_product . ' '
|
|
. 'AND `id_product_attribute` <> ' . (int) $id_combination);
|
|
foreach ($combinations as $comb) {
|
|
$temp = new Combination((int) $comb['id_product_attribute']);
|
|
if (Validate::isLoadedObject($temp)) {
|
|
$temp->delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
array_push($imported_products, $id_product);
|
|
}
|
|
|
|
file_put_contents(_IMPORT_STATUS_PATH_ . 'imported_products', implode(',', $imported_products));
|
|
}
|
|
|
|
public function setAsDefault(&$combination)
|
|
{
|
|
$id_product = (int) $combination->id_product;
|
|
|
|
$shop_ids = array((int) PShow_Import::getInstance()->id_shop);
|
|
if (PShow_Addon::exists('Multistore')) {
|
|
$shop_ids = PShow_Import_Object_Multistore::getShopsIdToImport();
|
|
}
|
|
|
|
foreach ($shop_ids as $shop_id) {
|
|
|
|
// get current default combination
|
|
$q = "SELECT `id_product_attribute` "
|
|
. "FROM `" . _DB_PREFIX_ . "product_attribute_shop` "
|
|
. "WHERE `id_product` = " . (int) $id_product . " "
|
|
. "AND `id_shop` = " . (int) $shop_id . " "
|
|
. "AND `default_on` = 1; ";
|
|
$defAttr = Db::getInstance()->getValue($q);
|
|
|
|
if (!$defAttr || array_key_exists('set_as_default', $this->data) && $this->data['set_as_default'][0]) {
|
|
|
|
$q = "UPDATE IGNORE `" . _DB_PREFIX_ . "product_attribute` "
|
|
. "SET `default_on` = null "
|
|
. "WHERE `id_product` = " . (int) $id_product . "; ";
|
|
$q .= "UPDATE IGNORE `" . _DB_PREFIX_ . "product_attribute_shop` "
|
|
. "SET `default_on` = null "
|
|
. "WHERE `id_product` = " . (int) $id_product . " AND `id_shop` = " . (int) $shop_id . "; ";
|
|
Db::getInstance()->execute($q);
|
|
|
|
$combination->default_on = true;
|
|
try {
|
|
$combination->update();
|
|
PShow_Log::addImportLog("default product attribute changed");
|
|
} catch (PrestaShopDatabaseException $e) {
|
|
PShow_Log::addImportLog("unable to change default product combination because: " . $e->getMessage());
|
|
$combination->default_on = false;
|
|
$combination->update();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function _import($key, &$_value)
|
|
{
|
|
if (strpos($key, 'attribute:') !== false) {
|
|
$attribute_group_id = (int) str_replace('attribute:', '', $key);
|
|
$key = 'attribute';
|
|
}
|
|
|
|
$classname = $this->getObjectName();
|
|
$thisObject = &PShow_Import::$objects[$classname];
|
|
|
|
if (!parent::_import($key, $_value)) {
|
|
return false;
|
|
}
|
|
$value = $_value;
|
|
|
|
if (!function_exists('getProductIdByReference')) {
|
|
|
|
/**
|
|
* @param string $value
|
|
* @return integer/null
|
|
*/
|
|
function getProductIdByReference($value)
|
|
{
|
|
if (is_array($value)) {
|
|
$value = reset($value);
|
|
}
|
|
|
|
$q = 'SELECT p.`id_product` '
|
|
. 'FROM `' . _DB_PREFIX_ . 'product` p '
|
|
. 'JOIN `' . _DB_PREFIX_ . 'product_shop` ps ON ( '
|
|
. 'p.`id_product` = ps.`id_product` AND ps.`id_shop` = ' . (int) PShow_Import::getInstance()->id_shop . ' '
|
|
. ') '
|
|
. 'WHERE p.`reference` = \'' . pSQL($value) . '\'; ';
|
|
return Db::getInstance()->getValue($q);
|
|
}
|
|
}
|
|
|
|
$id_product = (int) PShow_Import::$objects[$classname]->id_product;
|
|
|
|
if (!$id_product && isset($this->data['pro_id'])) {
|
|
$temp = $this->data['pro_id'];
|
|
$this->checkAndMergeValues($temp, true);
|
|
$id_product = (int) $temp;
|
|
}
|
|
|
|
if (!$id_product && isset($this->data['pro_reference'])) {
|
|
$temp = $this->data['pro_reference'];
|
|
$this->checkAndMergeValues($temp, true);
|
|
$id_product = (int) getProductIdByReference($temp);
|
|
}
|
|
|
|
if (!$id_product) {
|
|
PShow_Log::addImportLog("product id not found");
|
|
return;
|
|
}
|
|
|
|
PShow_Import::$objects[$classname]->id_product = (int) $id_product;
|
|
|
|
switch ($key) {
|
|
|
|
case 'price':
|
|
|
|
$this->checkAndMergeValues($value, true);
|
|
|
|
$margin = (float) PShow_Config::get('margin_prices');
|
|
|
|
if ($margin == 0) {
|
|
$margin = 1;
|
|
}
|
|
|
|
if (PShow_Config::get('tax_included', 'intval')) {
|
|
$value = $this->nettToGross($value, $this->getVatFromConfig());
|
|
}
|
|
|
|
$thisObject->price = round($value * $margin, 9, PHP_ROUND_HALF_DOWN);
|
|
|
|
break;
|
|
|
|
case 'pro_reference':
|
|
|
|
break;
|
|
|
|
case 'img_url':
|
|
$this->checkAndMergeValues($value);
|
|
|
|
$combination = &PShow_Import::$objects[$classname];
|
|
|
|
$this->new_images = array();
|
|
|
|
foreach ($value as $img_path) {
|
|
|
|
$img_path = urldecode($img_path);
|
|
|
|
// check: image exists
|
|
$headers = PShow_File::get_headers($img_path);
|
|
if (!$headers || !PShow_File::isImage($img_path)) {
|
|
PShow_Log::add(pathinfo(PShow_Import::getInstance()->filepath, PATHINFO_FILENAME) . ".log", "Error in importing image from url: " . $img_path);
|
|
continue;
|
|
}
|
|
|
|
// add image
|
|
$img = new Image();
|
|
|
|
if ($combination->id_product) {
|
|
$img->id_product = (int) $combination->id_product;
|
|
} elseif ($this->data['pro_id'][0]) {
|
|
$img->id_product = (int) $this->data['pro_id'][0];
|
|
} elseif ($this->data['pro_reference']) {
|
|
$id = getProductIdByReference($this->data['pro_reference']);
|
|
if ($id !== null) {
|
|
$img->id_product = (int) $id;
|
|
} else {
|
|
PShow_Log::addImportLog("Unable to import image (product id not found): " . $img_path);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
try {
|
|
$img->save();
|
|
} catch (PrestaShopException $e) {
|
|
PShow_Log::addExceptionLog($e);
|
|
continue;
|
|
}
|
|
|
|
$img->createImgFolder();
|
|
|
|
$images_path = $img->getPathForCreation();
|
|
|
|
PShow_File::import_image(
|
|
$img_path, $images_path, 80, true, pathinfo(PShow_Import::getInstance()->filepath, PATHINFO_FILENAME) . ".log"
|
|
);
|
|
|
|
$this->new_images[] = $img->id;
|
|
}
|
|
$new_images = $this->new_images;
|
|
|
|
$images = $combination->getWsImages();
|
|
foreach ($images as $i) {
|
|
$new_images[] = $i['id'];
|
|
}
|
|
|
|
// set image to this combination
|
|
$combination->setImages($new_images);
|
|
|
|
break;
|
|
|
|
case 'pro_id':
|
|
|
|
break;
|
|
|
|
case 'asm_warehouse_name':
|
|
break;
|
|
|
|
case 'quantity';
|
|
$this->checkAndMergeValues($value, true);
|
|
|
|
if (PShow_Config::isChecked('product_qty_int')) {
|
|
$value = (int) str_replace(array('.', ',', ' '), '', $value);
|
|
} else {
|
|
$value = (int) intval($value);
|
|
}
|
|
|
|
$id_product = (int) PShow_Import::$objects[$classname]->id_product;
|
|
|
|
if (!$id_product && isset($this->data['pro_id'])) {
|
|
$id_product = (int) $this->data['pro_id'];
|
|
}
|
|
|
|
if (!$id_product && isset($this->data['pro_reference'])) {
|
|
$id_product = (int) getProductIdByReference($this->data['pro_reference']);
|
|
}
|
|
|
|
if (!(int) PShow_Import::$objects[$classname]->id) {
|
|
PShow_Log::addImportLog("combination id not found");
|
|
return;
|
|
}
|
|
|
|
if (!(int) $id_product) {
|
|
$id_product = (int) PShow_Import::$objects[$classname]->id_product;
|
|
|
|
if (!$id_product) {
|
|
PShow_Log::addImportLog("product id not found");
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (PShow_Addon::getInstance('ASM') && PShow_Addon::getInstance('ASM')->isEnabled() && PShow_Config::get('asm_enabled', 'boolval')) {
|
|
StockAvailable::setProductDependsOnStock($id_product, 1);
|
|
PShow_Addon::getInstance('ASM')->importCombinationQuantity($id_product, $value);
|
|
} else {
|
|
|
|
$q = "DELETE FROM `" . _DB_PREFIX_ . "stock_available` WHERE `id_product` = 0 ; ";
|
|
Db::getInstance()->execute($q);
|
|
|
|
if (PShow_Config::get('type', 'intval') == 2) {
|
|
$current_qty = StockAvailable::getQuantityAvailableByProduct($id_product, $thisObject->id, PShow_Import::getInstance()->id_shop);
|
|
PShow_Log::addImportLog("current product quantity: " . $current_qty);
|
|
$value = $value + $current_qty;
|
|
PShow_Log::addImportLog("new product quantity: " . $value);
|
|
}
|
|
|
|
PShow_Import::$objects[$classname]->quantity = (int) $value;
|
|
|
|
StockAvailable::setQuantity($id_product, $thisObject->id, $value, PShow_Import::getInstance()->id_shop);
|
|
StockAvailable::setProductDependsOnStock($id_product, 0);
|
|
}
|
|
|
|
StockAvailable::synchronize($id_product, null);
|
|
Product::updateDefaultAttribute($id_product);
|
|
|
|
break;
|
|
|
|
case 'attr_texture':
|
|
|
|
break;
|
|
|
|
case 'attr_color':
|
|
|
|
break;
|
|
|
|
case 'attr_type':
|
|
|
|
break;
|
|
|
|
case 'attr_group':
|
|
|
|
break;
|
|
|
|
case 'attr_value':
|
|
|
|
$attribute_group_name = $this->data['attr_group'][0];
|
|
|
|
if (empty($value) || empty($attribute_group_name)) {
|
|
PShow_Log::addImportLog("combination value not imported because name or value is empty (" . $attribute_group_name . " / " . $value . ")");
|
|
return;
|
|
}
|
|
|
|
$attribute_group_id = (int) Db::getInstance()->getValue('
|
|
SELECT agl.`id_attribute_group`
|
|
FROM `' . _DB_PREFIX_ . 'attribute_group_lang` agl
|
|
WHERE agl.`name` = \'' . $attribute_group_name . '\'
|
|
');
|
|
|
|
if (!$attribute_group_id) {
|
|
try {
|
|
$ag = new AttributeGroup(null, null, PShow_Import::getInstance()->id_shop);
|
|
$this->prepareLangField($ag->name, $attribute_group_name);
|
|
$this->prepareLangField($ag->public_name, $attribute_group_name);
|
|
|
|
if (isset($this->data['attr_type']) && count($this->data['attr_type']) && in_array(strtolower($this->data['attr_type'][0]), array('select', 'radio', 'color')))
|
|
$ag->group_type = $this->data['attr_type'][0];
|
|
else
|
|
$ag->group_type = 'radio';
|
|
|
|
$ag->add();
|
|
$attribute_group_id = $ag->id;
|
|
} catch (PrestaShopException $e) {
|
|
PShow_Log::addExceptionLog($e);
|
|
}
|
|
}
|
|
|
|
if ($attribute_group_id) {
|
|
$this->_import('attribute:' . $attribute_group_id, $value);
|
|
}
|
|
|
|
break;
|
|
|
|
case 'attribute':
|
|
$this->checkAndMergeValues($value, true);
|
|
|
|
if (empty($value))
|
|
return;
|
|
|
|
// find attribute and group by name
|
|
$q = "SELECT al.`id_attribute` "
|
|
. "FROM `" . _DB_PREFIX_ . "attribute` a "
|
|
. "JOIN `" . _DB_PREFIX_ . "attribute_lang` al "
|
|
. "ON (al.`id_attribute` = a.`id_attribute`) "
|
|
. "WHERE a.`id_attribute_group` = " . $attribute_group_id . " "
|
|
. "AND al.`name` = '" . pSQL($value) . "' "
|
|
. "LIMIT 1";
|
|
|
|
$rows = Db::getInstance()->executeS($q);
|
|
|
|
if (!is_array($rows) || count($rows) == 0) {
|
|
// create attribute if not existing
|
|
//$attribute = new Attribute(null, null, PShow_Import::getInstance()->id_shop);
|
|
$attribute = new Attribute(null, null, PShow_Import::getInstance()->id_shop);
|
|
$attribute->id_attribute_group = $attribute_group_id;
|
|
$this->prepareLangField($attribute->name, pSQL($value));
|
|
|
|
// import attribute color
|
|
if (isset($this->data['attr_color']) && count($this->data['attr_color'])) {
|
|
$attribute->color = $this->data['attr_color'][0];
|
|
}
|
|
|
|
try {
|
|
$attribute->save();
|
|
} catch (PrestaShopException $e) {
|
|
PShow_Log::addExceptionLog($e);
|
|
}
|
|
$id_attribute = $attribute->id;
|
|
} else {
|
|
$row = reset($rows);
|
|
$id_attribute = $row['id_attribute'];
|
|
}
|
|
|
|
// import attribute texture
|
|
if (isset($this->data['attr_texture'])) {
|
|
$attr_texture = reset($this->data['attr_texture']);
|
|
$img_path = urldecode($attr_texture);
|
|
|
|
PShow_File::importAttributeTexture($img_path, $id_attribute);
|
|
}
|
|
|
|
$id_product_attribute = PShow_Import::$objects[$classname]->id;
|
|
|
|
// remove old attribute from this combination
|
|
$q = "DELETE "
|
|
. "FROM `" . _DB_PREFIX_ . "product_attribute_combination` "
|
|
. "WHERE `id_product_attribute` = " . (int) $id_product_attribute . " "
|
|
. "AND `id_attribute` IN ( "
|
|
. "SELECT `id_attribute` "
|
|
. "FROM `" . _DB_PREFIX_ . "attribute` "
|
|
. "WHERE `id_attribute_group` = " . $attribute_group_id . ""
|
|
. ")";
|
|
Db::getInstance()->query($q);
|
|
|
|
// insert new attribute to this combination
|
|
$q = "INSERT IGNORE INTO `" . _DB_PREFIX_ . "product_attribute_combination` "
|
|
. "SET `id_attribute` = " . (int) $id_attribute . ", "
|
|
. "`id_product_attribute` = " . (int) $id_product_attribute . ";";
|
|
Db::getInstance()->query($q);
|
|
|
|
break;
|
|
|
|
default:
|
|
$this->checkAndMergeValues($value, true);
|
|
|
|
if (empty($value))
|
|
return;
|
|
|
|
if (array_key_exists('lang', $classname::$definition['fields'][$key])) {
|
|
$this->prepareLangField(PShow_Import::$objects[$classname]->{$key}, $value);
|
|
} else {
|
|
PShow_Import::$objects[$classname]->$key = $value;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|