3

During the course of work, I ran into some issues with the visibility attribute in Magento 1.8 and decided to write a test script. Unfortunately, the results have only made me MORE confused. Basically, I test having an installer script use addAttribute() and updateAttribute(), targeting the is_visible attribute.

Code:

<?php 
ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.dirname(__FILE__).'/app'.PATH_SEPARATOR.dirname(__FILE__));
ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.dirname(__FILE__).'/tests');
ini_set('memory_limit', '512M'); //so coverage generation don't barf
require_once 'Mage.php';         //so autoloading and all work...
//require_once 'tools.php';
Mage::app('default');            //create the app

function assertTrue($assertion)
{
    if ($assertion) {
        echo "Passed\n";
    } else {
        echo "Failed\n";
    }
    return $assertion;
}

// your own installer
$installer = Mage::getModel('eav/entity_setup', 'catalog_setup');

/*
    Test these cases:

    Models: customer/customer, catalog/product
    addAttribute(visible = true), addAttribute(visible = false)
    updateAttribute(is_visible = 1), updateAttribute(is_visible = 0)

 */

$customerResource = Mage::getModel('customer/customer')->getResource();
$productResource = Mage::getModel('catalog/product')->getResource();

$installer->removeAttribute('customer','test_attr_1');
$installer->removeAttribute('customer','test_attr_2');
$installer->removeAttribute('catalog_product','test_attr_1');
$installer->removeAttribute('catalog_product','test_attr_2');

echo "Customer addAttribute(visible=false)...";
$installer->addAttribute('customer', 'test_attr_1', array(
    'label'         => 'Test Attribute 1',
    'visible'       => false
));
assertTrue($customerResource->getAttribute('test_attr_1')->getIsVisible() == 0);

echo "Customer updateAttribute(visible=true)...";
$installer->updateAttribute('customer', 'test_attr_1', 'is_visible', 1);
assertTrue($customerResource->getAttribute('test_attr_1')->getIsVisible() == 1);


echo "Customer addAttribute(visible=true)...";
$installer->addAttribute('customer', 'test_attr_2', array(
    'label'         => 'Test Attribute 2',
    'visible'       => true
));
assertTrue($customerResource->getAttribute('test_attr_2')->getIsVisible() == 1);

echo "Customer updateAttribute(visible=false)...";
$installer->updateAttribute('customer', 'test_attr_2', 'is_visible', 0);
assertTrue($customerResource->getAttribute('test_attr_2')->getIsVisible() == 0);

echo "Product addAttribute(visible=false)...";
$installer->addAttribute('catalog_product', 'test_attr_1', array(
    'label'         => 'Test Attribute 1',
    'visible'       => false
));
assertTrue($productResource->getAttribute('test_attr_1')->getIsVisible() == 0);

echo "Product updateAttribute(visible=true)...";
$installer->updateAttribute('catalog_product', 'test_attr_1', 'is_visible', 1);
assertTrue($productResource->getAttribute('test_attr_1')->getIsVisible() == 1);


echo "Product addAttribute(visible=true)...";
$installer->addAttribute('catalog_product', 'test_attr_2', array(
    'label'         => 'Test Attribute 2',
    'visible'       => true
));
assertTrue($productResource->getAttribute('test_attr_2')->getIsVisible() == 1);

echo "Product updateAttribute(visible=false)...";
$installer->updateAttribute('catalog_product', 'test_attr_2', 'is_visible', 0);
assertTrue($productResource->getAttribute('test_attr_2')->getIsVisible() == 0);

die;
?>

Output:

Customer addAttribute(visible=false)...Failed
Customer updateAttribute(visible=true)...Passed
Customer addAttribute(visible=true)...Passed
Customer updateAttribute(visible=false)...Failed
Product addAttribute(visible=false)...Failed
Product updateAttribute(visible=true)...Passed
Product addAttribute(visible=true)...Passed
Product updateAttribute(visible=false)...Failed

To muddy the waters even more, when I check the catalog_eav_attribute table and customer_eav_attribute table, is_visible=0 for test_attr_2 (which is what is expected, but the script says otherwise).

Also:

  • When at the new customer page, is_visible = 1 and Test Attribute 1 does not display in the form
  • When at the new product page, is_visible = 1 and Test Attribute 1 does display in the form

Is there anyone that can make any sense of this behavior? Is my test wrong in any way?

1

