array(
* "lib" => "",
* "local" => "",
* "bin" => "",
* "hugo" => array(
* "nummer1" => "",
* "nummer2" => "",
* "nummer3" => ""
* ),
* "servuz" => ""
* )
* );
*
* ... and can generate a tree like
*
* /
* --+ usr
* --+ lib
* + local
* + bin
*
*/
class Tree {
var $classname = "Tree";
var $delimiter = "^"; ## Delimiter for path-index
var $tree;
var $prfx=array();
var $sufx=array();
var $outp;
var $flags;
function build_tree () {
## Dis function must be overriden by user!
## Result should fill $this->tree
## Perhaps it is easier to use this function in a recursive manner
## e.g. recursive scanning of directory structure.
##
}
function go_through_tree ($key="",$path="",$depth=0,$lcount=0,$pcount=0) {
STATIC $k,$t,$v,$eval2,$tmp1,$tmp2;
# Remeber: path_to_index: $path is call by value!
$index=$this->path_to_index($path,$key);
#DEB echo "-------------
*PATH: $path $key
";
#DEB echo "*INDEX: $depth $index
";
$eval="\$this->tree${index}";
if ($depth) {
eval("\$v=$eval; \$c=Count($eval);");
$eval2 = $eval . "[0]";
eval("if (isset(${eval2})) \$v=$eval2 ;");
$this->growtree($key,$v,$path,$depth,$lcount,$pcount);
} else {
$this->starttree();
eval("\$c=Count(\$this->tree);");
}
eval("\$t = gettype($eval);");
if ("array"==$t) { ## Just to be sure
$evalnext="list(\$k) = each($eval);";
eval($evalnext); ## First element
$i=1;
while ($k || "0"==$k) {
$eval2= $eval . "[\"". ereg_Replace("\"","\\\"",$k) ."\"]";
eval("\$t=gettype($eval2); \$v=$eval2;");
#DEB echo "
$i: $t - $k -> '$v' - $c
";
if ("0" != $k) {
switch ($t) {
case "array" :
eval("\$tmp1=Count($eval2); \$tmp2=isset(${eval2}[\"0\"]);");
if ($tmp1==1 && $tmp2 ) {
eval("\$v=${eval2}[\"0\"];");
$this->leaftree($k,$v,$this->path_add($path,$k),$depth+1,$c,$i);
} else {
$this->go_through_tree($k,$path,$depth+1,$c,$i);
}
break;
default :
$this->leaftree($k,$v,$this->path_add($path,$k),$depth+1,$c,$i);
break;
}
}
eval($evalnext); # Next element
$i++;
}
}
if ($depth) {
$this->shrinktree($key,$depth);
} else {
$this->endtree();
}
}
##########################################################
## Calculate index
## $key is added to $path (call by reference!!!)
## -> $path is something like "hugo^bla^nana"
## $index is then ["hugo"]["bla"]["nana"]
function path_to_index (&$path,$key="") {
$key=ereg_Replace("\"","\\\"",$key);
if ($path && $key) {
$path.=$this->delimiter . $key;
} else {
$path.=$key;
}
if ($path) {
$index=implode("\"][\"",explode($this->delimiter,$path));
$index = "[\"${index}\"]";
}
return($index);
}
############################################################
## eg. $path is "hugo^bla^wusel" then after call to this function
## $path is "hugo^bla" and it will return '["hugo"]["bla"]'
## if $path is empty it will return false!
##
function path_to_parent (&$path) {
if ($path) {
## calculate parent
$path=substr($path,0,strrpos($path,$this->delimiter));
} else {
return(false);
}
if ($path) {
$index=implode("\"][\"",explode($this->delimiter,$path));
$index = "[\"${index}\"]";
} else {
$index="";
}
return($index);
}
######################################################
## Same as path_to_index and path_to_child but only
## working on path
##
function path_add ($path,$key) {
$key=ereg_Replace("\"","\\\"",$key);
if ($path && $key) {
$path.=$this->delimiter . $key;
} else {
$path.=$key;
}
return($path);
}
function path_sub ($path) {
if ($path) {
## calculate parent
$path=substr($path,0,strrpos($path,$this->delimiter));
} else {
return(false);
}
return($path);
}
function path_index ($path) {
if ($path) {
$index=implode("\"][\"",explode($this->delimiter,$path));
$index = "[\"${index}\"]";
}
return($index);
}
###################################################
# These functions are all user definable
# I have made a little example, of how to make a simple
# explorer like output
function starttree () {
#DEB echo "!!! STARTREE
";
$this->outp.= " /
";
$this->flag=true;
}
function growtree ($key,$value,$path,$depth,$count,$pcount) {
#DEB echo ">>> GROWTREE
";
$this->outp.= "" . join($this->prfx,"");
if ($this->flag) {
$this->outp.="^----";
} elseif ($count==$pcount) {
$this->outp.=" \---";
} else {
$this->outp.="O----";
}
$this->outp.= sprintf(" %s->'%s'".
" : '%s' (%s) [%s/%s]
\n",
$key,URLEncode($value),$value,$path,$depth,$pcount,$count);
if ($count > $pcount) {
$this->prfx[$depth]="| ";
} else {
$this->prfx[$depth]=" ";
}
$this->flag=true;
}
function leaftree ($key,$value,$path,$depth,$count,$pcount) {
#DEB echo "--- LEAFTREE
";
$this->outp.= "" . join($this->prfx,"");
if ($this->flag) {
$this->outp.="*----";
} elseif ($count==$pcount) {
$this->outp.=" \---";
} else {
$this->outp.="+----";
}
$this->outp.= sprintf(" %s->'%s'".
" : '%s' (%s) [%s/%s]
\n",
$key,URLEncode($value),$value,$path,$depth,$pcount,$count);
$this->flag=false;
}
function shrinktree ($key,$depth) {
#DEB echo "<<< SHRINKTREE
";
unset($this->prfx[$depth]);
}
function endtree () {
#DEB echo "... ENDTREE
";
}
}