Solving Magento

Solutions for Magento E-Commerce Platform

by Oleg Ishenko

A Magento File Custom Option Type Primer

In the following example we are going to take a simple product and add a file option to it to see how the file is being handled by the system.

Our test product is “The Get Up Kids: Band Camp Pullover Hoodie (Shirts T)” from the Magento sample data (download). Its SKU is 4fasd5f5. We would like to allow customers to upload an image file to be printed on the shirt. Open this product in the back-end and switch to the Custom Options tab. The list of options is empty. Click the “Add New Option” button in the upper right corner. In the form that appears select File in the “Input Type” drop-down list. The form must look like this:

Figure 1. File custom options form

Figure 1. File custom options form

Enter the following values into the form fields:

  • Title: Print
  • Is Required: yes
  • Price: leave blank so that uploading a print file doesn’t change the product price
  • SKU: leave blank, our example doesn’t require this option to be a unique SKU
  • Allowed File extensions: png, jpg, jpeg, bmp, tiff, tif, gif – a string of the most common image file extensions, comma separated.
  • Maximum Image Size: since we are expecting images, enter 1024 by 1024 px. For non-image file options these two fields should be left blank.

Save the product and open it in the front-end. You will see that the product details page now has an additional form to upload the required print image option.

Figure 2. File custom option in the product detail page

Figure 2. File custom option on the product detail page

Since we have indicated the Print option as required, you can’t add this product to the shopping cart unless a file is uploaded. The validation options we set in the back-end mandate that this file must be an image file with one of the allowed extensions and dimensions not exceeding the 1024 by 1024 pixel limit.

Let’s try to find out how this limitations are enforced by uploading a text file instead of an image. Select any file with a “txt” extension and click “Add to Cart”.

Before a product can be added to the cart its options must be processed. This functionality is provided by Product Type models. The base product type functionality is defined in class Mage_Catalog_Model_Product_Type_Abstract. Some products type, such as configurable or bundle extend it for their specific purposes, but in a case of a simple product this class covers all the required functions. Thus, product options are taken care of in method Mage_Catalog_Model_Product_Type_Abstract::_prepareOptions. It goes through all the options defined for the product and validates the user input for them. Since we are testing an option of type “File” the validation is performed in method Mage_Catalog_Model_Product_Option_Type_File::_validateUploadedFile. In our example the uploaded file is checked against three constraints:

  • File extension must be in one of the image file extensions we’ve provided (case insensitive).
  • Image dimensions must not exceed 1024 by 1024 pixel
  • File size must not exceed the server setting for upload_max_filesize and post_max_size (the lowest value of the two).

Naturally, the validation fails as the “txt” doesn’t match the allowed image extensions.

Now, go ahead and upload any image file with a proper extension.

The uploaded custom option files are stored in the directory custom_options under the shop’s media folder. If such directory doesn’t exist yet, it is created automatically. The custom_options has two sub-directories order and quote to where the uploaded file will be placed in.

Once uploaded, the file remains in the media/custom_options/quote folder. If you look in there, you’ll notice that the system has created some new sub-directories. This was the work of dispersion (Varien_File_Uploader::getDispretionPath): uploaded files are arranged into a directory structure, which consist of two nested folders each with a 1 character name. If your file is called “test.gif”, it will be placed under t/e/ path. The folder names correspond to the first and the second characters of the file name.

The uploaded file doesn’t retain its original name for security reasons, of course. For the same reasons the directories the file is uploaded into are made inaccessible from the outside, i.e. you cannot link directly to the file. The file, however, can be downloaded. You can see a link to it in the shopping cart overview. The link is provided by the Mage_Sales module’s download controller. Remarkably, the link can be opened without checking user credentials, which poses a security risk. Beware if some customer decides to use your shop as a file sharing service!

After the order is placed the file is copied to the media/custom_options/order folder, where it again is placed under the dispersion sub-folders.

That’s it, the uploaded file is a part of the order now as an item option. You can access the item options by calling Mage_Sales_Model_Order_Item::getProductOptions(). The result is an array, whose element “options” contains an array of all item options. The link to the file can be found there under the key “value”:

