You are here

webform_report.module in Webform Report 6

File

webform_report.module
View source
<?php

/**
 * This module allows users to create simple, dynamic reports based on data collected
 * by the webform module. It adds a new node type that contains the report criteria,
 * and the data displayed is updated automatically as webforms are date. The data
 * can be sorted according to the viewer's preference without altering the report criteria.
 *
 * The module is written by Kristian Lance for Communications Research Centre Canada (CRC),
 * an agency of Industry Canada.
 *
 */

/**
 * Implementation of hook_help
 */
function webform_report_help($path) {
  switch ($path) {
    case 'admin/modules#description':
      return t('Allows users to create reports from Webform data.');
      break;
    case 'node/add#webform_report':
      return 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;
  }
}

/**
 * Implementation of hook_perm
 */
function webform_report_perm() {
  return array(
    'access webform reports',
    'create webform reports',
    'edit webform reports',
    'edit own webform reports',
  );
}

/**
 * Implementation of hook_access
 */
function webform_report_access($op, $node, $account = NULL) {
  global $user;
  if (empty($account)) {
    $account = $user;
  }
  switch ($op) {
    case 'view':
      return user_access('access webform reports', $account);
      break;
    case 'create':
      return user_access('create webform reports', $account);
      break;
    case 'update':
    case 'delete':
      return user_access("edit webform reports") || user_access("edit own webform reports") && $user->uid == $node->uid;
      break;
  }
}

/**
 * Implementation of hook_db_rewrite_sql(), to prevent webform_reports from being
 * displayed on the front page (promoted) while view access to them is denied
 * the current role. Don't ask, just smile and nod.
 */
function webform_report_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
  switch ($primary_field) {
    case 'nid':

      // this query deals with node objects
      $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':

      // this query deals with taxonomy objects
      break;
    case 'vid':

      // this query deals with vocabulary objects
      break;
  }
}

/**
 * Implementation of hook_menu()
 */
