You are here

dependent_dropdown.inc in Dropdown Attributes 6

Same filename and directory in other branches
  1. 7 dependent_dropdown.inc

Administrative interface for specifying the attribute dependencies.

These functions supply the administrative interface for specifying the attribute dependencies using AHAH. Based on code from the Examples module.

File

dependent_dropdown.inc
View source
<?php

/**
 * @file
 * Administrative interface for specifying the attribute dependencies.
 *
 * These functions supply the administrative interface for specifying the
 * attribute dependencies using AHAH.  Based on code from the Examples module.
 */

/**
 * Specify the attribute dependencies.
 */
function uc_dropdown_attributes_product(&$form_state, $product) {
  $nid = $product->nid;
  $attributes = uc_product_get_attributes($nid);
  $query = 'SELECT aid, parent_aid, parent_values, required
    FROM {uc_dropdown_attributes} WHERE nid="%s"';
  $dependencies = db_query($query, $nid);
  _uc_dropdown_attributes_form($form, $form_state, $attributes, $dependencies);

  // Check for overriding product class dropdowns.
  $type = uc_dropdown_attributes_dependency_type($nid);
  if (!is_null($type) && $type == 'class') {
    $form['submit']['#value'] = t('Override product class');
  }
  return $form;
}

/**
 * Submit handler for the second drop down.
 */
function uc_dropdown_attributes_dropdown_submit_handler($form, &$form_state) {
  $values = $form_state['values'];
  unset($form_state['submit_handlers']);
  form_execute_handlers('submit', $form, $form_state);
  $form_state['my_values'] = $values;
  $form_state['rebuild'] = TRUE;
}

/**
 * Callback for AHAH processing.
 */
function uc_dropdown_attributes_edit_callback($aid) {
  $form_state = array(
    'storage' => NULL,
    'submitted' => FALSE,
  );
  $form_build_id = $_POST['form_build_id'];
  $form = form_get_cache($form_build_id, $form_state);
  $args = $form['#parameters'];
  $form_id = array_shift($args);
  $form_state['post'] = $form['#post'] = $_POST;
  $form['#programmed'] = $form['#redirect'] = FALSE;
  drupal_process_form($form_id, $form, $form_state);
  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
  $changed_elements = $form['attributes'][$aid]['values-' . $aid . '-wrapper'];
  unset($changed_elements['#prefix'], $changed_elements['#suffix']);

  // Prevent duplicate wrappers.
  drupal_json(array(
    'status' => TRUE,
    'data' => theme('status_messages') . drupal_render($changed_elements),
  ));
}

/**
 * Write form values out to the database table.
 */
function uc_dropdown_attributes_product_submit($form, &$form_state) {
  if ($form_state['clicked_button']['#id'] == 'edit-submit') {
    $form_state['rebuild'] = FALSE;
    $nid = $form['#parameters'][2]->nid;
    $attributes = array();
    foreach ($form_state['values'] as $key => $value) {
      $keys = explode('-', $key);
      if (count($keys) > 1 && is_numeric($keys[1])) {
        if (!isset($attributes[$keys[1]])) {
          $attributes[$keys[1]] = new stdClass();
        }
        switch ($keys[0]) {
          case 'parent':
            $attributes[$keys[1]]->parent_aid = $value;
            break;
          case 'values':
            $attributes[$keys[1]]->parent_values = $value['values-' . $keys[1]];
            break;
          case 'required':
            $attributes[$keys[1]]->required = $value;
            break;
        }
      }
    }
    $query = 'DELETE FROM {uc_dropdown_attributes} WHERE nid=%d';
    $result = db_query($query, $nid);
    drupal_set_message(t('Processing node @nid', array(
      '@nid' => $nid,
    )));
    foreach ($attributes as $aid => $attribute) {
      if (property_exists($attribute, 'parent_values') && count($attribute->parent_values) > 0) {
        $success = uc_dropdown_attributes_product_create_dependency($nid, $aid, $attribute->parent_aid, $attribute->parent_values, $attribute->required);
        $attr = uc_attribute_load($aid);
        if ($success) {
          drupal_set_message(t('Saved @name', array(
            '@name' => $attr->name,
          )));
        }
        else {
          drupal_set_message(t('Database write failed for @name', array(
            '@name' => $attr->name,
          )), 'error');
        }
      }
    }
  }

  // edit-next or anything else will cause rebuild.
  $form_state['rebuild'] = TRUE;
}

