como adicionar produtos padrão à lista de produtos relacionados

7

Quero adicionar produtos padrão de certos IDs (exemplo: 1,5,7,3) a serem adicionados à lista de produtos relacionados sempre com todos os produtos no final da página do produto e não precisam ser armazenados no banco de dados. adicione-os à coleção de produtos relacionados no magento

mano
fonte

Respostas:

5

Você pode gravar um observador catalog_product_collection_load_aftere adicionar produtos à coleção carregada se a coleção for a coleção de produtos relacionados :

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);
        }
    }
}

Algumas partes que eu gostaria de destacar:

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

Isso carrega os produtos, [1,5,7,3]mas exclui o próprio produto e os produtos que já estão definidos manualmente como produtos relacionados. Caso contrário, obteríamos um erro devido a duplicatas na coleção. Você provavelmente deseja mover esses IDs codificados para uma configuração.

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

Isso prepara a coleção de produtos para carregar os dados necessários para exibir preços, o link do produto e quaisquer atributos configurados como "usados ​​na lista de produtos", mas não mais.

Esta é uma solução muito semelhante à do meu módulo AutoUpsell descrito em Obter lista de produtos por ID de categoria em view.phtml , copiei a maior parte do código de lá com pequenas modificações.

Fabian Schmengler
fonte
5

Você pode fazer isso com a ajuda de um método observador personalizado. Para fazer isso, chame a função de seu observador no evento catalog_product_save_after.

Ao usar isso, sempre que um produto for salvo no painel do administrador, você poderá verificar se o produto possui produtos relacionados atribuídos ou não.

Se não houver produtos relacionados, você poderá atribuir produtos relacionados (por IDs de produto) programaticamente.

Suponha que o produto no qual você deseja atribuir produtos relacionados tenha o ID 2 e os IDs relacionados sejam 1,5,7 e 3.

Então:

$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();
}

Por favor, deixe-me saber se você tem alguma dúvida.

Mohit Kumar Arora
fonte
Eu preciso adicionar alguns dos produtos sempre relacionados, a todos os produtos em minha loja, mas não precisa armazenar no banco de dados,
mano
Eu só quero adicionar os produtos relacionados padrão na página do produto de forma programática, não com o banco de dados, então estou procurando o arquivo em \ app \ code \ core \ Mage \ Catalog \ Block \ Product \ List \ Related.php para adicionar o padrão com a coleção, como adicionar o produto a essa coleção?
mano 27/07
Desculpe, mas não consegui entender o que você quer dizer no seu último comentário?
Mohit Kumar Arora
eu só quero adicionar produtos com o ID 1,5,7,3 relacionados a todos os produtos da loja, não quero armazenar isso no banco de dados.
mano 27/07
-2

Crie um novo arquivo \app\code\local\Mage\Catalog\Block\Product\List\Related.phpe procure o método e substitua pelo código abaixo:

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
fonte
você pode adicionar comentários em cada estágio para que possamos entender como isso funciona.
Mano
1
Copie também o arquivo no caminho "\ app \ code \ local \ Mage \ Catalog \ Block \ Product \ List \ Related.php" para que as alterações não sejam removidas no momento da atualização do magento.
Chirag Rajput
1
Por favor, não faça alterações diretamente nos arquivos principais do magento. É sempre melhor substituir os arquivos principais do magento para evitar problemas durante a atualização do magento.
Mohit Kumar Arora
1
Reescrever a classe é uma abordagem válida (embora não seja necessária), mas você carrega uma coleção completa três vezes, o que não é uma boa idéia em termos de desempenho. Poderia ser melhorado com $ids = array_merge([1,3,5,7], $product->getRelatedProductCollection()->getAllIds());seguido por uma única carga com #addIdFilter($ids)
Fabian Schmengler
1
na verdade não é três cargas, mas dois, além de duas consultas adicionais para IDs: primeiro (implícita) de carga: foreach ($this->_itemCollection, duas consultas para IDs: array_merge($productscoll1->getAllIds(), $productscoll2->getAllIds()); , segunda carga: $this->_itemCollection->load();. Com a minha sugestão acima, você iria reduzir pela metade que para uma consulta ID e uma carga coleção
Fabian Schmengler