Magento Dev: Create a product feed

 Creating a product export feed for your Magento shop products can be handy. Either for your own website or for external services.

Setting up

Let’s create a folder in the root of your magento installation (for example in the httpdocs folder) named exporter. This folder can have any name you want, but let’s stick with this one for now.

Create a file named exporter.php, all of the interesting stuff will go here.

The exporter

Exporter.php doesn’t know Magento exists yet, so let’s change that:

[code lang=”php”]
<?php
header(‘Content-Type: text/xml’); // XML’s a handy dandy format

include ‘../app/Mage.php'; // Include the magento core

Mage::app(); //And start up the Magento app

[/code]

Now we can use magento’s awesome functionality! So let’s get the collection of products with the following code:

[code lang=”php”]
$_products = Mage::getModel(‘catalog/product’)->getCollection();
[/code]

We now have a collection with all of the products currently in your Magento store, now we’ll just have to return them in a more favorable format, an Array!

[code lang=”php”]
$_result = array(); // Make sure we have a result array to store our products

foreach($_products as $_product) {
$_product = $_product->load();
$_result[‘products’][‘product’][] = $_product->toArray();

}
[/code]

So now we have a nice array in which we have stored all of our products, ready to be transformed into an xml feed.

Array to XML

So we now have an array of products, we need to convert that to some nicer format namely xml. The great thing is that both the array and xml have a similar structure, namely: key -> value. So if we have an array like this:

[code lang=”php”]
array( ‘my_key’ => ‘my value’ );
[/code]

It’ll easily translate to:

[code lang=”xml”]
<my_key>my_value</my_key>
[/code]

And we can use php’s SimpleXML to accomplish this, just use the following class:

[code lang=”php”]
<?php
// Filename: ArrayXml.php
class ArrayXml
{

private $xml;

public function __construct($root=’root’)
{
$this->xml = new SimpleXMLElement(“<$root></$root>”);
}

private function iterate($element, $xmlNode)
{
foreach($element as $name=>$value) {
if(is_string($value) || is_numeric($value)) {
$xmlNode->$name = $value;
} else {
$xmlNode->$name = null;
$this->iterate($value, $xmlNode->$name);
}
}
}

public function toXML($array)
{
$this->iterate($array, $this->xml);
return $this->xml->asXML();
}

}
[/code]

The constructor element accepts an optional root element name, so if you want your root element named something else than <root> you can use your own.

It uses a recursive method, iterate(), to loop through all the elements and their children of an array and stuff them in a XML node (element). We can use the toXML method to pass our product array to our class, loop through it, and return it as an XML string.

Back to the exporter

First we’ll have to include the ArrayXml class, so the first part of code becomes:

[code lang=”php”]
<?php
header(‘Content-Type: text/xml’); // XML’s a handy dandy format

include ‘../app/Mage.php'; // Include the magento core

include ‘ArrayXml.php';

Mage::app(); //And start up the Magento app

[/code]

Now we can use our class to convert the array to an xml string, and output it:

[code lang=”php”]
$_result = array(); // Make sure we have a result array to store our products

foreach($_products as $_product) {
$_result[‘products’][‘product’][] = $_product->toArray();
}
$_converter = new ArrayXML();
echo $_converter->toXML($_result);
[/code]

When you run the following it should result in something like this:

[code lang=”xml”]
<?xml version=”1.0″?>
<root>
<products>
<product>
… lot’s of elements named after the product properties
</product>

… more products here
</products>
</root>
[/code]

Conclusion

Now we have a working export for Magento. You might want to narrow the results for products down (to just the name or price for example), if that’s the case you can create a custom result array using the product functions like this:

[code lang=”php”]
$_result = array(); // Make sure we have a result array to store our products

foreach($_products as $_product) {
$_result[‘products’][‘product’][] = array(
‘product_name’ => $_product->getName(),
‘product_price’ => $_product->getPrice()
);
}
$_converter = new ArrayXML();
echo $_converter->toXML($_result);
[/code]

Happy Coding!

Full Code:

export.php:
¬†[code lang=”php”]

<?php
header(‘Content-Type: text/xml’); // XML’s a handy dandy format

include ‘../app/Mage.php'; // Include the magento core

include ‘ArrayXml.php';

Mage::app(); //And start up the Magento app

$_products = Mage::getModel(‘catalog/product’)->getCollection();

$_result = array(); // Make sure we have a result array to store our products

foreach($_products as $_product) {
$_product = $_product->load();
$_result[‘products’][‘product’][] = array(
‘product_name’ => $_product->getName(),
‘product_price’ => $_product->getPrice()
);
}
$_converter = new ArrayXML();
echo $_converter->toXML($_result);

[/code]

ArrayXml.php:

[code lang=”php”]
<?php
// Filename: ArrayXml.php
class ArrayXml
{

private $xml;

public function __construct($root=’root’)
{
$this->xml = new SimpleXMLElement(“<$root></$root>”);
}

private function iterate($element, $xmlNode)
{
foreach($element as $name=>$value) {
if(is_string($value) || is_numeric($value)) {
$xmlNode->$name = $value;
} else {
$xmlNode->$name = null;
$this->iterate($value, $xmlNode->$name);
}
}
}

public function toXML($array)
{
$this->iterate($array, $this->xml);
return $this->xml->asXML();
}

}
[/code]

 

11 Responses to “Magento Dev: Create a product feed”

  1. Rick Jansen says:

    Wanneer ik de code gebruik krijg ik op de XML output van de producten export niks te zien. Wel de structuur maar geen data. Zelf maak ik gebruik van Magento 1.7.0.2. Wat zou hier het probleem kunnen zijn?

    • Bas Tuijnman says:

      Ik zie dat ik een klein (belangrijk) dingetje vergeten ben, het laden van de product data. Dat kun je doen in het begin van de foreach door dit te callen:

      $_product = $_product->load();
      

      Ik heb ook de code in de post aangepast.

  2. Peter Svegrup says:

    Hi Bas,

    Thanks a bunch for your article! It got me up and running in creating a product feed for an external service but now I’m of course stuck on some details that might be too much to ask you here but I’ll give it a shot.

    What product parameters are available to print? I assume there are nested arrays cause when I test your first example I get a group of parameters and the 2 example parameters you use to narrow down the result in the second example, product_name and product_price, are not included in the first result??

    Secondly how do I go about to nest nodes in the resulting xml? For example if I want a main node called with children nodes .

    Thanks a lot in advance!!

    Peter

    • Peter Svegrup says:

      Some xml was not included so the main node was Categories and the children nodes were Category.

    • Bas Tuijnman says:

      All parameters of a product are available. You can just add them to the products array by doing this for example:

      if we have an attribute with the code: my_custom_attribute, you can add this to the product result array:
      ‘my_attribute_code’ => $_product->getMyAttributeCode()

      If you want to add a nested node to the XML, you can add a child to (for example) the root node using SimpleXML’s addChild(), which will add a child node to your object and return the resulting child node.

      http://www.php.net/manual/en/simplexmlelement.addchild.php

      happy coding!

  3. William de Vries says:

    Hi Bas,

    Super script, werkt heel goed. Alleen ben ik geen hardcore php’er, dus daarom de volgende vraag:
    Op welke manier kun je het id nummer van een product verwerken in de tag? Bijvoorbeeld: . Via php.net kom ik er achter dat het via addAttribute moet lukken, maar ik heb geen idee hoe ik dat in jouw script toe kan passen.

    Alvast bedankt!

    William

    • Bas Tuijnman says:

      Hi William,

      Helaas is dat door de structuur van de code in de huidige vorm niet mogelijk, omdat de elementen specifiek op key=>value worden gedaan en er dus geen ruimte is voor attributen.

      Je zou echter de conversie van array naar XML kunnen laten voor wat het is en gewoon direct in de export.php een XML object aan kunnen maken. Dan kun je op je product element gewoon een ID attribute toevoegen.

  4. William de Vries says:

    Het voorbeeld is niet helemaal goed aangekomen, maar wat ik bedoelde is:

  5. Abu Wahid says:

    It’s really help full. Thanks.

  6. aone says:

    Hello,
    I was concerning is there any method to save the product feed in file extension .xml.

    Thanks.

Leave a Reply