Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

YML Выгрузка дополнительных фотографий


Recommended Posts

Здравствуйте, есть бесплатный плагин для выгрузки YML но он выгружает только 1 основную фотографию. Не подскажите как правильно сделать выгрузку еще и доп. фотографии в YML файл.
Вот код контролера, место с выводом картинки.

 

 $data['picture'] = $this->model_tool_image->resize($product['image'], 600, 600);

 

<?php
/**
 * Класс YML экспорта
 * YML (Yandex Market Language) - стандарт, разработанный "Яндексом"
 * для принятия и публикации информации в базе данных Яндекс.Маркет
 * YML основан на стандарте XML (Extensible Markup Language)
 * описание формата YML http://partner.market.yandex.ru/legal/tt/
 */
class ControllerFeedYandexMarket extends Controller {
    private $shop = array();
    private $currencies = array();
    private $categories = array();
    private $offers = array();
    private $from_charset = 'utf-8';
    private $eol = "\n";

    public function index() {
        if ($this->config->get('yandex_market_status')) {

            if (!($allowed_categories = $this->config->get('yandex_market_categories'))) exit();

            $this->load->model('export/yandex_market');
            $this->load->model('localisation/currency');
            $this->load->model('tool/image');

            // Магазин
            $this->setShop('name', $this->config->get('yandex_market_shopname'));
            $this->setShop('company', $this->config->get('yandex_market_company'));
            $this->setShop('url', HTTP_SERVER);
            $this->setShop('phone', $this->config->get('config_telephone'));
            $this->setShop('platform', 'ocStore');
            $this->setShop('version', VERSION);

            // Валюты
            // TODO: Добавить возможность настраивать проценты в админке.
            $offers_currency = $this->config->get('yandex_market_currency');
            if (!$this->currency->has($offers_currency)) exit();

            $decimal_place = $this->currency->getDecimalPlace($offers_currency);

            $shop_currency = $this->config->get('config_currency');

            $this->setCurrency($offers_currency, 1);

            $currencies = $this->model_localisation_currency->getCurrencies();

            $supported_currencies = array('RUR', 'RUB', 'USD', 'BYR', 'KZT', 'EUR', 'UAH');

            $currencies = array_intersect_key($currencies, array_flip($supported_currencies));

            foreach ($currencies as $currency) {
                if ($currency['code'] != $offers_currency && $currency['status'] == 1) {
                    $this->setCurrency($currency['code'], number_format(1/$this->currency->convert($currency['value'], $offers_currency, $shop_currency), 4, '.', ''));
                }
            }

            // Категории
            $categories = $this->model_export_yandex_market->getCategory();

            foreach ($categories as $category) {
                $this->setCategory($category['name'], $category['category_id'], $category['parent_id']);
            }

            // Товарные предложения
            $in_stock_id = $this->config->get('yandex_market_in_stock'); // id статуса товара "В наличии"
            $out_of_stock_id = $this->config->get('yandex_market_out_of_stock'); // id статуса товара "Нет на складе"
            $vendor_required = false; // true - только товары у которых задан производитель, необходимо для 'vendor.model'
            $products = $this->model_export_yandex_market->getProduct($allowed_categories, $out_of_stock_id, $vendor_required);

            foreach ($products as $product) {
                $data = array();

                // Атрибуты товарного предложения
                $data['id'] = $product['product_id'];
//                $data['type'] = 'vendor.model';
                $data['available'] = ($product['quantity'] > 0 || $product['stock_status_id'] == $in_stock_id);
//                $data['bid'] = 10;
//                $data['cbid'] = 15;

                // Параметры товарного предложения
                $data['url'] = $this->url->link('product/product', 'path=' . $this->getPath($product['category_id']) . '&product_id=' . $product['product_id']);
                $data['price'] = number_format($this->currency->convert($this->tax->calculate($product['price'], $product['tax_class_id']), $shop_currency, $offers_currency), $decimal_place, '.', '');
                $data['currencyId'] = $offers_currency;
                $data['categoryId'] = $product['category_id'];
                $data['delivery'] = 'true';
//                $data['local_delivery_cost'] = 100;
                $data['name'] = $product['name'];
                $data['vendor'] = $product['manufacturer'];
                $data['vendorCode'] = $product['model'];
                $data['model'] = $product['name'];
                $data['description'] = $product['description'];
//                $data['manufacturer_warranty'] = 'true';
//                $data['barcode'] = $product['sku'];
                if ($product['image']) {
                    $data['picture'] = $this->model_tool_image->resize($product['image'], 600, 600);
                }
/*
                // пример структуры массива для вывода параметров
                $data['param'] = array(
                    array(
                        'name'=>'Wi-Fi',
                        'value'=>'есть'
                    ), array(
                        'name'=>'Размер экрана',
                        'unit'=>'дюйм',
                        'value'=>'20'
                    ), array(
                        'name'=>'Вес',
                        'unit'=>'кг',
                        'value'=>'4.6'
                    )
                );
*/
                $this->setOffer($data);
            }

            $this->categories = array_filter($this->categories, array($this, "filterCategory"));

            $this->response->addHeader('Content-Type: application/xml');
            $this->response->setOutput($this->getYml());
        }
    }

