2

I have to use a custom product attribute in the mini cart and the full cart view. After creating the file /etc/catalog_attributes.xml in my module folder i could read my custom attribute in the full cart view at base.url/checkout/cart.

/etc/catalog_attributes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="custom_attribute"/>
    </group>
</config>

I now can access the custom_attribute via $product->getData("custom_attribute"). But this doesn't work for the minicart.

Is there any way to add the attribute to the minicart view?

0

Adding the attribute to the collection is working exactly as you describe, for the cart AND the minicart.

You also need to overwrite \Magento\Checkout\CustomerData\DefaultItem::doGetItemData to provide a new attribute, as shown here with the brand attribute:

protected function doGetItemData()
{
    $imageHelper = $this->imageHelper->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail');
    $productName = $this->escaper->escapeHtml($this->item->getProduct()->getName());
    $productBrand = $this->escaper->escapeHtml($this->item->getProduct()->getAttributeText('brand'));

    return [
        'options' => $this->getOptionList(),
        'qty' => $this->item->getQty() * 1,
        'item_id' => $this->item->getId(),
        'configure_url' => $this->getConfigureUrl(),
        'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(),
        'product_id' => $this->item->getProduct()->getId(),
        'product_name' => $productName,
        'product_brand' => $productBrand,
        'product_sku' => $this->item->getProduct()->getSku(),
        'product_url' => $this->getProductUrl(),
        'product_has_url' => $this->hasProductUrl(),
        'product_price' => $this->checkoutHelper->formatPrice($this->item->getCalculationPrice()),
        'product_price_value' => $this->item->getCalculationPrice(),
        'product_image' => [
            'src' => $imageHelper->getUrl(),
            'alt' => $imageHelper->getLabel(),
            'width' => $imageHelper->getWidth(),
            'height' => $imageHelper->getHeight(),
        ],
        'canApplyMsrp' => $this->msrpHelper->isShowBeforeOrderConfirm($this->item->getProduct())
            && $this->msrpHelper->isMinimalPriceLessMsrp($this->item->getProduct()),
    ];
}

Please use a preference for overwriting the method.

And then the html template vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html will have to be overwritten in order to add the placeholder like <!-- ko text: product_brand --><!-- /ko --> in it.

2
  • Is this really the correct way to do this? I'm feeling doubtfull that this would work. Correct me If I'm wrong but di.xml preference won't overwritte \Magento\Checkout\CustomerData\DefaultItem::doGetItemData because it is protected method. Instead plugin should be created for Magento\Checkout\CustomerData\AbstractItem::getItemData which calls doGetItemData only then do rewrite.
    – Trenox
    Oct 18 '18 at 10:59
  • A preference absolutely works for protected methods. Of course you can go the way with the plugin, but as the protected method has many references to other protected and private methods and fields, it will mean a lot more work. Rule of thumb: If protected is used, it's less modern code for which Plugins don't work well. Oct 19 '18 at 8:05
0

As @Andreas von Studnitz wrote you have to create a plugin (answered in 2019) but now you cannot create a preference for protected function and abstract class

https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html

So in this case you have to create a preference

etc/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\Checkout\CustomerData\DefaultItem">
        <plugin name="Yourmodule_Checkout::add-custom-attribute-to-cart-minicart"
                type="Yourmodule\Checkout\Plugin\Checkout\CustomerData\DefaultItemPlugin" />
    </type>
</config>

Plugin/Checkout/CustomerData/DefaultItemPlugin.php

<?php
declare(strict_types=1);

namespace Yourmodule\Checkout\Plugin\Checkout\CustomerData;

class DefaultItemPlugin
{
    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    private $productRepository;

    public function __construct(
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ) {
        $this->productRepository = $productRepository;
    }

    public function afterGetItemData(\Magento\Checkout\CustomerData\DefaultItem $subject, $result)
    {
        $product = $this->productRepository->get($result['product_sku']);

        return \array_merge(
            ['your_custom_attribute' => $product->getData('your_custom_attribute')],
            $result
        );
    }
}

for the function getItemData(..) that is the only public function you can use (and you can find in \Magento\Checkout\CustomerData\AbstractItem because is the extended class)

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.