You are here

uc_webform_pane.module in Ubercart Webform Checkout Pane 6.2

uc_webform_pane.module

Ubercart Webform Checkout Panes.

@note Ubercart webform data is stored in database during checkout, even when order is not complete.

File

uc_webform_pane.module
View source
<?php

/**
 * @file uc_webform_pane.module
 * 
 * Ubercart Webform Checkout Panes.
 * 
 * @note Ubercart webform data is stored in database during checkout, even when order is not complete.
 */

/**
 * Implementation of hook_init().
 */
function uc_webform_pane_init() {
  drupal_add_css(drupal_get_path('module', 'uc_webform_pane') . '/uc_webform_pane.css');
}

/**
 * Implementation of hook_theme().
 */
function uc_webform_pane_theme() {
  $theme = array(
    'uc_webform_pane_order_view' => array(
      'arguments' => array(
        'data' => NULL,
      ),
    ),
  );
  return $theme;
}

/**
 * Implementation of hook_form_alter().
 */
function uc_webform_pane_form_alter(&$form, &$form_state, $form_id) {

  // Make sure the webform form supports files.
  if ($form_id == 'uc_cart_checkout_form') {
    $form['#attributes']['enctype'] = 'multipart/form-data';
  }

  // Add a config option to webform nodes to enable them as checkout panes.
  if ($form_id == 'webform_node_form') {
    $form['webform']['advanced']['uc_webform_pane'] = array(
      '#type' => 'checkbox',
      '#return_value' => 1,
      '#default_value' => uc_webform_pane_nodestatus($form['nid']['#value']),
      '#title' => t('Generate a checkout pane'),
      '#description' => t('Allow this form to be used as a Ubercart checkout pane.'),
      '#weight' => -15,
      '#access' => user_access('administer store'),
    );
  }

  // Add access validation to all UC checkout pane webforms.
  $nid = arg(1);
  $node = node_load($nid);
  if ($node->type == 'webform' && $node->webform['uc_webform_pane']) {
    global $user;
    $form['uc_access'] = array(
      '#type' => 'hidden',
      '#value' => user_access('administer store', $user) ? '1' : '0',
    );
    $form['#validate'][] = 'uc_webform_pane_access_validate';
  }
}

/**
 * Make sure that the user trying to modify the UC checkout pane enabled webform has adequate Ubercart permissions.
 */
