diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/date.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/date.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/date.inc 2008-06-26 22:41:44.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/date.inc 2008-07-02 15:56:24.061875000 -0400 @@ -265,11 +265,13 @@ function _webform_help_date($section) { * submissions. */ function _webform_analysis_rows_date($component) { - $query = 'SELECT no,data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d '. - ' ORDER BY sid,no ASC '; + $query = 'SELECT sd.no,sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. + ' AND sd.cid = %d '. +' AND s.is_draft != 1'. + ' ORDER BY sd.sid,sd.no ASC '; $result = db_query($query, $component['nid'], $component['cid']); // build an array of timestamps from entered values. diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/email.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/email.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/email.inc 2008-04-02 00:05:16.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/email.inc 2008-07-02 15:56:28.077500000 -0400 @@ -157,10 +157,12 @@ function _webform_help_email($section) { * submissions. */ function _webform_analysis_rows_email($component) { - $query = 'SELECT data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d'; + $query = 'SELECT sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. +' AND s.is_draft != 1'. + ' AND sd.cid = %d'; $nonblanks = 0; $submissions = 0; $wordcount = 0; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/file.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/file.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/file.inc 2008-06-20 23:31:22.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/file.inc 2008-07-21 11:03:35.399375000 -0400 @@ -243,8 +243,8 @@ function _webform_render_file($component '#attributes' => $component['extra']['attributes'], '#tree' => false, // file_check_upload assumes a flat $_FILES structure. '#validate' => array( - '_webform_validate_file' => array($component['form_key'], $component['name'], $component['extra']['filtering']), - '_webform_required_file' => array($component['form_key'], $component['name'], $component['mandatory']), // Custom required routine. + '_webform_CHECKALWAYS_validate_file' => array($component['form_key'], $component['name'], $component['extra']['filtering']), + '_webform_required_file' => array($component['form_key'], $component['name'], $component['mandatory'], $component), // Custom required routine. ), '#prefix' => '
', '#suffix' => '
', @@ -257,22 +257,62 @@ function _webform_render_file($component return $form_item; } -function _webform_required_file($form_element, $form_key, $fieldname, $required = false) { - if (empty($_FILES['files']['name'][$form_key]) && $required) { - form_set_error($fieldname, t('%field field is required.', array('%field' => $fieldname))); - } -} +function _webform_required_file($form_element, $form_key, $fieldname, $required = false, $component) { + + //now about when submitting for first time? is form #details sid available? if not look for way to include it //if( isset( $form_element['details'])) -function _webform_validate_file($form_element, $form_key, $fieldname, $filters) { + if( $required ) + {//no new file + + if( empty($_FILES['files']['name'][$form_key]) ) + { + $qargs = array( $component['nid'], $form_element['#post']['details']['sid'], $component['cid'] ); + $result = db_query("SELECT `data` FROM {webform_submitted_data} d WHERE nid=%d and sid=%d and cid=%d", $qargs ); + + if ($row = db_fetch_object($result)) + { + $current_file = unserialize( $row->data ); //drupal_set_message( 'currentfile='. print_r( $current_file,1) ); + if( trim($current_file['filepath']) == "" ) + {//no filepath define before, user probably just saved form, and hence no filepath values + form_set_error($fieldname, t('%field field is required.', array('%field' => $fieldname))); + setFileComponantError($form_key); + } + else + {//filepath is defined/saved before + if(! file_exists($current_file['filepath']) ) + { + form_set_error($fieldname, t('Your previously uploaded file %filename is not found/lost. The %field field is required so please reupload file.', array('%field' => $fieldname, '%filename'=>$current_file['filename'])) ); + setFileComponantError($form_key); + } + } + + } + else//no old data but no new data and since required, error + { + form_set_error($fieldname, t('%field field is required.', array('%field' => $fieldname))); + setFileComponantError($form_key); + } + } + + } + +} +function setFileComponantError($form_key){//drupal doesnt automatically handle so we handle setting css + drupal_add_js("$(document).ready(function(){ + $('#webform-component-". $form_key ." input').addClass('error');//adds error class so highlights input field + });", "inline"); +} +function _webform_CHECKALWAYS_validate_file($form_element, $form_key, $fieldname, $filters) { // Set the current file as the default. + + //return here or remove this part entirely with unset_req_fields if saving + if( empty($_FILES['files']['name'][ $form_key ]) ) //if saving no file wont have a name, maybe pass is_draft here later + return; + if (isset($form_element['#webform_current_file'])) { form_set_value(array('#parents' => $form_element['#parents']), serialize($form_element['#webform_current_file'])); } - if (empty($_FILES['files']['name'][$form_key])) { - return; - } - // Build a human readable list of extensions: $extensions = $filters['types']; if (count($extensions) > 1) { @@ -289,12 +329,19 @@ function _webform_validate_file($form_el $extension = strtolower(substr($_FILES['files']['name'][$form_key], $dot+1)); if (!in_array($extension, $extensions)) { form_set_error($form_key, t("Files with the '%ext' extension are not allowed, please upload a file with a %exts extension.", array('%ext' => $extension, '%exts' => $extension_list))); + setFileComponantError($form_key); } // Now let's check the file size (limit is set in KB). if ($_FILES['files']['size'][$form_key] > $filters['size']*1024) { form_set_error($form_key, t("The file '%filename' is too large (%filesize KB). Please upload a file %maxsize KB or smaller.", array('%filename' => $_FILES['files']['name'][$form_key], '%filesize' => (int)($_FILES['files']['size'][$form_key]/1024), '%maxsize' => $filters['size']))); + setFileComponantError($form_key); + } + else if($_FILES['files']['size'][$form_key] <= 0){//a 0byte fake file (forget if a scenario creates this but included just in case) or nonexistant file on server + form_set_error($form_key, t("The file '%filename' does not seem to exist on your computer. Please click the Browse button and repick a file, and make sure to not modify the text that auto-fills the textfield.", array('%filename' => $_FILES['files']['name'][$form_key]) )); + setFileComponantError($form_key); } + } /** @@ -308,17 +355,44 @@ function _webform_validate_file($form_el * @return * Nothing. */ -function _webform_submit_file(&$data, $component) { +function _webform_submit_file(&$data, $component, $node) { // Hack to get the form value for this file component (not necessary in D6). global $form_values; + global $sidToInsert; $data = $form_values[$component['form_key']]; $current_file = unserialize($data); - if ($file = file_check_upload($component['form_key'])) { - $upload_dir = file_directory_path() ."/webform/". $component['extra']['savelocation']; - - if (file_check_directory($upload_dir, FILE_CREATE_DIRECTORY)) { + if( isset($form_values['details']['sid']) ) + $sid = $form_values['details']['sid']; + else + {//submitting value first time arrive at the page so no sid yet, so set one to preserve cool directory structure + if( !isset($sidToInsert) ) + { + $sidToInsert = db_next_id('{webform_submissions}_sid');//is this safe to call here? what if two users submitting around same exact time? if not safe, store sid in database until inserted so other inserts can check to see what next $sid is , if orig way unsafe or database storage of next_ids is too much of hassle, then go back to old saving scheme where file is uploaded to generic webforms directory.... and change _insert hook back to old way + $sid = $sidToInsert; + } + else + $sid = $sidToInsert;//inserting 2nd+ file, reuse insert just gotten above + } + + if ($file = file_check_upload($component['form_key'])) { //$_FILES["files"]["name"][$source] $_FILES["files"]["tmp_name"][$source] + + if( trim($component['extra']['savelocation'])=='' ) + { + $upload_dir_pre = file_directory_path() ."/webform/". $form_values['details']['nid']; //standardized structure to find easily + $upload_dir_append = "/". $sid;//makes sense to put in nid/sid i think so easier to find on server + $upload_dir = $upload_dir_pre.$upload_dir_append; + $dodetailedpath = TRUE; + } + else + $upload_dir = file_directory_path() ."/webform/". $component['extra']['savelocation']; + + if ( + ( ($dodetailedpath==FALSE) && file_check_directory($upload_dir, FILE_CREATE_DIRECTORY) ) + || + ( ($dodetailedpath==TRUE) && file_check_directory($upload_dir_pre, FILE_CREATE_DIRECTORY) && file_check_directory($upload_dir, FILE_CREATE_DIRECTORY) ) + ) { $file_saved = file_save_upload($component['form_key'], $upload_dir); if (!$file_saved) { drupal_set_message(t("The uploaded file %filename was unable to be saved. The destination directory may not be writable.", array('%filename' => $file_saved['filename'])), "error"); @@ -329,7 +403,7 @@ function _webform_submit_file(&$data, $c } } else { - drupal_set_message(t("The uploaded file was unable to be saved. The destination directory does not exist.", "error")); + drupal_set_message(t("The uploaded file was unable to be saved. The destination directory does not exist."), "error"); } } } @@ -377,8 +451,14 @@ function _webform_submission_display_fil if ($enabled) { $form_item['#description'] = t('Uploading a new file will replace the current file.'); $form_item['#webform_current_file'] = $filedata; + + drupal_add_js("$(document).ready(function(){ + + $('#webform-component-". $component['form_key'] ." label .form-required').append(' (You have already uploaded a file for this field so not required to reupload new file unless want to replace.)'); + });", "inline"); } } + return $form_item; } @@ -424,10 +504,12 @@ function _webform_help_file($section) { * submissions. */ function _webform_analysis_rows_file($component) { - $query = 'SELECT data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d'; + $query = 'SELECT sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. +' AND s.is_draft != 1'. + ' AND sd.cid = %d'; $nonblanks = 0; $submissions = 0; $wordcount = 0; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/grid.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/grid.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/grid.inc 2008-06-29 19:54:10.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/grid.inc 2008-07-03 10:14:20.999375000 -0400 @@ -182,12 +182,14 @@ function _webform_analysis_rows_grid($co $questions = array_values(_webform_grid_options($component['extra']['questions'])); // Generate a lookup table of results. - $query = 'SELECT no, data, count(data) as datacount '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d '. - " AND data != '0' AND data != '' ". - ' GROUP BY no, data'; + $query = 'SELECT sd.no, sd.data, count(sd.data) as datacount '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. + ' AND sd.cid = %d '. + " AND sd.data != '0' AND sd.data != '' ". +' AND s.is_draft != 1'. + ' GROUP BY sd.no, sd.data'; $result = db_query($query, $component['nid'], $component['cid']); $counts = array(); while ($data = db_fetch_object($result)) { diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/hidden.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/hidden.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/hidden.inc 2008-05-08 15:38:02.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/hidden.inc 2008-07-02 15:56:50.280625000 -0400 @@ -102,10 +102,12 @@ function _webform_help_hidden($section) * submissions. */ function _webform_analysis_rows_hidden($component) { - $query = 'SELECT data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d'; + $query = 'SELECT sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. +' AND s.is_draft != 1'. + ' AND sd.cid = %d'; $nonblanks = 0; $submissions = 0; $wordcount = 0; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/select.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/select.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/select.inc 2008-06-26 23:19:12.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/select.inc 2008-07-02 15:56:55.046250000 -0400 @@ -261,12 +261,14 @@ function _webform_help_select($section) function _webform_analysis_rows_select($component) { $options = _webform_select_options($component['extra']['items']); - $query = 'SELECT data, count(data) as datacount '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d '. - " AND data != '0' AND data != '' ". - ' GROUP BY data '; + $query = 'SELECT sd.data, count(sd.data) as datacount '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. + ' AND sd.cid = %d '. +' AND s.is_draft != 1'. + " AND sd.data != '0' AND sd.data != '' ". + ' GROUP BY sd.data '; $result = db_query($query, $component['nid'], $component['cid']); $rows = array(); while ($data = db_fetch_array($result)) { diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/textarea.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/textarea.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/textarea.inc 2008-05-27 12:31:16.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/textarea.inc 2008-07-02 15:55:51.952500000 -0400 @@ -117,10 +117,12 @@ function _webform_help_textarea($section * submissions. */ function _webform_analysis_rows_textarea($component) { - $query = 'SELECT data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d'; + $query = 'SELECT sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. +' AND s.is_draft != 1'. + ' AND sd.cid = %d'; $nonblanks = 0; $submissions = 0; $wordcount = 0; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/textfield.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/textfield.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/textfield.inc 2008-06-29 19:55:14.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/textfield.inc 2008-07-02 15:52:49.530625000 -0400 @@ -160,10 +160,12 @@ function _webform_help_textfield($sectio * submissions. */ function _webform_analysis_rows_textfield($component) { - $query = 'SELECT data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d'; + $query = 'SELECT sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. +' AND s.is_draft != 1'. + ' AND sd.cid = %d'; $nonblanks = 0; $submissions = 0; $wordcount = 0; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/time.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/time.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/components/time.inc 2008-04-02 00:05:16.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/components/time.inc 2008-07-02 15:52:31.858750000 -0400 @@ -226,11 +226,13 @@ function _webform_help_time($section) { * submissions. */ function _webform_analysis_rows_time($component) { - $query = 'SELECT no,data '. - ' FROM {webform_submitted_data} '. - ' WHERE nid = %d '. - ' AND cid = %d '. - ' ORDER BY sid,no ASC '; + $query = 'SELECT sd.no,sd.data '. + ' FROM {webform_submitted_data} sd'. +' JOIN {webform_submissions} s ON sd.sid = s.sid'. + ' WHERE sd.nid = %d '. + ' AND sd.cid = %d '. +' AND s.is_draft != 1'. + ' ORDER BY sd.sid,sd.no ASC '; $result = db_query($query, $component['nid'], $component['cid']); // build an array of timestamps from entered values. Only in /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/: temp diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform.module /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform.module --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform.module 2008-06-30 16:09:48.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform.module 2008-07-18 17:55:18.790000000 -0400 @@ -113,6 +113,13 @@ function webform_menu($may_cache) { 'callback arguments' => array($node), 'access' => node_access('view', $node), 'type' => MENU_CALLBACK, + ); + $items[]= array( + 'path' => 'node/'. $node->nid .'/draft_saved', + 'title' => t('Draft saved'), + 'callback' => '_webform_draft_confirmation', + 'callback arguments' => array(arg(1)), + 'type' => MENU_CALLBACK, ); $items[] = array( 'path' => 'node/'. $nid .'/done', @@ -201,15 +208,20 @@ function webform_menu($may_cache) { 'weight' => 2, 'type' => MENU_CALLBACK, ); + if (isset($sid)) { include_once(drupal_get_path('module', 'webform') ."/webform_submissions.inc"); $submission = webform_get_submission($node->nid, $sid); + if(!$submission)//false value so page not found + drupal_not_found(); + $items[] = array( 'path' => 'node/'. $nid .'/submission/'. $sid, 'title' => t('Webform submission'), 'callback' => 'drupal_get_form', - 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, FALSE, FALSE), + //enabled, preview, isdraft + 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, FALSE, FALSE, FALSE, $submission->is_draft),//all of these were false before? 'access' => webform_submission_access($node, $submission, 'view'), 'type' => MENU_CALLBACK, ); @@ -217,7 +229,7 @@ function webform_menu($may_cache) { 'path' => 'node/'. $nid .'/submission/'. $sid .'/view', 'title' => t('View'), 'callback' => 'drupal_get_form', - 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, FALSE, FALSE), + 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, FALSE, FALSE, FALSE, $submission->is_draft),//all of these were false before? 'access' => webform_submission_access($node, $submission, 'view'), 'weight' => 0, 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -226,7 +238,7 @@ function webform_menu($may_cache) { 'path' => 'node/'. $nid .'/submission/'. $sid .'/edit', 'title' => t('Edit'), 'callback' => 'drupal_get_form', - 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, TRUE, FALSE), + 'callback arguments' => array('webform_client_form_'. $node->nid, $node, $submission, TRUE, FALSE, FALSE, $submission->is_draft),//all of these were false before? 'access' => webform_submission_access($node, $submission, 'edit'), 'weight' => 1, 'type' => MENU_LOCAL_TASK, @@ -287,6 +299,7 @@ function webform_access($op, $node) { * All webform_client_form forms share the same form handler */ function webform_forms($args) { + $form_id = $args[0]; if (strpos($form_id, 'webform_client_form_') === 0) { $forms[$form_id]['callback'] = 'webform_client_form'; @@ -301,10 +314,46 @@ function webform_forms($args) { */ function webform_file_download($file) { $file = file_check_location(file_directory_path() .'/'. $file, file_directory_path() .'/webform/'); - if ($file && user_access('access webform results')) { - $info = image_get_info(file_create_path($file)); - return array('Content-type: '. $info['mime_type']); - } + //makes sense that if they save their submission and want to recome back to it to check on it... that they can dl and view their file to see if they want to replace it, also give access to anyone who can edit webform submissions + global $user; + + //get sid of file so can figure out uid of who submitted this file as an answer (to base permissions off of) + //(originally had planned to get it based on filepath like 'webforms/nid/sid/filename' which i thought was useful and use currently but i allow the extra save functionality, which can be set in the webform options, to save to a generic directory like i assume people would want a folder like 'webforms/resume' that can be set in many webforms), So if extra save location is set, how would i get sid since not in the filepath anymore? i think i will handle by looking at the filepath in database, return the sid from webform_submitted_data, and get uid based on that, filepath shouldnt be the same for anything but ill check for that in case (maybe admin hand deleted the file, and forgot to delete database submission) + $result = db_query("SELECT `data`, nid, sid FROM {webform_submitted_data} d"); + $numFiles = 0; + while( $row = db_fetch_object($result)) + { + $data = unserialize($row->data); + $pathinfoFilePathUrl = pathinfo($file); + $pathinfoDB = pathinfo($data['filepath']); + + //so making sure the database entry is same filepath if requested file + if( (realpath($pathinfoFilePathUrl['dirname'])==realpath($pathinfoDB['dirname'])) && ($pathinfoFilePathUrl['basename']==$pathinfoDB['basename']) )//base on filedir, and then filename cause windows seems to insert funky filenames like c:\files/webform/1/2/node1submissionfile.blah + { + $numFiles++; + $sid = $row->sid; + $nid = $row->nid; + //$cid = $row->cid; //info not needed + } + } + + + if( $numFiles == 1 )//found a match, now lets see if the user can access it by being an webformadmin-type person or if matches the user who submitted that file + { + $file_uid = db_result(db_query("SELECT uid FROM {webform_submissions} ws WHERE sid=%d AND nid=%d", $sid, $nid)); + if ($file && ( + user_access('access webform results') + || (user_access('edit own webform submissions') && ($file_uid==$user->uid) ) + || (user_access('access own webform submissions') && ($file_uid==$user->uid) ) + || user_access('edit webform submissions') + )) { + $info = image_get_info(file_create_path($file)); + return array('Content-type: '. $info['mime_type']); + } + } + else + drupal_set_message( 'There are 2 of these files with same filepath in the database for some reason so we are not sure if you are allowed to access this file. Please ask website administrator to fix so you may get access.' ) ; + } /** @@ -314,8 +363,7 @@ function webform_insert($node) { include_once(drupal_get_path('module', 'webform') .'/webform_components.inc'); // Insert the Webform. - db_query("INSERT INTO {webform} (nid, confirmation, teaser, submit_text, submit_limit, submit_interval, email, email_from_name, email_from_address, email_subject, additional_validate, additional_submit) VALUES (%d, '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->nid, $node->webform['confirmation'], $node->webform['teaser'], $node->webform['submit_text'], $node->webform['submit_limit'], $node->webform['submit_interval'], $node->webform['email'], $node->webform['email_from_name'], $node->webform['email_from_address'], $node->webform['email_subject'], $node->webform['additional_validate'], $node->webform['additional_submit']); - + db_query("INSERT INTO {webform} (nid, confirmation, teaser, submit_text, submit_limit, submit_interval, email, email_from_name, email_from_address, email_subject, additional_validate, additional_submit, allow_draft) VALUES (%d, '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d)", $node->nid, $node->webform['confirmation'], $node->webform['teaser'], $node->webform['submit_text'], $node->webform['submit_limit'], $node->webform['submit_interval'], $node->webform['email'], $node->webform['email_from_name'], $node->webform['email_from_address'], $node->webform['email_subject'], $node->webform['additional_validate'], $node->webform['additional_submit'], $node->webform['allow_draft']); // Insert the components into the database. if (isset($node->webform['components']) && !empty($node->webform['components'])) { foreach ($node->webform['components'] as $cid => $component) { @@ -665,6 +713,14 @@ function webform_form(&$node, &$param) { '#default_value' => $node->webform['submit_text'], '#description' => t('By default the submit button on this form will have the label Submit. Enter a new title here to override the default.'), ); + + // Allow save draft + $form['webform']['advanced']['allow_draft'] = array( + '#type' => 'checkbox', + '#title' => t('Allow users to save a draft'), + '#default_value' => $node->webform['allow_draft'], + ); + if (user_access('use PHP for additional processing')) { $form['webform']['advanced']['additional_validate'] = array( '#type' => 'textarea', @@ -892,7 +948,7 @@ function webform_view(&$node, $teaser = $limit_exceeded = FALSE; if (isset($_POST['op']) && $_POST['op'] == t('Preview')) { - $preview = true; + $preview = TRUE; $additions = webform_load($node); $node->webform['components'] = $additions->webform['components']; } @@ -930,6 +986,7 @@ function webform_view(&$node, $teaser = // Check if the user can add another submission. if ($node->webform['submit_limit'] != -1) { // -1: Submissions are never throttled. include_once(drupal_get_path('module', 'webform') ."/webform_submissions.inc"); + if ($limit_exceeded = _webform_submission_limit_check($node)) { $enabled = FALSE; } @@ -937,12 +994,25 @@ function webform_view(&$node, $teaser = // Get a count of previous submissions by this user. if ($user->uid && (user_access('access own webform submissions') || user_access('access webform results') || user_access('access webform submissions'))) { - $submission_count = db_result(db_query("SELECT count(*) FROM {webform_submissions} WHERE nid = %d AND uid = %d", $node->nid, $user->uid)); + $submission_count = db_result(db_query("SELECT count(*) FROM {webform_submissions} WHERE nid = %d AND uid = %d AND is_draft = false", $node->nid, $user->uid)); } + // Check if this user has a draft for this webform. + $is_draft = FALSE; + if ($node->webform['allow_draft'] && $user->uid != 0) { + // Draft found - display form with draft data for further editing. + if ($_draft_sid = _webform_fetch_draft_sid($node->nid, $user->uid)) { + include_once(drupal_get_path('module', 'webform') ."/webform_submissions.inc"); + $submission = webform_get_submission($node->nid, $_draft_sid); + $enabled = TRUE; + $is_draft = TRUE; + } + } + // Render the form and generate the output. - $form = drupal_get_form('webform_client_form_'. $node->nid, $node, $submission, $enabled, $preview); - $output = theme('webform_view', $node, $teaser, $page, $form, $enabled); + $form = drupal_get_form('webform_client_form_'. $node->nid, $node, $submission, $enabled, $preview, NULL, $is_draft);//CHANGE from the save.patch... that one themed using just $form (no $output), formvalues not needed? + $output = theme('webform_view', $node, $teaser, $page, $form, $enabled, $is_draft); //just in case needs it? old patch only used output + // Remove the surrounding
tag if this is a preview. if ($preview) { @@ -951,7 +1021,7 @@ function webform_view(&$node, $teaser = // Print out messages for the webform. if (!$preview && !$logging_in) { - theme('webform_view_messages', $node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles); + theme('webform_view_messages', $node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles, $is_draft); } // Add the output to the node. @@ -977,7 +1047,7 @@ function webform_view(&$node, $teaser = * @param $enabled * If the form allowed to be completed by the current user. */ -function theme_webform_view($node, $teaser, $page, $form, $enabled) { +function theme_webform_view($node, $teaser, $page, $form, $enabled, $is_draft) { // Only show the form if this user is allowed access. if ($enabled) { return $form; @@ -1001,7 +1071,7 @@ function theme_webform_view($node, $teas * @param $allowed_roles * A list of user roles that are allowed to submit this webform. */ -function theme_webform_view_messages($node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles) { +function theme_webform_view_messages($node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles, $is_draft) { $type = 'notice'; // If not allowed to submit the form, give an explaination. @@ -1036,11 +1106,17 @@ function theme_webform_view_messages($no // If the user has submitted before, give them a link to their submissions. if ($submission_count > 0) { + global $user; + + $allowedAnotherSubmitNsg = $limit_exceeded ? '' : ( ($is_draft) ? t(' (You may still submit your saved version below)') : t(' (You may still submit another time below)') ); + $allowedEditOwnForm = user_access("edit webforms") || (user_access("edit own webforms") && ($user->uid == $node->uid)); + $allowedEditOwnFormMsg = $allowedEditOwnForm ? ' or Edit' : ''; + if (empty($message)) { - $message = t('You have already submitted this form.') .' '. t('View your previous submissions.', array('!url' => url('node/'. $node->nid .'/submissions'))); + $message = t('You have already submitted this form'. $allowedAnotherSubmitNsg .'.') .' '. t('View'. $allowedEditOwnFormMsg .' your previous submissions.', array('!url' => url('node/'. $node->nid .'/submissions'))); } else { - $message .= ' '. t('View your previous submissions.', array('!url' => url('node/'. $node->nid .'/submissions'))); + $message .= ' '. t('View'. $editMessage .' your previous submissions.', array('!url' => url('node/'. $node->nid .'/submissions'))); } } @@ -1174,65 +1250,74 @@ function theme_webform_admin_settings($f * @param $submission * An array of values for the form if we're displaying a result. * @param $enabled - * If displaying a result, specify if form elements are enabled for - * editing. + * If displaying a result, specify if form elements are enabled for editing. + * @param $is_draft + * Optional. Set to TRUE if displaying a draft. * @param $form_values * The current form values of a submission, used in multipage webforms. * Note: The position of this parameter depends on all other parameters being * specified when using drupal_get_form(). */ -function webform_client_form(&$node, $submission, $enabled, $preview, $form_values = NULL) { +function webform_client_form(&$node, $submission, $enabled, $preview, $form_values = NULL, $is_draft) { include_once(drupal_get_path('module', 'webform') .'/webform_components.inc'); webform_load_components(); - if (isset($submission->sid)) { + if (isset($submission->sid) && (!$is_draft) ) { drupal_set_title(t('Submission #@sid', array('@sid' => $submission->sid))); } - // Set a header for navigating results. if ($submission && user_access('access webform results')) { // Add CSS to display submission info. Don't preprocess because this CSS file is used rarely. - drupal_add_css(drupal_get_path('module', 'webform') .'/webform.css', 'module', 'all', FALSE); + + if (!$is_draft) { + // Add CSS to display submission info. Don't preprocess because this CSS file is used rarely. + drupal_add_css(drupal_get_path('module', 'webform') .'/webform.css', 'module', 'all', FALSE); + + $previous = db_result(db_query('SELECT MAX(sid) FROM {webform_submissions} WHERE nid = %d AND sid < %d', array($node->nid, $submission->sid))); + $next = db_result(db_query('SELECT MIN(sid) FROM {webform_submissions} WHERE nid = %d AND sid > %d', array($node->nid, $submission->sid))); + + $form['navigation'] = array( + '#prefix' => '
', + '#suffix' => '
', + ); + $form['navigation']['previous'] = array( + '#value' => $previous ? l(t('Previous submission'), 'node/'. $node->nid .'/submission/'. $previous . ($enabled ? '/edit' : '') , array('class' => 'webform-submission-previous'), ($enabled ? 'destination=node/'. $node->nid .'/submission/'. $previous .'/edit' : NULL)) : ''. t('Previous submission') .'', + ); + $form['navigation']['next'] = array( + '#value' => $next ? l(t('Next submission'), 'node/'. $node->nid .'/submission/'. $next . ($enabled ? '/edit' : ''), array('class' => 'webform-submission-next'), ($enabled ? 'destination=node/'. $node->nid .'/submission/'. $next .'/edit' : NULL)) : ''. t('Next submission') .'', + ); - $previous = db_result(db_query('SELECT MAX(sid) FROM {webform_submissions} WHERE nid = %d AND sid < %d', array($node->nid, $submission->sid))); - $next = db_result(db_query('SELECT MIN(sid) FROM {webform_submissions} WHERE nid = %d AND sid > %d', array($node->nid, $submission->sid))); - $form['submission'] = array( - '#type' => 'value', - '#value' => $submission, - ); - $form['navigation'] = array( - '#prefix' => '
', - '#suffix' => '
', - ); - $form['navigation']['previous'] = array( - '#value' => $previous ? l(t('Previous submission'), 'node/'. $node->nid .'/submission/'. $previous . ($enabled ? '/edit' : '') , array('class' => 'webform-submission-previous'), ($enabled ? 'destination=node/'. $node->nid .'/submission/'. $previous .'/edit' : NULL)) : ''. t('Previous submission') .'', - ); - $form['navigation']['next'] = array( - '#value' => $next ? l(t('Next submission'), 'node/'. $node->nid .'/submission/'. $next . ($enabled ? '/edit' : ''), array('class' => 'webform-submission-next'), ($enabled ? 'destination=node/'. $node->nid .'/submission/'. $next .'/edit' : NULL)) : ''. t('Next submission') .'', - ); - $form['submission_info'] = array( - '#title' => t('Submission Information'), - '#type' => 'fieldset', - '#collapsible' => FALSE, - ); - $account = user_load(array('uid' => $submission->uid)); - $form['submission_info']['user_picture'] = array( - '#value' => theme('user_picture', $account), - ); - $form['submission_info']['form'] = array( - '#value' => '
'. t('Form: !form', array('!form' => l($node->title, 'node/'. $node->nid))) .'
', - ); - $form['submission_info']['submitted'] = array( - '#value' => '
'. t('Submitted by !name', array('!name' => theme('username', $account))) .'
', - ); - $form['submission_info']['time'] = array( - '#value' => '
'. format_date($submission->submitted, 'large') .'
', - ); - $form['submission_info']['ip_address'] = array( - '#value' => '
'. $submission->remote_addr .'
', - ); + $form['submission'] = array( + '#type' => 'value', + '#value' => $submission, + ); + $form['submission_info'] = array( + '#title' => t('Submission Information'), + '#type' => 'fieldset', + '#collapsible' => FALSE, + ); + $account = user_load(array('uid' => $submission->uid)); + $form['submission_info']['user_picture'] = array( + '#value' => theme('user_picture', $account), + ); + $form['submission_info']['form'] = array( + '#value' => '
'. t('Form: !form', array('!form' => l($node->title, 'node/'. $node->nid))) .'
', + ); + $form['submission_info']['submitted'] = array( + '#value' => '
'. t('Submitted by !name', array('!name' => theme('username', $account))) .'
', + ); + $form['submission_info']['time'] = array( + '#value' => '
'. format_date($submission->submitted, 'large') .'
', + ); + $form['submission_info']['ip_address'] = array( + '#value' => '
'. $submission->remote_addr .'
', + ); + } + //else??? for maybe saving Saved instead of Submitted info + + } // Add a theme function for this form. @@ -1321,12 +1406,22 @@ function webform_client_form(&$node, $su '#weight' => 1000, ); } + // Save draft button + global $user; + if ($node->webform['allow_draft'] && $user->uid != 0) { + $form['draftbutton'] = array( + '#type' => 'submit', + '#value' => t('Save Draft'), + '#weight' => 999, + ); + $form['#no_validate_on'] = 'op=Save Draft';//quicksketch: "I don't see how this is any different from using the $_POST['op']"?, maybe change to $form['#op'] = 'Save Draft'; + } } // Recursively add components to the form. Microweights keep thins in webform order. $microweight = 0.001; foreach ($component_tree['children'] as $cid => $component) { - _webform_client_form_add_component($cid, $component, $form['submitted'], $form, $submission, $page_num, $enabled); + _webform_client_form_add_component($cid, $component, $form['submitted'], $form, $submission, $page_num, $enabled, ( ((int) $node->webform['allow_draft']) && ($user->uid != 0) ) ); $form['submitted'][$component['form_key']]['#weight'] += $microweight; $microweight += 0.001; } @@ -1360,8 +1455,65 @@ function webform_client_form(&$node, $su return $form; } +//* -function _webform_client_form_add_component($cid, $component, &$parent_fieldset, &$form, $submission, $page_num, $enabled = false) { +function unset_required_fields(&$array){ ////$parent_fieldset[$component['form_key']] so $parent[current_revenue_of_the_organization] pass in so $parent[current_revenue_of_the_organization]['#required'] looked at and $parent[current_revenue_of_the_organization]['current_revenue_of_the_organization1 etc'] looked at + foreach( $array as $key=>$value) + { + /*//test + if( is_array($value) ) + echo '#KEY being looked at:
'.htmlspecialchars(print_r($key, true)).'

'; + else + echo '#KEY being looked at:'.$key.'
'; + //*/ + //echo '$array be4:
'.htmlspecialchars(print_r($array, true)).'

'; + + if( is_array($value) && ($key != '#validate') )//Dont need to loop over validate array and look for require/other validate fields + { + unset_required_fields( $array[$key] ); + } + else if( $key == '#required') + { + //*//test echo 'CHANGED array!!!'.'
'; + $array['#required'] = 0; //turn off drupals required validation if saving, problem: * wont show up then? how to fix? + } + else if( $key == '#validate' )//value here is an array of funcnames mapped to funcparams + { + //go through and unset validation functions which dont have _CHECKALWAYS_ in their callback name + + foreach($value as $validationFunctionName=>$validationFuncArgs) + { + //echo 'Looking at'. $validationFunctionName .'
'; + $pos = strpos($validationFunctionName, '_CHECKALWAYS_'); + + //if this is file type, possibly unset validation function to check file validation if already submitted a file before and no new file + //stop validation if( ! empty($_FILES['files']['name'][ $node->webform['components'][$cid]['form_key'] ]) ) + + //unset( $array['#validate'][$validationFunctionName] ); + + + if( $pos === FALSE )//found match + { + //*//test echo 'CHANGED array, got rid of validation func:'.$validationFunctionName.'!!!'.'
'; + unset( $array['#validate'][$validationFunctionName] ); + } + + } + + if( count( $array['#validate'] ) <= 0) + unset( $array['#validate'] ); + } + + //echo '$array after:
'.htmlspecialchars(print_r($array, true)).'

'; + + } + + +} + + +//*/ +function _webform_client_form_add_component($cid, $component, &$parent_fieldset, &$form, $submission, $page_num, $enabled = FALSE, $allow_draft = 0) { // Load with submission information if necessary. if (!$enabled) { // This component is display only, with the value set according information @@ -1389,6 +1541,37 @@ function _webform_client_form_add_compon } } } + + // Save drafts: If the webform is being built during a submission, and draft save + // has been requested, disable required fields to prevent validation warning. + // @todo This leaves the form elements in the rendered page without the 'required' + // markers. At the moment, that undesirable result is circumvented by having + // save-draft submissions redirect to a status page w/o the form. Also, this only + // disables 'required' field validation. Need to test/develop for other validation. + $validate = TRUE; + if (isset($form['#no_validate_on'])) {//thinks this can for just $form['#op'] if using changes by quicksketch + list($no_validate_key, $no_validate_value) = explode('=', $form['#no_validate_on']);//not needed if use that quicksketch change? + //echo '
OUT'; + //echo 'no_validate_key='. $_POST[$no_validate_key] .',no_validate_value='. $no_validate_value .'
'; + if ($_POST[$no_validate_key] == $no_validate_value) {//$POST['op']=='Save Draft' + $validate = FALSE; + } + } + + //*//test echo '########################################################################################'.'
'; + //*//test echo '
NEW COMPONANT:
'. htmlspecialchars($component['name']) .'
'; //print_r($component, true) .''; + //echo '
full COMPONANT:
'. htmlspecialchars(print_r($component, true)) .'
'; //print_r($component, true) .''; + //echo '
its parents:
'. htmlspecialchars(print_r($parent_fieldset, true)).'
';//print_r($parent_fieldset, true) .''; + + if (!$validate) {//if validate is false, set not required + //echo 'Validate off for field: '. $component[form_key].'
'; + //echo '$component[form_key]='. $component['form_key']; + unset_required_fields( $parent_fieldset[$component['form_key']] ); + //*//test echo '
new parents:
'. htmlspecialchars(print_r($parent_fieldset, true)) .'
';//print_r($parent_fieldset, true) .''; + unset($form['#redirect']); + } + //*//test echo '########################################################################################'.'
'; + if (isset($component['children']) && is_array($component['children'])) { $microweight = 0.001; foreach ($component['children'] as $scid => $subcomponent) { @@ -1420,7 +1603,7 @@ function webform_client_form_submit($for $session_key = 'webform_form_'. $node->nid; // Check for a multi-page form that is not yet complete. - if ($form_values['op'] != (empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'])) { + if ( ($form_values['op'] != (empty($node->webform['submit_text']) ? t('Submit') : $node->webform['submit_text'])) && ($form_values['op'] != t('Save Draft')) ) { // This is a multi-page form that is not yet complete. // Save the order of the current post into a copied array. $original_post = is_array($_POST['submitted']) ? $_POST['submitted'] : array(); @@ -1495,19 +1678,27 @@ function webform_client_form_submit($for eval("?>". $node->webform['additional_submit']); } + // Check if user is submitting as a draft + $is_draft = ($node->webform['allow_draft'] && $form_values['op'] == t('Save Draft')) ? 1 : 0; + // Save the submission to the database. if (!$form_values['details']['sid']) { // No sid was found thus insert it in the datatabase. - $form_values['details']['sid'] = webform_submission_insert($node, $form_values['submitted']); + $form_values['details']['sid'] = webform_submission_insert($node, $form_values['submitted'], $is_draft); $form_values['details']['is_new'] = TRUE; } else { // Sid was found thus update the existing sid in the datatbase. - webform_submission_update($node, $form_values['details']['sid'], $form_values['submitted']); + webform_submission_update($node, $form_values['details']['sid'], $form_values['submitted'], $is_draft); $form_values['details']['is_new'] = FALSE; } $sid = $form_values['details']['sid']; + + // If saving a draft, return redirect to confirmation page (no email processing). + if ($node->webform['allow_draft'] && $form_values['op'] == t('Save Draft')) { + return array('node/'. $node->nid .'/draft_saved', 'sid='. $sid); //should this be further down in case the form is sending an email, so it doesnt return value too early before it does that? + } // Check if this form is sending an email. if ((!empty($node->webform['email']) || !empty($node->webform['additional_emails'])) && $form_values['details']['is_new']) { @@ -1639,7 +1830,7 @@ function _webform_client_form_submit_pro if (is_array($form_values)) { foreach ($form_values as $form_key => $value) { $cid = webform_get_cid($node, $form_key, $parent); - if (is_array($value) && $node->webform['components'][$cid]['type'] == 'fieldset') { + if ($cid && is_array($value) && $node->webform['components'][$cid]['type'] == 'fieldset') {//also should other similar line be updated in _webform_client_form_submit_flatten? _webform_client_form_submit_process($node, $form_values[$form_key], $cid); } } @@ -1651,7 +1842,7 @@ function _webform_client_form_submit_pro if ($component['pid'] == $parent) { $submit_function = "_webform_submit_". $component['type']; if (function_exists($submit_function)) { - $submit_function($form_values[$component['form_key']], $component); // Call the component process submission function. + $submit_function($form_values[$component['form_key']], $component, $node); // Call the component process submission function. } } } @@ -1664,8 +1855,8 @@ function _webform_client_form_submit_fla if (is_array($fieldset)) { foreach ($fieldset as $form_key => $value) { $cid = webform_get_cid($node, $form_key, $parent); - - if (is_array($value) && $node->webform['components'][$cid]['type'] == 'fieldset') { + + if (is_array($value) && $node->webform['components'][$cid]['type'] == 'fieldset') {//MAYBE CHANGE if cid needed? like similar line in _webform_client_form_submit_process? _webform_client_form_submit_flatten($node, $value, $form, $cid); unset($form[$form_key]); unset($form[$cid]); @@ -1673,7 +1864,9 @@ function _webform_client_form_submit_fla else { // The order here is significant! unset($form[$form_key]); - $form[$cid] = $value; + if ($cid) { + $form[$cid] = $value; + } } } } @@ -1713,6 +1906,47 @@ function theme_webform_confirmation($nod } /** + * Prints the confirmation message after a successful draft submission. + */ +function _webform_draft_confirmation($nid) { + if ($node = node_load($nid)) { + if (node_access('view', $node)) { + drupal_set_title($node->title); + drupal_set_message(t('Draft saved.')); + return theme('webform_draft_confirmation', $node); + } + else { + return drupal_access_denied(); + } + } +} + +/** + * Themable function for webform draft confirmation + */ +function theme_webform_draft_confirmation($node) { + $node->body = check_markup('Your draft has been successfully saved. ', $node->format, FALSE); + $node->links['webform_back'] = array( + 'href' => 'node/'. $node->nid, + 'title' => t('Go back to the form'), + ); + return theme('node', $node, FALSE, TRUE); +} + +/** + * Check if current user has a draft of this webform, and return the sid. + */ +function _webform_fetch_draft_sid($nid, $uid) { + $query = 'SELECT sid FROM {webform_submissions} WHERE nid = %d AND uid = %d AND is_draft = 1 ORDER BY submitted DESC'; + $res = db_query($query, $nid, $uid); + $row = db_fetch_array($res); + if (isset($row['sid'])) { + return (int) $row['sid']; + } + return FALSE; +} + +/** * Theme the contents of e-mails sent by webform. * * @param $form_values @@ -1914,7 +2148,8 @@ function _webform_filter_values($string, } if ($strict) { - return filter_xss($string); + $allowed_tags = array('a', 'em', 'strong', 'cite', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'div', 'b', 'i', 'span' ); //allowed tags ADDED so i can get my popup footnotes to show up + return filter_xss($string, $allowed_tags); } else { return $string; @@ -1925,7 +2160,7 @@ function _webform_filter_values($string, * Filters all special tokens provided by webform, and allows basic layout in descriptions. */ function _webform_filter_descriptions($string, $node = NULL, $submission = NULL, $strict = TRUE) { - return check_markup(_webform_filter_values($string, $node = NULL, $submission = NULL, $strict = TRUE)); + return check_markup(_webform_filter_values($string, $node = NULL, $submission = NULL, $strict = TRUE), 3, FALSE); //ADDED input format and dont check to see if role allowed to access that filter } /** @@ -2092,7 +2327,21 @@ function _webform_component_options($com * Convert an array of components into a tree */ function _webform_components_tree_build($src, &$tree, $parent, &$page_count) { - foreach ($src as $cid => $component) { + + global $addedRequiredJSField; + $addedRequiredJSField[] = array(); + + foreach ($src as $cid => $component) { + //not sure how to make this run once for the required field, hence my hackish check here and in javascript, this runs before _webform_client_form_add_component (where #required may get unset) so we are good i think adding this here, could be optimized and placed somewhere else maybe? + if( (!in_array($component['form_key'], $addedRequiredJSField)) && ($component['mandatory']== 1))//this is for file required fields... since drupal doesnt set required * for it since we use non-drupal required-ness validation and also for when saving, we unset required field so that we can save, but then the * wont show for other fields so need to check for that + { + $addedRequiredJSField[] = $component['form_key']; + drupal_add_js("$(document).ready(function(){ + if( $('#webform-component-". $component['form_key'] ." label span.form-required').length == 0 )// if * doesnt exist for this required field, then add it + $('#webform-component-". $component['form_key'] ." label').append('*');//think this hack is fine cause it catches file fields and adds * for them and also for scenario when saving, it unchecks other fields #required so drupal validation on those does not occur, but possibly file validation fails like bad filename, so still want the * to show up for those fields that we unset the #required attribute for to indicate the field is required should he fix his mistake and want to submit. + });", "inline"); + } + if ($component['pid'] == $parent) { _webform_components_tree_build($src, $component, $cid, $page_count); $tree['children'][$cid] = $component; diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform_report.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform_report.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform_report.inc 2008-06-07 23:01:42.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform_report.inc 2008-07-02 16:00:42.546250000 -0400 @@ -61,10 +61,11 @@ function theme_webform_results_submissio $header = theme('webform_results_submissions_header', $node); $rows = array(); - foreach ($submissions as $sid => $submission) { + foreach ($submissions as $sid => $submission) { + $row = array( $sid, - format_date($submission->submitted, 'small'), + format_date($submission->submitted, 'small'). (($submission->is_draft) ? ' (Saved, not Submitted)':''), ); if (user_access('access webform results')) { $row[] = theme('username', $submission); @@ -137,7 +138,7 @@ function theme_webform_results_table($no // Generate a row for each submission. foreach ($submissions as $sid => $submission) { $cell[] = l($sid, 'node/'. $node->nid .'/submission/'. $sid); - $cell[] = format_date($submission->submitted, "small"); + $cell[] = format_date($submission->submitted, "small"). (($submission->is_draft) ? ' (Saved, not Submitted)':''); $cell[] = theme('username', $submission); $cell[] = $submission->remote_addr; $component_headers = array(); diff -urp --strip-trailing-cr /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform_submissions.inc /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform_submissions.inc --- /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/backup webform changes/old/webform/webform_submissions.inc 2008-06-07 23:01:42.000000000 -0400 +++ /cygdrive/c/Program Files/Apache Group/Apache2/htdocs/drupaltest/sites/all/modules/webformModified/webform_submissions.inc 2008-07-17 18:32:27.118125000 -0400 @@ -23,18 +23,51 @@ function webform_submission_access($node } } -function webform_submission_update($node, $sid, $submitted) { - // Update the submission data by first removing all this submissions data. - db_query("DELETE FROM {webform_submitted_data} WHERE sid = %d", $sid); +function webform_submission_update($node, $sid, $submitted, $is_draft = 0) { + global $user; + + db_query("DELETE FROM {webform_submissions} WHERE sid = %d", $sid);//removes previous 'saved' submission id and creates new one below + db_query("INSERT INTO {webform_submissions} (nid, sid, uid, submitted, remote_addr, is_draft) "." VALUES (%d, %d, %d, %d, '%s', %d)", $node->nid, $sid, $user->uid, time(), $_SERVER['REMOTE_ADDR'], $is_draft); + + // If is draft, only delete data for components submitted, to preserve any data from form pages not visited in this submission. + //if ($is_draft) //take this out possibly, only update needed componants whether hit save draft or submitting + //{ + $_submitted_cids = array(); + foreach ($submitted as $cid => $value) + { + + //only delete so can insert new filename if new data submitted + if( ($node->webform['components'][$cid]['type'] == 'file') ) + { + if( ! empty($_FILES['files']['name'][ $node->webform['components'][$cid]['form_key'] ]) )//if not empty replace old data + { + $_submitted_cids[$cid] = $value; + } + } + else + $_submitted_cids[$cid] = $value; + + //drupal_set_message( $node->webform['components'][$cid] .' '. $node->webform['components'][$cid]['form_key'] .', '. print_r($_submitted_cids,1) ); + } + + if( count($_submitted_cids) > 0 )//if just 1 fileupload question and resaving and didnt submit a new file, submitted_cids array will be empty + db_query("DELETE FROM {webform_submitted_data} WHERE sid = %d AND cid IN (" . implode(', ', array_keys($_submitted_cids) ) . ")", $sid); + //else//still deletes old data if submitting, but have an old file? CHECK THIS!!! + //db_query("DELETE FROM {webform_submitted_data} WHERE sid = %d", $sid); + + //} + + // Then re-add it to the database. - foreach ($submitted as $cid => $value) { + foreach ($_submitted_cids as $cid => $value) { + // Don't save pagebreaks as submitted data. if ($node->webform['components'][$cid]['type'] == 'pagebreak') { continue; } if (is_array($value)) { - $delta = 0; + $delta = 0;//array of values being inserted like for multiple select boxes? i think 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++; @@ -48,12 +81,16 @@ function webform_submission_update($node return $sid; } -function webform_submission_insert($node, $submitted) { +function webform_submission_insert($node, $submitted, $is_draft = 0) { global $user; - + global $sidToInsert; + + if( isset($sidToInsert) ) + $sid = $sidToInsert; //set via file.inc maybe come up with better file saving scheme, like save to /$nid then moving all files submitted in this submission to /$sid after save + else $sid = db_next_id('{webform_submissions}_sid'); - db_query("INSERT INTO {webform_submissions} (nid, sid, uid, submitted, remote_addr) "." VALUES (%d, %d, %d, %d, '%s')", $node->nid, $sid, $user->uid, time(), $_SERVER['REMOTE_ADDR']); + db_query("INSERT INTO {webform_submissions} (nid, sid, uid, submitted, remote_addr, is_draft) "." VALUES (%d, %d, %d, %d, '%s', %d)", $node->nid, $sid, $user->uid, time(), $_SERVER['REMOTE_ADDR'], $is_draft); foreach ($submitted as $cid => $value) { // Don't save pagebreaks as submitted data. @@ -64,6 +101,7 @@ function webform_submission_insert($node 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++; } @@ -165,6 +203,7 @@ function webform_get_submissions($nid, $ $submissions[$row->sid]->uid = $row->uid; $submissions[$row->sid]->name = $row->name; $submissions[$row->sid]->status = $row->status; + $submissions[$row->sid]->is_draft = $row->is_draft; } $submissions[$row->sid]->data[$row->cid]['value'][$row->no] = $row->data; $previous = $row->sid; @@ -193,7 +232,8 @@ function webform_get_submission($nid, $s $submission->uid = $row->uid; $submission->remote_addr = $row->remote_addr; $submission->submitted = $row->submitted; - + $submission->is_draft = $row->is_draft; + while ($row) { $submission->data[$row->cid]['value'][$row->no] = $row->data; $row = db_fetch_object($result); @@ -226,6 +266,7 @@ function _webform_submission_spam_check( function _webform_submission_limit_check($node) { global $user, $db_type; + // Check if submission limiting is enabled. if ($node->webform['submit_limit'] == '-1') { return FALSE; // No check enabled. @@ -235,8 +276,7 @@ function _webform_submission_limit_check $query = "SELECT submitted, uid, remote_addr ". "FROM {webform_submissions} ". "WHERE (( 0 = %d AND remote_addr = '%s') OR uid = %d )". - "AND submitted > %d AND nid = %d"; - + "AND submitted > %d AND nid = %d AND is_draft = false"; // Fetch all the entries from the database within the submit interval with this username and IP. $result = db_query($query, $user->uid, $_SERVER['REMOTE_ADDR'], $user->uid, ($node->webform['submit_interval'] != -1) ? (time() - $node->webform['submit_interval']) : $node->webform['submit_interval'], $node->nid); $num_submissions_database = db_num_rows($result);