'', 'form_key' => NULL, 'pid' => 0, 'weight' => 0, 'value' => '', 'mandatory' => 0, 'extra' => array( 'options' => '', 'questions' => '', 'optrand' => 0, 'qrand' => 0, 'title_display' => 0, 'custom_option_keys' => 0, 'custom_question_keys' => 0, 'description' => '', 'attributes' => array(), 'private' => FALSE, 'products' => NULL, ), ); } // Product Grid depends on functions provided by select. webform_component_include('select'); /** * Implements _webform_theme_component(). */ function _webform_theme_product_grid() { return array( 'uc_webform_render_product_grid' => array( 'render element' => 'element', 'file' => 'components/product_grid.inc', 'path' => drupal_get_path('module', 'uc_webform'), ), 'uc_webform_display_product_grid' => array( 'render element' => 'element', 'file' => 'components/product_grid.inc', 'path' => drupal_get_path('module', 'uc_webform'), ), ); } /** * Implements _webform_edit_component(). */ function theme_uc_webform_render_product_grid($element) { // TODO: Should this theme uc_webform_render_product_grid be declared in // hook_theme()? $temp_rows = array(); $columns = array(array( 'data' => '', 'class' => 'uc_webform-product-grid-product', )); $option_ids = array(); $product_keys = element_children($element['element']); // This loop creates the row at the top (which is a list of product options) // and the first column on the left (which is the product title column). foreach (element_children($element['element']) as $key) { $product_element = $element['element'][$key]; // Create a row with the Product title. $row = array(array( 'data' => $product_element['#title'], 'class' => 'uc_webform-product-grid-product', 'product' => "$key", )); foreach ($product_element['#options'] as $optionid => $opt_val) { if (!in_array($optionid, $option_ids)) { $columns[] = array( 'data' => $opt_val, 'class' => 'checkbox uc_webform-product-grid-option', 'oid' => $optionid, ); } $option_ids[] = $optionid; } $temp_rows[] = $row; } $final_rows = array(); foreach ($temp_rows as $row) { $product_key = $row[0]['product']; $radios = form_process_radios($element['element'][$product_key]); foreach ($columns as $col) { if (isset($col['oid'])) { if (isset($radios[$col['oid']])) { unset($radios[$col['oid']]['#title']); $row[] = array( 'data' => drupal_render($radios[$col['oid']]), 'class' => 'checkbox webform-grid-option', ); } else { $row[] = array( 'data' => 'n/a', 'class' => 'checkbox webform-grid-option', ); } } } $final_rows[] = $row; } $option_count = count($columns) - 1; $output = theme('table', array( 'header' => $columns, 'rows' => $final_rows, 'attributes' => array( 'class' => array( 'uc_webform-product-grid uc_webform-product-grid-' . $option_count, ), ), )); $variables['element'] = $element; $variables['value'] = $output; return $output; } /** * @todo Please document this function. * @see http://drupal.org/node/1354 */ function theme_uc_webform_display_product_grid($element) { // TODO: Should this theme uc_webform_display_product_grid be declared in // hook_theme()? $output = ''; if (isset($element['#value'])) { $output = (count($element['#value']) > 1) ? theme('item_list', array('items' => $element['#value'])) : $element['#value'][0]; } return $output; } /** * Implementation of _webform_edit_component(). */ function _webform_edit_product_grid($component) { $form = array(); $product_types = uc_product_types(); // I need to limit the users selection to only those products that *do* // contain attributes. $attrib_query = db_select('uc_product_attributes', 'pa') ->fields('pa', array('nid')); $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->condition('n.nid', $attrib_query, 'IN'); $query->join('uc_products', 'p', 'p.nid = n.nid'); $query->addField('p', 'model'); $query->orderBy('n.title'); $products = array(); foreach ($query->execute() as $product) { $products[$product->nid . '_' . $product->model] = check_plain($product->title); } // Most options are stored in the "extra" array, which stores any settings // unique to a particular component type. $form['extra']['products'] = array( '#type' => 'select', '#title' => t('Products'), '#default_value' => $component['extra']['products'], '#multiple' => TRUE, '#description' => t('Please select your products. Only products with attributes are displayed.'), '#weight' => -3, '#size' => 20, '#required' => TRUE, '#options' => $products, ); return $form; } /** * Implements _webform_render_component(). */ function _webform_render_product_grid($component) { $product_nodes = array(); $stock_description = ""; foreach ($component['extra']['products'] as $val) { $product_info = explode('_', $val, 2); if (module_exists('uc_stock')) { $stock_level = uc_stock_level($product_info[1]); } else { $stock_level = FALSE; } // Check stock levels. The product is only selectable if it is in stock. if (($stock_level === FALSE) or (intval($stock_level) > 0)) { $product_nodes[$val] = node_load($product_info[0]); } else { $node = node_load($product_info[0]); $stock_description .= check_plain($node->title) . ' ' . t('is out of stock.') . '
'; } } $element = array( '#title' => $component['name'], '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', '#required' => $component['mandatory'], '#weight' => $component['weight'], '#description' => $component['extra']['description'] . $stock_description, '#theme' => 'uc_webform_render_product_grid', '#theme_wrappers' => array('webform_element'), '#pre_render' => array('webform_element_title_display'), '#post_render' => array('webform_element'), '#webform_component' => $component, ); // Iterate through each product that will be offered. Products will appear on // the left of the grid. if(is_array($product_nodes)) { foreach ($product_nodes as $key => $product_node) { if($product_node) { $element[$key] = array( '#title' => $product_node->title, '#required' => $component['mandatory'], '#type' => 'radios', '#process' => array('form_process_radios', 'webform_expand_select_ids'), ); // Iterate through each product option for each product. Product options // will appear on the top of the grid. $product_options = array(); foreach ($product_node->attributes as $aid => $attribute) { foreach ($attribute->options as $option) { // aid_oid $product_options[$aid . '_' . $option->oid] = $option->name; } } $element[$key]['#options'] = $product_options; } } drupal_add_js(drupal_get_path('module', 'uc_webform') . '/js/deselect.js'); return $element; } } /** * Implementation of _webform_display_component(). */ function _webform_display_product_grid($component, $value, $format = 'html') { $products = array(); foreach ($value as $key => $val) { $nid_sku = explode('_', $key, 2); $aid_oid = explode('_', $val, 2); $node = node_load($nid_sku[0]); if (!empty($val)) { $products[] = $node->title . ', SKU: ' . $node->model . ', Attribute: ' . $node->attributes[$aid_oid[0]]->name . ', Option: ' . $node->attributes[$aid_oid[0]]->options[$aid_oid[1]]->name; } } $element = array( '#title' => $component['name'], '#weight' => $component['weight'], '#theme' => 'uc_webform_display_product_grid', '#component' => $component, '#format' => $format, '#post_render' => array('webform_element'), '#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), '#value' => $products, ); return $element; } /** * Implementation of _webform_analysis_component(). */ function _webform_analysis_product_grid($component, $sids = array()) { // Create an entire table to be put into the returned row. $rows = array(array()); $header = array(array()); $product_nids = array(); $option_ids = array(); foreach ($component['extra']['products'] as $product) { $nid_sku = explode('_', $product, 2); $product_nids[] = $nid_sku[0]; $product_node = node_load($nid_sku[0]); // A nid_sku combination is used as the key here. $rows[$product] = array($product_node->title); } // Select the available option IDs and names for each product in the table. if (!empty($product_nids)) { $query = db_select('uc_product_options', 'po') ->fields('po', array('oid')); $query->join('uc_attribute_options', 'ao', 'ao.oid = po.oid'); $query->addField('ao', 'name'); $query->condition('po.oid', $product_nids, 'IN'); } // Build the header row. $options = array(); foreach ($query->execute() as $option) { // Use the oid as an array key to help when quering the // webform_submitted_data table (since it stores the oid instead of the // option name). $header[$option->oid] = $option->name; } $query = db_select('webform_submitted_data', 'wsd') ->fields('wsd', array('no', 'data')); $query->addExpression('COUNT(data)', 'datacount'); $query->condition('nid', $component['nid'], '='); $query->condition('cid', $component['cid'], '='); $query->groupBy('no'); $query->groupBy('data'); $selections = array(); foreach ($query->execute() as $data) { $aid_oid = explode('_', $data->data, 2); // The information is stored in the DB as attribute-ID_option-ID. This line // removes the attribute ID and leaves the $selections key as the option ID. if (isset($aid_oid[1])) { $selections[$data->no][$aid_oid[1]] = $data->datacount; } } foreach ($rows as $rkey => $rval) { if ($rkey != 0) { foreach ($header as $hkey => $hval) { if ($hkey != 0) { // $rkey = product-nid_sku. // $hkey = option ID. $rows[$rkey][] = isset($selections[$rkey][$hkey]) ? $selections[$rkey][$hkey] : 0; } } } } $output = theme('table', array( 'header' => $header, 'rows' => $rows, 'attributes' => array( 'class' => array('webform-product-grid'), ), )); return array(array(array('data' => $output, 'colspan' => 2))); } /** * Implements _webform_table_component(). */ function _webform_table_product_grid($component, $value) { $output = ''; // Set the value as a single string. foreach ($value as $key => $val) { $nid_sku = explode('_', $key, 2); $aid_oid = explode('_', $val, 2); if (isset($nid_sku[0])) { $node = node_load($nid_sku[0]); // Output the SKU and the option. if (isset($aid_oid[0]) && isset($aid_oid[1])) { $output .= $node->model . ' - ' . $node->attributes[$aid_oid[0]]->options[$aid_oid[1]]->name . '
'; } } } return $output; } /** * Implements _webform_csv_headers_component(). */ function _webform_csv_headers_product_grid($component, $export_options) { $headers = array( 0 => array(), 1 => array(), 2 => array(), ); if ($export_options['select_format'] == 'separate') { $headers[0][] = ''; $headers[1][] = $component['name']; $count = 0; foreach ($component['extra']['products'] as $val) { $product_info = explode('_', $val, 2); $node = node_load($product_info[0]); // Add blank cells. if ($count != 0) { // Empty column per sub-field in main header. $headers[0][] = ''; $headers[1][] = ''; } // List the product options as header cells. $headers[2][] = $node->title; $count++; } } else { $headers[0][] = ''; $headers[1][] = ''; $headers[2][] = $component['name']; } return $headers; } /** * Implements _webform_csv_data_component(). */ function _webform_csv_data_product_grid($component, $export_options, $value) { $data = array(); // Separate format. if ($export_options['select_format'] == 'separate') { foreach ($component['extra']['products'] as $product) { if (isset($value[$product])) { $nid_sku = explode('_', $product, 2); $aid_oid = explode('_', $value[$product], 2); if (isset($nid_sku[0])) { $node = node_load($nid_sku[0]); if (isset($aid_oid[0]) && isset($aid_oid[1])) { $data[] = $node->attributes[$aid_oid[0]]->options[$aid_oid[1]]->name; } } } } } // Compact format. else { $data_string; foreach ($component['extra']['products'] as $product) { if (isset($value[$product])) { $nid_sku = explode('_', $product, 2); $aid_oid = explode('_', $value[$product], 2); if (isset($nid_sku[0])) { $node = node_load($nid_sku[0]); if (isset($aid_oid[0]) && isset($aid_oid[1])) { $data_string .= $node->attributes[$aid_oid[0]]->options[$aid_oid[1]]->name . ','; } } } } $data[] = rtrim($data_string, ','); } return $data; }