function importYml($profile) { $db = Database::getInstance()->getConnection(); // Завантаження YML файлу з перевіркою помилок $content = @file_get_contents($profile['source_url']); if (!$content) { throw new Exception("Не вдалося завантажити файл за посиланням. Перевірте URL та доступність файлу."); } // Парсинг XML з перевіркою помилок libxml_use_internal_errors(true); $xml = simplexml_load_string($content); if (!$xml) { $errors = libxml_get_errors(); $error_msg = "Помилка розбору XML: "; foreach ($errors as $error) { $error_msg .= $error->message . " "; } libxml_clear_errors(); throw new Exception($error_msg); } // Починаємо транзакцію $db->beginTransaction(); try { $categories_count = 0; $products_count = 0; // Перевіряємо структуру XML if (!isset($xml->shop)) { throw new Exception("Некоректний формат YML: відсутній елемент shop"); } // Імпорт категорій if (isset($xml->shop->categories->category)) { foreach ($xml->shop->categories->category as $category) { $external_id = (string)$category['id']; $name = (string)$category; $parent_id = isset($category['parentId']) ? (string)$category['parentId'] : null; $stmt = $db->prepare(" INSERT INTO categories (external_id, name, parent_id) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), parent_id = VALUES(parent_id) "); $stmt->execute([$external_id, $name, $parent_id]); $categories_count++; } // Оновлення зв'язків категорій $stmt = $db->prepare(" UPDATE categories c1 JOIN categories c2 ON c1.parent_id = c2.external_id SET c1.parent_id = c2.id WHERE c1.parent_id IS NOT NULL AND c1.parent_id REGEXP '^[0-9]+$' "); $stmt->execute(); } // Імпорт товарів if (isset($xml->shop->offers->offer)) { $total_offers = count($xml->shop->offers->offer); echo "Всього товарів в YML: " . $total_offers . "
"; foreach ($xml->shop->offers->offer as $offer) { try { $external_id = (string)$offer['id']; // Перевіряємо обов'язкові поля if (!isset($offer->name) || empty($offer->name)) { echo "Пропущено товар без назви: " . $external_id . "
"; continue; } if (!isset($offer->price) || empty($offer->price)) { echo "Пропущено товар без ціни: " . $external_id . "
"; continue; } $name = (string)$offer->name; $price = (float)$offer->price; $available = ((string)$offer['available'] === 'true') ? 1 : 0; // Якщо товар недоступний і ми його не імпортуємо if (!$available && !$profile['import_unavailable']) { continue; } // Застосовуємо коефіцієнт ціни $price = $price * ($profile['price_multiplier'] / 100); if ($profile['round_prices']) { $price = round($price); } // Знаходимо категорію $category_id = null; if (isset($offer->categoryId)) { $category_external_id = (string)$offer->categoryId; $stmt = $db->prepare("SELECT id FROM categories WHERE external_id = ?"); $stmt->execute([$category_external_id]); $category = $stmt->fetch(); if ($category) { $category_id = $category['id']; } } // Вставляємо або оновлюємо товар $stmt = $db->prepare(" INSERT INTO products ( external_id, name, price, category_id, available, description, image_url, vendor_code, url ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), price = VALUES(price), category_id = VALUES(category_id), available = VALUES(available), description = VALUES(description), image_url = VALUES(image_url), vendor_code = VALUES(vendor_code), url = VALUES(url) "); $description = isset($offer->description) ? (string)$offer->description : null; $image_url = isset($offer->picture) ? (string)$offer->picture : null; $vendor_code = isset($offer->vendorCode) ? (string)$offer->vendorCode : null; $url = isset($offer->url) ? (string)$offer->url : null; $stmt->execute([ $external_id, $name, $price, $category_id, $available, $description, $image_url, $vendor_code, $url ]); $products_count++; // Кожні 100 товарів зберігаємо транзакцію та починаємо нову if ($products_count % 100 === 0) { $db->commit(); $db->beginTransaction(); echo "Оброблено " . $products_count . " з " . $total_offers . " товарів
"; } } catch (Exception $e) { echo "Помилка при обробці товару: " . $e->getMessage() . "
"; continue; // Продовжуємо з наступним товаром } } } // Підтверджуємо транзакцію $db->commit(); // Логуємо імпорт $stmt = $db->prepare(" INSERT INTO import_logs (profile_id, status, message) VALUES (?, 'success', ?) "); $stmt->execute([ $profile['id'], "Імпортовано {$products_count} товарів і {$categories_count} категорій" ]); return [ 'products' => $products_count, 'categories' => $categories_count ]; } catch (Exception $e) { $db->rollBack(); // Логуємо помилку $stmt = $db->prepare(" INSERT INTO import_logs (profile_id, status, message) VALUES (?, 'error', ?) "); $stmt->execute([$profile['id'], $e->getMessage()]); throw $e; } }