You are here

lineage.module in Taxonomy Lineage 5

Same filename and directory in other branches
  1. 6 lineage.module
  2. 7 lineage.module

File

lineage.module
View source
<?php

function lineage_taxonomy($op, $type, $term = '') {

  // we care not about vocabularies
  if ($type == 'vocabulary') {
    return;
  }
  switch ($op) {
    case 'delete':
      lineage_delete_term($term['tid']);
      break;
    case 'insert':
    case 'update':
      lineage_update_term($term);
      break;
  }
}
function lineage_enable() {
  drupal_set_message(t("Updated @number taxonomy records.", array(
    '@number' => lineage_update_all(),
  )));
}
function lineage_update_all() {
  $tids = array();
  $result = db_query("SELECT td.tid, td.name, td.weight FROM {term_data} td LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE th.parent = 0");
  while ($term = db_fetch_object($result)) {
    $tids = lineage_update_term_r($term, array(), $tids);
  }
  return count($tids);
}

// This can run a lot of queries, but luckily only happens when an admin
// edits a vocabulary.
function lineage_update_term($term) {
  if (is_array($term)) {
    $term = (object) $term;
  }
  $base = _lineage_get_parent_lineage($term->parent);
  return count(lineage_update_term_r($term, $base, array()));
}
function lineage_update_term_r($term, $base, $tids) {

  // Extend the base.
  $base['base'] .= lineage_string($term);

  // Update the hierarchy for the current tid.
  db_query("DELETE FROM {term_lineage} WHERE tid = '%d'", $term->tid);
  db_query("INSERT INTO {term_lineage} (tid, lineage, depth) VALUES ('%d', '%s', '%d')", $term->tid, $base['base'], $base['depth']);
  $base['depth']++;

  // Mark that we've done this one to prevent looping.
  $tids[$term->tid] = true;

  // Update all the children.
  $result = db_query("SELECT td.tid, td.name, td.weight FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE th.parent = '%d'", $term->tid);
  while ($child = db_fetch_object($result)) {

    // loop protection, just in case.
    if (!isset($tids[$child->tid])) {
      $tids = lineage_update_term_r($child, $base, $tids);
    }
  }
  return $tids;
}
function lineage_delete_term($tid) {
  db_query("DELETE FROM {term_lineage} WHERE tid = '%d'", $tid);
}
function lineage_string($term) {

  // add 10 to the weight cause negative numbers don't sort the same
  // in strong form as they do numerically.
  return sprintf("%02d", $term->weight + 10) . $term->name . "\n";
}

// recurse until there are no more parents.
function _lineage_get_parent_lineage($tid) {
  if (!$tid) {
    return array();
  }
  $term = db_fetch_object(db_query("SELECT td.tid, td.name, td.weight, th.parent FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE td.tid = '%d'", $tid));
  if (!$term->tid) {
    return $ret;
  }
  $ret = _lineage_get_parent_lineage($term->parent);
  $ret['base'] .= lineage_string($term);
  $ret['depth'] += 1;
  return array();
}
function lineage_views_tables() {
  $tables['term_lineage'] = array(
    "name" => "term_lineage",
    "join" => array(
      "left" => array(
        "table" => "term_node",
        "field" => "tid",
      ),
      "right" => array(
        "field" => "tid",
      ),
    ),
    "fields" => array(
      "lineage" => array(
        'name' => "Lineage: Taxonomy Hierarchy",
        'sortable' => true,
        'handler' => 'lineage_view_handler',
      ),
      "depth" => array(
        'name' => "Lineage: Depth",
        'sortable' => false,
      ),
    ),
    "sorts" => array(
      "lineage" => array(
        'name' => "Lineage: Taxonomy Hierarchy",
      ),
    ),
  );
  return $tables;
}
function lineage_view_handler($field, $field_details, $content, $content_details) {

  // split lineage string into pieces, i.e. hierarchial path (getting rid of weight numbers, too)
  $path = split("\n[0-9]+", "\n" . $content);
  $s = '';

  // compose the path in readable form
  foreach ($path as $a) {
    if ($s != '') {
      $s .= '  /  ';
    }
    $s .= str_replace("\n", '', $a);
  }

  // output pseudo-link (without href) with hierarchically indented term and full path via title/alt-rollover
  return str_repeat('&nbsp;&nbsp;&nbsp;', substr_count($content, "\n") - 1) . '<a title="' . $s . '" alt="' . $s . '">' . $a . '</a>';
}