Hinzufügen von Standardprodukten zur Liste verwandter Produkte

7

Ich möchte Standardprodukte mit bestimmten IDs hinzufügen (Beispiel: 1,5,7,3), die der Liste der verwandten Produkte immer mit allen Produkten am Ende der Produktseite hinzugefügt werden sollen, und muss nicht in der Datenbank gespeichert werden Fügen Sie diese mit der zugehörigen Produktkollektion in Magento hinzu

Mano
quelle

Antworten:

5

Sie können einen Beobachter für schreiben catalog_product_collection_load_afterund dann Produkte zur geladenen Sammlung hinzufügen, wenn es sich bei der Sammlung um die verwandte Produktsammlung handelt :

use Mage_Catalog_Model_Product as Product;
use Mage_Catalog_Model_Product_Link as RelatedProduct;
use Mage_Catalog_Model_Resource_Product_Link_Product_Collection as RelatedProductCollection;

class IntegerNet_AutoRelated_Model_Observer
{
    /**
     * @see event catalog_product_collection_load_after
     * @param Varien_Event_Observer $observer
     * @throws Mage_Core_Exception
     */
    public function addToRelatedCollection(Varien_Event_Observer $observer)
    {
        $collection = $observer->getCollection();
        if ($collection instanceof RelatedProductCollection
            && $collection->getLinkModel()->getLinkTypeId() === RelatedProduct::LINK_TYPE_RELATED
        ) {
            $this->addItems($collection);
        }
    }

    protected function addItems(RelatedProductCollection $collection)
    {
        /** @var Mage_Catalog_Model_Resource_Product_Collection $productsToAdd */
        $productsToAdd = Mage::getResourceModel('catalog/product_collection');
        $productsToAdd
            ->addStoreFilter()
            ->addIdFilter(array_diff([1,5,7,3], [$collection->getProduct()->getId()], $collection->getAllIds()))
            ->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
            ->addMinimalPrice()
            ->addFinalPrice()
            ->addTaxPercents()
            ->setPageSize($numberOfItems)
            ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
            ->addUrlRewrite();
        foreach ($productsToAdd as $product) {
            $collection->addItem($product);
        }
    }
}

Einige Teile, die ich hervorheben möchte:

->addIdFilter(array_diff([1,5,7,3], [$collection->getProduct()->getId()], $collection->getAllIds()))

Dadurch werden die Produkte [1,5,7,3]geladen, jedoch das Produkt selbst und die Produkte, die bereits manuell als verwandte Produkte definiert wurden, ausgeschlossen. Andernfalls würden wir aufgrund von Duplikaten in der Sammlung einen Fehler erhalten. Sie möchten diese fest codierten IDs wahrscheinlich in eine Konfiguration verschieben.

->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addUrlRewrite();

Dadurch wird die Produktkollektion darauf vorbereitet, die erforderlichen Daten zum Anzeigen der Preise, des Produktlinks und aller Attribute zu laden, die als "in der Produktliste verwendet" konfiguriert sind, jedoch nicht mehr.

Dies ist eine sehr ähnliche Lösung wie in meinem AutoUpsell-Modul, das unter Produktliste nach Kategorie-ID in view.phtml abrufen beschrieben ist. Ich habe den größten Teil des Codes von dort mit geringfügigen Änderungen kopiert.

Fabian Schmengler
quelle
5

Sie können dies mit Hilfe einer benutzerdefinierten Beobachtermethode tun. Rufen Sie dazu die Funktion Ihres Beobachters bei der Veranstaltung auf catalog_product_save_after.

Auf diese Weise können Sie bei jedem Speichern eines Produkts im Admin-Bereich überprüfen, ob dem Produkt verwandte Produkte zugewiesen sind oder nicht.

Wenn keine verwandten Produkte vorhanden sind, können Sie verwandte Produkte (nach Produkt-IDs) programmgesteuert zuweisen.

Angenommen, das Produkt, dem Sie verwandte Produkte zuweisen möchten, hat die ID 2 und die zugehörigen IDs sind 1,5,7 und 3.

Dann:

$product = Mage::getModel('catalog/product')->load(2);
if($product)
{
    $sRelatedIds = '1,5,7,3';
    $aRelatedIds = explode(',', $sRelatedIds);
    $aParams = array();
    $nRelatedCounter = 1;

    foreach($aRelatedIds as $id)
    {
        $aRelatedProduct = Mage::getModel('catalog/product')->load($id);
        $aParams[$aRelatedProduct['entity_id']] = array('position' => $nRelatedCounter);
        $nRelatedCounter++;
    }

    $product->setRelatedLinkData($aParams);
    $product->save();
}

Bitte lassen Sie mich wissen, wenn Sie Fragen haben.

