Why is this test script for eav visibility attribute failing?
-
16-10-2019 - |
Question
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?
Solution
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;
}
OTHER TIPS
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];
}
}
// ...
}