View source
<?php
require_once drupal_get_path('module', 'webform') . '/components/select.inc';
function _webform_defaults_productfield() {
return array(
'name' => '',
'form_key' => NULL,
'mandatory' => 0,
'pid' => 0,
'weight' => 0,
'value' => '',
'extra' => array(
'items' => '',
'product_type' => '',
'multiple' => NULL,
'choose_quantity' => NULL,
'aslist' => NULL,
'optrand' => 0,
'other_option' => NULL,
'other_text' => t('Other...'),
'title_display' => 0,
'description' => '',
'custom_keys' => FALSE,
'options_source' => '',
'private' => FALSE,
),
);
}
function _webform_edit_productfield($component) {
$form = array();
$items = isset($component['extra']['items']) && is_array($component['extra']['items']) ? $component['extra']['items'] : array();
$product_ids = array();
$skus = array();
foreach ($items as $item) {
$product_ids[] = $item['product_id'];
$skus[] = $item['sku'];
}
$form['extra']['product_type'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => commerce_product_type_options_list(),
'#title' => t('Product type'),
'#default_value' => $component['extra']['product_type'],
'#description' => t('Use either this OR the product skus field below. By selecting a product type here, all products of this type will be available for selection on the webform.'),
'#weight' => 4,
);
$form['extra']['items'] = array(
'#type' => 'textfield',
'#title' => t('Product skus'),
'#description' => t('Use this instead of setting a product type above. List the product skus you would like to offer as options on this webform. When the webform is saved, the user has that product added to thier basket.'),
'#default_value' => implode(', ', $skus),
'#autocomplete_path' => 'commerce_webform/autocomplete',
'#size' => 128,
'#maxlength' => 2048,
'#element_validate' => array(
'_webform_edit_validate_productfield',
),
'#weight' => 5,
);
$form['value'] = array(
'#type' => 'textfield',
'#title' => t('Default sku'),
'#default_value' => $component['value'],
'#description' => t('Enter the product sku which should be selected by default or leave blank for no default. You can also use webform tokens like %get[sku] to get the sku from the URL query string.'),
'#size' => 60,
'#maxlength' => 1024,
'#weight' => 3,
);
$form['extra']['choose_quantity'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the user to set the quantity.'),
'#default_value' => empty($component['extra']['choose_quantity']) ? 0 : $component['extra']['choose_quantity'],
'#description' => t('Check this option if the user should be allowed to set the number of products selected. The default is 1 for single selections and 0 if it is possbile to select multiple products.'),
'#weight' => 0,
);
$form['extra']['multiple'] = array(
'#type' => 'checkbox',
'#title' => t('Multiple'),
'#default_value' => $component['extra']['multiple'],
'#description' => t('Check this option if the user should be allowed to choose multiple values.'),
'#weight' => 0,
);
$form['display']['aslist'] = array(
'#type' => 'checkbox',
'#title' => t('Listbox'),
'#default_value' => $component['extra']['aslist'],
'#description' => t('Check this option if you want the select component to be of listbox type instead of radio buttons or checkboxes.'),
'#weight' => 0,
'#parents' => array(
'extra',
'aslist',
),
);
return $form;
}
function _webform_edit_validate_productfield($element, &$form_state) {
if (!empty($element['#value'])) {
$typed_skus = drupal_explode_tags($element['#value']);
$value = array();
foreach ($typed_skus as $typed_sku) {
if ($product = commerce_product_load_by_sku(trim($typed_sku))) {
$value[$product->product_id] = array(
'product_id' => $product->product_id,
'title' => $product->title,
'sku' => $product->sku,
'type' => $product->type,
);
}
}
}
else {
$value = array();
}
form_set_value($element, $value, $form_state);
}
function _webform_render_productfield($component, $value = NULL, $filter = TRUE) {
$node = isset($component['nid']) ? node_load($component['nid']) : NULL;
$items = isset($component['extra']['items']) ? $component['extra']['items'] : array();
$multiple = $component['extra']['multiple'];
$choose_quantity = !empty($component['extra']['choose_quantity']);
$product_type = $component['extra']['product_type'];
$hidden_elements_html = '';
$options = array();
if ($multiple != '1') {
$options[''] = ' - ' . (empty($component['mandatory']) ? t('None') : t('Select')) . ' - ';
}
$product_ids = array();
if (empty($product_type)) {
foreach ($items as $item) {
$product_ids[] = $item['product_id'];
}
}
else {
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', 'commerce_product')
->entityCondition('bundle', $product_type)
->execute();
if (!empty($result['commerce_product'])) {
$product_ids = array_keys($result['commerce_product']);
}
}
$products = commerce_product_load_multiple($product_ids);
foreach ($products as $product) {
if ($product->status == 1) {
$price = commerce_product_calculate_sell_price($product);
$options[$product->product_id] = theme('commerce_webform_product_display', array(
'product' => $product,
'price' => $price,
'component' => $component,
));
$hidden_elements_html .= "<input type='hidden' name='commerce_webform_product[{$product->product_id}]' value='{$price['amount']}' />\n";
}
}
$default_product_ids = $multiple ? array() : 0;
$default_quantities = $multiple ? array() : 1;
$disabled = FALSE;
if (!empty($value)) {
foreach ($value as $id => $encoded_details) {
$details = json_decode($encoded_details);
if ($details->paid && !user_access('alter product field on paid webform')) {
$disabled = TRUE;
}
if ($multiple) {
$default_product_ids[] = $details->product_id;
if ($choose_quantity) {
$default_quantities[$details->product_id] = $details->quantity;
}
else {
$default_quantities = $details->quantity;
}
}
else {
$default_product_ids = $details->product_id;
$default_quantities = $details->quantity;
}
}
}
elseif (!empty($component['value'])) {
$defaults = explode(',', _webform_filter_values($component['value']));
foreach ($defaults as $default) {
$product = commerce_product_load_by_sku(trim($default));
if (!empty($product) && array_key_exists($product->product_id, $options)) {
if ($component['extra']['multiple']) {
$default_product_ids[] = $product->product_id;
if ($choose_quantity) {
$default_quantities[$product->product_id] = 1;
}
}
else {
$default_product_ids = $product->product_id;
}
}
}
}
$element = array(
'#weight' => $component['weight'],
);
if (!$multiple || !$choose_quantity) {
if ($disabled) {
$rows = array();
$element[] = array(
'#type' => 'value',
'#value' => $default_product_ids,
);
$element[] = array(
'#type' => 'value',
'#value' => $default_quantities,
);
if (is_array($default_product_ids)) {
foreach ($default_product_ids as $product_id) {
$rows[] = array(
$product_id,
$options[$product_id],
$default_quantities,
);
}
}
elseif ($default_product_ids > 0) {
$rows[] = array(
$default_product_ids,
$options[$default_product_ids],
$default_quantities,
);
}
$element['#markup'] = '<strong>' . _webform_filter_xss($component['name']) . '</strong>';
$element['#markup'] .= theme('table', array(
'header' => array(
'Product ID',
'Product name',
'Quantity',
),
'rows' => $rows,
));
$element['#markup'] .= '<p>' . t('This order has been completed and products choices cannot be edited online.') . '</p>';
}
else {
$element[] = array(
'#type' => $component['extra']['aslist'] ? 'select' : ($component['extra']['multiple'] ? 'checkboxes' : 'radios'),
'#multiple' => $component['extra']['multiple'],
'#size' => $component['extra']['aslist'] && $component['extra']['multiple'] ? 4 : 0,
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
'#required' => $component['mandatory'],
'#weight' => $component['weight'],
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
'#translatable' => array(
'title',
'description',
'options',
),
'#options' => $options,
'#default_value' => $default_product_ids,
'#prefix' => '<div class="commerce_webform_products">',
'#suffix' => $hidden_elements_html . '</div>',
'#pre_render' => array(),
'#theme_wrappers' => array(
'webform_element',
),
'#element_validate' => array(
'_webform_productfield_selection_validate',
),
);
$editable = empty($component['extra']['multiple']) && !empty($component['extra']['choose_quantity']);
$element[] = array(
'#type' => $editable ? 'textfield' : 'value',
'#title' => t('@product quantity', array(
'@product' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
)),
'#default_value' => $choose_quantity ? is_array($default_quantities) ? 1 : $default_quantities : 1,
'#element_validate' => array(
'_webform_productfield_quantity_validate',
),
'#required' => $component['mandatory'],
'#weight' => $component['weight'] + 0.5,
);
}
}
else {
$i = 1;
if ($disabled) {
$rows = array();
foreach ($default_quantities as $product_id => $quantity) {
$element[$product_id] = array(
'#type' => 'value',
'#value' => $quantity,
);
$rows[] = array(
$product_id,
$options[$product_id],
$quantity,
);
}
$element['#markup'] = '<strong>' . _webform_filter_xss($component['name']) . '</strong>';
$element['#markup'] .= theme('table', array(
'header' => array(
'Product ID',
'Product name',
'Quantity',
),
'rows' => $rows,
));
$element['#markup'] .= '<p>' . t('This order has been completed and products choices cannot be edited online.') . '</p>';
}
else {
$element = array(
'#type' => 'fieldset',
'#title' => _webform_filter_xss($component['name']),
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
'#element_validate' => array(
'_webform_productfield_required_multiple_quantities_validate',
),
'#required' => $component['mandatory'],
'#weight' => $component['weight'],
'#pre_render' => array(
'webform_element_title_display',
),
);
foreach ($options as $product_id => $product_name) {
$element[$product_id] = array(
'#type' => 'textfield',
'#title' => $product_name,
'#title_display' => 'after',
'#size' => 2,
'#default_value' => isset($default_quantities[$product_id]) ? $default_quantities[$product_id] : 0,
'#element_validate' => array(
'_webform_productfield_quantity_validate',
),
'#weight' => $component['weight'] + ('0.' . $i),
);
$i++;
}
}
}
return $element;
}
function _webform_display_productfield($component, $value, $format = 'html') {
$options = array();
foreach ($component['extra']['items'] as $product_id => $details) {
$options[$product_id] = "{$details['sku']}: {$details['title']} ";
}
return array(
'#title' => $component['name'],
'#weight' => $component['weight'],
'#theme' => 'webform_display_productfield',
'#theme_wrappers' => $format == 'html' ? array(
'webform_element',
) : array(
'webform_element_text',
),
'#format' => $format,
'#options' => $options,
'#value' => (array) $value,
'#translatable' => array(
'title',
'options',
),
);
}
function _webform_submit_productfield($component, $value) {
$return = array();
$multiple = $component['extra']['multiple'];
$choose_quantity = !empty($component['extra']['choose_quantity']);
if ($multiple && $choose_quantity) {
foreach ($value as $product_id => $quantity) {
if ($quantity > 0) {
$details = array(
'product_id' => $product_id,
'quantity' => $quantity,
'order_id' => FALSE,
'line_item_id' => FALSE,
'paid' => FALSE,
);
$return[] = json_encode($details);
}
}
}
else {
if (is_array($value[0])) {
foreach ($value[0] as $id => $product_id) {
$details = array(
'product_id' => $product_id,
'quantity' => 1,
'order_id' => FALSE,
'line_item_id' => FALSE,
'paid' => FALSE,
);
$return[] = json_encode($details);
}
}
else {
$details = array(
'product_id' => $value[0],
'quantity' => empty($value[0]) ? '0' : $value[1],
'order_id' => FALSE,
'line_item_id' => FALSE,
'paid' => FALSE,
);
$return[] = json_encode($details);
}
}
return $return;
}
function theme_webform_display_productfield($variables) {
$element = $variables['element'];
$options = $element['#options'];
$items = array();
foreach ($element['#value'] as $value) {
$value = json_decode($value);
if (!empty($value->product_id)) {
if (isset($options[$value->product_id])) {
$paid_display_option = empty($value->paid) ? t('Unpaid') : t('Paid');
$paid_display_option = empty($value->order_id) ? $paid_display_option : l($paid_display_option, "admin/commerce/orders/{$value->order_id}/view");
$name = _webform_filter_xss($options[$value->product_id]);
$items[] = "{$value->quantity} x {$name} (<strong>{$paid_display_option}</strong>)";
}
else {
$items[] = check_plain($value->product_id);
}
}
}
if ($element['#format'] == 'html') {
$output = count($items) > 1 ? theme('item_list', array(
'items' => $items,
)) : (isset($items[0]) ? $items[0] : t('Not selected'));
}
else {
if (count($items) > 1) {
foreach ($items as $key => $item) {
$items[$key] = ' - ' . $item;
}
$output = implode("\n", $items);
}
else {
$output = isset($items[0]) ? $items[0] : t('Not selected');
}
}
return $output;
}
function _webform_analysis_productfield($component, $sids = array(), $single = FALSE) {
$query = db_select('webform_submitted_data', 'wsd', array(
'fetch' => PDO::FETCH_ASSOC,
))
->fields('wsd', array(
'data',
))
->condition('nid', $component['nid'])
->condition('cid', $component['cid'])
->condition('data', '', '<>')
->groupBy('data');
if (count($sids)) {
$query
->condition('sid', $sids, 'IN');
}
$results = $query
->execute();
$rows = array();
foreach ($results as $result) {
$submission = json_decode($result['data']);
if (isset($component['extra']['items'][$submission->product_id])) {
$display_option = _webform_filter_xss($component['extra']['items'][$submission->product_id]['title']);
$paid_display_option = !empty($submission->paid) ? 'Paid' : 'Unpaid';
if (isset($rows[$submission->product_id . '_' . $paid_display_option])) {
$rows[$submission->product_id . '_' . $paid_display_option]++;
}
else {
$rows[$submission->product_id . '_' . $paid_display_option] = array(
$display_option . ' (' . _webform_filter_xss(t($paid_display_option)) . ')',
1,
);
}
}
}
return $rows;
}
function _webform_table_productfield($component, $value) {
$options = $component['extra']['items'];
$value = (array) $value;
$items = array();
foreach ($value as $option_value) {
$option_value = json_decode($option_value);
if (!empty($option_value->product_id)) {
if (isset($options[$option_value->product_id])) {
$item = $option_value->quantity . ' x ' . _webform_filter_xss($options[$option_value->product_id]['title']);
}
else {
$item = check_plain($option_value->product_id);
}
$paid_display_option = empty($option_value->paid) ? t('Unpaid') : t('Paid');
$paid_display_option = empty($option_value->order_id) ? $paid_display_option : l($paid_display_option, "admin/commerce/orders/{$option_value->order_id}/view");
$item .= " (<strong>{$paid_display_option}</strong>)";
$items[] = $item;
}
}
return implode('<br />', $items);
}
function _webform_csv_headers_productfield($component, $export_options) {
$options = $component['extra']['items'];
$headers = array(
0 => array(),
1 => array(),
2 => array(),
);
$headers[0][] = '';
$headers[1][] = '';
foreach ($options as $product_id => $details) {
$headers[2][] = $details['sku'] . ': PAID';
$headers[2][] = $details['sku'] . ': UNPAID';
}
return $headers;
}
function _webform_csv_data_productfield($component, $export_options, $values) {
$options = $component['extra']['items'];
foreach ($values as $id => $value) {
$values[$id] = json_decode($value);
}
$return = array();
foreach ($options as $key => $item) {
$index = FALSE;
foreach ($values as $value) {
if ($value->product_id == $key) {
$index = $value;
}
}
if ($index !== FALSE) {
if (!empty($index->paid)) {
$return[] = $index->quantity;
$return[] = '0';
}
else {
$return[] = '0';
$return[] = $index->quantity;
}
}
else {
$return[] = '0';
$return[] = '0';
}
}
return $return;
}
function _webform_productfield_quantity_validate($element, &$form_state, $form) {
$value = $form_state['values'];
foreach ($element['#parents'] as $parent) {
$value = $value[$parent];
}
$name = implode('][', $element['#parents']);
if (!isset($value) || empty($value)) {
$value = 0;
}
if (!is_numeric($value)) {
form_set_error($name, 'Quantity must be a number.');
}
elseif ($element['#required'] && $value < 1) {
form_set_error($name, 'Quantity must be greater than 0.');
}
elseif ($element['#required'] && $value < 0) {
form_set_error($name, 'Quantity must be a positive number or 0.');
}
}
function _webform_productfield_selection_validate($element, &$form_state, $form) {
if ($element['#required'] && $element['#multiple'] == '0') {
$value = $form_state['values'];
$name = '';
foreach ($element['#parents'] as $index => $container) {
$value = $value[$container];
$name .= !empty($name) ? '][' : '';
$name .= $element['#parents'][$index];
}
if (!isset($value[0]) || $value[0] < 1) {
form_set_error($name, t('!name field is required', array(
'!name' => $element['#title'],
)));
}
}
}
function _webform_productfield_required_multiple_quantities_validate($element, &$form_state, $form) {
if ($element['#required']) {
$form_key = $element['#webform_component']['form_key'];
foreach ($form_state['values']['submitted'][$form_key] as $product_id => $quantity) {
if ($quantity > 0) {
return;
}
}
$name = implode('][', $element['#parents']);
form_set_error($name, t('You must choose at least one product from this selection by setting its quantity to something greater than 1'));
}
}
function theme_commerce_webform_product_display($variables) {
$product = $variables['product'];
$price = $variables['price'];
return filter_xss($product->title) . ' [' . commerce_currency_format($price['amount'], $price['currency_code'], $product) . ']';
}