* @author Pontus Ullgren * @copyright Pontus Ullgren 2004 */ /** * Retrieve lists of submissions for a given webform. * * @param $nid * The node id of the webform */ function _webform_results_submissions($nid) { $header = theme('webform_results_submissions_header', $nid); $submissions = _webform_fetch_submissions($nid, $header); return theme('webform_results_submissions', $nid, $submissions); } /** * Theme the header of the submissions table. * * This is done in it's own function so that webform can retrieve the header and * use it for sorting the results. */ function theme_webform_results_submissions_header($nid) { return array( array('data' => t('#'), 'field' => 'sid', 'sort' => 'asc'), array('data' => t('Submitted'), 'field' => 'submitted'), array('data' => t('User'), 'field' => 'name'), array('data' => t('IP Address'), 'field' => 'remote_addr'), array('data' => t('Operations'), 'colspan' => user_access('clear webform results') ? '3' : '2'), ); } /** * Theme the submissions tab of the webform results page. * * @param $nid * The nid of the node whose results are being displayed. * @param $submissions * An array of all submissions for this webform. */ function theme_webform_results_submissions($nid, $submissions) { global $user; // This header has to be generated seperately so we can add the SQL necessary // to sort the results. $header = theme('webform_results_submissions_header', $nid); $rows = array(); foreach ($submissions as $sid => $submission) { $row = array( $sid, format_date($submission->submitted, 'small'), theme('username', $submission), $submission->remote_addr, l(t('View'), "node/$nid/results/view/". $submission->sid, NULL, NULL, NULL, FALSE), ); if ((user_access("edit own webform submissions") && ($user->uid == $submission->uid)) || user_access("edit webform submissions")) { $row[] = l(t('Edit'), "node/$nid/results/edit/". $submission->sid, NULL, NULL, NULL, FALSE); } else { $row[] = t('Edit'); } if (user_access('clear webform results')) { $row[] = l(t('Delete'), "node/$nid/results/delete/". $submission->sid, NULL, NULL, NULL, FALSE); } $rows[] = $row; } return theme('table', $header, $rows); } /** * Create a table containing all submitted values for a webform node. * * @param $nid * The node ID of the node to show results for. */ function _webform_results_table($nid) { include_once(drupal_get_path('module', 'webform') ."/webform.inc"); // Load Components. _webform_load_components(); // Get all the component cid and names for the node. $node = node_load($nid); // Get all the submissions for the node. $header = theme('webform_results_table_header', $nid); $submissions = _webform_fetch_submissions($nid, $header); return theme('webform_results_table', $nid, $node->ewbformcomponents, $submissions); } function theme_webform_results_table_header($nid) { return array( array('data' => t('#'), 'field' => 'sid', 'sort' => 'asc'), array('data' => t('Submitted'), 'field' => 'submitted'), array('data' => t('User'), 'field' => 'name'), array('data' => t('IP Address'), 'field' => 'remote_addr'), ); } /** * Theme the results table displaying all the submissions for a particular node. * * @param $nid * The nid of the node whose results are being displayed. * @param $components * An associative array of the components for this webform. * @param $submissions * An array of all submissions for this webform. */ function theme_webform_results_table($nid, $components, $submissions) { $header = array(); $rows = array(); $cell = array(); $node = node_load($nid); // This header has to be generated seperately so we can add the SQL necessary. // to sort the results. $header = theme('webform_results_table_header', $nid); // Generate a row for each submission. foreach ($submissions as $sid => $submission) { $cell[] = l($sid, 'node/'. $nid, NULL, "sid=". $sid); $cell[] = format_date($submission->submitted, "small"); $cell[] = theme('username', $submission); $cell[] = $submission->remote_addr; $component_headers = array(); // Generate a cell for each component. foreach ($node->webformcomponents as $component) { $table_function = "_webform_table_data_". $component['type']; if (function_exists($table_function)) { $submission_output = $table_function($submission->data[$component['cid']], $component); if ($submission_output !== NULL) { $component_headers[] = $component['name']; $cell[] = $submission_output; } } } $rows[] = $cell; unset($cell); } if (!empty($component_headers)) { $header = array_merge($header, $component_headers); } return theme('table', $header, $rows); } /** * Generate a Excel-readable CSV file containing all submissions for a webform. * * The CSV requires that the data be presented in a flat file. In order * to maximize useability to the Excel community and minimize subsequent * stats or spreadsheet programming this program extracts data from the * various records for a given session and presents them as a single file * where each row represents a single record. * The structure of the file is: * Heading Line 1: Gives group overviews padded by empty cells to the * next group. A group may be a question and corresponds * to a component in the webform philosophy. Each group * overview will have a fixed number of columns beneath it. * Heading line 2: gives column headings * Data line 1 ..... * Data line 2 ..... * * An example of this format is given below. Note the columns have had spaces * added so the columns line up. This is not the case with actual file where * a column may be null. Note also, that multiple choice questions as produced * by checkboxes or radio buttons have been presented as "yes" or "no" and the * actual choice text is retained only in the header line 2. * Data from text boxes and input fields are written out in the body of the table. * * Submission Details, , , ,Question 1, , ,.., ,Question 2, , ,.., ,Question n * timestamp ,time,SID,userid,Choice 1 ,Choice 2,Choice 3,..,Choice n,Choice 1 ,Choice 2,Choice 3,..,Choice n,Comment * 21 Feb 2005 ,1835,23 ,34 ,Yes ,No ,No ,..,No ,Yes ,Yes ,Yes ,..,Yes ,My comment * 23 Feb 2005 ,1125,24 ,89 ,Yes ,Yes ,No ,..,No ,Yes ,Yes ,Yes ,..,Yes ,Hello * ............................................................................................................... * 27 Feb 2005 ,1035,56 ,212 ,Yes ,No ,No ,..,No ,Yes ,No ,Yes ,..,Yes ,How is this? * */ function _webform_results_download($nid) { include_once(drupal_get_path('module', 'webform') ."/webform.inc"); $node = node_load($nid); $file_name = tempnam(variable_get('file_directory_temp', FILE_DIRECTORY_TEMP), 'webform'); $handle = @fopen($file_name, 'w'); // The @ suppresses errors. $header[0] .= $node->title .",,,,"; $header[1] .= "Submission Details,,,,,"; $header[2] .= "Serial,SID,Time,IP Address,UID,Username"; // Compile header information. _webform_load_components(); // Load all components. foreach ($node->webformcomponents as $cid => $component) { $csv_header_function = "_webform_csv_headers_". $component['type']; if (function_exists($csv_header_function)) { // Let each component determine its headers. $component_header = $csv_header_function($component); $header[0] .= ',"'. str_replace(array('"', '\,'), array('""', '","'), $component_header[0]) .'"'; $header[1] .= ',"'. str_replace(array('"', '\,'), array('""', '","'), $component_header[1]) .'"'; $header[2] .= ',"'. str_replace(array('"', '\,'), array('""', '","'), $component_header[2]) .'"'; } } // Write header information. $file_record = $header[0] ."\n". $header[1] ."\n". $header[2] ."\n"; @fwrite($handle, $file_record); // Get all the submissions for the node. $submissions = _webform_fetch_submissions($nid); // Generate a row for each submission. $rowcount = 0; foreach ($submissions as $sid => $submission) { $row = ++$rowcount .",". $sid .",\"". format_date($submission->submitted, 'small') ."\",\"". $submission->remote_addr ."\",". $submission->uid .",\"". $submission->name ."\""; foreach ($node->webformcomponents as $cid => $component) { $csv_data_function = "_webform_csv_data_". $component['type']; if (function_exists($csv_data_function)) { // Let each component add its data. $row .= ',"'. str_replace(array('"', '\,'), array('""', '","'), $csv_data_function($submission->data[$cid], $component)) .'"'; } } // Write data from submissions. @fwrite($handle, $row ."\n"); } // Close the file. @fclose($handle); drupal_set_header("Content-type: text/csv; charset=utf-8"); drupal_set_header("Content-Disposition: attachment; filename=". preg_replace('/\.$/', '', str_replace(' ', '_', $node->title)) .".csv"); @readfile($file_name); // The @ makes it silent. @unlink($file_name); // Clean up, the @ makes it silent. exit(0); } /** * Provides a simple analysis of all submissions to a webform. */ function _webform_results_analysis($nid) { $rows = array(); $question_number = 0; $node = node_load($nid); $headers = array( t('Q'), array('data' => t('responses'), 'colspan' => '10') ); _webform_load_components(); // Load all component types. foreach ($node->webformcomponents as $component) { $question_number++; // Do component specific call. $analysis_function = "_webform_analysis_rows_". $component['type']; if (function_exists($analysis_function)) { $crows = $analysis_function($component); if (is_array($crows)) { $row[0] = array('data' => ''. $question_number .'', 'rowspan' => count($crows) + 1, 'valign' => 'top'); $row[1] = array('data' => ''. $component['name'] .'', 'colspan' => '10'); $rows = array_merge($rows, array_merge(array($row), $crows)); } } } return theme('table', $headers, $rows); }