blog site of branko ajzele, senior developer / project manager

Color switcher (improved) for Magento, part 1

Long time ago, I wrote an article on “Color switcher topic” named Magento product image change on colour selection. Given that it is an old article and that my understanding of Magento inner workings has grown significantly, I would like to show you a new concept, or shall I say a new way of doing things.

Before I start, I would like to emphasise that the code I will present in this article is not the full solution. This is a part one of the topic. I make no promise of ever writing a part two :) If so, one might wonder, why even bother reading it since its not complete.

Please take some time to review the screenshots provided. This article is focused on core problem of “colour switcher”. For me this kind of solution seems most user friendly, unlike some currently available commercial extensions that do the same job.

My idea was to add a new column to Product edit page under the Images section, like shown on photo below. This way, site owner can easily “map” images to “colours” by using the existing and familiar management interface.

ColorSwitcher2

I believe that advantages of using this kind of approach are obvious. Although, I am not saying it will suite to all of you. Now lets jump to the implementation of the core logic to make this work (to certain extent).

First, I decided to use the “Attribute” section in order to create new “internal use only” attribute named internal_map2color to which I would save the necessary “photo to colour mapping info”. See the screenshots below.

ColorSwitcher5a

ColorSwitcher5b

After we create the necessary internal_map2color attribute (use Text Area as type, can hold more text data) its time to do a bit of code modifications. Note that I say “modifications”, although the extraction to full blown extension would be more proper. Given the scale of extension development and my limited free time, I will guide you trough modifications steps.

Open the app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php file and look for “public function saveAction()”. Under it you will find the section that actually saves the product, its wrapped under the try-catch block. Add the following code right before the $_product->save();.

/**
 * START Custom added code
 * Ads the extra info to gallery object (array) so we know which photo maps to which color attribute
 */
//$media_gallery['map2Color'] = 'my cool values here'; 
 
//Grab entire product gallery object
$media_gallery = $product->media_gallery;
//Grab images section of above gallery object
$mediaGalleryImages = $product->media_gallery['images'];
 
//Manipulate the $mediaGalleryImages var, add extra data to it
$mediaGalleryImageObjects = json_decode($mediaGalleryImages);
 
$map2Color = $this->getRequest()->getParam('map2Color');
if(isset($map2Color['__value_id__'])) { 
	unset($map2Color['__value_id__']); 
}
 
//We must create the 'internal_map2color' text attribute first and add it to attribute set
$product->setInternalMap2color(serialize($map2Color)); 
/**
 * END Custom added code
 */

Now we open the app/design/adminhtml/default/default/template/catalog/product/helper/gallery.phtml file. Here we will add the three sections. First section is the “html” code that will be outputted and visible in the Images tab under product edit like shown on photo above. Here is the code for this firs section:

<?php /* START Custom added */ ?>
<?php 
 
$map2ColorOptions = Mage::getResourceModel('eav/entity_attribute_option_collection')
		                ->setAttributeFilter(272)
		                ->setPositionOrder('desc', true)
		                ->load();
 
//foreach($map2ColorOptions as $optionItem) {
	/** @var $optionItem Mage_Eav_Model_Entity_Attribute_Option */
	//$optionItem = new Mage_Eav_Model_Entity_Attribute_Option();
 
	/**
	 * var_dump($optionItem->debug());
		array
		  'option_id' => string '60' (length=2)
		  'attribute_id' => string '272' (length=3)
		  'sort_order' => string '0' (length=1)
		  'value' => string 'White' (length=5)
 
		array
		  'option_id' => string '23' (length=2)
		  'attribute_id' => string '272' (length=3)
		  'sort_order' => string '0' (length=1)
		  'value' => string 'Silver' (length=6)
 
		array
		  'option_id' => string '26' (length=2)
		  'attribute_id' => string '272' (length=3)
		  'sort_order' => string '0' (length=1)
		  'value' => string 'Red' (length=3)
 
	 */
//}
 
