Задать вопрос
@Windramix

Как правильно выгрузить фото и характеристик через API?

Есть снипет (написанный с пару с ии, но до конца не могу разобраться в чём проблема) подскажите в какую сторону копать хз сколько дней бьюсь с этим =(

Покажу тот который отвечает за выгрузку.

Фото скачивается в папку assets/images/products/ в галерею товара добавляется, но в том виде как буд-то не прочитал формат(приложу фото).

689977e5c54b2890963220.png
689977ed24e5d292839869.png

А так же не получается что бы заполнялись характеристики товаров.

Вот так они в json

"attributes": {
            "pa_material": [
                "Алюминий Al6005-T5"
            ],
            "pa_warranty": [
                "10 лет"
            ]
        },

Пытаюсь точечно вытащить от туда из pa_warranty и поместить его в тв поле но что-то не получается.

Полный код --
<?php
// Карта категорий MODX
$categoryIds = [
    'Гибридная бесперебойная система' => 2813,
    'Сетевые станции' => 2814,
    'Автономия' => 2815,
    'Бесперебойник' => 2816,
    
    'Монокристалл' => 2818,
    'Поликристалл' => 2819,
    'Раскладные' => 2820,
    'Гибкие' => 2821,
    
    'MPPT' => 2823,
    'PWM' => 2824,
    
    'Инверторы с подмешиванием' => 2826,
    'ИБП' => 2827,
    'Гибридные' => 2828,
    'Инверторы 220' => 2829,
    'Сетевые инверторы' => 2830,
    'Портативные зарядные станции' => 2831,
    'Зарядные устройства' => 2832,
    
    'LiFePO4' => 2834,
    'GeI' => 2835,
    'AGM' => 2836,
    'CARBON' => 2837,
    
    'Автоматы переменного тока' => 2839,
    'Автоматы постоянного тока' => 2840,
    'Предохранители и диоды' => 2841,
    'Прочее защитное оборудование' => 2842,
    
    'Тепловые насосы' => 2843,
    
    'Кровельные конструкции' => 2845,
    'Степлажи' => 2846,
    'Регулируемые конструкции' => 2848,
    
    'Аккумуляторы' => 2850,
    'Солнечные батареи' => 2851,
    'Контроллеры заряда' => 2852,
    
    'Ветрогенераторы' => 2854,
    
    'Комплектующие' => 2855,
    
    'Провода' => 2856,
    'Коннекторы и перемычки' => 2857,
    'Распределительные щитки' => 2858,
    'Балансиры' => 2859,
    'Мониторинг' => 2860,
    'Прочие комплектующие' => 2861,
    
    'Прочее' => 2862,
];

// Путь и файловый источник
$saveDirRelative = 'assets/images/products/';
$saveDirFull = MODX_BASE_PATH . $saveDirRelative;
$mediaSourceId = 2; // ID источника файлов MS2 Images (проверь в админке)

// Создаем папку для изображений, если не существует
if (!is_dir($saveDirFull)) {
    mkdir($saveDirFull, 0755, true);
}

// Получаем JSON-данные от API
$data = $modx->runSnippet('importProductsFromWP');
$products = json_decode($data, true);

if (!$products || !is_array($products)) {
    return 'Нет товаров для импорта';
}

$count = 0;

foreach ($products as $item) {
    $title = $item['title'] ?? 'Без названия';
    $description = $item['description'] ?? '';
    $price = $item['price'] ?? 0;
    $article = $item['sku'] ?? '';
    $categories = $item['categories'] ?? [];

    if (!$article || empty($categories)) {
        continue;
    }

    // Определяем parent
    $parentId = 0;
    foreach ($categories as $catName) {
        if (isset($categoryIds[$catName])) {
            $parentId = $categoryIds[$catName];
            break;
        }
    }
    if ($parentId === 0) {
        continue;
    }

    // Проверка по артикулу
    $product = $modx->getObject('msProduct', ['article' => $article]);

    if (!$product) {
        // Новый товар
        $product = $modx->newObject('msProduct');
        $product->fromArray([
            'pagetitle' => $title,
            'alias' => $modx->sanitizeString($title),
            'published' => 1,
            'template' => 5, // шаблон
            'parent' => $parentId,
            'class_key' => 'msProduct',
            'article' => $article,
            'price' => $price,
            'content' => $description,
        ]);
        $product->save();
        $count++;
    } else {
        // Обновление
        $product->fromArray([
            'pagetitle' => $title,
            'price' => $price,
            'content' => $description,
            'parent' => $parentId,
        ]);
        $product->save();
    }

    $productId = $product->get('id');

    // Устанавливаем значения TV-полей
    if (!empty($item['attributes'])) {
        $attributes = $item['attributes'];

        if (!empty($attributes['pa_power'][0])) {
            $product->setTVValue('power', $attributes['pa_power'][0]);
        }

        if (!empty($attributes['pa_warranty'][0])) {
            $product->setTVValue('guarantee', $attributes['pa_warranty'][0]);
        }
    }

    // Сохраняем характеристики в msProductData
    if (!empty($item['attributes'])) {
        $dataObject = $product->getOne('Data');
        if ($dataObject) {
            foreach ($item['attributes'] as $key => $value) {
                $optionKey = strtolower(trim($key));
                if (is_array($value)) {
                    $value = implode(', ', $value);
                }
                $dataObject->set($optionKey, $value);
            }
            $dataObject->save();
        }
    }

    // Обработка изображений
    if (!empty($item['images']) && is_array($item['images'])) {
        $rank = 0;
        foreach ($item['images'] as $imgUrl) {
            $imageName = basename(parse_url($imgUrl, PHP_URL_PATH));
            $savePath = $saveDirFull . $imageName;
            $fileRelative = 'assets/images/products/' . $imageName;

            // Скачиваем файл
            if (!file_exists($savePath)) {
                $imageContents = @file_get_contents($imgUrl);
                if ($imageContents !== false) {
                    file_put_contents($savePath, $imageContents);
                }
            }

            // Проверка наличия и добавление в msProductFile
            if (file_exists($savePath)) {
                $existing = $modx->getObject('msProductFile', [
                    'product_id' => $productId,
                    'file' => $fileRelative,
                ]);
                if (!$existing) {
                    $image = $modx->newObject('msProductFile');
                    $image->fromArray([
                        'product_id' => $productId,
                        'source' => $mediaSourceId,
                        'parent' => 0,
                        'name' => $imageName,
                        'file' => $fileRelative,
                        'path' => 'assets/images/products/',
                        'url' => '/assets/images/products/' . $imageName,
                        'rank' => $rank,
                        'createdon' => date('Y-m-d H:i:s'),
                        'active' => 1,
                    ]);
                    $image->save();
                    $rank++;
                }
            }
        }
    }
}

return "Импорт завершен. Создано/обновлено товаров: {$count}";
  • Вопрос задан
  • 31 просмотр
Подписаться 1 Простой 5 комментариев
Пригласить эксперта
Ответы на вопрос 1
DanArst
@DanArst
Гриффиндор в моде при любой погоде!
Ну во первых, article - это не поле объекта класса msProduct, это поле объекта класса msProductData, т.е. должно быть так:
$productData = $modx->getObject('msProductData', ['article' => $article]);
if (!$productData) {
    // Новый товар
    // остальной код
} else {
    $product = $modx->getObject('msProduct', $productData->id);
    //остальной код
}

$productId = $product->get('id');


Во вкладке Галерея отображаются превьюшки, а их у тебя нет по факту. Используй процессоры для таких вещей. Создай временную папку в корне сайта, например tmpimages, скачивай туда картинки и процессором добавляй в галерею товаров. Примерно так:
if (!empty($item['images']) && is_array($item['images'])) {
    foreach ($item['images'] as $imgUrl) {
        $savePath = MODX_BASE_PATH . 'tmpimages/';
        $filename = basename(parse_url($imgUrl, PHP_URL_PATH));
        $destination = $savePath . $filename;
        $imageContent = file_get_contents($imgUrl);
        
        if ($imageContent !== false) {
            file_put_contents($destination, $imageContent);
            $response = $modx->runProcessor('gallery/upload',
    			array('id' => $productId, 'name' => $filename, 'file' => $destination),
    			array('processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/')
    		);
    		if ($response->isError()) {
    		    echo "Ошибка загрузки изображения:" . print_r($response->getAllErrors(), true); //обработка ошибки
    		}
    		unlink($destination);
        }
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы