Google Merchant PHP Magento Product Data Feed

/, PHP / MySQL/Google Merchant PHP Magento Product Data Feed

Google Merchant PHP Magento Product Data Feed

There are a number of ways to feed product data to Google Merchant (Google Base) from Magento, however we have never found a paid for magento module which actually does everything thats needed, especially when dealing with complex data sets like clothing & apparel, where there can be hugely complicated configurable products, and multiple attribute sets used dependant on product etc, so for a truly bespoke Google Merchant Data Feed sometimes there is no option but to break out the PHP and script a bespoke XML Data Feed.

Magento Google Merchant data feeds

There are a number of off the shelf Magento modules out there which can be utilised to produce basic data feeds from Magento for Google Merchant / Shopping, and most are fairly configurable, however, once you exceed the configuration limits of these feed systems, then you will need to get your hands dirty and script your own data feed, or find someone who can do it for you.

Google Merchant Product Feed for Magento via PHP Script

Google Merchant Product Feed for Magento via PHP Script

Scripting something as complex as a google merchant data feed in PHP from Magento is a fairly daunting task, not just from the perspective of the Magento API’s and making sure you are getting the correct data, but also from the perspective that if you get it wrong you will be pouring money into Google Merchant / Google Shopping to promote incorrect products, and then of course there is the aspect that we don’t want to slow Magento down whilst our PHP script extracts the data for potentially thousands of products for Google.

Additionally you may be dealing with multiple product attribute sets which define differing types of products, which require different data sets to be sent to the Google Merchant interface, and add to the potentially huge configurable products within Magento which need to be grouped so that all available options are detailed to the Google Merchant feed and you have a massive undertaking in not only designing but also scripting the feed.

To this end we have decided to publish one of our custom PHP Scripts for producing an XML Google Merchant Data feed from Magento via PHP & the XML Dom Document Interface, using the Magento API’s to extract and manipulate the data.

Using PHP and XML Dom to produce a Google Merchant data feed from Magento

The script below deals with both simple and configurable products (ensuring that configurable products are entered into the feed using an item_group_id so fully compliant with Google’s Merchant Data Feed Specification, this also allows you to feed all you configurable items, together with sizes, colours, and whatever other options you have available to you.

The full php script file is available on Github (apw_php_magento_google_data_feed).

It is highly unlikely that the script posted in the Github repository will work out of the box for you, as it uses various custom attributes and also a database table for managing the relationship between Magento Categories and Google’s Product Taxonomy, it was not our intention in publishing this script to give out a finished product but more to give you an idea of how to produce your own highly customised Google Merchant XML data feed from Magento using PHP and the DOM XML Model, it is however our intention to make this more flexible and user friendly in time by integrating Google Taxonomy attributes in both the category and the product of magento, with the taxonomy being chosen on a priority basis, i.e. if no taxonomy exists for the product then the taxonomy of the category will be take, if there is no taxonomy for the category, then the default taxonomy of the site will be used etc However this is not included in this basic version of the script, and will be released at a later date as a fully fledged Magento Module.

Creating the XML Dom Document

The first part of our script deals with setting up the XML Dom Document container that will contain the product item data, this is a few simple lines to initialise the document and add the headers that the Google Merchant interface is expecting to see.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] $nsUrl = ‘http://base.google.com/ns/1.0’;
$doc = new DOMDocument(‘1.0’, ‘UTF-8’);

