Home ›
Listing of all possible ancestor paths DEFEATED!Listing of all possible ancestor paths DEFEATED!
Submitted by Benjamin Melançon on August 26, 2007 - 4:02pm
Rube Goldberg has nothing on me.
Here it is, in its last testing phase. It'll get the comments cleaned up, but after-the-fact advice on the way the module actually works would be greatly appreciated.
<?php
function cmt_get_ladders($tid) {
// each level is either done, or has the tid (or count?) of the next term to trace
// ladder[0] has levels 0, 1, 2, 3
// level 2 had an extra tid (term 1 had two parents)
// level 1 had two extra tid (had three parents)
// when we reach level 3, the term given has no parents
// return to the most recent fork, level 2
// duplicate ladder [0] to ladder [1], unset everything above level
// on ladder[1], follow level 2 to the point that it has no parents
// return to the remaining fork, level 1
// duplicate ladder
$howdeep = 0;
$ladders_done = array();
$ladder = 0;
$level = 0;
$lterm = array(0 => $tid); // term we're currently dealing with by level
$ladders[$ladder][$level][$tid] = cmt_get_term($tid);
cmt_build_ladder($tid, $ladders, $ladder, $level, $lterm);
agaric_a($ladders, "Still got it!");
return
$ladders;
}
function
cmt_build_ladder($tid, &$ladders = array(), $ladder = 0, $level = 0, $lterm = array()) {
global $howdeep;
$howdeep++;
drupal_set_message("tid: " . $tid . ", ladder: " . $ladder . ", level: ".$level);
agaric_a($ladders, "Begin:");
// agaric_a($lterm);
$done = array();
//if ($ladder > 20 || $level > 25) return $ladders;
if ($parents = cmt_get_parents($tid, 'tid')) {
$level = $level + 1;
$ladders[$ladder][$level] = $parents;
$terms = array_keys($parents);
sort($terms); // sort function works by reference
$tid = $terms[0];
$lterm[$level] = $tid;
cmt_build_ladder($tid, $ladders, $ladder, $level, $lterm);
}
else { // we reached the top!
for ($total_levels = $level; $level > 0; $level--) {
drupal_set_message('total_levels '.$total_levels.', level '.$level);
if (count($ladders[$ladder][$level]) > 1) {
// make new ladder and start counting back up
$old_ladder = $ladder;
$new_ladder = $ladder+1;
$old_tid = $lterm[$level];
$new_tid = _cmt_next_highest_key($ladders[$old_ladder][$level], $old_tid);
$ladders[$new_ladder] = array(0 => $ladders[$old_ladder][0]); // the original term, so there'll be only one
for ($new_level = 1; $new_level <= $level; $new_level++) {
$ladders[$new_ladder][$new_level] = $ladders[$old_ladder][$new_level];
foreach ($ladders[$old_ladder][$new_level] AS $key => $value) {
// drupal_set_message("Key: $key and Value: $value");
if ($key != $lterm[$new_level]) {
unset($ladders[$old_ladder][$new_level][$key]);
}
}
}
unset($ladders[$new_ladder][$level][$old_tid]);
// agaric_a($ladders[$old_ladder], "Old ladder");
// agaric_a($ladders[$new_ladder], "New ladder");
// get the next tid
$lterm[$level] = $new_tid;
// $ladders =
cmt_build_ladder($new_tid, $ladders, $new_ladder, $level, $lterm);
}
}
// we reached the bottom of a clean stack!
//return $
drupal_set_message("Etid: " . $tid . ", ladder: " . $ladder . ", level: ".$level);
agaric_a($ladders, "End:");
}
}
/**
* Find all parents of a given term ID.
*/
function cmt_get_parents($tid, $key = 'tid') {
if (is_int($tid)) { // allows 0 (root) to be returned, added specially to the database
// need object, so no good: 'SELECT parent FROM {cmt_term_hierarchy} WHERE tid = %d'
$result = db_query('SELECT t.tid, t.* FROM {cmt_term_data} t INNER JOIN {cmt_term_hierarchy} h ON h.parent = t.tid WHERE h.tid = %d ORDER BY h.vote DESC, weight DESC, tid DESC', $tid);
$parents = array();
$i = 0;
while ($parent = db_fetch_object($result)) {
$parent->count = $i;
$parents[$parent->$key] = $parent;
$i++;
}
// drupal_set_message('Parents of ' . $tid );
// agaric_a($parents);
return $parents;
}
else {
return array();
}
}
?>
Comments
Post new comment