You are here

function commerce_cart_field_attach_view_alter in Commerce Core 7

Implements hook_field_attach_view_alter().

When a field is formatted for display, the display formatter does not know what view mode it is being displayed for. Unfortunately, the Add to Cart form display formatter needs this information when displaying product reference fields on nodes to provide adequate context for product field replacement on multi-value product reference fields. This hook is used to transform a set of arguments into a form using the arguments and the extra context information gleaned from the parameters passed into this function.

File

modules/cart/commerce_cart.module, line 2785
Implements the shopping cart system and add to cart features.

Code

function commerce_cart_field_attach_view_alter(&$output, $context) {

  // Loop through the fields passed in looking for any product reference fields
  // formatted with the Add to Cart form display formatter.
  foreach ($output as $field_name => $element) {
    if (!empty($element['#formatter']) && $element['#formatter'] == 'commerce_cart_add_to_cart_form') {

      // Prepare the context information needed by the cart form.
      $cart_context = $context;

      // Remove the full entity from the context array and put the ID in instead.
      list($entity_id, $vid, $bundle) = entity_extract_ids($context['entity_type'], $context['entity']);
      $cart_context['entity_id'] = $entity_id;
      unset($cart_context['entity']);

      // Remove any Views data added to the context by views_handler_field_field.
      // It unnecessarily increases the size of rows in the cache_form table for
      // Add to Cart form state data.
      if (!empty($cart_context['display']) && is_array($cart_context['display'])) {
        unset($cart_context['display']['views_view']);
        unset($cart_context['display']['views_field']);
        unset($cart_context['display']['views_row_id']);
      }

      // Add the context for displaying product fields in the context of an entity
      // that references the product by looking at the entity this product
      // reference field is attached to.
      $cart_context['class_prefix'] = $context['entity_type'] . '-' . $entity_id;
      $cart_context['view_mode'] = $context['entity_type'] . '_' . $element['#view_mode'];
      $entity_uri = entity_uri($context['entity_type'], $element['#object']);
      foreach (element_children($element) as $key) {

        // Extract the drupal_get_form() arguments array from the element.
        $arguments = $element[$key]['#arguments'];

        // Add the display path and referencing entity data to the line item.
        if (!empty($entity_uri['path'])) {
          $arguments['line_item']->data['context']['display_path'] = $entity_uri['path'];
        }
        $arguments['line_item']->data['context']['entity'] = array(
          'entity_type' => $context['entity_type'],
          'entity_id' => $entity_id,
          'product_reference_field_name' => $field_name,
        );

        // Update the product_ids variable to point to the entity data if we're
        // referencing multiple products.
        if (count($arguments['line_item']->data['context']['product_ids']) > 1) {
          $arguments['line_item']->data['context']['product_ids'] = 'entity';
        }

        // Translate button text.
        $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
        $translated_instance = commerce_i18n_object('field_instance', $instance);
        $view_mode = $element['#view_mode'];

        // Special case for full view mode.
        if ($view_mode == 'full') {
          $view_modes = field_view_mode_settings($element['#entity_type'], $element['#bundle']);
          if (!empty($view_modes['full']) && !$view_modes['full']['custom_settings']) {
            $view_mode = 'default';
          }
        }
        if (!empty($translated_instance['add_to_cart_form-button_text-' . $view_mode])) {
          $arguments['line_item']->data['context']['button_text'] = $translated_instance['add_to_cart_form-button_text-' . $view_mode];
        }

        // Replace the array containing the arguments with the return value of
        // drupal_get_form(). It will be rendered when the rest of the object is
        // rendered for display.
        $output[$field_name][$key] = drupal_get_form($arguments['form_id'], $arguments['line_item'], $arguments['show_quantity'], $cart_context);
      }
    }
  }
}