$rootNode = $doc->appendChild($doc->createElement(‘rss’));
$rootNode->setAttribute(‘version’, ‘2.0’);
$rootNode->setAttributeNS(‘http://www.w3.org/2000/xmlns/’, ‘xmlns:g’, $nsUrl);
$channelNode = $rootNode->appendChild($doc->createElement(‘channel’));
$channelNode->appendChild($doc->createElement(‘title’, ‘APW Trading Google Data Feed’));
$channelNode->appendChild($doc->createElement(‘description’, ‘Google Products Data Feed’));
$channelNode->appendChild($doc->createElement(‘link’, ‘http://www.apwtrading.co.uk’));[/code]

Selecting the Products Collection from Magento

The next thing we must do is select the products that we want to push through the Google Merchant Feed from the Magento Product Catalogue into a Collection.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] $products = Mage::getModel(‘catalog/product’)->getCollection()
->addAttributeToSelect(‘id’)
->addAttributeToFilter(‘status’, 1)
->addAttributeToFilter(‘visibility’, Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->getAllIds();[/code]

The above code selects a collection of product id’s only from Magento in order to keep down the amount of data we are pulling back, and adds filters for visibility and the status of the product, in this case we are selecting products which are enabled and with a visibility of Catalogue_Search

Parsing the Product List for Processing

Next we need to parse the selected product id’s and create the xml nodes because in this example we are dealing with both simple and configurable products we are using a PHP switch statement wrapped in a foreach loop to parse the products and route each product to the relevant function for processing based on it being a simple of configurable product.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] foreach($products as $pid) {
$_product = Mage::getModel(‘catalog/product’)->load($pid);

if ($_product->getAttributeText(‘googleblock’) == ‘No’) {
switch ($_product->getTypeId()) {
case ‘simple’:
process_simple_product($_product, $channelNode, $doc);
break;
case ‘configurable’:
process_configurable_product($_product, $channelNode, $doc);
break;
}
}

}[/code]

In order for the above code to work and update the XML DOM Document we need to ensure that the two functions we are calling have the $channelnode and the $doc variables passed by reference so they can be updated from within the functions rather than passed back as a return from the function.

Saving the XML DOM Document

Once we have completed the processing it is a simple case of saving the XML DOM Document, in our example because the number of products is high and the file quiet large we are saving the XML DOM Document to disc, it is also possible to output it directly to the page, so that your script returns the XML directly back to the called page.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] $doc->save(‘GoogleShopping.xml’);[/code]

Processing Simple Products into XML Items

The code below parses the product data for a given product and adds the XML node to the XML DOM Document. For simple products in Magento this is relatively easy as 99% of the data we need is contained within the Magento Product collection and it is simply a case of filling in the nodes.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] function process_simple_product($_product, &$channelNode, &$doc) {

$itemNode = $channelNode->appendChild($doc->createElement(‘item’));

$itemNode->appendChild($doc->createElement(‘g:id’))->appendChild($doc->createTextNode($_product->getId()));
$itemNode->appendChild($doc->createElement(‘g:title’))->appendChild($doc->createTextNode($_product->getName()));
$itemNode->appendChild($doc->createElement(‘g:description’))->appendChild($doc->createTextNode($_product->getShortDescription()));
$itemNode->appendChild($doc->createElement(‘g:image_link’))->appendChild($doc->createTextNode($_product->getImageUrl()));
$itemNode->appendChild($doc->createElement(‘g:brand’))->appendChild($doc->createTextNode($_product->getAttributeText(‘brand’)));
$itemNode->appendChild($doc->createElement(‘g:link’))->appendChild($doc->createTextNode($_product->getProductUrl()));
$itemNode->appendChild($doc->createElement(‘g:gender’))->appendChild($doc->createTextNode($_product->getAttributeText(‘gender’)));
$itemNode->appendChild($doc->createElement(‘g:material’))->appendChild($doc->createTextNode($_product->getAttributeText(‘mainmaterial’)));
$itemNode->appendChild($doc->createElement(‘g:pattern’))->appendChild($doc->createTextNode($_product->getAttributeText(‘pattern’)));

$topcat = do_producttypes($_product, $doc, $itemNode);
$itemNode->appendChild($doc->createElement(‘g:google_product_category’))->appendChild($doc->createTextNode(get_googleTaxonmyCat($topcat)));

$itemNode->appendChild($doc->createElement(‘g:mpn’))->appendChild($doc->createTextNode($_product->getSku()));
if (strlen($_product->getEan()) > 7) {
$itemNode->appendChild($doc->createElement(‘g:gtin’))->appendChild($doc->createTextNode($_product->getEan()));
}

$itemNode->appendChild($doc->createElement(‘g:price’))->appendChild($doc->createTextNode($_product->getPrice()));
$itemNode->appendChild($doc->createElement(‘g:sale_price’))->appendChild($doc->createTextNode($_product->getSpecialPrice()));

$itemNode->appendChild($doc->createElement(‘g:size’))->appendChild($doc->createTextNode($_product->getAttributeText(‘size’)));
$itemNode->appendChild($doc->createElement(‘g:color’))->appendChild($doc->createTextNode($_product->getAttributeText(‘color’)));

$itemNode->appendChild($doc->createElement(‘g:availability’))->appendChild($doc->createTextNode(do_isinstock($_product)));

$itemNode->appendChild($doc->createElement(‘g:size_system’))->appendChild($doc->createTextNode(‘uk’));
$itemNode->appendChild($doc->createElement(‘g:age_group’))->appendChild($doc->createTextNode(‘adult’));
$itemNode->appendChild($doc->createElement(‘g:condition’))->appendChild($doc->createTextNode(‘new’));
$itemNode->appendChild($doc->createElement(‘g:identifier_exists’))->appendChild($doc->createTextNode(‘TRUE’));
$itemNode->appendChild($doc->createElement(‘g:adult’))->appendChild($doc->createTextNode(do_isadult($_product)));

}[/code]