function webform_report_menu() {
  global $user;
  $items = array();
  $items['admin/content/webform_report'] = array(
    'title' => t('Webform Reports'),
    'description' => t('View and edit Webform reports.'),
    'page callback' => '_webform_report_page',
    'access callback' => 'user_access',
    'access arguments' => array(
      'access webform reports',
    ),
    'file' => 'webform_report.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['node/%webform_report_menu/edit/webform_report/configuration'] = array(
    'title' => t('Configuration'),
    'page callback' => 'node_page_edit',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_report_access',
    'access arguments' => array(
      'update',
      1,
      $user,
    ),
    'weight' => 1,
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['node/%webform_report_menu/edit/webform_report/criteria'] = array(
    'title' => t('Report Criteria'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'webform_report_criteria_form',
      1,
    ),
    'access callback' => 'webform_report_access',
    'access arguments' => array(
      'update',
      1,
      $user,
    ),
    'weight' => 2,
    'type' => MENU_LOCAL_TASK,
  );

  // Without this, users with Create, and not Edit, would not be able to complete the Criteria form
  $items['node/%webform_report_menu/add/webform_report/criteria'] = array(
    'title' => t('Report Criteria'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'webform_report_criteria_form',
      1,
    ),
    'access callback' => 'webform_report_access',
    'access arguments' => array(
      'create',
      1,
      $user,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['node/%webform_report_menu/csv'] = array(
    'title' => t('Report CSV Export'),
    'page callback' => 'webform_report_csv',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_report_access',
    'access arguments' => array(
      'view',
      1,
      $user,
    ),
    'file' => 'webform_report.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Menu loader callback; Load a webform report node if the given nid is a webform report
 */
function webform_report_menu_load($nid) {
  if (!is_numeric($nid)) {
    return FALSE;
  }
  $node = node_load($nid);
  if (empty($node->type) || $node->type != 'webform_report') {
    return FALSE;
  }
  return $node;
}

/**
 * Implementation of hook_node_info
 */
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.'),
    ),
  );
}

/**
 * Implementation of hook_load
 */
function webform_report_load($node) {
  $additions = NULL;

  // Populate webform_report-specific node variables only if no new data has been submitted via a form.
  if (empty($_POST['wnid'])) {
    $additions = db_fetch_object(db_query("SELECT wnid, kcid, description, sort, filter_type, filter_value, results_per_page, components\n                                           FROM {webform_report} WHERE nid = %d", $node->nid));

    // Unpack components (slashes added for MySQL compatibility).
    $components = unserialize(stripslashes($additions->components));
    if (is_array($components)) {
      $additions->components = $components;
    }
    else {

      // This is here because base64_encode had to be used for schema updates since Drupal strips slashes from update queries
      $additions->components = unserialize(base64_decode($additions->components));
    }

    // Table column sort value.
    $additions->sort_col = $additions->kcid;
  }
  else {
    if ($_POST['wnid'] != 0) {
      $additions->wnid = $_POST['wnid'];
      $additions->kcid = $_POST['kcid'];
      $additions->description = $_POST['description'];
      $additions->sort = $_POST['sort'];
      $additions->sort_col = $_POST['sort_col'];
      $additions->components = $_POST['components'];
      $additions->filter_type = $_POST['filter_type'];
      $additions->filter_value = $_POST['filter_value'];
      $additions->results_per_page = $_POST['results_per_page'];
    }
  }
  return $additions;
}

/**
 * Implementation of hook_view
 */
function webform_report_view($node, $teaser = FALSE, $page = FALSE) {
  if (!empty($node->nid) && empty($node->wnid) && (arg(2) != 'add' && arg(2) != 'edit')) {
    drupal_goto('node/' . $node->nid . '/add/webform_report/criteria');
  }
  module_load_include('inc', 'webform_report', 'webform_report');
  $data = _webform_report_get_data($node);
  $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;
}

/**
 * Implementation of hook_insert
 */
function webform_report_insert($node) {
  db_query("INSERT INTO {webform_report} (nid, description)\n            VALUES (%d, '%s')", $node->nid, $node->description);
  watchdog('webform_report', 'Webform report @title added', array(
    '@title' => $node->title,
  ), WATCHDOG_NOTICE);

  // log it
}

/**
 * Implementation of hook_update
 */
function webform_report_update($node) {

  // What to update, based on url arguments.
  if (arg(2) == 'add' | arg(2) == 'edit') {
    if (arg(4) == 'criteria') {
      db_query("UPDATE {webform_report} SET wnid = %d, kcid = %d, sort = %d, components = '%s', filter_type = %d, filter_value = '%s', results_per_page = %d\n                WHERE nid = %d", $node->wnid, $node->kcid, $node->sort, addslashes(serialize($node->components)), $node->filter_type, $node->filter_value, $node->results_per_page, $node->nid);
    }
    else {
      db_query("UPDATE {webform_report} SET description = '%s' WHERE nid = '" . $node->nid . "'", $node->description);
      watchdog('webform_report', 'Webform report @title updated', array(
        '@title' => $node->title,
      ), WATCHDOG_NOTICE);

      // log it
    }
  }
}

/**
 * Implementation of hook_delete
 */
function webform_report_delete($node) {
  db_query("DELETE FROM {webform_report} WHERE nid = %d", $node->nid);
  watchdog('webform_report', 'Webform report @title deleted', array(
    '@title' => $node->title,
  ), WATCHDOG_NOTICE);

  // log it
}
function webform_report_validate($node, &$form) {

  // make the delete button redirect properly
  if ($node->op == t('Delete')) {
    drupal_goto('node/' . $node->nid . '/delete');
  }
}

/**
 * Implementation of hook_form
 */
function webform_report_form(&$node, $form_state) {
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#required' => TRUE,
    '#default_value' => $node->title,
    '#weight' => -9,
    '#description' => t('Enter a title for your Webform report page'),
  );
  $form['description'] = array(
    '#type' => 'textarea',
    '#title' => t('Description'),
    '#description' => t('The description will be displayed at the top of the report page'),
    '#default_value' => $node->description,
    '#required' => FALSE,
    '#weight' => -8,
  );
  if (arg(2) == 'edit') {
    $form['#redirect'] = 'node/' . $node->nid . '/edit/webform_report/criteria';
  }
  return $form;
}

/**
 * Implementation of hook_validate
 */
function webform_report_criteria_form_validate($form, &$form_state) {
  if ($_POST['wnid'] == 0) {
    form_set_error('wnid', t('You must select a form'));
    unset($form_state['values']);
  }
  else {
    if ($_POST['kcid'] == 0) {
      form_set_error('kcid', t('You must select a field'));
    }
    else {
      if ($_POST['filter_type'] != 0 && $_POST['filter_type'] != 7 && $_POST['filter_type'] != 8 && empty($_POST['filter_value'])) {
        form_set_error('filter_value', t('You must specify a filter value'));
      }
      else {
        if (empty($_POST['components'])) {
          form_set_error('components', t('You must select at least one field  '));
        }
      }
    }
  }
  $form_state['rebuild'] = TRUE;
}

/**
 * Validates and saves criteria form data when Publish button is pressed
 *
 * @param form is a form object
 * @param form_state is a form_state object
 */
function webform_report_criteria_form_publish($form, &$form_state) {
  $errors = form_get_errors();
  if (empty($errors)) {
    webform_report_update(node_load(arg(1)));
  }
}

/**
 * Generate a form for specifying report criteria.
 *
 * @param $form_state
 * @return an array of form elements
 */
function webform_report_criteria_form($form_state) {
  global $user;
  $node = node_load(arg(1));

  // Check if the webform report has already been submitted, so that edits can be denied to users with only create permission
  $webform_report = db_fetch_object(db_query("SELECT wnid FROM {webform_report} WHERE nid = '" . $node->nid . "'"));
  module_load_include('inc', 'webform_report', 'webform_report');
  if (arg(2) == 'add' && empty($webform_report->wnid) && user_access('create webform reports') || (user_access('edit webform reports') || user_access('edit own webform reports') && $user->uid == $node->uid) || arg(2) == 'edit') {
    $webforms = _webform_report_get_webforms();
    $webform_components = _webform_report_get_components($node->wnid);
    $meta_components = array(
      -1 => t('User'),
      -2 => t('Date'),
      -3 => t('Time'),
      -4 => t('IP Address'),
    );
    $filter_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('equals'),
      6 => t('does not equal'),
      7 => t('is empty'),
      8 => t('is not empty'),
    );
    $sort_options = array(
      SORT_ASC => t('Ascending'),
      SORT_DESC => t('Descending'),
    );
    $results_per_page_options = array(
      0 => 'All',
      20 => '20',
      40 => '40',
      60 => '60',
      80 => '80',
      100 => '100',
    );
    if (!empty($node->wnid)) {
      $default = $node->wnid;
    }
    else {
      $default = 0;
    }
    $form['wnid'] = array(
      '#type' => 'select',
      '#title' => t('Webform'),
      '#default_value' => $default,
      '#options' => array(
        0 => t('Select a Webform'),
      ) + $webforms,
      '#attributes' => array(
        'onchange' => 'this.form.submit()',
      ),
      '#required' => TRUE,
      '#weight' => 0,
      '#description' => 'Select a webform to include in the report.',
    );
    unset($default);
    if (!empty($node->wnid)) {
      if (!empty($node->kcid)) {
        $default = $node->kcid;
      }
      else {
        $default = 0;
      }
      $form['kcid'] = array(
        '#type' => 'select',
        '#title' => t('Key field'),
        '#default_value' => $default,
        '#options' => array(
          0 => t('Select a field'),
        ) + $meta_components + $webform_components,
        '#attributes' => array(
          'onchange' => 'this.form.submit()',
        ),
        '#required' => TRUE,
        '#weight' => 1,
      );
    }
    unset($default);
    if (!empty($node->kcid)) {
      $form['filter_type'] = array(
        '#type' => 'select',
        '#title' => t('Filter Type'),
        '#options' => $filter_options,
        '#attributes' => array(
          'onchange' => 'this.form.submit()',
        ),
        '#default_value' => $node->filter_type,
        '#weight' => 3,
      );
    }
    if (!empty($node->kcid) && !empty($node->filter_type)) {
      $form['filter_value'] = array(
        '#type' => 'textfield',
        '#title' => t('Filter Value'),
        '#description' => t('Filter the key field using the specified value'),
        '#default_value' => $node->filter_value,
        '#attributes' => array(
          'onchange' => 'this.form.submit()',
        ),
        '#required' => FALSE,
        '#weight' => 4,
      );
    }
    if (!empty($node->kcid)) {
      $form['sort'] = array(
        '#type' => 'select',
        '#title' => t('Sort order'),
        '#options' => $sort_options,
        '#default_value' => $node->sort,
        '#weight' => 2,
      );
    }
    if (is_array($node->components)) {
      $default = $node->components;
    }
    else {
      $default = array();
    }
    if (!empty($node->kcid)) {
      $form['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' => array_map('filter_xss', $meta_components + $webform_components + array(
          -5 => t('Edit link'),
        )),
        '#default_value' => $default,
        '#required' => TRUE,
        '#weight' => 5,
      );
    }
    unset($default);
    if (!empty($node->kcid)) {
      if (arg(2) != 'add' && (!empty($node->results_per_page) || $node->results_per_page == 0)) {
        $default = $node->results_per_page;
      }
      else {
        $default = 20;
      }
      $form['results_per_page'] = array(
        '#type' => 'select',
        '#title' => t('Results per page'),
        '#options' => $results_per_page_options,
        '#default_value' => $default,
        '#weight' => 6,
      );
    }
    unset($default);
    $form['update'] = array(
      '#type' => 'submit',
      '#value' => t('Update'),
      '#weight' => 8,
    );
    if (!form_get_errors()) {
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Publish'),
        '#validate' => array(
          'webform_report_criteria_form_publish',
        ),
        '#weight' => 9,
      );
    }
    $form['#redirect'] = 'node/' . $node->nid;
    return $form;
  }
  else {
    drupal_access_denied();
    exit;
  }
}

Functions

Namesort descending Description
webform_report_access Implementation of hook_access
webform_report_criteria_form Generate a form for specifying report criteria.
webform_report_criteria_form_publish Validates and saves criteria form data when Publish button is pressed
webform_report_criteria_form_validate Implementation of hook_validate
webform_report_db_rewrite_sql Implementation of hook_db_rewrite_sql(), to prevent webform_reports from being displayed on the front page (promoted) while view access to them is denied the current role. Don't ask, just smile and nod.
webform_report_delete Implementation of hook_delete
webform_report_form Implementation of hook_form
webform_report_help Implementation of hook_help
webform_report_insert Implementation of hook_insert
webform_report_load Implementation of hook_load
webform_report_menu Implementation of hook_menu()
webform_report_menu_load Menu loader callback; Load a webform report node if the given nid is a webform report
webform_report_node_info Implementation of hook_node_info
webform_report_perm Implementation of hook_perm
webform_report_update Implementation of hook_update
webform_report_validate
webform_report_view Implementation of hook_view