UMI CMS – Обмен данными. Добавление новых форматов экспорта на примере Google Merchant FEED

01.11.2017

Задача: добавить в экспорт каталога в формате Google Merchant Feed. Подробнее о спецификации.

Спецификация данных о товарах.

Статьи в вики справочнике UMI, которые могут пригодиться:

  1. В Шаблонах Данных в справочник Форматы Экспорта добавляем наименование. Произвольное название и идентификатор, например “FEED“.
  2. В директорию /classes/system/subsystems/export/exporters добавляем файл FEEDExporter.php
  3. Содержимое файла. Берем за основу например YMLExporter.php или catalogCommerceMLExporter.php
<?php

	class FEEDExporter extends umiExporter {
		public function setOutputBuffer() {
			$buffer = outputBuffer::current('HTTPOutputBuffer');
			$buffer->charset("utf-8");
			$buffer->contentType("text/xml");
			return $buffer;
		}

		public function export($branches, $excludedBranches) {
			if (!count($branches)) {
				$sel = new selector('pages');
				$sel->where('hierarchy')->page(0)->childs(0);
				$branches = $sel->result();
			}

			$exporter = new xmlExporter("FEED");
			$exporter->addBranches($branches);
			$exporter->setIgnoreRelations(array('guides'));
			$exporter->excludeBranches($excludedBranches);
			$result = $exporter->execute();

			$umiDump = $result->saveXML();

			$style_file = './xsl/export/' . $this->type . '.xsl';
			if (!is_file($style_file)) {
				throw new publicException("Can't load exporter {$style_file}");
			}


			$doc = new DOMDocument("1.0", "utf-8");
			$doc->formatOutput = XML_FORMAT_OUTPUT;
			$doc->loadXML($umiDump);

			$templater = umiTemplater::create('XSLT', $style_file);
			return $templater->parse($doc);
		}

	}
?>

4. В строках 3 и 18 используется идентификатор FEED из пункта 1

5. В директории /xsl/export создаем файл FEED.xsl Пример файла:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
				xmlns:g="http://base.google.com/ns/1.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
				xmlns:php="http://php.net/xsl"
				extension-element-prefixes="php"
				exclude-result-prefixes="xsl php">
<xsl:output method="xml" encoding="utf-8"/>

<xsl:key name="property" match="/umidump/types/type[base/@module = 'catalog']//field" use="@id"/>

<xsl:template match="umidump[@version='2.0']">
	<rss version="2.0">
	<!-- <xsl:copy-of select="."/> --> <!-- Так можно увидеть входные данные -->
		<channel>
			<title>Магазин Номер 1</title>
			<link>https://<xsl:value-of select="meta/domain"/>/</link> <!-- Домен -->
			<xsl:apply-templates select="pages/page[basetype/@module = 'catalog' and basetype/@method = 'object' and @type-id='123']" mode="good-feed" /> <!-- Берем только композиции -->
		</channel>
	</rss>
</xsl:template>

