Top Question Answers about PrestaShop Product Customization Module

Posted On: Sep 14, 2018

Categories: Shopping Carts & Platforms

At the time when there is huge competition in market, only the successful are those who have adopted the latest trend and techniques of the business. The store owners that are most facilitating the customers while buying are most likely to be the successful. The latest trend that is followed by well versed shop owners is to allow the customer to customize the products attributes by their own e.g. if customer is buying a shirt, he can insert a logo on it, write something, paste a picture or any style of designing on the shirt. All will be done by the customers and when all customization is done, he can submit it to the admin on the same product page. In result, the same thing will be delivered to the customers. As customers gets full control on their product, so they like to go to such store.

When we come into implementation, PrestaShop itself is not so flexible. Here we can’t say that developers from PrestaShop don’t know this function. They know it very well but to make software really light weight, they are providing only the necessary function in its installation. Therefore, it is needed to design you own module for this purpose or to use a free or paid PrestaShop custom design module.

Here in this guide, we are discussing some basis issues related to PrestaShop product customization. Hopefully, this question answer post will help you a lot to solve store’s issues. So let’s start here;

Question No.1: Hi, I am facing an issue with PrestaShop customization field. When clients upload an image file, saves and then refreshes the page. It shows a corrupted thumbnail. Also, when I click on the image or opens it in a new tab, it just goes to 404 error page. What is the issue?

Answer: You have to edit the file /upload/.htaccess and remove line php_flag engine off. You will find these lines at the end of the file. Save the file and then it will work well.

Question No. 2: Hi, I want to upload PDF file on product customization page. Currently, I am able to upload images files only. Which tweak I needs for this?

Answer: To enable this function on your store, you have to override the product controller>picture upload method in override>controllers>front. Download the following code, put it into ProductController.php and upload it to override>controllers>front.

class ProductController extends ProductControllerCore

{

                const CUSTOMIZATION_FILE_DIR = 'customizations';

 

                protected function pictureUpload()

                {

                                if (!($field_ids = $this->product->getCustomizationFieldIds()))

                                                return false;

                                $authorized_file_fields = array();

                                foreach ($field_ids AS $field_id)

                                {

                                                if ($field_id['type'] == Product::CUSTOMIZE_FILE)

                                                                $authorized_file_fields[(int)$field_id['id_customization_field']] = 'file' . (int)$field_id['id_customization_field'];

                                }

 

                                $indexes = array_flip($authorized_file_fields);

                                foreach ($_FILES AS $field_name => $file)

                                {

                                                if (in_array($field_name, $authorized_file_fields) AND isset($file['tmp_name']) AND !empty($file['tmp_name']))

                                                {

                                                                // If there is an upload error, let the parent handle it

                                                                if ($file['error'] != UPLOAD_ERR_OK)

                                                                                continue;

 

                                                                // If the file is not allowed, let the parent handle it

                                                                if (!$this->isUploadTypeAllowed($file))

                                                                                continue;

 

                                                                // Unset the PDF to prevent the parent to handle this file

                                                                unset($_FILES[$field_name]);

 

                                                                // Create dir

                                                                mkdir(_PS_UPLOAD_DIR_ . ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id, 0777, true);

 

                                                                // Mark the file as a custom upload

                                                                $file_name = ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id.'/P'. md5(uniqid(rand(), true));

                                                                $tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');

                                                                if (!move_uploaded_file($file['tmp_name'], $tmp_name))

                                                                {

                                                                                $this->errors[] = Tools::displayError('An error occurred during the PDF upload.');

                                                                                return false;

                                                                }

                                                                // Copy file to the upload dir

                                                                if (!copy($tmp_name, _PS_UPLOAD_DIR_.$file_name))

                                                                {

                                                                                $this->errors[] = Tools::displayError('An error occurred during the PDF upload.');

                                                                                return false;

                                                                }

                                                                // Chmod the new file

                                                                if (!chmod(_PS_UPLOAD_DIR_.$file_name, 0777))

                                                                {

                                                                                $this->errors[] = Tools::displayError('An error occurred during the PDF upload.');

                                                                                return false;

                                                                }

 

                                                                // Create a fake thumb to avoid error on delete, this hack avoids lots of core method override

                                                                file_put_contents(_PS_UPLOAD_DIR_ . $file_name . '_small', '');

                                                                chmod(_PS_UPLOAD_DIR_ . $file_name . '_small', 0777);

 

                                                                // Register the file

                                                                $this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_FILE, $file_name);

 

                                                                // Remove tmp file

                                                                unlink($tmp_name);

                                                }

                                }

