├── README.md ├── app ├── code │ └── community │ │ └── JR │ │ └── AttributeOptionImage │ │ ├── Block │ │ └── Catalog │ │ │ └── Product │ │ │ └── Attribute │ │ │ └── Edit │ │ │ └── Tab │ │ │ └── Options.php │ │ ├── Helper │ │ ├── Cms │ │ │ └── Wysiwyg │ │ │ │ └── Images.php │ │ └── Data.php │ │ ├── Model │ │ ├── Catalog │ │ │ └── Resource │ │ │ │ └── Eav │ │ │ │ └── Mysql4 │ │ │ │ └── Attribute.php │ │ ├── Eav │ │ │ ├── Entity │ │ │ │ └── Attribute │ │ │ │ │ └── Source │ │ │ │ │ └── Table.php │ │ │ └── Mysql4 │ │ │ │ └── Entity │ │ │ │ └── Attribute │ │ │ │ └── Option.php │ │ └── Observer.php │ │ ├── controllers │ │ └── Cms │ │ │ └── Wysiwyg │ │ │ └── ImagesController.php │ │ ├── etc │ │ └── config.xml │ │ └── sql │ │ └── jr_attributeoptionimage_setup │ │ ├── mysql4-install-1.0.0.php │ │ └── mysql4-upgrade-1.0.0-1.0.1.php ├── design │ └── adminhtml │ │ └── default │ │ └── default │ │ └── template │ │ └── jr │ │ └── catalog │ │ └── product │ │ └── attribute │ │ └── options.phtml └── etc │ └── modules │ └── JR_AttributeOptionImage.xml ├── composer.json └── modman /README.md: -------------------------------------------------------------------------------- 1 | # Add images/icons to attribute options of your Magento products 2 | 3 | ![Attribute Option Image](http://i.imgur.com/VB2W5.jpg) 4 | 5 | ## Features 6 | 7 | * Associate image/icon to attribute options 8 | * Specify relative/external url or pick an image from Magento Media Gallery 9 | 10 | ## Installation 11 | 12 | ### Magento CE 1.5.x, 1.6.x 13 | 14 | Install with [modgit](https://github.com/jreinke/modgit): 15 | 16 | $ cd /path/to/magento 17 | $ modgit init 18 | $ modgit clone attr-opt-img https://github.com/jreinke/magento-attribute-option-image.git 19 | 20 | or download package manually: 21 | 22 | * Download latest version [here](https://github.com/jreinke/magento-attribute-option-image/downloads) 23 | * Unzip in Magento root folder 24 | * Clean cache 25 | 26 | ## Usage 27 | 28 | 1. Go to *Catalog > Attributes > Manage Attributes*, choose an attribute with options and associate an image/icon to each option 29 | 2. In frontend templates, retrieve image src like this `Mage::helper('attributeoptionimage')->getAttributeOptionImage($optionId);` where `$optionId` could be something like `$product->getColor()` 30 | 31 | ## Full overview 32 | 33 | I wrote an article on my blog for full extension overview, [click here](http://www.johannreinke.com/en/2012/02/05/magento-add-images-to-product-attribute-options/). 34 | -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Block/Catalog/Product/Attribute/Edit/Tab/Options.php: -------------------------------------------------------------------------------- 1 | setTemplate('jr/catalog/product/attribute/options.phtml'); 9 | } 10 | 11 | public function getOptionValues() 12 | { 13 | $attributeType = $this->getAttributeObject()->getFrontendInput(); 14 | $defaultValues = $this->getAttributeObject()->getDefaultValue(); 15 | if ($attributeType == 'select' || $attributeType == 'multiselect') { 16 | $defaultValues = explode(',', $defaultValues); 17 | } else { 18 | $defaultValues = array(); 19 | } 20 | 21 | switch ($attributeType) { 22 | case 'select': 23 | $inputType = 'radio'; 24 | break; 25 | case 'multiselect': 26 | $inputType = 'checkbox'; 27 | break; 28 | default: 29 | $inputType = ''; 30 | break; 31 | } 32 | 33 | $values = $this->getData('option_values'); 34 | if (is_null($values)) { 35 | $values = array(); 36 | $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection') 37 | ->setAttributeFilter($this->getAttributeObject()->getId()) 38 | ->setPositionOrder('desc', true) 39 | ->load(); 40 | 41 | foreach ($optionCollection as $option) { 42 | $value = array(); 43 | if (in_array($option->getId(), $defaultValues)) { 44 | $value['checked'] = 'checked="checked"'; 45 | } else { 46 | $value['checked'] = ''; 47 | } 48 | 49 | $value['intype'] = $inputType; 50 | $value['id'] = $option->getId(); 51 | $value['sort_order'] = $option->getSortOrder(); 52 | $value['image'] = $option->getImage(); 53 | $value['thumb'] = $option->getThumb(); 54 | foreach ($this->getStores() as $store) { 55 | $storeValues = $this->getStoreOptionValues($store->getId()); 56 | if (isset($storeValues[$option->getId()])) { 57 | $value['store'.$store->getId()] = htmlspecialchars($storeValues[$option->getId()]); 58 | } 59 | else { 60 | $value['store'.$store->getId()] = ''; 61 | } 62 | } 63 | $values[] = new Varien_Object($value); 64 | } 65 | $this->setData('option_values', $values); 66 | } 67 | 68 | return $values; 69 | } 70 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Helper/Cms/Wysiwyg/Images.php: -------------------------------------------------------------------------------- 1 | getStaticUrlsAllowed()) { 8 | return true; 9 | } 10 | 11 | return parent::isUsingStaticUrlsAllowed(); 12 | } 13 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Helper/Data.php: -------------------------------------------------------------------------------- 1 | getAttributeOptionImages(); 8 | $image = array_key_exists($optionId, $images) ? $images[$optionId] : ''; 9 | if ($image && (strpos($image, 'http') !== 0)) { 10 | $image = Mage::getDesign()->getSkinUrl($image); 11 | } 12 | 13 | return $image; 14 | } 15 | 16 | public function getAttributeOptionImages() 17 | { 18 | $images = Mage::getResourceModel('eav/entity_attribute_option')->getAttributeOptionImages(); 19 | 20 | return $images; 21 | } 22 | 23 | public function getAttributeOptionThumb($optionId) 24 | { 25 | $images = $this->getAttributeOptionThumbs(); 26 | $image = array_key_exists($optionId, $images) ? $images[$optionId] : ''; 27 | if ($image && (strpos($image, 'http') !== 0)) { 28 | $image = Mage::getDesign()->getSkinUrl($image); 29 | } 30 | 31 | return $image; 32 | } 33 | 34 | public function getAttributeOptionThumbs() 35 | { 36 | $images = Mage::getResourceModel('eav/entity_attribute_option')->getAttributeOptionThumbs(); 37 | 38 | return $images; 39 | } 40 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Model/Catalog/Resource/Eav/Mysql4/Attribute.php: -------------------------------------------------------------------------------- 1 | getOption(); 8 | if (is_array($option)) { 9 | $write = $this->_getWriteAdapter(); 10 | $optionTable = $this->getTable('attribute_option'); 11 | $optionValueTable = $this->getTable('attribute_option_value'); 12 | $stores = Mage::getModel('core/store') 13 | ->getResourceCollection() 14 | ->setLoadDefault(true) 15 | ->load(); 16 | 17 | if (isset($option['value'])) { 18 | $attributeDefaultValue = array(); 19 | if (!is_array($object->getDefault())) { 20 | $object->setDefault(array()); 21 | } 22 | 23 | foreach ($option['value'] as $optionId => $values) { 24 | $intOptionId = (int) $optionId; 25 | if (!empty($option['delete'][$optionId])) { 26 | if ($intOptionId) { 27 | $condition = $write->quoteInto('option_id=?', $intOptionId); 28 | $write->delete($optionTable, $condition); 29 | } 30 | 31 | continue; 32 | } 33 | 34 | if (!$intOptionId) { 35 | $data = array( 36 | 'attribute_id' => $object->getId(), 37 | 'sort_order' => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0, 38 | 'image' => isset($option['image'][$optionId]) ? $option['image'][$optionId] : '', 39 | 'thumb' => isset($option['thumb'][$optionId]) ? $option['thumb'][$optionId] : '', 40 | ); 41 | $write->insert($optionTable, $data); 42 | $intOptionId = $write->lastInsertId(); 43 | } 44 | else { 45 | $data = array( 46 | 'sort_order' => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0, 47 | 'image' => isset($option['image'][$optionId]) ? $option['image'][$optionId] : '', 48 | 'thumb' => isset($option['thumb'][$optionId]) ? $option['thumb'][$optionId] : '', 49 | ); 50 | $write->update($optionTable, $data, $write->quoteInto('option_id=?', $intOptionId)); 51 | } 52 | 53 | if (in_array($optionId, $object->getDefault())) { 54 | if ($object->getFrontendInput() == 'multiselect') { 55 | $attributeDefaultValue[] = $intOptionId; 56 | } else if ($object->getFrontendInput() == 'select') { 57 | $attributeDefaultValue = array($intOptionId); 58 | } 59 | } 60 | 61 | 62 | // Default value 63 | if (!isset($values[0])) { 64 | Mage::throwException(Mage::helper('eav')->__('Default option value is not defined.')); 65 | } 66 | 67 | $write->delete($optionValueTable, $write->quoteInto('option_id=?', $intOptionId)); 68 | foreach ($stores as $store) { 69 | if (isset($values[$store->getId()]) && (!empty($values[$store->getId()]) || $values[$store->getId()] == "0")) { 70 | $data = array( 71 | 'option_id' => $intOptionId, 72 | 'store_id' => $store->getId(), 73 | 'value' => $values[$store->getId()], 74 | ); 75 | $write->insert($optionValueTable, $data); 76 | } 77 | } 78 | } 79 | 80 | $write->update($this->getMainTable(), array( 81 | 'default_value' => implode(',', $attributeDefaultValue) 82 | ), $write->quoteInto($this->getIdFieldName() . '=?', $object->getId())); 83 | } 84 | } 85 | return $this; 86 | } 87 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Model/Eav/Entity/Attribute/Source/Table.php: -------------------------------------------------------------------------------- 1 | setPositionOrder('asc') 9 | ->setAttributeFilter($this->getAttribute()->getId()) 10 | ->setStoreFilter($this->getAttribute()->getStoreId()) 11 | ->load() 12 | ->toArray(); 13 | foreach ($options['items'] as $item) { 14 | if ($item['option_id'] == $value) { 15 | return $item['image']; 16 | } 17 | } 18 | return false; 19 | } 20 | 21 | public function getOptionThumb($value) 22 | { 23 | $options = Mage::getResourceModel('eav/entity_attribute_option_collection') 24 | ->setPositionOrder('asc') 25 | ->setAttributeFilter($this->getAttribute()->getId()) 26 | ->setStoreFilter($this->getAttribute()->getStoreId()) 27 | ->load() 28 | ->toArray(); 29 | foreach ($options['items'] as $item) { 30 | if ($item['option_id'] == $value) { 31 | return $item['thumb']; 32 | } 33 | } 34 | return false; 35 | } 36 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Model/Eav/Mysql4/Entity/Attribute/Option.php: -------------------------------------------------------------------------------- 1 | getReadConnection() 8 | ->select() 9 | ->from($this->getTable('eav/attribute_option'), array('option_id', 'image')); 10 | 11 | return $this->getReadConnection()->fetchPairs($select); 12 | } 13 | 14 | public function getAttributeOptionThumbs() 15 | { 16 | $select = $this->getReadConnection() 17 | ->select() 18 | ->from($this->getTable('eav/attribute_option'), array('option_id', 'thumb')); 19 | 20 | return $this->getReadConnection()->fetchPairs($select); 21 | } 22 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/Model/Observer.php: -------------------------------------------------------------------------------- 1 | getBlock('head') 9 | ->setCanLoadExtJs(true) 10 | ->addJs('mage/adminhtml/variables.js') 11 | ->addJs('mage/adminhtml/wysiwyg/widget.js') 12 | ->addJs('lib/flex.js') 13 | ->addJs('lib/FABridge.js') 14 | ->addJs('mage/adminhtml/flexuploader.js') 15 | ->addJs('mage/adminhtml/browser.js') 16 | ->addJs('prototype/window.js') 17 | ->addItem('js_css', 'prototype/windows/themes/default.css') 18 | ->addItem('js_css', 'prototype/windows/themes/magento.css'); 19 | } 20 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/controllers/Cms/Wysiwyg/ImagesController.php: -------------------------------------------------------------------------------- 1 | getRequest()->getParam('static_urls_allowed')) { 10 | $this->_getSession()->setStaticUrlsAllowed(true); 11 | } 12 | parent::indexAction(); 13 | } 14 | 15 | public function onInsertAction() 16 | { 17 | parent::onInsertAction(); 18 | $this->_getSession()->setStaticUrlsAllowed(); 19 | } 20 | } -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1.0.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | JR_AttributeOptionImage 13 | 14 | 15 | 16 | 17 | 18 | JR_AttributeOptionImage_Model 19 | 20 | 21 | 22 | JR_AttributeOptionImage_Model_Catalog_Resource_Eav_Mysql4_Attribute 23 | 24 | 25 | 26 | 27 | JR_AttributeOptionImage_Model_Eav_Entity_Attribute_Source_Table 28 | 29 | 30 | 31 | 32 | JR_AttributeOptionImage_Model_Eav_Mysql4_Entity_Attribute_Option 33 | 34 | 35 | 36 | 37 | 38 | 39 | JR_AttributeOptionImage_Block_Catalog_Product_Attribute_Edit_Tab_Options 40 | 41 | 42 | 43 | 44 | 45 | JR_AttributeOptionImage_Helper 46 | 47 | 48 | 49 | JR_AttributeOptionImage_Helper_Cms_Wysiwyg_Images 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | JR_AttributeOptionImage 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | jr_attributeoptionimage/observer 71 | updateLayout 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/sql/jr_attributeoptionimage_setup/mysql4-install-1.0.0.php: -------------------------------------------------------------------------------- 1 | getTable('eav_attribute_option'); 7 | $installer->startSetup(); 8 | 9 | $installer->run(" 10 | ALTER TABLE `{$tableOption}` 11 | ADD `image` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; 12 | "); 13 | 14 | $installer->endSetup(); 15 | -------------------------------------------------------------------------------- /app/code/community/JR/AttributeOptionImage/sql/jr_attributeoptionimage_setup/mysql4-upgrade-1.0.0-1.0.1.php: -------------------------------------------------------------------------------- 1 | getTable('eav_attribute_option'); 7 | $installer->startSetup(); 8 | 9 | $installer->run(" 10 | ALTER TABLE `{$tableOption}` 11 | ADD `thumb` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; 12 | "); 13 | 14 | $installer->endSetup(); 15 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/jr/catalog/product/attribute/options.phtml: -------------------------------------------------------------------------------- 1 | 27 | 34 |
35 | 42 |
43 | 44 |
45 |
46 |