    /**
     * Методы формирования YML
     */

    /**
     * Формирование массива для элемента shop описывающего магазин
     *
     * @param string $name - Название элемента
     * @param string $value - Значение элемента
     */
    private function setShop($name, $value) {
        $allowed = array('name', 'company', 'url', 'phone', 'platform', 'version', 'agency', 'email');
        if (in_array($name, $allowed)) {
            $this->shop[$name] = $this->prepareField($value);
        }
    }

    /**
     * Валюты
     *
     * @param string $id - код валюты (RUR, RUB, USD, BYR, KZT, EUR, UAH)
     * @param float|string $rate - курс этой валюты к валюте, взятой за единицу.
     *    Параметр rate может иметь так же следующие значения:
     *        CBRF - курс по Центральному банку РФ.
     *        NBU - курс по Национальному банку Украины.
     *        NBK - курс по Национальному банку Казахстана.
     *        СВ - курс по банку той страны, к которой относится интернет-магазин
     *         по Своему региону, указанному в Партнерском интерфейсе Яндекс.Маркета.
     * @param float $plus - используется только в случае rate = CBRF, NBU, NBK или СВ
     *        и означает на сколько увеличить курс в процентах от курса выбранного банка
     * @return bool
     */
    private function setCurrency($id, $rate = 'CBRF', $plus = 0) {
        $allow_id = array('RUR', 'RUB', 'USD', 'BYR', 'KZT', 'EUR', 'UAH');
        if (!in_array($id, $allow_id)) {
            return false;
        }
        $allow_rate = array('CBRF', 'NBU', 'NBK', 'CB');
        if (in_array($rate, $allow_rate)) {
            $plus = str_replace(',', '.', $plus);
            if (is_numeric($plus) && $plus > 0) {
                $this->currencies[] = array(
                    'id'=>$this->prepareField(strtoupper($id)),
                    'rate'=>$rate,
                    'plus'=>(float)$plus
                );
            } else {
                $this->currencies[] = array(
                    'id'=>$this->prepareField(strtoupper($id)),
                    'rate'=>$rate
                );
            }
        } else {
            $rate = str_replace(',', '.', $rate);
            if (!(is_numeric($rate) && $rate > 0)) {
                return false;
            }
            $this->currencies[] = array(
                'id'=>$this->prepareField(strtoupper($id)),
                'rate'=>(float)$rate
            );
        }

        return true;
    }