As you will see above there are a couple of data items that we need to do a little more work with these are the Product Types (our internal Categories), the Google Taxonomy (Google Merchants own category list) and the availability element, for each of these data items we have created functions to handle the data and return the correct values for insertion into the XML, for details of those function please see the full script in the Github repository.

Processing Configurable Products into XML Items

With Magento’s Configurable Products life is not quite so easy as we actually never write out the main configurable product to the Google Merchant Feed, instead we loop through the configurable products children and create a element in the XML Dom Document for each child utilising data from both the child (simple products) and the parent (configurable product).

With a configurable product we also need to include additional data in the feed to pass into Google Merchant, you will notice that each in this data set also contains the item_group_id after the actual product_id this additional data item allows the Google Merchant interface to group together all child items back into a single product but with all it’s variants (colours and sizes etc).

Selecting the Child Products of a Configurable Product in Magento

Our first job is to select up the simple child products from the parent confgurable product, and then we can simple loop through them on a foreach loop and process them much as we did in the simple products example above.

[code title=”googledatafeed.php” language=”php” firstline=”7″ autolinks=”false” wraplines=”false” light=”true”] $_childProducts = Mage::getModel(‘catalog/product_type_configurable’)
->getUsedProducts(null,$_product);

foreach($_childProducts as $_child) {
$itemNode = $channelNode->appendChild($doc->createElement(‘item’));

$_childproduct = Mage::getModel(‘catalog/product’)->load($_child->getID());

$itemNode->appendChild($doc->createElement(‘g:id’))->appendChild($doc->createTextNode($_childproduct->getId()));
$itemNode->appendChild($doc->createElement(‘g:item_group_id’))->appendChild($doc->createTextNode($_product->getSku()));
}[/code]

You will notice above the when we select the various elements for inclusion in the node we use both the $_childproduct and the $_product (the parent) the bulk of the data we will output will be coming from the parent product (the image, url, description etc) however from the child product we will take variation data for instance (the product_id, size, colour, mpn and gtin) in this way we create an almost duplicate data set for each child with only the key variation data items changed.

We can also include additional items from the child product for instance price and availability to ensure that we get the best possible data set for submission into Google Merchant, after all there is no point putting your CPC budget into promoting a size 4.5 shoe on Google if you have every available size except that one.

More to Come

If you have any questions about the above script and it’s usage then please feel free to comment below and we will attempt to answer your questions as best we can, the full version of this script is available on GitHub and can be used, abused, chopped up and put back together however you please.

It is our plan to turn this script into a full Magento community module in the near future so watch this space for more information in the no to distant future.

By | 2019-06-04T08:55:37+01:00 July 2nd, 2015|Magento, PHP / MySQL|Comments Off on Google Merchant PHP Magento Product Data Feed

About the Author: