Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

Page 1 of 3
Add Media Uploader to Custom Module
 
SwiftCol
Sr. Member
 
Total Posts:  85
Joined:  2008-05-22
 

I have created a custom module, and would like to add the Media Uploader to it, so that my module can include the uploading of images. I really have no idea how this is done, and it is vital that I get this working. Can anyone help point me in the right direction?

Thank you.

 
Magento Community Magento Community
Magento Community
Magento Community
 
alistek
Sr. Member
 
Total Posts:  293
Joined:  2008-04-02
Normal, IL
 

Take a look at the /adminhtml/Blocks/Media folder.  That appears to control the Images section of a product.  You can see that it is set up much like the other grids.  The main difference is that it is pulling data through JSON.  Also if you look at the Media/Uploader.phtml file it uses some Flash (FLEX) to do the uploading.  I would study those and that should help.

-Adam

 
Magento Community Magento Community
Magento Community
Magento Community
 
SwiftCol
Sr. Member
 
Total Posts:  85
Joined:  2008-05-22
 

Looking at those files only tells me where the Image Uploader code is, not how to implement it.

Take a look at core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php, in that file there is this chunk of code:

$this->addTab('group_'.$group->getId(), array(
    
'label'     => Mage::helper('catalog')->__($group->getAttributeGroupName()),
    
'content'   => $this->getLayout()->createBlock('adminhtml/catalog_product_edit_tab_attributes')
        ->
setGroup($group)
        ->
setGroupAttributes($attributes)
        ->
toHtml(),
));

I’ve studied it, and during a loop, that chunk of code renders the Image Uploader from the Media module. I took a look at core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Attributes.php to try and figure out how it goes about building the tab content, but i’ve hit a few snags. One, is that the $attribute variable is too big to even var_dump(), which is amazing. So i can’t really see whats in it. Two, is that when creating the fieldset, gallery is excluded, possibly leaving the Media Module to another chunk of code that I can’t find.

Again, in the attributes.php file, I see this line:

$form->getElement('media_gallery')
The Images section of the Catalog Products editor is the only tab without a new attribute button, telling me that some how the attributes.php file is creating the Image tab, which includes the Media Module, but I just can’t for the life of my figure out how it does this!

Do you see how it’s including the Media Module, or do you know how I can do so?

 
Magento Community Magento Community
Magento Community
Magento Community
 
mkd
Jr. Member
 
Total Posts:  10
Joined:  2008-06-25
 

Hello,

Did you have any luck using Media/Uploader in your custom module? I’m trying to do the same, but it’s not all clear to me where to start. Including the Uploader with the following code in a (Module)Controller does show the media uploader buttons.

public function testmediaAction() {
  $this
->loadLayout();
  
$this->_addContent($this->getLayout()->createBlock('adminhtml/media_uploader'));
  
$this->renderLayout();
}

However, from here I do not know where to configure the upload actions in order te catch the uploaded items and store them somewhere.

If you have any experience in this, you’re welcome!

 
Magento Community Magento Community
Magento Community
Magento Community
 
mkd
Jr. Member
 
Total Posts:  10
Joined:  2008-06-25
 

I just discovered that the media uploader searches for an uploadAction in the controller where it is called.

So in my case I have the method testmediaAction in <Module>Controller to create and display a media uploader block:

public function testmediaAction() {
  $this
->loadLayout();
        
  
$uploader $this->getLayout()->createBlock('adminhtml/media_uploader');
  
$this->_addContent($uploader);
        
  
$this->renderLayout();
}
This media uploader fires a request for magento/index.php/<module>/adminhtml_<module>/upload when you push the Upload button.

Simply creating an uploadAction in <Module>Controller gives you the possibility to adjust what to happen to the uploaded files.

The method that is used by the image gallery attributes of a product can be found in the class Mage_Adminhtml_Catalog_Product_GalleryController:

public function uploadAction()
    