    /**
     * Категории товаров
     *
     * @param string $name - название рубрики
     * @param int $id - id рубрики
     * @param int $parent_id - id родительской рубрики
     * @return bool
     */
    private function setCategory($name, $id, $parent_id = 0) {
        $id = (int)$id;
        if ($id < 1 || trim($name) == '') {
            return false;
        }
        if ((int)$parent_id > 0) {
            $this->categories[$id] = array(
                'id'=>$id,
                'parentId'=>(int)$parent_id,
                'name'=>$this->prepareField($name)
            );
        } else {
            $this->categories[$id] = array(
                'id'=>$id,
                'name'=>$this->prepareField($name)
            );
        }

        return true;
    }

    /**
     * Товарные предложения
     *
     * @param array $data - массив параметров товарного предложения
     */
    private function setOffer($data) {
        $offer = array();

        $attributes = array('id', 'type', 'available', 'bid', 'cbid', 'param');
        $attributes = array_intersect_key($data, array_flip($attributes));

        foreach ($attributes as $key => $value) {
            switch ($key)
            {
                case 'id':
                case 'bid':
                case 'cbid':
                    $value = (int)$value;
                    if ($value > 0) {
                        $offer[$key] = $value;
                    }
                    break;

                case 'type':
                    if (in_array($value, array('vendor.model', 'book', 'audiobook', 'artist.title', 'tour', 'ticket', 'event-ticket'))) {
                        $offer['type'] = $value;
                    }
                    break;

                case 'available':
                    $offer['available'] = ($value ? 'true' : 'false');
                    break;

                case 'param':
                    if (is_array($value)) {
                        $offer['param'] = $value;
                    }
                    break;

                default:
                    break;
            }
        }

        $type = isset($offer['type']) ? $offer['type'] : '';

        $allowed_tags = array('url'=>0, 'buyurl'=>0, 'price'=>1, 'wprice'=>0, 'currencyId'=>1, 'xCategory'=>0, 'categoryId'=>1, 'picture'=>0, 'store'=>0, 'pickup'=>0, 'delivery'=>0, 'deliveryIncluded'=>0, 'local_delivery_cost'=>0, 'orderingTime'=>0);

        switch ($type) {
            case 'vendor.model':
                $allowed_tags = array_merge($allowed_tags, array('typePrefix'=>0, 'vendor'=>1, 'vendorCode'=>0, 'model'=>1, 'provider'=>0, 'tarifplan'=>0));
                break;

            case 'book':
                $allowed_tags = array_merge($allowed_tags, array('author'=>0, 'name'=>1, 'publisher'=>0, 'series'=>0, 'year'=>0, 'ISBN'=>0, 'volume'=>0, 'part'=>0, 'language'=>0, 'binding'=>0, 'page_extent'=>0, 'table_of_contents'=>0));
                break;

            case 'audiobook':
                $allowed_tags = array_merge($allowed_tags, array('author'=>0, 'name'=>1, 'publisher'=>0, 'series'=>0, 'year'=>0, 'ISBN'=>0, 'volume'=>0, 'part'=>0, 'language'=>0, 'table_of_contents'=>0, 'performed_by'=>0, 'performance_type'=>0, 'storage'=>0, 'format'=>0, 'recording_length'=>0));
                break;

            case 'artist.title':
                $allowed_tags = array_merge($allowed_tags, array('artist'=>0, 'title'=>1, 'year'=>0, 'media'=>0, 'starring'=>0, 'director'=>0, 'originalName'=>0, 'country'=>0));
                break;

            case 'tour':
                $allowed_tags = array_merge($allowed_tags, array('worldRegion'=>0, 'country'=>0, 'region'=>0, 'days'=>1, 'dataTour'=>0, 'name'=>1, 'hotel_stars'=>0, 'room'=>0, 'meal'=>0, 'included'=>1, 'transport'=>1, 'price_min'=>0, 'price_max'=>0, 'options'=>0));
                break;

            case 'event-ticket':
                $allowed_tags = array_merge($allowed_tags, array('name'=>1, 'place'=>1, 'hall'=>0, 'hall_part'=>0, 'date'=>1, 'is_premiere'=>0, 'is_kids'=>0));
                break;

            default:
                $allowed_tags = array_merge($allowed_tags, array('name'=>1, 'vendor'=>0, 'vendorCode'=>0));
                break;
        }

        $allowed_tags = array_merge($allowed_tags, array('aliases'=>0, 'additional'=>0, 'description'=>0, 'sales_notes'=>0, 'promo'=>0, 'manufacturer_warranty'=>0, 'country_of_origin'=>0, 'downloadable'=>0, 'adult'=>0, 'barcode'=>0));

        $required_tags = array_filter($allowed_tags);

        if (sizeof(array_intersect_key($data, $required_tags)) != sizeof($required_tags)) {
            return;
        }

        $data = array_intersect_key($data, $allowed_tags);
//        if (isset($data['tarifplan']) && !isset($data['provider'])) {
//            unset($data['tarifplan']);
//        }

        $allowed_tags = array_intersect_key($allowed_tags, $data);

        // Стандарт XML учитывает порядок следования элементов,
        // поэтому важно соблюдать его в соответствии с порядком описанным в DTD
        $offer['data'] = array();
        foreach ($allowed_tags as $key => $value) {
            $offer['data'][$key] = $this->prepareField($data[$key]);
        }

        $this->offers[] = $offer;
    }