                                return parent::pictureUpload();

                }

 

                protected function isUploadTypeAllowed($file)

                {

                                /* Detect mime content type */

                                $mime_type = false;

                                $types = array('application/pdf',); // Extra mime types can be added here

 

                                if (function_exists('finfo_open'))

                                {

                                                $finfo = finfo_open(FILEINFO_MIME);

                                                $mime_type = finfo_file($finfo, $file['tmp_name']);

                                                finfo_close($finfo);

                                }

                                elseif (function_exists('mime_content_type'))

                                {

                                                $mime_type = mime_content_type($file['tmp_name']);

                                }

                                elseif (function_exists('exec'))

                                {

                                                $mime_type = trim(exec('file -b --mime-type '.escapeshellarg($file['tmp_name'])));

                                }

                                if (empty($mime_type) || $mime_type == 'regular file')

                                {

                                                $mime_type = $file['type'];

                                }

 

                                if (($pos = strpos($mime_type, ';')) !== false)

                                                $mime_type = substr($mime_type, 0, $pos);

                                // is it allowed?

                                return $mime_type && in_array($mime_type, $types);

                }

    }

}

Clear the cache.

  1.  
  2.  
  3. if isset($pictures.$key)}
  4.       <divclass="customizationUploadBrowse">
  5.             {if substr(basename($pictures.$key), 0, 1) == 'P'}
  6.                   <ahref="{$pic_dir}{$pictures.$key}"target="_blank">{l s='View the file'}
  7.             {else}
  8.                   <imgsrc="{$pic_dir}{$pictures.$key}_small"alt=""/>
  9.             {/if}
  10.             <ahref="{$link->getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html':'UTF-8'}" title="{l s='Delete'}" >
  11.                   <imgsrc="{$img_dir}icon/delete.gif"alt="{l s='Delete'}"class="customization_delete_icon"width="11"height="13"/>
  12.            
  13.      
  14. {/if}

Further you have to fix the file preview at frontend of store. In product.tpl use the following code:{if isset($pictures.$key)}

     

              {if substr(basename($pictures.$key),0,1)=='P'}

                      {l s='View the file'}

              {else}

                     

              {/if}

             

                      {l s='Delete'}

             

     

{/if}

Open "order-payment.tpl", "order-detail.tpl", "order-return.tpl" and search for "customizationUploaded", comment the div and paste this code above it:

{foreach $custom_data as $picture}
{if substr(basename($picture.value), 0, 1) == 'P'}
<a href="{$pic_dir}{$picture.value}" target="_blank">Open attached filea>
{else}
<img src="{$pic_dir}{$picture.value}_small" alt="" />
{/if}
<a href="{$link->getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html':'UTF-8'}" title="{l s='Delete'}" >
<img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="customization_delete_icon" width="11" height="13" />
a>
{/foreach}

- Now last step: open "/ps-admin/themes/default/template/controllers/orders/_customized_data.tpl", search for "Product::CUSTOMIZE_FILE", comment the first foreach and paste this code above:

              {foreach from=$datas item=data}
                      <div class="form-group">
                             <span class="col-lg-4 control-label"><strong>{if $data['name']}{$data['name']}{else}{l s='Picture #'}{$data@iteration}{/if}strong>span>
                             <div class="col-lg-8">
                                     {if substr(basename($data.value), 0, 1) == 'P'}
                                             <a href="{$pic_dir}{$data.value}" target="_blank">Open attached filea>
                                     {else}
                                             <a href="displayImage.php?img={$data['value']}&name={$order->id|intval}-file{$data@iteration}" class="_blank">
                                                    <img class="img-thumbnail" src="{$smarty.const._THEME_PROD_PIC_DIR_}{$data['value']}_small" alt=""/>
                                             a>
                                     {/if}
                             div>
                      div>
              {/foreach}

