Skip to content

Instantly share code, notes, and snippets.

@julesjanssen
Created June 9, 2011 23:18
Show Gist options
  • Save julesjanssen/1017978 to your computer and use it in GitHub Desktop.
Save julesjanssen/1017978 to your computer and use it in GitHub Desktop.
Magento XML productfeed voor Beslist.nl
<?php
/**
*
* @license MIT License
*
*/
// om 't script wat tijd te geven
ini_set("memory_limit","320M");
ini_set("max_execution_time", 240);
set_time_limit(240);
$time_start = microtime(true);
$cachetime = 24 * 60 * 60; //1 dag
$verzendkosten = 5.95;
$maxproducts = 0;
ob_start();
// standaard Magento spul
$_SERVER['SCRIPT_NAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_NAME']);
$_SERVER['SCRIPT_FILENAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_FILENAME']);
// indien je meer winkels hebt, stel hier (op basis van $_SERVER['MAGE_RUN_CODE']) de juiste storeID in
$storeID = 1;
$cachefile = dirname(__FILE__) .'/var/cache/'. md5('beslistproductfeed'. $storeID);
$filetime = is_file($cachefile) ? filemtime($cachefile) : 0;
if((time() - $cachetime) < $filetime){
header("Content-type: application/xml; charset=utf-8");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
readfile($cachefile);
}else{
// init db connectie
$pdo = new PDO(
'mysql:host=localhost;dbname=databasenaam',
'databaseuser',
'databasepass',
array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
PDO::ATTR_CASE => PDO::CASE_LOWER
)
);
header("Content-type: application/xml; charset=utf-8");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo '<?xml version="1.0" encoding="utf-8"?>
<Products>';
$sql = "SELECT
p.entity_id,
p.sku,
p.type_id
FROM
catalog_product_entity p
LEFT JOIN
catalog_product_website w ON w.product_id = p.entity_id
WHERE
w.website_id = ". $storeID ."
ORDER BY
p.entity_id ASC";
if($maxproducts){
$sql .= "
LIMIT ". (int) $maxproducts;
}
$sth = $pdo->prepare($sql);
$sth->execute();
$products = $sth->fetchAll();
foreach($products as $product){
$sql = "SELECT
*
FROM
catalog_product_flat_". $storeID ."
WHERE
entity_id = ". $product['entity_id'];
$sth = $pdo->prepare($sql);
$sth->execute();
$flatproduct = $sth->fetch();
// product niet gevonden of niet zichtbaar
if($flatproduct == false || $flatproduct['visibility'] < 1) continue;
$special_from = !empty($flatproduct['special_from_date']) ? strtotime($flatproduct['special_from_date']) : 0;
$special_to = !empty($flatproduct['special_to_date']) ? strtotime($flatproduct['special_to_date']) : 0;
$price = (float) $flatproduct['price'];
if( !empty($flatproduct['special_price']) &&
floatVal($flatproduct['special_price']) < $price &&
$special_from <= time() &&
($special_to >= time() || $special_to == 0)
){
$price = (float) $flatproduct['special_price'];
}
$sql = "SELECT
c.entity_id,
c.name
FROM
catalog_category_flat_store_". $storeID ." c
LEFT JOIN
catalog_category_product cp ON cp.category_id = c.entity_id
WHERE
cp.product_id = ". $product['entity_id'] ." AND
c.parent_id <> 1
ORDER BY
c.level ASC";
$sth = $pdo->prepare($sql);
$sth->execute();
$categories = $sth->fetchAll();
$merk = $categories[0]['name'];
$categorie = $categories[1]['name'];
echo '
<Product>
<Categorie>'. htmlspecialchars($categorie) .'</Categorie>
<Merk>'. htmlspecialchars($merk) .'</Merk>
<Titel>'. htmlspecialchars($flatproduct['name']) .'</Titel>
<Omschrijving>'. htmlspecialchars($flatproduct['short_description']) .'</Omschrijving>
<Image>'. $basepath .'media/catalog/product'. $flatproduct['small_image'] .'</Image>
<Deeplink>'. $basepath . $flatproduct['url_path'] .'</Deeplink>
<Prijs>'. number_format($price, 2, '.', ',') .'</Prijs>
<Verzendkosten>'. number_format($verzendkosten, 2, '.', ',') .'</Verzendkosten>
<Levertijd>Op werkdagen voor 16.00 uur besteld, de volgende dag in huis</Levertijd>
<Productcode>'. $product['sku'] .'</Productcode>
</Product>';
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo '
<!-- '. number_format($time, 4) .' -->
<!-- count '. count($products) .' -->
</Products>';
$data = ob_get_clean();
file_put_contents($cachefile, $data);
echo $data;
}
@julesjanssen
Copy link
Author

