From 8c6d8323a16598253a482ecabe0cf75f99ac3513 Mon Sep 17 00:00:00 2001 From: Roman Zimmermann Date: Tue, 27 May 2014 12:34:47 +0200 Subject: [PATCH 2/2] Use hooks to get submission information. --- includes/webform.report.inc | 289 ++++++++++++++++++++++++++++---------------- webform.module | 6 +- 2 files changed, 183 insertions(+), 112 deletions(-) diff --git a/includes/webform.report.inc b/includes/webform.report.inc index 38abcb1..22f1ab1 100644 --- a/includes/webform.report.inc +++ b/includes/webform.report.inc @@ -177,26 +177,32 @@ function webform_results_table($node, $pager_count = 0) { } // Get all the submissions for the node. - $header = theme('webform_results_table_header', array('node' => $node)); + $options['type'] = 'results'; + $header = webform_results_download_submission_information($node, $options); + foreach ($header as &$info) { + $info['data'] = $info['title']; + } $submissions = webform_get_submissions($node->nid, $header, $pager_count); $total_count = webform_get_submission_count($node->nid); + foreach ($submissions as $sid => &$submission) { + $extra_data[$sid] = module_invoke_all('webform_results_download_submission_information_data', $submission, $options, 0, $total_count); + } - $output = theme('webform_results_table', array('node' => $node, 'components' => $node->webform['components'], 'submissions' => $submissions, 'total_count' => $total_count, 'pager_count' => $pager_count)); + $output = theme('webform_results_table', array( + 'node' => $node, + 'components' => $node->webform['components'], + 'submissions' => $submissions, + 'total_count' => $total_count, + 'pager_count' => $pager_count, + 'header' => $header, + 'extra_data' => $extra_data, + )); if ($pager_count) { $output .= theme('pager'); } return $output; } -function theme_webform_results_table_header($variables) { - return array( - array('data' => t('#'), 'field' => 'sid', 'sort' => 'desc'), - 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. * @@ -219,23 +225,20 @@ function theme_webform_results_table($variables) { $submissions = $variables['submissions']; $total_count = $variables['total_count']; $pager_count = $variables['pager_count']; + $header = $variables['header']; + $extra_data = $variables['extra_data']; - $header = array(); $rows = array(); $cell = array(); - // This header has to be generated separately so we can add the SQL necessary. - // to sort the results. - $header = theme('webform_results_table_header', array('node' => $node)); - // Generate a row for each submission. foreach ($submissions as $sid => $submission) { - $cell[] = l($sid, 'node/' . $node->nid . '/submission/' . $sid); - $cell[] = format_date($submission->submitted, 'short'); - $cell[] = theme('username', array('account' => $submission)); - $cell[] = $submission->remote_addr; $component_headers = array(); + foreach (array_keys($header) as $key) { + $cell[] = isset($extra_data[$sid][$key]) ? $extra_data[$sid][$key] : ''; + } + // Generate a cell for each component. foreach ($node->webform['components'] as $component) { $data = isset($submission->data[$component['cid']]['value']) ? $submission->data[$component['cid']]['value'] : NULL; @@ -372,16 +375,11 @@ function webform_results_download_form($form, &$form_state, $node) { '#theme' => 'webform_results_download_select_format', ); - $csv_components = array( - 'info' => t('Submission information'), - 'serial' => '-' . t('Submission Number'), - 'sid' => '-' . t('Submission ID'), - 'time' => '-' . t('Time'), - 'draft' => '-' . t('Draft'), - 'ip_address' => '-' . t('IP Address'), - 'uid' => '-' . t('User ID'), - 'username' => '-' . t('Username'), - ); + $csv_components = array('info' => t('Submission information')); + // Prepend information fields with "-" to indent. + foreach (webform_results_download_submission_information($node, array('type' => 'download')) as $key => $info) { + $csv_components[$key] = '-' . $info['title']; + } $csv_components += webform_component_list($node, 'csv', TRUE); $form['components'] = array( @@ -670,33 +668,16 @@ function webform_results_export($node, $format = 'delimited', $options = array() module_load_include('inc', 'webform', 'includes/webform.export'); module_load_include('inc', 'webform', 'includes/webform.components'); - $submission_information = array( - 'serial' => t('Serial'), - 'sid' => t('SID'), - 'time' => t('Time'), - 'draft' => t('Draft'), - 'ip_address' => t('IP Address'), - 'uid' => t('UID'), - 'username' => t('Username'), + $options['type'] = 'download'; + $submission_information = webform_results_download_submission_information($node, $options); + $options += array( + 'delimiter' => variable_get('webform_csv_delimiter', '\t'), + 'components' => array_merge(array_keys($submission_information), array_keys(webform_component_list($node, 'csv', TRUE))), + 'select_keys' => 0, + 'select_format' => 'separate', + 'range_type' => 'all', ); - if (empty($options)) { - $options = array( - 'delimiter' => variable_get('webform_csv_delimiter', '\t'), - 'components' => array_merge(array_keys($submission_information), array_keys(webform_component_list($node, 'csv', TRUE))), - 'select_keys' => 0, - 'select_format' => 'separate', - 'range_type' => 'all', - ); - } - else { - foreach ($submission_information as $key => $label) { - if (!in_array($key, $options['components'])) { - unset($submission_information[$key]); - } - } - } - // Open a new Webform exporter object. $exporter = webform_export_create_handler($format, $options); @@ -704,38 +685,14 @@ function webform_results_export($node, $format = 'delimited', $options = array() $handle = @fopen($file_name, 'w'); // The @ suppresses errors. $exporter->bof($handle); - // Fill in the header for the submission information (if any). - $header[2] = $header[1] = $header[0] = count($submission_information) ? array_fill(0, count($submission_information), '') : array(); - if (count($submission_information)) { - $header[0][0] = $node->title; - $header[1][0] = t('Submission Details'); - foreach (array_values($submission_information) as $column => $label) { - $header[2][$column] = $label; - } - } - - // Compile header information for components. - foreach ($options['components'] as $cid) { - if (isset($node->webform['components'][$cid])) { - $component = $node->webform['components'][$cid]; - - // Let each component determine its headers. - if (webform_component_feature($component['type'], 'csv')) { - $component_header = (array) webform_component_invoke($component['type'], 'csv_headers', $component, $options); - // Allow modules to modify the component CSV header. - drupal_alter('webform_csv_header', $component_header, $component); - - // Merge component CSV header to overall CSV header - $header[0] = array_merge($header[0], (array) $component_header[0]); - $header[1] = array_merge($header[1], (array) $component_header[1]); - $header[2] = array_merge($header[2], (array) $component_header[2]); - } - } - } - // Add headers to the file. - foreach ($header as $row) { - $exporter->add_row($handle, $row); + $row_count = 0; + $col_count = 0; + $headers = webform_results_download_headers($node, $options); + foreach ($headers as $row) { + $exporter->add_row($handle, $row, $row_count); + $row_count++; + $col_count = count($row) > $col_count ? count($row) : $col_count; } // Get all the required submissions for the download. @@ -771,7 +728,7 @@ function webform_results_export_batch($filters, $options, $submission_informatio ); } $pager = &$context['sandbox']['pager']; - $row_count = $pager['page'] * $pager['size']; + $serial_start = $row_count = $pager['page'] * $pager['size']; // Set current page $pages = isset($_GET['page']) ? explode(',', $_GET['page']) : array(); @@ -790,26 +747,12 @@ function webform_results_export_batch($filters, $options, $submission_informatio $row_count++; $row = array(); - if (isset($submission_information['serial'])) { - $row[] = $row_count; - } - if (isset($submission_information['sid'])) { - $row[] = $sid; - } - if (isset($submission_information['time'])) { - $row[] = format_date($submission->submitted, 'short'); - } - if (isset($submission_information['draft'])) { - $row[] = $submission->is_draft; - } - if (isset($submission_information['ip_address'])) { - $row[] = $submission->remote_addr; - } - if (isset($submission_information['uid'])) { - $row[] = $submission->uid; - } - if (isset($submission_information['username'])) { - $row[] = $submission->name; + // Add submission information. + $data = module_invoke_all('webform_results_download_submission_information_data', $submission, $options, $serial_start, $row_count); + $c = array('submission' => $submission, 'options' => $options, 'serial_start' => $serial_start, 'row_count' => $row_count); + drupal_alter('webform_results_download_submission_information_data', $data, $c); + foreach (array_keys($submission_information) as $token) { + $row[] = isset($data[$token]) ? $data[$token] : ''; } foreach ($options['components'] as $cid) { @@ -865,6 +808,138 @@ function webform_results_export_batch_finish($success, $results, $operations) { } /** + * Default columns for submission information. + * + * By default all exports have several columns of generic information that + * applies to all submissions. This function returns the list of generic columns + * plus columns added by other modules. + * + * @param $options + * Filter down the list of columns based on a provided column list. + */ +function webform_results_download_submission_information($node, $options = array()) { + $submission_information = module_invoke_all('webform_results_download_submission_information_info', $node, $options); + drupal_alter('webform_results_download_submission_information_info', $submission_information, $node, $options); + + foreach ($submission_information as $key => &$info) { + if (!is_array($info)) { + $info = array('title' => $info); + } + } + if (isset($options['components'])) { + foreach ($submission_information as $key => $label) { + if (!in_array($key, $options['components'])) { + unset($submission_information[$key]); + } + } + } + + return $submission_information; +} + +/** + * Implements hook_webform_results_download_submission_information_info(). + */ +function webform_webform_results_download_submission_information_info($node, $options) { + $info = array(); + if ($options['type'] == 'results') { + $info['webform_sid'] = array('title' => t('#'), 'field' => 'sid', 'sort' => 'desc'); + $info['webform_time'] = array('title' => t('Submitted'), 'field' => 'submitted'); + $info['webform_user'] = array('title' => t('User'), 'field' => 'name'); + $info['webform_ip_address'] = array('title' => t('IP Address'), 'field' => 'remote_addr'); + } + else { + $info['webform_serial'] = t('Serial'); + $info['webform_sid'] = array('title' => t('SID'), 'field' => 'sid', 'sort' => 'desc'); + $info['webform_time'] = array('title' => t('Time'), 'field' => 'submitted'); + $info['webform_draft'] = t('Draft'); + $info['webform_ip_address'] = array('title' => t('IP Address'), 'field' => 'remote_addr'); + $info['webform_uid'] = t('UID'); + $info['webform_username'] = t('Username'); + } + return $info; +} + +/** + * Implements hook_webform_results_download_submission_information_data(). + */ +function webform_webform_results_download_submission_information_data($submission, array $options, $serial_start, $row_count) { + $data = array(); + $data['webform_serial'] = $serial_start + $row_count; + $sid = $submission->sid; + if ($options['type'] == 'results') { + $link_text = $submission->is_draft ? t('@sid (draft)', array('@sid' => $sid)) : $sid; + $data['webform_sid'] = l($link_text, 'node/' . $submission->nid . '/submission/' . $submission->sid); + } + else { + $data['webform_sid'] = $sid; + } + if (!empty($options['iso8601_date'])) { + $time = format_date($submission->submitted, 'custom', 'Y-m-d\TH:i:s', 'UTC'); + } + else { + $time = format_date($submission->submitted, 'short'); + } + $data['webform_time'] = $time; + $data['webform_draft'] = $submission->is_draft; + $data['webform_ip_address'] = $submission->remote_addr; + $data['webform_uid'] = $submission->uid; + $data['webform_username'] = $submission->name; + $data['webform_user']['data'] = array( + '#theme' => 'username', + '#account' => $submission + ); + return $data; +} + +/** + * Print the header rows for the downloadable webform data. + * + * @param $node + * The webform node on which to generate the analysis. + * @param array $options + * A list of options that define the output format. These are generally passed + * through from the GUI interface. + */ +function webform_results_download_headers($node, $options) { + module_load_include('inc', 'webform', 'includes/webform.components'); + $submission_information = webform_results_download_submission_information($node, $options); + + // Fill in the header for the submission information (if any). + $header[2] = $header[1] = $header[0] = count($submission_information) ? array_fill(0, count($submission_information), '') : array(); + if (count($submission_information)) { + $header[0][0] = $node->title; + + $header[1][0] = t('Submission Details'); + $submission_information_headers = array_values($submission_information); + foreach ($submission_information_headers as $column => $info) { + $header[2][$column] = $info['title']; + } + } + + // Compile header information for components. + foreach ($options['components'] as $cid) { + if (isset($node->webform['components'][$cid])) { + $component = $node->webform['components'][$cid]; + + // Let each component determine its headers. + if (webform_component_feature($component['type'], 'csv')) { + $component_header = (array) webform_component_invoke($component['type'], 'csv_headers', $component, $options); + // Allow modules to modify the component CSV header. + drupal_alter('webform_csv_header', $component_header, $component); + + // Merge component CSV header to overall CSV header + $header[0] = array_merge($header[0], (array) $component_header[0]); + $header[1] = array_merge($header[1], (array) $component_header[1]); + $header[2] = array_merge($header[2], (array) $component_header[2]); + } + } + } + + return $header; +} + +/** * Send a generated webform results file to the user's browser. * * @param $node diff --git a/webform.module b/webform.module index 925713c..c2559b8 100644 --- a/webform.module +++ b/webform.module @@ -618,12 +618,8 @@ function webform_theme() { 'template' => 'templates/webform-results-submissions', 'file' => 'includes/webform.report.inc', ), - 'webform_results_table_header' => array( - 'variables' => array('node' => NULL), - 'file' => 'includes/webform.report.inc', - ), 'webform_results_table' => array( - 'variables' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'node' => NULL, 'total_count' => NULL, 'pager_count' => NULL), + 'variables' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'extra_data' => NULL, 'node' => NULL, 'total_count' => NULL, 'pager_count' => NULL), 'file' => 'includes/webform.report.inc', ), 'webform_results_download_range' => array( -- 1.8.3.2