2

In Magento 1, we used the lockAttribute($attributeCode) method from a catalog_product_edit_action observer, and it prevented the admin user from editing that particular attribute. See Read-Only Product Backend attribute.

Magento 2 has the same lockAttribute method in Magento\Catalog\Model\AbstractModel. However, the UI for the attribute is no different after calling this method.

I also tried it on catalog_product_save_before, and it still allowed me to apply a new value to the attribute.

Vendor/Module/Observer/Lock.php

namespace Vendor\Module\Observer;

class Lock implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * Observer to catalog_product_save_before to lock attributes.
     *
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getEvent()->getProduct();
        $product->lockAttribute('my_custom_attribute');
    }
}

Vendor/Module/etc/adminhtml/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <!-- <event name="catalog_product_save_before"> -->
    <event name="catalog_product_edit_action">
        <observer name="test_lock_attributes" instance="Vendor\Module\Observer\Lock"/>
    </event>
</config>
9

Starting from 2.1 Magento uses UI component to build product admin form. Thus, it should be customized as suggested in the manual.

In particular, your task could be accomplished with modifier approach.

Create DI file under YourVendor/YourModule/etc/adminhtml/di.xml with the content like:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="sap_product" xsi:type="array">
                    <item name="class" xsi:type="string">YourVendor\YourModule\Ui\DataProvider\Product\Form\Modifier\Attributes</item>
                    <item name="sortOrder" xsi:type="number">1000</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Create modifier class:

<?php
namespace YourVendor\YourModule\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;

class Attributes extends AbstractModifier
{
    private $arrayManager;

    public function __construct(ArrayManager $arrayManager)
    {
        $this->arrayManager = $arrayManager;
    }

    public function modifyData(array $data)
    {
        return $data;
    }

    public function modifyMeta(array $meta)
    {
        $attribute = '...'; // Your attribute code goes here

        $path = $this->arrayManager->findPath($attribute, $meta, null, 'children');
        $meta = $this->arrayManager->set(
            "{$path}/arguments/data/config/disabled",
            $meta,
            true
        );
        return $meta;
    }
}

modifyMeta method allows you to dynamically customise UI component's configuration. Here we find the attribute element configuration and update it's disabled flag to true.

|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.