1

I'm using a using a custom function to display child nodes of a taxonomy term while displaying the term page. Here is the function

function theme_name_child_terms($vid = 1) {
  if(arg(0) == 'taxonomy' && arg(1) == 'term') {   
    $children = taxonomy_get_children(arg(2), $vid);
      if(!$children) {
        $custom_parent = taxonomy_get_parents(arg(2));
          $parent_tree = array();
          foreach ($custom_parent as $custom_child => $key) {
            $parent_tree = taxonomy_get_tree($vid, $key->tid);
          }
          $children = $parent_tree;
      }

    $output = '<ul>';
    // Avoid unnecessary "Invalid foreach" errors showing up in the log:
    if (!empty($children)) {
        // If not empty, run the foreach loop:
        foreach ($children as $term) {
            // Then check to see if any nodes exist for that term id:
            $number_of_nodes = taxonomy_term_count_nodes($term->tid);
            // If there ARE nodes...
            if ($number_of_nodes > 0) {
              // ... then add them to the output:
              $output .= '<li>';
              $output .= l($term->name . ' (' . $number_of_nodes . ')', 'taxonomy/term/' . $term->tid);
              $output .= '</li>';
              }
        }
    }
    $output .= '</ul>';

    return $output;
  }
}

This is the output: screen shot. You can can see that it's showing terms and node counts in brackets for items that are not in the 'jewellery' catalogue anymore as they are sold.

The problem I have is that the nodes i'm dealing with are products in an ubercart catalogue - - all items are unique as it's an antique trading site. The function above still counts 'sold' items as nodes associated with the term - a sold item is of course still tagged with a taxonomy term . - so, some terms are leading to blank pages, because I filter out nodes that are sold, from the taxonomy view.

Can another step be added to the function that checks each node associated with a term if it is a has stock level of 1 or above?

I've found the following function in uc_stock.module:

/**
 * Get the stock level of a particular product SKU.
 *
 * @param $sku
 *   The Ubercart product SKU of the stock level to return.
 * @return:
 *   The SKU's stock level, or FALSE if not active.
 */
function uc_stock_level($sku) {
  $stock = db_fetch_object(db_query("SELECT active, stock FROM {uc_product_stock} WHERE sku = '%s'", $sku));

  if ($stock && $stock->active) {
    return $stock->stock;
  }

  return FALSE;
}

I just can't figure out where or how to call this function in the original function. It needs to be passed the product 'sku', but i'm not sure how to give it that parameter. I guess it should be something like:

$stock = uc_stock_level($sku);
  if ($stock > 0) {
    ...
  }

Any help much appreciated.

1 Answer 1

1

Note: here's a good page to have bookmarked when you use Ubercart with D6: http://www.ubercart.org/docs/api (as opposed to http://api.ubercart.me for when you use D7).

Also note: this ended up being a lot more in-depth than I anticipated, but I was already knee-deep in it so I figured I'd finish it up. ;) That said...


You're definitely on the right track... Like you said, you could just supply the function uc_stock_level($sku) with the value of $sku, but that might be a lot of SKUs and therefore kind of resource intensive.

Another alternative that should work would be something like this:

Change this part of your code:

$output = '<ul>';
// Avoid unnecessary "Invalid foreach" errors showing up in the log:
if (!empty($children)) {
    // If not empty, run the foreach loop:
    foreach ($children as $term) {
        // Then check to see if any nodes exist for that term id:
        $number_of_nodes = taxonomy_term_count_nodes($term->tid);
        // If there ARE nodes...
        if ($number_of_nodes > 0) {
          // ... then add them to the output:
          $output .= '<li>';
          $output .= l($term->name . ' (' . $number_of_nodes . ')', 'taxonomy/term/' . $term->tid);
          $output .= '</li>';
          }
    }
}
$output .= '</ul>';

To something like this:

$output = '<ul>';
// Avoid unnecessary "Invalid foreach" errors showing up in the log:
if (!empty($children)) {
  // If not empty, run the foreach loop:
  foreach ($children as $term) {
    // Then check to see if any nodes exist for that term id:
    $number_of_nodes = taxonomy_term_count_nodes($term->tid);
    // And then check to see what the current stock level is:
    $stock_level = fetch_stock_level_from_termid($term->tid);
    // If there ARE nodes...
    if ($number_of_nodes > 0) {
      // And if the product is in stock...
      if ($stock_level > 0) {
        // ... then add them to the output:
        $output .= '<li>';
        $output .= l($term->name . ' (' . $number_of_nodes . ')', 'taxonomy/term/' . $term->tid);
        $output .= '</li>';
      }
    }
  }
}
$output .= '</ul>';

You'll then need to add the function fetch_stock_level_from_termid() to your code as well:

function fetch_stock_level_from_termid($term_id) {
  $sql = "SELECT SUM( {uc_product_stock}.stock ) AS stock
          FROM {uc_product_stock}
          INNER JOIN {node} ON {uc_product_stock}.nid = {node}.nid
          INNER JOIN {term_node} ON {node}.vid = {term_node}.vid
          WHERE {term_node}.tid = %d
          AND {node}.status = 1";
  $stock_available = db_result(db_query($sql, $term_id));
  return $stock_available;
}

Hope that helps... :)

2
  • Wow! Thank you so much! Works perfectly. Really appreciate your time and effort coming up with an elegant solution. Saved me a lot of head scratching!
    – NickTr
    Commented Jun 4, 2013 at 14:54
  • Hey no prob. Been there a few times so I know what it can be like sometimes... >_< OH and also, if you use path aliases you could change the line that reads $output .= l($term->name . ' (' . $number_of_nodes . ')', 'taxonomy/term/' . $term->tid); to something like this: $output .= l($term->name . ' (' . $number_of_nodes . ')', drupal_get_path_alias('taxonomy/term/' . $term->tid));
    – jerdiggity
    Commented Jun 4, 2013 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.