乐趣区

关于magento2:Load-additional-product-attributes-in-Wishlist

Where are the products loaded?
The products are loaded in the “_afterLoad” method of the items collection. A product collection is instantiated there based on the product ids of all items and directly loaded to assign the products to their wishlist items.

Unfortunately it is instantiated and loaded from within the same method, so it is not easily changed via plugin. The attributes to select are hard coded:

$attributesToSelect = [
      'name',
      'visibility',
      'small_image',
      'thumbnail',
      'links_purchased_separately',
      'links_title',
  ];

The method dispatches an event wishlist_item_collection_products_after_load, but unfortunately no “before load” event.

How can you specify the loaded attributes then?
You could replace the collection class, or write a plugin for the _assignProducts method that replaces the whole method.

But I found a better way: use a custom product collection factory that sets the attributes to select during creation.

These files go into a custom module Stack_Wishlist:

etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="\Magento\Wishlist\Model\ResourceModel\Item\Collection">
        <arguments>
            <argument name="productCollectionFactory" xsi:type="object">\Stack\Wishlist\ResourceModel\ProductCollectionFactory</argument>
        </arguments>
    </type>
</config>

ResourceModel/ProductCollectionFactory.php

<?php

namespace Stack\Wishlist\ResourceModel;

use Magento\Catalog\Model\Config as CatalogConfig;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
use Magento\Framework\ObjectManagerInterface;

class ProductCollectionFactory extends \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
{
    /**
     * @var CatalogConfig
     */
    protected $catalogConfig;

    public function __construct(ObjectManagerInterface $objectManager, CatalogConfig $catalogConfig, $instanceName = ProductCollection::class)
    {parent::__construct($objectManager, $instanceName);
        $this->catalogConfig = $catalogConfig;
    }

    public function create(array $data = array())
    {$collection = parent::create($data);
        $collection->addAttributeToSelect($this->catalogConfig->getProductAttributes());
        return $collection;
    }
}

Here I add all attributes that are configured as “used in product listing”, i.e. all that are present in the flat index tables. You could specify them manually instead as well.

退出移动版