Change:

$installer = Mage::getModel('eav/entity_setup', 'catalog_setup'); 

To:

$installer = Mage::getModel('catalog/resource_setup', 'core_setup');

Your problem is that you loaded the default EAV-setup model, since product attributes have different settings then other attributes, they override the _prepareValues() function in:

/app/code/core/Mage/Catalog/Model/Resource/Setup.php

protected function _prepareValues($attr)
{
    $data = parent::_prepareValues($attr);
    $data = array_merge($data, array(
        'frontend_input_renderer'       => $this->_getValue($attr, 'input_renderer'),
        'is_global'                     => $this->_getValue(
            $attr,
            'global',
            Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL
        ),
        'is_visible'                    => $this->_getValue($attr, 'visible', 1),
        'is_searchable'                 => $this->_getValue($attr, 'searchable', 0),
        'is_filterable'                 => $this->_getValue($attr, 'filterable', 0),
        'is_comparable'                 => $this->_getValue($attr, 'comparable', 0),
        'is_visible_on_front'           => $this->_getValue($attr, 'visible_on_front', 0),
        'is_wysiwyg_enabled'            => $this->_getValue($attr, 'wysiwyg_enabled', 0),
        'is_html_allowed_on_front'      => $this->_getValue($attr, 'is_html_allowed_on_front', 0),
        'is_visible_in_advanced_search' => $this->_getValue($attr, 'visible_in_advanced_search', 0),
        'is_filterable_in_search'       => $this->_getValue($attr, 'filterable_in_search', 0),
        'used_in_product_listing'       => $this->_getValue($attr, 'used_in_product_listing', 0),
        'used_for_sort_by'              => $this->_getValue($attr, 'used_for_sort_by', 0),
        'apply_to'                      => $this->_getValue($attr, 'apply_to'),
        'position'                      => $this->_getValue($attr, 'position', 0),
        'is_configurable'               => $this->_getValue($attr, 'is_configurable', 1),
        'is_used_for_promo_rules'       => $this->_getValue($attr, 'used_for_promo_rules', 0)
    ));
    return $data;
}

See difference from default _prepareValues() in:

/app/code/core/Mage/Eav/Model/Enitity/Setup.php

protected function _prepareValues($attr)
{
    $data = array(
        'backend_model'   => $this->_getValue($attr, 'backend'),
        'backend_type'    => $this->_getValue($attr, 'type', 'varchar'),
        'backend_table'   => $this->_getValue($attr, 'table'),
        'frontend_model'  => $this->_getValue($attr, 'frontend'),
        'frontend_input'  => $this->_getValue($attr, 'input', 'text'),
        'frontend_label'  => $this->_getValue($attr, 'label'),
        'frontend_class'  => $this->_getValue($attr, 'frontend_class'),
        'source_model'    => $this->_getValue($attr, 'source'),
        'is_required'     => $this->_getValue($attr, 'required', 1),
        'is_user_defined' => $this->_getValue($attr, 'user_defined', 0),
        'default_value'   => $this->_getValue($attr, 'default'),
        'is_unique'       => $this->_getValue($attr, 'unique', 0),
        'note'            => $this->_getValue($attr, 'note'),
        'is_global'       => $this->_getValue($attr, 'global', 1),
    );

    return $data;
}
0

Did you have a look into getAttribute() ?

The attributes are cached inside of the Resource model, therefore you need to use all the time a new resource model, then your tests should pass.

public function getAttribute($attribute)
{
    if (is_numeric($attribute)) {
        $attributeId = $attribute;

        if (isset($this->_attributesById[$attributeId])) {
            return $this->_attributesById[$attributeId];
        }
        // ... 
    } else if (is_string($attribute)) {
        $attributeCode = $attribute;

        if (isset($this->_attributesByCode[$attributeCode])) {
            return $this->_attributesByCode[$attributeCode];
        }
        // ...         } else if ($attribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract) {

        $attributeInstance = $attribute;
        $attributeCode = $attributeInstance->getAttributeCode();
        if (isset($this->_attributesByCode[$attributeCode])) {
            return $this->_attributesByCode[$attributeCode];
        }
    }
    // ... 
}
  • While this was a good suggestion, and I added unsetAttributes() to my code, it still unfortunately does not pass. Also, that does not explain the Failure in the first test. – Paul Wisniewski Dec 30 '13 at 17:35

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.