1

We want to implement the attribute group name on the compare product page and separate all attributes based on the attribute group.

We use the following code to show the attribute group name on the specifications section on the product page.

How can we implement this on the product compare page?

CODE;

<?php
namespace AttributeGroup\Module\Block\Product;

class Specification extends \Magento\Catalog\Block\Product\View
{
     /**
      * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory
      */
     protected $groupCollectionFactory;

     public function __construct(
         \Magento\Catalog\Block\Product\Context $context,
         \Magento\Framework\Url\EncoderInterface $urlEncoder,
         \Magento\Framework\Json\EncoderInterface $jsonEncoder,
         \Magento\Framework\Stdlib\StringUtils $string,
         \Magento\Catalog\Helper\Product $productHelper,
         \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
         \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory $groupCollectionFactory,
         array $data = []
    ) {
        parent::__construct($context, $urlEncoder, $jsonEncoder, $string,
        $productHelper, $productTypeConfig, $localeFormat, $customerSession,
        $productRepository, $priceCurrency, $data);
        $this->groupCollectionFactory = $groupCollectionFactory;
    }


    public function getAttributeLabels()
     {
    $product = $this->getProduct();

    $attributeSetId = $product->getAttributeSetId();

    $groupCollection = $this->groupCollectionFactory->create()
        ->setAttributeSetFilter($attributeSetId)
        ->setSortOrder()
        ->load();

    $html = '';
    foreach ($groupCollection as $group) {
        $attributes = $product->getAttributes($group->getId(), true);



        $new_html = "";
        foreach ($attributes as $key => $attribute) {
            if($attribute->getIsVisibleOnFront() && $attribute->getFrontend()->getValue($product) !="" && $attribute->getFrontend()->getValue($product) !="Non"){

                $new_html .= '<div class="product-specs-list-item">
                                <dt class="product-specs-item-title">' . $attribute->getStoreLabel(). '</dt>
                                <dl class="product-specs-item-spec">' . $attribute->getFrontend()->getValue($product) . '</dl>              
                            </div>';

            }
        }

        if($new_html!=''){

            $html .= "<div class='grid-section-xs-specification active'>";
            $html .= '<h3 class="noselect toggle-specification">' . $group->getData('attribute_group_name').'</h3>';
            $html .= "<dl class='product-specs'>";
            $html .= $new_html;
            $html .= "</dl>
            </div>";
        }

    }

    return $html;
}
}?>
2
  • Hi Jelle, is there any chance to describe what you are trying to do without the code? May 22, 2020 at 14:03
  • @HerveTribouilloy Thanks for the reply! I want to divide all attributes based on the attribute group name. This so that the compare page becomes clearer and it is easy to compare.
    – JGeer
    May 22, 2020 at 14:07

1 Answer 1

1
+150

I have worked out a solution for your problem. To make this happening, I have taken over the Magento template for the compare product listing.

The template gains awareness of the product attributes' groups from the attributes Magento has come up with the function below:

  /**
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @return \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection
     */
    public function findGroupListForProduct(\Magento\Catalog\Api\Data\ProductInterface $product, $attributes)
    {
        $groupCollection = $this->_groupCollection->create();
        $groupCollection->addFieldToFilter('main_table.attribute_set_id', $product->getAttributeSetId());

        $attributeIds = [];
        foreach ($attributes as $attribute) {
            $attributeIds[] = $attribute->getId();
        }

        $groupCollection->getSelect()->join(
            ['entity_table' => $groupCollection->getTable('eav_entity_attribute')],
            sprintf('entity_table.attribute_group_id=main_table.attribute_group_id and entity_table.attribute_id in (%s)', implode(',', $attributeIds)),
            []
        )->group('main_table.attribute_group_id');

        return $groupCollection;
    }

and then, a second function brings the attributes for a given group

/**
         * @param $groupId
         * @param $attributes
         * @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection
         */
        public function getAttributesListInGroup($groupId, $attributes)
            {
                $attributeIds = [];
                foreach ($attributes as $attribute) {
                    $attributeIds[] = $attribute->getId();
                }

                $collection = $this->collectionFactory->create();
                $collection->addFieldToFilter('main_table.attribute_id', ['in' => $attributeIds]);

                $collection->getSelect()->join(
                    ['entity_table' => $collection->getTable('eav_entity_attribute')],
                    'entity_table.attribute_id=main_table.attribute_id',
                    []
                )->where('entity_table.attribute_group_id=?', $groupId);

                return $collection;
            }

I put a link for the whole module as I find it more reliable to convey my solution.

https://bitbucket.org/magstaging/productcompare/src/master/

My solution eventually uses a viewModel for readability benefits. I chose this solution as the template and its way to retrieve its data are not coupled. Hope this resolve your problem

12
  • Thanks a lot! This works perfect, only that some of the attribute groups are not displayed with their label, any idea? And it also shows the attribute groups that are empty, how can we hide all empty attribute groups and their attributes?
    – JGeer
    May 23, 2020 at 8:28
  • It displays some of the attribute groups with empty values. I still can not find out why this happens. All the attributes inside that empty group label are displayed well, it seems to be only the label that is missing.
    – JGeer
    May 23, 2020 at 11:26
  • I have updated the repo now, thanks for your feedback May 23, 2020 at 13:58
  • Thanks Herve! Almost perfect, the labels of all attribute groups are now displayed well. The only problem we still face is, that there are attribute groups displayed that are empty, so they contain not attribute data to compare. In that case only the attribute group label is displayed. How can we remove this?
    – JGeer
    May 23, 2020 at 15:30
  • 1
    Thanks for accepting the answer May 23, 2020 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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