Index: includes/tree.inc =================================================================== RCS file: includes/tree.inc diff -N includes/tree.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/tree.inc 7 Dec 2008 19:21:17 -0000 @@ -0,0 +1,323 @@ +$vid) ); + while ($term = db_fetch_object($result)) { + $arrayq=array(':vid'=>$vid,':flv1'=>$term->flv,':flv2'=>($term->snv/$term->sdv)); + $query='SELECT * FROM {' . $table . '} WHERE vid = :vid AND flv > :flv1 AND flv < :flv2'; + if($depth > 0){ + $arrayq[":depth"]=$depth; + $query.=' AND depth<=:depth'; + } + $result2 = db_query($query,$arrayq); + while ($children = db_fetch_object($result2)) { + $tree[]=$children; + } + } + }else{ + // all the tree for a nv, dv + $term = db_query('SELECT * FROM {' . $table . '} WHERE vid=:vid and nv=:nv AND dv=:dv ',array(':vid'=>$vid,':nv'=>$nv,':dv'=>$dv) )->fetchObject(); + // calculate all the parent of the term + $ancnv = 0; + $ancdv = 1; + $ancsnv = 1; + $ancsdv = 0; + $numerator = $nv; + $denominator = $dv; + while ($numerator>0 && $denominator>0){ + $div = (int) ($numerator / $denominator); + $mod = $numerator % $denominator; + $ancnv = $ancnv + $div * $ancsnv; + $ancdv = $ancdv + $div * $ancsdv; + $ancsnv = $ancnv + $ancsnv; + $ancsdv = $ancdv + $ancsdv; + // grab the parent + $tree[] = db_query('SELECT * FROM {' . $table . '} WHERE nv=:nv AND dv=:dv AND vid=:vid ',array(':nv'=>$ancnv,':dv'=>$ancdv,':vid'=>$vid))->fetchObject(); + $numerator = $mod; + if($numerator>0){ + $denominator = $denominator - $mod; + if ($denominator==0){ + $denominator==1; + } + } + } + // grab the children + $arrayq=array(':vid'=>$vid,':flv1'=>$term->flv,':flv2'=>($term->snv/$term->sdv)); + $query='SELECT * FROM {' . $table . '} WHERE vid = :vid AND flv > :flv1 AND flv < :flv2'; + if($depth > 0){ + $arrayq[":depth"]=$term->depth+$depth; + $query.=' AND depth<=:depth'; + } + $result2 = db_query($query,$arrayq); + while ($children = db_fetch_object($result2)) { + $tree[] =$children; + } + } + return $tree; + +} + + +/** + * save a term in a tree with his parents as input + * + * @param $parents + * contains the parents to store, each element the nv,dv values + * also contains the tid and vid of the term + * @param $table + * database table to use + */ +function tree_term_save(&$parents,$table='term_hierarchy') { + if (count($parents->parent)>0) { + bcscale(9); + foreach ($parents->parent as $parent) { + //multiple parent case ordering needs to be done elsewhere, + //we insert at the rightest position in a level + // get values of parent + $p = db_query('SELECT * FROM {' . $table . '} WHERE nv = :nv AND dv = :dv AND vid= :vid',array(':nv'=>$parent["nv"],':dv'=>$parent["dv"],':vid'=>$parents->vid))->fetchObject(); + // get last right son + $s = db_query('SELECT snv,sdv FROM {' . $table . '} WHERE pflv = :pflv and vid=:vid ORDER BY flv DESC LIMIT 1', array(':pflv'=>$p->nv."-".$p->dv,':vid'=>$p->vid))->fetchObject(); + if( isset($s->snv) ){ + $nv=$s->snv; + $dv=$s->sdv; + }else{ + $nv=$p->nv + $p->snv; + $dv=$p->dv + $p->sdv; + } + $child_num = db_query('SELECT count(*) as num FROM {' . $table . '} WHERE pflv = :pflv and vid=:vid ', array(':pflv'=>$p->nv."-".$p->dv,':vid'=>$p->vid))->fetchObject(); + if(isset($child_num->num)){ + $num=$child_num->num + 2; + }else{ + $num=1; + } + // insert term + db_query('INSERT INTO {' . $table . '} (tid, nv, dv, snv, sdv,flv,pflv, vid,depth) VALUES (:tid,:nv,:dv,:snv,:sdv,:flv,:pflv,:vid,:depth)', + array(':tid'=>$parents->tid, + ':nv'=>$nv, + ':dv'=> $dv, + ':snv'=>($p->nv + $num * $p->snv), + ':sdv'=>($p->dv + $num * $p->sdv), + ':flv'=>bcdiv($nv,$dv), + ':pflv'=>$p->nv.'-'.$p->dv, + ':vid'=>$p->vid, + ':depth'=>($p->depth + 1)) ); + } + } else { + #top level insert + #we need in this case the vid in parents + $max = db_query('SELECT MAX(nv) as max FROM {' . $table . '} WHERE depth=0 and vid=:vid ',array(':vid'=>$parents->vid))->fetchObject(); + if(isset($max->max)){ + $last=$max->max +1; + }else{ + $last=2; + } + $nv = $last ; + $snv = $nv +1 ; + $dv = 1 ; + $sdv = 1 ; + db_query('INSERT INTO {' . $table . '} (tid, nv, dv, snv, sdv,flv,pflv, vid,depth) VALUES (:tid,:nv,:dv,:snv,:sdv,:flv,:pflv,:vid,:depth)', + array(':tid'=>$parents->tid, + ':nv'=>$last, + ':dv'=> 1, + ':snv'=>$nv+1, + ':sdv'=>1, + ':flv'=>$last, + ':pflv'=>'0', + ':vid'=>$parents->vid, + ':depth'=>0) ); + } +} + +/** + * remove an element of a tree + * @param $nv + * numerator value of the term + * @param $dv + * denominator value of the term + * @param $tid + * taxonomy term id, for complete removal purpose + * @param $table + * database table to use + */ +function tree_term_del($nv,$dv,$tid='',$vid, $table='term_hierarchy'){ + #TODO : remove the term +} + +/** + * move a subtree from under a term, to under the mth child of a term + * @param $nv + * numerator value of the term + * @param $dv + * denominator value of the term + * @param $pnv + * numerator value of parent of the term underneath the subtree will be moved + * @param $pdv + * denominator value of parent of the term underneath the subtree will be moved + * @param $m + * child number of the new root. The subtree, will be under this child + * @param $vid + * vid value of the term + * @param $table + * database table to use + */ +function tree_subtree_move($nv,$dv,$pnv,$pdv,$m,$vid, $table='term_hierarchy'){ + $sub = db_query('SELECT * FROM {' . $table . '} WHERE nv = :nv AND dv = :dv AND vid= :vid',array(':nv'=>$nv,':dv'=>$dv,':vid'=>$vid))->fetchObject(); + $s=explode('-',$sub->pflv); + $rnv=$s[0]; + $rdv=$s[1]; + $root = db_query('SELECT * FROM {' . $table . '} WHERE nv = :nv AND dv = :dv AND vid= :vid',array(':nv'=>$rnv,':dv'=>$rdv,':vid'=>$vid))->fetchObject(); + $children = tree_children_get($nv,$dv, $vid ,$table); + $new_root = db_query('SELECT * FROM {' . $table . '} WHERE nv = :nv AND dv = :dv AND vid= :vid',array(':nv'=>$pnv,':dv'=>$pdv,':vid'=>$vid))->fetchObject(); + #calculate root child number (n) + $c_child = db_query('SELECT count(*) as c FROM {' . $table . '} WHERE flv < :flv AND pflv = :pflv AND vid= :vid',array(':flv'=>$sub->flv,':pflv'=>$sub->pflv,':vid'=>$vid))->fetchObject(); + if($c_child->c==0){ + $n=1; + }else{ + $n=$c_child->c+1; + } + bcscale(9); + #calculate nv and dv of the mth child of new_root for updating the parent + $pflv= ( $new_root->nv + $m * $new_root->snv) .'-'. ( $new_root->dv +$m * $new_root->sdv ); + #calculate children relocation + foreach($children as $child){ + + $child->new_nv1= ( $new_root->nv + ($m -$n)*$new_root->snv ) * ( -$root->sdv ) + $new_root->snv * $root->dv; + $child->new_dv1= ( $new_root->dv + ($m -$n)*$new_root->sdv ) * ( -$root->sdv ) + $new_root->sdv * $root->dv; + $child->new_snv1= ( $new_root->nv + ($m -$n)*$new_root->snv ) * $root->snv + $new_root->snv * ( -$root->nv ); + $child->new_sdv1= ( $new_root->dv + ($m -$n)*$new_root->sdv ) * $root->snv + $new_root->sdv * ( -$root->nv ); + + $child->new_nv= $child->new_nv1 * $child->nv + $child->new_snv1 * $child->dv; + $child->new_dv= $child->new_dv1 * $child->nv + $child->new_sdv1 * $child->dv; + $child->new_snv= $child->new_nv1 * $child->snv + $child->new_snv1 * $child->sdv; + $child->new_sdv= $child->new_dv1 * $child->snv + $child->new_sdv1 * $child->sdv; + db_query('UPDATE {' . $table . '} set nv=:nnv,dv=:ndv,snv=:nsnv,sdv=:nsdv,depth=:depth,pflv=:pflv,flv=:flv + WHERE nv = :nv AND dv = :dv AND vid= :vid', + array(':nv'=>$child->nv, + ':dv'=>$child->dv, + ':vid'=>$vid, + ':nnv'=>$child->new_nv, + ':ndv'=>$child->new_dv, + ':nsnv'=>$child->new_snv, + ':nsdv'=>$child->new_sdv, + ':depth'=>$new_root->depth+2, + ':pflv'=>$pflv, + ':flv'=>bcdiv($child->new_nv,$child->new_dv) + ) ); + + } + +} + +/** + * get the parents of a term + * @param $nv + * numerator value of the term + * @param $dv + * denominator value of the term + * @param $vid + * vid value of the term + * @param $table + * database table to use + */ + +function tree_parents_get($nv,$dv,$vid,$table='term_hierarchy'){ + // first take nv / dv of the flv + // calculate all the parent of the term + $ancnv = 0; + $ancdv = 1; + $ancsnv = 1; + $ancsdv = 0; + $numerator = $nv; + $denominator = $dv; + $parents = array(); + while ($numerator>0 && $denominator>0){ + $div=(int)($numerator / $denominator); + $mod = $numerator % $denominator; + $ancnv = $ancnv + $div * $ancsnv; + $ancdv = $ancdv + $div * $ancsdv; + $ancsnv = $ancnv + $ancsnv; + $ancsdv = $ancdv + $ancsdv; + // grab the parent + $parents[] = db_query('SELECT * FROM {' . $table . '} WHERE nv=:nv AND dv= :dv AND vid=:vid ',array(':nv'=>$ancnv,':dv'=> $ancdv,':vid'=>$vid))->fetchObject(); + $numerator = $mod; + if($numerator>0){ + $denominator = $denominator - $mod; + if ($denominator==0){ + $denominator==1; + } + } + } + return $parents; +} + +/** + * get the first level childrens of a term + * @param $nv + * numerator value of the term + * @param $dv + * denominator value of the term + * @param $vid + * vid value of the term + * @param $table + * database table to use + */ + +function tree_children_get($nv,$dv, $vid ,$table='term_hierarchy'){ + #first find nv and dv for the first child + if($dv==1){ + $flv=0; + }else{ + $flv=$nv.'-'.$dv; + } + $result = db_query('SELECT * FROM {' . $table . '} WHERE vid = :vid AND pflv = :flv ORDER BY nv ', array(':vid'=>$vid,':flv'=>$flv) ); + $children = array(); + while ($parent = db_fetch_object($result)) { + $children[]=$parent; + } + return $children; + +} +?>