$_product = Mage::helper('catalog')->getProduct();
$_internalMap2Color = unserialize($_product->getData('internal_map2color'));
 
?>
 
<td>
	<select class="map2ColorSelects" id="map2Color__value_id__" name="map2Color[__value_id__]" style="width:60px;">
		<option value=""><?php echo $this->__('') ?></option>
		<?php foreach($map2ColorOptions as $map2ColorItem): ?>
		<option value="<?php echo $map2ColorItem["value"] ?>"><?php echo $map2ColorItem["value"] ?></option>
		<?php endforeach; ?>
	</select>
</td>
<?php /* END Custom added */ ?>

One important thing to note here, I used the setAttributeFilter(272) method to “make the code look for” for attribute color given that 272 is the id assigned to color attribute won my machine. You need to set it to id of your attribute or write some extra code to fetch it by attribute code name. Note that I am not referring to internal_map2color attribute here.

Second section we need to add to this file is the section that will set already assigned values to select element of html. So if we already assigned colour “Green” to certain image, than set this as selected index to dropdown so we do not have to reset colours each time we re-save the product. Here is the code for second section, it goes at the bottom of the app/design/adminhtml/default/default/template/catalog/product/helper/gallery.phtml file.

<?php /* START Custom added */ ?>
&lt;script type="text/javascript"&gt;
//<![CDATA[
 
<?php if(!empty($_internalMap2Color)): ?>
var colorMap2ColorVarValue = new Array();
 
<?php foreach ($_internalMap2Color as $colorVarKey => $colorVarValue): ?>
colorMap2ColorVarValue[<?php echo $colorVarKey ?>] = "<?php echo $colorVarValue ?>";
<?php endforeach; ?>
 
<?php endif; ?>
 
var idNamePrefix = 'map2Color';
 
$$('select.map2ColorSelects').each(function(data) {
	if(data.id != 'map2Color__value_id__') {
		//"Select" element type and its id value
		var fullElementIdValue = String(data.id);
 
		if(idNamePrefix.indexOf(fullElementIdValue)) {
			var numericId = fullElementIdValue.substring(idNamePrefix.length);
			var options = data.options;
 
			for(i = 0; i < options.length; i++) {
				if(options[i].value == colorMap2ColorVarValue[numericId]) {
					$(fullElementIdValue).selectedIndex = i;
				}
				//console.log(options[i].value);
			}
 
			//console.log(options.length);
 
			//alert(fullElementIdValue);
			//alert(colorMap2ColorVarValue[numericId]);
 
			//$(fullElementIdValue).selectedIndex = activeIndex;
		}
	}
});
//]]>
&lt;/script&gt;
<?php /* END Custom added */ ?>

Third section is minor, a th column label like:

<th><?php echo Mage::helper('catalog')->__('Map2Color') ?></th>

And final modifications would go into the app/design/frontend/default/default/template/catalog/product/view/media.phtml file (or any other view file for frontend). There, you can use the code like:

//Fecth sthe assigned photo-colors relations from products
$_internalMap2Color = unserialize($_product->getData('internal_map2color'));
 
$_internalMap2ColorArray = array();
$_internalMap2ColorIds = array();
 
foreach($_internalMap2Color as $_internalMap2ColorKey => $_internalMap2ColorValue) {
	$_internalMap2ColorIds[$_internalMap2ColorValue][] = $_internalMap2ColorKey;
}
 
print_r($_internalMap2ColorIds);

Code above would give us result like shown on photo below.

ColorSwitcher3

As you can see, we end up with having nice array of mappings between colour and true product photo id. So much for the “part 1″ of this article :) -Now with little JavaScript you can take from here and do nice colour switcher, leaving site owner to have full control of “true colour mapping” for images.

Please use the code on development machines. I have no interest on hearing about “It broke my site” issues. Sorry if I sound a bit grungy :)

Hope it helps. Cheers.

blog comments powered by Disqus
Powered by Wordpress | Designed by Elegant Themes