Is there any specific reason for hook_tapir_table_header_alter() not being called for many tables like op_products_view_table, op_order_comments_view_table etc? Hook_tapir_table_alter() does get called by way of tapir_get_table() but without being able to add a new column header, the extra data will not be observed, either. Adding the required

drupal_alter('tapir_table_header', $table['#columns'], 'xxx');

lines in uc_order.order_pane.inc and other files seems to work without problems (with the usual caveat of being nasty to modify core).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

longwave’s picture

If you can supply a patch for the relevant places I'd be happy to review it.

djg_tram’s picture

OK, a quickie... :-)

longwave’s picture

Status: Active » Needs review

Is that hook actually needed at all? This seems to work:

function test_tapir_table_alter(&$data, $table_id) {
  if ($table_id == 'op_products_view_table') {
    $data['#columns']['test'] = array(
      'cell' => array('data' => 'Test'),
      'weight' => 6,
    );

    foreach ($data['#rows'] as $id => &$row) {
      $row['test'] = array('#value' => 'test');
    }
  }
}
djg_tram’s picture

Ooops, good idea, I'll try it tomorrow, it's getting late over here... I just assumed that header definitions should go into headers (the doc hooks.php shows it that way, too), it never occurred to me to try this approach. If it does work, I stand corrected, but then, the doc should mention this...

PS: I just had to try it right now... :-) OK, it does work, you're completely right. Patch retracted. Not really straightforward to do this with all tables except uc_product_table that does call the header function but it sure works. Thanks.

arpieb’s picture

Status: Needs review » Active

This is still not a catch-all solution. I attempted to use this code to modify the 'view cart' page's table (table_id == 'uc_cart_view_table') since hook_tapir_table_header_alter() is not getting invoked for this table either, and it works only for the product listing portion of the cart (albeit the '#rows' key does not exist for that table, had to use element_children() instead).

The original columns are still somehow coming into play in the subtotal line as I'm getting the proper total column (now my eighth column), but a '$0.00' value is showing up in the third column position - which is where the default total column used to be.

IMHO, if the hook is documented to work a certain way, it should work. Not sometimes. Not if you hold your mouth just right. In actuality in the 6.x-2.x-dev codebase, the drupal_alter() call needed to invoke this hook is only called in one place in uc_product.module in uc_product_table_header(). With all the tables generated by Ubercart, I can't believe they documented a hook that is only ever invoked in one place...?

djg_tram's patch is a good start to correcting this behavior - but it really needs to be implemented everywhere that UC generates a TAPIr table instead of conditionally coding around it... Flipping this issue back to 'active' as it does need to be addressed.

longwave’s picture

@arpieb: So does your code work on uc_cart_view_table if the patch from #2 is applied? Can you paste your code, or a simplified version, so it can be used to test this hook?

arpieb’s picture

@longwave, that patch above applies to uc_order - I'm trying to alter the tables being displayed for the 'view cart' and checkout pane (which as it turns out doesn't use the same process at all). I can try to cut down what I wound up implementing for the 'view cart' solution, but the code is heavily customized (rearranging columns via weighting, changing classes, adding new columns, etc).

First off, I kind of hate the large switch statement thing, so have a utility "wrapper" function to redirect traffic in my module (not unlike the way hook_form_FORM_ID_alter works):

function module_tapir_table_alter(&$table, $table_id) {
  //drupal_set_message(__FUNCTION__ . ' : ' . $table_id);
  //drupal_set_message(__FUNCTION__ . ' : <br /><pre>' . print_r($table, TRUE) . '</pre>');
  
  $table_id = str_replace(' ', '_', $table_id);
  $function = '_module_tapir_table_alter_'. $table_id;
  if (function_exists($function)) {
    return $function($table);
  }
}

In my function for handling the table uc_cart_view_table I do the following:

/*
 * Function modifying the table 'uc_cart_view_table' called from module_tapir_table_alter 
 */
function _module_tapir_table_alter_uc_cart_view_table(&$table) {
  // Update column headers:
  $cols = &$table['#columns'];
  $cols['image']['cell'] = t('Photo');
  $cols['desc']['cell'] = t('Style');
  
  // Add new columns:
  $cols['model'] = array(
    'cell' => t('Item #'),
  );
  $cols['color'] = array(
    'cell' => t('Color'),
  );
  $cols['unit_price'] = array(
    'cell' => t('Per Yard'),
  );
  
  // Change order of columns:
  $weight = 0;
  $cols['image']['weight'] = $weight++;
  $cols['model']['weight'] = $weight++;
  $cols['desc']['weight'] = $weight++;
  $cols['color']['weight'] = $weight++;
  $cols['qty']['weight'] = $weight++;
  $cols['unit_price']['weight'] = $weight++;
  $cols['total']['weight'] = $weight++;
  $cols['remove']['weight'] = $weight++;
  
  // Loop through rows and add column data:    
  foreach (element_children($table) as $key) {
    $row = &$table[$key];
    
    // Bail on subtotal row:
    if ('subtotal' == $row['total']['#cell_attributes']['class']) {
      continue;
    }
  
    $node = node_load($table['#parameters'][1][$key]['nid']['#value']);

    // Adjust current columns:
    $row['desc']['#cell_attributes']['class'] = 'style';
    
    // Add new column data to row:
    $row['model'] = array(
      '#value' => l($node->model, 'node/' . $node->nid),
      '#cell_attributes' => array(
        'align' => 'left',
        'class' => 'item_no',
      ),
    );
    $row['color'] = array(
      '#value' => $node->body,
      '#cell_attributes' => array(
        'align' => 'left',
        'class' => 'color',
      ),
    );
    $row['unit_price'] = array(
      '#value' => uc_price($node->sell_price, array('revision' => 'themed')),
      '#cell_attributes' => array(
        'align' => 'right',
        'class' => 'unit_price',
      ),
    ); 
  }
}

You can see a screenshot of the resulting 'view cart' content here:

http://screencast.com/t/on9wWmaahrIz

It would have been nice to isolate the headers in the expected hook according to the docs, but I made due... Notice how the structure of the data is significantly different than that of the product listings that the solution in #3 lists.

And, the checkout pane cart view? Not using either of these mechanisms, it invokes a theme function to render the raw HTML... I wound up building a new cart pane that replaces the default cart view pane defined in uc_cart_checkout_pane.inc so I could totally control the look and feel of that cart view.

longwave’s picture

Status: Active » Needs review

If #2 still applies, I guess there is no harm in committing it.

Status: Needs review » Needs work

The last submitted patch, uc_order_table_header_alter.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
FileSize
1.28 KB

Reuploading #2

longwave’s picture

Status: Needs review » Fixed

Committed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.