17 replies [Last post]
dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
Was this information Helpful?

How can I extend product features ?

I want to use ubercart for a online voucher ordering system.

I need to give the customer the following opportunities :

to upload a logo, or a picture that will be printed on the voucher,
Free text lines that can be printed on the voucher,
a dropdown with the language in which the voucher has to be printed,

Could it also be possible that the user can give the amount of the voucher himself ?

How can this be achieved ? Is this a programming job ? How and where can this easily be done in ubercart ?

Thank you for your advice !

ssherriff's picture
Offline
Early adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/08/2007
Juice: 215
Re: Add upload logo functionality during checkout by client

I'm actually wanting something like this as well. It is definitely a programming job, and I was planning on creating a special module for the website I need it for, and possibly using the hook_nodeapi function. The problem I'm having is I have virtually no idea how to deal with file uploads in Drupal. I'm going to give it a try tonight, so if I have any luck, I'll post back here.

Cheers,
Steph

quaoar's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.Not Kulvik
Joined: 08/08/2007
Juice: 179
Re: Re: Add upload logo functionality during checkout by client

Here is a short example (module) for uploading a file. This was and is still used on one of our Drupal 4.7 installations. Haven't tested it with latest Drupal release. Shouldn't be to hard to make it work if it's not working already Smiling
What it does:
-registers a menu item
-displays a small form where you can choose a file for upload
-stores the file at default temporary storage (usually /tmp/)
-deletes the file

/**
* Implementation of hook_perm().
*/
function uploadfile_perm() {
  return array('upload file');
}

/**
* Implementation of hook_menu().
*/
function uploadfile_menu($may_cache) {
  $items = array();

  if (!$may_cache) {
    $items[] = array(
      'title' => 'upload file',
      'path' => 'uploadfile/upload',
      'callback' => '_uploadfile_upload',
      'access' => user_access('upload file'),
      'type' => MENU_NORMAL_ITEM
    );
  }
  return $items;
}

function _uploadfile_upload() {
    $output = drupal_get_form('uploadfile', _uploadfile_form());
    return $output;
}

function _uploadfile_form() {
    $form = array();
    // Attachments fieldset
    $form['upload'] = array(
      '#type' => 'file',
      '#title' => t('File for upload'),
      '#size' => 30,
      '#description' => t('Choose file for upload.'),
    );
    $form['#attributes']['enctype'] = 'multipart/form-data';
    $form['submit'] = array('#type' => 'submit', '#value' => t('Upload'));
   
    return $form;
}

function uploadfile_validate($form_id, $form_values) {
  if(!file_check_upload('upload')) {
    form_set_error('upload', t('Choose file for upload.'));
  }
}

function uploadfile_submit($form_id, $form_values) {
    $source = file_check_upload('csvfile');    
    // Security measure to prevent exploit of file.php.png
    #$source->filename = upload_munge_filename($source->filename);
   

    if ($file = file_save_upload($source)) {
      $output = array();
      drupal_set_message(t('File stored.'));
     
      // do stuff here
     
      // remove file if needed:
      file_delete($file->filepath);
    } else {
      drupal_set_message(t('Error during file process.'));
    }
}

Erlend Strømsvik
Ny Media AS
erlend@nymedia.no

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
activate feature on a product base

Hi Steph,

Nice to hear that I'm not alone needing this feature Eye-wink

It's not the meaning to offer the upload functionality on all products.
Ideally this functionality is activated when creating the product.

I don't know yet where to start yet. I'll take a closer look at the hook_nodeapi.

I'm willing to work together on this one ...

Ciao,
Dauli

ssherriff's picture
Offline
Early adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/08/2007
Juice: 215
Re: activate feature on a product base

