| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: webform.submissions.inc,v 1.18.2.12 2010/09/08 05:23:47 quicksketch Exp $ 3 4 /** 5 * @file 6 * This file is loaded when handling submissions, either submitting new, 7 * editing, or viewing. It also contains all CRUD functions for submissions. 8 * 9 * @author Nathan Haug <nate@lullabot.com> 10 */ 11 12 /** 13 * Given an array of submitted values, flatten it into data for a submission. 14 */ 15 function webform_submission_data($node, $submitted) { 16 $data = array(); 17 18 foreach ($submitted as $cid => $values) { 19 // Don't save pagebreaks as submitted data. 20 if ($node->webform['components'][$cid]['type'] == 'pagebreak') { 21 continue; 22 } 23 24 if (is_array($values)) { 25 $data[$cid]['value'] = $values; 26 } 27 else { 28 $data[$cid]['value'][0] = $values; 29 } 30 } 31 32 return $data; 33 } 34 35 function webform_submission_update($node, $submission) { 36 // Allow other modules to modify the submission before saving. 37 foreach (module_implements('webform_submission_presave') as $module) { 38 $function = $module . '_webform_submission_presave'; 39 $function($node, $submission); 40 } 41 42 // Update the main submission info. 43 $result = db_query("UPDATE {webform_submissions} SET uid = %d, submitted = %d, remote_addr = '%s', is_draft = %d WHERE sid = %d", $submission->uid, $submission->submitted, $submission->remote_addr, $submission->is_draft, $submission->sid); 44 45 // If is draft, only delete data for components submitted, to 46 // preserve any data from form pages not visited in this submission. 47 if ($submission->is_draft) { 48 $submitted_cids = array_keys($submission->data); 49 db_query("DELETE FROM {webform_submitted_data} WHERE sid = %d AND cid IN (" . implode(', ', $submitted_cids) . ")", $submission->sid); 50 } 51 else { 52 db_query("DELETE FROM {webform_submitted_data} WHERE sid = %d", $submission->sid); 53 } 54 55 // Then re-add submission data to the database. 56 $submission->is_new = FALSE; 57 webform_submission_insert($node, $submission); 58 59 module_invoke_all('webform_submission_update', $node, $submission); 60 61 return $submission->sid; 62 } 63 64 function webform_submission_insert($node, $submission) { 65 // The submission ID may already be set if being called as an update. 66 if (!isset($submission->sid) && (!isset($submission->is_new) || $submission->is_new == FALSE)) { 67 // Allow other modules to modify the submission before saving. 68 foreach (module_implements('webform_submission_presave') as $module) { 69 $function = $module . '_webform_submission_presave'; 70 $function($node, $submission); 71 } 72 73 $result = db_query("INSERT INTO {webform_submissions} (nid, uid, submitted, remote_addr, is_draft) VALUES (%d, %d, %d, '%s', %d)", $node->nid, $submission->uid, $submission->submitted, $submission->remote_addr, $submission->is_draft); 74 $submission->sid = db_last_insert_id('webform_submissions', 'sid'); 75 $is_new = TRUE; 76 } 77 78 foreach ($submission->data as $cid => $values) { 79 foreach ($values['value'] as $delta => $value) { 80 db_query("INSERT INTO {webform_submitted_data} (nid, sid, cid, no, data) VALUES (%d, %d, %d, '%s', '%s')", $node->nid, $submission->sid, $cid, $delta, $value); 81 } 82 } 83 84 // Invoke the insert hook after saving all the data. 85 if (isset($is_new)) { 86 module_invoke_all('webform_submission_insert', $node, $submission); 87 } 88 89 return $submission->sid; 90 } 91 92 /** 93 * Delete a single submission. 94 * 95 * @param $nid 96 * ID of node for which this webform was submitted. 97 * @param $sid 98 * ID of submission to be deleted (from webform_submitted_data). 99 */ 100 function webform_submission_delete($node, $submission) { 101 // Iterate through all components and let each do cleanup if necessary. 102 foreach ($node->webform['components'] as $cid => $component) { 103 if (isset($submission->data[$cid])) { 104 webform_component_invoke($component['type'], 'delete', $component, $submission->data[$cid]['value']); 105 } 106 } 107 108 // Delete any anonymous session information. 109 if (isset($_SESSION['webform_submission'][$submission->sid])) { 110 unset($_SESSION['webform_submission'][$submission->sid]); 111 } 112 113 db_query('DELETE FROM {webform_submitted_data} WHERE nid = %d AND sid = %d', $node->nid, $submission->sid); 114 db_query('DELETE FROM {webform_submissions} WHERE nid = %d AND sid = %d', $node->nid, $submission->sid); 115 116 module_invoke_all('webform_submission_delete', $node, $submission); 117 } 118 119 /** 120 * Confirm form to delete a single form submission. 121 * 122 * @param $form_state 123 * The current form state. 124 * @param $node 125 * The node for which this webform was submitted. 126 * @param $submission 127 * The submission to be deleted (from webform_submitted_data). 128 */ 129 function webform_submission_delete_form($form_state, $node, $submission) { 130 webform_set_breadcrumb($node, $submission); 131 132 // Keep the NID and SID in the same location as the webform_client_form(). 133 // This helps mollom identify the same fields when deleting a submission. 134 $form['#tree'] = TRUE; 135 $form['details']['nid'] = array( 136 '#type' => 'value', 137 '#value' => $node->nid, 138 ); 139 $form['details']['sid'] = array( 140 '#type' => 'value', 141 '#value' => $submission->sid, 142 ); 143 144 $question = t('Are you sure you want to delete this submission?'); 145 146 if (isset($_GET['destination'])) { 147 $destination = $_GET['destination']; 148 } 149 elseif (webform_results_access($node)) { 150 $destination = 'node/' . $node->nid . '/webform-results'; 151 } 152 else { 153 $destination = 'node/' . $node->nid . '/submissions'; 154 } 155 156 return confirm_form($form, NULL, $destination, $question, t('Delete'), t('Cancel')); 157 } 158 159 function webform_submission_delete_form_submit($form, &$form_state) { 160 $node = node_load($form_state['values']['details']['nid']); 161 $submission = webform_get_submission($form_state['values']['details']['nid'], $form_state['values']['details']['sid']); 162 webform_submission_delete($node, $submission); 163 drupal_set_message(t('Submission deleted.')); 164 165 $form_state['redirect'] = 'node/' . $node->nid . '/webform-results'; 166 } 167 168 /** 169 * Menu title callback; Return the submission number as a title. 170 */ 171 function webform_submission_title($node, $submission) { 172 return t('Submission #@sid', array('@sid' => $submission->sid)); 173 } 174 175 /** 176 * Menu callback; Present a Webform submission page for display or editing. 177 */ 178 function webform_submission_page($node, $submission, $format) { 179 global $user; 180 webform_set_breadcrumb($node, $submission); 181 182 if ($format == 'form') { 183 $output = drupal_get_form('webform_client_form_' . $node->nid, $node, $submission); 184 } 185 else { 186 $output = webform_submission_render($node, $submission, NULL, $format); 187 } 188 189 // Determine the mode in which we're displaying this submission. 190 $mode = ($format != 'form') ? 'display' : 'form'; 191 if (preg_match("!^q=print/!", $_SERVER['QUERY_STRING'])) { 192 $mode = 'print'; 193 } 194 if (preg_match("!^q=printpdf/!", $_SERVER['QUERY_STRING'])) { 195 $mode = 'pdf'; 196 } 197 198 // Add navigation for administrators. 199 if (webform_results_access($node)) { 200 $navigation = ($mode != 'pdf') ? theme('webform_submission_navigation', $node, $submission, $mode) : NULL; 201 $information = theme('webform_submission_information', $node, $submission); 202 } 203 else { 204 $navigation = NULL; 205 $information = NULL; 206 } 207 208 // Disable the page cache for anonymous users viewing or editing submissions. 209 if (!$user->uid) { 210 webform_disable_page_cache(); 211 } 212 213 return theme('webform_submission_page', $node, $submission, $output, $navigation, $information); 214 } 215 216 /** 217 * Print a Webform submission for display on a page or in an e-mail. 218 */ 219 function webform_submission_render($node, $submission, $email, $format) { 220 $component_tree = array(); 221 $renderable = array(); 222 $page_count = 1; 223 $excluded_components = isset($email) ? $email['excluded_components'] : array(); 224 225 // Meta data that may be useful for modules implementing 226 // hook_webform_submission_render_alter(). 227 $renderable['#node'] = $node; 228 $renderable['#submission'] = $submission; 229 $renderable['#email'] = $email; 230 $renderable['#format'] = $format; 231 232 // Set the theme function for submissions. 233 $renderable['#theme'] = array('webform_submission_' . $node->nid, 'webform_submission'); 234 235 _webform_components_tree_build($node->webform['components'], $component_tree, 0, $page_count); 236 237 // Recursively add components to the form. 238 foreach ($component_tree['children'] as $cid => $component) { 239 if (!in_array($cid, $excluded_components) && _webform_client_form_rule_check($node, $component, $component['page_num'], NULL, $submission)) { 240 _webform_client_form_add_component($node, $component, NULL, $renderable, $renderable, NULL, $submission, $format); 241 } 242 } 243 244 drupal_alter('webform_submission_render', $renderable); 245 return drupal_render($renderable); 246 } 247 248 /** 249 * Return all the submissions for a particular node. 250 * 251 * @param $filters 252 * An array of filters to apply to this query. Usually in the format 253 * array('nid' => $nid, 'uid' => $uid). A single integer may also be passed 254 * in, which will be equivalent to specifying a $nid filter. 255 * @param $header 256 * If the results of this fetch will be used in a sortable 257 * table, pass the array header of the table. 258 * @param $pager_count 259 * Optional. The number of submissions to include in the results. 260 */ 261 function webform_get_submissions($filters = array(), $header = NULL, $pager_count = 0) { 262 $submissions = array(); 263 264 if (!is_array($filters)) { 265 $filters = array('nid' => $filters); 266 } 267 268 // UID filters need to be against a specific table. 269 if (isset($filters['uid'])) { 270 $filters['u.uid'] = $filters['uid']; 271 unset($filters['uid']); 272 } 273 274 // No need to find SIDs if it was given to us. 275 if (isset($filters['sid'])) { 276 $sids = array($filters['sid']); 277 } 278 // Build the list of SIDs that need to be retrieved. 279 else { 280 $arguments = array_values($filters); 281 $where = array(); 282 foreach ($filters as $column => $value) { 283 $where[] = $column . ' = ' . (is_numeric($value) ? '%d' : "'%s'"); 284 } 285 286 if (isset($filters['uid']) && $filters['uid'] === 0 && isset($_SESSION['webform_submission'])) { 287 $anonymous_sids = array_keys($_SESSION['webform_submission']); 288 if (count($anonymous_sids)) { 289 $placeholders = array_fill(0, count($anonymous_sids), "%d"); 290 $where[] = 'sid IN (' . implode(',', $placeholders) . ')'; 291 $arguments = array_merge($arguments, $anonymous_sids); 292 } 293 } 294 295 $where_clause = implode(' AND ', $where); 296 $pager_query = 'SELECT sid FROM {webform_submissions} s LEFT JOIN {users} u ON u.uid = s.uid WHERE ' . $where_clause; 297 298 if (is_array($header)) { 299 $pager_query .= tablesort_sql($header); 300 } 301 else { 302 $pager_query .= ' ORDER BY sid ASC'; 303 } 304 305 if ($pager_count) { 306 $result = pager_query($pager_query, $pager_count, 0, NULL, $arguments); 307 } 308 else { 309 $result = db_query($pager_query, $arguments); 310 } 311 312 $sids = array(); 313 while ($row = db_fetch_object($result)) { 314 $sids[] = $row->sid; 315 $submissions[$row->sid] = FALSE; 316 } 317 } 318 319 // If there are no submissions being retrieved, return an empty array. 320 if (empty($sids)) { 321 return $submissions; 322 } 323 324 // Query the required submission data. 325 $query = 'SELECT s.*, sd.cid, sd.no, sd.data, u.name, u.mail, u.status ' . 326 'FROM {webform_submissions} s ' . 327 'LEFT JOIN {webform_submitted_data} sd ON sd.sid = s.sid ' . 328 'LEFT JOIN {users} u ON u.uid = s.uid ' . 329 'WHERE s.sid IN (' . implode($sids, ',') . ') ' . 330 'ORDER BY sd.sid ASC, sd.cid ASC, sd.no ASC'; 331 332 $result = db_query($query); 333 334 // Convert the queried rows into submissions. 335 $previous = array(); 336 while ($row = db_fetch_object($result)) { 337 if ($row->sid != $previous) { 338 $submissions[$row->sid] = new stdClass(); 339 $submissions[$row->sid]->sid = $row->sid; 340 $submissions[$row->sid]->nid = $row->nid; 341 $submissions[$row->sid]->submitted = $row->submitted; 342 $submissions[$row->sid]->remote_addr = $row->remote_addr; 343 $submissions[$row->sid]->uid = $row->uid; 344 $submissions[$row->sid]->name = $row->name; 345 $submissions[$row->sid]->is_draft = $row->is_draft; 346 } 347 $submissions[$row->sid]->data[$row->cid]['value'][$row->no] = $row->data; 348 $previous = $row->sid; 349 } 350 351 foreach (module_implements('webform_submission_load') as $module) { 352 $function = $module . '_webform_submission_load'; 353 $function($submissions); 354 } 355 356 return $submissions; 357 } 358 359 /** 360 * Return a count of the total number of submissions for a node. 361 * 362 * @param $nid 363 * The node ID for which submissions are being fetched. 364 * @param $uid 365 * Optional; the user ID to filter the submissions by. 366 * @return 367 * An integer value of the number of submissions. 368 */ 369 function webform_get_submission_count($nid, $uid = NULL, $reset = FALSE) { 370 static $counts; 371 372 if (!isset($counts[$nid][$uid]) || $reset) { 373 $query = 'SELECT count(*) FROM {webform_submissions} WHERE nid = %d'; 374 $arguments = array($nid); 375 if ($uid !== NULL) { 376 $query .= ' AND uid = %d'; 377 $arguments[] = $uid; 378 } 379 if ($uid === 0) { 380 $submissions = isset($_SESSION['webform_submission']) ? $_SESSION['webform_submission'] : array(); 381 $placeholders = count($submissions) ? array_fill(0, count($submissions), "%d") : array(); 382 $query .= count($submissions) ? ' AND sid IN (' . implode(',', $placeholders) . ')' : ' AND sid = 0'; 383 $arguments = array_merge($arguments, array_keys($submissions)); 384 } 385 386 $counts[$nid][$uid] = db_result(db_query($query, $arguments)); 387 } 388 return $counts[$nid][$uid]; 389 } 390 391 /** 392 * Fetch a specified submission for a webform node. 393 */ 394 function webform_get_submission($nid, $sid, $reset = FALSE) { 395 static $submissions = array(); 396 397 if ($reset) { 398 $submissions = array(); 399 if (!isset($sid)) { 400 return; 401 } 402 } 403 404 // Load the submission if needed. 405 if (!isset($submissions[$sid])) { 406 $new_submissions = webform_get_submissions(array('sid' => $sid)); 407 $submissions[$sid] = $new_submissions[$sid]; 408 } 409 410 // Ensure that the requested NID matches the submission NID. 411 if ($submissions[$sid]->nid != $nid) { 412 return FALSE; 413 } 414 415 return $submissions[$sid]; 416 } 417 418 function _webform_submission_spam_check($to, $subject, $from, $headers = array()) { 419 $headers = implode('\n', (array)$headers); 420 // Check if they are attempting to spam using a bcc or content type hack. 421 if (preg_match('/(b?cc\s?:)|(content\-type:)/i', $to . "\n" . $subject . "\n" . $from . "\n" . $headers)) { 422 return TRUE; // Possible spam attempt. 423 } 424 return FALSE; // Not spam. 425 } 426 427 /** 428 * Check if the current user has exceeded the limit on this form. 429 * 430 * @param $node 431 * The webform node to be checked. 432 * @return 433 * Boolean TRUE if the user has exceeded their limit. FALSE otherwise. 434 */ 435 function _webform_submission_limit_check($node) { 436 global $user; 437 438 // Check if submission limiting is enabled. 439 if ($node->webform['submit_limit'] == '-1') { 440 return FALSE; // No check enabled. 441 } 442 443 // Retrieve submission data for this IP address or username from the database. 444 $query = 'SELECT count(*) ' . 445 'FROM {webform_submissions} ' . 446 "WHERE (( 0 = %d AND remote_addr = '%s') OR (uid > 0 AND uid = %d)) " . 447 'AND submitted > %d AND nid = %d AND is_draft = 0'; 448 449 // Fetch all the entries from the database within the submit interval with this username and IP. 450 $num_submissions_database = db_result(db_query($query, $user->uid, ip_address(), $user->uid, ($node->webform['submit_interval'] != -1) ? (time() - $node->webform['submit_interval']) : $node->webform['submit_interval'], $node->nid)); 451 452 // Double check the submission history from the users machine using cookies. 453 $num_submissions_cookie = 0; 454 if ($user->uid == 0 && variable_get('webform_use_cookies', 0)) { 455 $cookie_name = 'webform-' . $node->nid; 456 457 if (isset($_COOKIE[$cookie_name]) && is_array($_COOKIE[$cookie_name])) { 458 foreach ($_COOKIE[$cookie_name] as $key => $timestamp) { 459 if ($node->webform['submit_interval'] != -1 && $timestamp <= time() - $node->webform['submit_interval']) { 460 // Remove the cookie if past the required time interval. 461 setcookie($cookie_name . '[' . $key . ']', '', 0); 462 } 463 } 464 // Count the number of submissions recorded in cookies. 465 $num_submissions_cookie = count($_COOKIE[$cookie_name]); 466 } 467 else { 468 $num_submissions_cookie = 0; 469 } 470 } 471 472 if ($num_submissions_database >= $node->webform['submit_limit'] || $num_submissions_cookie >= $node->webform['submit_limit']) { 473 // Limit exceeded. 474 return TRUE; 475 } 476 477 // Limit not exceeded. 478 return FALSE; 479 } 480 481 /** 482 * Preprocess function for webform-submission.tpl.php. 483 */ 484 function template_preprocess_webform_submission(&$vars) { 485 $vars['node'] = $vars['renderable']['#node']; 486 $vars['submission'] = $vars['renderable']['#submission']; 487 $vars['email'] = $vars['renderable']['#email']; 488 $vars['format'] = $vars['renderable']['#format']; 489 } 490 491 /** 492 * Preprocess function for webform-submission-navigation.tpl.php. 493 */ 494 function template_preprocess_webform_submission_navigation(&$vars) { 495 $start_path = ($vars['mode'] == 'print') ? 'print/' : 'node/'; 496 $vars['previous'] = db_result(db_query('SELECT MAX(sid) FROM {webform_submissions} WHERE nid = %d AND sid < %d', array($vars['node']->nid, $vars['submission']->sid))); 497 $vars['next'] = db_result(db_query('SELECT MIN(sid) FROM {webform_submissions} WHERE nid = %d AND sid > %d', array($vars['node']->nid, $vars['submission']->sid))); 498 $vars['previous_url'] = $start_path . $vars['node']->nid . '/submission/' . $vars['previous'] . ($vars['mode'] == 'form' ? '/edit' : ''); 499 $vars['next_url'] = $start_path . $vars['node']->nid . '/submission/' . $vars['next'] . ($vars['mode'] == 'form' ? '/edit' : ''); 500 } 501 502 /** 503 * Preprocess function for webform-submission-navigation.tpl.php. 504 */ 505 function template_preprocess_webform_submission_information(&$vars) { 506 $vars['account'] = user_load($vars['submission']->uid); 507 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |