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