uc_webform_pane.module in Ubercart Webform Checkout Pane 7.3
Same filename and directory in other branches
uc_webform_pane.module Ubercart Webform Checkout Pane.
@note Ubercart webform data is stored in database during checkout, even when order is not complete.
File
uc_webform_pane.moduleView source
<?php
/**
* @file uc_webform_pane.module
* Ubercart Webform Checkout Pane.
*
* @note Ubercart webform data is stored in database during checkout, even when order is not complete.
*/
/**
* Implements hook_theme().
*/
function uc_webform_pane_theme() {
$theme = array(
'uc_webform_pane_order_view' => array(
'variables' => array(
'data' => NULL,
),
),
);
return $theme;
}
/**
* Implements hook_form_alter().
*/
function uc_webform_pane_form_alter(&$form, &$form_state, $form_id) {
global $user;
// Make sure the webform form supports files.
if ($form_id == 'uc_cart_checkout_form' || $form_id == 'uc_order_edit_form') {
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['#process'][] = 'webform_client_form_includes';
}
// Support for Webform Validation module
if ($form_id == 'uc_cart_checkout_form' && function_exists('webform_validation_validate')) {
$form['#validate'][] = 'uc_webform_pane_wv_validate';
}
// Make sure the webform form supports files.
if ($form_id == 'uc_order_edit_form') {
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['#process'][] = 'webform_client_form_includes';
}
// Add a config option to webform nodes to enable them as checkout panes.
if ($form_id == 'webform_configure_form') {
$form['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'),
);
$form['#submit'][] = 'uc_webform_pane_webform_configure_form_submit';
}
// Add access validation to all UC checkout pane webforms.
if (preg_match('|webform_.*_form|', $form_id)) {
$nid = arg(1);
if (uc_webform_pane_nodestatus($nid)) {
$form['uc_access'] = array(
'#type' => 'hidden',
'#value' => user_access('administer store', $user) ? '1' : '0',
);
$form['#validate'][] = 'uc_webform_pane_access_validate';
}
}
}
/**
* Send the values of each Webform Pane through to Webform Validation checkers.
*/
function uc_webform_pane_wv_validate($form, &$form_state) {
$panes = $form_state['values']['panes'];
if (!$panes) {
return;
}
foreach ($panes as $paneid => $values) {
if (drupal_substr($paneid, 0, 11) == 'webform_nid') {
$nid = drupal_substr($paneid, 11);
$pane_values = array();
$pane_values['op'] = t('Submit');
$pane_values['submitted'] = $values;
$pane_values['details']['nid'] = $nid;
$pane_state = array();
$pane_state['values'] = $pane_values;
webform_validation_validate($form, $pane_state);
}
}
}
/**
* 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.'));
}
}
/**
* Mark the webform as a potential checkout pane.
*/
function uc_webform_pane_webform_configure_form_submit($form, &$form_state) {
if ($form_state['values']['uc_webform_pane']) {
db_merge('uc_webform_pane')
->key(array(
'nid' => $form_state['values']['nid'],
))
->execute();
}
else {
db_delete('uc_webform_pane')
->condition('nid', $form_state['values']['nid'])
->execute();
}
}
/**
* Implements hook_node_prepare().
*/
function uc_webform_pane_node_prepare($node) {
if (in_array($node->type, webform_variable_get('webform_node_types'))) {
$node->webform['uc_webform_pane'] = isset($node->nid) ? uc_webform_pane_nodestatus($node->nid) : FALSE;
}
}
/**
* Implements hook_node_delete().
*/
function uc_webform_pane_node_delete($node) {
if (in_array($node->type, webform_variable_get('webform_node_types'))) {
db_delete('uc_webform_pane')
->condition('nid', $node->nid)
->execute();
}
}
/**
* Check if a webform node should be selectable as a checkout pane.
*/
function uc_webform_pane_nodestatus($nid) {
$found = db_select('uc_webform_pane', 'uwp')
->fields('uwp', array(
'nid',
))
->condition('nid', $nid)
->execute()
->fetchField();
return $found ? TRUE : FALSE;
}
/**
* Implements hook_token_info().
*/
function uc_webform_pane_token_info() {
$types = array();
$tokens = array();
$webforms = _uc_webform_pane_get_nodes();
foreach ($webforms as $webform) {
$nid = $webform->nid;
$node = node_load($nid);
$type = array(
'name' => $node->title,
'description' => t('Webform tokens.'),
'needs-data' => 'ucwf_' . $nid,
);
$info = array();
foreach ($node->webform['components'] as $field) {
if ($field['type'] == 'markup' || $field['type'] == 'fieldset') {
continue;
}
$info['uc-webform-' . $nid . '-' . str_replace('_', '-', $field['form_key'])] = array(
'name' => $field['name'],
'description' => '',
);
}
$types['ucwf_' . $nid] = $type;
$tokens['ucwf_' . $nid] = $info;
$tokens['uc_order']['ucwf_' . $nid] = array(
'name' => $node->title,
'description' => t('Webform tokens.'),
'type' => 'ucwf_' . $nid,
);
}
return array(
'types' => $types,
'tokens' => $tokens,
);
}
/**
* Implements hook_tokens().
*/
function uc_webform_pane_tokens($type, $tokens, $data = array(), $options = array()) {
$values = array();
if ($type == 'uc_order' && !empty($data['uc_order'])) {
$order = $data['uc_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, $order->order_id));
foreach ($node->webform['components'] as $field) {
if ($field['type'] == 'markup' || $field['type'] == 'fieldset') {
continue;
}
$field_data = isset($data['data'][$field['cid']]['value']) ? $data['data'][$field['cid']]['value'] : NULL;
$field_element = webform_component_invoke($field['type'], 'display', $field, $field_data);
$field_element['#webform_component'] = $field;
$submission_output = theme($field_element['#theme'], array(
'element' => $field_element,
));
$values['uc-webform-' . $nid . '-' . str_replace('_', '-', $field['form_key'])] = $submission_output;
}
}
}
return $values;
}
/**
* Implements hook_uc_checkout_pane().
*/
function uc_webform_pane_uc_checkout_pane() {
$panes = array();
$webforms = _uc_webform_pane_get_nodes();
foreach ($webforms as $webform) {
$nid = $webform->nid;
$funcname = '_uc_webform_pane_' . $nid;
// Dynamically create callback function
if (!function_exists($funcname)) {
eval('function ' . $funcname . '($op, $order, $form = NULL, &$form_state = NULL) { return uc_webform_pane_uc_checkout_pane_callback(' . $nid . ', $op, $order, $form, $form_state); } ');
}
$node = node_load($nid);
$body = !empty($node->body) ? $node->body[$node->language][0]['safe_value'] : '';
$panes['webform_nid' . $nid] = array(
'callback' => $funcname,
'title' => check_plain($node->title),
'desc' => $body,
'weight' => 0,
);
}
return $panes;
}
/**
* Checkout Pane callback for dynamic callback function.
*/
function uc_webform_pane_uc_checkout_pane_callback($nid, $op, $order, $form = NULL, &$form_state = NULL) {
switch ($op) {
case 'view':
$form = _uc_webform_pane_edit_form($nid, $order->order_id, 'checkout');
$node = node_load($nid);
$body = !empty($node->body) ? $node->body[$node->language][0]['safe_value'] : '';
return array(
'contents' => array(
$form,
),
'description' => $body,
);
break;
case 'process':
_uc_webform_pane_save($nid, $order->order_id, $form_state['values']['panes']['webform_nid' . $nid][0]);
// save to database
return TRUE;
break;
case 'review':
$data = _uc_webform_pane_render($nid, $order->order_id);
if ($data) {
return $data;
}
break;
default:
break;
}
}
/**
* Implements of drupal_alter('uc_checkout_pane', $panes).
*/
function uc_webform_pane_uc_checkout_pane_alter(&$panes) {
global $user;
// Validate all the webform panes individually during the checkout process
foreach ($panes as $pid => $pane) {
if ($pane['enabled'] == 1 && drupal_substr($pane['id'], 0, 11) == 'webform_nid') {
// Make sure Webform styles/scripts are shown
drupal_add_css(drupal_get_path('module', 'webform') . '/css/webform.css');
drupal_add_js(drupal_get_path('module', 'webform') . '/js/webform.js');
// Load the Webform node
$nid = drupal_substr($pane['id'], 11);
$node = node_load($nid);
// Check if this page is cached or not
$cached = $user->uid == 0 && (variable_get('cache', 0) || drupal_page_is_cacheable() === FALSE);
// Check if the webform user submission limit has already been reached
if ($node->webform['submit_limit'] != -1) {
// -1: Submissions are never throttled.
module_load_include('inc', 'webform', 'includes/webform.submissions');
// Disable the form if the limit is exceeded and page cache is not active
if (($user_limit_exceeded = _webform_submission_user_limit_check($node)) && !$cached) {
$panes[$pid]['enabled'] = FALSE;
}
}
// Check if the webform total submission limit has already been reached
if ($node->webform['total_submit_limit'] != -1) {
// -1: Submissions are never throttled.
module_load_include('inc', 'webform', 'includes/webform.submissions');
// Disable the form if the limit is exceeded and page cache is not active
if (($total_limit_exceeded = _webform_submission_total_limit_check($node)) && !$cached) {
$panes[$pid]['enabled'] = FALSE;
}
}
}
}
}
/**
* Implements of hook_uc_checkout_complete().
*/
function uc_webform_pane_uc_checkout_complete($order, $account) {
// Assign the Webform pane submissions to the newly created user
if (isset($order->data['new_user'])) {
$webforms = _uc_webform_pane_get_nodes();
foreach ($webforms as $webform) {
$nid = $webform->nid;
// Get the sid for webform submission in the current order
$sid = _uc_webform_pane_get_sid($nid, $order->order_id);
if ($sid) {
db_query("UPDATE {webform_submissions} SET uid = :uid WHERE sid = :sid", array(
':uid' => $order->uid,
':sid' => $sid,
));
}
}
}
}
/**
* Implements hook_uc_order_pane().
*/
function uc_webform_pane_uc_order_pane() {
$panes = array();
$webforms = _uc_webform_pane_get_nodes();
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, $order, &$form = NULL, &$form_state = NULL) { return uc_webform_pane_uc_order_pane_callback(' . $nid . ', $op, $order, $form, $form_state); } ');
}
$node = node_load($nid);
$body = !empty($node->body) ? $node->body[$node->language][0]['safe_value'] : '';
$panes['webform_nid' . $nid] = array(
'callback' => $funcname,
'title' => $node->title,
'desc' => $body,
'class' => 'abs-left',
'weight' => 7,
'show' => array(
'view',
'customer',
'edit',
),
);
}
return $panes;
}
/**
* Order Pane callback for dynamic order callback function.
*/
function uc_webform_pane_uc_order_pane_callback($nid, $op, $order, &$form = NULL, &$form_state = NULL) {
switch ($op) {
case 'view':
case 'customer':
$data = _uc_webform_pane_render($nid, $order->order_id);
if ($data) {
$build = array(
'#markup' => theme('uc_webform_pane_order_view', array(
'data' => $data,
)),
);
return $build;
}
break;
case 'edit-form':
$webform = _uc_webform_pane_edit_form($nid, $order->order_id, 'order');
$node = node_load($nid);
$form['webform_nid' . $nid] = array(
'#type' => 'fieldset',
'#title' => t('Modify @title information', array(
'@title' => $node->title,
)),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
foreach ($webform as $field_id => $field_settings) {
$form['webform_nid' . $nid][$field_id] = $field_settings;
}
return $form;
case 'edit-theme':
drupal_add_css(drupal_get_path('module', 'uc_webform_pane') . '/uc_webform_pane.css');
$output = '<div id="webform-' . $nid . '-select"></div><table class="uc-webform-edit-table">';
foreach (element_children($form['webform_nid' . $nid]) as $field) {
if (isset($form['webform_nid' . $nid][$field]['#type']) && in_array($form['webform_nid' . $nid][$field]['#type'], array(
'value',
'markup',
))) {
continue;
}
elseif (isset($form['webform_nid' . $nid][$field]['#type']) && $form['webform_nid' . $nid][$field]['#type'] == 'hidden') {
$output .= drupal_render($form['webform_nid' . $nid][$field]);
}
else {
$title = $form['webform_nid' . $nid][$field]['#title'];
// Process select_or_other widgets
if (isset($form['webform_nid' . $nid][$field]['select'])) {
$title = $form['webform_nid' . $nid][$field]['select']['#title'];
$form['webform_nid' . $nid][$field]['select']['#title'] = NULL;
}
$form['webform_nid' . $nid][$field]['#title'] = NULL;
$output .= '<tr><td class="uwet-label">' . check_plain($title) . ':</td><td>' . drupal_render($form['webform_nid' . $nid][$field]) . '</td></tr>';
}
}
$output .= '</table>';
return $output;
case 'edit-process':
_uc_webform_pane_save($nid, $order->order_id, $form_state['input']['webform_nid' . $nid]);
break;
}
}
/**
* Implements hook_uc_order().
*/
function uc_webform_pane_uc_order($op, &$order, $arg2) {
switch ($op) {
// Delete from the database.
case 'delete':
include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'webform') . "/includes/webform.submissions.inc";
$uc_wf_subs = db_select('uc_webform_pane_submissions', 'uwps')
->fields('uwps', array(
'nid',
'sid',
))
->condition('order_id', $order->order_id)
->execute();
foreach ($uc_wf_subs as $uc_wf_sub) {
$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_delete('uc_webform_pane_submissions')
->condition('order_id', $order->order_id)
->execute();
break;
}
}
/**
* Save pane values as webform submission through Webform submit handler.
*/
function _uc_webform_pane_save($nid, $order_id, $submitted) {
global $user;
$node = node_load($nid);
$sid = _uc_webform_pane_get_sid($nid, $order_id);
$values['op'] = t('Submit');
$values['submitted'] = $submitted;
$values['details']['uid'] = $user->uid;
$values['details']['nid'] = $nid;
$values['details']['sid'] = $sid;
$values['details']['finished'] = FALSE;
$form_state = array();
$form_state['values'] = $values;
// Perform post processing by components.
_webform_client_form_submit_process($node, $form_state['values']['submitted']);
// Flatten trees within the submission.
$form_state['values']['submitted_tree'] = $form_state['values']['submitted'];
$form_state['values']['submitted'] = _webform_client_form_submit_flatten($node, $form_state['values']['submitted']);
// Do some cleaning up before our fake submit
foreach ($form_state['values']['submitted'] as $key => $value) {
// Clean up anything that is not a Webform component
if (!is_numeric($key)) {
unset($form_state['values']['submitted'][$key]);
}
// Clean up empty values as these won't be saved anyway
if (is_array($value) && sizeof($value) == 0) {
unset($form_state['values']['submitted'][$key]);
}
}
// If the values list ends up empty, all required fields must be empty - get out
if (!$form_state['values']['submitted']) {
return;
}
// Set a flag indicating processing should continue and be saved.
$form_state['webform_completed'] = TRUE;
webform_client_form_submit(array(
'#node' => $node,
), $form_state);
if (!$sid) {
$sid = $form_state['values']['details']['sid'];
db_insert('uc_webform_pane_submissions')
->fields(array(
'nid' => $nid,
'sid' => $sid,
'order_id' => $order_id,
))
->execute();
}
}
/**
* Return webform submission id.
*/
function _uc_webform_pane_get_sid($nid, $order_id) {
return db_select('uc_webform_pane_submissions', 'uwps')
->fields('uwps', array(
'sid',
))
->condition('nid', $nid)
->condition('order_id', $order_id)
->execute()
->fetchField();
}
/**
* 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_ROOT . '/' . drupal_get_path('module', 'webform') . "/includes/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() {
$query = db_select('node', 'n')
->fields('n', array(
'nid',
))
->condition('type', webform_variable_get('webform_node_types'))
->condition('status', 1)
->orderBy('title', 'DESC');
$query
->join('uc_webform_pane', 'uwp', 'n.nid = uwp.nid');
$rs = $query
->execute();
$webforms = array();
foreach ($rs as $webform) {
$webforms[] = $webform;
}
return $webforms;
}
/**
* Render webform submission data.
*/
function _uc_webform_pane_render($nid, $order_id) {
$data = get_object_vars(_uc_webform_pane_get_data($nid, $order_id));
$output = array();
if ($data) {
$node = node_load($nid);
foreach ($node->webform['components'] as $field) {
if (!in_array($field['type'], array(
'hidden',
'markup',
'fieldset',
))) {
$field_data = isset($data['data'][$field['cid']]['value']) ? $data['data'][$field['cid']]['value'] : NULL;
$field_element = webform_component_invoke($field['type'], 'display', $field, $field_data);
$field_element['#webform_component'] = $field;
$submission_output = theme($field_element['#theme'], array(
'element' => $field_element,
));
if ($submission_output !== NULL && trim($submission_output)) {
$output[] = array(
'title' => check_plain($field['name']),
'data' => $submission_output,
);
}
}
}
}
return $output;
}
/**
* Theme webform submission data on the order view page.
*/
function theme_uc_webform_pane_order_view($variables) {
$data = $variables['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, $pane_type) {
// Load the node and make sure it's a Webform
$node = node_load($nid);
if (!$node->webform['components']) {
return array();
}
$submission = _uc_webform_pane_get_data($nid, $order_id);
// Mark the node as a checkout pane
$node->in_checkout = TRUE;
// Load the Webform
$form_state = array(
'method' => 'post',
);
$form_state['build_info']['args'] = array(
$node,
$submission,
);
$form = drupal_retrieve_form('webform_client_form_' . $node->nid, $form_state);
drupal_prepare_form('webform_client_form_' . $node->nid, $form, $form_state);
// Remove some things that get in the way
foreach (array(
'details',
'form_id',
'form_token',
'form_build_id',
'actions',
'#parents',
'#theme',
'#tree',
'#id',
'#type',
'#theme_wrappers',
) as $key) {
unset($form[$key]);
}
// Wrap the form in same id's as it would be as a real Webform
$form['#prefix'] = '<div id="webform-client-form-' . $nid . '">';
$form['#suffix'] = '</div>';
foreach ($form['submitted'] as $key => $field) {
$form[$key] = $field;
}
unset($form['submitted']);
// Prepare form fields for processing using UCWP
_uc_webform_pane_edit_form_prepare($form, $pane_type);
return $form;
}
/**
* Prepare form fields for processing using UCWP.
*/
function _uc_webform_pane_edit_form_prepare(&$form, $pane_type) {
foreach (element_children($form) as $k) {
$form[$k]["#validated"] = FALSE;
if ($pane_type == 'order') {
$form[$k]["#required"] = FALSE;
}
if (isset($form[$k]["#type"]) && $form[$k]["#type"] == 'fieldset') {
_uc_webform_pane_edit_form_prepare($form[$k], $pane_type);
}
}
}
Functions
Name![]() |
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_form_alter | Implements hook_form_alter(). |
uc_webform_pane_nodestatus | Check if a webform node should be selectable as a checkout pane. |
uc_webform_pane_node_delete | Implements hook_node_delete(). |
uc_webform_pane_node_prepare | Implements hook_node_prepare(). |
uc_webform_pane_theme | Implements hook_theme(). |
uc_webform_pane_tokens | Implements hook_tokens(). |
uc_webform_pane_token_info | Implements hook_token_info(). |
uc_webform_pane_uc_checkout_complete | Implements of hook_uc_checkout_complete(). |
uc_webform_pane_uc_checkout_pane | Implements hook_uc_checkout_pane(). |
uc_webform_pane_uc_checkout_pane_alter | Implements of drupal_alter('uc_checkout_pane', $panes). |
uc_webform_pane_uc_checkout_pane_callback | Checkout Pane callback for dynamic callback function. |
uc_webform_pane_uc_order | Implements hook_uc_order(). |
uc_webform_pane_uc_order_pane | Implements hook_uc_order_pane(). |
uc_webform_pane_uc_order_pane_callback | Order Pane callback for dynamic order callback function. |
uc_webform_pane_webform_configure_form_submit | Mark the webform as a potential checkout pane. |
uc_webform_pane_wv_validate | Send the values of each Webform Pane through to Webform Validation checkers. |
_uc_webform_pane_edit_form | Generate a form to edit webform submission data. |
_uc_webform_pane_edit_form_prepare | Prepare form fields for processing using UCWP. |
_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. |