isotope_feeds fit für merchant-center-update?
Hallo zusammen,
weiß jemand, ob die aktuelle Version der Erweiterung isotope_feeds den neuen Richtlinien für das google-merchant-center entspricht?
Gruß
Hauge
Neue Richtlinien für merchant center
Hallo Ale, danke für Deine Info.
Ich habe vor kurzem ne Meldung von google bekommen, dass die Richtlinien geändert wurden und diese Änderung bis September 2011 durchgeführt wird. Es sollen künftig etwa Attribute für Zustand (neu, gebraucht etc.) oder auch die "google-produktlinie" angegeben werden.
Siehe: http://www.google.com/support/mercha...&answer=188494
Gruß
Hauge
isotope_feeds mit Varianten
Wie kann ich mit isotope_feeds die Varianten unserer Produkte berücksichtigen?
Contao isotope & google merchant center
Ich habe eine konkrete Frage:
Die Integration von Google Merchant Center ist bedingt durch Kundenwünsche ein mittlerweile nahezu unabdingbarer Bestandteil eines Shops.
(ist ja auch verständlich, da es eine einfache Möglichkeit ist Verkaufsziele zu erreichen).
Wird es nach heutigem Stand der Dinge in diesem Bereich eine Entwicklung geben, welche verlässlich in das System integriert wird oder eher nicht?
(Egal ob Erweiterung oder feste Integration)
Anhand der milestones ist hier leider nichts erkennbar:
Info: http://projects.winanscreative.com/p...245/milestones
Und anhand der Entwicklung von Erweiterungen kann ich da nicht viel herauslesen:
Info: http://projects.winanscreative.com/p...1#comment11620
Wenn ich das alles richtig interpretiere und auch sehe, dass isotope_feeds seit 2.9.2 nicht mehr upgedatet wurde, so wird es da für contao 2.10 in nächster Zukunft KEINE Anbindung von isotope an das google merchant center geben?
Auf eine Antwort freut sich
Hauge
Google Merchant Center und Isotope - neues Modul
Hallo Zusammen,
ich möchte diesen Thread nun wieder mal nach vorne holen.
Ich habe nun einige Shops mit isotope aufgesetzt - stets in der Hoffnung, dass die Merchant-Center-Anbindung irgendwann zum Laufen kommt.
Derzeit befindet sich auf github eine version von isotope-googlemerchant. Leider bringe ich nun auch diese Version nicht wirklich zum laufen.
Gibt es hier schon eine ungefähre Zeitangabe (wäre schon hilfreich wenn man wüsste ob das ganze überhaupt noch weiter verfolgt wird)
Ich versuche jedenfalls vergeblich seit etwa August letzten Jahres die Anbindung herzustellen - mit verschiedensten Versionen von isotope, von contao und dem damaligen modul isotope_feeds und jetzt isotope_googlemerchant.
Da ich ja ein kleiner Fan von Isotope bin, möchte ich nach heutigem Stand der Dinge empfehlen, die auf:
http://de.contaowiki.org/Online-Shops eingetragene Exportschnittstelle zum Merchant-Center mal zu entfernen.
Dies wird einigen die daran interessiert sind sicher helfen das Ganze mal etwas besser einzuordnen.
Gruß
Hauge
Liste der Anhänge anzeigen (Anzahl: 3)
Möglichkeit zur Umsetzung gefunden / Zwischenlösung
Hab da ne Zwischenlösung mit dem älteren Modul zur Anbindung bis die Version auf github läuft.
Etwas kompliziert - aber es funktioniert (zumindest bei mir )
Lösung läuft über die Attribute:
1. isotope_feeds installieren
2. folgende Codes im Modul abändern:
Datei GoogleFeed.php:
PHP-Code:
<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
/**
* TYPOlight Open Source CMS
* Copyright (C) 2005-2010 Leo Feyer
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, please visit the Free
* Software Foundation website at <http://www.gnu.org/licenses/>.
*
* PHP version 5
* @copyright Winans Creative 2009, Intelligent Spark 2010, iserv.ch GmbH 2010
* @author Fred Bliss <fred.bliss@intelligentspark.com>
* @author Andreas Schempp <andreas@schempp.ch>
* @license http://opensource.org/licenses/lgpl-3.0.html
*/
class GoogleFeed extends Feed
{
/**
* Generate an Google RSS 2.0 feed and return it as XML string
* @return string
*/
public function generateGoogle()
{
$xml = '<?xml version="1.0"?>' . "\n";
$xml .= '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" version="2.0">' . "\n";
$xml .= ' <channel>' . "\n";
$xml .= ' <title>' . specialchars($this->title) . '</title>' . "\n";
$xml .= ' <description>' . specialchars($this->description) . '</description>' . "\n";
$xml .= ' <link>' . specialchars($this->link) . '</link>' . "\n";
foreach ($this->arrItems as $objItem)
{
$xml .= ' <item>' . "\n";
$xml .= ' <title><![CDATA[' . specialchars($objItem->title) . ']]></title>' . "\n";
$xml .= ' <link>' . specialchars($objItem->link) . '</link>' . "\n";
$xml .= ' <description><![CDATA[' . preg_replace('/[\n\r]+/', ' ', $objItem->description) . ']]></description>' . "\n";
$xml .= ' <g:image_link><![CDATA[' . specialchars($objItem->image) . ']]></g:image_link>' . "\n";
$xml .= ' <g:id>' . specialchars($objItem->sku) . '</g:id>' . "\n";
$xml .= ' <g:google_product_category>' . specialchars($objItem->google_category) . '</g:google_product_category>' . "\n";
$xml .= ' <g:product_type>' . specialchars($objItem->product_type) . '</g:product_type>' . "\n";
$xml .= ' <g:price>' . specialchars($objItem->price) . '</g:price>' . "\n";
$xml .= ' <g:condition>' . specialchars($objItem->google_condition) . '</g:condition>' . "\n";
$xml .= ' <g:availability>' . specialchars($objItem->availability) . '</g:availability>' . "\n";
$xml .= ' <g:brand>' . specialchars($objItem->brand) . '</g:brand>' . "\n";
$xml .= ' <g:gtin>' . specialchars($objItem->gtin) . '</g:gtin>' . "\n";
$xml .= ' </item>' . "\n";
}
$xml .= ' </channel>' . "\n";
$xml .= '</rss>';
return $xml;
}
}
Datei isotopeFeeds.php:
PHP-Code:
<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
/**
* TYPOlight Open Source CMS
* Copyright (C) 2005-2010 Leo Feyer
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, please visit the Free
* Software Foundation website at <http://www.gnu.org/licenses/>.
*
* PHP version 5
* @copyright Winans Creative 2009, Intelligent Spark 2010, iserv.ch GmbH 2010
* @author Fred Bliss <fred.bliss@intelligentspark.com>
* @author Andreas Schempp <andreas@schempp.ch>
* @license http://opensource.org/licenses/lgpl-3.0.html
*/
class IsotopeFeeds extends Controller
{
/**
* Import some default libraries
*/
protected function __construct()
{
parent::__construct();
$this->import('Database');
}
/**
* Update a particular store config's RSS feed
* @param integer
*/
public function generateFeed($intId)
{
$objConfig = $this->Database->prepare("SELECT * FROM tl_iso_config WHERE id=? AND addFeed=?")
->limit(1)
->execute($intId, 1);
if ($objConfig->numRows < 1)
{
return;
}
$objConfig->feedName = strlen($objConfig->feedName) ? $objConfig->feedName : 'products' . $objConfig->id;
$arrTypes = deserialize($objConfig->feedTypes);
// Delete XML file
if ($this->Input->get('act') == 'delete')
{
$this->import('Files');
foreach($arrTypes as $feedType)
{
$this->Files->delete($objConfig->feedName . '-' . $feedType . '.xml');
}
}
// Update XML file
else
{
foreach($arrTypes as $feedType)
{
$this->generateFiles($objConfig->row(), $feedType);
$this->log('Generated products feed ' . $objConfig->feedName . '-'. $feedType . '.xml"', 'IsotopeFeeds generateFeed()', TL_CRON);
}
}
}
/**
* Delete old files and generate all product feeds
*/
public function generateFeeds()
{
$this->removeOldFeeds();
$objConfig = $this->Database->execute("SELECT * FROM tl_iso_config WHERE addFeed=1");
while ($objConfig->next())
{
$objConfig->feedName = strlen($objConfig->feedName) ? $objConfig->feedName : 'products' . $objConfig->id;
$arrFeedTypes = deserialize($objConfig->feedTypes);
foreach( $arrFeedTypes as $feedType )
{
$this->generateFiles($objConfig->row(), $feedType);
$this->log('Generated product feed ' . $objConfig->feedName . '-'. $feedType . '.xml"', 'IsotopeFeeds generateFeeds()', TL_CRON);
}
}
}
/**
* remove feeds hook to preserve files
*/
public function preserveFeeds()
{
$objConfig = $this->Database->execute("SELECT * FROM tl_iso_config WHERE addFeed=1");
$arrFeeds = array();
$objConfig->feedName = strlen($objConfig->feedName) ? $objConfig->feedName : 'products' . $objConfig->id;
$arrFeedTypes = deserialize($objConfig->feedTypes);
if(is_array($arrFeedTypes) && count($arrFeedTypes)>0)
{
foreach( $arrFeedTypes as $feedType )
{
$arrFeeds[] = $objConfig->feedName . '-'. $feedType;
}
}
return $arrFeeds;
}
/**
* hook to add feed to head
*/
public function addFeedToLayout(Database_Result $objPage, Database_Result $objLayout, PageRegular $objPageRegular)
{
$arrFeeds = deserialize($objLayout->productfeeds);
if(is_array($arrFeeds) && count($arrFeeds) > 0)
{
foreach($arrFeeds as $feed)
{
$arrConfig = explode('|', $feed);
if(is_array($arrConfig) && count($arrConfig) > 0)
{
$objConfig = $this->Database->prepare("SELECT * FROM tl_iso_config WHERE addFeed=1 AND id=?")->limit(1)->execute($arrConfig[0], $arrConfig[1]);
$arrTypes = deserialize($objConfig->feedTypes);
foreach($arrTypes as $type)
{
if($arrConfig[1]==$type)
{
$strFeedname = strlen($objConfig->feedName) ? $objConfig->feedName : 'products' . $objConfig->id;
$strName = $strFeedname . '-'. $type;
$base = strlen($objConfig->feedBase) ? $objConfig->feedBase : $this->Environment->base;
$GLOBALS['TL_HEAD'][] = '<link rel="alternate" href="' . $base . $strName . '.xml" type="application/rss+xml" title="' . $objConfig->feedTitle . '" />' . "\n";
}
}
}
}
}
}
/**
* Generate an XML files and save them to the root directory
* @param array
* @param string
*/
protected function generateFiles($arrConfig, $strType)
{
$this->import('Isotope');
$arrType = $GLOBALS['ISO_FEEDS'][$strType];
$time = time();
$strLink = strlen($arrConfig['feedBase']) ? $arrConfig['feedBase'] : $this->Environment->base;
$strFile = $arrConfig['feedName'] . '-' . $strType;
try
{
$objFeed = new $arrType[0]($strFile);
}
catch (Exception $e)
{
$objFeed = new GoogleFeed($strFile);
}
$objFeed->link = $strLink;
$objFeed->title = $arrConfig['feedTitle'];
$objFeed->description = $arrConfig['feedDesc'];
$objFeed->language = $arrConfig['language'];
$objFeed->published = time();
// Get root pages that belong to this store config.
$objRoot = $this->Database->prepare("SELECT * FROM tl_page p WHERE type='root' AND iso_config=?")->execute($arrConfig['id']);
if($objRoot->numRows)
{
//Get an array of all pages under the root so that we can compare to product categories
$objPages = $this->Database->execute("SELECT id FROM tl_page");
while($objPages->next())
{
$objDetails = $this->getPageDetails($objPages->id);
if($objDetails->rootId == $objRoot->id)
{
$arrPages[] = $objPages->id;
}
}
}
$objProducts = $this->Database->execute("SELECT *, (SELECT class FROM tl_iso_producttypes WHERE tl_iso_products.type=tl_iso_producttypes.id) AS product_class FROM tl_iso_products WHERE pid=0 AND (start='' OR start<$time) AND (stop='' OR stop>$time) AND published=1 ORDER BY tstamp DESC");
while($objProducts->next())
{
$strClass = $GLOBALS['ISO_PRODUCT'][$objProducts->product_class]['class'];
if(count($arrPages))
{
$arrProductPages = deserialize($objProducts->pages, true);
if( count(array_intersect($arrPages, $arrProductPages)) )
{
$arrProducts[] = $objProducts->row();
}
}
else
{
$arrProducts[] = $objProducts->row();
}
}
// Get default URL
$objParent = $this->Database->prepare("SELECT id, alias FROM tl_page WHERE id=?")
->limit(1)
->execute($arrConfig['feedJumpTo']);
if(!$objParent->numRows)
{
//Get the first reader page we can find
//@todo: restrict it to store config root
$objModules = $this->Database->prepare("SELECT iso_reader_jumpTo FROM tl_module WHERE iso_reader_jumpTo!=''")->limit(1)->execute();
$objParent = $this->Database->prepare("SELECT id, alias FROM tl_page WHERE id=?")
->limit(1)
->execute($objModules->iso_reader_jumpTo);
}
$strUrl = $this->generateFrontendUrl($objParent->fetchAssoc(), '/product/%s');
// Parse items
foreach($arrProducts as $product)
{
$objItem = new FeedItem();
$objItem->title = $product['name'];
$objItem->link = $this->getLink($product, $strLink . $strUrl);
$objItem->published = time();
// Prepare the description
$strDescription = $product['description'];
$strDescription = $this->replaceInsertTags($strDescription);
$objItem->description = $this->convertRelativeUrls($strDescription, $strLink);
// Prepare the new googlefeed data
$objItem->google_category = strlen($product['google_category']) ? $product['google_category'] : $product['alias'];
$objItem->product_type = strlen($product['product_type']) ? $product['product_type'] : $product['alias'];
$objItem->google_condition = strlen($product['google_condition']) ? $product['google_condition'] : $product['alias'];
$objItem->availability = strlen($product['availability']) ? $product['availability'] : $product['alias'];
$objItem->brand = strlen($product['brand']) ? $product['brand'] : $product['alias'];
$objItem->gtin = strlen($product['gtin']) ? $product['gtin'] : $product['alias'];
//Sku, price, etc
$objItem->sku = strlen($product['sku']) ? $product['sku'] : $product['alias'];
$objItem->price = $product['price'] .' '. $this->Isotope->Config->currency;
//Prepare the images
$arrImages = $this->getProductImages($product);
if(is_array($arrImages) && count($arrImages)>0)
{
$objItem->image = $this->Environment->base . $arrImages[0]['medium'];
$objItem->addEnclosure($arrImages[0]['medium']);
}
$objFeed->addItem($objItem);
}
// Create file
$objRss = new File($strFile . '.xml');
$objRss->write($this->replaceInsertTags($objFeed->$arrType[1]()));
$objRss->close();
}
/**
* Return the link of a product
* @param object
* @param string
* @return string
*/
protected function getLink($arrProduct, $strUrl)
{
// Link to the default page
return sprintf($strUrl, ((strlen($arrProduct['alias']) && !$GLOBALS['TL_CONFIG']['disableAlias']) ? $arrProduct['alias'] : $arrProduct['id']));
}
protected function getProductImages($arrProduct)
{
$this->import('Isotope');
$varValue = deserialize($arrProduct['images']);
if(is_array($varValue) && count($varValue))
{
foreach( $varValue as $k => $file )
{
$strFile = 'isotope/' . substr($file['src'], 0, 1) . '/' . $file['src'];
if (is_file(TL_ROOT . '/' . $strFile))
{
$objFile = new File($strFile);
if ($objFile->isGdImage)
{
$strImage = $this->getImage($strFile, 250, 250, 'proportional');
if ($strImage != $strFile && $size['watermark'] != '')
{
$this->import('IsotopeFrontend');
$strImage = $this->IsotopeFrontend->watermarkImage($strImage, $size['watermark'], $size['position']);
}
$arrSize = @getimagesize(TL_ROOT . '/' . $strImage);
if (is_array($arrSize) && strlen($arrSize[3]))
{
$file['medium_size'] = $arrSize[3];
}
$file['medium'] = $strImage;
$arrReturn[] = $file;
}
}
}
}
// No image available, add default image
if (!count($arrReturn) && is_file(TL_ROOT . '/' . $this->Isotope->Config->missing_image_placeholder))
{
$strImage = $this->getImage($this->Isotope->Config->missing_image_placeholder, 250, 250, 'proportional');
$arrSize = @getimagesize(TL_ROOT . '/' . $strImage);
if (is_array($arrSize) && strlen($arrSize[3]))
{
$file['medium_size'] = $arrSize[3];
}
$file['medium'] = $strImage;
$arrReturn[] = $file;
}
return $arrReturn;
}
}
?>
3. Neue Attribute anlegen welche vom Merchant Center benötigt werden
Anhang 7224
Anhang 7225
4. Feed sollte dann in etwa so aussehen:
Anhang 7226
ANGABEN WIE IMMER OHNE GEWÄHR!