View source
<?php
function webform_report_help($section = '') {
$output = '';
switch ($section) {
case "admin/modules#description":
$output = t("Allows users to create reports from Webform data. <b>Requires webform module</b>, and accents module (optional) for sorting accented characters.");
break;
case 'node/add#webform_report':
$output = t("A Webform report is a dynamic page that contains Webform data. The data can be sorted by a particular field, and fields can be included/excluded from the report as needed.");
break;
}
return $output;
}
function webform_report_perm() {
return array(
'access webform reports',
'create webform reports',
'edit webform reports',
'edit own webform reports',
);
}
function webform_report_access($op, $node) {
global $user;
switch ($op) {
case "view":
if (user_access("access webform reports")) {
return TRUE;
}
case "create":
return user_access("create webform reports");
break;
case "update":
case "delete":
if (user_access("edit own webform reports") && $user->uid == $node->uid || user_access("edit webform reports")) {
return TRUE;
}
break;
}
}
function webform_report_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
switch ($primary_field) {
case 'nid':
$return = array();
if (!user_access('access webform reports')) {
if ($primary_table != 'n' && $primary_table != 'node') {
$return['join'] = "LEFT JOIN {node} n ON {$primary_table}.nid = n.nid";
$return['where'] = "n.type <> 'webform_report'";
}
else {
if ($primary_table == 'n') {
$return['where'] = "n.type <> 'webform_report'";
}
if ($primary_table == 'node') {
$return['where'] = "node.type <> 'webform_report'";
}
}
return $return;
}
break;
case 'tid':
break;
case 'vid':
break;
}
}
function webform_report_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/content/webform_report',
'title' => t('Webform reports'),
'callback' => '_webform_report_page',
'access' => user_access('access webform reports'),
'description' => t('View and edit Webform reports.'),
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'node/' . arg(1) . '/csv',
'title' => t('Report CSV Export'),
'callback' => 'webform_report_csv',
'callback arguments' => array(
arg(1),
),
'access' => user_access('access webform reports'),
'type' => MENU_CALLBACK,
);
}
return $items;
}
function webform_report_node_info() {
return array(
'webform_report' => array(
'name' => t('Webform report'),
'module' => 'webform_report',
'description' => t('A webform report is a dynamic page that contains user-specified data
collected by the Webform module. The data can be sorted by a particular field, and fields can
be included/excluded as needed.'),
),
);
}
function webform_report_load($node) {
$webform_report = NULL;
if (!isset($_POST['wnid'])) {
$result = db_query("SELECT r.nid, r.wnid, rc.cid, c.name, r.kcid, r.description, r.sort, r.filter_type, r.filter_value,\n r.options, r.results_per_page FROM {webform_report} r LEFT JOIN {webform_report_component} rc\n ON r.nid = rc.nid LEFT JOIN {webform_component} c ON rc.cid = c.cid WHERE rc.nid = %d ORDER BY\n c.weight", $node->nid);
if (db_num_rows($result) > 0) {
while ($row = db_fetch_object($result)) {
if (!isset($webform_report->wnid)) {
$webform_report->wnid = $row->wnid;
}
if (!isset($webform_report->kcid)) {
$webform_report->kcid = $row->kcid;
}
if (!isset($webform_report->sort)) {
$webform_report->sort = $row->sort;
}
if (!isset($webform_report->filter_type)) {
$webform_report->filter_type = $row->filter_type;
}
if (!isset($webform_report->filter_value)) {
$webform_report->filter_value = $row->filter_value;
}
if (!isset($webform_report->description)) {
$webform_report->description = $row->description;
}
$webform_report->components[] = $row->cid;
if (!isset($webform_report->options)) {
$webform_report->options = unserialize(stripslashes($row->options));
}
if (!isset($webform_report->results_per_page)) {
$webform_report->results_per_page = $row->results_per_page;
}
}
}
else {
webform_report_prepare($node);
}
}
else {
$webform_report->wnid = $_POST['wnid'];
$webform_report->kcid = $_POST['kcid'];
$webform_report->sort = $_POST['sort'];
$webform_report->filter_type = $_POST['filter_type'];
$webform_report->filter_value = $_POST['filter_value'];
$webform_report->description = $_POST['description'];
$webform_report->components = $_POST['components'];
$webform_report->options = $_POST['options'];
$webform_report->results_per_page = $_POST['results_per_page'];
}
return $webform_report;
}
function webform_report_prepare(&$node) {
if (!isset($node->wnid)) {
$node->wnid = $_POST['wnid'];
}
if (!isset($node->kcid)) {
$node->kcid = $_POST['kcid'];
}
if (!isset($node->kcid)) {
$node->sort = $_POST['sort'];
}
if (!isset($node->filter_type)) {
$node->filter_type = $_POST['filter_type'];
}
if (!isset($node->filter_value)) {
$node->filter_value = $_POST['filter_value'];
}
if (!isset($node->description)) {
$node->description = $_POST['description'];
}
if (!isset($node->components)) {
$node->components = $_POST['components'];
}
if (!isset($node->options)) {
$node->options['show_date'] = $_POST['show_date'];
$node->options['show_time'] = $_POST['show_time'];
$node->options['show_user'] = $_POST['show_user'];
$node->options['show_ip'] = $_POST['show_ip'];
$node->options['show_edit'] = $_POST['show_edit'];
}
if (!isset($node->results_per_page)) {
$node->results_per_page = $_POST['results_per_page'];
}
}
function webform_report_view($node, $teaser = 0, $page = 0) {
if (arg(0) == "comment" || $teaser) {
return;
}
$data = _webform_report_get_data($node);
$output = "<p>" . filter_xss_admin($node->description);
$output .= _webform_report_get_body_content($data, $node);
$node->content['body'] = array(
'#value' => check_markup($node->body, $node->format, FALSE),
);
$node->content['webform_report'] = array(
'#value' => $output,
'#weight' => 10,
);
return $node;
}
function webform_report_validate($node, &$form) {
if ($_POST['wnid'] == 0) {
form_set_error('wnid', t('You must select a form'));
}
else {
if ($_POST['kcid'] == '') {
form_set_error('kcid', t('You must select a field'));
}
else {
if ($_POST['filter_type'] != 0 && $_POST['filter_type'] != 5 && $_POST['filter_type'] != 6 && $_POST['filter_value'] == '') {
form_set_error('filter_value', t('You must specify a filter value'));
}
else {
if ($_POST['components'] == '') {
form_set_error('components', t('You must select at least one component '));
}
}
}
}
}
function webform_report_insert($node, $log = TRUE) {
webform_report_prepare($node);
db_query("INSERT INTO {webform_report} (nid, wnid, kcid, description, sort, filter_type, filter_value, options, results_per_page)\n VALUES (%d, %d, %d, '%s', %d, '%s', '%s', '%s', %d)", $node->nid, $node->wnid, $node->kcid, $node->description, $node->sort, $node->filter_type, $node->filter_value, addslashes(serialize($node->options)), $node->results_per_page);
foreach ($node->components as $cid) {
if ($cid != 0) {
db_query("INSERT INTO {webform_report_component} (nid, cid) VALUES (%d, %d)", $node->nid, $cid);
}
}
if ($log) {
watchdog('webform_report', t('Webform report @title added', array(
'@title' => $node->title,
)), WATCHDOG_NOTICE);
}
}
function webform_report_update($node, $log = TRUE) {
webform_report_delete($node, FALSE);
webform_report_insert($node, FALSE);
if ($log) {
watchdog('webform_report', t('Webform report @title updated', array(
'@title' => $node->title,
)), WATCHDOG_NOTICE);
}
}
function webform_report_delete($node, $log = TRUE) {
db_query("DELETE FROM {webform_report} WHERE nid = '{$node->nid}'");
db_query("DELETE FROM {webform_report_component} WHERE nid = '{$node->nid}'");
if ($log) {
watchdog('webform_report', t('Webform report @title deleted', array(
'@title' => $node->title,
)), WATCHDOG_NOTICE);
}
}
function webform_report_form(&$node) {
$form['webform_report'] = array(
'#type' => 'fieldset',
'#title' => t('Webform report'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => -3,
);
$form['webform_report']['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -2,
'#description' => t('Enter a title for your Webform report page'),
);
if ($_POST['description']) {
$value = $_POST['description'];
}
else {
$value = $node->description;
}
$form['webform_report']['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#description' => t('The description will be displayed at the top of the report page'),
'#value' => $value,
'#required' => FALSE,
'#weight' => -1,
);
if (isset($node->wnid)) {
$default = $node->wnid;
}
else {
$default = array(
'0' => t('Select a webform'),
);
}
$options = _webform_report_get_webforms(t('Select a webform'));
$form['webform_report']['wnid'] = array(
'#type' => 'select',
'#title' => t("Webform"),
'#default_value' => $default,
'#options' => $options,
'#attributes' => array(
'onchange' => 'this.form.submit()',
),
'#required' => TRUE,
'#weight' => 0,
);
unset($default, $options);
if (isset($node->wnid) && $node->wnid != 0) {
if (isset($node->kcid)) {
$default = $node->kcid;
}
else {
$default = t('Select a field');
}
$options = _webform_report_get_components($node->wnid);
$form['webform_report']['kcid'] = array(
'#type' => 'select',
'#title' => t("Key field"),
'#default_value' => $default,
'#options' => $options,
'#attributes' => array(
'onchange' => 'this.form.submit()',
),
'#required' => TRUE,
'#weight' => 1,
);
unset($default, $options);
$options = array(
SORT_ASC => t('Ascending'),
SORT_DESC => t('Descending'),
);
$form['webform_report']['sort'] = array(
'#type' => 'select',
'#title' => t("Sort order"),
'#options' => $options,
'#default_value' => $node->sort,
'#weight' => 2,
);
}
unset($default, $options);
if (isset($node->kcid) && $node->kcid != '0') {
$options = array(
0 => t('none'),
1 => t('begins with'),
2 => t('does not begin with'),
3 => t('contains'),
4 => t('does not contain'),
5 => t('is empty'),
6 => t('is not empty'),
);
$form['webform_report']['filter_type'] = array(
'#type' => 'select',
'#title' => t("Filter Type"),
'#options' => $options,
'#attributes' => array(
'onchange' => 'this.form.submit()',
),
'#default_value' => $node->filter_type,
'#weight' => 3,
);
}
unset($options);
if (isset($node->kcid) && $node->kcid != '0' && $node->filter_type != 0) {
$form['webform_report']['filter_value'] = array(
'#type' => 'textfield',
'#title' => t('Filter Value'),
'#description' => t('Filter the key field using the specified value'),
'#default_value' => $node->filter_value,
'#required' => FALSE,
'#weight' => 4,
);
}
if (isset($node->kcid) && $node->kcid != '0') {
$options = _webform_report_get_components($node->wnid);
$values = $node->components;
if (is_array($values)) {
$values = array_map('filter_xss', $values);
}
$form['webform_report']['components'] = array(
'#type' => 'checkboxes',
'#title' => t("Include components"),
'#description' => t('Select all of the components to include in this report and click Preview to display the results'),
'#options' => $options,
'#default_value' => $values,
'#required' => TRUE,
'#weight' => 5,
);
}
unset($options);
if (isset($node->kcid) && $node->kcid != '0') {
$options = array(
'show_date' => t('Show date'),
'show_time' => t('Show time'),
'show_user' => t('Show user'),
'show_ip' => t('Show IP Address'),
'show_edit' => t('Show edit link'),
);
$form['webform_report']['options'] = array(
'#type' => 'checkboxes',
'#title' => t('Display options'),
'#description' => t('Select display options for this report and click Preview to display the results'),
'#options' => $options,
'#default_value' => $node->options,
'#required' => FALSE,
'#weight' => 6,
);
}
unset($options);
if (isset($node->kcid) && $node->kcid != '') {
if (isset($node->results_per_page)) {
$default = $node->results_per_page;
}
else {
$default = 20;
}
$options = array(
20 => '20',
40 => '40',
60 => '60',
80 => '80',
100 => '100',
);
$form['webform_report']['results_per_page'] = array(
'#type' => 'select',
'#title' => t('Results per page'),
'#options' => $options,
'#default_value' => $default,
'#weight' => 7,
);
}
unset($options, $default);
if (!isset($node->kcid) || $node->kcid == '') {
$form['webform_report']['next'] = array(
'#type' => 'button',
'#value' => t(' Next > '),
'#weight' => 8,
'#attributes' => array(
'onclick' => 'this.form.submit()',
),
);
}
return $form;
}
function _webform_report_get_webforms($first = NULL) {
$result = db_query(db_rewrite_sql("SELECT nid FROM {node} n WHERE n.type = 'webform'"));
$webforms = array(
0 => $first,
);
while ($row = db_fetch_object($result)) {
$webform_report = node_load($row->nid);
$webforms[$webform_report->nid] = t($webform_report->title);
}
return $webforms;
}
function _webform_report_get_components($nid, $default = NULL) {
if (isset($default)) {
$components = array(
$default,
);
}
else {
$components = array();
}
$result = db_query("SELECT c.cid, c.name FROM {webform_component} c WHERE c.type <> 'fieldset' AND c.nid = %d ORDER BY c.weight", $nid);
while ($row = db_fetch_object($result)) {
$component_name = substr($row->name, 0, 65);
if (strlen($row->name) > 65) {
$component_name .= "...";
}
$components[$row->cid] = t($component_name);
}
return $components;
}
function _webform_report_get_data($node) {
$result = NULL;
if (is_array($node->components) and count($node->components) > 0) {
$query = "c.cid = '";
$count = 0;
foreach ($node->components as $component) {
$query .= $component;
if ($count < count($node->components) - 1) {
$query .= "' OR c.cid = '";
}
$count++;
}
$query .= "'";
$result = db_query("SELECT w.nid, c.name, c.cid, c.type, d.nid, d.sid, d.data, s.uid, u.name as user, s.submitted, s.remote_addr\n FROM {webform} w\n LEFT JOIN {webform_submitted_data} d ON w.nid = d.nid\n LEFT JOIN {webform_component} c ON d.cid = c.cid AND d.nid = c.nid\n LEFT JOIN {webform_submissions} s ON d.sid = s.sid\n LEFT JOIN {users} u ON s.uid = u.uid\n WHERE w.nid = %d\n AND (" . $query . ")\n ORDER BY d.sid, c.cid, c.name, d.data", $node->wnid);
}
return $result;
}
function _webform_report_get_body_content($data, $node, $formatcsv = FALSE) {
if (db_num_rows($data) > 0) {
$fields = array();
$values = array();
$last_value = 0;
if ($node->options['show_edit']) {
$fields['edit'] = array(
'data' => t('Edit'),
'field' => 'edit',
'sort' => $_GET['sort'],
);
}
if ($node->options['show_date'] || $node->options['show_time']) {
$fields['date'] = array(
'data' => t('Submitted'),
'field' => 'date',
'sort' => $_GET['sort'],
);
}
if ($node->options['show_user']) {
$fields['user'] = array(
'data' => t('User'),
'field' => 'user',
'sort' => $_GET['sort'],
);
}
if ($node->options['show_ip']) {
$fields['remote_addr'] = array(
'data' => t('IP Address'),
'field' => 'remote_addr',
'sort' => $_GET['sort'],
);
}
while ($row = db_fetch_object($data)) {
if (!isset($fields[$row->cid])) {
$fields[$row->cid] = array(
'data' => check_plain($row->name),
'field' => $row->cid,
'sort' => $_GET['sort'],
);
}
if ($node->options['show_edit']) {
$values[$row->sid]['edit'] = array(
'data' => l(t('edit'), 'node/' . $row->nid . '/submission/' . $row->sid . '/edit'),
);
}
if ($node->options['show_date'] || $node->options['show_time']) {
if ($node->options['show_date']) {
$dateformat = 'Y-m-d';
if ($node->options['show_time']) {
$dateformat .= ' H:m';
}
}
else {
if ($node->options['show_time']) {
$dateformat = 'H:m';
}
}
$values[$row->sid]['date'] = array(
'data' => date($dateformat, $row->submitted),
);
}
if ($node->options['show_user']) {
if ($row->user == '') {
$row->user = t('anonymous');
}
$values[$row->sid]['user'] = array(
'data' => $row->user,
);
}
if ($node->options['show_ip']) {
$values[$row->sid]['remote_addr'] = array(
'data' => $row->remote_addr,
);
}
if ($row->data != '0') {
if ($row->cid == $last_cid && $row->sid == $last_sid && !empty($last_value)) {
$row->data .= ', ' . $last_value;
}
if ($row->type == 'file') {
$tmp = unserialize($row->data);
$link = ' ';
if (!empty($tmp['filename'])) {
$link = '<a href="' . base_path() . $tmp['filepath'] . '">' . $tmp['filename'] . ' (' . (int) ($tmp['filesize'] / 1024) . ' KB)' . '</a>';
}
$values[$row->sid][$row->cid] = array(
'data' => $link,
);
}
else {
$values[$row->sid][$row->cid] = array(
'data' => filter_xss($row->data),
);
}
}
else {
if (!$formatcsv) {
$values[$row->sid][$row->cid] = array(
'data' => ' ',
);
}
}
if (isset($_GET['order'])) {
if ($_GET['order'] == $row->name && $node->kcid != $row->cid) {
$node->kcid = $row->cid;
}
}
else {
switch ($node->kcid) {
case $row->cid:
$_GET['order'] = $row->name;
break;
case 'remote_addr':
$_GET['order'] = t('IP Address');
break;
case 'user':
$_GET['order'] = t('User');
break;
case 'date':
$_GET['order'] = t('Submitted');
break;
}
}
$last_cid = $row->cid;
$last_sid = $row->sid;
$last_value = $row->data;
}
reset($fields);
$column = array();
foreach ($fields as $key1 => $field) {
foreach ($values as $key2 => $value) {
if (module_exists('accents')) {
$column[$key1][$key2] = trim(strtolower(accents_search_preprocess($value[$key1]['data'])));
}
else {
$column[$key1][$key2] = trim(strtolower($value[$key1]['data']));
}
}
}
if (isset($_GET['sort'])) {
switch ($_GET['sort']) {
case 'asc':
$node->sort = SORT_ASC;
break;
case 'desc':
$node->sort = SORT_DESC;
break;
}
}
else {
if ($node->sort == SORT_ASC) {
$_GET['sort'] = 'asc';
}
else {
$_GET['sort'] = 'desc';
}
}
switch ($_GET['order']) {
case t('IP Address'):
$node->kcid = 'remote_addr';
$sort = SORT_REGULAR;
break;
case t('User'):
$node->kcid = 'user';
$sort = SORT_STRING;
break;
case t('Submitted'):
$node->kcid = 'date';
$sort = SORT_REGULAR;
break;
default:
$sort = SORT_REGULAR;
}
array_multisort($column[$node->kcid], (int) $node->sort, $values);
if ($node->filter_type != 0) {
$values = _webform_report_filter_values($values, $node);
}
if ($formatcsv) {
$output = _webform_report_output_csv($fields, $values);
}
else {
$values = _webform_report_add_data_links($fields, $values);
$output .= ' (' . count($values) . ' ' . t('results') . ') ' . l(t('Download as CSV'), 'node/' . arg(1) . '/csv') . '</p>';
$output .= _webform_report_pager($fields, $values, $node);
}
}
else {
$output = t('Note: There are no submissions for the selected webform.</b> Either the form
has not yet been completed by anyone, or the results have been cleared. This will not
prevent you from creating this report, but this message will be displayed on the report
page until someone submits the selected webform.');
}
return $output;
}
function _webform_report_add_data_links($fields, $values) {
foreach ($fields as $fkey => $field) {
foreach ($values as $vkey => $value) {
$data =& $values[$vkey][$fkey]['data'];
if ($fkey == 'user') {
$data = l($data, 'user/' . _webform_report_get_uid_for_user($data));
}
else {
if (valid_email_address($data)) {
$data = l($data, 'mailto:' . $data);
}
else {
if (valid_url($data, TRUE)) {
$data = l($data, $data);
}
}
}
}
}
return $values;
}
function _webform_report_filter_values($values, $node) {
$filtered_values = array();
foreach ($values as $key => $value) {
switch ($node->filter_type) {
case 1:
if (substr(strtolower(trim($value[$node->kcid]['data'])), 0, strlen($node->filter_value)) == strtolower($node->filter_value)) {
$filtered_values[] = $value;
}
break;
case 2:
if (substr(strtolower(trim($value[$node->kcid]['data'])), 0, strlen($node->filter_value)) != strtolower($node->filter_value)) {
$filtered_values[] = $value;
}
break;
case 3:
if (strpos(strtolower(trim($value[$node->kcid]['data'])), strtolower($node->filter_value)) !== FALSE) {
$filtered_values[] = $value;
}
break;
case 4:
if (strpos(strtolower(trim($value[$node->kcid]['data'])), strtolower($node->filter_value)) === FALSE) {
$filtered_values[] = $value;
}
break;
case 5:
if (strlen(trim($value[$node->kcid]['data'])) == 0) {
$filtered_values[] = $value;
}
break;
case 6:
if (strlen(trim($value[$node->kcid]['data'])) != 0) {
$filtered_values[] = $value;
}
break;
}
}
return $filtered_values;
}
function _webform_report_get_uid_for_user($name) {
$result = db_query("SELECT uid FROM users WHERE name = '%s'", $name);
$user = db_fetch_object($result);
return $user->uid;
}
function _webform_report_page() {
$output = NULL;
if (user_access('access webform reports')) {
$header = array(
t('Title'),
array(
'data' => t('View'),
'colspan' => '4',
),
);
$result = db_query(db_rewrite_sql("SELECT nid, title FROM {node} n WHERE n.type='webform_report'"));
while ($node = db_fetch_object($result)) {
$rows[] = array(
l($node->title, 'node/' . $node->nid),
l(t('edit'), 'node/' . $node->nid . '/edit'),
);
}
$output = theme_table($header, $rows, array(
'class' => 'webform',
));
drupal_set_title(check_plain($node->title));
}
return $output;
}
function _webform_report_pager($fields, $values, $node) {
global $pager_page_array, $pager_total;
if (!$node->results_per_page) {
$results_per_page = 20;
}
else {
$results_per_page = $node->results_per_page;
}
drupal_add_css(drupal_get_path('module', 'webform_report') . '/webform_report.css');
$pages = array_chunk($values, $results_per_page, TRUE);
$page = isset($_GET['page']) ? $_GET['page'] : '';
$pager_page_array = explode(',', $page);
if ($page == '') {
$page = 0;
}
$output = theme_table($fields, $pages[$page], array(
'class' => 'webform_report',
));
$pager_total[0] = count($pages);
$pager_page_array[0] = max(0, min((int) $pager_page_array[0], (int) $pager_total[0] - 1));
$output .= theme('pager', NULL, $results_per_page, 0);
return $output;
}
function webform_report_csv($nid) {
$node = node_load($nid);
$data = _webform_report_get_data($node);
$output = _webform_report_get_body_content($data, $node, TRUE);
$fname = 'wfr_export.csv';
header('Content-Type: text/plain');
header('Content-Length: ' . strlen($output));
header('Content-Disposition: attachment; filename="' . $fname . '"');
echo $output;
}
function _webform_report_output_csv($fields, $values) {
$output = '';
$tmp = array();
foreach ($fields as $cell) {
$tmp[] .= _webform_report_format_csv_column($cell['data']);
}
$output .= implode(',', $tmp) . "\r\n";
foreach ($values as $row) {
$tmp = array();
foreach ($row as $cell) {
$tmp[] = _webform_report_format_csv_column($cell['data']);
}
$output .= implode(',', $tmp) . "\r\n";
}
return $output;
}
function _webform_report_format_csv_column($value) {
if (strpos($value, ',')) {
if (strpos($value, '"')) {
return '"' . str_replace('"', '""', $value) . '"';
}
else {
return '"' . $value . '"';
}
}
return $value;
}