[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/webform/includes/ -> webform.submissions.inc (source)

   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  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7