| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @file 5 * This file includes helper functions for creating reports for webform.module 6 * 7 * @author Nathan Haug <nate@lullabot.com> 8 */ 9 10 // All functions within this file need the webform.submissions.inc. 11 module_load_include('inc', 'webform', 'includes/webform.submissions'); 12 13 /** 14 * Retrieve lists of submissions for a given webform. 15 */ 16 function webform_results_submissions($node, $user_filter, $pager_count) { 17 global $user; 18 19 if (isset($_GET['results']) && is_numeric($_GET['results'])) { 20 $pager_count = $_GET['results']; 21 } 22 23 $header = theme('webform_results_submissions_header', $node); 24 if ($user_filter) { 25 if ($user->uid) { 26 drupal_set_title(t('Submissions for %user', array('%user' => $user->name))); 27 } 28 else { 29 drupal_set_title(t('Your submissions')); 30 webform_disable_page_cache(); 31 } 32 webform_set_breadcrumb($node); 33 $submissions = webform_get_submissions(array('nid' => $node->nid, 'uid' => $user->uid), $header, $pager_count); 34 $count = webform_get_submission_count($node->nid, $user->uid); 35 } 36 else { 37 $submissions = webform_get_submissions($node->nid, $header, $pager_count); 38 $count = webform_get_submission_count($node->nid); 39 } 40 41 $operation_column = end($header); 42 $operation_total = $operation_column['colspan']; 43 44 $rows = array(); 45 foreach ($submissions as $sid => $submission) { 46 $row = array( 47 $submission->is_draft ? t('@sid (draft)', array('@sid' => $sid)) : $sid, 48 format_date($submission->submitted, 'small'), 49 ); 50 if (webform_results_access($node, $user)) { 51 $row[] = theme('username', $submission); 52 $row[] = $submission->remote_addr; 53 } 54 $row[] = l(t('View'), "node/$node->nid/submission/$sid"); 55 $operation_count = 1; 56 // No need to call this multiple times, just reference this in a variable. 57 $destination = drupal_get_destination(); 58 if (webform_submission_access($node, $submission, 'edit', $user)) { 59 $row[] = l(t('Edit'), "node/$node->nid/submission/$sid/edit", array('query' => $destination)); 60 $operation_count++; 61 } 62 if (webform_submission_access($node, $submission, 'delete', $user)) { 63 $row[] = l(t('Delete'), "node/$node->nid/submission/$sid/delete", array('query' => $destination)); 64 $operation_count++; 65 } 66 if ($operation_count < $operation_total) { 67 $row[count($row) - 1] = array('data' => $row[count($row) - 1], 'colspan' => $operation_total - $operation_count + 1); 68 } 69 $rows[] = $row; 70 } 71 72 $element['#theme'] = 'webform_results_submissions'; 73 $element['#node'] = $node; 74 $element['#submissions'] = $submissions; 75 $element['#total_count'] = $count; 76 $element['#pager_count'] = $pager_count; 77 78 $element['table']['#theme'] = 'table'; 79 $element['table']['#header'] = $header; 80 $element['table']['#rows'] = $rows; 81 $element['table']['#operation_total'] = $operation_total; 82 83 return drupal_render($element); 84 } 85 86 /** 87 * Theme the list of links for selecting the number of results per page. 88 * 89 * @param $total_count 90 * The total number of results available. 91 * @param $pager_count 92 * The current number of results displayed per page. 93 */ 94 function theme_webform_results_per_page($total_count, $pager_count) { 95 $output = ''; 96 97 // Create a list of results-per-page options. 98 $counts = array( 99 '20' => '20', 100 '50' => '50', 101 '100' => '100', 102 '200' => '200', 103 '500' => '500', 104 '1000' => '1000', 105 '0' => t('All'), 106 ); 107 108 $count_links = array(); 109 110 foreach ($counts as $number => $text) { 111 if ($number < $total_count) { 112 $count_links[] = l($text, $_GET['q'], array('query' => 'results=' . $number, 'attributes' => array('class' => $pager_count == $number ? 'selected' : ''))); 113 } 114 } 115 116 $output .= '<div class="webform-results-per-page">'; 117 if (count($count_links) > 1) { 118 $output .= t('Show !count results per page.', array('!count' => implode(' | ', $count_links))); 119 } 120 else { 121 $output .= t('Showing all results.'); 122 } 123 if ($total_count > 1) { 124 $output .= ' ' . t('@total results total.', array('@total' => $total_count)); 125 } 126 $output .= '</div>'; 127 128 return $output; 129 } 130 131 /** 132 * Theme the header of the submissions table. 133 * 134 * This is done in it's own function so that webform can retrieve the header and 135 * use it for sorting the results. 136 */ 137 function theme_webform_results_submissions_header($node) { 138 $columns = array( 139 array('data' => t('#'), 'field' => 'sid', 'sort' => 'desc'), 140 array('data' => t('Submitted'), 'field' => 'submitted'), 141 ); 142 if (webform_results_access($node)) { 143 $columns[] = array('data' => t('User'), 'field' => 'name'); 144 $columns[] = array('data' => t('IP Address'), 'field' => 'remote_addr'); 145 } 146 $columns[] = array('data' => t('Operations'), 'colspan' => module_exists('print') ? 5 : 3); 147 148 return $columns; 149 } 150 151 /** 152 * Preprocess function for webform-results-submissions.tpl.php 153 */ 154 function template_preprocess_webform_results_submissions(&$vars) { 155 $vars['node'] = $vars['element']['#node']; 156 $vars['submissions'] = $vars['element']['#submissions']; 157 $vars['table'] = $vars['element']['table']; 158 $vars['total_count'] = $vars['element']['#total_count']; 159 $vars['pager_count'] = $vars['element']['#pager_count']; 160 $vars['is_submissions'] = (arg(2) == 'submissions')? 1 : 0; 161 162 unset($vars['element']); 163 } 164 165 /** 166 * Create a table containing all submitted values for a webform node. 167 */ 168 function webform_results_table($node, $pager_count = 0) { 169 if (isset($_GET['results']) && is_numeric($_GET['results'])) { 170 $pager_count = $_GET['results']; 171 } 172 173 // Get all the submissions for the node. 174 $header = theme('webform_results_table_header', $node); 175 $submissions = webform_get_submissions($node->nid, $header, $pager_count); 176 $total_count = webform_get_submission_count($node->nid); 177 178 $output = theme('webform_results_table', $node, $node->webform['components'], $submissions, $total_count, $pager_count); 179 if ($pager_count) { 180 $output .= theme('pager', NULL, $pager_count, 0); 181 } 182 return $output; 183 } 184 185 function theme_webform_results_table_header($node) { 186 return array( 187 array('data' => t('#'), 'field' => 'sid', 'sort' => 'desc'), 188 array('data' => t('Submitted'), 'field' => 'submitted'), 189 array('data' => t('User'), 'field' => 'name'), 190 array('data' => t('IP Address'), 'field' => 'remote_addr'), 191 ); 192 } 193 194 /** 195 * Theme the results table displaying all the submissions for a particular node. 196 * 197 * @param $node 198 * The node whose results are being displayed. 199 * @param $components 200 * An associative array of the components for this webform. 201 * @param $submissions 202 * An array of all submissions for this webform. 203 * @param $total_count 204 * The total number of submissions to this webform. 205 * @param $pager_count 206 * The number of results to be shown per page. 207 */ 208 function theme_webform_results_table($node, $components, $submissions, $total_count, $pager_count) { 209 drupal_add_css(drupal_get_path('module', 'webform') . '/css/webform-admin.css', 'theme', 'all', FALSE); 210 211 $header = array(); 212 $rows = array(); 213 $cell = array(); 214 215 // This header has to be generated seperately so we can add the SQL necessary. 216 // to sort the results. 217 $header = theme('webform_results_table_header', $node); 218 219 // Generate a row for each submission. 220 foreach ($submissions as $sid => $submission) { 221 $cell[] = l($sid, 'node/' . $node->nid . '/submission/' . $sid); 222 $cell[] = format_date($submission->submitted, 'small'); 223 $cell[] = theme('username', $submission); 224 $cell[] = $submission->remote_addr; 225 $component_headers = array(); 226 227 // Generate a cell for each component. 228 foreach ($node->webform['components'] as $component) { 229 $data = isset($submission->data[$component['cid']]['value']) ? $submission->data[$component['cid']]['value'] : NULL; 230 $submission_output = webform_component_invoke($component['type'], 'table', $component, $data); 231 if ($submission_output !== NULL) { 232 $component_headers[] = check_plain($component['name']); 233 $cell[] = $submission_output; 234 } 235 } 236 237 $rows[] = $cell; 238 unset($cell); 239 } 240 if (!empty($component_headers)) { 241 $header = array_merge($header, $component_headers); 242 } 243 244 if (count($rows) == 0) { 245 $rows[] = array(array('data' => t('There are no submissions for this form. <a href="!url">View this form</a>.', array('!url' => url('node/' . $node->nid))), 'colspan' => 4)); 246 } 247 248 249 $output = ''; 250 $output .= theme('webform_results_per_page', $total_count, $pager_count); 251 $output .= theme('table', $header, $rows); 252 return $output; 253 } 254 255 /** 256 * Delete all submissions for a node. 257 * 258 * @param $nid 259 * The node id whose submissions will be deleted. 260 */ 261 function webform_results_clear($nid) { 262 $node = node_load($nid); 263 $submissions = webform_get_submissions($nid); 264 foreach ($submissions as $submission) { 265 webform_submission_delete($node, $submission); 266 } 267 } 268 269 /** 270 * Confirmation form to delete all submissions for a node. 271 * 272 * @param $nid 273 * ID of node for which to clear submissions. 274 */ 275 function webform_results_clear_form($form_state, $node) { 276 drupal_set_title(t('Clear Form Submissions')); 277 278 $form = array(); 279 $form['nid'] = array('#type' => 'value', '#value' => $node->nid); 280 $question = t('Are you sure you want to delete all submissions for this form?'); 281 282 return confirm_form($form, $question, 'node/' . $node->nid . '/webform-results', NULL, t('Clear'), t('Cancel')); 283 } 284 285 function webform_results_clear_form_submit($form, &$form_state) { 286 webform_results_clear($form_state['values']['nid']); 287 $node = node_load($form_state['values']['nid']); 288 $title = $node->title; 289 290 $message = t('Webform %title entries cleared.', array('%title' => $title)); 291 drupal_set_message($message); 292 watchdog('webform', $message); 293 $form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/webform-results'; 294 } 295 296 /** 297 * Form to configure the download of CSV files. 298 */ 299 function webform_results_download_form(&$form_state, $node) { 300 module_load_include('inc', 'webform', 'includes/webform.export'); 301 module_load_include('inc', 'webform', 'includes/webform.components'); 302 303 $form = array(); 304 305 $form['node'] = array( 306 '#type' => 'value', 307 '#value' => $node, 308 ); 309 310 $form['format'] = array( 311 '#type' => 'radios', 312 '#title' => t('Export format'), 313 '#options' => webform_export_list(), 314 '#default_value' => isset($form_state['values']['format']) ? $form_state['values']['format'] : variable_get('webform_export_format', 'delimited'), 315 ); 316 317 $form['delimiter'] = array( 318 '#type' => 'select', 319 '#title' => t('Delimited text format'), 320 '#description' => t('This is the delimiter used in the CSV/TSV file when downloading Webform results. Using tabs in the export is the most reliable method for preserving non-latin characters. You may want to change this to another character depending on the program with which you anticipate importing results.'), 321 '#default_value' => isset($form_state['values']['delimiter']) ? $form_state['values']['delimiter'] : variable_get('webform_csv_delimiter', '\t'), 322 '#options' => array( 323 ',' => t('Comma (,)'), 324 '\t' => t('Tab (\t)'), 325 ';' => t('Semicolon (;)'), 326 ':' => t('Colon (:)'), 327 '|' => t('Pipe (|)'), 328 '.' => t('Period (.)'), 329 ' ' => t('Space ( )'), 330 ), 331 ); 332 333 $form['select_options'] = array( 334 '#type' => 'fieldset', 335 '#title' => t('Select list options'), 336 '#collapsible' => TRUE, 337 '#collapsed' => TRUE, 338 ); 339 340 $form['select_options']['select_keys'] = array( 341 '#type' => 'radios', 342 '#title' => t('Select keys'), 343 '#options' => array( 344 0 => t('Full, human-readable options (values)'), 345 1 => t('Short, raw options (keys)'), 346 ), 347 '#default_value' => isset($form_state['values']['select_options']['select_keys']) ? $form_state['values']['select_options']['select_keys'] : 0, 348 '#description' => t('Choose which part of options should be displayed from key|value pairs.'), 349 ); 350 351 $form['select_options']['select_format'] = array( 352 '#type' => 'radios', 353 '#title' => t('Select list format'), 354 '#options' => array( 355 'separate' => t('Separate'), 356 'compact' => t('Compact'), 357 ), 358 '#default_value' => isset($form_state['values']['select_options']['select_format']) ? $form_state['values']['select_options']['select_format'] : 'separate', 359 '#attributes' => array('class' => 'webform-select-list-format'), 360 '#theme' => 'webform_results_download_select_format', 361 ); 362 363 $csv_components = array( 364 'info' => t('Submission information'), 365 'serial' => '-' . t('Submission Number'), 366 'sid' => '-' . t('Submission ID'), 367 'time' => '-' . t('Time'), 368 'draft' => '-' . t('Draft'), 369 'ip_address' => '-' . t('IP Address'), 370 'uid' => '-' . t('User ID'), 371 'username' => '-' . t('Username'), 372 ); 373 $csv_components += webform_component_list($node, 'csv', TRUE); 374 375 $form['components'] = array( 376 '#type' => 'select', 377 '#title' => t('Included export components'), 378 '#options' => $csv_components, 379 '#default_value' => isset($form_state['values']['components']) ? $form_state['values']['components'] : array_keys($csv_components), 380 '#multiple' => TRUE, 381 '#size' => 10, 382 '#description' => t('The selected components will be included in the export.'), 383 '#process' => array('webform_component_select'), 384 ); 385 386 $form['range'] = array( 387 '#type' => 'fieldset', 388 '#title' => t('Download range options'), 389 '#collapsible' => TRUE, 390 '#collapsed' => TRUE, 391 '#tree' => TRUE, 392 '#theme' => 'webform_results_download_range', 393 '#element_validate' => array('webform_results_download_range_validate'), 394 '#after_build' => array('webform_results_download_range_after_build'), 395 ); 396 397 $form['range']['range_type'] = array( 398 '#type' => 'radios', 399 '#options' => array( 400 'all' => t('All submissions'), 401 'new' => t('Only new submissions since your last download'), 402 'latest' => t('Only the latest'), 403 'range' => t('All submissions starting from'), 404 ), 405 '#default_value' => 'all', 406 ); 407 $form['range']['latest'] = array( 408 '#type' => 'textfield', 409 '#size' => 5, 410 '#maxlength' => 8, 411 '#default_value' => '', 412 ); 413 $form['range']['start'] = array( 414 '#type' => 'textfield', 415 '#size' => 5, 416 '#maxlength' => 8, 417 '#default_value' => '', 418 ); 419 $form['range']['end'] = array( 420 '#type' => 'textfield', 421 '#size' => 5, 422 '#maxlength' => 8, 423 '#default_value' => '', 424 '#description' => '', 425 ); 426 427 // By default results are downloaded. User can override this value if 428 // programmatically submitting this form. 429 $form['download'] = array( 430 '#type' => 'value', 431 '#default_value' => TRUE 432 ); 433 434 $form['submit'] = array( 435 '#type' => 'submit', 436 '#value' => t('Download'), 437 ); 438 439 return $form; 440 } 441 442 /** 443 * FormAPI element validate function for the range fieldset. 444 */ 445 function webform_results_download_range_validate($element, $form_state) { 446 switch ($element['range_type']['#value']) { 447 case 'latest': 448 // Download latest x submissions. 449 if ($element['latest']['#value'] == '') { 450 form_error($element['latest'], t('Latest number of submissions field is required.')); 451 } 452 else{ 453 if (!is_numeric($element['latest']['#value'])) { 454 form_error($element['latest'], t('Latest number of submissions must be numeric.')); 455 } 456 else{ 457 if ($element['latest']['#value'] <= 0) { 458 form_error($element['latest'], t('Latest number of submissions must be greater than 0.')); 459 } 460 } 461 } 462 break; 463 case 'range': 464 // Download Start-End range of submissions. 465 // Start submission number. 466 if ($element['start']['#value'] == '') { 467 form_error($element['start'], t('Start submission number is required.')); 468 } 469 else{ 470 if (!is_numeric($element['start']['#value'])) { 471 form_error($element['start'], t('Start submission number must be numeric.')); 472 } 473 else{ 474 if ($element['start']['#value'] <= 0) { 475 form_error($element['start'], t('Start submission number must be greater than 0.')); 476 } 477 } 478 } 479 // End submission number. 480 if ($element['end']['#value'] != '') { 481 if (!is_numeric($element['end']['#value'])) { 482 form_error($element['end'], t('End submission number must be numeric.')); 483 } 484 else{ 485 if ($element['end']['#value'] <= 0) { 486 form_error($element['end'], t('End submission number must be greater than 0.')); 487 } 488 else{ 489 if ($element['end']['#value'] < $element['start']['#value']) { 490 form_error($element['end'], t('End submission number may not be less than Start submission number.')); 491 } 492 } 493 } 494 } 495 break; 496 } 497 498 } 499 500 /** 501 * Validate handler for webform_results_download_form(). 502 */ 503 function webform_results_download_form_submit(&$form, &$form_state) { 504 $options = array( 505 'delimiter' => $form_state['values']['delimiter'], 506 'components' => array_keys(array_filter($form_state['values']['components'])), 507 'select_keys' => $form_state['values']['select_keys'], 508 'select_format' => $form_state['values']['select_format'], 509 'range_type' => $form_state['values']['range']['range_type'], 510 'download' => $form_state['values']['download'], 511 ); 512 513 // Retrieve the list of required SIDs. 514 if ($options['range_type'] != 'all') { 515 $options['sids'] = webform_download_sids($form_state['values']['node']->nid, $form_state['values']['range']); 516 } 517 518 $export_info = webform_results_export($form_state['values']['node'], $form_state['values']['format'], $options); 519 520 // If webform result file should be downloaded, send the file to the browser, 521 // otherwise save information about the created file in $form_state. 522 if ($options['download']) { 523 webform_results_download($form_state['values']['node'], $export_info); 524 } 525 else { 526 $form_state['export_info'] = $export_info; 527 } 528 } 529 530 /** 531 * FormAPI after build function for the download range fieldset. 532 */ 533 function webform_results_download_range_after_build($element, &$form_state) { 534 $node = $form_state['values']['node']; 535 536 // Build a list of counts of new and total submissions. 537 $count = webform_get_submission_count($node->nid); 538 $sids = webform_download_sids($node->nid, array('range_type' => 'new')); 539 540 $last_download = webform_download_last_download_info($node->nid); 541 542 $element['#webform_download_info']['sid'] = $last_download ? $last_download['sid'] : 0; 543 $element['#webform_download_info']['requested'] = $last_download ? $last_download['requested'] : $node->created; 544 $element['#webform_download_info']['total'] = $count; 545 $element['#webform_download_info']['new'] = count($sids); 546 547 return $element; 548 } 549 550 /** 551 * Theme the output of the export range fieldset. 552 */ 553 function theme_webform_results_download_range($element) { 554 drupal_add_css(drupal_get_path('module', 'webform') . '/css/webform-admin.css', 'theme', 'all', FALSE); 555 drupal_add_js(drupal_get_path('module', 'webform') . '/js/webform-admin.js', 'module', 'header', FALSE, TRUE, FALSE); 556 557 $download_info = $element['#webform_download_info']; 558 559 // Set description for total of all submissions. 560 $element['range_type']['all']['#description'] = '(' . t('@count total', array('@count' => $download_info['total'])) . ')'; 561 $element['range_type']['all']['#prefix'] = '<div class="webform-container-inline">'; 562 $element['range_type']['all']['#suffix'] = '</div>'; 563 564 // Set description for "New submissions since last download". 565 $format = webform_date_format('short'); 566 $requested_date = format_date($download_info['requested'], 'custom', $format); 567 $element['range_type']['new']['#description'] = '(' . t('@count new since @date', array('@count' => $download_info['new'], '@date' => $requested_date)) . ')'; 568 $element['range_type']['new']['#prefix'] = '<div class="webform-container-inline">'; 569 $element['range_type']['new']['#suffix'] = '</div>'; 570 571 // Disable option if there are no new submissions. 572 if ($download_info['new'] == 0) { 573 $element['range_type']['new']['#attributes']['disabled'] = 'disabled'; 574 } 575 576 // Render latest x submissions option. 577 $element['latest']['#attributes']['class'] = 'webform-set-active'; 578 $element['range_type']['latest']['#title'] = t('Only the latest !number submissions', array('!number' => drupal_render($element['latest']))); 579 $element['range_type']['latest']['#prefix'] = '<div class="webform-container-inline">'; 580 $element['range_type']['latest']['#suffix'] = '</div>'; 581 582 // Render Start-End submissions option. 583 $element['start']['#attributes']['class'] = 'webform-set-active'; 584 $element['end']['#attributes']['class'] = 'webform-set-active'; 585 $element['range_type']['range']['#title'] = t('All submissions starting from: !start and optionally to: !end', array('!start' => drupal_render($element['start']), '!end' => drupal_render($element['end']))); 586 $element['range_type']['range']['#prefix'] = '<div class="webform-container-inline">'; 587 $element['range_type']['range']['#suffix'] = '</div>'; 588 589 590 $last_sid = $download_info['sid'] ? $download_info['sid'] : theme('placeholder', t('none')); 591 $element['range_type']['range']['#description'] = '(' . t('Use submission IDs for the range. Last downloaded end SID: !sid.', array('!sid' => $last_sid)) . ')'; 592 593 return drupal_render($element); 594 } 595 596 /** 597 * Theme the output of the select list format radio buttons. 598 */ 599 function theme_webform_results_download_select_format($element) { 600 drupal_add_css(drupal_get_path('module', 'webform') . '/css/webform-admin.css', 'theme', 'all', FALSE); 601 602 $output = ''; 603 604 // Build an example table for the separate option. 605 $header = array(t('Option A'), t('Option B'), t('Option C')); 606 $rows = array( 607 array('X', '', ''), 608 array('X', '', 'X'), 609 array('', 'X', 'X'), 610 ); 611 612 $element['separate']['#attributes']['class'] = ''; 613 $element['separate']['#description'] = theme('table', $header, $rows); 614 $element['separate']['#description'] .= t('Separate options are more suitable for building reports, graphs, and statistics in a spreadsheet application.'); 615 $output .= drupal_render($element['separate']); 616 617 // Build an example table for the compact option. 618 $header = array(t('My select list')); 619 $rows = array( 620 array('Option A'), 621 array('Option A,Option C'), 622 array('Option B,Option C'), 623 ); 624 625 $element['separate']['#attributes']['class'] = ''; 626 $element['compact']['#description'] = theme('table', $header, $rows); 627 $element['compact']['#description'] .= t('Compact options are more suitable for importing data into other systems.'); 628 $output .= drupal_render($element['compact']); 629 630 return $output; 631 } 632 633 /** 634 * Generate a Excel-readable CSV file containing all submissions for a Webform. 635 * 636 * The CSV requires that the data be presented in a flat file. In order 637 * to maximize usability to the Excel community and minimize subsequent 638 * stats or spreadsheet programming this program extracts data from the 639 * various records for a given session and presents them as a single file 640 * where each row represents a single record. 641 * The structure of the file is: 642 * Heading Line 1: Gives group overviews padded by empty cells to the 643 * next group. A group may be a question and corresponds 644 * to a component in the webform philosophy. Each group 645 * overview will have a fixed number of columns beneath it. 646 * Heading line 2: gives column headings 647 * Data line 1 ..... 648 * Data line 2 ..... 649 * 650 * An example of this format is given below. Note the columns have had spaces 651 * added so the columns line up. This is not the case with actual file where 652 * a column may be null. Note also, that multiple choice questions as produced 653 * by checkboxes or radio buttons have been presented as "yes" or "no" and the 654 * actual choice text is retained only in the header line 2. 655 * Data from text boxes and input fields are written out in the body of the table. 656 * 657 * Submission Details, , , ,Question 1, , ,.., ,Question 2, , ,.., ,Question n 658 * timestamp ,time,SID,userid,Choice 1 ,Choice 2,Choice 3,..,Choice n,Choice 1 ,Choice 2,Choice 3,..,Choice n,Comment 659 * 21 Feb 2005 ,1835,23 ,34 ,X , , ,.., ,X ,X ,X ,..,X ,My comment 660 * 23 Feb 2005 ,1125,24 ,89 ,X ,X , ,.., ,X ,X ,X ,..,X ,Hello 661 * ................................................................................................................................. 662 * 27 Feb 2005 ,1035,56 ,212 ,X , , ,.., ,X ,X ,X ,..,X ,How is this? 663 * 664 */ 665 function webform_results_export($node, $format = 'delimited', $options = array()) { 666 global $user; 667 module_load_include('inc', 'webform', 'includes/webform.export'); 668 module_load_include('inc', 'webform', 'includes/webform.components'); 669 670 $submission_information = array( 671 'serial' => t('Serial'), 672 'sid' => t('SID'), 673 'time' => t('Time'), 674 'draft' => t('Draft'), 675 'ip_address' => t('IP Address'), 676 'uid' => t('UID'), 677 'username' => t('Username'), 678 ); 679 680 if (empty($options)) { 681 $options = array( 682 'delimiter' => variable_get('webform_csv_delimiter', '\t'), 683 'components' => array_keys($submission_information) + array_keys(webform_component_list($node, 'csv', TRUE)), 684 'components' => array_merge(array_keys($submission_information), array_keys(webform_component_list($node, 'csv', TRUE))), 685 'select_display' => 'value', 686 'select_format' => 'separate', 687 'range_type' => 'all', 688 ); 689 } 690 else { 691 foreach ($submission_information as $key => $label) { 692 if (!in_array($key, $options['components'])) { 693 unset($submission_information[$key]); 694 } 695 } 696 } 697 698 // Open a new Webform exporter object. 699 $exporter = webform_export_create_handler($format, $options); 700 701 $file_name = tempnam(variable_get('file_directory_temp', file_directory_temp()), 'webform'); 702 $handle = @fopen($file_name, 'w'); // The @ suppresses errors. 703 $exporter->bof($handle); 704 705 // Fill in the header for the submission information (if any). 706 $header[2] = $header[1] = $header[0] = count($submission_information) ? array_fill(0, count($submission_information), '') : array(); 707 if (count($submission_information)) { 708 $header[0][0] = $node->title; 709 $header[1][0] = t('Submission Details'); 710 foreach (array_values($submission_information) as $column => $label) { 711 $header[2][$column] = $label; 712 } 713 } 714 715 // Compile header information for components. 716 foreach ($options['components'] as $cid) { 717 if (isset($node->webform['components'][$cid])) { 718 $component = $node->webform['components'][$cid]; 719 720 // Let each component determine its headers. 721 if (webform_component_feature($component['type'], 'csv')) { 722 $component_header = (array) webform_component_invoke($component['type'], 'csv_headers', $component, $options); 723 $header[0] = array_merge($header[0], (array) $component_header[0]); 724 $header[1] = array_merge($header[1], (array) $component_header[1]); 725 $header[2] = array_merge($header[2], (array) $component_header[2]); 726 } 727 } 728 } 729 730 // Add headers to the file. 731 foreach ($header as $row) { 732 $exporter->add_row($handle, $row); 733 } 734 735 // Get all the submissions for the node. 736 $filters['nid'] = $node->nid; 737 if (!empty($options['sids'])){ 738 $filters['sid'] = $options['sids']; 739 } 740 $submissions = webform_get_submissions($filters); 741 742 // Generate a row for each submission. 743 $row_count = 0; 744 foreach ($submissions as $sid => $submission) { 745 $row_count++; 746 747 $row = array(); 748 if (isset($submission_information['serial'])) { 749 $row[] = $row_count; 750 } 751 if (isset($submission_information['sid'])) { 752 $row[] = $sid; 753 } 754 if (isset($submission_information['time'])) { 755 $row[] = format_date($submission->submitted, 'small'); 756 } 757 if (isset($submission_information['draft'])) { 758 $row[] = $submission->is_draft; 759 } 760 if (isset($submission_information['ip_address'])) { 761 $row[] = $submission->remote_addr; 762 } 763 if (isset($submission_information['uid'])) { 764 $row[] = $submission->uid; 765 } 766 if (isset($submission_information['username'])) { 767 $row[] = $submission->name; 768 } 769 770 foreach ($options['components'] as $cid) { 771 if (isset($node->webform['components'][$cid])) { 772 $component = $node->webform['components'][$cid]; 773 // Let each component add its data. 774 $raw_data = isset($submission->data[$cid]['value']) ? $submission->data[$cid]['value'] : NULL; 775 if (webform_component_feature($component['type'], 'csv')) { 776 $data = webform_component_invoke($component['type'], 'csv_data', $component, $options, $raw_data); 777 if (is_array($data)) { 778 $row = array_merge($row, array_values($data)); 779 } 780 else { 781 $row[] = isset($data) ? $data : ''; 782 } 783 } 784 } 785 } 786 787 // Write data from submissions. 788 $data = $exporter->add_row($handle, $row); 789 } 790 791 // Add the closing bytes. 792 $exporter->eof($handle); 793 794 // Close the file. 795 @fclose($handle); 796 797 $export_info['options'] = $options; 798 $export_info['file_name'] = $file_name; 799 $export_info['exporter'] = $exporter; 800 $export_info['row_count'] = $row_count; 801 $export_info['last_sid'] = $sid; 802 803 return $export_info; 804 } 805 806 /** 807 * Send a generated webform results file to the user's browser. 808 * 809 * @param $node 810 * The webform node. 811 * @param $export_info 812 * Export information array retrieved from webform_results_export(). 813 */ 814 function webform_results_download($node, $export_info) { 815 global $user; 816 817 // $exporter, $file_name, $row_count 818 $export_name = _webform_safe_name($node->title); 819 $export_info['exporter']->set_headers($export_name); 820 @readfile($export_info['file_name']); // The @ makes it silent. 821 @unlink($export_info['file_name']); // Clean up, the @ makes it silent. 822 823 // Update user last downloaded sid if required. 824 if ($export_info['options']['range_type'] != 'range' && $export_info['row_count'] > 0) { 825 // Delete existing record. 826 db_query('DELETE FROM {webform_last_download} WHERE nid = %d AND uid = %d', $node->nid, $user->uid); 827 // Write new record. 828 db_query('INSERT INTO {webform_last_download} (nid, uid, sid, requested) VALUES (%d, %d, %d, %d)', $node->nid, $user->uid, $export_info['last_sid'], time()); 829 } 830 831 exit(); 832 } 833 834 /** 835 * Provides a simple analysis of all submissions to a webform. 836 * 837 * @param $node 838 * The webform node on which to generate the analysis. 839 * @param $sids 840 * An array of submission IDs to which this analysis may be filtered. May be 841 * used to generate results that are per-user or other groups of submissions. 842 * @param $analysis_component 843 * A webform component. If passed in, additional information may be returned 844 * relating specifically to that component's analysis, such as a list of 845 * "Other" values within a select list. 846 */ 847 function webform_results_analysis($node, $sids = array(), $analysis_component = NULL) { 848 if (!is_array($sids)) { 849 $sids = array(); 850 } 851 852 // If showing a component's details, we don't want to loose the menu tabs. 853 if ($analysis_component) { 854 $item = menu_get_item('node/' . $node->nid . '/webform-results/analysis'); 855 menu_set_item(NULL, $item); 856 } 857 858 $components = isset($analysis_component) ? array($analysis_component['cid'] => $analysis_component) : $node->webform['components']; 859 $data = array(); 860 foreach ($components as $cid => $component) { 861 // Do component specific call. 862 if ($row_data = webform_component_invoke($component['type'], 'analysis', $component, $sids, isset($analysis_component))) { 863 $data[$cid] = $row_data; 864 } 865 } 866 867 return theme('webform_results_analysis', $node, $data, $sids, $analysis_component); 868 } 869 870 /** 871 * Output the content of the Analysis page. 872 * 873 * @see webform_results_analysis() 874 */ 875 function theme_webform_results_analysis($node, $data, $sids = array(), $analysis_component = NULL) { 876 877 $rows = array(); 878 $question_number = 0; 879 $single = isset($analysis_component); 880 881 $header = array( 882 $single ? $analysis_component['name'] : t('Q'), 883 array('data' => $single ? ' ' : t('responses'), 'colspan' => '10') 884 ); 885 886 foreach ($data as $cid => $row_data) { 887 $question_number++; 888 889 if (is_array($row_data)) { 890 $row = array(); 891 if (!$single) { 892 $row['data'][] = array('data' => '<strong>' . $question_number . '</strong>', 'rowspan' => count($row_data) + 1, 'valign' => 'top'); 893 $row['data'][] = array('data' => '<strong>' . check_plain($node->webform['components'][$cid]['name']) . '</strong>', 'colspan' => '10'); 894 $row['class'] = 'webform-results-question'; 895 } 896 $rows = array_merge($rows, array_merge(array($row), $row_data)); 897 } 898 } 899 900 if (count($rows) == 0) { 901 $rows[] = array(array('data' => t('There are no submissions for this form. <a href="!url">View this form</a>.', array('!url' => url('node/' . $node->nid))), 'colspan' => 20)); 902 } 903 904 return theme('table', $header, $rows, array('class' => 'webform-results-analysis')); 905 } 906 907 /** 908 * Given a set of range options, retrieve a set of SIDs for a webform node. 909 */ 910 function webform_download_sids($nid, $range_options, $uid = NULL) { 911 $query = 'SELECT sid FROM {webform_submissions} WHERE nid = %d'; 912 $args = array($nid); 913 914 switch ($range_options['range_type']) { 915 case 'all': 916 // All Submissions. 917 $query .= ' ORDER BY sid ASC'; 918 break; 919 case 'new': 920 // All Since Last Download. 921 $download_info = webform_download_last_download_info($nid, $uid); 922 $last_sid = $download_info ? $download_info['sid'] : 0; 923 $query .= ' AND sid > %d ORDER BY sid ASC'; 924 $args[] = $last_sid; 925 break; 926 case 'latest': 927 // Last x Submissions. 928 $query .= ' ORDER BY sid DESC LIMIT 0, %d'; 929 $args[] = $range_options['latest']; 930 break; 931 case 'range': 932 // Submissions Start-End. 933 $query .=' AND sid >= %d'; 934 $args[] = $range_options['start']; 935 if ($range_options['end']) { 936 $query .= ' AND sid <= %d'; 937 $args[] = $range_options['end']; 938 } 939 $query .= ' ORDER BY sid ASC'; 940 break; 941 } 942 $result = db_query($query, $args); 943 $sids = array(); 944 while ($row = db_fetch_object($result)) { 945 $sids[] = $row->sid; 946 } 947 948 // The last x submissions option has SIDs that are in reverse order. 949 if ($range_options['range_type'] == 'latest') { 950 $sids = array_reverse($sids); 951 } 952 953 return $sids; 954 } 955 956 /** 957 * Get this user's last download information, including the SID and timestamp. 958 * 959 * This function provides an array of information about the last download that 960 * a user had for a particular Webform node. Currently it only returns an array 961 * with two keys: 962 * - sid: The last submission ID that was downloaded. 963 * - requested: The timestamp of the last download request. 964 * 965 * @param $nid 966 * The Webform NID. 967 * @param $uid 968 * The user account ID for which to retrieve download information. 969 * @return 970 * An array of download information or FALSE if this user has never downloaded 971 * results for this particular node. 972 */ 973 function webform_download_last_download_info($nid, $uid = NULL) { 974 $uid = isset($uid) ? $uid : $GLOBALS['user']->uid; 975 $result = db_query("SELECT * FROM {webform_last_download} WHERE nid = %d AND uid = %d", $nid, $uid); 976 $info = db_fetch_array($result); 977 978 return $info; 979 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |