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