Mohit Kumar Arora
quelle
Ich muss einige der Produkte, die immer in Beziehung stehen, zu allen Produkten in meinem Shop hinzufügen, muss sie aber nicht in der Datenbank speichern,
mano
Ich möchte nur die standardmäßigen verwandten Produkte auf der Produktseite programmgesteuert und nicht mit der Datenbank hinzufügen. Daher schaue ich in der Datei unter \ app \ code \ core \ Mage \ Catalog \ Block \ Product \ List \ Related.php nach, um die Standardprodukte hinzuzufügen Wie füge ich das Produkt mit der Sammlung zu dieser Sammlung hinzu?
Mano
Entschuldigung, aber ich konnte nicht verstehen, was Sie in Ihrem letzten Kommentar sagen möchten?
Mohit Kumar Arora
Ich möchte nur Produkte mit der ID 1,5,7,3 hinzufügen, die sich auf alle Produkte im Geschäft beziehen. Ich möchte das nicht in einer Datenbank speichern.
Mano
-2

Erstellen Sie eine neue Datei in \app\code\local\Mage\Catalog\Block\Product\List\Related.phpund suchen Sie nach der Methode und ersetzen Sie sie durch den folgenden Code:

protected function _prepareData()
{
    $product = Mage::registry('product');
    /* @var $product Mage_Catalog_Model_Product */

    $this->_itemCollection = $product->getRelatedProductCollection()
        ->addAttributeToSelect('required_options')
        ->setPositionOrder()
        ->addStoreFilter();

    foreach ($this->_itemCollection as $product) {
        $productIds1[] = $product->getId();   // here we are getting the product ids of related products of current product.
    }

    $productIds = [1, 5, 7, 3];    // here you can set product id you want to show by default in all products.
    $productscoll1 = Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToFilter('entity_id', ['in' => $productIds]);

    $productscoll1->getSelect()->order("find_in_set(entity_id,'" . implode(',', $productIds) . "')");

    $productscoll2 = Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToFilter('entity_id', ['in' => $productIds1]);
    $productscoll2->getSelect()->order("find_in_set(entity_id,'" . implode(',', $productIds) . "')");

    // print_r($productscoll1->getAllIds());
    // print_r($productscoll2->getAllIds());

    $merged_ids = array_merge($productscoll1->getAllIds(), $productscoll2->getAllIds());   // here we merge both collection ids.
    // can sometimes use "getLoadedIds()" as well

    //print_r($merged_ids);
    //exit;

    $this->_itemCollection = Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToFilter('entity_id', ['in' => $merged_ids]);

    // In this we set collection with default products merge with related products

    if (Mage::helper('catalog')->isModuleEnabled('Mage_Checkout')) {
        Mage::getResourceSingleton('checkout/cart')->addExcludeProductFilter($this->_itemCollection,
            Mage::getSingleton('checkout/session')->getQuoteId()
        );
        $this->_addProductAttributesAndPrices($this->_itemCollection);
    }
    //        Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
    Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);

    $this->_itemCollection->load();

    foreach ($this->_itemCollection as $product) {
        $product->setDoNotUseCategoryId(true);
    }

    return $this;
}
Chirag Rajput
quelle
Können Sie in jeder Phase Kommentare hinzufügen, damit wir verstehen, wie es funktioniert?
Mano
1
Kopieren Sie die Datei auch in den Pfad "\ app \ code \ local \ Mage \ Catalog \ Block \ Product \ List \ Related.php", damit die Änderungen zum Zeitpunkt des Upgrades von Magento nicht entfernt werden.
Chirag Rajput
1
Bitte nehmen Sie keine Änderungen direkt in den Magento-Kerndateien vor. Es ist immer besser, Magento-Kerndateien zu überschreiben, um Probleme beim Upgrade von Magento zu vermeiden.
Mohit Kumar Arora
1
Das Umschreiben der Klasse ist ein gültiger Ansatz (obwohl nicht erforderlich), aber Sie laden eine vollständige Sammlung dreimal, was in Bezug auf die Leistung keine gute Idee ist. Könnte verbessert werden mit $ids = array_merge([1,3,5,7], $product->getRelatedProductCollection()->getAllIds());gefolgt von einer einzigen Ladung mitaddIdFilter($ids)
Fabian Schmengler
1
Tatsächlich sind es nicht drei Ladevorgänge, sondern zwei plus zwei zusätzliche Abfragen für IDs: erstes (implizites) Laden : foreach ($this->_itemCollection, zwei Abfragen für IDs : array_merge($productscoll1->getAllIds(), $productscoll2->getAllIds()); , zweites Laden : $this->_itemCollection->load();. Mit meinem Vorschlag oben würden Sie das auf eine ID-Abfrage und eine Sammlungslast halbieren
Fabian Schmengler