{
        $result 
= array();
        try 
{
            $uploader 
= new Varien_File_Uploader('image');
            
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
            
$uploader->setAllowRenameFiles(true);
            
$uploader->setFilesDispersion(true);
            
$result $uploader->save(
                
Mage::getSingleton('catalog/product_media_config')->getBaseTmpMediaPath()
            );

            
$result['url'Mage::getSingleton('catalog/product_media_config')->getTmpMediaUrl($result['file']);
            
$result['file'$result['file''.tmp';
            
$result['cookie'= array(
                
'name'     => session_name(),
                
'value'    => $this->_getSession()->getSessionId(),
                
'lifetime' => $this->_getSession()->getCookieLifetime(),
                
'path'     => $this->_getSession()->getCookiePath(),
                
'domain'   => $this->_getSession()->getCookieDomain()
            );
        
catch (Exception $e{
            $result 
= array('error'=>$e->getMessage(), 'errorcode'=>$e->getCode());
        
}

        $this
->getResponse()->setBody(Zend_Json::encode($result));
    
}
Hope this helps for those who have the same trouble digging out all the stuff about Media Upload in Magento.
 
Magento Community Magento Community
Magento Community
Magento Community
 
somesid
Sr. Member
 
Total Posts:  83
Joined:  2008-06-20
 

I must say I feel really dumb right now, mainly got stuck because of the enctype we forgot ! But here is how you make your upload work !!!

First lets suppose you created a custom module with the module creator.

Then in /app/code/local/Company/ModName/Block/Adminhtml/ModName/Edit/Form.php

Add ‘enctype’ => ‘multipart/form-data’, yeah ! That should help to get something in $_FILES ....

$form = new Varien_Data_Form(array(
        
'id' => 'edit_form',
        
'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
        
'method' => 'post',
        
'enctype' => 'multipart/form-data'
   
)
 );

Then in /app/code/local/Company/ModName/Block/Adminhtml/ModName/Edit/Tab/Form.php

in _prepareForm
Add your image field (you can add a field of type file or imagefile for vidéos !

$fieldset->addField('fileinputname''image', array(
          
'label'     => Mage::helper('pictos')->__('File label'),
          
'required'  => false,
          
'name'      => 'fileinputname',
));

Then in /app/code/local/Company/ModName/controllers/Adminhtml/ModuleNameController.php again
after if ($data = $this->getRequest()->getPost()) { in saveAction()

if($_FILES['fileinputname']['name'!= ''{

    
try {    
         $uploader 
= new Varien_File_Uploader('fileinputname');
         
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
         
$uploader->setAllowRenameFiles(false);
         
$uploader->setFilesDispersion(false);
     
         
$path Mage::getBaseDir('media') . DS ;
                
         
$uploader->save($path$_FILES['fileinputname']['name']);
    
catch (Exception $e{
          
    }

    $data[
'fileinputname'$_FILES['fileinputname']['name'];

}

EDITED WITH FIX : if you are using an image field type, (image is set in addField), then you should add the following code after the if in the controller code. It will now handle a “delete” checkbox linked to the upload field.

else {        
    
if(isset($data['fileinputname']['delete']) && $data['fileinputname']['delete'== 1)
         
$data['fileinputname''';
    else 
        unset(
$data['fileinputname']);
}

That’s it you’re done.

I made some progress as well with the uploader from the product page, will post tomorrow.

 
Magento Community Magento Community
Magento Community
Magento Community
 
somesid
Sr. Member
 
Total Posts:  83
Joined:  2008-06-20
 

To use the media uploader mkd pointed out the right direction :

in/app/code/local/Company/ModName/controllers/Adminhtml/ModuleNameController.php

in editAction

add after

$this->_addContent($this->getLayout()->createBlock('pictos/adminhtml_pictos_edit'))
    ->
_addLeft($this->getLayout()->createBlock('pictos/adminhtml_pictos_edit_tabs'));

$this->_addContent(
        
$this->getLayout()->createBlock('adminhtml/media_uploader')
    );

still in /app/code/local/Company/ModName/controllers/Adminhtml/ModuleNameController.php

Add

public function uploadAction()
    
{

        
try {
            $uploader 
= new Varien_File_Uploader('file');
            
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
            
$uploader->setAllowRenameFiles(false);
            
$uploader->setFilesDispersion(false);

            
$path Mage::getBaseDir('media') . DS ;
            
            
$uploader->save($path);
            
        
catch (Exception $e{
            $result 
= array('error'=>$e->getMessage(), 'errorcode'=>$e->getCode());
        
}

        $this
->getResponse()->setBody(Zend_Json::encode($result));
    
}

You got an media uploader working, but saving the names in DB that’s probably something else !! (involving I guess some js).

$uploader->setFilesDispersion(true);
means do you want the file the magento way (folders with first letter), or just directly in you folder $path
 
Magento Community Magento Community
Magento Community
Magento Community
 
SwiftCol
Sr. Member
 
Total Posts:  85
Joined:  2008-05-22
 

You guys are making a hell of a lot more progress than I did. I eventually used Varien to create a simple file uploader, (which I ended up needing in addition to an image uploader.)

First of all, make sure you have enctype set to multipart/form-data, whether this is done through Varien or through your module’s template file.

Next you want to make sure that your file path doesn’t erased from the database if someone edits the record and doesn’t upload a new file. To do this, we’ll need to seperate the file path from the file upload. Check this out:

$fieldset->addField('my_file''hidden', array(
        
'name'        => 'my_file',
    ));
    
    
$object Mage::getModel('modulename/blockname')->load$this->getRequest()->getParam('id') );
    
$note false;
    if( 
$object->getMyFile() ){
        $note 
'<a href="'.Mage::getBaseUrl('media').$object->getMyFile().'" target="_blank">View current file</a>';
    
}
    
    $fieldset
->addField('my_file_uploader''file', array(
        
'label'        => Mage::helper('modulename')->__('My File'),
        
'note'      => $note,
        
'name'        => 'my_file_uploader',
        
'class'     => (($object->getMyFile()) '' 'required-entry'),
        
'required'  => (($object->getMyFile()) false true),
    ));

The next step is to upload the file if it is present when saving the entry. In the saveAction() on the block’s controller, I added this:

## Upload files, and set database values to file path    
            $files $this->uploadFiles$_FILES );
            
            if( 
$files && is_array($files) ){
                
for( $f=0$f<count($files); $f++ ){
                    
if( $files[$f] ){
                        $fieldname 
str_replace('_uploader','',$files[$f]['fieldname']);
                        if( 
array_key_exists($fieldname$data) ){
                            $data[$fieldname] 
$files[$f]['url'];
                        
}
                    }
                }
            }

And as for the function that it uses, I added these (below the saveAction function)

protected function uploadFiles$files ){
        
if( !empty($files) && is_array($files) ){
            $result 
= array();
            foreach( 
$files as $file=>$info ){
                $result[] 
$this->uploadFile( $file );
            
}
            
return $result;
        
}
    }
    
    
protected function uploadFile$file_name ){
        
if( !empty($_FILES[$file_name]['name']) ){
            $result 
= array();
            
$dynamicScmsURL 'ModuleName' DS 'files';
            
$baseScmsMediaURL Mage::getBaseUrl('media') . DS 'ModuleName' DS 'files';
            
$baseScmsMediaPath Mage::getBaseDir('media') . DS .  'ModuleName' DS 'files';
            
            
$uploader = new Varien_File_Uploader$file_name );
            
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png','pdf','xls','xlsx','doc','docx'));
            
$uploader->setAllowRenameFiles(true);
            
$uploader->setFilesDispersion(true);
            
$result $uploader->save$baseScmsMediaPath );
            
            
$file str_replace(DS'/'$result['file']);
            if( 
substr($baseScmsMediaURLstrlen($baseScmsMediaURL)-1)=='/' && substr($file01)=='/' )    $file substr($file1);
            
$ScmsMediaUrl $dynamicScmsURL.$file;
            
            
$result['fieldname'$file_name;
            
$result['url'$ScmsMediaUrl;
            
$result['file'$result['file'];
            return 
$result;
        
else {
            
return false;
        
}
    }

This isn’t the cleanest method, I’m sure that Magento has an easier way to do file uploads, but I didn’t have time to dig through thousands of files to find out how to do it. (Magento team, your documentation is horrible.) So this is my method. I hope it helps someone.

 
Magento Community Magento Community
Magento Community
Magento Community
 
Devpen
Jr. Member
 
Total Posts:  11
Joined:  2008-07-30
 

somesid, i followed your Guide, works great for uploading images.

However, if i edit an article, but do not want to change the image, it throws an error complaining that the files array is empty
(ie its trying to replace the image).

any way i can fix this ?

 
Magento Community Magento Community
Magento Community
Magento Community
 
somesid
Sr. Member
 
Total Posts:  83
Joined:  2008-06-20
 

Yeah just change in saveAction() two things :

Add a try catch, and add

if($_FILES['fileinputname']['name'!= '')
, this way if you didn’t upload a new file, the value will stay the same in the DB.
Another upgrade: in
$uploader->save()
add
$_FILES['fileinputname']['name']
as a second argument.

then

if($_FILES['fileinputname']['name'!= ''{

    
try {    
         $uploader 
= new Varien_File_Uploader('fileinputname');
         
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
         
$uploader->setAllowRenameFiles(false);
         
$uploader->setFilesDispersion(false);
     
         
$path Mage::getBaseDir('media') . DS ;
                
         
$uploader->save($path$_FILES['fileinputname']['name']);
    
catch (Exception $e{
          
    }

    $data[
'fileinputname'$_FILES['fileinputname']['name'];

}
 
Magento Community Magento Community
Magento Community
Magento Community
 
Devpen
Jr. Member
 
Total Posts:  11
Joined:  2008-07-30
 

thanks, but that doesn’t seem to work unfortunately :(

Warning: preg_match() expects parameter 2 to be string, array given in /www/SITE/http/shop/lib/Varien/Data/Form/Element/Image.php on line 55

#0 /www/SITE.co.uk/http/shop/lib/Varien/Data/Form/Element/Image.php(55): mageCoreErrorHandler(2, ‘preg_match() ex...’, ‘/www/SITE...’, 55, Array)

here is my code in saveAction()

public function saveAction() {
    
if ($data $this->getRequest()->getPost()) {
      
try {

        $uploader 
= new Varien_File_Uploader('image_name');
        
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
        
$uploader->setAllowRenameFiles(false);
        
$uploader->setFilesDispersion(false);

        
$path Mage::getBaseDir('media') . DS ;

        
$uploader->save($path$_FILES['image_name']['name']);

        

        
catch (Exception $e)
        
{
        }
        
        
if ($_FILES['image_name']['name'!= '')
          
$data['image_name'$_FILES['image_name']['name'];

      
$model Mage::getModel('news/news');   
      
$model->setData($data)
        ->
setId($this->getRequest()->getParam('id'));

      try 
{
        
if ($model->getCreatedTime == NULL || $model->getUpdateTime() == NULL{
          $model
->setCreatedTime(now())
            ->
setUpdateTime(now());
        
else 
          
$model->setUpdateTime(now());
        
}

        $model
->save();
        
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('news')->__('Item was successfully saved'));
        
Mage::getSingleton('adminhtml/session')->setFormData(false);

        if (
$this->getRequest()->getParam('back')) {
          $this
->_redirect('*/*/edit', array('id' => $model->getId()));
          return;
        
}
        $this
->_redirect('*/*/');
        return;
            
catch (Exception $e{
                Mage
::getSingleton('adminhtml/session')->addError($e->getMessage());
                
Mage::getSingleton('adminhtml/session')->setFormData($data);
                
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
                return;
            
}
        }
        Mage
::getSingleton('adminhtml/session')->addError(Mage::helper('news')->__('Unable to find item to save'));
        
$this->_redirect('*/*/');
  
}
 
Magento Community Magento Community
Magento Community
Magento Community
 
Devpen
Jr. Member
 
Total Posts:  11
Joined:  2008-07-30
 

i forgot to mention that error occurs when I try to edit the news item without adding a new picture.

it would seem the in the $data array, there is no image_name field, and the form does not know the name of the original file.

how can i fix this ?

 
Magento Community Magento Community
Magento Community
Magento Community
 
somesid
Sr. Member
 
Total Posts:  83
Joined:  2008-06-20
 

Ok not sure if it’s related, but I had the same error when I was trying to save some fields which were missing in the database I think. Do you have a field image_name in the table related to your module ?

 
Magento Community Magento Community
Magento Community
Magento Community
 
Devpen
Jr. Member
 
Total Posts:  11
Joined:  2008-07-30
 

ok i found a fix.

If you have a column called “image_name”

in your AdminHTML form, add image_name as a hidden field. This ensures that the value is passed each time.
then, call the upload field “newimage”

In your uploadAction, check is newimage is set.
if it is, set $data[’image_name’] to the result of the uploader

boom smile

 
Magento Community Magento Community
Magento Community
Magento Community
 
raven
Jr. Member
 
Total Posts:  10
Joined:  2008-07-08
Philippines
 

Hello Guys,

I am also researching about Media Uploads and wanted to try somesid’s Guide.

I’ve created a custom module using the Module Creator.

But then, after that, I can’t find the /controllers/Adminhtml/ folder under the /app/code/local/CompanyName/ModuleName/Block/Adminhtml/ModuleName/. Should I create this myself then make my own ModuleNameController.php?

smile

 
Magento Community Magento Community
Magento Community
Magento Community
 
somesid
Sr. Member
 
Total Posts:  83
Joined:  2008-06-20
 

It was a bad copy/paste in the tutorials, the right path are edited both on the post and on the wiki but
raven you can directly generate a module with a working example of upload if you download the last modulecreator (0.0.9.1):  http://www.magentocommerce.com/wiki/custom_module_with_custom_database_table

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top
Page 1 of 3