Kurzinfo


Andreas von Studnitz

mehr »

Andreas von Studnitz arbeitet seit 2012 als Geschäftsführer und Entwickler für die Magento-Agentur integer_net GmbH. Aktuelle Informationen finden Sie unter www.integer-net.de

Kontakt

Telefon:
0170 486 0 464

E-Mail:
avs(at)avs-webentwicklung.de

Twitter: twitter.com/avstudnitz

mehr »

< Magento ImportExport: Der Visibility-Bug

Magento: Partielle Indizierung von Produkten

18.06.2012 15:20

Im Anschluss an einen Produktimport ist häufig eine Neuindizierung notwendig. Sind nur wenige Produkte importiert worden, ist es sinnvoller, keine komplette Neuindizierung durchzuführen, sondern nur partiell für die importierten Produkte. Wie das in einer individuellen Schnittstelle geht, beschreibt dieser Artikel.

Für den Produktimport in einer individuellen Schnittstelle gibt es mehrere Methoden. Früher habe ich üblicherweise den Import über Magento-Models umgesetzt, der zwar langsam, aber zuverlässig funktioniert. Heute setze ich die seit Magento 1.5 verfügbare ImportExport-Schnittstelle ein, die deutlich schneller arbeitet und komfortabel zu bedienen ist, aber ein paar Fallstricke hat (siehe dazu meinen Artikel zu ImportExport bei den Webguys). Unter anderem ist eine Indizierung nicht enthalten, diese muss manuell im Nachhinein durchgeführt werden. Für individuelle Importe nutze ich hier mein frei verfügbares Modul AvS_FastSimpleImport, das Importdaten als PHP-Arrays akzeptiert.

Produkt-Updates und Neuprodukte

Für die Beschreibung des partiellen Imports gehe ich davon aus, dass soeben ein Produkt importiert wurde und als Produkt-Model $product der Klasse Mage_Catalog_Model_Product zur Verfügung steht. Die Indizierung erfolgt dann mit folgendem PHP-Code:

/** @var $stockItem Mage_CatalogInventory_Model_Stock_Item */
$stockItem = Mage::getModel('cataloginventory/stock_item')
->loadByProduct($product->getId());
$stockItem->setForceReindexRequired(true);
Mage::getSingleton('index/indexer')->processEntityAction(
$stockItem,
Mage_CatalogInventory_Model_Stock_Item::ENTITY,
Mage_Index_Model_Event::TYPE_SAVE
);
$product
->setForceReindexRequired(true)
->setIsChangedCategories(true);
Mage::getSingleton('index/indexer')->processEntityAction(
$product,
Mage_Catalog_Model_Product::ENTITY,
Mage_Index_Model_Event::TYPE_SAVE
);

Es muss also der Indexer zunächst für das zugehörige StockItem (das teilweise auch per $product->getStockItem() zur Verfügung steht, beim Import über ImportExport aber z.B. noch nicht) und dann für das Produkt ausgeführt werden.

Gelöschte Produkte

Um gelöschte Produkte aus dem Index zu entfernen, ist das Vorgehen etwas anders, da hier das Produkt-Model nicht mehr zur Verfügung steht. Es muss daher vor dem eigentlichen Löschen des Produktes das Index-Event registriert werden, das am Ende ausgeführt wird. Der Code dafür ist wie folgt:

Mage::getSingleton('index/indexer')->logEvent(
$product,
Mage_Catalog_Model_Product::ENTITY,
Mage_Index_Model_Event::TYPE_DELETE
);
$product->delete(); // Oder sonstiger Code zum Löschen des Produkts
Mage::getSingleton('index/indexer')->indexEvents(
Mage_Catalog_Model_Product::ENTITY,
Mage_Index_Model_Event::TYPE_DELETE
);

Der letzte Befehl muss nur einmalig ausgeführt werden, auch wenn mehrere Produkte gelöscht wurden. Diese Trennung von Logging und Indexing kann auch beim Save-Event (s.o.) eingesetzt werden, bringt jedoch keinen nennenswerten Performancegewinn.

AvS_FastSimpleImport

In meiner freien Import-Schnittstelle habe ich dieses Vorgehen implementiert. Details befinden sich in der Klasse AvS_FastSimpleImport_Model_Import_Entity_Product, aufgerufen von AvS_FastSimpleImport_Model_Import. Der Aufruf der Schnittstelle zum Import eines Beispielprodukts sieht wie folgt aus:

$data = array(
array(
'sku' => '1234567',
'_type' => 'simple',
'_attribute_set' => 'Default',
'_product_websites' => 'base',
'name' => 'Default',
'price' => 0.99,
'description' => 'Default',
'short_description' => 'Default',
'weight' => 0,
'status' => 1,
'visibility' => 4,
'tax_class_id' => 2,
'qty' => 76,
),
);
/** @var $import AvS_FastSimpleImport_Model_Import */
$import = Mage::getModel('fastsimpleimport/import');
$import->setPartialIndexing(true);
$import->processProductImport($data);

Danksagung

Die Basics für die Partielle Indizierung habe ich Magento Answers entnommen und weiterentwickelt. Vielen Dank an die Magento Expert Consulting Group und an Gerrit Pechman von aijko für die Vorarbeiten und Anregungen.

Kommentare

Keine Kommentare
Kommentar hinzufügen












Den Code eingeben: *


* - Pflichtfeld