/**
 * Form constructor for the uc_dropdown_attributes classes form.
 *
 * Administrative form for specifying the attribute dependencies for classes.
 *
 * @param $class
 *   The class with the attribute dependencies.
 *
 * @see uc_dropdown_attributes_class_submit()
 * @ingroup forms
 */
function uc_dropdown_attributes_class(&$form_state, $class) {
  $attributes = uc_class_get_attributes($class);
  $query = 'SELECT aid, parent_aid, parent_values, required
    FROM {uc_dropdown_classes} WHERE pcid="%s"';
  $dependencies = db_query($query, $class);
  _uc_dropdown_attributes_form($form, $form_state, $attributes, $dependencies);
  return $form;
}

/**
 * Write form values out to the database table.
 */
function uc_dropdown_attributes_class_submit($form, &$form_state) {
  if ($form_state['clicked_button']['#id'] == 'edit-submit') {
    $form_state['rebuild'] = FALSE;
    $pcid = $form['#parameters'][2];
    $attributes = array();
    foreach ($form_state['values'] as $key => $value) {
      $keys = explode('-', $key);
      if (count($keys) > 1 && is_numeric($keys[1])) {
        if (!isset($attributes[$keys[1]])) {
          $attributes[$keys[1]] = new stdClass();
        }
        switch ($keys[0]) {
          case 'parent':
            $attributes[$keys[1]]->parent_aid = $value;
            break;
          case 'values':
            $attributes[$keys[1]]->parent_values = $value['values-' . $keys[1]];
            break;
          case 'required':
            $attributes[$keys[1]]->required = $value;
            break;
        }
      }
    }
    $query = 'DELETE FROM {uc_dropdown_classes} WHERE pcid="%s"';
    $result = db_query($query, $pcid);
    drupal_set_message(t('Processing class @pcid', array(
      '@pcid' => $pcid,
    )));
    foreach ($attributes as $aid => $attribute) {
      if (property_exists($attribute, 'parent_values') && count($attribute->parent_values) > 0) {
        $success = uc_dropdown_attributes_class_create_dependency($pcid, $aid, $attribute->parent_aid, $attribute->parent_values, $attribute->required);
        $attr = uc_attribute_load($aid);
        if ($success) {
          drupal_set_message(t('Saved @name', array(
            '@name' => $attr->name,
          )));
        }
        else {
          drupal_set_message(t('Database write failed for @name', array(
            '@name' => $attr->name,
          )), 'error');
        }
      }
    }
  }

  // edit-next or anything else will cause rebuild.
  $form_state['rebuild'] = TRUE;
}

/**
 * Internal form constructor for administration of attribute dependencies.
 *
 * This function takes the data retrieved for products and classes and
 * constructs the dependencies administration form.
 *
 * @param array $form
 *   The form array.
 * @param array $form_state
 *   The values and state of the form.
 * @param array $attributes
 *   The attributes for this node or product class.
 * @param $dependencies
 *   The dependency information for the node or product class from the database.
 */