Well, it is turning out to be more difficult then I thought. I've figured out how to add an upload field to the product form, and I know how to upload it, the problem is it has to be uploaded to the cart, and then it has to be added to the order when that is created. My brain is a bit fried after trying to figure out the whole file upload thing, trying to figure out how to hook into when the order is created and move the image file so it is associated with the order instead of just the cart anymore is just making my entire brain shutdown. Well, last night it did at least, maybe I will figure it out tonight.....riiiiiight.

Anyway, just as a start, what I've done is create a custom module for my site, and added the hook for altering a form:

function uc_cards4kids_form_alter($form_id, &$form) {
  if ('uc_product_add_to_cart_form_' . $form['nid']['#value'] == $form_id) {
     $node = node_load($form['nid']['#value']);
     if($node->type == 'personalised_cards'){
$form['logo'] = array('#type' => 'file',
'#title' => t('Upload Logo'),
'#size' => 40,
'#weight' => 0,
);
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['#submit'] = array('_uc_cards4kids_add_to_cart_submit_handler' => array()) + (array)$form['#submit'];
     }
  }
}

As you can see I also created a class which I use for the products that need to have the upload logo field. I've also added a custom submit handler to handle the upload of the file.

function _uc_cards4kids_add_to_cart_submit_handler($form_id, $form_values) {
  if ('uc_product_add_to_cart_form_' . $form_values['nid'] == $form_id) {
$dir = variable_get('file_directory_path', NULL);
$is_writable = file_check_directory($dir, 1);
        if($is_writable) {
            $dir .= '/logos/cart/' . uc_cart_get_id();
    mkdir($dir);
    $source = file_check_upload('logo');
    $source->filename = upload_munge_filename($source->filename);

    if ($file = file_save_upload($source,$dir )) {
               if (image_get_info($file->filepath)) {
                  drupal_set_message(t('New image saved.'));
               } else {
                  file_delete($file->filepath);
                  drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
               }
           }
}
   }
}

Ok, the truth is I haven't tested the submit handler, but I think that's the basic idea. Something I'm wondering about though is where does add_to_cart_data() come into it? Should I be uploading my image when that is called instead? Or is that when I would create the link to allow the store administrator to download the image?

So the next step I imagine is that when the order is created, I then move the image to something like /logos/order/$order_id and remove the image from the cart directory.

Warning, the code above has not been thoroughly tested. It is mainly to get an idea if I'm heading in the right direction.

Cheers,
Steph

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
Add uploaded logo to order

Hi Steph,

I've been on a short holiday the past few days. This weekend I'll take a look at what you already have done.

Could you send me a private message with your emailaddress ? Maybe we can change ideas (and files) more easily by email ?

cheers.
dauli

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
Validate and submit in hook_alter

Hi,

I rewrote the code a little bit to make the upload work for me.

I'm not shure why you wrote the special submit handler since it is already expected by hook_alter.

Also, why would you create separate directories to store the files ?

What I want to do know is store the path in the database. I think that what we need to do is append the file and filepath to the order object somehow.

Do someone has already have some ideas how to achieve this ?

<?php
/*
inside your implementation of hook_form_alter you need to make a validation and a submit function.
http://groups.drupal.org/node/4308#comment-15623
*/
function uc_upload_logo_form_alter($form_id, &$form) {
if (
'uc_product_add_to_cart_form_' . $form['nid']['#value'] == $form_id) {
$node = node_load($form['nid']['#value']);
if(
$node->type == 'class_a'){
//$form['#attributes'] = array('enctype' => 'multipart/form-data');
$form['logo'] = array('#type' => 'file',
'#title' => t('Upload Logo'),
'#size' => 40,
'#weight' => 0,
);
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['#submit'] += array('uc_upload_logo_form_submit' => array($form_id, &$form_values));
}
}
}

function