__('Manage Titles (Size, Color, etc.)') ?>

47 |
48 |
49 |
50 | 51 | 52 | getStores() as $_store): ?> 53 | 54 | 55 | 56 | 57 | getLabelValues() ?> 58 | getStores() as $_store): ?> 59 | 62 | 63 | 64 |
getName() ?>
60 | getReadOnly()):?> disabled="disabled"/> 61 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |

__('Manage Options (values of your attribute)') ?>

72 |
73 |
74 |
75 | 76 | 77 | getStores() as $_store): ?> 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | getStores() as $_store): ?> 92 | 93 | 94 | 95 | 96 | 102 | 103 |
getName() ?>__('Position') ?>__('Is Default') ?>__('Image') ?>__('Thumbnail') ?> 85 | getReadOnly()):?> 86 | getAddNewButtonHtml() ?> 87 | 88 |
getReadOnly()):?> disabled="disabled"/>getReadOnly()):?> disabled="disabled"/>getReadOnly()):?> disabled="disabled"/> 97 | 98 | getReadOnly()):?> 99 | getDeleteButtonHtml() ?> 100 | 101 |
104 |
105 | 106 |
107 |
108 | 217 | -------------------------------------------------------------------------------- /app/etc/modules/JR_AttributeOptionImage.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"aligent/magento-attribute-option-image", 3 | "type":"magento-module", 4 | "license":"OSL-3.0", 5 | "homepage":"https://github.com/aligent/magento-attribute-option-image.git", 6 | "description":"Add images/icons to attribute options of your Magento products", 7 | "require":{ 8 | "magento-hackathon/magento-composer-installer":"*" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | # JReinke Magento Attribute Option Image deploy instructions 2 | app/code/community/JR app/code/community/JR 3 | app/design/adminhtml/default/default/template/jr app/design/adminhtml/default/default/template/jr 4 | app/etc/modules/JR_AttributeOptionImage.xml app/etc/modules/JR_AttributeOptionImage.xml 5 | --------------------------------------------------------------------------------