I have not be able to access the Submission ID in the function when inserting a new submission. Tried too many things to go into but if anyone know a way to access the SID at this point it would be very helpful. I found several other posts asking about file naming etc but did not see anyone ask this particular question, hence the new issue.

My goal is to change the following line:

$upload_dir = file_directory_path() .'/webform/'. $component['extra']['savelocation'];

to

$upload_dir = file_directory_path() .'/webform/'. $component['extra']['savelocation']."/".$sid;

Comments

quicksketch’s picture

What you're trying to do is extremely difficult (as it sounds like you've found), and you can't do it with the additional validation or submission textareas, since the submission ID is not yet known at the time these code snippets are run. The only way you can do what you're attempting is to write a custom module which adds an additional #submit handler to the webform. Drupal will always upload files to their "final" location, meaning that when a user uploads a file it will immediately be saved in the files directory, but at that point you don't yet know what the SID is. In your custom module, you'd have to move the file from the first location to it's new location once the SID becomes available.

RobertW’s picture

Thanks quicksketch,

I had pretty much come to that conclusion but I was hoping I was missing something somewhere. Oh well, so I have the beginning of a modification to the webform_submissions.inc. I decided to rename rather than create subfolders after I started looking at the data and the function does what I want. I still have some error checking to add and I will create a select on the file field definition page to turn the feature on and off at some point.

Here is what I have so far. If anyone more familiar with Drupal modules has any pointers they would be much appreciated.

Changes start at:
"webform_file_move_rename($node->nid, $sid)"

function webform_submission_insert($node, $submitted) {
  global $user;

  $result = db_query("INSERT INTO {webform_submissions} (nid, uid, submitted, remote_addr) VALUES (%d, %d, %d, '%s')", 

$node->nid, $user->uid, time(), ip_address());

  $sid = db_last_insert_id('webform_submissions', 'sid');

  foreach ($submitted as $cid => $value) {
    // Don't save pagebreaks as submitted data.
    if ($node->webform['components'][$cid]['type'] == 'pagebreak') {
      continue;
    }

    if (is_array($value)) {
      $delta = 0;
      foreach ($value as $k => $v) {
        db_query("INSERT INTO {webform_submitted_data} (nid, sid, cid, no, data) VALUES (%d, %d, %d, %d, '%s')", $node->nid, 

$sid, $cid, $delta, $v);
        $delta++;
      }
    }
    else {
      db_query("INSERT INTO {webform_submitted_data} (nid, sid, cid, no, data) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $sid, 

$cid, 0, $value);
    }
  }
//---------------------------------------Start Changes---------------------------------------
  webform_file_move_rename($node->nid, $sid); // This line and webform_file_move_rename function below added -RobertW.
  return $sid;
}


/**
 * Function to rename files.  Effected files will be named (sid)-(form_key).(originalextension)
 * -RobertW
 */
function webform_file_move_rename($nid, $sid) {

//**Find all fields of type file for the current submission
  $query = "SELECT sd.*, c.form_key ".
           "FROM {webform_submitted_data} sd ".
           "LEFT JOIN {webform_component} c USING (cid,nid) ".
           "WHERE sd.nid = %d AND sd.sid = %d AND c.type='file'";
  $res = db_query($query,$nid,$sid);

//**Loop through file fields renameing files and updating the data field in {webform_submitted_data}
  while ($row = db_fetch_object($res)) {
    $cid = $row->cid;
    $data = unserialize($row->data);
    $oldLocation = $data['filepath'];
    if ($oldLocation == "") continue;
//**Build New Location based on form_key and existing path and file extension
    $newLocation = substr($oldLocation,0,strrpos($oldLocation, "/")+1);
    $newLocation .= $sid."-".$row->form_key;
    $newLocation .= substr($oldLocation,strrpos($oldLocation, "."));

//**Move file to new location
    $file_moved = file_move($oldLocation,$newLocation,'FILE_EXISTS_REPLACE');
    if ($file_moved) {
//**Update file location in the {webform_submitted_data} data field of the file was moved properly
      $data['filepath'] = $newLocation;
      $data['destination'] = $newLocation;
      $newdata = serialize($data);
      $query = "UPDATE {webform_submitted_data} SET data='%s' WHERE nid=%d AND sid=%d AND cid=%d";
      db_query($query,$newdata,$nid,$sid,$cid);
    }
  }

 return 0;

}
//---------------------------------------End Changes---------------------------------------
/**
 * Delete a single submission.
 */

Thanks in advance,
Robert W.

quicksketch’s picture

I'd say first off, modifying the module is a quick way to make sure you *don't* get help from the Webform issue queue. There are so many questions and support requests filed that I don't answer questions for users that have modified their installations of Webform.

Like I said in #1, you can do this without hacking the Webform module. Make a custom module such as "webform_rename.module", then have something like the following in that module:


/**
 * Implementation of hook_form_alter().
 */
