-
-
Save julesjanssen/1017978 to your computer and use it in GitHub Desktop.
<?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; | |
} |
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 ([email protected])
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.
Erg slim om direct de database uit te lezen.
Hoe zou je het script uitbreiden zodat je de waarde van een attribuut kunt inlezen?
@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/
@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'?
@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)
@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!
Bedankt voor de feed! Ik kom hem met een paar kleine aanpassingen (log path, sku escapen) zo gebruiken voor mijn Beslist export. :)
Kun je mij vertellen hoe je de XML automatiche kan wegschrijven in een directory?
Alvast bedankt
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
@BDStudioNL, gewoon de database gegevens aanpassen in het document en uploaden. Dan als je naar het bestand gaat zie je de feed.
@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
Toegevoegd:
$basepath = 'http://www.mijn-domein.nl';
--> clear cache /var/cache/...
@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?
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.