Get Grouped Products Associated Child Product Custom Attribute
-
22-03-2021 - |
質問
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:
- Magento 2: How to display custom attribute in catalog
- Magento 2: Get custom attribute value of product
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:
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__
);
解決
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!
他のヒント
[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;
}
}
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);
?>