3

I've created a few product attributes with these settings:

  • Scope: Store View
  • Add to Column Options: Yes
  • Visible on Catalog Pages on Storefront: Yes
  • Used in Product Listing: Yes
  • Used for sorting in Product Listing: Yes

In my grouped product, I have a value:

[![enter image description here][1]][1]

But, in my custom /design/frontend/Vendor/Theme/Magento_GroupedProduct/templates/product/view/type/grouped.phtml file, I've got this:

<?php
    $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/trey.log');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);

    foreach ($_item->getAttributes() as $attr)
    {
        $logger->info(
            $attr->getAttributeCode(). ': '. $attr->getFrontend()->getValue($_item)
        );
    }
?>

Which produces these (skimmed) results in the log file:

2019-12-03T10:23:01+00:00 INFO (6): entity_id: 228
2019-12-03T10:23:02+00:00 INFO (6): type_id: simple
2019-12-03T10:23:02+00:00 INFO (6): attribute_set_id: 4
2019-12-03T10:23:02+00:00 INFO (6): status: Enabled
2019-12-03T10:23:02+00:00 INFO (6): name: Bulb 501 w5w 12v
2019-12-03T10:23:02+00:00 INFO (6): sku: BULB-501-SIN001
2019-12-03T10:23:02+00:00 INFO (6): price: 1.1900
2019-12-03T10:23:02+00:00 INFO (6): ref_code:
2019-12-03T10:23:02+00:00 INFO (6): image_ref:
2019-12-03T10:23:02+00:00 INFO (6): required:

As you can see, ref_code, image_ref and required is empty, but I'm not sure why as the values are there in the database. I've tried re-indexing fully and clearing cache via rm -rf /var/cache/*

The methods listed in:

didn't work.

I didn't try the Object Manager method as I don't wish to use it as I know it's not the right way to go.

Edit:

snappy of my attribute:

image

Edit 2:

I created a module as advised, but couldn't get it 100%. This is the code I implemented:

|-app
|-----code
|---------Vendor
|-------------Module
|-----------------etc
|---------------------frontend
|-------------------------di.xml
|---------------------module.xml
|-----------------Plugin
|---------------------Model
|-------------------------Product
|-----------------------------Type
|---------------------------------Grouped.php
|-----------------registration.php

di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\GroupedProduct\Model\Product\Type\Grouped">
        <plugin name="addAttributes" type="Vendor\Module\Model\Plugin\Product\Type\Grouped" />
    </type>
</config>

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Catalog" />
            <module name="Magento_GroupedProduct" />
        </sequence>
    </module>
</config>

Grouped.php

namespace Vendor\Module\Model\Plugin\Product\Type;

class Grouped
{
    /**
     * @param $subject
     * @param $result
     *
     * @return mixed
     */
    public function afterGetAssociatedProductCollection($subject, $result)
    {
        $result->addAttributeToSelect('*');

        return $result;
    }
}

registration.php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Module',
    __DIR__
);
  • 1
    try to change scope "Store" to "Global" – Rk Rathod Dec 5 '19 at 15:08
  • @RkRathod that's what it was to start with :/ – treyBake Dec 5 '19 at 15:16
  • what you mean ?? – Rk Rathod Dec 5 '19 at 15:18
  • @RkRathod as in, I initially set attribute scope = global, but it makes no difference – treyBake Dec 5 '19 at 15:23
  • @RkRathod see edit – treyBake Dec 5 '19 at 15:27
4
+200

Create di.xml file here in your custom module

app/code/Vendor/Module/etc/di.xml

Content for this file is..

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\GroupedProduct\Model\Product\Type\Grouped" type="Vendor\Module\Model\Product\Type\Grouped" />
</config>

Now you need to create Model file here in your custom module..

app/code/Vendor/Module/Model/Product/Type/Grouped.php

Content for this file is..

<?php

namespace Vendor\Module\Model\Product\Type;

use Magento\Catalog\Api\ProductRepositoryInterface;

class Grouped extends \Magento\GroupedProduct\Model\Product\Type\Grouped
{
    public function getAssociatedProductCollection($product)
    {
        parent::getAssociatedProductCollection($product);
        $links = $product->getLinkInstance();
        $links->setLinkTypeId(\Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED);
        $collection = $links->getProductCollection()->addAttributeToSelect('*')->setFlag(
            'product_children',
            true
        )->setIsStrongMode();
        $collection->setProduct($product);
        return $collection;
    }
}

Note : Here Vendor is your module's namespace and Module is your module name in above file path.

Hope this will help you!

| improve this answer | |
  • 1
    Hey, apologies for long delay! I tried following the steps but it's still not added :/ am I missing a step after adding the above files? – treyBake Dec 10 '19 at 11:21
  • Have you created new module ? with registration.php and module.xml file ? Or Can you please let me know where you've created this module and how ? – Kishan Savaliya Dec 10 '19 at 11:22
  • Hey, I did indeed, can see it as active in /app/etc/config.php – treyBake Dec 10 '19 at 11:25
  • I'll edit my question with what I did :) – treyBake Dec 10 '19 at 11:26
  • Yes, this will be helpful to me :) Thanks – Kishan Savaliya Dec 10 '19 at 11:26