function _uc_dropdown_attributes_form(&$form, $form_state, $attributes, $dependencies) {
  $form['#cache'] = TRUE;

  // the contents will either come from the db or from $form_state
  if (isset($form_state['my_values'])) {
    $my_values = $form_state['my_values'];
  }
  else {
    while ($item = db_fetch_object($dependencies)) {
      $my_values['parent-' . $item->aid] = $item->parent_aid;
      $my_values['required-' . $item->aid] = $item->required;
      $my_values['values-' . $item->aid . '-wrapper']['values-' . $item->aid] = unserialize($item->parent_values);
    }
  }
  $form['intro'] = array(
    '#type' => 'markup',
    '#value' => '<p>' . t('Since drop down attributes may not appear, they cannot be always required.  The required checkbox applies only when the dropdown attribute appears.  Any dropdown attribute is also checked under the attributes table to make sure it is not required there as this would cause validation errors.') . '</p><p>' . t('If Javascript is not enabled, a Choose button appears at the bottom of the page to allow this page to be reloaded with the updated values.') . '</p>',
  );
  $form['prefix'] = array(
    '#type' => 'markup',
    '#value' => '<table><tr><th>' . t('Attribute') . '</th><th>' . t('Depends On') . '</th><th>' . t('With Values') . '</th><th>' . t('Required') . '</th></tr>',
  );
  $index = 1;
  foreach ($attributes as $attribute) {
    $form['attributes'][$attribute->aid]['attribute-' . $attribute->aid] = array(
      '#type' => 'markup',
      '#prefix' => '<tr><td>',
      '#value' => $attribute->name,
      '#suffix' => '</td>',
    );
    $options = array();
    $options[0] = 'None';
    foreach ($attributes as $option) {
      if ($option->aid != $attribute->aid) {
        $options[$option->aid] = $option->name;
      }
    }
    $selected = isset($my_values['parent-' . $attribute->aid]) ? $my_values['parent-' . $attribute->aid] : 0;
    $form['attributes'][$attribute->aid]['parent-' . $attribute->aid] = array(
      '#type' => 'select',
      '#prefix' => '<td>',
      '#options' => $options,
      '#default_value' => $selected,
      '#ahah' => array(
        'path' => 'dropdown/dependencies/' . $attribute->aid . '/callback',
        'wrapper' => 'values-' . $attribute->aid . '-replace',
      ),
    );
    $form['attributes'][$attribute->aid]['values-' . $attribute->aid . '-wrapper'] = array(
      '#tree' => TRUE,
      '#prefix' => '<td><div id="values-' . $attribute->aid . '-replace">',
      '#suffix' => '</div></td>',
    );
    $options = array();
    if ($selected == 0) {
      $type = 'select';
    }
    else {
      $parent_attributes = uc_attribute_load($selected);
      if (count($parent_attributes->options) == 0) {
        $type = 'textfield';
      }
      else {
        $type = 'select';
        foreach ($parent_attributes->options as $oid => $option) {
          $options[$oid] = $option->name;
        }
      }
    }
    if ($type == 'select') {
      $form['attributes'][$attribute->aid]['values-' . $attribute->aid . '-wrapper']['values-' . $attribute->aid] = array(
        '#type' => $type,
        '#options' => $options,
        '#multiple' => TRUE,
        '#default_value' => isset($my_values['values-' . $attribute->aid . '-wrapper']['values-' . $attribute->aid]) ? $my_values['values-' . $attribute->aid . '-wrapper']['values-' . $attribute->aid] : '',
      );
    }
    else {
      $form['attributes'][$attribute->aid]['values-' . $attribute->aid . '-wrapper']['values-' . $attribute->aid] = array(
        '#type' => $type,
        '#size' => 30,
        '#default_value' => isset($my_values['values-' . $attribute->aid]) ? $my_values['values-' . $attribute->aid] : '',
      );
    }
    if (isset($my_values['required-' . $attribute->aid])) {
      $default_value = $my_values['required-' . $attribute->aid];
    }
    else {
      $default_value = 0;
    }
    $form['attributes'][$attribute->aid]['required-' . $attribute->aid] = array(
      '#type' => 'checkbox',
      '#prefix' => '<td>',
      '#returned_value' => 1,
      '#default_value' => $default_value,
      '#suffix' => '</td></tr>',
    );
    $index++;
  }
  $form['suffix'] = array(
    '#type' => 'markup',
    '#value' => '</table>',
  );

  // The CSS for this module hides this next button if JS is enabled.
  $form['continue'] = array(
    '#type' => 'submit',
    '#value' => t('Choose'),
    '#suffix' => '</td>',
    '#attributes' => array(
      'class' => 'next-button',
    ),
    '#submit' => array(
      'uc_dropdown_attributes_dropdown_submit_handler',
    ),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return;
}

Functions

Namesort descending Description
uc_dropdown_attributes_class Form constructor for the uc_dropdown_attributes classes form.
uc_dropdown_attributes_class_submit Write form values out to the database table.
uc_dropdown_attributes_dropdown_submit_handler Submit handler for the second drop down.
uc_dropdown_attributes_edit_callback Callback for AHAH processing.
uc_dropdown_attributes_product Specify the attribute dependencies.
uc_dropdown_attributes_product_submit Write form values out to the database table.
_uc_dropdown_attributes_form Internal form constructor for administration of attribute dependencies.