Question No. 3: I have created 2 new files on product customization pages but I am not happy after creating it. As user have to go to the bottom and click on the additional tabs. Can I move these fields to the same place where exists product combination drop down menu? I tried to do it by moving the code from footer to other places like product.tpl but it doesn’t help.

Answer: You can do it by the following method.

File:

/themes/your-template/product.tpl



Find and delete the following code:

 

{if isset($product) && $product->customizable}

<divid="idTab10"class="bullet customization_block">

<formmethod="post"action="{$customizationFormTarget}"enctype="multipart/form-data"id="customizationForm"class="clearfix">

<pclass="infoCustomizable">

{l s='After saving your customized product, remember to add it to your cart.'}

{if $product->uploadable_files}
{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}

{if $product->uploadable_files|intval}

<divclass="customizableProductsFile">

{l s='Pictures'}

<ulid="uploadable_files"class="clearfix">

{counter start=0 assign='customizationField'}

{foreach from=$customizationFields item='field' name='customizationFields'}

{if $field.type == 0}

<liclass="customizationUploadLine{if $field.required} required{/if}">{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}

{if isset($pictures.$key)}

<divclass="customizationUploadBrowse">

<imgsrc="{$pic_dir}{$pictures.$key}_small"alt=""/>

<ahref="{$link->getProductDeletePictureLink($product, $field.id_customization_field)}" title="{l s='Delete'}" >

<imgsrc="{$img_dir}icon/delete.gif"alt="{l s='Delete'}"class="customization_delete_icon"width="11"height="13"/>

{/if}

<divclass="customizationUploadBrowse">

<labelclass="customizationUploadBrowseDescription">{if !empty($field.name)}{$field.name}{else}{l s='Please select an image file from your computer'}{/if}{if $field.required}*{/if}

<inputtype="file"name="file{$field.id_customization_field}"id="img{$customizationField}"class="customization_block_input {if isset($pictures.$key)}filled{/if}"/>

{counter}

{/if}

{/foreach}

{/if}

{if $product->text_fields|intval}

<divclass="customizableProductsText">

{l s='Text'}

<ulid="text_fields">

{counter start=0 assign='customizationField'}

{foreach from=$customizationFields item='field' name='customizationFields'}

{if $field.type == 1}

<liclass="customizationUploadLine{if $field.required} required{/if}">

<labelfor="textField{$customizationField}">{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}

<textareatype="text"name="textField{$field.id_customization_field}"id="textField{$customizationField}"rows="1"cols="40"class="customization_block_input">{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}

{counter}

{/if}

{/foreach}

{/if}

<pid="customizedDatas">

<inputtype="hidden"name="quantityBackup"id="quantityBackup"value=""/>

<inputtype="hidden"name="submitCustomizedDatas"value="1"/>

<inputtype="button"class="button"value="{l s='Save'}"onclick="javascript:saveCustomization()"/>

<spanid="ajax-loader"style="display:none"><imgsrc="{$img_ps_dir}loader.gif"alt="loader"/>

<pclass="clear required">* {l s='required fields'}

{/if}


-------

And before this line:

{if (isset($product) && $product->description) || (isset($features) && $features) || (isset($accessories) && $accessories) || (isset($HOOK_PRODUCT_TAB) && $HOOK_PRODUCT_TAB) || (isset($attachments) && $attachments) || isset($product) && $product->customizable}


Paste this code:

{if isset($product) && $product->customizable}

  <divclass="bullet customization_block">

   <formmethod="post"action="{$customizationFormTarget}"enctype="multipart/form-data"id="customizationForm"class="clearfix">

      <pclass="infoCustomizable">

       {l s='After saving your customized product, remember to add it to your cart.'}

       {if $product->uploadable_files}
{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}

     

      {if $product->uploadable_files|intval}

      <divclass="customizableProductsFile">

       