    /**
     * Формирование YML файла
     *
     * @return string
     */
    private function getYml() {
        $yml  = '<?xml version="1.0" encoding="windows-1251"?>' . $this->eol;
        $yml .= '<!DOCTYPE yml_catalog SYSTEM "shops.dtd">' . $this->eol;
        $yml .= '<yml_catalog date="' . date('Y-m-d H:i') . '">' . $this->eol;
        $yml .= '<shop>' . $this->eol;

        // информация о магазине
        $yml .= $this->array2Tag($this->shop);

        // валюты
        $yml .= '<currencies>' . $this->eol;
        foreach ($this->currencies as $currency) {
            $yml .= $this->getElement($currency, 'currency');
        }
        $yml .= '</currencies>' . $this->eol;

        // категории
        $yml .= '<categories>' . $this->eol;
        foreach ($this->categories as $category) {
            $category_name = $category['name'];
            unset($category['name'], $category['export']);
            $yml .= $this->getElement($category, 'category', $category_name);
        }
        $yml .= '</categories>' . $this->eol;

        // товарные предложения
        $yml .= '<offers>' . $this->eol;
        foreach ($this->offers as $offer) {
            $tags = $this->array2Tag($offer['data']);
            unset($offer['data']);
            if (isset($offer['param'])) {
                $tags .= $this->array2Param($offer['param']);
                unset($offer['param']);
            }
            $yml .= $this->getElement($offer, 'offer', $tags);
        }
        $yml .= '</offers>' . $this->eol;

        $yml .= '</shop>';
        $yml .= '</yml_catalog>';

        return $yml;
    }

    /**
     * Фрмирование элемента
     *
     * @param array $attributes
     * @param string $element_name
     * @param string $element_value
     * @return string
     */
    private function getElement($attributes, $element_name, $element_value = '') {
        $retval = '<' . $element_name . ' ';
        foreach ($attributes as $key => $value) {
            $retval .= $key . '="' . $value . '" ';
        }
        $retval .= $element_value ? '>' . $this->eol . $element_value . '</' . $element_name . '>' : '/>';
        $retval .= $this->eol;

        return $retval;
    }

    /**
     * Преобразование массива в теги
     *
     * @param array $tags
     * @return string
     */
    private function array2Tag($tags) {
        $retval = '';
        foreach ($tags as $key => $value) {
            $retval .= '<' . $key . '>' . $value . '</' . $key . '>' . $this->eol;
        }

        return $retval;
    }

    /**
     * Преобразование массива в теги параметров
     *
     * @param array $params
     * @return string
     */
    private function array2Param($params) {
        $retval = '';
        foreach ($params as $param) {
            $retval .= '<param name="' . $this->prepareField($param['name']);
            if (isset($param['unit'])) {
                $retval .= '" unit="' . $this->prepareField($param['unit']);
            }
            $retval .= '">' . $this->prepareField($param['value']) . '</param>' . $this->eol;
        }

        return $retval;
    }

