0

I have attribute that values are dynamically mapped from custom tables. So attribute don't have values by it self. I'd like to get mapped values every time getValue() is called. But i don't want affect core magento files with additional "if's".

For admin panel i created backend_model for this attribute and method afterLoad() with my custom logic for this attribute. At admin panel it works fine.

But i have problem with Product model and $product->getData(). In this call of course it returns data directly from DB. Without backend model logic.

Is there any place that I can add logic for fetching values for this attribute, that it will be visible at $product->getData()? Maybe some model for this attribute? But it's just idea but don't know why.

For some reasons perfect solution is to not use any plugins, preferences for core magento files. That's why i think about some models mayby.

Can anyone help? Any tips?


EDIT

I'm trying to use it in magento import-export module.

1 Answer 1

0

You can create 2 plugins for after load method for collection and product.

Plugin declaration

app/code/Acme/StackExchange/etc/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\Catalog\Model\Product">
        <plugin name="Acme_StackExchange_Plugin_Catalog_Model_ProductPlugin"
                type="Acme\StackExchange\Plugin\Catalog\Model\ProductPlugin" sortOrder="10"/>
    </type>
    <type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
        <plugin name="Acme_StackExchange_Plugin_Catalog_Model_ResourceModel_Product_CollectionPlugin"
                type="Acme\StackExchange\Plugin\Catalog\Model\ResourceModel\Product\CollectionPlugin" sortOrder="10"/>
    </type>
</config>

Product Model Plugin

app/code/Acme/StackExchange/Plugin/Catalog/Model/ProductPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\Catalog\Model;

use Magento\Catalog\Model\Product;

class ProductPlugin
{
    public function afterLoad(Product $product)
    {
        // load your custom data and assign to $product instance

        return $product;
    }
}

Product Collection Plugin

app/code/Acme/StackExchange/Plugin/Catalog/Model/ResourceModel/Product/CollectionPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\Catalog\Model\ResourceModel\Product;

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

class CollectionPlugin
{
    protected bool $isLoaded = false;

    public function beforeLoad(Collection $subject, $printQuery = false, $logQuery = false): array
    {
        $this->isLoaded = $subject->isLoaded();

        return [$printQuery, $logQuery];
    }

    public function afterLoad(Collection $subject, Collection $result): Collection
    {
        if (!$this->isLoaded) {
            $this->isLoaded = true;

            // collect loaded product ids
            $productIds = [];
            /** @var Product $product */
            foreach ($subject->getItems() as $product) {
                $productIds[] = $product->getId();
            }

            // load your data for $productIds

            foreach ($subject->getItems() as $product) {
                // check is data loaded for $product
                // assign loaded data to $product instance
            }
        }

        return $result;
    }
}
5
  • Thanks. But this approach affects all products and all attributes. Sure i can add additional if's inside. But i'm looking something that is more scoped on attribute. Perfectly if it's assigned to single attribute. I'm adding attribute by dataPatch. I was trying to set custom backend_model and it works only at admin panel. I'm trying set custom attribute_model.
    – Sebas
    Jul 18, 2022 at 6:26
  • Summarizing - i'd like to add logic when attribute is loading value from DB. That's why i think about Attribute models. I achieved that on backend model and values are displayed on admin panel. But when I create product's collection, i get data directly from DB, without extra logic.
    – Sebas
    Jul 18, 2022 at 16:04
  • And it's a reason why I've suggested to create plugins Jul 18, 2022 at 18:03
  • But plugins will affect ALL attributes with additional 'if' inside. For some reasons i don't want this.
    – Sebas
    Jul 18, 2022 at 18:53
  • Plugin will affect once per load collection or product and doesn't matter by performance to use product and more effective with collection. Jul 18, 2022 at 19:27

Your Answer

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

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