Read-Only Product Backend attribute

From the referenced SO article - I tried and this indeed works on 1.6CE and 1.7CE / 1.12EE. I haven't tried on 1.8/1.13 as of yet.

https://stackoverflow.com/questions/6384120/magento-read-only-and-hidden-product-attributes

OK, it looks like it can be done after all. After adding an observer for the catalog_product_load_after event, the lockAttribute method of the Mage_Catalog_Model_Abstract class may be used to make a product attribute read-only. Here is the code for the observer method:

public function lockAttributes($observer) {
    $event = $observer->getEvent();
    $product = $event->getProduct();
    $product->lockAttribute('attribute_code');
}

If it is enough for you to make it not editable in product management, use the frontend input type label, which replaces the form input with plain text:

addAttribute($entity, $code, array(
    ...
    'input' => 'label',
    ...
));

Note that this will not prevent saving the attribute through API or manipulated POST request. To make it secure, additionally use lockAttribute() as suggested above.

Also it only looks good for text type attributes, for other types, again, fall back to lockAttributes or extend the "label" type.


To make this fixed, you can alternatively use an input renderer for this. The downside is, you would have to do this for each input type and set this via setup for each attribute.

To do so, use the input_renderer key when using addAttribute an attribute or frontend_input_renderer when using updateAttribute. Example:

$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, 'yourattribute', array(
// ...
// won't be used actually as you use a custom renderer (constant equals to text), but I'm not sure what omitting this will have as effect..
    'input' => Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT,
    'input_renderer' => 'yourns_yourmodule/adminhtml_product_helper_form_disabledText',
    'frontend_class' => 'disabled',
    'note' => 'This field is disabled',
// ...
));

Then with your class Yourns_Yourmodule_Block_Adminhtml_Product_Helper_Form_DisabledText extend the input class you would actually use. For a text field it would be Varien_Data_Form_Element_Text. For selects it would be Varien_Data_Form_Element_Select and so on.

Now add your code like this to disable the attribute, overwriting the getHtml method, setting the attribute and returning the actual HTML code for the input field:

public function getHtml()
{
    // Set disabled
    $this->setReadonly(true, true);
    return parent::getHtml();
}

The method can be found in lib/Varien/Data/Form/Abstract.php which will be inherited by all form input element fields, so it should alaways be available.

/**
 * Disable elements
 *
 * @param boolean $readonly
 * @param boolean $useDisabled
 * @return Varien_Data_Form_Abstract
 */
public function setReadonly($readonly, $useDisabled = false)
{
    if ($useDisabled) {
        $this->setDisabled($readonly);
        $this->setData('readonly_disabled', $readonly);
    } else {
        $this->setData('readonly', $readonly);
    }
    foreach ($this->getElements() as $element) {
        $element->setReadonly($readonly, $useDisabled);
    }

    return $this;
}

It's probably senseful to include the disabled class in the attribute setup like shown above to visualize the denied input possibility. You can probably also use $this->addClass('disabled') in the method, I did not try this yet.