    /**
     * Подготовка текстового поля в соответствии с требованиями Яндекса
     * Запрещаем любые html-тэги, стандарт XML не допускает использования в текстовых данных
     * непечатаемых символов с ASCII-кодами в диапазоне значений от 0 до 31 (за исключением
     * символов с кодами 9, 10, 13 - табуляция, перевод строки, возврат каретки). Также этот
     * стандарт требует обязательной замены некоторых символов на их символьные примитивы.
     * @param string $text
     * @return string
     */
    private function prepareField($field) {
        $field = htmlspecialchars_decode($field);
        $field = strip_tags($field);
        $from = array('"', '&', '>', '<', '\'');
        $to = array('"', '&', '>', '<', ''');
        $field = str_replace($from, $to, $field);
        if ($this->from_charset != 'windows-1251') {
            $field = iconv($this->from_charset, 'windows-1251//TRANSLIT//IGNORE', $field);
        }
        $field = preg_replace('#[\x00-\x08\x0B-\x0C\x0E-\x1F]+#is', ' ', $field);

        return trim($field);
    }

    protected function getPath($category_id, $current_path = '') {
        if (isset($this->categories[$category_id])) {
            $this->categories[$category_id]['export'] = 1;

            if (!$current_path) {
                $new_path = $this->categories[$category_id]['id'];
            } else {
                $new_path = $this->categories[$category_id]['id'] . '_' . $current_path;
            } 

            if (isset($this->categories[$category_id]['parentId'])) {
                return $this->getPath($this->categories[$category_id]['parentId'], $new_path);
            } else {
                return $new_path;
            }

        }
    }

    function filterCategory($category) {
        return isset($category['export']);
    }
}
?>
Надіслати
Поділитися на інших сайтах


можно приспособить код для вывода доп. картинок в карточке товара

$results = $this->model_catalog_product->getProductImages($this->request->get['product_id']);
foreach ($results as $result) {
	$data['images'][] = array(
				'popup' => $this->model_tool_image->resize($result['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height')),
				'thumb' => $this->model_tool_image->resize($result['image'], $this->config->get('config_image_additional_width'), $this->config->get('config_image_additional_height'))
			);
}
  • +1 1
Надіслати
Поділитися на інших сайтах


Я не до конца понял, в плане в карточке товара?

 

Смотрите это как пример, тут в YML выводиться 1 фото, хотя в карточке товара есть и доп.фото.

И они должны выводиться тоже.

<yml_catalog date="2016-11-17 11:15"><shop><name/><company/><url>http://vapeself.com.ua/</url><phone>335645</phone><platform>ocStore</platform><version>2.0.3.1</version><currencies><currency id="UAH" rate="1"/></currencies><categories><category id="18">
Жидкость для электронных сигарет</category></categories><offers><offer id="194" available="true"><url>http://vapeself.com.ua/zhidkost-dlja-elektronnyx-sigaret/zhidkost</url><price>10.00</price><currencyId>UAH</currencyId><categoryId>18</categoryId><picture>http://vapeself.com.ua/image/cache/catalog/1-100x100.jpg</picture><delivery>true</delivery><name>Жидкость</name><vendor/><vendorCode>1</vendorCode><description>Жидкость    </description></offer></offers></shop></yml_catalog>
Надіслати
Поділитися на інших сайтах


приведенный кусок кода добавляет дополнительные изображения в массив. Вставьте его после кода, который добавляет основное изображение.
Каким образом должны выводиться дополнительные изображения? тег pictureможет повторяться несколько раз?

  • +1 1
Надіслати
Поділитися на інших сайтах


Думаю, на пальцах тут не объяснить. Не предусмотрен в этом плагине вывод повторяющихся тегов. Либо искать другой, либо серьезно дорабатывать этот.

  • +1 1
Надіслати
Поділитися на інших сайтах


Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.