Speichern Sie spezifische verwandte Produkte, Upselling- oder Cross-Selling-Produkte in Magento
-
13-12-2019 - |
Frage
Magento speichert standardmäßig verwandte Produkte, Upsell- und Cross-Selling-Produkte im allgemeinen Umfang.Gibt es eine Erweiterung, um sie im Store-Bereich zu speichern?Hat jemand Erfahrung mit der Implementierung dieser Funktion?
Lösung
Das Speichern der Relation erfolgt im Mage_Adminhtml_Catalog_ProductController
.Sie können es über die verfolgen saveAction
Methode zur _initProductSave
Methode, bei der es um die Linie geht 640 Es ist im Produktobjekt festgelegt.
Im Mage_Catalog_Model_Product
Klasse, Methode _afterSave
online 540
die Methode Mage_Catalog_Model_Product_Link::saveProductRelations
heißt das ruft Mage_Catalog_Model_Resource_Product_Link::saveProductLinks
mit dem Argument $product
, $data
Und $typeId
das wird tatsächlich in der Datenbank gespeichert, was etwa in Zeile 99 geschieht.
Mit all dieser Rückverfolgung können wir nun tatsächlich etwas tun, um Ihre Frage zu lösen.
Um dies richtig zu machen, schreiben Sie Ihr eigenes Modul. Ein Tutorial dazu finden Sie hier Tutsplus.com.
Sie benötigen außerdem ein Installationsskript.Schau dir das an Inchoo-Tutorial über das.
Fügen wir also zunächst eine Spalte hinzu catalog_product_link
Tabelle, in der die Daten tatsächlich gespeichert sind (danke @MagePsycho für dieses Diagramm)
$installer = $this;
$connection = $installer->getConnection();
$installer->startSetup();
$installer->getConnection()
->addColumn($installer->getTable('catalog/product_link'),
'store_id',
array(
'type' => Varien_Db_Ddl_Table::TYPE_INT,
'nullable' => false,
'default' => 0,
'comment' => 'Store ID'
)
);
$installer->endSetup();
Jetzt schreiben wir das Ressourcenmodell um und speichern die Daten tatsächlich so, dass auch die Geschäfts-ID enthalten ist.
Fügen Sie Folgendes zu Ihren Modulen hinzu config.xml
, im global
Knoten.
<models>
<catalog_resource>
<rewrite>
<product_link>[Namespace]_[Module]_Model_Resource_Catalog_Product_Link</product_link>
</rewrite>
</catalog_resource>
</models>
mit folgendem Inhalt
class [Namespace]_[Module]_Model_Resource_Catalog_Product_Link extends Mage_Catalog_Model_Resource_Product_Link
{
/**
* Save Product Links process
*
* @param Mage_Catalog_Model_Product $product
* @param array $data
* @param int $typeId
* @return Mage_Catalog_Model_Resource_Product_Link
*/
public function saveProductLinks($product, $data, $typeId)
{
if (!is_array($data)) {
$data = array();
}
$attributes = $this->getAttributesByType($typeId);
$adapter = $this->_getWriteAdapter();
$bind = array(
':product_id' => (int)$product->getId(),
':link_type_id' => (int)$typeId
);
$select = $adapter->select()
->from($this->getMainTable(), array('linked_product_id', 'link_id'))
->where('product_id = :product_id')
->where('link_type_id = :link_type_id');
$links = $adapter->fetchPairs($select, $bind);
$deleteIds = array();
foreach($links as $linkedProductId => $linkId) {
if (!isset($data[$linkedProductId])) {
$deleteIds[] = (int)$linkId;
}
}
if (!empty($deleteIds)) {
$adapter->delete($this->getMainTable(), array(
'link_id IN (?)' => $deleteIds,
));
}
foreach ($data as $linkedProductId => $linkInfo) {
$linkId = null;
if (isset($links[$linkedProductId])) {
$linkId = $links[$linkedProductId];
unset($links[$linkedProductId]);
} else {
/**
* The actual change in the code
*/
$storeId = (int)$this->getRequest()->getParam('store');
$bind = array(
'product_id' => $product->getId(),
'linked_product_id' => $linkedProductId,
'link_type_id' => $typeId,
'store_id' => $storeId
);
$adapter->insert($this->getMainTable(), $bind);
$linkId = $adapter->lastInsertId($this->getMainTable());
}
foreach ($attributes as $attributeInfo) {
$attributeTable = $this->getAttributeTypeTable($attributeInfo['type']);
if ($attributeTable) {
if (isset($linkInfo[$attributeInfo['code']])) {
$value = $this->_prepareAttributeValue($attributeInfo['type'],
$linkInfo[$attributeInfo['code']]);
$bind = array(
'product_link_attribute_id' => $attributeInfo['id'],
'link_id' => $linkId,
'value' => $value
);
$adapter->insertOnDuplicate($attributeTable, $bind, array('value'));
} else {
$adapter->delete($attributeTable, array(
'link_id = ?' => $linkId,
'product_link_attribute_id = ?' => $attributeInfo['id']
));
}
}
}
}
return $this;
}
}
Ehrlich gesagt ist es nicht zu „sauber“, Beitragsdaten im Ressourcenmodell abzurufen, aber auf diese Weise müssen Sie nicht alle oben genannten Klassen und Methoden neu schreiben, um ein Extra zu akzeptieren $storeId
Variable.
Nun zum Abrufen der richtigen Sammlung im Raster, wenn Sie das Produkt bearbeiten.In diesem Fall müssen Sie die folgenden Blöcke neu schreiben
Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Related
Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Upsell
Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Crosssell
und ändern Sie die Methode _prepareCollection
um der abgerufenen Sammlung rund um die Linie einen Filial-ID-Filter hinzuzufügen 99.Was ungefähr so aussehen würde
$collection = Mage::getModel('catalog/product_link')->use[...]Links()
->getProductCollection()
->setProduct($this->_getProduct())
->addAttributeToSelect('*')
->addAttributeToFilter('store_id', $this->getRequest()->getParam('store_id'));
HAFTUNGSAUSSCHLUSS:Das ist ungetesteter Code.Das sollte funktionieren, erfordert aber möglicherweise hier und da einige Anpassungen.
Andere Tipps
Aus der Tabellenstruktur für verknüpfte Produkte (verwandte, Upsell- und Cross-Selling-Produkte) geht hervor, dass es keine store_id gibt.
Der erste Schritt besteht also darin, a hinzuzufügen store_id
Feld zur Tabelle hinzufügen.Anschließend müssen Sie die verknüpften Produkt-IDs vorbereiten, während Sie die Produkte gemäß der Store-Ansicht anzeigen und speichern.
Eventuell sind viele Optimierungen nötig, nur eine grobe Idee für den Anfang.