Files
drmaterac.pl/import-product.php

499 lines
18 KiB
PHP

<?php
// https://pacyga.pl/wp-content/uploads/woo-feed/custom/xml/komplet-produktow-3.xml
// Include PrestaShop configuration
$config['update_price'] = false;
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
// Load XML file
$xml = simplexml_load_file('https://cdn.projectpro.pl/drmaterac.pl/produkty-amz.xml') or die("Error: Cannot create object");
// Logowanie czasu wykonania
function logTime($message, $startTime) {
file_put_contents('import_log.txt', $message . ' - Czas: ' . round(microtime(true) - $startTime, 10) . " s\n", FILE_APPEND);
}
$startGlobal = microtime(true);
// Function to find attribute group by name
function findAttributeGroupByName($name) {
$id_lang = Context::getContext()->language->id;
$result = Db::getInstance()->getRow('SELECT `id_attribute_group` FROM `'._DB_PREFIX_.'attribute_group_lang` WHERE `name` = \''.pSQL($name).'\' AND `id_lang` = '.(int)$id_lang);
return $result ? new AttributeGroup($result['id_attribute_group']) : false;
}
// Function to find attribute by name
function findAttributeByName($id_attribute_group, $name) {
$id_lang = Context::getContext()->language->id;
$sql = 'SELECT a.`id_attribute`
FROM `'._DB_PREFIX_.'attribute` a
JOIN `'._DB_PREFIX_.'attribute_lang` al ON a.`id_attribute` = al.`id_attribute`
WHERE al.`name` = \''.pSQL($name).'\' AND al.`id_lang` = '.(int)$id_lang.' AND a.`id_attribute_group` = '.(int)$id_attribute_group;
$result = Db::getInstance()->getRow($sql);
return $result ? new Attribute($result['id_attribute']) : false;
}
// Function to check if a product already has images
function productHasImages($productId) {
$images = Image::getImages(Context::getContext()->language->id, $productId);
return !empty($images);
}
// Function to create attribute if it doesn't exist
function createAttribute($name, $values) {
$attributeGroup = findAttributeGroupByName($name);
if (!$attributeGroup) {
$attributeGroup = new AttributeGroup();
$attributeGroup->name = createMultiLangField($name);
$attributeGroup->public_name = createMultiLangField($name);
$attributeGroup->group_type = 'select';
$attributeGroup->add();
}
foreach ($values as $value) {
$attribute = findAttributeByName($attributeGroup->id, $value);
if (!$attribute) {
$attribute = new Attribute();
$attribute->id_attribute_group = $attributeGroup->id;
$attribute->name = createMultiLangField($value);
$attribute->add();
}
}
return $attributeGroup->id;
}
// Helper function to create a multi-language field
function createMultiLangField($field) {
$languages = Language::getLanguages(false);
$res = [];
foreach ($languages as $lang) {
$res[$lang['id_lang']] = $field;
}
return $res;
}
// Helper function to create a valid link_rewrite
function createLinkRewrite($field) {
$languages = Language::getLanguages(false);
$res = [];
$linkRewrite = Tools::link_rewrite($field); // PrestaShop's function to create valid link_rewrite
foreach ($languages as $lang) {
$res[$lang['id_lang']] = $linkRewrite;
}
return $res;
}
// Function to get category ID from name
function getCategoryId($categoryName) {
$category = Category::searchByName(1, $categoryName); // 1 for default language id
if (!empty($category)) {
return $category['id_category'];
} else {
// Create category if not exists
$category = new Category();
$category->name = createMultiLangField($categoryName);
$category->link_rewrite = createLinkRewrite($categoryName);
$category->id_parent = 2; // Default parent category
$category->add();
return $category->id;
}
}
// Function to log added images
function logAddedImage($productId, $imageUrl) {
$logFile = dirname(__FILE__) . '/image_log.json';
$logData = file_exists($logFile) ? json_decode(file_get_contents($logFile), true) : [];
if (!isset($logData[$productId])) {
$logData[$productId] = [];
}
$logData[$productId][] = $imageUrl;
file_put_contents($logFile, json_encode($logData));
}
// Function to check if an image has been added
function isImageAdded($productId, $imageUrl) {
$logFile = dirname(__FILE__) . '/image_log.json';
if (!file_exists($logFile)) {
return false;
}
$logData = json_decode(file_get_contents($logFile), true);
return isset($logData[$productId]) && in_array($imageUrl, $logData[$productId]);
}
// Function to download image from URL and associate it with a product
function addProductImage($productId, $imageUrl) {
// if (isImageAdded($productId, $imageUrl)) {
// return false; // Skip duplicate images
// }
$image = new Image();
$image->id_product = $productId;
$image->position = Image::getHighestPosition($productId) + 1;
$image->add();
$imagePath = $image->getPathForCreation();
$url = str_replace(' ', '%20', $imageUrl);
if (!copy($url, $imagePath . '.jpg')) {
$image->delete();
return false;
}
$imageTypes = ImageType::getImagesTypes('products');
foreach ($imageTypes as $imageType) {
ImageManager::resize($imagePath . '.jpg', $imagePath . '-' . stripslashes($imageType['name']) . '.jpg', $imageType['width'], $imageType['height']);
}
logAddedImage($productId, $imageUrl);
return $image->id;
}
// Function to set the first image as cover
function setCoverImage($productId) {
$images = Image::getImages(Context::getContext()->language->id, $productId);
if (!empty($images)) {
$firstImage = reset($images);
$firstImageId = $firstImage['id_image'];
Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'image` SET cover = 0 WHERE id_product = '.(int)$productId);
Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'image` SET cover = 1 WHERE id_image = '.(int)$firstImageId);
Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'image_shop` SET cover = 0 WHERE id_product = '.(int)$productId);
Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'image_shop` SET cover = 1 WHERE id_image = '.(int)$firstImageId);
}
}
// Function to find product by reference
function findProductByReference($reference) {
$result = Db::getInstance()->getRow('SELECT `id_product` FROM `'._DB_PREFIX_.'product` WHERE `reference` = \''.pSQL($reference).'\'');
return $result ? new Product($result['id_product']) : false;
}
// Function to find combination by product ID and attribute IDs
function findCombinationByAttributes($id_product, $attributeIds) {
sort($attributeIds);
$sql = 'SELECT c.`id_product_attribute`
FROM `'._DB_PREFIX_.'product_attribute` c
JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON c.`id_product_attribute` = pac.`id_product_attribute`
WHERE c.`id_product` = '.(int)$id_product.'
GROUP BY c.`id_product_attribute`
HAVING SUM(pac.`id_attribute` = '.implode(' OR pac.`id_attribute` = ', array_map('intval', $attributeIds)).') = '.count($attributeIds);
$result = Db::getInstance()->getRow($sql);
return $result ? new Combination($result['id_product_attribute']) : false;
}
// Function to assign manufacturer to product
function assignManufacturerToProduct($productId, $manufacturerId) {
$product = new Product($productId);
$product->id_manufacturer = $manufacturerId;
$product->update();
}
// Function to assign feature to product (without searching for IDs)
function assignFeatureToProduct($productId, $featureId, $featureValueId) {
$existingFeature = Db::getInstance()->getRow(
'SELECT id_feature_product FROM `'._DB_PREFIX_.'feature_product` WHERE `id_product` = '.(int)$productId.' AND `id_feature` = '.(int)$featureId
);
if (!$existingFeature) {
Db::getInstance()->insert('feature_product', [
'id_product' => (int)$productId,
'id_feature' => (int)$featureId,
'id_feature_value' => (int)$featureValueId
]);
} else {
Db::getInstance()->update('feature_product', [
'id_feature_value' => (int)$featureValueId
], 'id_feature_product = '.(int)$existingFeature['id_feature_product']);
}
}
// Function to update additional delivery parameters
function updateDeliveryParameters($productId) {
$product = new Product($productId);
$product->additional_delivery_times = 2;
$product->delivery_in_stock = 'ok. 2-5 dni roboczych';
$product->delivery_out_stock = 'ok. 2-5 dni roboczych';
$product->update();
}
// Function to calculate combination price impact
function calculatePriceImpact($basePrice, $combinationPrice) {
return floatval(str_replace(',', '', $combinationPrice)) - floatval(str_replace(',', '', $basePrice));
}
function addProductToShops($product) {
$shops = [1, 2];
foreach ($shops as $shopId) {
Db::getInstance()->execute('INSERT IGNORE INTO `'._DB_PREFIX_.'product_shop` (`id_product`, `id_shop`, `id_category_default`, `price`, `active`)
VALUES ('.(int)$product->id.', '.(int)$shopId.', 2, '.(float)$product->price.', 1)');
}
}
// Funkcja do przypisania kombinacji do obu sklepów
function addCombinationToShops($combination) {
$shops = [1, 2];
foreach ($shops as $shopId) {
Db::getInstance()->execute('INSERT IGNORE INTO `'._DB_PREFIX_.'product_attribute_shop` (`id_product_attribute`, `id_product`, `id_shop`, `price`)
VALUES ('.(int)$combination->id.', '.(int)$combination->id_product.', '.(int)$shopId.', '.(float)$combination->price.')');
}
}
// Funkcja do dodawania obrazów do obu sklepów
function addImageToShops($imageId, $productId) {
$shops = [1, 2];
foreach ($shops as $shopId) {
Db::getInstance()->execute('INSERT IGNORE INTO `'._DB_PREFIX_.'image_shop` (`id_image`, `id_product`, `id_shop`, `cover`)
VALUES ('.(int)$imageId.', '.(int)$productId.', '.(int)$shopId.', 0)');
}
}
// Function to parse and import product features
function importProductFeatures($productId, $featuresString) {
$features = explode('|', $featuresString);
foreach ($features as $feature) {
list($featureName, $featureValue) = explode('>', $feature, 2);
if ( trim( $featureValue ) == 'Rozmiar' or $featureValue == 'ROZMIAR' or strpos( $featureName, 'filtr rozwijany' ) !== false )
continue;
$featureName = trim($featureName);
$featureValue = trim($featureValue);
$featureId = Db::getInstance()->getValue(
'SELECT id_feature FROM `'._DB_PREFIX_.'feature_lang` WHERE name = "' . pSQL($featureName) . '"'
);
if (!$featureId) {
$feature = new Feature();
$feature->name = createMultiLangField($featureName);
$feature->add();
$featureId = $feature->id;
}
if ( $featureId == 47 or $featureId == 76 )
continue;
$featureValueId = Db::getInstance()->getValue(
'SELECT fv.id_feature_value FROM `'._DB_PREFIX_.'feature_value` fv
JOIN `'._DB_PREFIX_.'feature_value_lang` fvl ON fv.id_feature_value = fvl.id_feature_value
WHERE fvl.value = "' . pSQL($featureValue) . '" AND fv.id_feature = ' . (int)$featureId
);
if (!$featureValueId) {
$featureValueObj = new FeatureValue();
$featureValueObj->id_feature = $featureId;
$featureValueObj->value = createMultiLangField($featureValue);
$featureValueObj->add();
$featureValueId = $featureValueObj->id;
}
Db::getInstance()->insert('feature_product', [
'id_product' => (int)$productId,
'id_feature' => (int)$featureId,
'id_feature_value' => (int)$featureValueId
]);
}
}
// Parse XML and group products by Symbol
$productsBySymbol = [];
foreach ( $xml -> post as $productData )
{
$i = 1;
$product_tmp = (array)$productData;
$Dostępnerozmiaryjeślidotyczy = $product_tmp['Dostępnerozmiaryjeślidotyczy:untitled_3'];
$sku = $product_tmp['KodEAN-13'];
$title = $product_tmp['Nazwaproduktu'] . ' AMZ';
$description = $product_tmp['Długiopis'];
$short_description = $product_tmp['Krótkiopis'];
$price = $product_tmp['CenaBRUTTO'];
$rozmiar = $product_tmp['Dostępnerozmiaryjeślidotyczy:untitled_3'];
$kolor = $product_tmp['Dostępnekoloryjeślidotyczy:untitled_2'];
$images = explode( '|', $product_tmp['ZdjęciaproduktuURL-e'] );
if ( !count( $images ) or ( count( $images ) == 1 and empty( $images[0] ) ) )
{
if ( isset( $product_images[ $symbol ]['images'] ) )
$images = $product_images[ $symbol ]['images'];
}
foreach ( $images as $image )
{
$productData->{'images_' . $i} = $image;
$i++;
}
$symbol = md5( $productData -> Nazwaproduktu );
$productData->sku = $sku;
$productData->title = $title;
$productData->description = $description;
$productData->short_description = $short_description;
$productData->price = $price;
$productData->rozmiar = $rozmiar;
$productData->kolor = $kolor;
if ( !isset( $productsBySymbol[$symbol] ) ) {
$productsBySymbol[$symbol] = [];
}
if ( strpos( $Dostępnerozmiaryjeślidotyczy, '|' ) === false )
$productsBySymbol[$symbol][] = $productData;
else
{
$product_images[ $symbol ]['images'] = $images;
}
}
foreach ($productsBySymbol as $symbol => $products)
{
if ( empty( $products ) ) {
continue;
}
$mainProductData = $products[0];
$mainProduct = findProductByReference((string)$mainProductData->sku);
$productAdded = false;
if ( !$mainProduct )
{
// Create a new product if it doesn't exist
$mainProduct = new Product();
$mainProduct->name = createMultiLangField((string)$mainProductData->title);
$description = (string)$mainProductData->description;
$description = str_replace("\n", "<br>", $description);
$mainProduct->description = createMultiLangField($description);
$mainProduct->price = floatval(str_replace(',','',$mainProductData->price));
$mainProduct->reference = (string)$mainProductData->sku;
$mainProduct->id_category_default = 2;
$mainProduct->link_rewrite = createLinkRewrite((string)$mainProductData->title);
$mainProduct->id_shop_list = [1, 2]; // Przypisanie do sklepów
$mainProduct->add();
addProductToShops($mainProduct);
if (!empty($mainProductData->Cechyproduktu)) {
importProductFeatures($mainProduct->id, (string)$mainProductData->Cechyproduktu);
}
// Ensure the product has combinations enabled
$mainProduct->checkDefaultAttributes();
Product::updateDefaultAttribute($mainProduct->id);
assignFeatureToProduct($mainProduct->id, 41, 2499);
assignManufacturerToProduct($mainProduct->id, 53);
updateDeliveryParameters($mainProduct->id);
$productAdded = true;
}
else
{
if ( $config['update_price'] == true )
{
$mainProduct->price = floatval(str_replace(',','',$mainProductData->price));
$description = (string)$mainProductData->description;
$description = str_replace("\n", "<br>", $description);
$mainProduct->description = createMultiLangField($description);
$mainProduct->update();
}
}
// Ensure the product is saved before adding combinations
if (!$mainProduct->id) {
echo "Failed to create or update main product: " . (string)$mainProductData->title . "\n";
continue;
}
// Ensure the combination set is unique for the product
$addedCombinations = [];
// Add or update combinations for each product in the group
$combinationAdded = false;
foreach ($products as $productData)
{
$attributes = [
'Kolor' => (string)$productData->kolor,
'Rozmiar' => (string)$productData->rozmiar
];
$attributeIds = [];
foreach ($attributes as $name => $value) {
if (!empty($value)) {
$attributeGroupId = createAttribute($name, [$value]);
$attribute = findAttributeByName($attributeGroupId, $value);
if ($attribute) {
$attributeIds[] = $attribute->id;
}
}
}
// Create a unique key for the attribute set
sort($attributeIds);
$key = implode('-', $attributeIds);
// Add or update combination if it is unique
if (!empty($attributeIds))
{
$combination = findCombinationByAttributes($mainProduct->id, $attributeIds);
if (!$combination) {
// Create new combination
$combination = new Combination();
$combination->id_product = $mainProduct->id;
$combination->quantity = 100; // Default quantity, you can adjust this
$combination->reference = (string)$productData->sku;
$combination->price = calculatePriceImpact($mainProductData->price, $productData->price);
$combination->add();
$combination->setAttributes($attributeIds);
$combination->save();
addCombinationToShops($combination);
$combinationAdded = true;
} else {
// Update existing combination quantity if necessary
$combination->quantity = 100; // Update quantity, you can adjust this
$combination->update();
}
// Mark this combination as added
$addedCombinations[$key] = true;
}
if ( $combinationAdded )
{
if ( !productHasImages($mainProduct->id) and !empty($productData->images_2) )
{
for ($i = 1; $i <= 10; $i++) {
$imageUrl = (string)$productData->{'images_' . $i};
if (!empty($imageUrl)) {
$imageId = addProductImage($mainProduct->id, $imageUrl);
if ($imageId) {
addImageToShops($imageId, $mainProduct->id);
}
}
}
}
setCoverImage($mainProduct->id);
break; // Break if a new combination was added
}
}
if ($productAdded || $combinationAdded) {
if ($productAdded) {
echo "<p>Dodałem produkt: " . (string)$mainProductData->title . "</p>";
}
if ($combinationAdded) {
echo "<p>Dodałem kombinację: " . (string)$mainProductData->title . "</p>";
}
break; // Break if a new product or combination was added
}
}
// reload page after 1s if product or combination was added
if ($productAdded || $combinationAdded) {
echo "<script>setTimeout(function(){location.reload();}, 250);</script>";
}
?>