{l s='Pictures'}

       <ulid="uploadable_files"class="clearfix">

        {counter start=0 assign='customizationField'}

        {foreach from=$customizationFields item='field' name='customizationFields'}

         {if $field.type == 0}

              <liclass="customizationUploadLine{if $field.required} required{/if}">{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}

               {if isset($pictures.$key)}

               <divclass="customizationUploadBrowse">

                <imgsrc="{$pic_dir}{$pictures.$key}_small"alt=""/>

                <ahref="{$link->getProductDeletePictureLink($product, $field.id_customization_field)}" title="{l s='Delete'}" >

                 <imgsrc="{$img_dir}icon/delete.gif"alt="{l s='Delete'}"class="customization_delete_icon"width="11"height="13"/>

               

               

               {/if}

               <divclass="customizationUploadBrowse">

                <labelclass="customizationUploadBrowseDescription">{if !empty($field.name)}{$field.name}{else}{l s='Please select an image file from your computer'}{/if}{if $field.required}*{/if}

                <inputtype="file"name="file{$field.id_customization_field}"id="img{$customizationField}"class="customization_block_input {if isset($pictures.$key)}filled{/if}"/>

               

             

              {counter}

         {/if}

        {/foreach}

       

     

      {/if}

      {if $product->text_fields|intval}

      <divclass="customizableProductsText">

       

{l s='Text'}

       <ulid="text_fields">

       {counter start=0 assign='customizationField'}

       {foreach from=$customizationFields item='field' name='customizationFields'}

        {if $field.type == 1}

        <liclass="customizationUploadLine{if $field.required} required{/if}">

         <labelfor="textField{$customizationField}">{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}

         <textareatype="text"name="textField{$field.id_customization_field}"id="textField{$customizationField}"rows="1"cols="40"class="customization_block_input">{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}

       

        {counter}

        {/if}

       {/foreach}

       

     

      {/if}

      <pid="customizedDatas">

       <inputtype="hidden"name="quantityBackup"id="quantityBackup"value=""/>

       <inputtype="hidden"name="submitCustomizedDatas"value="1"/>

       <inputtype="button"class="button"value="{l s='Save'}"onclick="javascript:saveCustomization()"/>

       <spanid="ajax-loader"style="display:none"><imgsrc="{$img_ps_dir}loader.gif"alt="loader"/>

     

  

   <pclass="clear required">* {l s='required fields'}

 

{/if}


----

After search:

  {if isset($product)&& $product->customizable}

{/if}


change by

{*   {if isset($product)&& $product->customizable}

{/if}

*}

Note: To modify product.tpl, you have to do force compilation.

Question No. 4: I want to show product customization tab next to the more information tab. At the time, it is showing below the default tabs.

Answer: Hello!

Edit product.tpl

Change

{if $product->description || $features || $accessories || $HOOK_PRODUCT_TAB || $attachments}


to

{if $product->description || $features || $accessories || $HOOK_PRODUCT_TAB || $attachments || $product->customizable}



In

    , above {$HOOK_PRODUCT_TAB} insert line:

    {if $product->customizable}

    {/if}


    In

    , above {$HOOK_PRODUCT_TAB_CONTENT} insert :

    {if $product->customizable}

     

     

      

          Informations

          {l s='After saving your customized product, remember to add it to your cart.'}

          {if $product->uploadable_files}
    {l s='Allowed file formats are: GIF, JPG, PNG'}{/if}

      

       {if $product->uploadable_files|intval}

      

    {l s='Pictures'}

      

            {counter start=0 assign='customizationField'}

            {foreachfrom=$customizationFields item='field' name='customizationFields'}

             {if $field.type ==0}

             

      • {assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}

               {if isset($pictures.$key)}

                     

                     

                      {l s='Delete'}

                     

                    {/if}

              

      {if $field.required}*{/if}

              

      {if!empty($field.name)}{$field.name}{else}{l s='Please select an image file from your hard drive'}{/if}

             

              {counter}

             {/if}

            {/foreach}

        

         {/if}

        

         {if $product->text_fields|intval}

        

      {l s='Texts'}

        

              {counter start=0 assign='customizationField'}

              {foreachfrom=$customizationFields item='field' name='customizationFields'}

               {if $field.type ==1}

               

        • {assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}

                 {if!empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}