function uc_webform_pane_access_validate($form, $form_state) {
  if ($form_state['values']['uc_access'] === '0') {
    form_set_error('uc_access', t('This webform is used as an Ubercart checkout pane and cannot be accessed outside of Ubercart and/or without the appropriate Ubercart permissions.'));
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function uc_webform_pane_nodeapi(&$node, $op, $a3 = NULL, $a4 = NUL) {
  if ($node->type === 'webform') {
    switch ($op) {
      case 'load':
        $node->webform['uc_webform_pane'] = uc_webform_pane_nodestatus($node->nid);
        break;
      case 'update':
        if ($node->webform['uc_webform_pane']) {
          db_query("INSERT IGNORE INTO {uc_webform_pane} (nid) VALUES (%d)", $node->nid);
        }
        else {
          db_query("DELETE FROM {uc_webform_pane} WHERE nid = %d", $node->nid);
        }
        break;
      case 'insert':
        if ($node->webform['uc_webform_pane']) {
          db_query("INSERT INTO {uc_webform_pane} (nid) VALUES (%d)", $node->nid);
        }
        break;
      case 'delete':
        db_query("DELETE FROM {uc_webform_pane} WHERE nid = %d", $node->nid);
        break;
    }
  }
}

/**
 * Check if a webform node should be selectable as a checkout pane.
 */
function uc_webform_pane_nodestatus($nid) {
  $found = db_result(db_query("SELECT nid FROM {uc_webform_pane} WHERE nid = %d", $nid));
  return $found ? TRUE : FALSE;
}

/**
 * Implementation of hook_token_values().
 */
function uc_webform_pane_token_values($type, $object = NULL) {
  $values = array();
  switch ($type) {
    case 'order':
      $webforms = _uc_webform_pane_get_nodes();
      foreach ($webforms as $webform) {
        $nid = $webform->nid;
        $node = node_load($nid);
        $data = get_object_vars(_uc_webform_pane_get_data($nid, $object->order_id));
        foreach ($node->webform['components'] as $field) {
          $view_function = '_webform_table_data_' . $field['type'];
          if (function_exists($view_function)) {
            $field_data = isset($data['data'][$field['cid']]) ? $data['data'][$field['cid']] : '';
            $values['uc-webform-' . $nid . '-' . str_replace('_', '-', $field['form_key'])] = $view_function($field_data, $field);
          }
        }
      }
      break;
  }
  return $values;
}

/**
 * Implementation of hook_token_list().
 */
function uc_webform_pane_token_list($type = 'all') {
  $tokens = array();
  if ($type == 'order' || $type == 'ubercart' || $type == 'all') {
    $webforms = _uc_webform_pane_get_nodes();
    foreach ($webforms as $webform) {
      $nid = $webform->nid;
      $node = node_load($nid);
      $data = get_object_vars(_uc_webform_pane_get_data($nid, $object->order_id));
      foreach ($node->webform['components'] as $field) {
        $view_function = '_webform_table_data_' . $field['type'];
        if (function_exists($view_function)) {
          $field_data = isset($data['data'][$field['cid']]) ? $data['data'][$field['cid']] : '';
          $tokens['order']['uc-webform-' . $nid . '-' . str_replace('_', '-', $field['form_key'])] = $node->title . ': ' . $field['name'];
        }
      }
    }
  }
  return $tokens;
}

/**
 * Implementation of hook_checkout_pane().
 */
function uc_webform_pane_checkout_pane() {
  $webforms = _uc_webform_pane_get_nodes();
  $panes = array();
  foreach ($webforms as $webform) {
    $nid = $webform->nid;
    $funcname = '_uc_webform_pane_' . $nid;

    // Dynamically create callback function
    if (!function_exists($funcname)) {
      eval('function ' . $funcname . '($op, &$arg1, $arg2) { return uc_webform_pane_checkout_pane_callback(' . $nid . ',$op, $arg1, $arg2); } ');
    }
    $node = node_load($nid);
    $panes[] = array(
      'id' => 'webform_nid' . $nid,
      'callback' => $funcname,
      'title' => t($node->title),
      'desc' => t($node->body),
      'weight' => 0,
      'enabled' => FALSE,
      'process' => TRUE,
      'collapsible' => TRUE,
    );
  }
  return $panes;
}

/**
 * Checkout Pane callback for dynamic callback function.
 * 
 * @link http://www.ubercart.org/docs/developer/245/checkout.
 * @param $arg1 is the current order object if it exists.
 * @param $arg2 is the contents of the array of the submitted form information for that pane. 
 */
function uc_webform_pane_checkout_pane_callback($nid, $op, &$arg1, $arg2) {
  switch ($op) {
    case 'view':
      $form = _uc_webform_pane_edit_form($nid, $arg1->order_id);
      $node = node_load($nid);
      return array(
        'contents' => $form,
        'description' => t($node->body),
      );
      break;
    case 'process':
      _uc_webform_pane_save($nid, $arg1->order_id, $arg2);

      // save to database
      return TRUE;
      break;
    case 'review':
      return _uc_webform_pane_render($nid, $arg1->order_id);
      break;
    default:
      break;
  }
}

/**
 * Implementation of hook_order_pane().
 */
function uc_webform_pane_order_pane() {
  $webforms = _uc_webform_pane_get_nodes();
  $panes = array();
  foreach ($webforms as $webform) {
    $nid = $webform->nid;
    $funcname = '_uc_webform_order_pane_' . $nid;

    // Dynamically create callback function
    if (!function_exists($funcname)) {
      eval('function ' . $funcname . '($op, $arg1) { return uc_webform_pane_order_pane_callback(' . $nid . ',$op, $arg1); } ');
    }
    $node = node_load($nid);
    $panes[] = array(
      'id' => 'webform_nid' . $nid,
      'callback' => $funcname,
      'title' => $node->title,
      'class' => 'abs-left',
      'weight' => 7,
      'show' => array(
        'view',
        'edit',
      ),
    );
  }
  return $panes;
}

/**
 * Order Pane callback for dynamic order callback function.
 */
function uc_webform_pane_order_pane_callback($nid, $op, $arg1) {
  switch ($op) {
    case 'view':
      $data = _uc_webform_pane_render($nid, $arg1->order_id);
      return theme('uc_webform_pane_order_view', $data);
      break;
    case 'edit-form':
      $webform = _uc_webform_pane_edit_form($nid, $arg1->order_id);
      $node = node_load($nid);
      $form['webform_nid' . $nid] = array(
        '#type' => 'fieldset',
        '#title' => t("Modify '" . $node->title . "' information"),
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );
      foreach ($webform as $field_id => $field_settings) {
        $form['webform_nid' . $nid][$field_id] = $field_settings;
      }
      return $form;
      break;
    case 'edit-theme':
      $output = '<div id="webform-' . $nid . '-select"></div><table class="uc-webform-edit-table">';
      foreach (element_children($arg1['webform_nid' . $nid]) as $field) {
        if ($arg1['webform_nid' . $nid][$field]['#type'] == 'hidden') {
          $output .= drupal_render($arg1['webform_nid' . $nid][$field]);
        }
        else {
          $title = $arg1['webform_nid' . $nid][$field]['#title'];
          $arg1['webform_nid' . $nid][$field]['#title'] = NULL;
          $output .= '<tr><td class="uwet-label">' . $title . ':</td><td>' . drupal_render($arg1['webform_nid' . $nid][$field]) . '</td></tr>';
        }
      }
      $output .= '</table>';
      return $output;
      break;
    case 'edit-process':
      _uc_webform_pane_save($nid, $arg1['order_id'], $arg1);
      break;
  }
}

/**
 * Implementation of hook_order().
 */
function uc_webform_pane_order($op, &$arg1, $arg2) {
  switch ($op) {

    // Delete from the database.
    case 'delete':
      include_once drupal_get_path('module', 'webform') . "/webform_submissions.inc";
      $uc_wf_subs = db_query("SELECT nid, sid FROM {uc_webform_pane_submissions} WHERE order_id = %d", $arg1->order_id);
      while ($uc_wf_sub = db_fetch_object($uc_wf_subs)) {
        $node = node_load($uc_wf_sub->nid);
        $submission = webform_get_submission($uc_wf_sub->nid, $uc_wf_sub->sid);
        webform_submission_delete($node, $submission);
      }
      db_query("DELETE FROM {uc_webform_pane_submissions} WHERE order_id = %d", $arg1->order_id);
      break;
  }
}

/**
 * Save pane values as webform submission through Webform submit handler.
 */
function _uc_webform_pane_save($nid, $order_id, $values) {

  // reset keys (remove "webform_" prefix)
  foreach ($values as $k => $v) {
    if (substr($k, 0, 8) == 'webform_') {
      $values[substr($k, 8)] = $v;
    }
    unset($values[$k]);
  }
  if ($sid = _uc_webform_pane_get_sid($nid, $order_id)) {
    $formnode = node_load($nid);
    foreach ($values as $form_key => $value) {
      $cid = webform_get_cid($formnode, $form_key, 0);
      $submitted[$cid] = $value;
    }
    include_once drupal_get_path('module', 'webform') . "/webform_submissions.inc";
    webform_submission_update($formnode, $sid, $submitted);
  }
  else {
    $form_values['op'] = t('Submit');
    $form_values['submitted'] = $values;
    $form_values['details']['nid'] = $nid;
    $form_state = array();
    $form_state['values'] = $form_values;
    webform_client_form_submit(NULL, $form_state);
    $sid = $form_state['values']['details']['sid'];
    db_query("INSERT INTO {uc_webform_pane_submissions} (nid, sid, order_id) VALUES (%d, %d, %d)", $nid, $sid, $order_id);
  }
}

/**
 * Return webform submission id.
 */
function _uc_webform_pane_get_sid($nid, $order_id) {
  return db_result(db_query("SELECT sid FROM {uc_webform_pane_submissions} WHERE nid = %d AND order_id = %d", $nid, $order_id));
}

/**
 * Return webform submission data.
 */
function _uc_webform_pane_get_data($nid, $order_id) {
  if ($sid = _uc_webform_pane_get_sid($nid, $order_id)) {
    include_once drupal_get_path('module', 'webform') . "/webform_submissions.inc";
    return webform_get_submission($nid, $sid);
  }
  $empty = new stdClass();
  return $empty;
}

/**
 * Return list of webform nodes.
 */
function _uc_webform_pane_get_nodes($join_type = 'INNER') {
  $webforms = array();
  $q = db_query(db_rewrite_sql("SELECT n.nid, uc.nid AS uc_nid\n  FROM {node} n \n  {$join_type} JOIN {uc_webform_pane} uc ON (n.nid = uc.nid)\n  WHERE n.type = 'webform' AND n.status = 1 ORDER BY n.title DESC"));
  while ($webform = db_fetch_object($q)) {
    $webforms[] = $webform;
  }
  return $webforms;
}

/**
 * Render webform submission data.
 */
function _uc_webform_pane_render($nid, $order_id) {
  $node = node_load($nid);
  $form_state = array();
  $form = webform_client_form($form_state, $node, NULL);
  $form = $form['submitted'];
  $data = get_object_vars(_uc_webform_pane_get_data($nid, $order_id));
  $output = array();
  foreach ($node->webform['components'] as $field) {
    if (isset($form[$field['form_key']]) && $field['type'] != 'hidden') {
      $view_function = '_webform_table_data_' . $field['type'];
      if (function_exists($view_function)) {
        $field_data = isset($data['data'][$field['cid']]) ? $data['data'][$field['cid']] : NULL;
        $submission_output = $view_function($field_data, $field);
        if ($submission_output !== NULL) {
          $output[] = array(
            'title' => $field['name'],
            'data' => $submission_output,
          );
        }
      }
    }
  }
  return $output;
}

/**
 * Theme webform submission data on the order view page.
 */
function theme_uc_webform_pane_order_view($data) {
  $output = '<table>';
  foreach ($data as $row) {
    $border = '';
    if (isset($row['border'])) {
      $border = ' class="row-border-' . $row['border'] . '"';
    }
    $output .= '<tr valign="top"' . $border . '><td class="title-col" ' . 'nowrap>' . $row['title'] . ':</td><td class="data-col">' . $row['data'] . '</td></tr>';
  }
  $output .= '</table>';
  return $output;
}

/**
 * Generate a form to edit webform submission data.
 */
function _uc_webform_pane_edit_form($nid, $order_id) {
  $node = node_load($nid);
  if (!$node->webform['components']) {
    return array();
  }
  $form_state = array();
  $form = webform_client_form($form_state, $node, NULL, TRUE);
  $form = $form['submitted'];
  unset($form['#tree']);

  // Assign default values to webform
  if ($order_id) {
    $data = get_object_vars(_uc_webform_pane_get_data($nid, $order_id));
    foreach ($node->webform['components'] as $field) {
      if (isset($form[$field['form_key']]) && isset($form[$field['form_key']]['#default_value'])) {
        $default = $data['data'][$field['cid']]['value'];

        // options require safe key name
        if (is_array($default) && (count($default) > 1 || in_array($form[$field['form_key']]['#type'], array(
          'radios',
          'select',
        )))) {
          $default = array_filter($default);
          foreach ($default as $optk => $optv) {
            $default[$optk] = _webform_safe_name($optv);
          }
        }
        if (count($default) == 1) {
          $default = $default[0];
        }
        $form[$field['form_key']]['#default_value'] = $default;
      }
    }
  }

  // Cannot begin with a number
  foreach ($form as $k => $v) {
    $form["webform_{$k}"] = $v;
    unset($form[$k]);
  }
  return $form;
}

Functions

Namesort descending Description
theme_uc_webform_pane_order_view Theme webform submission data on the order view page.
uc_webform_pane_access_validate Make sure that the user trying to modify the UC checkout pane enabled webform has adequate Ubercart permissions.
uc_webform_pane_checkout_pane Implementation of hook_checkout_pane().
uc_webform_pane_checkout_pane_callback Checkout Pane callback for dynamic callback function.
uc_webform_pane_form_alter Implementation of hook_form_alter().
uc_webform_pane_init Implementation of hook_init().
uc_webform_pane_nodeapi Implementation of hook_nodeapi().
uc_webform_pane_nodestatus Check if a webform node should be selectable as a checkout pane.
uc_webform_pane_order Implementation of hook_order().
uc_webform_pane_order_pane Implementation of hook_order_pane().
uc_webform_pane_order_pane_callback Order Pane callback for dynamic order callback function.
uc_webform_pane_theme Implementation of hook_theme().
uc_webform_pane_token_list Implementation of hook_token_list().
uc_webform_pane_token_values Implementation of hook_token_values().
_uc_webform_pane_edit_form Generate a form to edit webform submission data.
_uc_webform_pane_get_data Return webform submission data.
_uc_webform_pane_get_nodes Return list of webform nodes.
_uc_webform_pane_get_sid Return webform submission id.
_uc_webform_pane_render Render webform submission data.
_uc_webform_pane_save Save pane values as webform submission through Webform submit handler.