Source for file DBMS_TREE.phpclass

Documentation is available at DBMS_TREE.phpclass

  1. <?php
  2. /**
  3.   * Class file dbms_treenode.phpclass
  4.   *
  5.   * @project    Open CSP-Management
  6.   * @package    dbms
  7.   *
  8.   * @author     Peter Krebs (pk) <pitlinz@users.sourceforge.net >
  9.   * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  10.   *
  11.   * @version $Id: DBMS_TREE.phpclass,v 1.9 2008/06/17 07:45:34 pitlinz Exp $
  12.   */
  13.  
  14. define('OCSP_TREETYPE_TABLE',0);
  15. define('OCSP_TREETYPE_LIST',1);
  16.  
  17. pcf_require_class('DBMS_TREE_NODE',dirname(__FILE__)."/DBMS_TREE_NODE.phpclass");
  18. pcf_require_class('DBMS_TABLEOBJ',dirname(__FILE__)."/DBMS_TABLEOBJ.phpclass");
  19.  
  20. /**
  21.   * ABSTRACT class DBMS_TREE to handel table tree data in an object
  22.   *
  23.   * @project    Open CSP-Management
  24.   * @package    dbms
  25.   *
  26.   * @author     Peter Krebs (pk) <pitlinz@users.sourceforge.net>
  27.   * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  28.   *
  29.   * @version pk-03-10-25
  30.   * @version pk-07-06-15 added parent class DBMS_TABLEOBJ to have some common db methods
  31.   * @version $Id: DBMS_TREE.phpclass,v 1.9 2008/06/17 07:45:34 pitlinz Exp $
  32.   * 
  33.   */
  34. class DBMS_TREE extends DBMS_TABLEOBJ {
  35.     /**
  36.       * @staticvar  string  $myIdFld        NOT FINAL name column which is the parent column
  37.       *                                      in childrows
  38.       ***/
  39.     protected $myIdFld        ="";
  40.  
  41.     /**
  42.       * @staticvar  string  $myParentFld    NOT FINAL name of the parent column
  43.       ***/
  44.     protected $myParentFld    ="";
  45.  
  46.     /**
  47.       * @staticvar  string  $mySortFld      NOT FINAL name of the sort field
  48.       ***/
  49.     protected $mySortFld      ="";
  50.  
  51.  
  52.     /**
  53.       * @var  string  $myGlobalTreeKey      index in $OCSP_VAL['DBMS_TREE'][]
  54.       ***/
  55.     protected $myGlobalTreeKey = "";
  56.  
  57.     /**
  58.       * @var  int     $myRootId             index of the root element (is not loaded)
  59.       ***/
  60.     protected $myRootId        = 0;
  61.  
  62.     /**
  63.       * @var  string  $myChildClass   NOT FINAL name of the class children should have
  64.       *                                      it is used in eval("new ".$myChildClass."()")
  65.       ***/
  66.     protected $myChildClass = "DBMS_TREE_NODE";
  67.  
  68.     /**
  69.       * @var string $childClassColumn name of the column holding the class name of children
  70.       * @since pk-06-07-26
  71.       ***/
  72.     protected $childClassColumn="";
  73.  
  74.     /**
  75.       * @var  string  $myChildKeys    NOT FINAL comma sperated list of keys the children
  76.       *                                      have to fit to
  77.       ***/
  78.     protected $myChildKeys    ="";
  79.  
  80.     /**
  81.       * @var array $myChildren array starts at 1 !! key=sortorder
  82.       ***/
  83.     protected $myChildren=array();
  84.  
  85.     /**
  86.       * @var doubl $myChildrenPopulateTS time() when childrens have been populated
  87.       ***/
  88.     protected $myChildrenPopulateTS=0;
  89.  
  90.     /**
  91.       * @var string $myLink                 link the entry
  92.       ***/
  93.     protected $myLink="";
  94.  
  95.     /**
  96.       * @var array $myFilterArr 
  97.       ***/
  98.     protected $myFilterArr    = NULL;
  99.  
  100.  
  101.  
  102.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  103.     // constructors
  104.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105.  
  106.     /**
  107.       * @param string $aGlobalTreeKey 
  108.       * @param boolean $debug 
  109.       *
  110.       * @access public
  111.       * @since pk-07-06-19
  112.       */
  113.     function DBMS_TREE($aGlobalTreeKey="",$debug=FALSE)
  114.     {
  115.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::DBMS_TREE($aGlobalTreeKey)");
  116.  
  117.         if (!empty($aGlobalTreeKey))
  118.         {
  119.             $this->setGlobalTreeKey($aGlobalTreeKey);
  120.         else if (!empty($this->myTable)) {
  121.             $this->setGlobalTreeKey($this->myTable);
  122.         else {
  123.             $this->getGlobalTreeKey($debug);
  124.         }
  125.  
  126.     }
  127.  
  128.  
  129.     // #############################################################
  130.  
  131.  
  132.     /**
  133.       * returns the GlobalTreeKey
  134.       *
  135.       * @param boolean $debug 
  136.       *
  137.       * @global $OCSP_OBJ 
  138.       * @global $OCSP_VAL 
  139.       *
  140.       * @return string 
  141.       *
  142.       * @version pk-06-07-26 generate a tree key if none exists
  143.       ***/
  144.     function getGlobalTreeKey($debug=FALSE{
  145.         global $OCSP_OBJ,$OCSP_VAL;
  146.  
  147.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getGlobalTreeKey()");
  148.         if (empty($this->myGlobalTreeKey)) {
  149.             $s_treeKey=(empty($this->myTableget_class($this$this->myTable);
  150.             $i_count=0;
  151.             $s_testKey=$s_treeKey;
  152.             while(isset($OCSP_VAL['DBMS_TREE'][$s_testKey])) {
  153.                 $s_testKey=$s_treeKey."_".($i_count++);
  154.             }
  155.             if ($debugechoDebug(__FILE__,"<blockquote style=\"font-size:80%\">NEW TreeKey: ".$s_testKey."</blockquote>");
  156.             $this->myGlobalTreeKey=$s_testKey;
  157.         }
  158.         if (!isset($OCSP_OBJ['DBMS_TREE'][$this->myGlobalTreeKey]))
  159.         {
  160.             $OCSP_OBJ['DBMS_TREE'][$this->myGlobalTreeKey]=&$this;
  161.         }
  162.         if (!isset($OCSP_VAL['DBMS_TREE'][$this->myGlobalTreeKey]))
  163.         {
  164.             $OCSP_VAL['DBMS_TREE'][$this->myGlobalTreeKey]=array()// init the cache
  165.         }
  166.         return $this->myGlobalTreeKey;
  167.     }
  168.  
  169.     /**
  170.       * sets the GlobalTreeKey
  171.       *
  172.       * @param string 
  173.       *
  174.       * @global $OCSP_OBJ 
  175.       * @global $OCSP_VAL 
  176.       *
  177.       ***/
  178.     function setGlobalTreeKey($aKey{
  179.         global $OCSP_OBJ,$OCSP_VAL;
  180.         if (!empty($aKey)) {
  181.             $this->myGlobalTreeKey=$aKey;
  182.             $OCSP_OBJ['DBMS_TREE'][$aKey]=&$this;
  183.             if (!isset($OCSP_VAL['DBMS_TREE'][$this->myGlobalTreeKey]))
  184.             {
  185.                 $OCSP_VAL['DBMS_TREE'][$this->myGlobalTreeKey]=array()// init the cache
  186.             }
  187.         }
  188.     }
  189.  
  190.     /**
  191.       * returns the tree root id
  192.       *
  193.       * @returns int
  194.       ***/
  195.     function getRootId({
  196.         return intval($this->myRootId);
  197.     }
  198.  
  199.     /**
  200.       * sets the tree root id
  201.       *
  202.       * @param int $aId 
  203.       *
  204.       ***/
  205.     function setRootId($aId{
  206.         $this->myRootId=intval($aId);
  207.     }
  208.  
  209.     /**
  210.       * sets a child key
  211.       *
  212.       * @param string   $kName 
  213.       * @param mixed    $kValue 
  214.       *
  215.       ***/
  216.     function setKey($kName,$kValue{
  217.         $this->{kName}=$kValue;
  218.     }
  219.  
  220.     /**
  221.       * gets a child key
  222.       *
  223.       * @param string   $kName 
  224.       *
  225.       * @returns mixed
  226.       *
  227.       ***/
  228.     function getKey($kName{
  229.         return $this->$kName;
  230.     }
  231.  
  232.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  233.     // key tree methods
  234.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  235.  
  236.  
  237.     /**
  238.       * returns the key tree [PARENT][ID]=>array()
  239.       *
  240.       * @return array 
  241.       * @access public
  242.       * @since pk-07-06-15
  243.       */
  244.     function getKeyTree()
  245.     {
  246.         global $OCSP_VAL;
  247.         if (!isset($OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['KEYS']|| !($this->isPopulated()))
  248.         {
  249.             $this->populateTree(FALSE);
  250.         }
  251.         return $OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['KEYS'];
  252.     }
  253.  
  254.  
  255.     /**
  256.       * sets the key tree
  257.       *
  258.       * @param array $treeArr 
  259.       * @access public
  260.       * @since pk-07-06-15
  261.       */
  262.     function setKeyTree($treeArr)
  263.     {
  264.         global $OCSP_VAL;
  265.         $OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['KEYS']=$treeArr;
  266.     }
  267.  
  268.     /**
  269.       * returns a node in the key tree
  270.       * to store more information to the keytree overwrite this in
  271.       *
  272.       * @param array $dbRow 
  273.       * @param boolean $debug 
  274.       *
  275.       * @return array 
  276.       * @access protected
  277.       * @since pk-07-06-16
  278.       */
  279.     function getKeyTreeNode($dbRow,$debug=FALSE)
  280.     {
  281.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getKeyTreeNode()");
  282.         return array('ID' => $arr_row[$this->myIdFld]);
  283.     }
  284.  
  285.     /**
  286.       * returns a pointers to the global tree array
  287.       *
  288.       * @param bool $debug 
  289.       *
  290.       * @returns ptr
  291.       *
  292.       * @since pk-04-07-23
  293.       ***/
  294.     function &getTreeArray({
  295.         global $OCSP_VAL;
  296.         return $OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['NODES'];
  297.     }
  298.  
  299.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  300.     // filter methods
  301.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  302.  
  303.     /**
  304.       * clears the filter
  305.       *
  306.       * @since pk-05-01-06
  307.       *
  308.       ***/
  309.     function filterClear({
  310.         $this->myFilterArr=NULL;
  311.     }
  312.  
  313.     /**
  314.       * adds a key value pair to $myFilterArr
  315.       *
  316.       * @param string $key 
  317.       * @param mixed $val 
  318.       * @param bool $debug 
  319.       *
  320.       * @since pk-05-01-06
  321.       *
  322.       ***/
  323.     function filterAdd($key,$val,$debug=FALSE{
  324.         if ($debugecho "<p><b>DBMS_TREE_NODE::filterAdd($key,$val,...)</b> (".get_class($this).")</p>";
  325.  
  326.         if (!is_array($this->myFilterArr)) {
  327.             $this->myFilterArr=array();
  328.         }
  329.         $this->myFilterArr[$key]=$val;
  330.  
  331.         if ($debugecho "<blockquote><pre>".print_r($this->myFilterArr,TRUE)."</pre></blockquote>";
  332.     }
  333.  
  334.     /**
  335.       * removes a key form the filter
  336.       *
  337.       * @param string $key 
  338.       * @param bool $debug 
  339.       *
  340.       * @since pk-05-01-06
  341.       *
  342.       ***/
  343.     function filterRemoveKey($key,$debug{
  344.         if ($debugecho "<p><b>DBMS_TREE_NODE::filterRemoveKey($key,...)</b> (".get_class($this).")</p>";
  345.  
  346.         unset($this->myFilterArr[$key]);
  347.         if (is_array($this->myFilterArr&& (!sizeof($this->myFilterArr))) {
  348.             $this->myFilterArr=NULL;
  349.         }
  350.         if ($debugecho "<blockquote><pre>".print_r($this->myFilterArr,TRUE)."</pre></blockquote>";
  351.     }
  352.  
  353.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  354.     // child methods
  355.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  356.  
  357.  
  358.     /**
  359.       * sets child class vars
  360.       *
  361.       * @param &DBMS_TREE_NODE $child 
  362.       * @param boolean $debug 
  363.       * 
  364.       */
  365.     function setChildClassVar(&$child,$debug=False{
  366.         $child->setDBObj($this->getDBObj);
  367.         $child->setTreeObj($this);
  368.  
  369.         $confArr=array();
  370.         if (!empty($this->myTable)) $confArr['myTable']=$this->myTable;
  371.         if (!empty($this->myIdFld)) $confArr['myIdFld']=$this->myIdFld;
  372.         if (!empty($this->myParentFld)) $confArr['myParentFld']=$this->myParentFld;
  373.         if (!empty($this->mySortFld)) $confArr['mySortFld']=$this->mySortFld;
  374.         if (!empty($this->myChildClass)) $confArr['myChildClass']=$this->myChildClass;
  375.         if (!empty($this->myChildKeys)) $confArr['myChildKeys']=$this->myChildKeys;
  376.         if (!empty($this->myFilterArr)) $confArr['myFilterArr']=$this->myFilterArr;
  377.  
  378.         $child->setConfigurationArr($confArr,$debug);
  379.     }
  380.  
  381.     /**
  382.       * opens a course to fetch node objects under the root (1st level)
  383.       *
  384.       * @param boolean $debug 
  385.       *
  386.       * @return DB_CURSOR 
  387.       *
  388.       * @since pk-06-07-27
  389.       *
  390.       */
  391.     function &getChildrenCursor($filtered=False,$debug=False{
  392.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getChildCursor()",($filtered "<b>FILTERED</b>" ""));
  393.  
  394.         if (!$this->isConnected(TRUE,$debug))
  395.         {
  396.             ocsp_logError(__FILE__,__LINE__,"No Database Connection in ".get_class($this));
  397.             return NULL;
  398.         }
  399.  
  400.         $s_query ="SELECT * FROM ".$this->myTable;
  401.         $s_query.=" WHERE ".$this->myParentFld."=".$this->getRootId();        // IDs are integer COLUMNS and VALUES
  402.  
  403.         if ((!empty($this->myChildKeys)) && ($keyCols=explode(",",$this->myChildKeys))) {
  404.             foreach($keyCols as $col{
  405.                 $s_query.=" AND ".$col." = ".$this->myDBObj->qs_getSlashedValue($this->getKey($col));
  406.             }
  407.         }
  408.  
  409.         if ($filtered && (is_array($this->myFilterArr))) {
  410.             foreach($this->myFilterArr as $s_Col => $s_Val{
  411.                 $s_query.=" AND ".$s_Col."=".$this->myDBObj->qs_getSlashedValue($s_Val);
  412.             }
  413.         }
  414.  
  415.         if (!empty($this->mySortFld)) {
  416.             $s_query.=" ORDER BY ".$this->mySortFld;
  417.         }
  418.  
  419.         if ($debugechoDebugLine(__FILE__,__LINE__,"child query$s_query");
  420.  
  421.         $obj_ret $this->myDBObj->query($s_query);
  422.         return $obj_ret;
  423.     }
  424.  
  425.  
  426.     /**
  427.       * populates the children of the tree (1st level nodes)
  428.       *
  429.       * @param  bool    $useCache 
  430.       * @param  bool    $debug 
  431.       *
  432.       * @return boolean 
  433.       *
  434.       * @version pk-05-07-27
  435.       * @version pk-06-07-26
  436.       *
  437.       ***/
  438.     function populate($useCache=TRUE,$debug=FALSE,$filtered=FALSE{
  439.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::populate()","\$useCache=".($useCache "TRUE" "FALSE"));
  440.  
  441.         if($o_cursor=$this->getChildrenCursor($filtered,$debug)) {
  442.             $i_noChildren=0;
  443.             $this->myChildren=array();
  444.  
  445.             while($a_row=$o_cursor->fetchArrayFld()) {
  446.                 $aId=$a_row[$this->myIdFld];
  447.                 if ($useCache && ($ptr_tmpObj=$this->getNodeObjectFromCache($aId))) {
  448.                     $ptr_tmpObj->setOrderNr(++$i_noChildren);
  449.                     $this->myChildren[$i_noChildren]=$aId;
  450.                 else if ($ptr_tmpObj=$this->newNodeObject($aId,$a_row,$debug)) {
  451.                     $ptr_tmpObj->setOrderNr(++$i_noChildren);
  452.                     $this->myChildren[$i_noChildren]=$aId;
  453.                 }
  454.             }
  455.             $this->myChildrenPopulateTS=time();
  456.             return TRUE;
  457.         else {
  458.             return FALSE;
  459.         }
  460.     }
  461.  
  462.  
  463.  
  464.  
  465.     /**
  466.       * populates the hole tree structure
  467.       *
  468.       * @param bool $useCache 
  469.       * @param bool $keysOnly 
  470.       * @param string $where (a full SQL where condition exampl: "WHERE PROJ_ID=1 OR PROJ_ID=0")
  471.       * @param bool $debug 
  472.       *
  473.       * @global array $OCSP_VAL 
  474.       *
  475.       * @return boolean 
  476.       *
  477.       * @version pk-07-06-15
  478.       *
  479.       ***/
  480.     function populateTree($useCache=TRUE,$keysOnly=TRUE,$where="",$debug=FALSE)
  481.     {
  482.         global $OCSP_VAL;
  483.  
  484.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DMBS_TREE::populateTree()");
  485.  
  486.         $arr_cache=&$OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()];
  487.  
  488.         if (!$useCache || !$this->isPopulated(|| !is_array($arr_cache['KEYS']))
  489.         {
  490.             // generate the key tree
  491.             $str_query ="SELECT * FROM ".$this->myTable;
  492.             $str_query.=$where;
  493.             $str_query.=" ORDER BY ".$this->myParentFld;
  494.             if (!empty($this->mySortFld)) {
  495.                 $str_query.=",".$this->mySortFld;
  496.             }
  497.  
  498.             if (!$this->isConnected(TRUE,$debug)) {
  499.                 ocsp_logError(__FILE__,__LINE__,"no database connection in tree: ".get_class($this));
  500.                 return FALSE;
  501.             }
  502.  
  503.             $arr_cache['KEYS']=array();
  504.  
  505.             if ($debugechoDebugLine(__FILE__,__LINE__,"Loading tree from database with: <br />".$str_query);
  506.             if ($o_cursor=$this->myDBObj->query($str_query))
  507.             {
  508.                 while($arr_row=$o_cursor->fetchArrayFld())
  509.                 {
  510.                     $arr_cache['KEYS'][$arr_row[$this->myParentFld]][$arr_row[$this->myIdFld]]=$this->getKeyTreeNode($arr_row);
  511.                     if (!$keysOnly$this->newNodeObject($arr_row[$this->myIdFld],$arr_row,$debug);
  512.                 }
  513.             }
  514.             if ($debugechoDebugLine(__FILE__,__LINE__,"KeyTree: <pre>".print_r($arr_cache['KEYS'],TRUE)."</pre>");
  515.             $this->populateTS=time();
  516.             return TRUE;
  517.         else {
  518.             if (!$keysOnly)
  519.             {
  520.                 $arr_toPopulate=array()// array of nodes which are to populate
  521.                 foreach($arr_cache['KEYS'as $idVal => $arr_vals)
  522.                 {
  523.                     if (!is_object($arr_cache['NODES']))
  524.                     {
  525.                         $arr_toPopulate[]=$idVal;
  526.                     }
  527.                     if (!sizeof($arr_toPopulate))
  528.                     {
  529.                         if ($debugechoDebugLine(__FILE__,__LINE__,"All nodes are already populated");
  530.                         return TRUE;
  531.                     }
  532.  
  533.                     if (!$this->isConnected(TRUE,$debug)) {
  534.                         ocsp_logError(__FILE__,__LINE__,"no database connection in tree: ".get_class($this));
  535.                         return FALSE;
  536.                     }
  537.  
  538.                     $str_query =$str_query ="SELECT * FROM ".$this->myTable;
  539.                     $str_query.="WHERE ".$this->myDBObj->qs_getWhereIn($this->myIdFld,$arr_toPopulate,FALSE);
  540.  
  541.                     if ($debugechoDebugLine(__FILE__,__LINE__,"Loading missing tree nodes from database with: <br />".$str_query);
  542.                     if ($o_cursor=$this->myDBObj->query($str_query))
  543.                     {
  544.                         while($arr_row=$o_cursor->fetchArrayFld())
  545.                         {
  546.                             newNodeObject($arr_row[$this->myIdFld],$arr_row,$debug);
  547.                         }
  548.                     }
  549.                 }
  550.             }
  551.             return TRUE;
  552.         }
  553.     }
  554.  
  555.     /**
  556.       * selects a node row from the database and returns the
  557.       * DB Values as array with quickQuery to the database object
  558.       *
  559.       * @param int $aId 
  560.       * @param boolean $debug 
  561.       *
  562.       * @returns array
  563.       *
  564.       * @since pk-06-07-26
  565.       *
  566.       ***/
  567.     function getNodeDBRowFromDB($aId,$debug=FALSE{
  568.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getNodeDBRowFromDB()","\$aId (".$this->myIdFld.")=$aId");
  569.  
  570.         if ($debugecho "<blockquote style=\"font-size: 80%;backgroud-color: #A0A0A0\">";
  571.         if (!$this->isConnected(TRUE,$debug))
  572.         {
  573.             ocsp_logError(__FILE__,__LINE__,"No Database Connection in ".get_class($this));
  574.             if ($debugecho "</blockquote>";
  575.             return NULL;
  576.         }
  577.  
  578.         $s_query ="SELECT * FROM ".$this->myTable;
  579.         $s_query.=" WHERE ".$this->myIdFld."=".intval($aId);        // IDs are integer COLUMNS and VALUES
  580.  
  581.         if ((!empty($this->myChildKeys)) && ($keyCols=explode(",",$this->myChildKeys))) {
  582.             foreach($keyCols as $col{
  583.                 if ($debugechoDebugLine(__FILE__,__LINE__,"adding childkey $col".$this->{$col});
  584.                 $s_query.=" AND ".$col." = ".$this->myDBObj->qs_getSlashedValue($this->{$col});
  585.             }
  586.         }
  587.  
  588.         if ($debug{echoDebugLine(__FILE__,__LINE__,"$s_query");echo "</blockquote>";}
  589.         return $this->myDBObj->quickQuery($s_query,-1,$debug,TRUE);
  590.     }
  591.  
  592.     /**
  593.       * populates a child node
  594.       * if $useCache the cache is checked if the node already exists
  595.       * if !$useCache the node is laoded from the db and the cache object is replaced
  596.       *
  597.       * @param  int     $aId 
  598.       * @param  bool    $useCache 
  599.       * @param  bool    $debug 
  600.       *
  601.       * @return DBMS_TREE_NODE 
  602.       *
  603.       * @version pk-06-06-20
  604.       * @version pk-06-08-08 bugfix
  605.       ***/
  606.     function &populateNode($aId,$useCache=TRUE,$debug=FALSE{
  607.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::populateNode()","\$aId=$aId,\$useCache=".($useCache "TRUE" "FALSE"));
  608.  
  609.         if ($aId==$this->getRootId()) {
  610.             if ($debugechoDebug(__FILE__,"<p>Root ID =&gt; NULL returned</p>");
  611.             $this->populate($useCache,$debug)// <pk-06-06-20>
  612.             return NULL;
  613.         }
  614.  
  615.         if ($useCache && ($obj_Node=$this->getNodeObjectFromCache($aId,$debug))) {
  616.             if ($debugechoDebug(__FILE__,"<p>returning cached object</p>");
  617.             return $obj_Node;
  618.         }
  619.  
  620.         if ($a_row $this->getNodeDBRowFromDB($aId,$debug)) // <pk-06-08-08 />
  621.             if (!$useCache && ($o_tmpObj=$this->getNodeObjectFromCache($aId,$debug))) {
  622.                 // overwrite existing object
  623.                 if (!pcf_is_instance_of($o_tmpObj,$this->myChildClass)) {
  624.                     pcf_castObject($o_tmpObj,$this->myChildClass,$debug);
  625.                 }
  626.                 $o_tmpObj->setDBRow($a_row,TRUE,$debug);
  627.                 $o_tmpObj->setId($aId);
  628.             else {
  629.                 $o_tmpObj=$this->newNodeObject($aId,$a_row,$debug);
  630.             }
  631.  
  632.             //$o_tmpObj->setOrderNr($noc);
  633.             $this->addNodeObjectToCache($aId,$o_tmpObj,$debug);
  634.             return $o_tmpObj;
  635.         }
  636.         if ($debugecho "<p>NO NODE FOUND </p></blockquote>";
  637.         return NULL;
  638.     }
  639.  
  640.  
  641.     /**
  642.       * generates a new child object and add it to the cache
  643.       *
  644.       * @param int $aId the (cache) id of the object
  645.       * @param string $aClassName if !empty $this-myChildClass is overwriten if class exists
  646.       * @param boolean $debug 
  647.       *
  648.       * @return DBMS_TREE_NODE 
  649.       *
  650.       * @since pk-06-07-26
  651.       * @version pk-07-06-19
  652.       *
  653.       ***/
  654.     function &newNodeObject($aId,$dataArr=NULL,$debug=FALSE{
  655.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::newNodeObject()","\$aId (".$this->myIdFld.")=$aId\n");
  656.  
  657.         if (!empty($this->myChildClass&& class_exists($this->myChildClass)) {
  658.             $s_className=$this->myChildClass;
  659.         else {
  660.             if ($debugechoDebug(__FILE__,"<p>Class: ".$this->myChildClass." NOT FOUND</p>");
  661.             $s_className='DBMS_TREE_NODE';
  662.         }
  663.  
  664.         $s_cmd="\$o_nodeObj=new ".$s_className."();";
  665.         if ($debugechoDebugLine(__FILE__,__LINE__,"Object cmd: ".$s_cmd);
  666.         eval($s_cmd);
  667.  
  668.         if (!is_object($o_nodeObj))
  669.         {
  670.             ocsp_logError(__FILE__,__LINE__,"could not eval node command for node ID$aId in class".get_class($this));
  671.             return $o_nodeObj;
  672.         }
  673.  
  674.         $this->setChildClassVar($o_nodeObj,$debug);
  675.         if (is_array($dataArr)) {
  676.             $o_nodeObj->setDBVal($dataArr);
  677.         }
  678.  
  679.         $this->addNodeObjectToCache($aId,$o_nodeObj,$debug);
  680.         return $o_nodeObj;
  681.     }
  682.  
  683.  
  684.  
  685.     /**
  686.       * get a node if the
  687.       *
  688.       * @param int  $aId 
  689.       * @param bool $debug 
  690.       *
  691.       * @return DBMS_TREE_NODE 
  692.       *
  693.       * @version pk-06-06-20
  694.       * @version pk-07-06-16 use global array
  695.       *
  696.       ***/
  697.     function &getNode($aId,$debug=FALSE{
  698.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getNode($aId)");
  699.  
  700.         if ($obj_Node=$this->getNodeObjectFromCache($aId,$debug))
  701.         {
  702.             return $obj_Node;
  703.         }
  704.  
  705.         if ($obj_Node=$this->populateNode($aId,TRUE,$debug)) {
  706.             return $obj_Node;
  707.         else {
  708.             if ($debugechoDebugLine(__FILE__,__LINE__,"DBMS_TREE::getNode -> returning NULL");
  709.             $obj_Node=NULL;
  710.             return $obj_Node;
  711.         }
  712.     }
  713.  
  714.     // --------------------------------------------------------------------------------------
  715.     // cache methods
  716.     // --------------------------------------------------------------------------------------
  717.  
  718.     /**
  719.       * adds a node to the cache
  720.       *
  721.       * @param int $aId 
  722.       * @param DBMS_TREE_NODE:: &$aNode 
  723.       *
  724.       * @global array $OCSP_VAL 
  725.       *
  726.       * @since pk-06-07-26
  727.       *
  728.       ***/
  729.     function addNodeObjectToCache($aId,&$aNode,$debug=FALSE{
  730.         global $OCSP_VAL;
  731.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::addNodeObjectToCache($aId)",print_r($aNode->getDBVal(),TRUE));
  732.  
  733.         $arr_tree=&$OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()];
  734.         $arr_tree['NODES'][$aId]=$aNode;
  735.  
  736.         $i_parentId=intval($aNode->getParentId());
  737.         if (!isset($arr_tree['KEYS'][$i_parentId][$aNode->getId()]))
  738.         {
  739.             $arr_tree['KEYS'][$i_parentId][$aNode->getId()]=$this->getKeyTreeNode($aNode->getDBRow());
  740.         }
  741.     }
  742.  
  743.     /**
  744.       * returns a pointer to a cached node object
  745.       * or NULL if the object is not in the cache
  746.       *
  747.       * @param int $aId 
  748.       * @param boolean $debug 
  749.       *
  750.       * @global array $OCSP_VAL 
  751.       *
  752.       * @returns DBMS_TREE_NODE
  753.       *
  754.       * @since pk-06-07-26
  755.       *
  756.       ***/
  757.     function &getNodeObjectFromCache($aId,$debug=FALSE{
  758.         global $OCSP_VAL;
  759.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getNodeObjectFromCache($aId)","TreeKey: ".$this->getGlobalTreeKey());
  760.  
  761.         $null_ret=NULL;
  762.         if (!isset($OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['NODES'][$aId])) {
  763.             if ($debugechoDebugLine(__FILE__,__LINE__,"returns NULL due to not set in \$OCSP_VAL['DBMS_TREE'][".$this->getGlobalTreeKey()."]['NODES']");
  764.             return $null_ret;
  765.         }
  766.         if (pcf_is_instance_of($OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['NODES'][$aId],'DBMS_TREE_NODE')) {
  767.             return $OCSP_VAL['DBMS_TREE'][$this->getGlobalTreeKey()]['NODES'][$aId];
  768.         }
  769.  
  770.         if ($debugechoDebugLine(__FILE__,__LINE__,"<b>WARNING:</b> returns NULL");
  771.         return $null_ret;
  772.     }
  773.  
  774.  
  775.     // #######################################################
  776.  
  777.     /**
  778.       * returns an array of pointers to the elements till root with all
  779.       *
  780.       * in case of an error false is return (use '===' type equal )
  781.       *
  782.       * @param mixed $aNode (DMBS_TREE_NODE) a node object or (int) a node id
  783.       * @param bool $useCache 
  784.       * @param bool $debug 
  785.       *
  786.       * @returns array  array of pointers to nodes key=DBMS_TREE_NODE::getId()
  787.       *
  788.       * @version pk-05-07-25
  789.       * @version pk-06-07-26 call the node method getRootPath()
  790.       * @version pk-07-08-15 changed type of $aNode
  791.       *
  792.       ***/
  793.     function getRootPath($aNode,$useCache=TRUE,$debug=FALSE{
  794.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getRootPath()","NODE$aNode");
  795.  
  796.         if ($debugecho "<blockquote style=\"backgroud-color: #febf00;font-size:80%\">";
  797.  
  798.         if (pcf_is_instance_of($aNode,'DBMS_TREE_NODE'))
  799.         {
  800.             if ($debugecho "</blockquote>";
  801.             return $aNode->getRootPath($useCache,$debug);
  802.         }
  803.  
  804.         if (empty($aNode)) return array();
  805.         if ($o_node=$this->getNode($aNode,$debug))
  806.         {
  807.             if ($debugecho "</blockquote>";
  808.             return $o_node->getRootPath($useCache,$debug);
  809.         }
  810.         ocsp_logError(__FILE__,__LINE__,"$aNode is not in the tree",E_WARNING);
  811.         if ($debugecho "</blockquote>";
  812.         return array();
  813.     }
  814.  
  815.     /**
  816.       * returns a array of pointers to the child objects
  817.       *
  818.       * @param bool $debug 
  819.       * @param bool $filtered 
  820.       *
  821.       * @returns array
  822.       *
  823.       * @since pk-04-07-23
  824.       *
  825.       * @version pk-05-01-06
  826.       * @version pk-06-07-27
  827.       *
  828.       */
  829.     function getChildrenList($debug=False,$filtered=False
  830.     {
  831.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getChildrenList()","\$filtered=".($filtered "TRUE" "FALSE"));
  832.  
  833.         if (($this->myChildrenPopulateTS (time(ini_get('max_execution_time'))) || (!sizeof($this->myChildren))) // <pk-06-07-27>
  834.             $this->populate(TRUE,$debug,$filtered);
  835.         }
  836.  
  837.         if ($filteredreturn $this->getFilteredChildrenList($debug);
  838.  
  839.         $ret=array();
  840.         $ndx=0;
  841.         foreach($this->myChildren as $key => $id{
  842.             $ret[$ndx]=$this->getNode($id,$debug);
  843.             // if ($debug) echo "<blockquote><pre>".pcf_object_info($ret[$ndx])."</pre></blockquote>";
  844.             $ndx++;
  845.         }
  846.         return $ret;
  847.     }
  848.  
  849.     /**
  850.       * returns a array of pointers to childs matching $myFilterArr
  851.       *
  852.       * @param bool $debug 
  853.       *
  854.       * @return array 
  855.       *
  856.       * @since pk-05-01-06
  857.       * @version pk-06-07-27
  858.       * @version pk-06-11-13 set $filtered to TRUE when calling populate
  859.       *
  860.       ***/
  861.     function getFilteredChildrenList($debug=FALSE{
  862.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE::getFilteredChildrenList()");
  863.         if (($this->myChildrenPopulateTS (time(ini_get('max_execution_time'))) || (!sizeof($this->myChildren))) // <pk-06-07-27>
  864.             $this->populate(TRUE,$debug,TRUE)// <pk-06-11-13 /> set $filtered to TRUE
  865.         }
  866.  
  867.         $ret=array();
  868.         $ndx=0;
  869.         foreach($this->myChildren as $key => $id{
  870.             // <pk-05-07-26>
  871.             if (is_array($id)) {
  872.                 $treeKey=$id['TREEKEY'];
  873.                 $treeIdx=$id['TREEIDX'];
  874.             else {
  875.                 $treeKey=$this->getGlobalTreeKey();
  876.                 $treeIdx=$id;
  877.             }
  878.             if ($debugecho "<p>$treeKey => $treeIdx</p>";
  879.  
  880.             if (is_object($GLOBALS['DBMS_TREE'][$treeKey][$treeIdx])) {
  881.                 if ($GLOBALS['DBMS_TREE'][$treeKey][$treeIdx]->matchFilter($debug)) {
  882.                     $ret[$ndx++]=&$GLOBALS['DBMS_TREE'][$treeKey][$treeIdx];
  883.                 }
  884.             }
  885.  
  886.             // </pk-05-07-26>
  887.         }
  888.  
  889.         return $ret;
  890.     }
  891.  
  892.  
  893.  
  894.  
  895.     /**
  896.       * returns an array sorted as tree
  897.       * the index is like [1] [1.1] [1.2] [2] [2.1] ....
  898.       * the value is an array with following fields:
  899.       *     INDEX   (same as index)
  900.       *     INTEND
  901.       *     NODE    pointer to the node
  902.       *     NODEID
  903.       *     [NODENAME] if $nameField is set
  904.       *
  905.       *
  906.       * @param DBMS_TREE_NODE $startNode 
  907.       * @param string $startIdx 
  908.       * @param string $startIntend 
  909.       * @param string $intendStr 
  910.       * @param string $nameField 
  911.       * @param boolean $debug 
  912.       *
  913.       * @returns array
  914.       *
  915.       * @since pk-04-08-12
  916.       *
  917.       * @version pk-06-08-09 return array() instead of FALSE
  918.       *
  919.       ***/
  920.     function getIndexedTreeArr($startNode=NULL,$startIdx="",$startIntend="",$intendStr="&nbsp;&nbsp;",$nameField="",$debug=FALSE{
  921.         if ($debugecho "<p><b>DBMS_TREE::getIndexedTreeArr(\$startNode,".htmlspecialchars($startIdx).",".htmlspecialchars($startIntend).",".htmlspecialchars($intendStr)."...)</b> (".get_class($this).")</p>";
  922.         if (!pcf_is_instance_of($startNode,"DBMS_TREE_NODE")) {
  923.             $childArr=$this->getChildrenList();
  924.         else {
  925.             $childArr=$startNode->getChildrenList(TRUE,$debug);
  926.         }
  927.  
  928.         if ($debug{
  929.             echo "<blockquote>\$childArr:<pre>".pcf_print_r($childArr,TRUE,2)."</pre></blockquote>";
  930.         }
  931.  
  932.         $ret=array();$count=1;
  933.         if (is_array($childArr)) {
  934.             foreach($childArr as $node{
  935.                 $key=$startIdx.$count++;
  936.                 $ret[$key]=array(
  937.                     "INDEX"     => $key,
  938.                     "INTEND"    => $startIntend,
  939.                     "NODE"      => $node,
  940.                     "NODEID"    => $node->{$this->myIdFld}
  941.                 );
  942.                 if (!empty($nameField)) {
  943.                     $ret[$key]['NODENAME']=$node->{$nameField};
  944.                 }
  945.  
  946.                 if ($cArr=$this->getIndexedTreeArr($node,$key.".",$startIntend.$intendStr,$intendStr,$nameField,$debug)) {
  947.                     foreach($cArr as $cKey => $cVal{
  948.                         $ret[$cKey]=$cVal;
  949.                     }
  950.                 }
  951.             }
  952.             if ($count 1)
  953.                 return $ret;
  954.             else
  955.                 return array()// <pk-06-08-09 />
  956.         }
  957.         return array()// <pk-06-08-09 />
  958.     }
  959. }
  960. ?>

Documentation generated on Thu, 08 Jan 2009 17:43:57 +0100 by phpDocumentor 1.4.0a2