Magento How to convert text attribute to dropdown attribute

If you are using Magento as ecommerce framework you could be interested on how to change an attribute type. The main answer is: you can’t!

Indeed, you have to create a new one because you can’t change the attribute types (nether the code name and many other things), so the best solution for me was to export the values and import them into a new one attribute.

Imagine to have a “book_language” EAV attribute set to text type, you know you can’t use it in layered navigation, to use it there, you have to create a new attribute, called for example “product_language” (you can’t use the same name), with type like “dropdown“.

Well, simple, but how to import the current values into the new attribute and use it instead the old one?

You need some code, precisely, this script and you are up&running 🙂

Note: you MUST edit the two lines with the your attribute names, script MUST reside into Magento root directory. Of course you should to run it from the command line (aka PHP CLI).

Have fun!

//
// Magento Convert Attributes
// Author: Michele Marcucci
// Email: michele@simplicissimus.it
// Script to convert a old Magento text attribute to a new one in dropdown format (useful to be used in navigation layer)
// // Put your old and new attribute
// Old attribute must be the one in text mode
// New attribute is the new one you want in dropdown
// ------ EDIT THESE: ------- // $attrCodeOLD = "book_language";
$attrCodeNEW = "product_language"; // ------ STOP EDITING ----- // require_once 'app/Mage.php';
umask( 0 );
Mage :: app( "default" ); Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); Mage::register('isSecureArea', true); //
// Collect/Export all the current old attribute values
// in a CSV file to be imported in the new one later
//
$collection = Mage::getModel('catalog/product') ->getCollection() ->addAttributeToSelect('sku') ->addAttributeToSelect($attrCodeOLD); $fp = fopen($attrCodeOLD.".csv", 'w');
foreach ($collection as $product) { fputcsv($fp, array($product->getId(), $product->getData($attrCodeOLD)));
} echo "CSV Createdn"; echo "Continue? (Y/N)";
$input = fgets(STDIN);
if (!preg_match("/y/s", $input))
{ die("Quitn");
} //
// Get unique values to create the new attribute
// $_resource = Mage::getSingleton('core/resource');
$_readConnection = $_resource->getConnection('core_read');
$_query = "SELECT distinct value FROM catalog_product_entity_varchar WHERE attribute_id in (SELECT attribute_id FROM eav_attribute WHERE attribute_code='".$attrCodeOLD."')"; $values = $_readConnection->fetchCol($_query); echo "Unique values are:n";
var_dump($values); echo "Continue? (Y/N)";
$input = fgets(STDIN);
if (!preg_match("/y/s", $input))
{ die("Quitn");
} //
// Add the unique values to the new attribute
// $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup(); $iProductEntityTypeId = Mage::getModel('catalog/product')->getResource()->getTypeId();
$aOption = array();
$aOption['attribute_id'] = $installer->getAttributeId($iProductEntityTypeId, $attrCodeNEW);
for($iCount=0;$iCount<sizeof($values);$iCount++){ $aOption['value']['option'.$iCount][0] = $values[$iCount];
} $installer->addAttributeOption($aOption); $installer->endSetup(); echo "New values configured:n";
var_dump($aOption); echo "Continue? (Y/N)";
$input = fgets(STDIN);
if (!preg_match("/y/s", $input))
{ die("Quitn");
} //
// Import all the products values into the new attribute // This could take a while if you have a large products catalog
// Thanks to updateAttributes method we can save a lot of memory // running this step smoothly also on huge db
// $attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', $attrCodeNEW); //change to your attribute code
$allOptions = $attribute->getSource()->getAllOptions(true, true);
foreach ($allOptions as $instance) { $myArray[$instance['label']] = $instance['value'];
} if (($handle = fopen($attrCodeOLD.".csv", "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000)) !== FALSE) { list($_id, $_value) = $data; if (empty($myArray[$_value]) or !isset($myArray[$_value])) $_v = null; else $_v = $myArray[$_value]; Mage::getModel('catalog/product_action')->updateAttributes(array($_id), array($attrCodeNEW => $_v), 0); echo $_id." Saved (".memory_get_usage().")n"; } fclose($handle);
}

Bonus hint: how to get the new attribute value from the frontend/template files?

Simply use this code:

 $product->getAttributeText("book_language") 

Post simili:

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Discover more from WHO WILL CARE eCommerce

Subscribe now to keep reading and get access to the full archive.

Continue reading