De functies om productoverzichten te krijgen binnen Magento zijn - vooral bij grote aantallen - vaak te langzaam om op een redelijke manier een XML uitdraai te genereren.
Het bovenstaande script werkt rechttoe rechtaan direct op de database en is daardoor erg snel (ruim 1500 producten worden in minder dan een seconde in een XML omgezet).
Dit voorbeeld is specifiek voor de Beslist.nl productfeed, maar is natuurlijk makkelijk aan te passen naar een iets aangepaste XML uitvoer.

@ceezoo
Copy link

ceezoo commented Jun 22, 2011

Hallo Jules,

Werkt inderdaad snel, maar ik krijg merken en categorieën niet (alleen en ) en zou graag alleen de visible =4 producten tonen.

douwe (info@ceezoo.nl)

@julesjanssen
Copy link
Author

Zoals gezegd is dit een specifiek voorbeeld voor Beslist.nl & uiteraard ook voor de shop waar ik het heb toegepast.
Met wat kleine aanpassingen is 't script waarschijnlijk zeer simpel op jouw wensen aan te passen.

@bluenix
Copy link

bluenix commented Jan 5, 2012

Erg slim om direct de database uit te lezen.
Hoe zou je het script uitbreiden zodat je de waarde van een attribuut kunt inlezen?

@julesjanssen
Copy link
Author

@bluenix Ik weet niet precies wat je bedoelt, maar helpt deze info wellicht: http://www.sharpdotinc.com/mdost/2009/04/06/magento-getting-product-attributes-values-and-labels/

@bluenix
Copy link

bluenix commented Jan 5, 2012

@julesjanssen Bedankt voor je antwoord. Dat is inderdaad wat ik bedoel, maar dan direct uit de database, zonder gebruik van de magento functies.

In het script voor de XML feed hierboven laad je bijvoorbeeld de prijs van een product. Maar hoe krijg je bijvoorbeeld de waarde voor een attribuut 'levertijd'?

@julesjanssen
Copy link
Author

@bluenix 'levertijd' is volgens mij geen veld in de catalog_product_flat tabel. Daar zul je dus een of meerdere andere queries voor moeten uitvoeren. De oplossing daarvoor heb ik helaas niet klaar liggen.
Ik zou beginnen te zoeken in de 'eav' tabellen (bijvoorbeeld: eav_attribute_option_value)

@bluenix
Copy link

bluenix commented Jan 6, 2012

@julesjanssen Ik kwam er met die andere queries niet uit, dus ik hoopte dat jij het wist! Ik ga er mee aan de slag. In ieder geval bedankt voor je reactie!

@mrbellek
Copy link

Bedankt voor de feed! Ik kom hem met een paar kleine aanpassingen (log path, sku escapen) zo gebruiken voor mijn Beslist export. :)

@asnsolutions
Copy link

Kun je mij vertellen hoe je de XML automatiche kan wegschrijven in een directory?

Alvast bedankt

@BDStudioNL
Copy link

Bedankt voor deze informatie. Weet iemand ook waar ik dit in welke map moet zetten? Is het ook voor Magento 1.9.0.1, en wordt er automatisch naar domeinnaam.nl/productfeed.xml overgeschreven o.i.d.? Ik ben zelf niet zo goed in PHP..

Bij voorbaat dank,
Bas

@fourroses666
Copy link

@BDStudioNL, gewoon de database gegevens aanpassen in het document en uploaden. Dan als je naar het bestand gaat zie je de feed.

@fourroses666
Copy link

@julesjanssen, bedankt voor het vrijgeven van het script.

Heb zojuist mijn feed geupload bij Beslist maar geeft een aantal kritieke punten.
Ik denk dat het probleem is dat de "basepath" niet wordt getoond.
. $basepath . is leeg, enig idee hoe ik dat kan fixen?

Ik heb het geprobeerd door: $basepath = 'http://www.mijn-domein.nl'; toe te voegen maar geen succes.
Helaas heb ik geen kennis van PHP

@fourroses666
Copy link

Toegevoegd:
$basepath = 'http://www.mijn-domein.nl';
--> clear cache /var/cache/...

@ktrfbr
Copy link

ktrfbr commented Mar 25, 2016

@fourroses666 Welke Magento versie gebruik jij? Ik heb het script geupload en mijn databases gegevens en store view aangepast. Ik krijg echter niets meer te zien dan "" in de XML. Heb jij nog een specifieke aanpassing gedaan om het werkend te krijgen?

EDIT: Inmiddels lijkt hij de artikelen wel in te laden, maar ik krijg geen output. , maar geen enkel artikel in de XML zichtbaar.

Iemand een idee hoe dit op te lossen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment