Files
interblue.pl/modules/pshowimporter/classes/PShow_Import_Combination.php
2024-10-25 14:16:28 +02:00

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