Skip to content

Instantly share code, notes, and snippets.

@scher200
Forked from mechanicalgux/text2dropdown.php
Last active June 4, 2019 15:18
Show Gist options
  • Select an option

  • Save scher200/76eff30480a9f91312b5 to your computer and use it in GitHub Desktop.

Select an option

Save scher200/76eff30480a9f91312b5 to your computer and use it in GitHub Desktop.
[Magento] Script that convert text attribute to dropdown attribute without losing values
<?php
//
// Magento Convert Attributes
// Author: Jeroen Schermer
// Original 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)
//
// Modified by mechanicalgux:
// - automatic temporary attribute creation
// - automatic replacement of old attribute by the newly created attribute
// - command line parameter to specify which attribute to convert
//
// Put this file in Magento var/tasks
// Usage: php text2dropdown.php attribute_code
//
// Tested with Magento 1.9.0.1
//
if(!$argv[1] || !$argv[2])
die("Usage: php text2dropdown.php attribute_code new_attribute_code\n");
/**
* Launch the process
* @param $attrCodeOLD
*/
function launch($attrCodeOLD, $attrCodeNEW)
{
$attrCodeTEMP = $attrCodeOLD."_temp".rand(1,1000);
/** @var Mage_Eav_Model_Entity_Attribute $attributeOLD */
$attributeOLD = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_product', $attrCodeOLD);
//
// 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) {
$data = trim($product->getData($attrCodeOLD));
if(!empty($data))
fputcsv($fp, array($product->getId(), $data));
}
echo "CSV Created\n";
//
// 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."') AND LENGTH(TRIM(value)) > 0";
$values = $_readConnection->fetchCol($_query);
//
// Create the new attribute
//
createAttribute($attributeOLD->getStoreLabel(), $attrCodeTEMP, true);
echo "New attribute created\n";
//
// Assign it to attribute sets
//
assignToAttributeSets($attributeOLD, $attrCodeTEMP);
echo "New attribute assigned to attribute sets\n";
//
// 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, $attrCodeTEMP);
for($iCount=0;$iCount<sizeof($values);$iCount++){
$aOption['value']['option'.$iCount][0] = $values[$iCount];
}
$installer->addAttributeOption($aOption);
$installer->endSetup();
echo "New values configured:\n";
//
// 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', $attrCodeTEMP); //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($attrCodeTEMP => $_v), 0);
echo $_id." Saved (".memory_get_usage().")\n";
}
fclose($handle);
}
unlink($attrCodeOLD.".csv");
echo "New attribute configured successfully\n";
//
//// Rename the old attribute
//
//$installer->removeAttribute('catalog_product', $attrCodeOLD);
//echo "Old attribute deleted\n";
//
// Rename temp attribute code to old attribute code
//
$installer->updateAttribute('catalog_product', $attrCodeTEMP, array('attribute_code' => $attrCodeNEW));
echo "New attribute code renamed to the original attribute code\n";
//
// Reindex
//
echo "Reindexing...";
$ids = array(1,2,3,4,5,6,7,8,9);
foreach($ids as $id)
{
$process = Mage::getModel('index/process')->load($id);
$process->reindexAll();
}
echo " Done\n";
}
/**
* Create an attribute.
*
* @param $name
* @param $attributeCode
* @param bool $configurable
* @param bool $visible
*/
function createAttribute($name, $attributeCode, $configurable = false, $visible = true)
{
/** @var Mage_Catalog_Model_Resource_Setup $setup */
$setup = Mage::getResourceModel('catalog/setup','catalog_setup');
if($setup->getAttributeId('catalog_product', $attributeCode))
return;
$data = array(
'label' => $name,
'input' => 'text',
'type' => 'varchar',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'visible' => true,
'unique' => false,
'required' => false,
'used_in_product_listing' => $visible,
'visible_on_front' => $visible,
'is_html_allowed_on_front' => false,
'user_defined' => true,
);
if($configurable)
{
$data = array_merge($data, array(
'input' => 'select',
'is_configurable' => true,
'option' => array('values' => array())
));
}
$setup->addAttribute('catalog_product', $attributeCode, $data);
}
/**
* @param Mage_Eav_Model_Entity_Attribute $attributeToDuplicate
* @param $newAttributeCode
*/
function assignToAttributeSets(Mage_Eav_Model_Entity_Attribute $attributeToDuplicate, $newAttributeCode)
{
/** @var Mage_Catalog_Model_Resource_Setup $setup */
$setup = Mage::getResourceModel('catalog/setup','catalog_setup');
$entityType = Mage::getModel('catalog/product')->getResource()->getTypeId();
$attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection')->setEntityTypeFilter($entityType);
$attributeID = $setup->getAttributeId('catalog_product', $newAttributeCode);
foreach($attributeSetCollection as $attributeSet)
{
/** @var Mage_Eav_Model_Entity_Attribute_Set $attributeSet */
$groups = Mage::getModel('eav/entity_attribute_group')
->getResourceCollection()
->setAttributeSetFilter($attributeSet->getAttributeSetId())
->setSortOrder()
->load();
$found = false;
foreach ($groups as $group)
{
/** @var Mage_Eav_Model_Entity_Attribute_Group $group */
$attributes = Mage::getResourceModel('catalog/product_attribute_collection')
->setAttributeGroupFilter($group->getId())
->addVisibleFilter()
->checkConfigurableProducts()
->load();
if ($attributes->getSize() > 0)
{
foreach ($attributes->getItems() as $attribute)
{
/* @var Mage_Eav_Model_Entity_Attribute $attribute */
if($attribute->getId() == $attributeToDuplicate->getId())
{
// OK to duplicate
$setup->addAttributeToSet('catalog_product', $attributeSet->getAttributeSetId(), $group->getId(), $attributeID);
$found = true;
break;
}
}
}
if($found)
break;
}
}
}
//
// Launch
//
require_once '../../app/Mage.php';
umask( 0 );
Mage::app();
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
Mage::register('isSecureArea', true);
launch($argv[1], $argv[2]);
@pieterjanliekens
Copy link
Copy Markdown

Hey. I want to use your script for changing a Color attribute (currently) text to dropdown.

However when trying I get the following error:
CSV Created
New attribute created
New attribute assigned to attribute sets
New values configured:
New attribute configured successfully
PHP Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4-color2' for key 'UNQ_EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE' in /home/hosts/testing2.host.nl/lib/Zend/Db/Statement/Pdo.php:228
Stack trace:
#0 /home/domains/testing2.host.nl/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
#1 /home/domains/testing2.host.nl/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
#2 /home/domains/testing2.host.nl/app/code/core/Zend/Db/Statement.php(311): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
#3 /home/domains/testing2.host.nl/lib/Zend/Db/Adapter/Abstract.php(480): Zend_Db_Statement->execute(Array)
#4 /home/domains/testing2.host.nl/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('UPDATE `eav_att...', Array)
#5 /home/domains/testing2.host.nl/app/code/community/Aoe/DbRetry/Resource/Db/Pdo/Mysql/Adapter.php(34): Zend_Db_Adapter_Pdo_Abs in /home/domains/testing2.host.nl/lib/Zend/Db/Statement/Pdo.php on line 234
o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment