We had a request from a client who wanted to display images for custom options. In this article, I’ll explain how to add the image field to the custom option in admin.
Create new module Inchoo_ProductCustomOptionsFile
app/etc/modules/Inchoo_ProductCustomOptionsFile.xml
-
<?xml version="1.0"?> <config> <modules> <Inchoo_ProductCustomOptionsFile> <active>true</active> <codePool>local</codePool> </Inchoo_ProductCustomOptionsFile> </modules> </config>
Configuration file
To add your custom field it is necessary to rewrite class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Type_Select and set your template. To fill custom option image filed with new image’s names it is necessary to rewrite the class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option.
/app/code/local/Inchoo/ProductCustomOptionsFile/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Inchoo_ProductCustomOptionsFile>
<version>1.0.0</version>
</Inchoo_ProductCustomOptionsFile>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<catalog_product_edit_tab_options_type_select>Inchoo_ProductCustomOptionsFile_Block_Adminhtml_Rewrite_Catalog_Product_Edit_Type_Select</catalog_product_edit_tab_options_type_select>
<catalog_product_edit_tab_options_option>Inchoo_ProductCustomOptionsFile_Block_Adminhtml_Rewrite_Catalog_Product_Edit_Tab_Options_Option</catalog_product_edit_tab_options_option>
</rewrite>
</adminhtml>
<inchoo_file>
<class>Inchoo_ProductCustomOptionsFile_Block</class>
</inchoo_file>
</blocks>
<resources>
<inchoo_productcustomoptionsfile_setup>
<setup>
<module>Inchoo_ProductCustomOptionsFile</module>
</setup>
</inchoo_productcustomoptionsfile_setup>
</resources>
</global>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<inchoo_product before="Mage_Adminhtml">Inchoo_ProductCustomOptionsFile_Adminhtml</inchoo_product>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
Blocks
/app/code/local/Inchoo/ProductCustomOptionsFile/Block/Adminhtml/Rewrite/Catalog/Product/Edit/Type/Select.php
We want to use our template instead default one for custom option.
<?php
class Inchoo_ProductCustomOptionsFile_Block_Adminhtml_Rewrite_Catalog_Product_Edit_Type_Select extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Type_Select
{
public function __construct()
{
parent::__construct();
$this->setTemplate('catalog/product/edit/options/type/select-with-file.phtml');
$this->setCanEditPrice(true);
$this->setCanReadPrice(true);
}
}
Create a template file and copy content of /app/design/adminhtml/default/default/template/catalog/product/edit/options/type/select.phtml into our new template file /app/design/adminhtml/default/default/template/catalog/product/edit/options/type/select-with-file.phtml
Add code between Inchoo into select-with-file.phtml template
<!---...-->
OptionTemplateSelect =
<!---...-->
'<th class="type-sku"><?php echo Mage::helper('core')->jsQuoteEscape(Mage::helper('catalog')->__('SKU')) ?></th>'+
// Inchoo
'<th class="type-title"><?php echo Mage::helper('core')->jsQuoteEscape(Mage::helper('catalog')->__('Image Name')) ?></th>'+
'<th class="type-title"><?php echo Mage::helper('core')->jsQuoteEscape(Mage::helper('catalog')->__('Upload New Image')) ?></th>'+
// Inchoo
'<th class="type-title"><?php echo Mage::helper('core')->jsQuoteEscape(Mage::helper('catalog')->__('Sort Order')) ?></th>'+
<!---...-->
OptionTemplateSelectRow =
<!---...-->
'<td><input type="text" class="input-text" name="product[options][{{id}}][values][{{select_id}}][sku]" value="{{sku}}"></td>'+
// Inchoo
'<td><input type="text" class="select-type-image" id="product_option_{{id}}_select_{{select_id}}_image" name="product[options][{{id}}][values][{{select_id}}][image]" value="{{image}}">{{checkboxScopeTitle}}</td>'+
'<td><input type="file" class="input-text select-type-image" id="image" name="{{id}}-{{select_id}}"></td>'+
// Inchoo
'<td><input type="text" class="validate-zero-or-greater input-text" name="product[options][{{id}}][values][{{select_id}}][sort_order]" value="{{sort_order}}"></td>'+
<!---...-->
To pass our new custom option value to template we need to rewrite Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option class. Create block /app/code/local/Inchoo/ProductCustomOptionsFile/Block/Adminhtml/Rewrite/Catalog/Product/Edit/Tab/Options/Option.php Add code between Inchoo comment. Function getOptionValues() returns all product custom options to javascript object which fills custom options fields.
class Inchoo_ProductCustomOptionsFile_Block_Adminhtml_Rewrite_Catalog_Product_Edit_Tab_Options_Option extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option
{
public function getOptionValues()
{
// ...
$i = 0;
$itemCount = 0;
foreach ($option->getValues() as $_value) {
/* @var $_value Mage_Catalog_Model_Product_Option_Value */
$value['optionValues'][$i] = array(
'item_count' => max($itemCount, $_value->getOptionTypeId()),
'option_id' => $_value->getOptionId(),
'option_type_id' => $_value->getOptionTypeId(),
'title' => $this->escapeHtml($_value->getTitle()),
'price' => ($showPrice)
? $this->getPriceValue($_value->getPrice(), $_value->getPriceType()) : '',
'price_type' => ($showPrice) ? $_value->getPriceType() : 0,
'sku' => $this->escapeHtml($_value->getSku()),
'sort_order' => $_value->getSortOrder(),
// Inchoo
'image' => $_value->getImage(),
// Inchoo
);
// ...
Now we have our custom fields Image Name and Upload New Images :
Saving images
To save images into database, we need to create setup script and rewrite Mage_Adminhtml_Catalog_ProductController. Then create setup script /app/code/local/Inchoo/ProductCustomOptionsFile/sql/inchoo_productcustomoptionsfile_setup/install-1.0.0.php
<?php
/* @var $installer Mage_Core_Model_Resource_Setup */
$installer = $this;
$installer->getConnection()
->addColumn($installer->getTable('catalog/product_option_type_value'), 'image', 'VARCHAR(255) NULL');
$installer->endSetup();
Rewrite class Mage_Adminhtml_Catalog_ProductController and add code between Inchoo to save images name into table catalog_product_option_type_value and upload images.
<?php
require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'Catalog'.DS.'ProductController.php');
class Inchoo_ProductCustomOptionsFile_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
/**
* Initialize product before saving
*/
protected function _initProductSave()
{
// ..
$product->setCanSaveConfigurableAttributes(
(bool) $this->getRequest()->getPost('affect_configurable_product_attributes')
&& !$product->getConfigurableReadonly()
);
// Inchoo
$skuImageName=trim($product->getSku());
$imagesFiles=$_FILES;
$path = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'customoption' .DS. 'images';
foreach ($imagesFiles as $key=>$value)
{
$optionsValue = explode('-',$key);
foreach ($value as $key2=>$value2)
{
if($key2=='name' && $value2!="") {
try {
$uploader = new Varien_File_Uploader($key);
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png','svg'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$optionTitle = trim($productData['options'][$optionsValue[0]]['title']);
$optionValueTitle = trim($productData['options'][$optionsValue[0]]['values'][$optionsValue[1]]['title']);
$imageExtension = pathinfo($value2,PATHINFO_EXTENSION);
$newImageName =$skuImageName.'_'.$optionTitle.'_'.$optionValueTitle.'.'.$imageExtension;
$uploader->save($path, $newImageName);
$productData['options'][$optionsValue[0]]['values'][$optionsValue[1]]['image']=$uploader->getUploadedFileName();
} catch(Exception $e) {
Mage::log('Unable to save custom option image. ' . $e->getMessage(), null, null, true);
}
}
}
}
// Inchoo
And that’s it. If you have any questions, feel free to post them in comments.