Yandex market price list generation in Magento

Sometimes we need to publish information in Yandex.Market database. So, for publishing information there you need to create a document in a specific YML format. However, by default Magento can not generate products list in YML format. That is why, we need to create a simple extension for YML generation.

About YML

YML (Yandex Market Language) is a standard developed by Yandex.Market for receiving and publishing information about your products in Yandex.Market. YML is based on the XML standard (XML DTD), and it has a unified data format that allows fast and accurate processing of information provided by stores about products and services.
Here are general requirements for a YML file:

1. The YML standard is sensitive to the order of elements. This is a requirement of the XML DTD standard.

2. The YML standard does not allow textual data that uses nonprintable characters with ASCII codes in the range from 0 to 31 (with the exception of characters with codes 9, 10, and 13 — tab, new line, and carriage return).

3. Valid encoding – UTF-8, windows-1251.

Creating simple extension for generating YML

This is not tutorial on creating Magento extension, we describe only the code for generating the YML product price list.

First of all, create a new tab in the Magento admin panel, here is your adminhtml.xml:

<config>
    <menu>
        <atwix_yandexexport translate="title" module="atwix_yandexexport">
            <title>Yandex export YML</title>
            <sort_order>900</sort_order>
            <action>atwix_yandexexport/export/index</action>
        </atwix_yandexexport>
    </menu>
    <acl>
        <resources>
            <all>
                <title>Yandex export CSV</title>
            </all>
            <admin>
                <children>
                    <atwix_yandexexport>
                        <atwix_yandexexport>
                            <title>Yandex export CSV</title>
                        </atwix_yandexexport>
                    </atwix_yandexexport>
                </children>
            </admin>
        </resources>
    </acl>
</config>

Note that we add the code to the config.xml for creating a route for our controller.
Here is a code snippet:

<admin>
        <routers>
            <atwix_yandexexport>
                <use>admin</use>
                <args>
                    <module>Atwix_Yandexexport</module>
                    <frontName>atwix_yandexexport</frontName>
                </args>
            </atwix_yandexexport>
        </routers>
    </admin>

Then, create a template containing the simple form:

<div class="content-header">
    <h3 class="icon-head head-adminhtml-import"><?php echo $this->__('Export products for Yandex market')?></h3>
</div>
<div class="entry-edit">
    <form id="edit_form" action="<?php echo $this->getUrl('*/*/export')?>" method="post" enctype="multipart/form-data" >
        <div>
            <input type="hidden" name="form_key" value="<?php echo Mage::getSingleton('core/session')->getFormKey(); ?>" />
        </div>
        <div class="entry-edit-head">
            <h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->__('Export products')?></h4>
            <div class="form-buttons"></div>
        </div>
        <div class="fieldset " id="base_fieldset">
            <div class="hor-scroll">
                <table cellspacing="0" class="form-list">
                    <tbody>
                    <tr>
                        <td class="label"><label for="import_file"><?php echo $this->__('Export to YML')?></label></td>
                        <td>
                            &nbsp;&nbsp;<input type="submit" value="Export" id="export_yml_to_file">
                        </td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </form>
</div>

Furthermore, the form contains a single button, after pressing the button YML document will be generated automatically.
Next step is to create the methods of our controller:

    /**
     * Index Action, prepare and display form
     */
    public function indexAction()
    {
        $this->loadLayout();
        $this->_setActiveMenu('atwix_yandexexport');
        $this->renderLayout();
    }

    /**
     * Export to csv file
     */
    public function exportAction()
    {
        $filename = 'export_product.yml';
        $content = Mage::helper('atwix_yandexexport')->exportYml();
        $this->_prepareDownloadResponse($filename, $content);
    }

The index action prepares a layout, and the export action creates a YML file and prepares a response for downloading. Also, the export action uses the method from our Data helper, it is the exportYml method. Look through the code of exportYml method:

 /**
     * Prepare data for export to yml file
     */
    public function exportYml()
    {
        $xmlHeader = '';
        $xml = new SimpleXMLElement($xmlHeader);

        $shop = $xml->addChild('shop');
        $shop->addChild('name', 'Shop name'); // use your shop name
        $shop->addChild('company', 'Company name')); // use your company name
        $shop->addChild('url', Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB));
        $currencies = $shop->addChild('currencies');
        $currency = $currencies->addChild('currency');
            $currency->addAttribute('id', 'USD');
            $currency->addAttribute('rate', '1');
            $currency->addAttribute('plus', '0');
        $categories = $shop->addChild('categories');

        $categoriesCollection = Mage::getModel('catalog/category')
            ->getCollection()
            ->addAttributeToSelect('*')
            ->load();

        foreach ($categoriesCollection as $categoryInfo) {
            $category = $categories->addChild('category', $categoryInfo->getName());
            $category->addAttribute('id', $categoryInfo->getId());
            $category->addAttribute('parentId', $categoryInfo->getParentId());
        }

        $offers = $shop->addChild('offers');
        $products = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
        ;
        Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($products);

        foreach ( $products as $offerInfo) {
            $offer = $offers->addChild('offer');
                $offer->addAttribute('id', $offerInfo->getId());
            $offer->addAttribute('available', 'true');
            $offer->addAttribute('bid', '21');

            $offer->addChild('url', Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB).$offerInfo->getUrlPath());
            $offer->addChild('price', $offerInfo->getPrice());
            $offer->addChild('currencyId', 'USD');
            $offer->addChild('categoryId', end($offerInfo->getCategoryIds()));
            if ($offerInfo->getImage()) {
                $offer->addChild('picture', Mage::getBaseUrl('media').'catalog/product'.$offerInfo->getImage());
            } else {
                $offer->addChild('picture', "");
            }
            $offer->addChild('store', 'true');
            $offer->addChild('pickup', 'true');
            $offer->addChild('delivery', 'true');
            $offer->addChild('name', $offerInfo->getName());
            $offer->addChild('vendor', '');
            $offer->addChild('description', htmlspecialchars($offerInfo->getDescription()));
            $offer->addChild('manufacturer_warranty', 'false');
            $offer->addChild('country_of_origin', 'USA');
        }

        return $xml->asXML();
    }

If you want to create YML price list for other categories, you will need to change some parts of the code in exportYml() method. We hope the described example of YML price list generation for simple product will be useful for you.