4

I want to show some additional product attributes in the wishlist template, but they are not loaded. On the category page it is working, so it is not an index problem.

When I call

$item->getProduct()

I see that the product has already been loaded, but not with all attributes, so obviously it is coming from a collection.

The wishlist items are coming from Magento\Wishlist\Block\Customer\Wishlist::getWishlistItems() and are passed around in the templates. But where are the products loaded and how can I specify which attributes I need?

I can force a reload, and it would work:

$item->getProduct()->load($item->getProduct()->getId()))

But obviously this is not the right way.

2

1 Answer 1

7

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.

6
  • Wouldn't it be easier to add the product attributes in a catalog_attributes.xml for the group wishlist_item? It was done that way in M1, not sure if it works in M2 though.
    – fmrng
    Jan 20, 2017 at 10:24
  • @fmrng does that work? I don't see these being applied anywhere? Jan 20, 2017 at 10:25
  • It does work for quote items, that's why I was wondering.. haven't tested it and i'm far from being an expert of M2, but it sounds much more reasonable than messing around with DI. I'm going to have a look at it, thought I'd point that out anyway, maybe you had tried it already.
    – fmrng
    Jan 20, 2017 at 10:28
  • 1
    Just seen that too, yeah... they did it ALMOST right :-) weird, might be worth a PR.
    – fmrng
    Jan 20, 2017 at 10:45
  • 2
    Oh, there already is one: github.com/magento/magento2/pull/6723 Feb 3, 2017 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.