uc_upload_logo_form_submit($form_id, $form_values) {

$dir = variable_get('file_directory_path', NULL);    
   
$is_writable = file_check_directory($dir, 1);
    if(
$is_writable) { 
     
$dir .= '/logos/cart/' . uc_cart_get_id();
     
$source = file_check_upload('logo');     
     
// Security measure to prevent exploit of file.php.png
     
$source->filename = upload_munge_filename($source->filename);
      
      if (
$file = file_save_upload($source,$dir )) {
        if (
image_get_info($file->filepath)) {
         
drupal_set_message(t('New image saved.'));
        } else {
         
file_delete($file->filepath);
         
drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
        }
      }
    }
}
?>
blucches@drupal.org's picture
Offline
Bug FinderGetting busy with the Ubercode.
Joined: 08/08/2007
Juice: 30
Re: Validate and submit in hook_alter

You can append data to the order object using hook_order (http://www.ubercart.org/docs/api/hook_order). However, you're likely going to want to associate the information with the product using hook_cart_item. (http://www.ubercart.org/docs/api/hook_cart_item). I would say possibly adding the filepath (or a unique id from a files table that contains more information about the file) to the attributes array for that particular cart item. It should be preserved for later recall during checkout automatically.

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
hook_cart_item()

Thank you for pointing me in the right direction.

I'm a PHP newbie and still a bit confused how the data attributes work.

I added two functions in addition to my alter and submit functions mentioned above. Am I missing something ?
When I go check the uc_cart_products table the attributes property shows up, but the value is empty.

<?php
/**
* Stores the customer's choices in the cart.
*/
function uc_upload_logo_add_to_cart_data($form_values){

  if (!isset(

$form_values['logo'])){
    return array(
'attributes' => array(), 'logoimage' => null);
  }

  return array(

'attributes' => $form_values['logo']);
}

/**
* Implementation of hook_cart_item().
*/
function uc_upload_logo_cart_item($op, &$item) {
  switch (
$op) {
    case
'load':
   
$item->data['attributes'];
      break;
  }
}
?>
ssherriff's picture
Offline
Early adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/08/2007
Juice: 215
Re: Add upload logo functionality during checkout by client

Ok, another question I have is should I be using the submit function to actually upload the image and save it, or can all of that be done in the hook_order function? (maybe hook_order isn't even necessary if the paragraph below is done ie attach it to cart item)

I definitely think you are right about having to attach it to the cart item, probably to have a link to be able to download/view the image uploaded.

I think maybe I've said this above, but basically I believe the steps (for me anyway) are as follows:

1. upload logo
2. save logo on server
3. attach the logo to the cart item so it shows up in attributes (not sure if this automatically associates this with the order, or if I have to do that separately with hook order).
4. If cart never becomes an order, delete logo images (so if cart emptied, item deleted, etc)
5. Carry logo with cart when becomes an order (I think this is just done by adding it as an attribute)

I think that's about it. Really doesn't seem that difficult, but just laying out how to do it, learning Drupal and Ubercart hooks, etc, is taking the time it seems.

Hopefully I can work on this again soon...have been over worked and brain dead, so had to take a break from it.

Cheers,
Steph

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
pass form_value logo created in hook_alter_form

I'm stuck in step 3 ...

I added

<?php
drupal_set_message
('<pre>'.print_r($form_values,true).'</pre>');
?>

in the add_to_cart function.

It seems that the fields of the original form return values, but the logo value is empty. I succeeded in uploading the file to the server, but the value is lost.

Is there something particular I need to do to pass the logo-filed added in hook_form_alter to the add_to_cart function ?

Can someone help me out please ?

dauli's picture
Offline
Joined: 08/10/2007
Juice: 35
the source...
<?php
/*
inside your implementation of hook_form_alter you need to make a validation and a submit function.
http://groups.drupal.org/node/4308#comment-15623
*/
function uc_upload_logo_form_alter($form_id, &$form) {
if (
'uc_product_add_to_cart_form_' . $form['nid']['#value'] == $form_id) {
$node = node_load($form['nid']['#value']);
if(
$node->type == 'class_a'){
$form['logo'] = array('#type' => 'file',
'#title' => t('Upload Logo'),
'#size' => 40,
'#weight' => 0,
);
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['#submit'] += array('uc_upload_logo_form_submit' => array($form_id, &$form_values));
}
}
}

function

uc_upload_logo_form_submit($form_id, $form_values) {
$dir = variable_get('file_directory_path', NULL);    
   
$is_writable = file_check_directory($dir, 1);
    if(
$is_writable) { 
     
$dir .= '/logos/cart/' . uc_cart_get_id();
     
$source = file_check_upload('logo');     
     
// Security measure to prevent exploit of file.php.png
     
$source->filename = upload_munge_filename($source->filename);
      
      if (
$file = file_save_upload($source,$dir )) {
        if (
image_get_info($file->filepath)) {
         
drupal_set_message(t('New image saved. '.$file->filepath.''));
        } else {
         
file_delete($file->filepath);
         
drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
        }
      }
    }
}

/**
* Stores the customer's choices in the cart.
*/
function uc_upload_logo_add_to_cart_data($form_values){
$logo=$form_values['logo'];
$logopath=$file->filepath;

  if (!isset(

$form_values['logo'])){
    return array(
'attributes' => array(), 'logoimage' => null);

  }

//  return array('attributes' => $form_values['logo']);
$model=$form_values[form_id];
drupal_set_message('Attributes to add to order Array(aid => oid):<pre>'. print_r($form_values, true) .'model:'. $model . '</pre>');
return array(
'attributes' => $form_values['attributes'], 'model' => $model);
}

/**
* Implementation of hook_cart_item().
*/
function uc_upload_logo_cart_item($op, &$item) {
  switch (
$op) {
    case
'load':
   
$item->data['attributes'];
      break;
  }
}
?>
JC (not verified)
JC's picture
any updates to this?

Hi,
I am also looking for "updload file on checkout" functionality in ubercart. This is the only missing feature that is stopping me from using ubercart.
Any updates to your attempts at adding this?

JC

zsiswick's picture
Offline
Joined: 05/05/2008
Juice: 55
Re: Add upload logo functionality during checkout by client

I desperately need this kind of functionality on a similar project I am currently working on. Has anyone else had any success implementing a custom module that will allow a customer to upload a custom logo before checkout? I'm a PHP noob but would be wiling to work in collaboration with anyone with a similar need. Please feel free to send me a private message or respond back to this thread, I will be checking it regularly.

Z

transpondermedia's picture
Offline
Joined: 12/07/2007
Juice: 15
Re: Re: Add upload logo functionality during checkout by client

Is there a way to allow different file extensions? (excel, word, etc.)

ckidow's picture
Offline
Joined: 10/27/2008
Juice: 46
Re: Add upload logo functionality during checkout by client

any updates for a solution to let the user upload an image to his order/product?

tembenite's picture
Offline
Joined: 08/15/2010
Juice: 64
Re: Re: Add upload logo functionality during checkout by client

I've got something about complete that should allow this functionality.

It extends the attributes to allow a "Customer File Upload" attribute. What type of file that can be uploaded can generically be set in the configuration settings for all attributes, or can be controlled on the attribute level by adding the extension of files to the list of "options".

File added to a cart are stored in one file location, and then moved to another location after the order is placed. Files associated with carts that no longer exist are periodically cleaned up via a cron hook.

The present structure allows for both anonymous and registered user uploads. Users need to be logged in to view files from past orders.

If an anonymous user places an order, they will have to supply their e-mail address and zip code to view the file later after the order is complete and they no longer have a valid session. (This last part I'm coding now).

I'm planning on adding this to a contrib when complete, but if anyone would like to help me beta test it in the next few weeks, send me a note. I should have this ready for review by the end of the week.

grazman's picture
Offline
Joined: 11/17/2010
Juice: 9
Is this ready to be tested?

I have been looking for this type of functionality with an ecommerce package, and its hard to find one that works. I'm willing to test, but I didn't see the contrib anywhere.