<xsl:template match="page" mode="good-feed">
	<xsl:param name="parent-id" select="@parentId" />
	<xsl:param name="property" select="properties/group/property" />
	<xsl:param name="id" select="@id"/>
	<xsl:variable name="original-price" select="document(concat('udata://emarket/price/', $id))/udata/price/original" />
	<xsl:variable name="price-old" select="$property[@name = 'price_old']/value" />
	<xsl:variable name="price" select="round(document(concat('udata://emarket/price/', $id))/udata/price/actual)" />
	<item>
		<g:id><xsl:value-of select="$property[@name = 'artikul']/value" /></g:id> <!-- ID = артикул -->
		<g:title><xsl:value-of select="name" /></g:title> <!-- Название товара -->
		<g:description> <!-- Составное описание  -->
			<xsl:value-of select="name" />
			<xsl:if test="$property[@name = 'cvet_proizvoditelya']/value">
				<xsl:text> с цветом фасада </xsl:text><xsl:value-of select="$property[@name = 'cvet_proizvoditelya']/value"/>
			</xsl:if>
			<xsl:if test="$property[@name = 'material_fasada']/value/item/@name">
				<xsl:text> выполнена из </xsl:text><xsl:value-of select="$property[@name = 'material_fasada']/value/item/@name"/>
			</xsl:if>
			<xsl:if test="$property[@name = 'cvet_korpusa_text']/value">
				<xsl:text>. Цвет корпуса: </xsl:text><xsl:value-of select="$property[@name = 'cvet_korpusa_text']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'dlina']/value) or ($property[@name = 'vysota']/value) or ($property[@name = 'glubina']/value)">
			<xsl:text>. Размеры: </xsl:text>
			</xsl:if>
			<xsl:if test="$property[@name = 'dlina']/value">
				<xsl:value-of select="$property[@name = 'dlina']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'dlina']/value) and ($property[@name = 'vysota']/value)">
			<xsl:text>x</xsl:text>
			</xsl:if>
			<xsl:if test="$property[@name = 'vysota']/value">
				<xsl:value-of select="$property[@name = 'vysota']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'vysota']/value) and ($property[@name = 'glubina']/value)">
			<xsl:text>x</xsl:text>
			</xsl:if>
			<xsl:if test="$property[@name = 'glubina']/value">
				<xsl:value-of select="$property[@name = 'glubina']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'dlina']/value) or ($property[@name = 'vysota']/value) or ($property[@name = 'glubina']/value)">
			<xsl:text>мм.</xsl:text>
			</xsl:if>
		</g:description>
		<xsl:apply-templates select="/umidump/pages/page[@id = $parent-id and basetype/@module = 'catalog' and basetype/@method = 'category']" mode="goods" /> <!-- Продуктовая категория -->
		<g:link><xsl:value-of select="concat('https://', /umidump/meta/domain, @link)" /></g:link> <!-- Ссылка на  товар -->
		<g:condition>new</g:condition> <!-- Товар не бу -->
		<xsl:choose> <!-- Цена и валюта -->
			<xsl:when test="$price-old > 0">
				<g:price><xsl:value-of select="$price-old" /> RUB</g:price>
				<g:sale_price><xsl:value-of select="$price" /> RUB</g:sale_price>
			</xsl:when>
			<xsl:when test="($price-old = 0) and ($original-price > $price)">
				<g:price><xsl:value-of select="$original-price" /> RUB</g:price>
				<g:sale_price><xsl:value-of select="$price" /> RUB</g:sale_price>
			</xsl:when>
			<xsl:when test="not($price-old) and ($original-price > $price)">
				<g:price><xsl:value-of select="$original-price" /> RUB</g:price>
				<g:sale_price><xsl:value-of select="$price" /> RUB</g:sale_price>
			</xsl:when>
			<xsl:otherwise>
				<g:price><xsl:value-of select="$price" /> RUB</g:price>
			</xsl:otherwise>
		</xsl:choose>
		<g:availability>in stock</g:availability> <!-- В наличии -->
		<g:image_link><xsl:value-of select="concat('https://', /umidump/meta/domain, $property[@name = 'photo']/value)" /></g:image_link> <!-- Картинка -->
		<!-- Доп. Картинки -->
		<xsl:if test="$property[@name = 'photo1']">
			<g:additional_image_link><xsl:value-of select="concat('https://', /umidump/meta/domain, $property[@name = 'photo1']/value)" /></g:additional_image_link>
		</xsl:if>
		<xsl:if test="$property[@name = 'photo2']">
			<g:additional_image_link><xsl:value-of select="concat('https://', /umidump/meta/domain, $property[@name = 'photo2']/value)" /></g:additional_image_link>
		</xsl:if>
		<xsl:if test="$property[@name = 'photo3']">
			<g:additional_image_link><xsl:value-of select="concat('https://', /umidump/meta/domain, $property[@name = 'photo3']/value)" /></g:additional_image_link>
		</xsl:if>
		<xsl:if test="$property[@name = 'photo4']">
			<g:additional_image_link><xsl:value-of select="concat('https://', /umidump/meta/domain, $property[@name = 'photo4']/value)" /></g:additional_image_link>
		</xsl:if>
		<xsl:if test="$property[@name = 'brand']">
			<g:brand><xsl:value-of select="$property[@name = 'brand']/value/item/@name"/></g:brand>
		</xsl:if>
		<g:identifier_exists>нет</g:identifier_exists> <!-- Нет цифрового кода -->
		<g:material><xsl:value-of select="$property[@name = 'material_fasada']/value/item/@name"/></g:material> <!-- Материал -->
		<g:color><xsl:value-of select="$property[@name = 'cvet_proizvoditelya']/value"/></g:color> <!-- Цвет -->
		<g:size> <!-- Размер -->
			<xsl:if test="$property[@name = 'dlina']/value">
				<xsl:value-of select="$property[@name = 'dlina']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'dlina']/value) and ($property[@name = 'vysota']/value)">
			<xsl:text>x</xsl:text>
			</xsl:if>
			<xsl:if test="$property[@name = 'vysota']/value">
				<xsl:value-of select="$property[@name = 'vysota']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'vysota']/value) and ($property[@name = 'glubina']/value)">
			<xsl:text>x</xsl:text>
			</xsl:if>
			<xsl:if test="$property[@name = 'glubina']/value">
				<xsl:value-of select="$property[@name = 'glubina']/value"/>
			</xsl:if>
			<xsl:if test="($property[@name = 'dlina']/value) or ($property[@name = 'vysota']/value) or ($property[@name = 'glubina']/value)">
			<xsl:text>мм.</xsl:text>
			</xsl:if>
		</g:size>
		<xsl:if test="$property[@name = 'weight']">
			<g:shipping_weight><xsl:value-of select="$property[@name = 'weight']/value"/> kg</g:shipping_weight> <!-- Вес -->
		</xsl:if>
	</item>
</xsl:template>

<xsl:template match="page" mode="goods">
 	<xsl:param name="parent-id" select="@parentId" /> 
	<xsl:if test="document(concat('upage://', $parent-id))//property[@name='google_product_category']/value">
		<!-- Вывод цифрового ID категории товаров из файла http://www.google.com/basepages/producttype/taxonomy-with-ids.ru-RU.xls -->
		<g:google_product_category><xsl:value-of select="document(concat('upage://', $parent-id))//property[@name='google_product_category']/value" /></g:google_product_category>
		<!-- Тип товара. Полезен для назначения ставок -->
		<g:product_type>Главная > <xsl:value-of select="document(concat('upage://', $parent-id))/udata/page/name" /> > <xsl:value-of select="name" /></g:product_type>
	</xsl:if>
</xsl:template>

<!-- -->
<xsl:template match="umidump">
	<error>Unknown umidump version</error>
</xsl:template>

</xsl:stylesheet>

 

6. Создаем новый экспорт в админке.

7. Запускаем экспорт и проверяем полученный файл в отладчике фидов

 

 

Comments 0

Александр
Александр
Reply

Спасибо! очень помогло!

13.11.2018

Добавить комментарий для Александр Отменить ответ

Your email address will not be published. Required fields are marked *