[options] => array(1) (
        [0] => array(7) (
                [label] => (string) Print
                [value] => (string) <a href="https://comm170.solvingmagento.dev/sales/download/downloadCustomOption/id/42/key/74d35b7205b48e5f07e1/" target="_blank">1.gif</a> 718 x 799 px.
                [print_value] => (string) 1.gif 718 x 799 px.
                [option_id] => (string) 3
                [option_type] => (string) file
                [option_value] => (string)

13 thoughts on “A Magento File Custom Option Type Primer

  1. Thanks for this great post that i accidently found while going through your articles. It is exactly the Feature we needed I didn’t know it existed in Magento.
    Do you know if it is possible to allow file Uploads for a whole bunch of articles, e.g. a category or articles with a specified attribute set?
    The problem is that noone wants to put that upload option onto every single article created in magento.

  2. I am trying to make a ajax upload on the input file field but i have no idea how to do it.
    Here’s the plan:
    – User choose file to upload, ajax show upload progress and then preview the file
    – File saves to session (temporary)
    – User set qty(number of items to order) and then click “Add to Cart”.
    – After clicked “Add to Cart” that’s when the image moves to real folder.

    How can i write a code like that?

  3. Been trying to get this to work but it says no file is selected – anyone else had trouble with this file type custom option not working? Tried creating the folder and setting permissions but still no luck.

    • The message “No file is selected” belongs to the input type “file” and is rendered by the browser, not Magento. It can be different depending on browser, OS, and language settings. Did you try it in a different browser?

  4. Hi there,

    I found this post and think that it is very close related to my problem on a custom theme/template.

    I have added “file upload” option to one of my products, which is working fine with the default template of magento. Files are uploaded and a link to the file is shown in the “Cart”.

    On my purchased theme files are not uploaded and of course now link to the file is shown in the “Cart”.

    Maybe someone can tell me how I can achieve that on my custom template or give me a hint where (in which file) the file upload is controlled.

    Looking forward to any reply which could help me on that issue.

    Regards,
    Dome

    • Hi Dome,

      The code that outputs cart item options (such as your file download URL) is in the default cart item template, /app/design/frontend/base/default/template/checkout/cart/item/default.phtml line 43-58. If your theme uses a different cart item template, try to customize it by including the item option rendering loop from the default template.

      To display the upload form for the file option in the product details page, the product view template must include an options block. The default product layout file, app/design/frontend/base/default/layout/catalog.xml defines such block in line 222-230. Note that the options block is not rendered directly in the view template. The view template, /app/design/frontend/base/default/template/catalog/product/view.phtml has a container child block “container2”. The options block is inserted into container2 – and is rendered as its child.

      You must check your new theme if it has a way to output the options block – not necessarily in the same manner as in the default theme – as long as you manage to include the “product_options_wrapper” and “product_options_wrapper_bottom” blocks into your template it should work.

      Hope this helps.

      • Hi Oleg,

        Thank you for your reply on my post this brought me a litte further.

        If I use the default theme and upload a file to the product I want to buy from the shop, the uploaded file is shown in the cart. If I now switch back to the purchased theme, I can see the uploaded file. So I assume the file:

        mytemplate/template/checkout/cart/item/default.phtml

        has the required options.

        The purchased theme/template uses Ajax to add products to the cart so the issue might be related to that.
        Do you have any idea where I could check for this problem?

        Looking forward to your reply and thank you so much for your help!

        Regards,
        Dome

  5. hello, how do you override the `getDispretionPath($fileName)`. I have a need to append a folder (the sku as a folder) to this. To test i have tryed to alter `Mage_Core_Model_File_Uploader` which extends `Varien_File_Uploader` with


    static public function getDispretionPath($fileName)
    {
    return parent::getDispretionPath($fileName).'/realdealtest/';
    }

    But it doesn’t work. That was just a test, but that need is to able to end up with a folder structure for product (with sku foo123) /f/o/foo123/ when a file for that product is uploaded. So if i uploaded bar.jpg for product sku foo123 that it’d be stored as /f/o/foo123/bar.jpg

  6. I have same jeremy’s problem…

    the context:

    1 – I have a input type file at my product page. My customer inputs a file and I need to view this file at the order later…

    2 – the inputs works fine at product view page and at the cart view page. I see the file and if I click at the file it’s open correctly..

    the problem:

    When I get a order at magento panel, I see the “Items Ordered”. here is the file attached name and the file view link.. but this link not works… return to me a 404 error…
    At the custom_options folder the images are correct…

    magento 1.8.0.1 and 1.9.0.1

  7. Any idea where the file name is being changed?

    I have looked inside:

    \lib\Varien\File\Uploader.php

    but even after disabling all the calls to the filename the name was still being changed.

  8. Hello Sir,

    I want to customize input type file.I want to give user to choose file from facebook.I did facebook part but i want add dynamic value for input type file in add to cart.

Leave a Reply to Dome Cancel reply

Your email address will not be published. Required fields are marked *

Theme: Esquire by Matthew Buchanan.