12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388 |
- <?php
- /**
- * @file
- * Attribute administration menu items.
- */
- /**
- * Displays a paged list and overview of existing product attributes.
- */
- function uc_attribute_admin() {
- $header = array(
- array('data' => t('Name'), 'field' => 'a.name', 'sort' => 'asc'),
- array('data' => t('Label'), 'field' => 'a.label'),
- t('Required'),
- array('data' => t('List position'), 'field' => 'a.ordering'),
- t('Number of options'),
- t('Display type'),
- array('data' => t('Operations'), 'colspan' => 3),
- );
- $display_types = _uc_attribute_display_types();
- $query = db_select('uc_attributes', 'a')->extend('PagerDefault')->extend('TableSort')
- ->fields('a', array('aid', 'name', 'label', 'required', 'ordering', 'display'))
- ->orderByHeader($header)
- ->limit(30);
- $rows = array();
- $result = $query->execute();
- foreach ($result as $attr) {
- $attr->options = db_query('SELECT COUNT(*) FROM {uc_attribute_options} WHERE aid = :aid', array(':aid' => $attr->aid))->fetchField();
- if (empty($attr->label)) {
- $attr->label = $attr->name;
- }
- $rows[] = array(
- check_plain($attr->name),
- check_plain($attr->label),
- $attr->required == 1 ? t('Yes') : t('No'),
- $attr->ordering,
- $attr->options,
- $display_types[$attr->display],
- l(t('edit'), 'admin/store/products/attributes/' . $attr->aid . '/edit'),
- l(t('options'), 'admin/store/products/attributes/' . $attr->aid . '/options'),
- l(t('delete'), 'admin/store/products/attributes/' . $attr->aid . '/delete'),
- );
- }
- $build['attributes'] = array(
- '#theme' => 'table',
- '#header' => $header,
- '#rows' => $rows,
- '#empty' => t('No product attributes have been added yet.'),
- );
- $build['pager'] = array(
- '#theme' => 'pager',
- );
- return $build;
- }
- /**
- * Form builder for product attributes.
- *
- * @see uc_attribute_form_submit()
- *
- * @ingroup forms
- */
- function uc_attribute_form($form, &$form_state, $attribute = NULL) {
- // If an attribute specified, add its ID as a hidden value.
- if (!empty($attribute)) {
- $form['aid'] = array('#type' => 'value', '#value' => $attribute->aid);
- drupal_set_title(t('Edit attribute: %name', array('%name' => $attribute->name)), PASS_THROUGH);
- }
- if (isset($attribute->name)) {
- if (empty($attribute->label)) {
- $attribute->label = $attribute->name;
- }
- $name = $attribute->name;
- $label = $attribute->label;
- }
- else {
- $name = $label = '';
- }
- $form['name'] = array(
- '#type' => 'textfield',
- '#title' => t('Name'),
- '#description' => t('The name of the attribute used in administrative forms'),
- '#default_value' => $name,
- '#required' => TRUE,
- );
- $form['label'] = array(
- '#type' => 'textfield',
- '#title' => t('Label'),
- '#description' => t("Enter a label that customers will see instead of the attribute name. Use <none> if you don't want a title to appear at all."),
- '#default_value' => $label,
- '#maxlength' => 255,
- );
- $form['description'] = array(
- '#type' => 'textfield',
- '#title' => t('Help text'),
- '#description' => t('<b>Optional.</b> Enter the help text that will display beneath the attribute on product add to cart forms.'),
- '#default_value' => isset($attribute->description) ? $attribute->description : '',
- '#maxlength' => 255,
- );
- $form['required'] = array(
- '#type' => 'checkbox',
- '#title' => t('Make this attribute required, forcing the customer to choose an option.'),
- '#description' => t('Selecting this for an attribute will disregard any default option you specify.<br />May be overridden at the product level.'),
- '#default_value' => isset($attribute->required) ? $attribute->required : 0,
- );
- $form['display'] = array(
- '#type' => 'select',
- '#title' => t('Display type'),
- '#description' => t('This specifies how the options for this attribute will be presented.<br />May be overridden at the product level.'),
- '#options' => _uc_attribute_display_types(),
- '#default_value' => isset($attribute->display) ? $attribute->display : 1,
- );
- $form['ordering'] = array(
- '#type' => 'weight',
- '#delta' => 25,
- '#title' => t('List position'),
- '#description' => t('Multiple attributes on an add to cart form are sorted by this value and then by their name.<br />May be overridden at the product level.'),
- '#default_value' => isset($attribute->ordering) ? $attribute->ordering : 0,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- '#suffix' => l(t('Cancel'), 'admin/store/products/attributes'),
- );
- return $form;
- }
- /**
- * Form submission handler for uc_attribute_form().
- *
- * @see uc_attribute_form()
- */
- function uc_attribute_form_submit($form, &$form_state) {
- if (!empty($form_state['values']['aid'])) {
- drupal_write_record('uc_attributes', $form_state['values'], 'aid');
- $form_state['redirect'] = 'admin/store/products/attributes';
- }
- else {
- drupal_write_record('uc_attributes', $form_state['values']);
- if ($form_state['values']['display'] == 0) {
- // No options needed/allowed for Textfield display type.
- $form_state['redirect'] = 'admin/store/products/attributes';
- }
- else {
- // All other display types we redirect to add options.
- $form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options';
- }
- }
- }
- /**
- * Confirms the deletion of the given attribute.
- *
- * @see uc_attribute_delete_confirm_submit()
- */
- function uc_attribute_delete_confirm($form, &$form_state, $attribute) {
- // If we got a bunk attribute, kick out an error message.
- if (empty($attribute)) {
- drupal_set_message(t('There is no attribute with that ID.'), 'error');
- drupal_goto('admin/store/products/attributes');
- }
- $form['aid'] = array('#type' => 'value', '#value' => $attribute->aid);
- $count = db_query("SELECT COUNT(*) FROM {uc_product_attributes} WHERE aid = :aid", array(':aid' => $attribute->aid))->fetchField();
- $output = confirm_form($form, t('Are you sure you want to delete the attribute %name?', array('%name' => $attribute->name)),
- 'admin/store/products/attributes', format_plural($count, 'There is 1 product with this attribute.', 'There are @count products with this attribute.'),
- t('Delete'), t('Cancel'));
- return $output;
- }
- /**
- * Form submission handler for uc_attribute_delete_confirm().
- *
- * @see uc_attribute_delete_confirm()
- */
- function uc_attribute_delete_confirm_submit($form, &$form_state) {
- if ($form_state['values']['confirm']) {
- $attribute = uc_attribute_load($form_state['values']['aid']);
- $options = array_keys($attribute->options);
- if ($options) {
- db_delete('uc_class_attribute_options')
- ->condition('oid', $options, 'IN')
- ->execute();
- db_delete('uc_product_options')
- ->condition('oid', $options, 'IN')
- ->execute();
- }
- if ($nodes = db_query("SELECT nid FROM {uc_product_attributes} WHERE aid = :aid", array(':aid' => $attribute->aid))->fetchCol()) {
- db_delete('uc_product_adjustments')
- ->condition('nid', $nodes, 'IN')
- ->execute();
- }
- db_delete('uc_class_attributes')
- ->condition('aid', $form_state['values']['aid'])
- ->execute();
- db_delete('uc_product_attributes')
- ->condition('aid', $form_state['values']['aid'])
- ->execute();
- db_delete('uc_attribute_options')
- ->condition('aid', $form_state['values']['aid'])
- ->execute();
- db_delete('uc_attributes')
- ->condition('aid', $form_state['values']['aid'])
- ->execute();
- drupal_set_message(t('Product attribute deleted.'));
- $form_state['redirect'] = 'admin/store/products/attributes';
- }
- }
- /**
- * Displays options and the modifications to products they represent.
- *
- * @see uc_attribute_options_form_validate()
- * @see uc_attribute_options_form_submit()
- *
- * @ingroup forms
- */
- function uc_attribute_options_form($form, &$form_state, $attribute) {
- // Set an appropriate title.
- drupal_set_title(t('Options for %name', array('%name' => $attribute->name)), PASS_THROUGH);
- // Store the attribute ID in the form array.
- $form['aid'] = array(
- '#type' => 'value',
- '#value' => $attribute->aid,
- );
- $form['options'] = array();
- // Loop through all the options on an attribute.
- foreach ($attribute->options as $key => $data) {
- $form['options'][$key] = array(
- 'name' => array(
- '#markup' => check_plain($data->name),
- ),
- 'cost' => array(
- '#theme' => 'uc_price',
- '#price' => $data->cost,
- ),
- 'price' => array(
- '#theme' => 'uc_price',
- '#price' => $data->price,
- ),
- 'weight' => array(
- '#markup' => (string) $data->weight,
- ),
- 'ordering' => array(
- '#type' => 'weight',
- '#delta' => 50,
- '#default_value' => $data->ordering,
- '#attributes' => array('class' => array('uc-attribute-option-table-ordering')),
- ),
- 'edit' => array('#markup' => l(t('edit'), 'admin/store/products/attributes/' . $attribute->aid . '/options/' . $key . '/edit')),
- 'delete' => array('#markup' => l(t('delete'), 'admin/store/products/attributes/' . $attribute->aid . '/options/' . $key . '/delete')),
- );
- }
- if (count($form['options'])) {
- $form['options']['#tree'] = TRUE;
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save changes'),
- '#weight' => 10,
- );
- }
- return $form;
- }
- /**
- * Form submission handler for uc_attribute_options_form().
- *
- * @see uc_attribute_options_form()
- * @see uc_object_options_form_submit()
- */
- function uc_attribute_options_form_submit($form, &$form_state) {
- foreach ($form_state['values']['options'] as $oid => $option) {
- db_update('uc_attribute_options')
- ->fields(array(
- 'ordering' => $option['ordering'],
- ))
- ->condition('oid', $oid)
- ->execute();
- }
- drupal_set_message(t('The changes have been saved.'));
- }
- /**
- * Formats an attribute and its options.
- *
- * @param $variables
- * An associative array containing:
- * - form: A render element representing the form.
- *
- * @ingroup themeable
- */
- function theme_uc_attribute_options_form($variables) {
- $form = $variables['form'];
- $header = array(t('Name'), t('Default cost'), t('Default price'), t('Default weight'), array('data' => t('List position'), 'sort' => 'asc'), array('data' => t('Operations'), 'colspan' => 2));
- $rows = array();
- foreach (element_children($form['options']) as $oid) {
- $rows[] = array(
- 'data' => array(
- drupal_render($form['options'][$oid]['name']),
- drupal_render($form['options'][$oid]['cost']),
- drupal_render($form['options'][$oid]['price']),
- drupal_render($form['options'][$oid]['weight']),
- drupal_render($form['options'][$oid]['ordering']),
- drupal_render($form['options'][$oid]['edit']),
- drupal_render($form['options'][$oid]['delete']),
- ),
- 'class' => array('draggable'),
- );
- }
- drupal_add_tabledrag('uc-attribute-option-table', 'order', 'sibling', 'uc-attribute-option-table-ordering');
- $output = theme('table', array(
- 'header' => $header,
- 'rows' => $rows,
- 'attributes' => array('id' => 'uc-attribute-option-table'),
- 'empty' => t('No options for this attribute have been added yet.'),
- ));
- $output .= drupal_render_children($form);
- return $output;
- }
- /**
- * Form builder for attribute options.
- *
- * @see uc_attribute_option_form_validate()
- * @see uc_attribute_option_form_submit()
- *
- * @ingroup forms
- */
- function uc_attribute_option_form($form, &$form_state, $attribute, $option = NULL) {
- // If we got a bunk attribute, kick out an error message.
- if (empty($attribute)) {
- drupal_set_message(t('There is no attribute with that ID.'), 'error');
- drupal_goto('admin/store/products/attributes');
- }
- $aid = $attribute->aid;
- $form['aid'] = array('#type' => 'hidden', '#value' => $aid);
- if (!empty($option)) {
- $form['oid'] = array('#type' => 'hidden', '#value' => $option->oid);
- drupal_set_title(t('Edit option: %name', array('%name' => $option->name)), PASS_THROUGH);
- }
- else {
- $option = new stdClass();
- $option->name = '';
- $option->ordering = 0;
- $option->cost = 0;
- $option->price = 0;
- $option->weight = 0;
- drupal_set_title(t('Options for %name', array('%name' => $attribute->name)), PASS_THROUGH);
- }
- $form['name'] = array(
- '#type' => 'textfield',
- '#title' => t('Name'),
- '#description' => t('This name will appear to customers on product add to cart forms.'),
- '#default_value' => $option->name,
- '#required' => TRUE,
- '#weight' => 0,
- );
- $form['ordering'] = array(
- '#type' => 'weight',
- '#delta' => 50,
- '#title' => t('List position'),
- '#description' => t('Options will be listed sorted by this value and then by their name.<br />May be overridden at the product level.'),
- '#default_value' => $option->ordering,
- '#weight' => 4,
- );
- $form['adjustments'] = array(
- '#type' => 'fieldset',
- '#title' => t('Default adjustments'),
- '#description' => t('Enter a positive or negative value for each adjustment applied when this option is selected.<br />Any of these may be overriden at the product level.'),
- '#collapsible' => FALSE,
- '#weight' => 8,
- );
- $form['adjustments']['cost'] = array(
- '#type' => 'uc_price',
- '#title' => t('Cost'),
- '#default_value' => $option->cost,
- '#weight' => 1,
- '#allow_negative' => TRUE,
- );
- $form['adjustments']['price'] = array(
- '#type' => 'uc_price',
- '#title' => t('Price'),
- '#default_value' => $option->price,
- '#weight' => 2,
- '#allow_negative' => TRUE,
- );
- $form['adjustments']['weight'] = array(
- '#type' => 'textfield',
- '#title' => t('Weight'),
- '#default_value' => $option->weight,
- '#weight' => 3,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- '#suffix' => l(t('Cancel'), 'admin/store/products/attributes/' . $aid . '/options'),
- '#weight' => 10,
- );
- return $form;
- }
- /**
- * Validates number formats.
- *
- * @see uc_attribute_option_form()
- * @see uc_attribute_option_form_submit()
- */
- function uc_attribute_option_form_validate($form, &$form_state) {
- $pattern = '/^-?\d*(\.\d*)?$/';
- $price_error = t('This must be in a valid number format. No commas and only one decimal point.');
- if (!is_numeric($form_state['values']['weight']) && !preg_match($pattern, $form_state['values']['weight'])) {
- form_set_error('weight', $price_error);
- }
- }
- /**
- * Form submission handler for uc_attribute_option_form().
- *
- * @see uc_attribute_option_form()
- * @see uc_attribute_option_form_validate()
- */
- function uc_attribute_option_form_submit($form, &$form_state) {
- if (!isset($form_state['values']['oid'])) {
- drupal_write_record('uc_attribute_options', $form_state['values']);
- drupal_set_message(t('Created new option %option.', array('%option' => $form_state['values']['name'])));
- watchdog('uc_attribute', 'Created new option %option.', array('%option' => $form_state['values']['name']), WATCHDOG_NOTICE, 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options/add');
- $form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options/add';
- }
- else {
- drupal_write_record('uc_attribute_options', $form_state['values'], array('aid', 'oid'));
- drupal_set_message(t('Updated option %option.', array('%option' => $form_state['values']['name'])));
- watchdog('uc_attribute', 'Updated option %option.', array('%option' => $form_state['values']['name']), WATCHDOG_NOTICE, 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options/' . $form_state['values']['oid']);
- $form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options';
- }
- }
- /**
- * Confirms deletion of the given attribute option.
- *
- * @see uc_attribute_option_delete_confirm_submit()
- */
- function uc_attribute_option_delete_confirm($form, &$form_state, $attribute, $option) {
- if (empty($option)) {
- drupal_set_message(t('There is no option with that ID.'), 'error');
- drupal_goto('admin/store/products/attributes/' . $attribute->aid . '/options');
- }
- $aid = $attribute->aid;
- $oid = $option->oid;
- $form['aid'] = array('#type' => 'value', '#value' => $aid);
- $form['oid'] = array('#type' => 'value', '#value' => $oid);
- $output = confirm_form($form, t('Are you sure you want to delete the option %name?', array('%name' => $option->name)), 'admin/store/products/attributes/' . $aid . '/options', '', t('Delete'), t('Cancel'));
- return $output;
- }
- /**
- * Form submission handler for uc_attribute_option_delete_confirm().
- *
- * @see uc_attribute_option_delete_confirm()
- */
- function uc_attribute_option_delete_confirm_submit($form, &$form_state) {
- if ($form_state['values']['confirm']) {
- $match = 'i:' . $form_state['values']['aid'] . ';s:' . strlen($form_state['values']['oid']) . ':"' . $form_state['values']['oid'] . '";';
- db_delete('uc_product_adjustments')
- ->condition('combination', '%' . db_like($match) . '%', 'LIKE')
- ->execute();
- $select = db_select('uc_attribute_options', 'ao')
- ->where('{uc_class_attribute_options}.oid = ao.oid')
- ->condition('ao.oid', $form_state['values']['oid']);
- $select->addExpression('1');
- db_delete('uc_class_attribute_options')
- ->condition('', $select, 'EXISTS')
- ->execute();
- $select = db_select('uc_attribute_options', 'ao')
- ->where('{uc_product_options}.oid = ao.oid')
- ->condition('ao.oid', $form_state['values']['oid']);
- $select->addExpression('1');
- db_delete('uc_product_options')
- ->condition('', $select, 'EXISTS')
- ->execute();
- db_delete('uc_attribute_options')
- ->condition('oid', $form_state['values']['oid'])
- ->execute();
- }
- $form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options';
- }
- /**
- * Form to associate attributes with products or classes.
- *
- * @see uc_object_attributes_form_submit()
- * @see theme_uc_object_attributes_form()
- *
- * @ingroup forms
- */
- function uc_object_attributes_form($form, &$form_state, $object, $type, $view = 'overview') {
- switch ($type) {
- case 'class':
- $class = $object;
- $id = $class->pcid;
- if (empty($class->name)) {
- drupal_goto('admin/store/products/classes/' . $id);
- }
- drupal_set_title($class->name);
- $attributes = uc_class_get_attributes($id);
- break;
- case 'product':
- default:
- $product = $object;
- $id = $product->nid;
- if (empty($product->title)) {
- drupal_goto('node/' . $id);
- }
- drupal_set_title($product->title);
- $attributes = uc_product_get_attributes($id);
- }
- $used_aids = array();
- foreach ($attributes as $attribute) {
- $used_aids[] = $attribute->aid;
- }
- if ($view == 'overview') {
- $form['#tree'] = TRUE;
- $form['attributes'] = array();
- if (count($attributes) > 0) {
- foreach ($attributes as $attribute) {
- $option = isset($attribute->options[$attribute->default_option]) ? $attribute->options[$attribute->default_option] : NULL;
- $form['attributes'][$attribute->aid] = array(
- 'remove' => array(
- '#type' => 'checkbox',
- '#title' => t('Remove'),
- '#title_display' => 'invisible',
- '#default_value' => 0,
- ),
- 'name' => array(
- '#markup' => check_plain($attribute->name),
- ),
- 'label' => array(
- '#type' => 'textfield',
- '#title' => t('Label'),
- '#title_display' => 'invisible',
- '#default_value' => empty($attribute->label) ? $attribute->name : $attribute->label,
- '#size' => 20,
- '#maxlength' => 255,
- ),
- 'option' => array(
- '#markup' => $option ? (check_plain($option->name) . ' (' . theme('uc_price', array('price' => $option->price)) . ')') : t('n/a'),
- ),
- 'required' => array(
- '#type' => 'checkbox',
- '#title' => t('Required'),
- '#title_display' => 'invisible',
- '#default_value' => $attribute->required,
- ),
- 'ordering' => array(
- '#type' => 'weight',
- '#title' => t('List position'),
- '#title_display' => 'invisible',
- '#delta' => 25,
- '#default_value' => $attribute->ordering,
- '#attributes' => array('class' => array('uc-attribute-table-ordering')),
- ),
- 'display' => array(
- '#type' => 'select',
- '#title' => t('Display'),
- '#title_display' => 'invisible',
- '#default_value' => $attribute->display,
- '#options' => _uc_attribute_display_types(),
- ),
- );
- }
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['save'] = array(
- '#type' => 'submit',
- '#value' => t('Save changes'),
- '#weight' => -2,
- );
- }
- }
- elseif ($view == 'add') {
- // Get list of attributes not already assigned to this node or class.
- $unused_attributes = array();
- $result = db_query("SELECT a.aid, a.name, a.label FROM {uc_attributes} a LEFT JOIN {uc_attribute_options} ao ON a.aid = ao.aid GROUP BY a.aid, a.name, a.label ORDER BY a.name");
- foreach ($result as $attribute) {
- if (!in_array($attribute->aid, $used_aids)) {
- $unused_attributes[$attribute->aid] = $attribute->name;
- }
- }
- $form['add_attributes'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Attributes'),
- '#options' => count($unused_attributes) > 0 ? $unused_attributes : array(t('No attributes left to add.')),
- '#disabled' => count($unused_attributes) == 0 ? TRUE : FALSE,
- '#weight' => -1,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['add'] = array(
- '#type' => 'submit',
- '#value' => t('Add attributes'),
- '#suffix' => l(t('Cancel'), $type == 'product' ? 'node/' . $id . '/edit/attributes' : 'admin/store/products/classes/' . $class->pcid . '/attributes'),
- '#weight' => 0,
- );
- }
- $form['id'] = array(
- '#type' => 'value',
- '#value' => $id,
- );
- $form['type'] = array(
- '#type' => 'value',
- '#value' => $type,
- );
- $form['view'] = array(
- '#type' => 'value',
- '#value' => $view,
- );
- return $form;
- }
- /**
- * Displays the formatted attribute form.
- *
- * @param $variables
- * An associative array containing:
- * - form: A render element representing the form.
- *
- * @see uc_object_attributes_form()
- *
- * @ingroup themeable
- */
- function theme_uc_object_attributes_form($variables) {
- $form = $variables['form'];
- $output = '';
- if ($form['view']['#value'] == 'overview') {
- $header = array(t('Remove'), t('Name'), t('Label'), t('Default'), t('Required'), t('List position'), t('Display'));
- $rows = array();
- foreach (element_children($form['attributes']) as $aid) {
- $rows[] = array(
- 'data' => array(
- drupal_render($form['attributes'][$aid]['remove']),
- drupal_render($form['attributes'][$aid]['name']),
- drupal_render($form['attributes'][$aid]['label']),
- drupal_render($form['attributes'][$aid]['option']),
- drupal_render($form['attributes'][$aid]['required']),
- drupal_render($form['attributes'][$aid]['ordering']),
- drupal_render($form['attributes'][$aid]['display']),
- ),
- 'class' => array('draggable'),
- );
- }
- drupal_add_tabledrag('uc-attribute-table', 'order', 'sibling', 'uc-attribute-table-ordering');
- if ($form['type']['#value'] == 'class') {
- $path = url('admin/store/products/classes/' . $form['id']['#value'] . '/attributes/add');
- }
- elseif ($form['type']['#value'] == 'product') {
- $path = url('node/' . $form['id']['#value'] . '/edit/attributes/add');
- }
- $output = theme('table', array(
- 'header' => $header,
- 'rows' => $rows,
- 'attributes' => array('id' => 'uc-attribute-table'),
- 'empty' => t('You must first <a href="!url">add attributes to this !type</a>.', array('!url' => $path, '!type' => $form['type']['#value'])),
- ));
- }
- else {
- $output = '<div class="uc-attributes-add-link">';
- $output .= t('You may add more attributes <a href="!url">here</a>.', array('!url' => url('admin/store/products/attributes/add')));
- $output .= '</div>';
- }
- $output .= drupal_render_children($form);
- return $output;
- }
- /**
- * Form submission handler for uc_object_attributes_form().
- *
- * @see uc_object_attributes_form()
- */
- function uc_object_attributes_form_submit($form, &$form_state) {
- if ($form_state['values']['type'] == 'product') {
- $attr_table = 'uc_product_attributes';
- $opt_table = 'uc_product_options';
- $id = 'nid';
- }
- elseif ($form_state['values']['type'] == 'class') {
- $attr_table = 'uc_class_attributes';
- $opt_table = 'uc_class_attribute_options';
- $id = 'pcid';
- }
- if ($form_state['values']['view'] == 'overview' && is_array($form_state['values']['attributes'])) {
- $changed = FALSE;
- foreach ($form_state['values']['attributes'] as $aid => $attribute) {
- if ($attribute['remove']) {
- $remove_aids[] = $aid;
- }
- else {
- $attribute['aid'] = $aid;
- $attribute[$id] = $form_state['values']['id'];
- drupal_write_record($attr_table, $attribute, array('aid', $id));
- $changed = TRUE;
- }
- }
- if (isset($remove_aids)) {
- $id_value = $form_state['values']['id'];
- $select = db_select('uc_attribute_options', 'ao')
- ->fields('ao', array('oid'))
- ->condition('ao.aid', $remove_aids, 'IN');
- db_delete($opt_table)
- ->condition('oid', $select, 'IN')
- ->condition($id, $id_value)
- ->execute();
- db_delete($attr_table)
- ->condition($id, $id_value)
- ->condition('aid', $remove_aids, 'IN')
- ->execute();
- if ($form_state['values']['type'] == 'product') {
- db_delete('uc_product_adjustments')
- ->condition('nid', $id_value)
- ->execute();
- }
- drupal_set_message(format_plural(count($remove_aids), '1 attribute has been removed.', '@count attributes have been removed.'));
- }
- if ($changed) {
- drupal_set_message(t('The changes have been saved.'));
- }
- }
- elseif ($form_state['values']['view'] == 'add') {
- foreach (array_filter($form_state['values']['add_attributes']) as $aid) {
- // Enable all options for added attributes.
- $attribute = uc_attribute_load($aid);
- $oid = 0;
- if (isset($attribute->options)) {
- foreach ($attribute->options as $option) {
- $option->$id = $form_state['values']['id'];
- drupal_write_record($opt_table, $option);
- $option->aid = $aid;
- }
- // Make the first option (if any) the default.
- if ($option = reset($attribute->options)) {
- $oid = $option->oid;
- }
- }
- $select = db_select('uc_attributes', 'a')
- ->condition('aid', $aid);
- $select->addExpression(':id', $id, array(':id' => $form_state['values']['id']));
- $select->addField('a', 'aid');
- $select->addField('a', 'label');
- $select->addField('a', 'ordering');
- $select->addExpression(':oid', 'default_option', array(':oid' => $oid));
- $select->addField('a', 'required');
- $select->addField('a', 'display');
- db_insert($attr_table)
- ->from($select)
- ->execute();
- }
- $num = count(array_filter($form_state['values']['add_attributes']));
- if ($num > 0) {
- if ($form_state['values']['type'] == 'product') {
- db_delete('uc_product_adjustments')
- ->condition('nid', $form_state['values']['id'])
- ->execute();
- }
- drupal_set_message(format_plural($num, '1 attribute has been added.', '@count attributes have been added.'));
- }
- }
- if ($form_state['values']['type'] == 'product') {
- if (module_exists('entitycache')) {
- cache_clear_all($form_state['values']['id'], 'cache_entity_node');
- }
- $form_state['redirect'] = 'node/' . $form_state['values']['id'] . '/edit/attributes';
- }
- else {
- $form_state['redirect'] = 'admin/store/products/classes/' . $form_state['values']['id'] . '/attributes';
- }
- }
- /**
- * Form to assign and modify attribute options on products or classes.
- *
- * @see uc_object_options_form_validate()
- * @see uc_object_options_form_submit()
- * @see theme_uc_object_options_form()
- *
- * @ingroup forms
- */
- function uc_object_options_form($form, &$form_state, $object, $type) {
- if ($type == 'product') {
- $product = $object;
- $id = $product->nid;
- drupal_set_title($product->title);
- $attributes = uc_product_get_attributes($id);
- $table = 'uc_product_options';
- $id_type = 'nid';
- }
- elseif ($type == 'class') {
- $class = $object;
- $id = $class->pcid;
- drupal_set_title($class->name);
- $attributes = uc_class_get_attributes($id);
- $table = 'uc_class_attribute_options';
- $id_type = 'pcid';
- }
- foreach ($attributes as $aid => $attribute) {
- $form['attributes'][$aid]['name'] = array(
- '#markup' => check_plain($attribute->name),
- );
- $form['attributes'][$aid]['aid'] = array(
- '#type' => 'hidden',
- '#value' => $attribute->aid,
- );
- $form['attributes'][$aid]['ordering'] = array(
- '#type' => 'value',
- '#value' => $attribute->ordering,
- );
- $form['attributes'][$aid]['options'] = array('#weight' => 2);
- $base_attr = uc_attribute_load($attribute->aid);
- if ($base_attr->options) {
- $options = array();
- $query = db_select('uc_attribute_options', 'ao')
- ->fields('ao', array(
- 'aid',
- 'oid',
- 'name',
- ));
- $query->leftJoin($table, 'po', "ao.oid = po.oid AND po.$id_type = :id", array(':id' => $id));
- $query->addField('ao', 'cost', 'default_cost');
- $query->addField('ao', 'price', 'default_price');
- $query->addField('ao', 'weight', 'default_weight');
- $query->addField('ao', 'ordering', 'default_ordering');
- $query->fields('po', array(
- 'cost',
- 'price',
- 'weight',
- 'ordering',
- ))
- ->addExpression('CASE WHEN po.ordering IS NULL THEN 1 ELSE 0 END', 'null_order');
- $query->condition('aid', $attribute->aid)
- ->orderBy('null_order')
- ->orderBy('po.ordering')
- ->orderBy('default_ordering')
- ->orderBy('ao.name');
- $result = $query->execute();
- foreach ($result as $option) {
- $oid = $option->oid;
- $options[$oid] = '';
- $form['attributes'][$aid]['options'][$oid]['select'] = array(
- '#type' => 'checkbox',
- '#default_value' => isset($attribute->options[$oid]) ? TRUE : FALSE,
- '#title' => check_plain($option->name),
- );
- $form['attributes'][$aid]['options'][$oid]['cost'] = array(
- '#type' => 'uc_price',
- '#title' => t('Cost'),
- '#title_display' => 'invisible',
- '#default_value' => is_null($option->cost) ? $option->default_cost : $option->cost,
- '#size' => 6,
- '#allow_negative' => TRUE,
- );
- $form['attributes'][$aid]['options'][$oid]['price'] = array(
- '#type' => 'uc_price',
- '#title' => t('Price'),
- '#title_display' => 'invisible',
- '#default_value' => is_null($option->price) ? $option->default_price : $option->price,
- '#size' => 6,
- '#allow_negative' => TRUE,
- );
- $form['attributes'][$aid]['options'][$oid]['weight'] = array(
- '#type' => 'textfield',
- '#title' => t('Weight'),
- '#title_display' => 'invisible',
- '#default_value' => is_null($option->weight) ? $option->default_weight : $option->weight,
- '#size' => 5,
- );
- $form['attributes'][$aid]['options'][$oid]['ordering'] = array(
- '#type' => 'weight',
- '#title' => t('List position'),
- '#title_display' => 'invisible',
- '#delta' => 50,
- '#default_value' => is_null($option->ordering) ? $option->default_ordering : $option->ordering,
- '#attributes' => array('class' => array('uc-attribute-option-table-ordering')),
- );
- }
- $form['attributes'][$aid]['default'] = array(
- '#type' => 'radios',
- '#title' => t('Default'),
- '#title_display' => 'invisible',
- '#options' => $options,
- '#default_value' => $attribute->default_option,
- );
- }
- }
- if (!empty($form['attributes'])) {
- $form['attributes']['#tree'] = TRUE;
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- '#weight' => 10,
- );
- }
- $form['id'] = array(
- '#type' => 'value',
- '#value' => $id,
- );
- $form['type'] = array(
- '#type' => 'value',
- '#value' => $type,
- );
- return $form;
- }
- /**
- * Displays the option form.
- *
- * @param $variables
- * An associative array containing:
- * - form: A render element representing the form.
- *
- * @see uc_object_options_form()
- *
- * @ingroup themeable
- */
- function theme_uc_object_options_form($variables) {
- $form = $variables['form'];
- $output = '';
- drupal_add_js('misc/tableselect.js');
- $header = array(array('data' => ' ' . t('Options'), 'class' => array('select-all')), t('Default'), t('Cost'), t('Price'), t('Weight'), t('List position'));
- $tables = 0;
- if (isset($form['attributes'])) {
- foreach (element_children($form['attributes']) as $key) {
- $rows = array();
- foreach (element_children($form['attributes'][$key]['options']) as $oid) {
- $rows[] = array(
- 'data' => array(
- drupal_render($form['attributes'][$key]['options'][$oid]['select']),
- drupal_render($form['attributes'][$key]['default'][$oid]),
- drupal_render($form['attributes'][$key]['options'][$oid]['cost']),
- drupal_render($form['attributes'][$key]['options'][$oid]['price']),
- drupal_render($form['attributes'][$key]['options'][$oid]['weight']),
- drupal_render($form['attributes'][$key]['options'][$oid]['ordering']),
- ),
- 'class' => array('draggable'),
- );
- }
- $table_id = 'uc-attribute-option-table-' . $tables++;
- drupal_add_tabledrag($table_id, 'order', 'sibling', 'uc-attribute-option-table-ordering');
- $output .= theme('table', array(
- 'header' => $header,
- 'rows' => $rows,
- 'attributes' => array(
- 'class' => array('product_attributes'),
- 'id' => $table_id,
- ),
- 'caption' => '<h2>' . drupal_render($form['attributes'][$key]['name']) . '</h2>',
- 'empty' => t('This attribute does not have any options.'),
- ));
- }
- }
- if (!$tables) {
- if ($form['type']['#value'] == 'product') {
- drupal_set_message(t('This product does not have any attributes.'), 'warning');
- }
- else {
- drupal_set_message(t('This product class does not have any attributes.'), 'warning');
- }
- }
- $output .= drupal_render_children($form);
- return $output;
- }
- /**
- * Returns a themed set of attribute options for use in order displays.
- *
- * @param $variables
- * An associative array containing:
- * - attributes: An associative array containing the set of attributes,
- * with each element keyed by attribute ID:
- * - <aid>: An associative array containing:
- * - #attribute_name: Attribute name.
- * - #options: Array of option names.
- *
- * @return
- * Themed set of attribute options.
- *
- * @ingroup themeable
- */
- function theme_uc_product_attributes($variables) {
- $attributes = $variables['attributes'];
- $option_rows = array();
- foreach (element_children($attributes) as $key) {
- $optionstr = '';
- foreach ((array) $attributes[$key]['#options'] as $option) {
- // We only need to allow translation from the second option onward
- if (empty($optionstr)) {
- $optionstr .= $option;
- }
- else {
- $optionstr .= t(', !option', array('!option' => $option));
- }
- }
- if ($optionstr != '') {
- $option_rows[$key] = t('@attribute: @option', array('@attribute' => $attributes[$key]['#attribute_name'], '@option' => $optionstr));
- }
- }
- if (!empty($option_rows)) {
- return theme('item_list', array('items' => array_values($option_rows), 'attributes' => array('class' => array('product-description'))));
- }
- return '';
- }
- /**
- * Makes sure that all selected default options are enabled.
- *
- * @see uc_object_options_form()
- * @see uc_object_options_form_submit()
- */
- function uc_object_options_form_validate($form, &$form_state) {
- $error = FALSE;
- if (isset($form_state['values']['attributes'])) {
- foreach ($form_state['values']['attributes'] as $aid => $attribute) {
- $selected_opts = array();
- if (isset($attribute['options'])) {
- foreach ($attribute['options'] as $oid => $option) {
- if ($option['select'] == 1) {
- $selected_opts[] = $oid;
- }
- }
- }
- if (!empty($selected_opts) && !isset($form['attributes'][$aid]['default']['#disabled']) && !in_array($attribute['default'], $selected_opts)) {
- form_set_error($attribute['default']);
- $error = TRUE;
- }
- }
- }
- if ($error) {
- drupal_set_message(t('All attributes with enabled options must specify an enabled option as default.'), 'error');
- }
- }
- /**
- * Form submission handler for uc_object_options_form().
- *
- * @see uc_object_options_form()
- * @see uc_object_options_form_validate()
- */
- function uc_object_options_form_submit($form, &$form_state) {
- if ($form_state['values']['type'] == 'product') {
- $attr_table = 'uc_product_attributes';
- $opt_table = 'uc_product_options';
- $id = 'nid';
- }
- elseif ($form_state['values']['type'] == 'class') {
- $attr_table = 'uc_class_attributes';
- $opt_table = 'uc_class_attribute_options';
- $id = 'pcid';
- }
- foreach ($form_state['values']['attributes'] as $attribute) {
- if (isset($attribute['default'])) {
- db_update($attr_table)
- ->fields(array(
- 'default_option' => $attribute['default'],
- ))
- ->condition($id, $form_state['values']['id'])
- ->condition('aid', $attribute['aid'])
- ->execute();
- }
- if (isset($attribute['options'])) {
- db_delete($opt_table)
- ->condition($id, $form_state['values']['id'])
- ->condition('oid', array_keys($attribute['options']), 'IN')
- ->execute();
- foreach ($attribute['options'] as $oid => $option) {
- if ($option['select']) {
- $option[$id] = $form_state['values']['id'];
- $option['oid'] = $oid;
- drupal_write_record($opt_table, $option);
- }
- elseif ($form_state['values']['type'] == 'product') {
- $aid = $attribute['aid'];
- $match = 'i:' . $aid . ';s:' . strlen($oid) . ':"' . $oid . '";';
- db_delete('uc_product_adjustments')
- ->condition('nid', $form_state['values']['id'])
- ->condition('combination', '%' . db_like($match) . '%', 'LIKE')
- ->execute();
- }
- }
- }
- }
- drupal_set_message(t('The @type options have been saved.', array('@type' => $form_state['values']['type'] == 'product' ? t('product') : t('product class'))));
- if ($form_state['values']['type'] == 'product') {
- // Clear the page and block caches.
- cache_clear_all();
- }
- }
- /**
- * Form builder: associate option combinations with a product variant's SKU.
- *
- * @see uc_product_adjustments_form_submit()
- *
- * @ingroup forms
- */
- function uc_product_adjustments_form($form, &$form_state, $node) {
- drupal_set_title($node->title);
- $nid = $node->nid;
- // Populate table and such.
- $model = $node->model;
- $query = db_select('uc_product_attributes', 'pa');
- $query->leftJoin('uc_attributes', 'a', 'pa.aid = a.aid');
- $query->leftJoin('uc_attribute_options', 'ao', 'a.aid = ao.aid');
- $query->leftJoin('uc_product_options', 'po', 'ao.oid = po.oid AND po.nid = :po_nid', array(':po_nid' => $nid));
- $result = $query->fields('pa', array('nid', 'aid', 'ordering', 'display'))
- ->fields('a', array('name', 'ordering', 'aid'))
- ->fields('ao', array('aid'))
- ->condition('pa.nid', $nid)
- ->having('COUNT(po.oid) > 0')
- ->groupBy('ao.aid')
- ->groupBy('pa.aid')
- ->groupBy('pa.display')
- ->groupBy('a.name')
- ->groupBy('pa.ordering')
- ->groupBy('a.ordering')
- ->groupBy('pa.nid')
- ->addTag('uc_product_adjustments_form')
- ->execute();
- $i = 1;
- $attribute_names = '';
- $full_attributes = array();
- $values = array();
- $query = db_select('uc_product_options', "po$i")->extend('PagerDefault')
- ->limit(20);
- $attribute_ids = array();
- foreach ($result as $prod_attr) {
- if ($i > 1) {
- $query->join('uc_product_options', "po$i");
- }
- $query->leftJoin('uc_attribute_options', "ao$i", "po$i.oid = ao$i.oid AND po$i.nid = :nid", array(':nid' => $nid));
- $query->addField("ao$i", 'aid', "aid$i");
- $query->addField("ao$i", 'name', "name$i");
- $query->addField("ao$i", 'oid', "oid$i");
- $query->addField("po$i", 'ordering', "ordering$i");
- $query->condition("ao$i.aid", $prod_attr->aid)
- ->orderBy("po$i.ordering")
- ->orderBy("ao$i.name");
- ++$i;
- $attribute_names .= '<th>' . check_plain($prod_attr->name) . '</th>';
- $attribute_ids[] = $prod_attr->aid;
- }
- $num_prod_attr = count($attribute_ids);
- if ($num_prod_attr) {
- // Get previous values.
- $old_vals = db_query("SELECT * FROM {uc_product_adjustments} WHERE nid = :nid", array(':nid' => $nid))->fetchAll();
- $result = $query->execute();
- $form['original'] = array(
- '#markup' => '<p><b>' . t('Default product SKU: @sku', array('@sku' => $model)) . '</b></p>',
- );
- $form['default'] = array(
- '#type' => 'value',
- '#value' => $model,
- );
- $form['table'] = array(
- '#prefix' => '<table class="combinations">',
- '#suffix' => '</table>',
- );
- $form['table']['head'] = array(
- '#markup' => '<thead><tr>' . $attribute_names . '<th>' . t('Alternate SKU') . '</th></tr></thead>',
- '#weight' => 0,
- );
- $form['table']['body'] = array(
- '#prefix' => '<tbody>',
- '#suffix' => '</tbody>',
- '#weight' => 1,
- '#tree' => TRUE,
- );
- $i = 0;
- while ($combo = $result->fetchObject()) {
- $cells = '';
- $row_title = '';
- $comb_array = array();
- for ($j = 1; $j <= $num_prod_attr; ++$j) {
- $cells .= '<td>' . check_plain($combo->{'name' . $j}) . '</td>';
- $row_title .= check_plain($combo->{'name' . $j}) . ', ';
- $comb_array[$combo->{'aid' . $j}] = $combo->{'oid' . $j};
- }
- ksort($comb_array);
- $row_title = substr($row_title, 0, strlen($row_title) - 2);
- $default_model = $model;
- foreach ($old_vals as $ov) {
- if ($ov->combination == serialize($comb_array)) {
- $default_model = $ov->model;
- break;
- }
- }
- $form['table']['body'][$i] = array(
- '#prefix' => '<tr title="' . $row_title . '">',
- '#suffix' => '</tr>',
- );
- $form['table']['body'][$i]['combo'] = array(
- '#markup' => $cells,
- );
- $form['table']['body'][$i]['combo_array'] = array(
- '#type' => 'value',
- '#value' => serialize($comb_array),
- );
- $form['table']['body'][$i]['model'] = array(
- '#type' => 'textfield',
- '#default_value' => $default_model,
- '#prefix' => '<td>',
- '#suffix' => '</td>',
- );
- ++$i;
- }
- $form['nid'] = array(
- '#type' => 'hidden',
- '#value' => $nid,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- );
- }
- else {
- $form['error'] = array(
- '#markup' => '<div><br />' . t('This product does not have any attributes that can be used for SKU adjustments.') . '</div>',
- );
- }
- $form['pager'] = array(
- '#theme' => 'pager',
- );
- return $form;
- }
- /**
- * Form builder for uc_product_adjustments_form().
- *
- * @see uc_product_adjustments_form()
- */
- function uc_product_adjustments_form_submit($form, &$form_state) {
- foreach ($form_state['values']['body'] as $value) {
- if (!empty($value['model']) && $value['model'] != $form_state['values']['default']) {
- db_merge('uc_product_adjustments')
- ->key(array(
- 'nid' => $form_state['values']['nid'],
- 'combination' => $value['combo_array'],
- ))
- ->fields(array(
- 'model' => $value['model'],
- ))
- ->execute();
- }
- else {
- db_delete('uc_product_adjustments')
- ->condition('nid', $form_state['values']['nid'])
- ->condition('combination', $value['combo_array'])
- ->execute();
- }
- }
- drupal_set_message(t('Product adjustments have been saved.'));
- }
|