Files
interblue.pl/modules/import_api/classes/creator.php

646 lines
24 KiB
PHP

<?php
/**
* NOTICE OF LICENSE
* With the purchase or the installation of the software in your application
* you accept the license agreement.
*
* You can not resell and redistribute this file.
*
* @author Dalibor Stojcevski <dal_sto@yahoo.com>
* @copyright 2019 Dalibor Stojcevski
* @license Dalibor Stojcevski
*/
/** Used for validatefields diying without user friendly error or not */
if (!defined('UNFRIENDLY_ERROR')) {
define('UNFRIENDLY_ERROR', false);
}
class Creator
{
private $home_category = 0;
private $id_lang = 1;
public function __construct($file_id)
{
$this->id_lang = (int)Configuration::get('PS_LANG_DEFAULT');
$this->home_category = Configuration::get('PS_HOME_CATEGORY');
//$query_file_settings = Db::getInstance()->executeS("SELECT f.*, fs.mapping FROM ". _DB_PREFIX_ . "ia_files f LEFT JOIN ". _DB_PREFIX_ . "ia_file_settings fs ON(fs.file_id = f.file_id) WHERE f.file_id = '" . $file_id . "' LIMIT 1");
$query_file_settings = Db::getInstance()->executeS("SELECT * FROM ". _DB_PREFIX_ . "ia_file_settings WHERE file_id = '" . $file_id . "' LIMIT 1");
$this->settings = !empty($query_file_settings[0]['settings']) ? json_decode($query_file_settings[0]['settings'], true) : array();
$this->setAttributes();
}
public function getManufacturerId($name)
{
if (is_numeric($name) && Manufacturer::manufacturerExists((int)$name)) {
return (int)$name;
} elseif (is_string($name)) {
if ($manufacturer_id = Manufacturer::getIdByName($name)) {
return (int)$manufacturer_id;
} else {
$manufacturer = new Manufacturer();
$manufacturer->name = $name;
$manufacturer->active = true;
if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&
($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $manufacturer->add()) {
return (int)$manufacturer->id;
//$manufacturer->associateTo($product->id_shop_list);
}
}
}
return 0;
}
public function getCategoryId($value, $parent_id = null)
{
if (!$parent_id) {
$parent_id = $this->home_category;
}
if (is_numeric($value) && Category::categoryExists((int)$value)) {
return (int)$value;
} elseif (is_string($value)) {
$existing_category = Category::searchByName($this->id_lang, $value, true, true);// try and false at end to work with Cache, view Category class function
if ($existing_category) {
return (int)$existing_category['id_category'];
} else {
$category_to_create = new Category();
$category_to_create->id = (int)$value;
$category_to_create->name = Creator::createMultiLangField($value);
$category_to_create->active = 1;
$category_to_create->id_parent = $parent_id; // Default parent is home for unknown category to create
$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$this->id_lang]);
$category_to_create->link_rewrite = Creator::createMultiLangField($category_link_rewrite);
if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&
($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add()) {
return (int)$category_to_create->id;
}
}
}
return 0;
}
protected static function createMultiLangField($field)
{
$res = array();
foreach (Language::getIDs(false) as $id_lang) {
$res[$id_lang] = $field;
}
return $res;
}
public function addImageToProduct($url, $id, $is_cover = false){
if (!empty($url)) {
$url = str_replace(' ', '%20', $url);
$image = new Image();
$image->id_product = (int)$id;
$image->position = Image::getHighestPosition($id) + 1;
$image->cover = $is_cover;
// file_exists doesn't work with HTTP protocol
if (($field_error = $image->validateFields(UNFRIENDLY_ERROR, true)) === true &&
($lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $image->add()) {
// associate image to selected shops
$shops = Shop::getContextListShopID();
$image->associateTo($shops);
if (!Creator::copyImg($id, $image->id, $url, 'products', true)) {
$image->delete();
}
}
}
}
public function addFeaturesToProduct($features, $id) {
foreach ($features as $single_feature) {
if (empty($single_feature)) {
continue;
}
$feature_name = $single_feature['feature'];
$feature_value = $single_feature['feature_value'];
$position = false;
$custom = false;
$id_lang = $this->id_lang;
$id_product = (int)$id;
if (!empty($feature_name) && !empty($feature_value)) {
$id_feature = (int)Feature::addFeatureImport($feature_name, $position);
$id_feature_value = (int)FeatureValue::addFeatureValueImport($id_feature, $feature_value, $id_product, $id_lang, $custom);
Product::addFeatureProductImport($id, $id_feature, $id_feature_value);
}
}
}
public function addAttributesToProduct($attributes_array, $id, $attribute_details = array()) {
$product = new Product($id);
$this->settings['combination_price_multiplier'];
$attributes_to_add = array();
$attributes_ids = array();
foreach ($attributes_array as $key => $attributes_full) {
foreach ($attributes_full as $attribute_pair) {
if (empty($attribute_pair['attribute_value'])) {
continue;
}
if ($id_attribute = $this->getAttributeId($attribute_pair)) {
$attributes_to_add[$key][] = $id_attribute;
if (isset($attribute_details)) {
$attributes_ids[$id_attribute] = $attribute_pair['attribute_value'];
}
}
}
}
$combinations = $this->generateCombinations($attributes_to_add);
$attribute_details_par = array('price', 'ean', 'quantity', 'weight');
if (isset($attribute_details)) {
foreach ($attribute_details_par as $parameter) {
foreach ($combinations as $key => $combination) {
foreach($combination as $c) {
if (isset($attribute_details[$parameter][$attributes_ids[$c]])) {
$combination_detais[$key][$parameter] = $attribute_details[$parameter][$attributes_ids[$c]];
}
}
}
}
}
foreach ($combinations as $key => $combination) {
$implode_sql = array();
if (!$combination) continue;
$combination_price = 0;
if (isset($combination_detais[$key]['price'])) {
$combination_price = (float)$combination_detais[$key]['price'];
if (!empty($this->settings['combination_price_multiplier'])) {
$combination_price *= (float)$this->settings['combination_price_multiplier'];
}
if (empty($this->settings['add_combination_price'])) {
$combination_price -= $product->price;
}
if ($combination_price < 0) {
$combination_price = 0;
}
}
$combination_ean = (!empty($combination_detais[$key]['ean']) && Validate::isEan13($combination_detais[$key]['ean'])) ? $combination_detais[$key]['ean'] : '';
$id_product_attribute = $product->productAttributeExists($combination, false, null, false, true); // Last 'true' is to return id
if (!$id_product_attribute) {
$combination_weight = isset($combination_detais[$key]['weight']) ? (float)$combination_detais[$key]['weight'] : 0;
$combination_quantity = isset($combination_detais[$key]['quantity']) ? (int)$combination_detais[$key]['quantity'] : (int)$product->quantity;
$id_product_attribute = $product->addCombinationEntity(
(float) 0,
$combination_price,
$combination_weight,
0,
(Configuration::get('PS_USE_ECOTAX') ? (float) $product->ecotax : 0),
$combination_quantity,
null,'', 0,
$combination_ean,
null);
foreach ($combination as $id_attribute ) {
Db::getInstance()->execute('
INSERT IGNORE INTO ' . _DB_PREFIX_ . 'product_attribute_combination (id_attribute, id_product_attribute)
VALUES (' . (int) $id_attribute . ',' . (int) $id_product_attribute . ')', false);
}
} else {
if (isset($attribute_details)) {
if(isset($combination_detais[$key]['price'])) {
$implode_sql['price'] = 'price = ' . (float)$combination_price;
}
if(isset($combination_detais[$key]['weight'])) {
$implode_sql['weight'] = 'weight = ' . (float)$combination_detais[$key]['weight'];
}
if(isset($combination_detais[$key]['ean'])) {
$implode_sql['ean13'] = 'ean13 = ' . pSQL($combination_ean);
}
}
}
if(isset($combination_detais[$key]['quantity'])) {
$implode_sql['quantity'] = 'quantity = ' . (int)$combination_detais[$key]['quantity'];
StockAvailable::setQuantity($id, $id_product_attribute, (int)$combination_detais[$key]['quantity']);
}
if ($implode_sql) {
Db::getInstance()->execute('
UPDATE ' . _DB_PREFIX_ . 'product_attribute SET ' . implode(', ', $implode_sql) . ' WHERE id_product_attribute = ' . (int)$id_product_attribute);
unset($implode_sql['ean13']);
unset($implode_sql['quantity']);
Db::getInstance()->execute('
UPDATE ' . _DB_PREFIX_ . 'product_attribute_shop SET ' . implode(', ', $implode_sql) . ' WHERE id_product_attribute = ' . (int)$id_product_attribute);
}
}
}
/**
* copyImg copy an image located in $url and save it in a path
* according to $entity->$id_entity .
* $id_image is used if we need to add a watermark
*
* @param int $id_entity id of product or category (set in entity)
* @param int $id_image (default null) id of the image if watermark enabled.
* @param string $url path or url to use
* @param string $entity 'products' or 'categories'
* @param bool $regenerate
* @return bool
*/
protected static function copyImg($id_entity, $id_image = null, $url, $entity = 'products', $regenerate = true)
{
$tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');
$watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));
switch ($entity) {
default:
case 'products':
$image_obj = new Image($id_image);
$path = $image_obj->getPathForCreation();
break;
case 'categories':
$path = _PS_CAT_IMG_DIR_.(int)$id_entity;
break;
case 'manufacturers':
$path = _PS_MANU_IMG_DIR_.(int)$id_entity;
break;
case 'suppliers':
$path = _PS_SUPP_IMG_DIR_.(int)$id_entity;
break;
}
$url = urldecode(trim($url));
$parced_url = parse_url($url);
if (isset($parced_url['path'])) {
$uri = ltrim($parced_url['path'], '/');
$parts = explode('/', $uri);
foreach ($parts as &$part) {
$part = rawurlencode($part);
}
unset($part);
$parced_url['path'] = '/'.implode('/', $parts);
}
if (isset($parced_url['query'])) {
$query_parts = array();
parse_str($parced_url['query'], $query_parts);
$parced_url['query'] = http_build_query($query_parts);
}
if (!function_exists('http_build_url')) {
require_once(_PS_TOOL_DIR_.'http_build_url/http_build_url.php');
}
$url = http_build_url('', $parced_url);
$orig_tmpfile = $tmpfile;
if (Tools::copy($url, $tmpfile)) {
// Evaluate the memory required to resize the image: if it's too much, you can't resize it.
if (!ImageManager::checkImageMemoryLimit($tmpfile)) {
@unlink($tmpfile);
return false;
}
if (!ImageManager::isRealImage($tmpfile)) {
@unlink($tmpfile);
return false;
}
$tgt_width = $tgt_height = 0;
$src_width = $src_height = 0;
$error = 0;
ImageManager::resize($tmpfile, $path.'.jpg', null, null, 'jpg', false, $error, $tgt_width, $tgt_height, 5,
$src_width, $src_height);
$images_types = ImageType::getImagesTypes($entity, true);
if ($regenerate) {
$previous_path = null;
$path_infos = array();
$path_infos[] = array($tgt_width, $tgt_height, $path.'.jpg');
foreach ($images_types as $image_type) {
$tmpfile = self::get_best_path($image_type['width'], $image_type['height'], $path_infos);
if (ImageManager::resize($tmpfile, $path.'-'.stripslashes($image_type['name']).'.jpg', $image_type['width'],
$image_type['height'], 'jpg', false, $error, $tgt_width, $tgt_height, 5,
$src_width, $src_height)) {
// the last image should not be added in the candidate list if it's bigger than the original image
if ($tgt_width <= $src_width && $tgt_height <= $src_height) {
$path_infos[] = array($tgt_width, $tgt_height, $path.'-'.stripslashes($image_type['name']).'.jpg');
}
if ($entity == 'products') {
if (is_file(_PS_TMP_IMG_DIR_.'product_mini_'.(int)$id_entity.'.jpg')) {
unlink(_PS_TMP_IMG_DIR_.'product_mini_'.(int)$id_entity.'.jpg');
}
if (is_file(_PS_TMP_IMG_DIR_.'product_mini_'.(int)$id_entity.'_'.(int)Context::getContext()->shop->id.'.jpg')) {
unlink(_PS_TMP_IMG_DIR_.'product_mini_'.(int)$id_entity.'_'.(int)Context::getContext()->shop->id.'.jpg');
}
}
}
if (in_array($image_type['id_image_type'], $watermark_types)) {
Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_entity));
}
}
}
} else {
@unlink($orig_tmpfile);
return false;
}
unlink($orig_tmpfile);
return true;
}
private static function get_best_path($tgt_width, $tgt_height, $path_infos)
{
$path_infos = array_reverse($path_infos);
$path = '';
foreach ($path_infos as $path_info) {
list($width, $height, $path) = $path_info;
if ($width >= $tgt_width && $height >= $tgt_height) {
return $path;
}
}
return $path;
}
public function getProductId($query, $table, $identifier = 'name')
{
$sql = new DbQuery();
$sql->select('p.`id_product`, p.`ean13`, p.`upc`, p.`active`, p.`reference`');
$sql->from('product', 'p');
if ($identifier == 'name') {
$sql->join(Shop::addSqlAssociation('product', 'p'));
$sql->leftJoin('product_lang', 'pl', '
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('pl')
);
$where = 'pl.`name` = \''.pSQL($query).'\'';
} else {
$where = 'p.`' . $identifier . '` = \''.pSQL($query).'\'';
}
$sql->where($where);
$sql->limit(1);
$result = Db::getInstance()->executeS($sql);
if(!empty($result[0]['id_product'])){
return $result[0]['id_product'];
}
return 0;
}
public function editProduct($product_id, $original_product)
{
$simple_fields = array('price', 'wholesale_price', 'additional_shipping_cost', 'ean13', 'ups', 'condition', 'width', 'height', 'depth', 'weight', 'active', 'minimal_quantity');
$product = new Product($product_id);
if ($product->name == null) {
return $product;
}
if (!empty($this->settings['update_manufacturer'])) {
if (!empty($original_product['brand'])) {
$product->id_manufacturer = $this->getManufacturerId($original_product['brand']);
} else {
$product->id_manufacturer = $this->settings['default_manufacturer_id'];
}
}
foreach ($simple_fields as $field) {
if (!empty($this->settings['update_' . $field]) && isset($original_product[$field])) {
$product->$field = $original_product[$field];
}
}
if (isset($this->settings['update_id_tax_rules_group']) && $this->settings['id_tax_rules_group'] != -1) {
$product->id_tax_rules_group = $this->settings['id_tax_rules_group'];
}
foreach (Language::getLanguages(false) as $lang) {
if (!empty($this->settings['update_name'])) {
$original_product['name'] = htmlspecialchars_decode($original_product['name']);
$original_product['name'] = str_replace(['>','<', '=', ';', '{', '}', '#'], ' ', $original_product['name']);
$product->name[$lang['id_lang']] = $original_product['name'];
$product->link_rewrite[$lang['id_lang']] = Tools::link_rewrite($original_product['name']);
$product->meta_keywords[$lang['id_lang']] = str_replace(' ', ',', $original_product['name']);
}
if (!empty($this->settings['update_description'])) {
$original_product['description'] = nl2br($original_product['description']);
$original_product['description'] = htmlspecialchars_decode(htmlspecialchars_decode($original_product['description'], ENT_COMPAT));
$product->description_long[$lang['id_lang']] = $original_product['description'];
$product->description[$lang['id_lang']] = $original_product['description'];
}
if (!empty($original_product['short_description']) && !empty($this->settings['update_short_description'])) {
$product->description_short[$lang['id_lang']] = $original_product['short_description'];
}
}
$product -> additional_delivery_times = 2;
$product->delivery_in_stock[7] = '1-5 dni roboczych';
//$product->active = isset($original_product['active']) ? (int)$original_product['active'] : 1;;
$product->save();
if (!empty($this->settings['update_quantity'])) {
StockAvailable::setQuantity((int)$product_id, 0, $original_product['quantity']);
}
/*if (!empty($this->settings['update_images']) && !empty($original_product['images']) && 0) {
foreach ($original_product['images'] as $image_url) {
$this->addImageToProduct($image_url, $product->id);
}
}*/
if (!empty($this->settings['update_cover']) && !empty($original_product['cover'])) {
$this->addImageToProduct($original_product['cover'], $product->id, true);
}
if ( $original_product['feature'] and $original_product['feature_value'] ) {
$original_product['features'] = array(
array(
'feature' => $original_product['feature'],
'feature_value' => $original_product['feature_value']
)
);
}
if (!empty($this->settings['update_features']) && !empty($original_product['features'])) {
$this->addFeaturesToProduct($original_product['features'], $product->id);
}
if (!empty($this->settings['update_attributes']) && !empty($original_product['attributes'])) {
$attribute_details = !empty($original_product['attribute_details']) ? $original_product['attribute_details'] : array();
$this->addAttributesToProduct($original_product['attributes'], $product->id, $attribute_details);
}
return $product;
}
public function processMissing($file_id, $queue_id) {
$sql = "SELECT * FROM " . _DB_PREFIX_ . "ia_products WHERE shop = 'default' AND file_id = " . (int)$file_id . " AND queue_id != " . (int)$queue_id;
//$sql .= " LIMIT 20";
if (!empty($this->settings['not_existing']) && $products = Db::getInstance()->executeS($sql)) {
if ($this->settings['not_existing'] == 1) {
foreach($products as $product) {
StockAvailable::setQuantity((int)$product['product_id'], 0, 0);
}
} elseif ($this->settings['not_existing'] == 2) {
foreach($products as $product) {
$productObject = new Product($product['product_id']);
if ($productObject->name) {
$productObject->active = 0;
$productObject->save();
}
}
} elseif ($this->settings['not_existing'] == 3) {
foreach($products as $product) {
$productObject = new Product($product['product_id']);
if ($productObject->name) {
$productObject->delete();
}
Db::getInstance()->execute("DELETE FROM " . _DB_PREFIX_ . "ia_products WHERE product_id = '" . (int)$product['product_id'] . "'");
}
}
}
Db::getInstance()->execute("UPDATE " . _DB_PREFIX_ . "ia_queues SET source = 'admin', status = '4', date_processed = '" . time() . "' WHERE queue_id = '" . (int)$queue_id . "'");
}
public function setAttributes() {
$default_language = $this->id_lang;
$this->groups = array();
foreach (AttributeGroup::getAttributesGroups($default_language) as $group) {
$this->groups[$group['name']] = (int) $group['id_attribute_group'];
}
$this->attributes = array();
foreach (Attribute::getAttributes($default_language) as $attribute) {
$this->attributes[$attribute['attribute_group'] . '_' . $attribute['name']] = (int) $attribute['id_attribute'];
}
}
function getAttributeGroupId($name) {
$tab_group = explode(':', $name);
$group = trim($tab_group[0]);
if (isset($this->groups[$group])) {
return $this->groups[$group];
}
if (!isset($tab_group[1])) {
$type = 'select';
} else {
$type = trim($tab_group[1]);
}
$obj = new AttributeGroup();
$obj->is_color_group = false;
$obj->group_type = pSQL($type);
$obj->name[$this->id_lang] = $group;
$obj->public_name[$this->id_lang] = $group;
//$obj->position = (!$position) ? AttributeGroup::getHigherPosition() + 1 : $position;
$obj->add();
$this->groups[$group] = $obj->id;
return $obj->id;
}
function getAttributeId($pair) {
$name = $pair['attribute_value'];
$group = $pair['attribute'];
if (isset($this->attributes[$group .'_'. $name])) {
return $this->attributes[$group .'_'. $name];
}
$id_attribute_group = $this->getAttributeGroupId($group);
$obj = new Attribute();
$obj->id_attribute_group = $id_attribute_group;
$obj->name[$this->id_lang] = str_replace('\n', '', str_replace('\r', '', $name));
$obj->add();
$this->attributes[$group .'_'. $name] = $obj->id;
return $obj->id;
}
function generateCombinations($attributes_to_add) {
$i = 0;
$combinations = array();
// 3 options
if (count($attributes_to_add) == 3) {
foreach ($attributes_to_add[1] as $attr_1) {
$temp_1 = isset($combinations[$i]) ? $combinations[$i] : array();
$combinations[$i][] = $attr_1;
foreach ($attributes_to_add[2] as $attr_2) {
$temp_2 = $combinations[$i];
$combinations[$i][] = $attr_2;
foreach ($attributes_to_add[3] as $attr_3) {
$temp_3 = $combinations[$i];
$combinations[$i][] = $attr_3;
$i++;
$combinations[$i] = $temp_3;
}
$combinations[$i] = $temp_2;
}
$combinations[$i] = $temp_1;
}
} elseif (count($attributes_to_add) == 2 && isset($attributes_to_add[1])) {
foreach ($attributes_to_add[1] as $attr_1) {
$temp_1 = isset($combinations[$i]) ? $combinations[$i] : array();
$combinations[$i][] = $attr_1;
foreach ($attributes_to_add[2] as $attr_2) {
$temp_2 = $combinations[$i];
$combinations[$i][] = $attr_2;
$i++;
$combinations[$i] = $temp_2;
}
$combinations[$i] = $temp_1;
}
} elseif (count($attributes_to_add) == 1 && isset($attributes_to_add[1])) {
foreach ($attributes_to_add[1] as $attr_1) {
//$temp_0 = isset($combinations[$i]) ? $combinations[$i] : array();
$combinations[$i][] = $attr_1;
$i++;
//$combinations[$i] = $temp_0;
}
}
return $combinations;
}
}