Ubercart: Add Unit Price to the Shopping Cart Table.

Profile picture for user Phil Frilling
By Phil Frilling, 6 April, 2012
We are working on an Ubercart store running Drupal 7 and we needed to add the price per unit to the shopping cart page. I didn't see any options for enabling this in the store administration area so I began looking for some code to make this happen. I came across this post, http://pixeljets.com/blog/adding-price-field-ubercart-cart-page, which was close to what I needed, but I figured there was a theme function I could use instead of a custom module. After searching the code of the uc_cart module I finally came across the theme function the cart page uses: theme_tapir_table!

Details

The following lines of code from the complete function below accomplish task. Basically, we do the following steps:
  1. Add the unit_price column to the #columns array
  2. Change the weights of the 'quantity' and 'total' columns to push them to the far right of the table.
  3. Loop through each row in the table and add the sell_price to the unit_price column for the row. The sell_price is stored in the $variables array keyed by the position in the table.

// Add the unit price to the $element['#columns'] array.
  $element['#columns']['unit_price'] = array(
    'cell' => t('Unit Price'),
    'weight' => 3,
  );
  
  // Change the weights of the qty and total columns.
  $element['#columns']['qty']['weight'] = 4;
  $element['#columns']['total']['weight'] = 5;
  
  // Loop through each row and if the entity exists in the variables array, 
  foreach ($element['#rows'] as $position => $data) {
    if (isset($element[$position]['#entity']->sell_price)) {
      $element['#rows'][$position]['unit_price'] = array(
        '#markup' => uc_currency_format($element[$position]['#entity']->sell_price),
      );
    }
    
  }

The final results

The Full Code


function MYTHEME_tapir_table($variables) {
  $element = $variables['element'];
  
  // Add the unit price to the $element['#columns'] array.
  $element['#columns']['unit_price'] = array(
    'cell' => t('Unit Price'),
    'weight' => 3,
  );
  
  // Change the weights of the qty and total columns.
  $element['#columns']['qty']['weight'] = 4;
  $element['#columns']['total']['weight'] = 5;
  
  foreach ($element['#rows'] as $position => $data) {
    //$element[$position]['#entity']['sell_price']
    if (isset($element[$position]['#entity']->sell_price)) {
      $element['#rows'][$position]['unit_price'] = array(
        '#markup' => uc_currency_format($element[$position]['#entity']->sell_price),
      );
    }
    
  }
  
  $header = array();
  $rows = array();

  // First sort the columns by weight.
  uasort($element['#columns'], 'uc_weight_sort');

  // Loop through the columns and create the header array.
  foreach ($element['#columns'] as $col_id => $col_data) {
    // Add the cell if available.
    if (!isset($col_data['access']) || $col_data['access'] !== FALSE) {
      $header[] = $col_data['cell'];
    }
  }

  // Loop through the row data and create rows with the data in the right order.
  foreach ($element['#rows'] as $data) {
    $attributes = array();
    $row = array();

    // Loop through each column in the header.
    foreach ($element['#columns'] as $col_id => $col_data) {
      // If this row defines cell data for the current column...
      if ((!isset($col_data['access']) || $col_data['access'] !== FALSE) && isset($data[$col_id])) {
        $cell = array();
        if (isset($data[$col_id]['#cell_attributes']) && is_array($data[$col_id]['#cell_attributes'])) {
          foreach ($data[$col_id]['#cell_attributes'] as $property => $value) {
            if ($property == 'colspan' && $value == 'full') {
              // Extend full-width cells to the number of columns actually
              // displayed.
              $value = count($header);
            }
            $cell[$property] = $value;
          }
          $cell['data'] = drupal_render($data[$col_id]);
        }
        else {
          $cell = drupal_render($data[$col_id]);
        }
        // Add it to the row array.
        $row[] = $cell;
      }
    }

    // Merge the row data into a single row array along with the attributes.
    if (isset($data['#attributes'])) {
      $row = array_merge(array('data' => $row), (array)$data['#attributes']);
    }

    // Add the current row to the table rows array.
    $rows[] = $row;
  }

  // Return the rendered table.
  $options = array(
    'header' => $header,
    'rows' => $rows,
  );
  if (isset($element['#attributes'])) {
    $options['attributes'] = (array)$element['#attributes'];
  }
  if (isset($element['#title'])) {
    $options['caption'] = $element['#title'];
  }

  return theme('table', $options) . drupal_render_children($element);
}