You are here

bpc_taxonomy.module in Commerce Bulk Product Creation 7

Same filename and directory in other branches
  1. 7.2 modules/bpc_taxonomy/bpc_taxonomy.module

The Commerce BPC Taxonomy integration module enables the use of taxonomy term references in bulk creation.

File

modules/bpc_taxonomy/bpc_taxonomy.module
View source
<?php

/**
 * @file
 *  The Commerce BPC Taxonomy integration module enables the use of taxonomy
 *  term references in bulk creation.
 */

/**
 * Implements hook_commerce_bpc_is_combination_field().
 */
function bpc_taxonomy_commerce_bpc_is_combination_field($instance) {
  $field = field_info_field($instance['field_name']);
  if ($field['type'] == 'taxonomy_term_reference') {
    $force_static = _commerce_bpc_get_value($instance, array(
      'commerce_bpc',
      'is_static',
    ), FALSE);
    $cart_settings = commerce_cart_field_instance_attribute_settings($instance);
    $is_attribute_field = $cart_settings['attribute_field'];
    return !$force_static && $is_attribute_field;
  }
}

/**
 * Implements hook_commerce_bpc_FIELD_TYPE_form_element_alter().
 */
function bpc_taxonomy_commerce_bpc_taxonomy_term_reference_form_element_alter(&$form, &$form_state, &$path) {
  $element = drupal_array_get_nested_value($form, $path);
  $lang = $element['#language'];
  $field_name = $element[$lang]['#field_name'];
  $instance = field_info_instance('commerce_product', $field_name, $form['product_type']['#value']);
  if (bpc_taxonomy_commerce_bpc_is_combination_field($instance)) {
    switch ($instance['widget']['type']) {
      case 'options_buttons':
        $element[$lang]['#type'] = 'checkboxes';
        unset($element[$lang]['#options']['_none']);
        break;
      case 'options_select':
        $element[$lang]['#multiple'] = TRUE;
        unset($element[$lang]['#options']['_none']);
        break;
      case 'taxonomy_autocomplete':

        // For now, we leave as is. Autocomplete is not recommended, though.
        break;
    }

    // Move to comibinations-fieldset
    $form['combinations'][$field_name] = $element;
    drupal_array_set_nested_value($form, $path, NULL);

    // Change path to allow subsequent hooks operate on the form element.
    $path = array(
      'combinations',
      $field_name,
    );
    if (empty($form_state['commerce_bpc']['bpc_taxonomy']['combination_fields']) || !in_array($field_name, $form_state['commerce_bpc']['bpc_taxonomy']['combination_fields'])) {

      // Record what we have done. As this hook may be run multiple times
      // due to form rebuilds, we need to make sure that we record each field
      // only once.
      $form_state['commerce_bpc']['bpc_taxonomy']['combination_fields'][] = $field_name;
    }
  }
}

/**
 * Implements hook_commmerce_bpc_get_combinations().
 *
 * @todo: This is EXACTLY the same as the list implementation, except for
 *   three places where 'list' needs to be replaced by 'bpc_taxonomy'.
 *   Refactoring.
 */
function bpc_taxonomy_commerce_bpc_get_combinations($form, &$form_state, &$combinations) {
  if (isset($form_state['commerce_bpc']['bpc_taxonomy'])) {
    $new_combinations = array();
    $fields = $form_state['commerce_bpc']['bpc_taxonomy']['combination_fields'];
    foreach ($fields as $field_name) {
      $new_combinations = array();

      // Todo: Treat languages properly.
      $langs = array_keys($form_state['values']['combinations'][$field_name]);
      $lang = reset($langs);
      $values =& $form_state['values']['combinations'][$field_name][$lang];
      if (empty($values)) {

        // If no value is present, we skip processing this field.
        continue;
      }
      foreach ($combinations as $combination) {
        foreach ($values as &$columns) {
          if ($columns['tid'] == 'autocreate') {

            // We save new values entered into the autocomplete here---for there
            // there is no sensible way to create combinations if the term does
            // not exist.
            $term = (object) $columns;
            unset($term->tid);
            taxonomy_term_save($term);
            $columns['tid'] = $term->tid;
          }
          if (!taxonomy_field_is_empty($columns, $field_name)) {
            $new_combinations[] = $combination + array(
              $field_name => array(
                $lang => array(
                  $columns,
                ),
              ),
            );
          }
          else {
            $new_combinations[] = $combination;

            // If the values for a field are empty, we make sure that
            // we (re)-add the original combination only once.
            break;
          }
        }
      }
      $combinations = $new_combinations;
    }
  }
}

/**
 * Implements hook_commerce_bpc_tokens().
 *
 */
function bpc_taxonomy_commerce_bpc_tokens($product_type, $combination, $options) {
  $replacements = array();
  $sanitize = !empty($options['sanitize']);
  foreach ($combination as $field_name => $values) {
    $field = field_info_field($field_name);
    $instance = field_info_instance('commerce_product', $field_name, $product_type);
    if ($field['type'] == 'taxonomy_term_reference' && !_commerce_bpc_get_value($instance, array(
      'commerce_bpc',
      'is_static',
    ), FALSE)) {

      // TODO: Treat languages properly.
      $items = reset($values);

      // We only allow a single value per combination, so we can treat
      // this like a single value field.
      $value = $items[0]['tid'];
      $replacements['values'][$field_name] = $value;
      $labels = taxonomy_allowed_values($field);
      if (!empty($value)) {

        // $value can be empty in the case of sample value generation for
        // an empty vocabulary.
        $replacements['labels'][$field_name] = $sanitize ? check_plain($labels[$value]) : $labels[$value];
      }
      else {

        // If empty, we just use the dummy term "example"
        $replacements['labels'][$field_name] = "example";
      }
    }
  }
  return $replacements;
}

/**
 * Implements hook_commerce_bpc_token_sample_values().
 */
function bpc_taxonomy_commerce_bpc_token_sample_values($instance) {
  $samples = array();
  $field_name = $instance['field_name'];
  $field = field_info_field($field_name);
  if ($field['type'] == 'taxonomy_term_reference') {
    $options = taxonomy_allowed_values($field);
    $values = array_keys($options);
    $samples['value'] = array(
      LANGUAGE_NONE => array(
        array(
          'tid' => reset($values),
        ),
      ),
    );
    $samples['label'] = reset($options);
  }
  return $samples;
}

/**
 * Implements hook_module_implements_alter().
 *
 * We make sure that our implementation of hook_form_FORM_ID_alter() is
 * invoked after commerce_bpc's, by moving it to the end of the list of
 * implementations.
 */
function bpc_taxonomy_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_field_ui_field_edit_form_alter') {
    $group = $implementations['bpc_taxonomy'];
    unset($implementations['bpc_taxonomy']);
    $implementations['bpc_taxonomy'] = $group;
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function bpc_taxonomy_form_field_ui_field_edit_form_alter(&$form, $form_state) {
  $settings = $form['#instance'];
  if ($form['#instance']['entity_type'] == 'commerce_product') {
    if ($form['#field']['type'] == 'taxonomy_term_reference') {
      $form['instance']['commerce_bpc']['is_static'] = array(
        '#type' => 'checkbox',
        '#title' => t('Treat this field as static'),
        '#default_value' => !isset($settings['commerce_bpc']['is_static']) ? FALSE : $settings['commerce_bpc']['is_static'],
        '#description' => t('Term reference fields can either be used to create combinations, or can be set to be static, in which case all bulk-created products will share the same value for the field.'),
      );
    }
  }
}