4

[Not sure if it's the correct way]

Take a look at vendor/magento/module-grouped-product/Model/Product/Type/Grouped.php

public function getAssociatedProducts($product) 
{
   ...
     ->addAttributeToSelect(
                ['name', 'price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id']
   ...
}

Seems that Magento just sets some fields.

My suggestion is to use Plugin to add your custom fields. For example:

app/code/Vendor/CatalogAttributes/etc/frontend/di.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\GroupedProduct\Model\Product\Type\Grouped">
        <plugin name="addAttributes"
                type="Vendor\CatalogAttributes\Model\Plugin\Product\Type\Grouped"/>
    </type>
</config>

app/code/Vendor/CatalogAttributes/Model/Plugin/Product/Type/Grouped.php

<?php declare(strict_types=1);

namespace Vendor\CatalogAttributes\Model\Plugin\Product\Type;

use Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection;

class Grouped
{
    /**
     * @param $subject
     * @param Collection $result
     * @return Collection $result
     */
    public function afterGetAssociatedProductCollection($subject, $result)
    {
        $result->addAttributeToSelect(['ref_code']);
        return $result;
    }
}
| improve this answer | |
  • That seems like a really counter-intuitive design flaw (on Magento's end) :/ so we have to do this per new attribute we add (that'll be used with grouped products)? – treyBake Dec 5 '19 at 16:45
  • Setting "used in product listing" should make the attribute value available in all product templates. Your log shows the attribute is recognised, just the value is not available. I don't think this is a solution. – paj Dec 5 '19 at 16:47
  • I'm actually not sure if it's the correct way. Just my finding about this part @paj – Khoa TruongDinh Dec 5 '19 at 16:50
  • @paj I tried changing that value - no changes, shall procdeed with Khoa's answer :) – treyBake Dec 5 '19 at 16:53
  • 1
    @KhoaTruongDinh I was curious about this and tested it on my dev store and you are correct - custom attributes must be added to the associated child product collection select if you want to get their values from the type/grouped template. – paj Dec 5 '19 at 19:05
0

I have created a viewmodel for displaying the custom attribute of the simple products in the grouped.phtml

<referenceBlock name="product.info.grouped.retailbb">
            <arguments>
                <argument name="view_model" xsi:type="object">BA\BasysProdLayouts\ViewModel\GetAttributes</argument>
            </arguments>
        </referenceBlock>

ViewModel Class

namespace BA\BasysProdLayouts\ViewModel;

use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory;
use Magento\CatalogInventory\Model\Stock\StockItemRepository;
use Psr\Log\LoggerInterface;

class GetAttributes implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    protected $groupCollection;
    protected $logger;
    protected $stockItemRepository;
    private $attrsArray = [];
public function __construct(CollectionFactory $groupCollection, LoggerInterface $logger, StockItemRepository $stockItemRepository)
{
    $this->groupCollection = $groupCollection;
    $this->stockItemRepository = $stockItemRepository;
    $this->logger = $logger;
}
public function createAttributeArray($groupId, $item)
{
    $productAttributes = $item->getAttributes($groupId);
    $productStock = $this
        ->stockItemRepository
        ->get($item->getId());
    $this->attrsArray['stock'][$item->getId() ] = $productStock->getQty();
    foreach ($productAttributes as $attribute)
    {
        $attrCode = $attribute->getAttributeCode();
        $attrValue = $item->getResource()
            ->getAttributeRawValue($item->getId() , $attrCode, $item->getId());
        /* Checking for blank values */
        $finalValue = is_array($attrValue) ? '' : $attrValue;
        $this->attrsArray[$attrCode][$item->getId() ] = $finalValue;
    }
}
public function getLayoutCustAttributes($items)
{
    $groupCollection = $this
        ->groupCollection
        ->create();
    $groupCollection->addFieldToFilter('attribute_group_name', 'Layout Customizations');
    $groupId = $groupCollection->getFirstItem()
        ->getData('attribute_group_id');
    foreach ($items as $item)
    {
        $this->createAttributeArray($groupId, $item);
    }
    $this->filterEmptyAttributes();
    return $this->attrsArray;
}
private function filterEmptyAttributes()
{
    foreach ($this->attrsArray as $key => $innerArray)
    { //check for each element
        foreach ($innerArray as $innerValue)
        {
            if (!empty($innerValue))
            {
                continue 2; //stop investigating at first non empty, we shoud keep this
                
            }
        }
        //all values in innerArray are empty, drop this
        unset($this->attrsArray[$key]);
    }
}
}

In the grouped.phtml

        <?php $attrArray = $block->getViewModel()->getLayoutCustAttributes($_associatedProducts);
?>
| improve this answer | |

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.