function webform_rename_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'webform_node_form') {
    $form['#submit'][] = 'webform_rename_files';
  }
}

/**
 * Additional submit handler for webform_node_form.
 */
function webform_rename_files(&$form, &$form_state) {
  $nid = $form_state['values']['nid'];
  $sid = $form_state['values']['sid'];

  // Call the rename function from your example in #2.
  webform_file_move_rename($nid, $sid);
}

Now all your custom changes are self-contained, and when the next version of Webform comes out you don't need to try to figure out what you've hacked and how to update it to the new version. Just delete the old version of Webform, replace it with the new version, and your custom changes keep on chugging along in a separate module.

RobertW’s picture

Category: support » feature

quicksketch,

I have taken your advise and moved my function into a module of its own. I can get the hook and all the functions to run but is looks like $form_state is not available when using a #submit. I found several posts referring to the problem as new in Drupal 6. I verified the function works as a module by throwing together a quick DB search to find the nid and sid but it is quite a kludge:

function webform_rename_files(&$form, $form_state) {

  if (arg(0) == 'node' && is_numeric(arg(1))) $nid = arg(1);
  $query = ("SELECT sid FROM {webform_submitted_data} WHERE nid=%d ORDER BY sid DESC Limit 1");
  $res = db_query($query,$nid);
  $row = db_fetch_object($res);
  $sid = $row->sid;
  drupal_set_message(t('Hook2 '.$nid." ".$sid));
 
  // Call the rename function from your example in #2.
  webform_file_rename($nid, $sid);
}

Any words of wisdom on how I might resolve this issue?

Thanks,
RobertW

RobertW’s picture

Category: feature » support

P.S. I have tried all combinations of $form and $form_state by reference to no effect. I don't think it should mater to the functions in my particular project anyway.

-Robert W.

jdwfly’s picture

I followed what quicksketch said in #3 and was able to access $form_state variable in my submit function. I would check your hook_form_alter for proper syntax and you also need to clear the cache for it to work (I think).

tejaspmehta’s picture

Hello quicksketch,

Your suggestion in #3 was good but if i only want to save $sid in my session variable than how can i do it ? as by altering form it might be not possible that i will receive $sid value in my session variable. I did try form_alter but it did nothing to get currently submitted $sid value in session.

Any suggestions ???

What i want to do is save this session value of webform_submission_id and enter in one table and after my webform successfully save vaules it will be redirected to ubercart for checkout and from there also i have to save ubercart_primary_key_id and save into table with webfrom_submission_id to make some reports. If you have any module like this also than you can let me know. i didnt find such type of module.

hope to receive soon reply.

Thank you.

tejaspmehta’s picture

Hello quicksketch,

As per your post in comment #3 here i made my module with name gluewebform. My main task is to save SID into database once webform is submitted. Here is my code


<?php 

/**
 * @file
 * Glue Webform Module File
 */

function gluewebform_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'webform_node_form') {
    $form['#submit'][] = 'gluewebform_getsid';
  }
}

function gluewebform_getsid(&$form, &$form_state) {
  $sid = $form_state['values']['sid'];

	print $sid;die;
}

Now here also i am not able to get SID. According to me i am doing some mistake in $form['#submit'][]. Is it correct ? or we need other value there ?

Please do reply.

Thank you.

richbaldwin’s picture

hello jdwfly,

since you got it to work can I ask what version of webform/drupal are you using?
also if its not too much of a problem can you please post a snippet of your code.
Just the necessary parts showing module setup and function call.
i've tried but i just can't get the sid value after the webform has been submitted...

tia,

-- r

jdwfly’s picture

I don't know which version it was because I have already switched to something else. It became too much of a hassle to add custom submit functions to my forms. I would suggest checking out Webform Associate and if you need Ubercart, check out Webform Productize. Personally I tried them out but they had other problems that just wouldn't make a complete solution for me. In the end I set up webform to put a product in their cart and passed attributes to it so that I knew which form submission it came from.

tejaspmehta’s picture

Hello jdwfly,

Thank you for your reply. Now before creating module i did check Webform Associate module and Webform Productize modules. Webform Associate module has bugs. it still gives error and they claim that it is solved but it is not. Also Webform Productize module need Webform Associate works properly. But it is also not working properly as per my need.

What i want is to save $sid value either in session or in database. If you have some idea than do let me know. i know its hard for you as you did it long time ago and now you switched to something else.

Thank you for your help.

richbaldwin’s picture

OK thanks for the reply. We had looked at webform productize before but didn't do what we wanted. Of course then we knew less about drupal too. May be a good time to have another look.

Thanks again.

-- r

quicksketch’s picture

Status: Active » Closed (fixed)

Just a note for future reference that Webform Associate is essentially built-into Webform 3.x if you're willing to try out a development version. Webform now simply "webform-enables" any content type, and makes the webform content type by default for easy installation for new users.

I'm closing this issue since it seems pretty well resolved. The submission guidelines for the Webform queue now state that help with custom coding is no longer provided.