Source for file DBMS_TREE_NODE.phpclass

Documentation is available at DBMS_TREE_NODE.phpclass

  1. <?php
  2. /**
  3.   * Class file DBMS_TABLEOBJ.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.   ***/
  12.  
  13. require_once __OCSP_PHPINCPATH__."common"._OCSP_DIRSEP_."pcf.phpinc";     // <pk-05-07-12 />
  14. require_once dirname(__FILE__)._OCSP_DIRSEP_."DBMS_TREE.phpclass";        // <pk-05-07-12 />
  15. require_once dirname(__FILE__)._OCSP_DIRSEP_."DBMS_TABLEOBJ.phpclass";
  16.  
  17.  
  18. /**
  19.   * ABSTRACT class DBMS_TREE_NODE to handel table tree data in an object
  20.   *
  21.   * the nodes are stored in GLOBAL array
  22.   * $GLOBALS['OCSP_VAL']['DBMS_TREE'][DBMS_TREE_NODE::myGlobalTreeKey][DBMS_TREE_NODE::getId()]
  23.   * to be able to easy cache the hole tree.
  24.   *
  25.   * references to parent or child objects are the index in the global array
  26.   * otherwise some mechanismen would be nessary to not get into loops when
  27.   * serializing the object.
  28.   *
  29.   *
  30.   * @project    Open CSP-Management
  31.   * @package    dbms
  32.   *
  33.   * @author     Peter Krebs (pk) <pitlinz@users.sourceforge.net>
  34.   *
  35.   * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  36.   *
  37.   * @version pk-03-10-25
  38.   * @version pk-05-07-12
  39.   *
  40.   ***/
  41. class DBMS_TREE_NODE EXTENDS DBMS_TABLEOBJ {
  42.  
  43.     /**
  44.       * @staticvar string $myClassSrcFile if is set the DBMS_FORM get the class object
  45.       * @since pk-07-10-14
  46.       ***/
  47.     protected $myClassSrcFile=__FILE__;
  48.  
  49.     /** -----------------------------------------------------
  50.       * Aggregations:
  51.       */
  52.  
  53.  
  54.     /** -----------------------------------------------------
  55.       * Compositions:
  56.       */
  57.  
  58.     /**
  59.       * @var DBMS_TREE $myTree 
  60.       * @since pk-05-07-12
  61.       * @access protected
  62.       ***/
  63.     protected $myTree=NULL;
  64.  
  65.     /**
  66.       * @var DBMS_TREE_NODE $myParent 
  67.       * @since pk-07-08-10
  68.       * @access protected
  69.       */
  70.     protected $myParent=NULL;
  71.  
  72.     /** -----------------------------------------------------
  73.       * Attributes:
  74.       */
  75.  
  76.     /**
  77.       * @staticvar  string  $myIdFld        NOT FINAL name column which is the parent column
  78.       *                                      in childrows
  79.       ***/
  80.     protected $myIdFld        ="";
  81.  
  82.     /**
  83.       * @staticvar  string  $myParentFld    NOT FINAL name of the parent column
  84.       ***/
  85.     protected $myParentFld    ="";
  86.  
  87.     /**
  88.       * @staticvar  string  $mySortFld      NOT FINAL name of the sort field
  89.       ***/
  90.     protected $mySortFld      ="";
  91.  
  92.     /**
  93.       * @staticvar string $myTreeClass 
  94.       * @since pk-05-07-12
  95.       ***/
  96.     protected $myTreeClass="DBMS_TREE";
  97.  
  98.  
  99.     /**
  100.       * @staticvar  string  $myChildClass   NOT FINAL name of the class children should have
  101.       *                                      it is used in eval("new ".$myChildClass."()")
  102.       ***/
  103.     protected $myChildClass = "DBMS_TREE_NODE";
  104.  
  105.     /**
  106.       * @staticvar  strint  $myChildKeys    NOT FINAL comma sperated list of keys the children
  107.       *                                      have to fit to
  108.       ***/
  109.     protected $myChildKeys    ="";
  110.  
  111.     /**
  112.      * array starts at 1 !! key=sortorder
  113.      * @var array $myChildren 
  114.      */
  115.     protected $myChildren = array();
  116.  
  117.  
  118.     /**
  119.       * @staticvar    int         $myChildCacheTTL 
  120.       ***/
  121.     protected $myChildCacheTTL    =  86400;    // 1 day
  122.  
  123.     /**
  124.      * timestamp when the $this->myChildren has been populates
  125.      * @var double $myChildrenPopulateTS 
  126.      */
  127.     protected $myChildrenPopulateTS=0;
  128.  
  129.  
  130.     /**
  131.       * @var    int         $level          level in the tree 0=root 1=children of root ...
  132.       ***/
  133.     protected $level=0;
  134.  
  135.     /**
  136.       * @var int $orderNr the child nr x of parent (SORTORDER !!)
  137.       *  take care the childs are ordered proper when using this
  138.       ***/
  139.     protected $orderNr=0;
  140.  
  141.  
  142.     /**
  143.       * @var string $myLink                 link the entry
  144.       ***/
  145.     protected $myLink="";
  146.  
  147.  
  148.     /**
  149.       * @var array $myFilterArr 
  150.       * @since pk-05-01-06
  151.       ***/
  152.     protected $myFilterArr=NULL;
  153.  
  154.  
  155.  
  156.     /**
  157.       * the child object changes parent
  158.       * if true changeParent() is called after populateChildren
  159.       * @var boolean $changesParent 
  160.       * @since pk-05-12-12
  161.       ***/
  162.     protected $changesParent=FALSE;
  163.  
  164.  
  165.     // ############################################################################
  166.  
  167.     /**
  168.       * constructor populates the node if intval($aId) and $auto_populate
  169.       *
  170.       * @param int $aId 
  171.       * @param mixed $myTree (sting) treeKey (DBMS_TREE) tree object
  172.       * @param boolean $auto_populate 
  173.       * @param boolean $debug 
  174.       *
  175.       * @global array $OCSP_OBJ 
  176.       *
  177.       * @access public
  178.       *
  179.       * @version pk-05-07-08 $auto_populate added
  180.       * @version pk-05-12-13
  181.       * @version pk-07-06-19
  182.       * @version pk-07-08-16
  183.       ***/
  184.     function DBMS_TREE_NODE($aId=0,$myTree="",$auto_populate=TRUE,$debug=FALSE{
  185.         global $OCSP_OBJ;
  186.  
  187.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::DBMS_TREE_NODE($aId)");
  188.         $this->init();
  189.  
  190.         if (pcf_is_instance_of($myTree,'DBMS_TREE'))
  191.         {
  192.             $this->myTree=&$myTree;
  193.         else if (is_string($myTree&& !empty($myTree)) {
  194.             if (pcf_is_instance_of($OCSP_OBJ['DBMS_TREE'][$myTree],'DBMS_TREE'))
  195.             {
  196.                 $this->myTree=&$OCSP_OBJ['DBMS_TREE'][$myTree];
  197.             }
  198.         else if (!empty($this->myTable)) {
  199.             if (pcf_is_instance_of($OCSP_OBJ['DBMS_TREE'][$this->myTable],'DBMS_TREE'))
  200.             {
  201.                 $this->myTree=&$OCSP_OBJ['DBMS_TREE'][$this->myTable];
  202.             }
  203.         else if ($debug{
  204.             ocsp_logError(__FILE__,__LINE__,"no tree object found",E_NOTICE);
  205.         }
  206.  
  207.         if (intval($aId)) {
  208.             $this->db_SetKey($this->myIdFld,intval($aId));
  209.             if ($auto_populate// <pk-05-07-08 />
  210.                 $this->dbPopulate($debug);
  211.                 if (pcf_is_instance_of($this->myTree,'DBMS_TREE'))
  212.                 {
  213.                     $this->myTree->addNodeObjectToCache($this);
  214.                 }
  215.             }
  216.         }
  217.     }
  218.  
  219.     // ############################################################################
  220.  
  221.     /**
  222.       * sets configuration attributes (if not set) out of an array
  223.       *
  224.       * @param array $confArr 
  225.       * @param boolean $debug 
  226.       *
  227.       * @since pk-07-08-15
  228.       */
  229.     function setConfigurationArr($confArr,$debug=FALSE)
  230.     {
  231.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::setConfigurationArr()");
  232.         if (is_array($confArr))
  233.         {
  234.             foreach($confArr as $str_name => $m_value)
  235.             {
  236.                 if (!isset($this->{$str_name}|| empty($this->{$str_name}))
  237.                 {
  238.                     if ($debugechoDebugLine(__FILE__,__LINE__,"setting $str_name to $m_value");
  239.                     $this->{$str_name}=$m_value;
  240.                 }
  241.             }
  242.         }
  243.     }
  244.  
  245.     /**
  246.       * @return string 
  247.       */
  248.     function getChildTblName()
  249.     {
  250.         if (!empty($this->myTable))             return $this->myTable;
  251.         if (pcf_is_instance_of($this->myTree))  return $this->myTree->getMyTable();
  252.     }
  253.  
  254.     /**
  255.       * returns the id
  256.       *
  257.       * @return int 
  258.       *
  259.       ***/
  260.     function getId({
  261.         return $this->getDBField($this->myIdFld);
  262.     }
  263.  
  264.     /**
  265.       * sets the id
  266.       *
  267.       * @param int $aId 
  268.       * @since pk-03-12-23
  269.       ***/
  270.     function setId($aId{
  271.         $this->db_SetKey($this->myIdFld,$aId);
  272.     }
  273.  
  274.     /**
  275.       * returns the Level
  276.       *
  277.       * @return int 
  278.       *
  279.       ***/
  280.     function getLevel({
  281.         return intval($this->level);
  282.     }
  283.  
  284.     /**
  285.       * sets the Level
  286.       *
  287.       * @param int $aLevel 
  288.       *
  289.       ***/
  290.     function setLevel($aLevel{
  291.         $this->level=intval($aLevel);
  292.     }
  293.  
  294.     /**
  295.       * returns the orderNr
  296.       *
  297.       * @return int 
  298.       *
  299.       ***/
  300.     function getOrderNr({
  301.         if (intval($this->orderNr))
  302.         {
  303.             return intval($this->orderNr);
  304.         else if (!empty($this->mySortFld)) {
  305.             return $this->getDBField($this->mySortFld);
  306.         else {
  307.             return 0;
  308.         }
  309.     }
  310.  
  311.     /**
  312.       * sets the OrderNr
  313.       *
  314.       * @param int $aOrderNr 
  315.       *
  316.       ***/
  317.     function setOrderNr($aOrderNr{
  318.         $this->orderNr=intval($aOrderNr);
  319.         if (!empty($this->mySortFld))
  320.         {
  321.             $this->setDBFieldIfDiff($this->mySortFld,$aOrderNr);
  322.         }
  323.     }
  324.  
  325.  
  326.  
  327.     /**
  328.       * sets the link url for the output
  329.       *
  330.       * @param string $aLink 
  331.       *
  332.       ***/
  333.     function setLink($aLink{
  334.         $this->myLink=$aLink;
  335.     }
  336.  
  337.     /**
  338.       * @return boolean 
  339.       *
  340.       * @since pk-05-12-13
  341.       *
  342.       ***/
  343.     function changesParent({
  344.         return $this->changesParent;
  345.     }
  346.  
  347.  
  348.  
  349.     // ---------------------------------------------------------------------------
  350.     // tree methods
  351.     // ---------------------------------------------------------------------------
  352.  
  353.    /**
  354.       *
  355.       * @param boolean $debug 
  356.       *
  357.       * @return DBMS_TREE 
  358.       *
  359.       * @since pk-05-07-12
  360.       * @version pk-07-08-09 use setObjVarIfEmpty()
  361.       *
  362.       * @access protected
  363.       *
  364.       ***/
  365.     protected function &newTreeObj($debug=False{
  366.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::newTreeObj()");
  367.  
  368.         if (class_exists($this->myTreeClass)) {
  369.             // ok tree class is loaded letz make a new object
  370.             $s_Cmd="\$this->myTree=new ".$this->myTreeClass."(\$this->getProjId(),\$debug);";
  371.             if ($debugecho "<blockquote>".$s_Cmd."</blockquote>";
  372.             eval ($s_Cmd);
  373.         else {
  374.             // use DBMS_TREE
  375.             $this->myTree=new DBMS_TREE();
  376.         }
  377.  
  378.         // set tree class and instance variables if not set
  379.         $a_TreeVars=array("myTable","myIdFld","myParentFld","mySortFld","myChildClass","myChildKeys");
  380.         foreach($a_TreeVars as $s_VarName{
  381.             $this->myTree->setObjVarIfEmpty($s_VarName,$this->{$s_VarName})// <pk-07-08-09 />
  382.         }
  383.  
  384.         if (!empty($this->myChildKeys)) {
  385.             $a_TreeVars=explode(",",$this->myChildKeys);
  386.             foreach($a_TreeVars as $s_VarName{
  387.                 $this->myTree->setObjVarIfEmpty($s_VarName,$this->{$s_VarName});  // <pk-07-08-09 />
  388.             }
  389.         }
  390.         return $this->myTree;
  391.     }
  392.  
  393.     /**
  394.       * returns myTree object
  395.       *
  396.       * @param boolean $useCache 
  397.       * @param boolean $debug 
  398.       * @param boolean $checkParent (if false $this->getParentObj is not called)
  399.       *
  400.       * @return DBMS_TREE 
  401.       *
  402.       * @since pk-05-07-12
  403.       * @version pk-07-08-09
  404.       * @version pk-07-08-23 added $checkParent to avoid loops in DBMS_TREE_NODE::getParentObj()
  405.       *
  406.       ***/
  407.     function &getTree($useCache=TRUE,$debug=FALSE,$checkParent=TRUE{
  408.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::getTree()","\$useCache=$useCache,...)");
  409.  
  410.         if (!is_object($this->myTree))
  411.         {
  412.             if (pcf_is_instance_of($this->myParent,'DBMS_TREE_NODE'))
  413.             {
  414.                 return $this->myParent->getTree($useCache,$debug,TRUE);
  415.             else if ($checkParent && ($o_myParent=$this->getParentObj($useCache,$debug&& method_exists($o_myParent,'getTree'))) {
  416.                 if ($debugechoDebugLine(__FILE__,__LINE__,"checking parent for tree object");
  417.                 $this->myTree=$o_myParent->getTree($useCache,$debug);
  418.                 $this->myTree->addNodeObjectToCache($this->getId(),$this);
  419.             else {
  420.                 if ($debugechoDebugLine(__FILE__,__LINE__,"generateing new tree object");
  421.                 $this->myTree=$this->newTreeObj($debug);
  422.                 $this->myTree->addNodeObjectToCache($this->getId(),$this);
  423.             }
  424.         }
  425.         return $this->myTree;
  426.     }
  427.  
  428.     /**
  429.       * sets the tree object
  430.       *
  431.       * @param DBMS_TREE $aTree 
  432.       *
  433.       * @since pk-06-07-26
  434.       *
  435.       ***/
  436.     function setTreeObj(&$aTree
  437.     {
  438.         $this->myTree=$aTree;
  439.     }
  440.  
  441.     /**
  442.       * returns the GlobalTreeKey
  443.       *
  444.       * @param boolean $debug 
  445.       *
  446.       * @return string 
  447.       *
  448.       * @version pk-06-07-26
  449.       * @version pk-07-06-19
  450.       * @version pk-07-08-15
  451.       ***/
  452.     function getGlobalTreeKey($debug=FALSE{
  453.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::getGlobalTreeKey()");
  454.         if (!pcf_is_instance_of($this->myTree,'DBMS_TREE'))
  455.         {
  456.             $this->getTree();
  457.         }
  458.         return $this->myTree->getGlobalTreeKey();
  459.     }
  460.  
  461.     /**
  462.       * returns a array back to the root
  463.       * (same as DBMS_TREE->getRootPath) but the tree is not populated
  464.       * saves time and space
  465.       *
  466.       * @param boolean $useCache 
  467.       * @param boolean $debug 
  468.       *
  469.       * @return array 
  470.       *
  471.       * @since pk-05-07-25
  472.       *
  473.       * @var DBMS_TREE_NODE $o_myParent 
  474.       * @var array $a_rPath 
  475.       *
  476.       ***/
  477.     function getRootPath($useCache=TRUE,$debug=FALSE{
  478.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::getRootPath()","NODE ID:".$this->getId());
  479.  
  480.         if ($o_myParent=$this->getParentObj($useCache,$debug)) {
  481.             $a_rPath=$o_myParent->getRootPath($useCache,$debug);
  482.         else {
  483.             $a_rPath=array();
  484.         }
  485.         $a_rPath[]=&$this;
  486.         return $a_rPath;
  487.     }
  488.  
  489.     /**
  490.       * returns the index of the node in the root path
  491.       *
  492.       * returns -1 if node is not in $rootPath
  493.       *
  494.       * @param array $rootPath 
  495.       * @param boolean $debug 
  496.       *
  497.       * @return int 
  498.       *
  499.       * @since pk-04-12-30
  500.       *
  501.       ***/
  502.     function getRootPathIdx(&$rootPath,$debug=FALSE{
  503.         if (is_array($rootPath)) {
  504.             foreach($rootPath as $key => &$obj{
  505.                 if ($obj->getId()==$this->getId()) {
  506.                     return $key;
  507.                 }
  508.             }
  509.             return -1;
  510.         else {
  511.             return -1;
  512.         }
  513.     }
  514.  
  515.  
  516.     // ---------------------------------------------------------------------------
  517.     // parent methods
  518.     // ---------------------------------------------------------------------------
  519.  
  520.     /**
  521.       * returns the parent id
  522.       *
  523.       * @param boolean $debug 
  524.       *
  525.       * @return mixed 
  526.       * @access public
  527.       *
  528.       * @version pk-05-01-04 $debug added
  529.       * @version pk-05-12-12 return value changed
  530.       * @version pk-07-06-19
  531.       *
  532.       ***/
  533.     function getParentId($debug=FALSE{
  534.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::getParentId()","Node ID: ".$this->getId()." Column: ".$this->myParentFld);
  535.         if ($m_id=$this->getDBField($this->myParentFld))
  536.         {
  537.             if ($debugechoDebugLine(__FILE__,__LINE__,"getParentId() returns $m_id");
  538.             return $m_id;
  539.         else if (pcf_is_instance_of($this->myParent,'DBMS_TREE_NODE')) {
  540.             $this->setParentId($this->myParent->getId());
  541.             if ($debugechoDebugLine(__FILE__,__LINE__,"getParentId() returns " $this->myParent->getId());
  542.             return $this->myParent->getId();
  543.         }
  544.         
  545.         if ($debug)  echoDebugLine(__FILE__,__LINE__,"getParentId() returns Null")
  546.         return NULL;
  547.     }
  548.  
  549.     /**
  550.       * sets the parent id
  551.       *
  552.       * @param int $aId 
  553.       * @access public
  554.       *
  555.       * @version pk-07-06-19
  556.       ***/
  557.     function setParentId($aId{
  558.         $this->setDBFieldIfDiff($this->myParentFld,$aId);
  559.     }
  560.  
  561.     /**
  562.       * returns the parent object or null if parent is root
  563.       *
  564.       * @param boolean $useCache 
  565.       * @param boolean $debug 
  566.       *
  567.       * @return DBMS_TREE_NODE 
  568.       *
  569.       * @since pk-05-01-04
  570.       * @version pk-06-07-26 bugfix
  571.       * @version pk-07-06-19
  572.       * @version pk-07-08-10 myParent added to class
  573.       *
  574.       ***/
  575.     function &getParentObj($useCache=TRUE,$debug=FALSE{
  576.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::getParentObj()","NodeId: ".$this->getId()." ".($useCache "USECACHE" "NOCHACHE"));
  577.  
  578.         if (pcf_is_instance_of($this->myParent,'DBMS_TREE_NODE'))
  579.         {
  580.             if ($debugechoDebugLine(__FILE__,__LINE__,"returning set ".get_class($this->myParent)." object with id: ".$this->myParent->getId());
  581.             return $this->myParent;
  582.         }
  583.  
  584.         if (!$parId=$this->getParentId($debug))
  585.         {
  586.             if ($debugechoDebugLine(__FILE__,__LINE__,"DBMS_TREE_NODE::getParentObj() returning NULL because of empty");
  587.             $this->myParent=NULL;
  588.             return $this->myParent;
  589.         else {
  590.             if ($debugechoDebugLine(__FILE__,__LINE__,"DBMS_TREE_NODE::getParentObj() searching for parent with id: ".$parId);
  591.         }
  592.  
  593.         if (!$this->getTree($useCache,$debug,FALSE)) // getTree MUST not call getParentObj() otherwise we have an endless loop
  594.         {
  595.             ocsp_logError(__FILE__,__LINE__,"DBMS_TREE_NODE::getParentObj() node has no tree",E_ERROR);
  596.             $this->myParent=NULL;
  597.             return $this->myParent;
  598.         }
  599.  
  600.         if ($parId==$this->myTree->getRootId())
  601.         {
  602.             if ($debugechoDebugLine(__FILE__,__LINE__,"DBMS_TREE_NODE::getParentObj() returning NULL because of tree root");
  603.             $this->myParent=NULL;
  604.             return $this->myParent;
  605.         }
  606.  
  607.         $this->myParent=$this->myTree->populateNode($parId,$useCache,$debug);
  608.         if ($debugechoDebugLine(__FILE__,__LINE__,"DBMS_TREE_NODE::getParentObj() returning set ".get_class($this->myParent)." object with id: ".$this->myParent->getId());
  609.         return $this->myParent;
  610.     }
  611.  
  612.  
  613.     /**
  614.       * @param DBMS_TREE_NODE $aParent 
  615.       */
  616.     function setParentObj(&$aParent)
  617.     {
  618.         $this->myParent=&$aParent;
  619.         if (method_exists($this->myParent,'getId'))
  620.         {
  621.             $this->setParentId($this->myParent->getId());
  622.         }
  623.     }
  624.  
  625.  
  626.  
  627.  
  628.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  629.     // filter methods
  630.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  631.  
  632.     /**
  633.       * clears the filter
  634.       *
  635.       * @since pk-05-01-06
  636.       *
  637.       ***/
  638.     function filterClear({
  639.         $this->myFilterArr=NULL;
  640.     }
  641.  
  642.     /**
  643.       * adds a key value pair to $myFilterArr
  644.       *
  645.       * @param string $key 
  646.       * @param mixed $val 
  647.       * @param boolean $debug 
  648.       *
  649.       * @since pk-05-01-06
  650.       *
  651.       ***/
  652.     function filterAdd($key,$val,$debug=FALSE{
  653.         if ($debugecho "<p><b>DBMS_TREE_NODE::filterAdd($key,$val,...)</b> (".get_class($this).")</p>";
  654.  
  655.         if (!is_array($this->myFilterArr)) {
  656.             $this->myFilterArr=array();
  657.         }
  658.         $this->myFilterArr[$key]=$val;
  659.  
  660.         if ($debugecho "<blockquote><pre>".print_r($this->myFilterArr,TRUE)."</pre></blockquote>";
  661.     }
  662.  
  663.     /**
  664.       * removes a key form the filter
  665.       *
  666.       * @param string $key 
  667.       * @param boolean $debug 
  668.       *
  669.       * @since pk-05-01-06
  670.       *
  671.       ***/
  672.     function filterRemoveKey($key,$debug{
  673.         if ($debugecho "<p><b>DBMS_TREE_NODE::filterRemoveKey($key,...)</b> (".get_class($this).")</p>";
  674.  
  675.         unset($this->myFilterArr[$key]);
  676.         if (is_array($this->myFilterArr&& (!sizeof($this->myFilterArr))) {
  677.             $this->myFilterArr=NULL;
  678.         }
  679.         if ($debugecho "<blockquote><pre>".print_r($this->myFilterArr,TRUE)."</pre></blockquote>";
  680.     }
  681.  
  682.     /**
  683.       * returns if the node matches the filter array
  684.       * NOTE checks only for exact match
  685.       *
  686.       * @param boolean $debug 
  687.       *
  688.       * @return boolean 
  689.       *
  690.       * @since pk-04-12-29
  691.       *
  692.       ***/
  693.     function matchFilter($debug=FALSE{
  694.         if ($debugecho "<p><b>DBMS_TREE_NODE::matchFilter(".print_r($filterArr,TRUE).",...)</b> NODE:".$this->getId()." (".get_class($this).")</p>";
  695.  
  696.         if (is_array($this->myFilterArr)) {
  697.             if ($debugecho "<blockquote>";
  698.             foreach($this->myFilterArr as $key => $val{
  699.                 if ($debugecho "<p>$key ";
  700.                 if ($this->{$key!= $val{
  701.                     if ($debugecho "|".$this->{$key}."does not match |$val|</p></blockquote>";
  702.                     return FALSE;  // <<<<<<<< -------------- RETURN --------------
  703.                 }
  704.                 if ($debugecho "match $val</p>";
  705.             }
  706.             if ($debugecho "</blockquote>";
  707.         }
  708.         return TRUE;
  709.     }
  710.  
  711.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  712.     // populate / children
  713.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  714.  
  715.     /**
  716.       * sets child class vars
  717.       *
  718.       * @param &DBMS_TREE_NODE   $child 
  719.       *
  720.       * @version pk-05-01-06
  721.       * @version pk-07-08-13 replaced some settings
  722.       *
  723.       ***/
  724.     function setChildClassVar(&$child{
  725.         // <pk-07-08-13>
  726.         //$child->set_gDBIDX($this->get_gDBIDX());
  727.         //$child->setGlobalTreeKey($this->getGlobalTreeKey());
  728.         $child->setDBObj($this->getDBObj());
  729.         $child->setTreeObj($this->getTree());
  730.         // </pk-07-08-13>
  731.  
  732.         $child->setParentId($this->getId());
  733.         $child->setLevel($this->getLevel()+1);
  734.  
  735.         /** DIRECT OBJECT VAR ACCESS !!! **/
  736.         if (empty($child->myTable)) {
  737.             $child->myTable=$this->myTable;
  738.         }
  739.  
  740.         if (empty($child->myIdFld)) {
  741.             $child->myIdFld=$this->myIdFld;
  742.         }
  743.  
  744.         if (empty($child->myParentFld)) {
  745.             $child->myParentFld=$this->myParentFld;
  746.         }
  747.  
  748.         if (empty($child->mySortFld)) {
  749.             $child->mySortFld=$this->mySortFld;
  750.         }
  751.  
  752.         if (empty($child->myChildClass)) {
  753.             $child->myChildClass=$this->myChildClass;
  754.         }
  755.  
  756.         if (empty($child->myChildKeys)) {
  757.             $child->myChildKeys=$this->myChildKeys;
  758.         }
  759.  
  760.         /* <pk-05-01-06> */
  761.         $child->myFilterArr=$this->myFilterArr;
  762.  
  763.     }
  764.  
  765.     // ########################################################################
  766.  
  767.     /**
  768.       * creates a child object out of database row
  769.       *
  770.       * NOTE does not add the object to the tree only sets objects parent
  771.       *
  772.       * @param array $dbRow 
  773.       * @param boolean $debug 
  774.       *
  775.       * @return DBMS_TREE_NODE (ptr)
  776.       *
  777.       * @since pk-05-11-22
  778.       * @version pk-06-07-27
  779.       *
  780.       ***/
  781.     function newChildObj($dbRow,$debug{
  782.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::newChildObj()");
  783.  
  784.         if (!empty($this->myChildClass&& (class_exists($this->myChildClass))) {
  785.             $s_childClass=$this->myChildClass;
  786.         else {
  787.             if ($debugechoDebugLine(__FILE__,__LINE__,"myChildClass is not set or not included");
  788.             $s_childClass=get_class($this);
  789.         }
  790.  
  791.         $o_tmpObj=NULL;
  792.         $s_cmd="\$o_tmpObj=new ".$s_childClass."();";
  793.         if ($debugechoDebugLine(__FILE__,__LINE__,"CHILD NEW CMD$s_cmd");
  794.         eval($s_cmd);
  795.         if (pcf_is_instance_of($o_tmpObj,$s_childClass)) {
  796.             $o_tmpObj->setDBObj($this->getDBObj());
  797.             $o_tmpObj->setDBRow($dbRow,TRUE);
  798.             if (intval($o_tmpObj->getId()))
  799.             {
  800.                 $o_tmpObj->setTreeObj($this->getTree());
  801.                 $o_tmpObj->setParentObj($this);
  802.  
  803.             }
  804.         else {
  805.             if ($debugechoDebugLine(__FILE__,__LINE__,"\$o_tmpObj is not an instance of $s_childClass ".get_type($o_tmpObj));
  806.         }
  807.  
  808.         return $o_tmpObj;
  809.  
  810.     }
  811.  
  812.     /**
  813.       * @param int $childId 
  814.       * @param boolean $debug 
  815.       *
  816.       * @return DBMS_TREE_NODE 
  817.       *
  818.       * @since pk-07-08-23
  819.       */
  820.     function &getChild($childId,$debug=FALSE)
  821.     {
  822.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE->getChild($childIdform Node".$this->getId());
  823.  
  824.         $obj_ret=NULL;
  825.  
  826.         if (!$this->getTree())
  827.         {
  828.             ocsp_logError(__FILE__,__LINE__,"node has no tree",E_WARNING);
  829.             return $obj_ret;
  830.         }
  831.         return $this->myTree->getNode($childId,$debug);
  832.     }
  833.  
  834.     /**
  835.       * returns the select statement to get the children
  836.       *
  837.       * @param string $cols ("SELECT ".$cols." FORM ...")
  838.       * @param boolean $debug 
  839.       *
  840.       * @return string 
  841.       *
  842.       * @since pk-05-11-23
  843.       *
  844.       ***/
  845.     function getChildQueryString($cols="*",$debug=FALSE{
  846.         if ($debugechoDebugMethod(__FILE__,__LINE__,"DBMS_TREE_NODE::getChildQueryString($cols)");
  847.  
  848.         if (!$this->isConnected(TRUE,$debug))
  849.         {
  850.             ocsp_logError(__FILE__,__LINE__,"No database connect in Class: ".get_class($this));
  851.             return NULL;
  852.         }
  853.         $query ="SELECT ".$cols." FROM ".$this->myTable;
  854.         $query.=" WHERE ".$this->myParentFld."=".$this->myDBObj->qs_getSlashedValue($this->getId());
  855.  
  856.         if ((!empty($this->myChildKeys)) && ($keyCols=explode(",",$this->myChildKeys))) {
  857.             foreach($keyCols as $kcol{
  858.                 $query.=" AND ".$kcol." = ".$this->myDBObj->qs_getSlashedValue($this->getDBField($kcol));
  859.             }
  860.         }
  861.  
  862.         if (!empty($this->mySortFld)) {
  863.             $query.=" ORDER BY ".$this->mySortFld;
  864.         }
  865.  
  866.         if ($debugechoDebugLine(__FILE__,__LINE__,"ChildQuery: <br />$query");
  867.         return $query;
  868.     }
  869.  
  870.     /**
  871.       * @abstract changeParent
  872.       *
  873.       * @param boolean $debug 
  874.       *
  875.       * @since pk-05-12-13
  876.       *
  877.       ***/
  878.     function changeParent($debug=FALSE{
  879.         // overwrite in subclasses
  880.     }
  881.  
  882.     /**
  883.       * populates the children
  884.       *
  885.       *
  886.       * if $useCache and a child object exists in the database
  887.       *     this object is used
  888.       * else a new object is created and stored to the global array (cache)
  889.       *     the cached values are overritten
  890.       *
  891.       * @param  boolean    $useCache 
  892.       * @param  boolean    $debug 
  893.       *
  894.       * @return double ($this->myChildrenPopulateTS)
  895.       *
  896.       * @version pk-05-07-08
  897.       * @version pk-05-07-25
  898.       * @version pk-05-12-12 changeParent added
  899.       *
  900.       ***/
  901.     protected function populateChildren($useCache=True,$debug=False)
  902.     {
  903.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::populateChildren()",($useCache "USECACHE" "NOCHACHE")."\n ID: ".$this->getId());
  904.  
  905.         $this->getTree()// ensure $this->myTree is set
  906.         $this->myChildren=array();
  907.  
  908.         // check if we are able to use the cache
  909.         if (!($arr_keyTree=$this->myTree->getKeyTree())) $useCache=FALSE;
  910.         if (!$this->childListIsPopulated())              $useCache=FALSE;
  911.  
  912.         $a_changeParNodes=array();
  913.  
  914.         if ($useCache && isset($arr_keyTree[$this->getId()]&& sizeof($arr_keyTree[$this->getId()]))
  915.         {
  916.             if ($debugechoDebugLine(__FILE__,__LINE__,"$arr_keyTree: <pre>".print_r($arr_keyTree[$this->getId()])."</pre>");
  917.             foreach($arr_keyTree[$this->getId()as $i_node => $arr_node)
  918.             {
  919.                 $obj_node=$this->myTree->getNode($i_node);
  920.                 if (method_exists($obj_node,'getOrderNr'))
  921.                 {
  922.                     $i_orderNr=$obj_node->getOrderNr();
  923.                 else {
  924.                     $i_orderNr=sizeof($this->myChildren);
  925.                 }
  926.                 $i_newOrder=$i_orderNr;
  927.                 while(isset($this->myChildren[$i_newOrder])) $i_newOrder++;
  928.                 if (($i_newOrder != $i_orderNr&& method_exists($obj_node,'setOrderNr'))
  929.                 {
  930.                     $obj_node->setOrderNr($i_newOrder);
  931.                 }
  932.                 $obj_node->setParentObj($this);
  933.                 if ($obj_node->changesParent()) {
  934.                     $a_changeParNodes[]=&$obj_node;
  935.                 }
  936.                 $this->myChildren[$i_newOrder]=$obj_node->getId();
  937.             }
  938.         else {
  939.             if (!$this->isConnected(TRUE,$debug))
  940.             {
  941.                 ocsp_logError(__FILE__,__LINE__,"no database connection",E_ERROR);
  942.                 return FALSE;
  943.             }
  944.             $query=$this->getChildQueryString("*",$debug);
  945.             if ($o_Cursor=$this->myDBObj->query($query))
  946.             {
  947.                 while($a_row $o_Cursor->fetchArrayFld())
  948.                 {
  949.                     if ($obj_node=$this->newChildObj($a_row,$debug))
  950.                     {
  951.                         $this->setChildClassVar($obj_node);
  952.                         if (method_exists($obj_node,"populateObjVals")) $obj_node->populateObjVals();
  953.  
  954.                         if (method_exists($obj_node,'getOrderNr'))  $i_orderNr=$obj_node->getOrderNr();
  955.                         else                                        $i_orderNr=sizeof($this->myChildren);
  956.                         $i_newOrder=$i_orderNr;
  957.                         while(isset($this->myChildren[$i_newOrder])) $i_newOrder++;
  958.                         if (($i_newOrder != $i_orderNr&& method_exists($obj_node,'setOrderNr'))
  959.                         {
  960.                             $obj_node->setOrderNr($i_newOrder);
  961.                         }
  962.                         $this->myTree->addNodeObjectToCache($obj_node->getId(),$obj_node,$debug);
  963.                         if ($obj_node->changesParent()) {
  964.                            $a_changeParNodes[]=&$obj_node;
  965.                         }
  966.                         $this->myChildren[$i_newOrder]=$obj_node->getId();
  967.                     }
  968.                 }
  969.                 $this->myChildrenPopulateTS time();
  970.             else {
  971.                 ocsp_logError(__FILE__,__LINE__,"child query failed",E_WARNING);
  972.                 return FALSE;
  973.             }
  974.         }
  975.  
  976.         foreach($a_changeParNodes as &$obj_node)
  977.         {
  978.             $obj_node->changeParent();
  979.         }
  980.         ksort($this->myChildren);
  981.         return $this->myChildrenPopulateTS;
  982.     }
  983.  
  984.     /**
  985.       * populates the hole tree structure
  986.       *
  987.       * @param  boolean    $useCache 
  988.       * @param  boolean    $debug 
  989.       *
  990.       ***/
  991.     function populateTree($useCache=TRUE,$debug=FALSE{
  992.         if ($debugecho "<hr /><p><b>DBMS_TREE_NODE::populateTree($useCache,$debugID".$this->getId()."</b> (".get_class($this).")</p><blockquote>";
  993.         // if ($debug) {echo "<pre style='font-size:10px;'>";print_r($this);echo "<pre>";}
  994.         $this->populateChildren($useCache,$debug);
  995.         foreach($this->myChildren as $orderNr => $id{
  996.             $GLOBALS['OCSP_VAL']['DBMS_TREE'][$this->getGlobalTreeKey()][$id]->populateTree($useCache,$debug);
  997.         }
  998.         if ($debugecho "<p>DONE populateTree($useCache,$debugID".$this->getId()."</p></blockquote>";
  999.     }
  1000.  
  1001.     /**
  1002.       * adds a node to childArray($key)
  1003.       *
  1004.       * @param DBMS_TREE_NODE $aNode 
  1005.       * @param boolean $debug 
  1006.       *
  1007.       * @return string 
  1008.       *
  1009.       ***/
  1010.     function addChildNode(&$aNode,$debug=FALSE{
  1011.         if (!is_object($aNode)) {
  1012.             echoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::addChildNode(".$aNode->getId().")");
  1013.             ocsp_logError(__FILE__,__LINE__,"\$aNode is not an object");
  1014.             return FALSE;
  1015.         }
  1016.  
  1017.         if (in_array($aNode->getId(),$this->myChildren))
  1018.         {
  1019.             if ($debugocsp_logError(__FILE__,__LINE__,"\$aNode already in array");
  1020.             return FALSE;
  1021.         }
  1022.  
  1023.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::addChildNode(".$aNode->getId().")");
  1024.  
  1025.         if (!is_array($this->myChildren))
  1026.         {
  1027.             echoDebugLine(__FILE__,__LINE__,"resetting \$this->myChildren because it's not an array");
  1028.             $this->myChildren=array();
  1029.         }
  1030.  
  1031.         if (!is_object($this->myTree)) $this->getTree();
  1032.  
  1033.         if (method_exists($aNode,'getOrderNr'))
  1034.         {
  1035.             $i_orderNr=intval($aNode->getOrderNr());
  1036.         else {
  1037.             $i_orderNr=sizeof($this->myChildren);
  1038.         }
  1039.  
  1040.         if (isset($this->myChildren[$i_orderNr]))
  1041.         {
  1042.             while(isset($this->myChildren[$i_orderNr]&& intval($this->myChildren[$i_orderNr]))
  1043.             {
  1044.                 $i_orderNr++;
  1045.             }
  1046.             if (method_exists($aNode,'setOrderNr'))
  1047.             {
  1048.                 $aNode->setOrderNr($i_orderNr);
  1049.             }
  1050.         }
  1051.  
  1052.         $aNode->setParentObj($this);
  1053.         $aNode->setParentId($this->getId());
  1054.  
  1055.         $this->myTree->addNodeObjectToCache($aNode->getId(),$aNode,$debug);
  1056.         $this->myChildren[$i_orderNr]=$aNode->getId();
  1057.  
  1058.         return $aNode->getId();
  1059.     }
  1060.  
  1061.  
  1062.     /**
  1063.       * resorts the children list and saves it to the database
  1064.       *
  1065.       * @param boolean $debug 
  1066.       * @param boolean $autosave 
  1067.       *
  1068.       * @var int $i_Counter 
  1069.       * @var int $i_ChildIdx 
  1070.       * @var DBMS_TREE_NODE $o_Child 
  1071.       *
  1072.       * @since pk-05-07-08
  1073.       * @version pk-07-08-24
  1074.       *
  1075.       ***/
  1076.     function resortChildren($debug=FALSE,$autosave=TRUE{
  1077.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::resortChildren()");
  1078.  
  1079.         if ($arr_keyTree=$this->myTree->getKeyTree())
  1080.         {
  1081.             unset($arr_keyTree[$this->getId()]);
  1082.         }
  1083.         $arr_children=$this->getChildrenList(FALSE,$debug,FALSE);
  1084.         $this->myChildren=array();
  1085.         $i_orderNr=1;
  1086.  
  1087.         foreach($arr_children as &$obj_child)
  1088.         {
  1089.             $this->myChildren[$i_orderNr]=$obj_child->getId();
  1090.             if ($obj_child->getOrderNr(!= $i_orderNr)
  1091.             {
  1092.                 $obj_child->setOrderNr($i_orderNr);
  1093.                 $arr_keyTree[$this->getId()][$obj_child->getId]['SORTORDER']=$obj_child->getOrderNr();
  1094.                 if ($autosave$obj_child->dbSave();
  1095.             }
  1096.             $i_orderNr++;
  1097.         }
  1098.  
  1099.         if ($debugechoDebugLine(__FILE__,__LINE__,"<h1>KeyTree:</h1><pre style=\"background-color:#FFCCCC\">".print_r($arr_keyTree[$this->getId()],TRUE)."<pre>");
  1100.  
  1101.  
  1102.     }
  1103.  
  1104.  
  1105.     /**
  1106.       * moves a child down (increase sort field)
  1107.       *
  1108.       * @param int $childId 
  1109.       * @param boolean $debug 
  1110.       * @param boolean $autosave (save changes to the database)
  1111.       *
  1112.       * @return boolean if the childs has changed
  1113.       *
  1114.       * @version pk-07-08-24
  1115.       *
  1116.       ***/
  1117.     function moveChildDown($childId,$debug=FALSE,$autosave=FALSE{
  1118.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::moveChildDown($childId,...) NODE".$this->getId());
  1119.  
  1120.         $arr_children=$this->getChildrenList(TRUE,$debug,FALSE);
  1121.  
  1122.         if ($o_child=$this->getChild($childId,$debug))
  1123.         {
  1124.             $i_orderNr=$o_child->getOrderNr();
  1125.             $i_count=0;
  1126.             while(($i_count <= sizeof($arr_children)) && (!isset($arr_children[$i_orderNr]|| $arr_children[$i_orderNr]->getId()==$o_child->getId()))
  1127.             {
  1128.                 $i_orderNr++;
  1129.                 $i_count++;
  1130.             }
  1131.             if (!pcf_is_instance_of($arr_children[$i_orderNr],'DBMS_TREE_NODE'))
  1132.             {
  1133.                 ocsp_logError(__FILE__,__LINE__,"could not find next child for node $childId",E_NOTICE);
  1134.                 return FALSE;
  1135.             }
  1136.  
  1137.             $arr_children[$i_orderNr]->setOrderNr($i_orderNr -1);
  1138.             $o_child->setOrderNr($i_orderNr);
  1139.  
  1140.             if ($autosave$arr_children[$i_orderNr]->dbSave($debug);
  1141.             if ($autosave$o_child->dbSave($debug);
  1142.  
  1143.             $this->resortChildren($debug,$autosave);
  1144.             return TRUE;
  1145.         else {
  1146.             return FALSE;
  1147.         }
  1148.     }
  1149.  
  1150.     /**
  1151.       * moves a child up (decrease sort field)
  1152.       *
  1153.       * @param int $childId 
  1154.       * @param boolean $debug 
  1155.       * @param boolean $autosave (save changes to the database)
  1156.       *
  1157.       * @return boolean if the childs has changed
  1158.       *
  1159.       * @version pk-07-08-24
  1160.       *
  1161.       ***/
  1162.     function moveChildUp($childId,$debug=FALSE,$autosave=TRUE{
  1163.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::moveChildDown($childId,...) NODE".$this->getId());
  1164.  
  1165.         $arr_children=$this->getChildrenList(TRUE,$debug,FALSE);
  1166.  
  1167.         if (($o_child=$this->getChild($childId,$debug)) && ($o_child->getOrderNr(1))
  1168.         {
  1169.             $i_orderNr=$o_child->getOrderNr();
  1170.             while($i_orderNr && (!isset($arr_children[$i_orderNr]|| $arr_children[$i_orderNr]->getId()==$o_child->getId()))
  1171.             {
  1172.                 $i_orderNr--;
  1173.             }
  1174.             if (($i_orderNr 1|| !pcf_is_instance_of($arr_children[$i_orderNr],'DBMS_TREE_NODE'))
  1175.             {
  1176.                 ocsp_logError(__FILE__,__LINE__,"could not find previous child for node $childId",E_NOTICE);
  1177.                 return FALSE;
  1178.             }
  1179.  
  1180.             if ($debug)
  1181.             {
  1182.                 $str_debug="<h2>Changeing Nodes:</h2>";
  1183.                 $str_debug.="<p>To Move: ChildId: ".$o_child->getId()." old orderNr: ".$o_child->getOrderNr()." new: ".$i_orderNr."</p>";
  1184.                 $str_debug.="<p>other: ChildId: ".$arr_children[$i_orderNr]->getId()." old orderNr: ".$arr_children[$i_orderNr]->getOrderNr()." new: ".($i_orderNr+1)."</p>";
  1185.                 echoDebug(__FILE__,"<blockquote style=\"font-size: 60%\">");
  1186.             }
  1187.             $arr_children[$i_orderNr]->setOrderNr($i_orderNr+1);
  1188.             $o_child->setOrderNr($i_orderNr);
  1189.  
  1190.             if ($autosave$arr_children[$i_orderNr]->dbSave($debug);
  1191.             if ($autosave$o_child->dbSave($debug);
  1192.  
  1193.             if ($debug)
  1194.             {
  1195.                 echoDebug(__FILE__,"</blockquote>");
  1196.                 $str_debug.="<p><br/>Result: childID:".$o_child->getId()." orderNr: ".$o_child->getOrderNr()."<br />";
  1197.                 $str_debug.="other ID:".$arr_children[$i_orderNr]->getId()." orderNr: ".$arr_children[$i_orderNr]->getOrderNr()."</p>";
  1198.                 echoDebugLine(__FILE__,__LINE__,$str_debug);
  1199.             }
  1200.  
  1201.  
  1202.             $this->resortChildren($debug,$autosave);
  1203.             return TRUE;
  1204.         else {
  1205.             return FALSE;
  1206.         }
  1207.     }
  1208.  
  1209.  
  1210.     //  ###########################################################
  1211.  
  1212.     /**
  1213.       * @return boolean 
  1214.       * @access public
  1215.       * @since pk-07-09-17
  1216.       */
  1217.     function childListIsPopulated()
  1218.     {
  1219.         //echoDebugLine(__FILE__,__LINE__,time()."-".$this->myChildCacheTTL." = ".(time() - $this->myChildCacheTTL)." > ".$this->myChildrenPopulateTS);
  1220.         if ((time($this->myChildCacheTTL$this->myChildrenPopulateTSreturn TRUE;
  1221.         return FALSE;
  1222.     }
  1223.  
  1224.     /**
  1225.       * returns if the node has children
  1226.       *
  1227.       * @param boolean $debug 
  1228.       *
  1229.       * @return boolean 
  1230.       */
  1231.     public function hasChildren($debug=FALSE)
  1232.     {
  1233.         if ($debugechoDebugMethod(__FILE__,get_class($this),"DBMS_TREE_NODE::hasChildren()");
  1234.         return (intval($this->numberOfChildren(TRUE,$debug)) TRUE FALSE);
  1235.     }
  1236.  
  1237.     /**
  1238.       * return the number of childrens
  1239.       *
  1240.       * @param  boolean    $useCache 
  1241.       * @param  boolean    $debug 
  1242.       *
  1243.       * @return int 
  1244.       *
  1245.       ***/
  1246.     function numberOfChildren($useCache=TRUE,$debug=FALSE{
  1247.         if ($debugecho "<hr /><p><b>DBMS_TREE_NODE::numberOfChildren($useCache,$debugID".$this->getId()."</b> (".get_class($this).")</p>";
  1248.         if ((!$useCache|| ((time($this->myChildrenPopulateTS$this->myChildCacheTTL)) {
  1249.             $this->populateChildren($useCache,$debug);
  1250.         }
  1251.         if (is_array($this->myFilterArr)) {
  1252.             $count=0;
  1253.             foreach($this->myChildren as $key => $id{
  1254.                 if ($GLOBALS['OCSP_VAL']['DBMS_TREE'][$this->getGlobalTreeKey()][$id]->matchFilter($this->myFilterArr)) $count++;
  1255.             }
  1256.             return $count;
  1257.         else {
  1258.             return sizeof($this->myChildren);
  1259.         }
  1260.     }
  1261.  
  1262.     /**
  1263.       * returns a array of pointers to the child objects
  1264.       *
  1265.       * if filtered $this->myFilterArr is used to check the child
  1266.       *
  1267.       * @param boolean $useCache 
  1268.       * @param boolean $debug 
  1269.       * @param boolean $filtered 
  1270.       *
  1271.       * @global array $OCSP_VAL 
  1272.       *
  1273.       * @return array 
  1274.       *
  1275.       * @since pk-04-07-23
  1276.       * @version pk-04-12-30 filtered added
  1277.       * @version pk-05-07-26
  1278.       * @version pk-07-08-10
  1279.       *
  1280.       ***/
  1281.     function getChildrenList($useCache=True,$debug=False,$filtered=False
  1282.     {
  1283.         if ($debugechoDebugMethod(__FILE__,__LINE__,"DBMS_TREE_NODE::getChildrenList(".$this->getId().")","\$useCache=".($useCache "TRUE" FALSE)."<br />\$filtered=".($filtered "TRUE" "FALSE"));
  1284.         //if (($debug) && ($useCache)) { echo "<div style=\"font-size:75%;background-color: #FF2244;padding-left:100px;\">\n";$this->debugMyTree();echo "\n</div>\n"; }
  1285.  
  1286.         $this->getTree()// ensure $this->myTree is set
  1287.         if ((!$useCache|| !$this->childListIsPopulated(|| !sizeof($this->myChildren)) {
  1288.             $this->populateChildren($useCache,$debug);
  1289.         }
  1290.  
  1291.         $arr_ret=array();
  1292.         if ($debugechoDebugLine(__FILE__,__LINE__,"<pre>".print_r($this->myChildren,TRUE)."</pre>");
  1293.  
  1294.         foreach($this->myChildren as $key => $m_nodeId{
  1295.             if ($o_node=$this->myTree->getNodeObjectFromCache($m_nodeId,$debug))
  1296.             {
  1297.                 if ($debugechoDebugLine(__FILE__,__LINE__,"Node: ".$o_node->getId());
  1298.                 $i_orderNr=$o_node->getOrderNr();
  1299.                 while(isset($arr_ret[$i_orderNr]))
  1300.                 {
  1301.                     $i_orderNr++;
  1302.                 }
  1303.                 $arr_ret[$i_orderNr]=$o_node;
  1304.             else {
  1305.                 // old style
  1306.  
  1307.                 // <pk-05-07-26>
  1308.                 if (is_array($m_nodeId)) {
  1309.                     $treeKey=$m_nodeId['TREEKEY'];
  1310.                     $treeIdx=$m_nodeId['TREEIDX'];
  1311.                 else {
  1312.                     $treeKey=$this->getGlobalTreeKey();
  1313.                     $treeIdx=$m_nodeId;
  1314.                 }
  1315.                 if ($debugechoDebugLine(__FILE__,__LINE__,"<p>$treeKey => $treeIdx</p>");
  1316.  
  1317.                 global $OCSP_VAL;
  1318.                 if (is_object($OCSP_VAL['DBMS_TREE'][$treeKey]['NODES'][$treeIdx])) {
  1319.                     if ($filtered{
  1320.                         if ($OCSP_VAL['DBMS_TREE'][$treeKey]['NODES'][$treeIdx]->matchFilter($debug)) {
  1321.                             $arr_ret[]=&$OCSP_VAL['DBMS_TREE'][$treeKey]['NODES'][$treeIdx];
  1322.                         }
  1323.                     else {
  1324.                         $arr_ret[]=&$OCSP_VAL['DBMS_TREE'][$treeKey]['NODES'][$treeIdx];
  1325.                     }
  1326.                 else {
  1327.                     ocsp_logError(__FILE__,__LINE__,"NO OBJECT found for key$treeKey:$treeIdx");
  1328.                 }
  1329.                 // </pk-05-07-26>
  1330.             }
  1331.         }
  1332.  
  1333.         ksort($arr_ret);
  1334.         if ($debugechoDebugLine(__FILE__,__LINE__,"Returning an array with ".sizeof($arr_ret)." elements");
  1335.         //foreach($arr_ret as &$o_node) echoDebugLine(__FILE__,__LINE__,"Node: ".$o_node->getId());
  1336.         return $arr_ret;
  1337.     }
  1338.  
  1339.  
  1340.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1341.     // HTML-CODE return (LAYOUT)
  1342.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1343.  
  1344.     /**
  1345.       * returns the link url
  1346.       *
  1347.       * @param boolean $debug 
  1348.       * @return string 
  1349.       *
  1350.       * @since pk-04-02-19
  1351.       *
  1352.       ***/
  1353.     function getLinkUrl($debug=FALSE{
  1354.         if ($debug{
  1355.             echo "#\"><p><b>DBMS_TREE_NODE::getLinkUrl()</b> (".get_class($this).")<br />";
  1356.             echo "<li>myLinkmatchFilter: ".$this->myLink."</li>";
  1357.             echo "<li>myIdFld: ".$this->myIdFld."</li>";
  1358.             echo "<li>ID: ".$this->getId()."</li>";
  1359.         }
  1360.         if (!empty($this->myLink)) {
  1361.             return pcf_HTML_changeURI_GetValue($this->myLink,$this->myIdFld,$this->getId(),$debug);
  1362.         else {
  1363.             return pcf_HTML_changeURI_GetValue($_SERVER['REQUEST_URI'],$this->myIdFld,$this->getId(),$debug);
  1364.         }
  1365.     }
  1366.  
  1367.     /**
  1368.       * @abstract getName
  1369.       *
  1370.       *  returns the show name of the node
  1371.       *
  1372.       * @param boolean $filtered 
  1373.       * @param boolean $debug 
  1374.       *
  1375.       * @return string 
  1376.       *
  1377.       * @since pk-04-12-21
  1378.       * @version pk-05-01-06
  1379.       *
  1380.       ***/
  1381.     function getName($filtered=TRUE,$debug=FALSE{
  1382.         if ($debugecho "<p><b>DBMS_TREE_NODE::getName(...)</b> (".get_class($this).")</p>";
  1383.         return "Function getName not implemented in Class: ".get_class($this);
  1384.     }
  1385.  
  1386.     /**
  1387.       * returns the html code for the nodetemplate
  1388.       *
  1389.       * special values set in dataArray:
  1390.       *
  1391.       * - _ONPATH
  1392.       * - _NAME      $this->GetName())
  1393.       * - _LINK      $this->getLinkUrl()
  1394.       * - _CSSLI     $this->tagLiAdd[$onPath]
  1395.       * - _CSSTD     $this->tagTdAdd[$onPath]
  1396.       * - _NOFCHILD  $this->numberOfChildren($useCache=TRUE,$debug=FALSE) filtered by $this->myFilterArr
  1397.       *
  1398.       * @param string $tmplFile 
  1399.       * @param int $onPath 
  1400.       * @param boolean $fromTmplDir 
  1401.       * @param boolean $debug 
  1402.       *
  1403.       * @return string 
  1404.       *
  1405.       * @since pk-04-12-29
  1406.       *
  1407.       ***/
  1408.     function getNodeTagTmpl($tmplFile,$onPath=0,$fromTmplDir=TRUE,$debug=FALSE{
  1409.         if ($debugecho "<hr /><p><b>DBMS_TREE_NODE::getNodeTagTmpl($tmplFile,$onPath,..) ID".$this->getId()."</b> (".get_class($this).")</p><blockquote>";
  1410.  
  1411.         $dataArr=$this->getDBRow(FALSE,$debug);
  1412.         $dataArr['_ONPATH']     =intval($onPath);
  1413.         $dataArr['_NAME']       =$this->getName();
  1414.         $dataArr['_LINK']       =$this->getLinkUrl();
  1415.  
  1416.         require_once __OCSP_PHPINCPATH__."common/pcf_templates.phpinc";
  1417.         $ret"\n".pcf_tmpl_get($tmplFile,$dataArr,$debug,$fromTmplDir);
  1418.         if ($debugecho "</blockquote>";
  1419.         return $ret;
  1420.     }
  1421.  
  1422.     /**
  1423.       * returns the htmlcode for the node
  1424.       *
  1425.       * calls $this->getLinkUrl() and $this->getName()
  1426.       *
  1427.       * $onPath:
  1428.       *     - 0 not in the path
  1429.       *     - 1 parent of the selected node
  1430.       *     - 2 selected node
  1431.       *
  1432.       * Layout can be handeled by setting
  1433.       * - $this->tagLiAdd[$onPath]  (<li $this->tagLiAdd[$onPath]> )
  1434.       * or
  1435.       * - $this->tagTdAdd[$onPath]  (<td $this->tagTdAdd[$onPath]>)
  1436.       *
  1437.       * @param int $treeType 
  1438.       * @param int $onPath 
  1439.       * @param boolean $debug 
  1440.       *
  1441.       ***/
  1442.     function getNodeTag($treeType=OCSP_TREETYPE_TABLE,$onPath=FALSE,$debug=FALSE{
  1443.         if ($debugecho "<hr /><p><b>DBMS_TREE_NODE::getNodeTag($treeType,$onPath,..) ID".$this->getId()."</b> (".get_class($this).")</p><blockquote>";
  1444.  
  1445.         switch($treeType{
  1446.             case OCSP_TREETYPE_LIST:
  1447.                 $ret"\n\t<li ".$this->tagLiAdd[$onPath]."><a href=\"".$this->getLinkUrl($debug)."\">".$this->getName(FALSE,$debug)."</a></li>";
  1448.                 break// <<<<<<<<<<<<<<<<<<< break <<<<<<<<<<<<<<<<<<<<<
  1449.             default:
  1450.                 $ret"\n\t<tr><td ".$this->tagTdAdd[$onPath]."><a href=\"".$this->getLinkUrl($debug)."\">".$this->getName(FALSE,$debug)."</a></td></tr>";
  1451.         }
  1452.  
  1453.         if ($debugecho "<hr width=\"50%\" align=\"center\"><p align=\"center\"> end DBMS_TREE_NODE::getNodeTag() ID ".$this->getId()."</p></blockquote>\n";
  1454.         return $ret;
  1455.     }
  1456.  
  1457.  
  1458.     /**
  1459.       * returns the html code for the subtree
  1460.       * if $this->myFilterArr is array only children matching the filter are shown
  1461.       *
  1462.       * @param array $rootPath 
  1463.       * @param int $treeType 
  1464.       * @param boolean $filtered 
  1465.       * @param boolean $debug 
  1466.       *
  1467.       * @return string 
  1468.       *
  1469.       * @since pk-04-12-29
  1470.       *
  1471.       ***/
  1472.     function getChildrenTag(&$rootPath,$treeType=OCSP_TREETYPE_TABLE,$filtered=TRUE,$debug=FALSE{
  1473.         if ($debugecho "<p><b>DBMS_TREE_NODE::getChildrenTag(...)</b> ID: ".$this->getId()." (".get_class($this).")</p><blockquote>";
  1474.  
  1475.         $rpId=$this->getRootPathIdx($rootPath,$debug);
  1476.         $rpChildId=$rpId+1;
  1477.         if (is_object($rootPath[$rpChildId])) {
  1478.             $nextChildId=$rootPath[$rpChildId]->getId();
  1479.         else {
  1480.             $nextChildId=0;
  1481.         }
  1482.  
  1483.         $childArr=$this->getChildrenList(TRUE,$debug);
  1484.         $ret="";
  1485.         foreach($childArr as $children{
  1486.             $children->tagLiAdd=$this->tagLiAdd;
  1487.             $children->tagTdAdd=$this->tagTdAdd;
  1488.             $children->tagUlAdd=$this->tagUlAdd;
  1489.             $children->tagTblAdd=$this->tagTblAdd;
  1490.             if ($children->getId()==$nextChildId{
  1491.                 if (!is_object($rootPath[$rpChildId+1])) {
  1492.                     $childonPath=1;
  1493.                 else {
  1494.                     $childonPath=2;
  1495.                 }
  1496.                 $ret.=$children->getNodeTag($treeType,$childonPath,$debug);
  1497.                 $chldTag=$children->getChildrenTag($rootPath,$treeType,$filtered,$debug);
  1498.                 if (!empty($chldTag)) {
  1499.                     switch($treeType{
  1500.                         case OCSP_TREETYPE_LIST:
  1501.                             $ret.="\n\t<ul ".$this->tagUlAdd.">";
  1502.                             $ret.="\n\t\t".$chldTag;
  1503.                             $ret.="\n\t</ul>";
  1504.                             break// <<<<<<<< ------------------ BREAK ----------------------
  1505.                         default:
  1506.                             if (empty($this->tagTblAdd)) {
  1507.                                 $this->tagTblAdd=" width=\"95%\"";
  1508.                             }
  1509.                             $ret.="\n\t<tr><td algin=\"right\"><table ".$this->tagTblAdd.">";
  1510.                             $ret.="\n\t\t".$chldTag;
  1511.                             $ret.="\n\t</table></td></tr>";
  1512.                     }
  1513.                 }
  1514.             else {
  1515.                 if ((!$filtered|| $children->matchFilter($debug)) {
  1516.                     $ret.=$children->getNodeTag($treeType,0,$debug);
  1517.                 }
  1518.             }
  1519.         }
  1520.  
  1521.         if ($debugecho "<hr /></blockquote>";
  1522.         return $ret;
  1523.  
  1524.     }
  1525.  
  1526.     /**
  1527.       * returns the html code for the subtree
  1528.       * if $this->myFilterArr is array only children matching the filter are shown
  1529.       *
  1530.       * special values set in dataArray:
  1531.       *
  1532.       * - _ONPATH
  1533.       * - _NAME      $this->getName())
  1534.       * - _LINK      $this->getLinkUrl()
  1535.       * - _CSSLI     $this->tagLiAdd[$onPath]
  1536.       * - _CSSTD     $this->tagTdAdd[$onPath]
  1537.       * - _NOFCHILD  $this->numberOfChildren($useCache=TRUE,$debug=FALSE) filtered by $this->myFilterArr
  1538.       *
  1539.       * @param array $tmplArr 
  1540.       * @param array $rootPath 
  1541.       * @param boolean $fromTmplDir 
  1542.       * @param boolean $debug 
  1543.       *
  1544.       * @return string 
  1545.       *
  1546.       * @since pk-04-12-29
  1547.       *
  1548.       ***/
  1549.     function getChildrenTagTmpl($tmplArr,&$rootPath,$frmTmplDir=TRUE,$debug=FALSE{
  1550.         if ($debugecho "<p><b>DBMS_TREE_NODE::getChildrenTag(...)</b> ID: ".$this->getId()." (".get_class($this).")</p>";
  1551.  
  1552.         $rPId=$this->getRootPathIdx($rootPath,$debug);
  1553.         $rpChildId=$rpId+1;
  1554.         if (!is_object($rootPath[$rpChildId+1])) {
  1555.             $childonPath=1;
  1556.         else {
  1557.             $childonPath=2;
  1558.         }
  1559.  
  1560.         $childArr=$this->getChildrenList(TRUE,$debug);
  1561.         $ret="";
  1562.         foreach($childArr as $children{
  1563.             $children->tagLiAdd=$this->tagLiAdd;
  1564.             $children->tagTdAdd=$this->tagTdAdd;
  1565.             $children->tagUlAdd=$this->tagUlAdd;
  1566.             $children->tagTblAdd=$this->tagTblAdd;
  1567.             if ($children->${$children->myIdFld}==$rootPath[$rpChildId]->${$rootPath[$rpChildId]->myIdFld}{
  1568.                 $ret.=$children->getNodeTag($treeType,$childonPath,$debug);
  1569.                 $chldTag=$children->getChildrenTag($rootPath,$treeType,$debug);
  1570.                 if (!empty($chldTag)) {
  1571.                     switch($treeType{
  1572.                         case OCSP_TREETYPE_LIST:
  1573.                             $ret.="<ul ".$this->tagUlAdd.">";
  1574.                             $ret.=$chldTag;
  1575.                             $ret.="</ul>";
  1576.                             break// <<<<<<<< ------------------ BREAK ----------------------
  1577.                         default:
  1578.                             if (empty($this->tagTblAdd)) {
  1579.                                 $this->tagTblAdd=" width=\"95%\"";
  1580.                             }
  1581.                             $ret.="<tr><td algin=\"right\"><table ".$this->tagTblAdd.">";
  1582.                             $ret.=$chldTag;
  1583.                             $ret.="</table></td></tr>";
  1584.                     }
  1585.                 }
  1586.             else {
  1587.                 if ($children->matchFilter($this->myFilterArr,$debug)) {
  1588.                     $ret.=$children->getNodeTag($treeType,0,$debug);
  1589.                 }
  1590.             }
  1591.         }
  1592.  
  1593.         return $ret;
  1594.  
  1595.     }
  1596.  
  1597.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1598.     // debugging
  1599.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1600.  
  1601.     /**
  1602.       * outputs debug information about the global tree array
  1603.       */
  1604.     function debugMyTree({
  1605.         echo "<p>TREE DEBUG: \$GLOBALS['OCSP_VAL']['DBMS_TREE'][".$this->getGlobalTreeKey()."]</p>\n";
  1606.  
  1607.         if (!is_array($GLOBALS['OCSP_VAL']['DBMS_TREE'][$this->getGlobalTreeKey()])) {
  1608.             echo "<b>ARRAY \$GLOBALS['OCSP_VAL']['DBMS_TREE'][".$this->getGlobalTreeKey()."]SET</b>";
  1609.         else {
  1610.             echo "<pre>\n";
  1611.             foreach($GLOBALS['OCSP_VAL']['DBMS_TREE'][$this->getGlobalTreeKey()as $m_idx => &$m_val{
  1612.                 if (pcf_is_instance_of($m_val,'DBMS_TREE_NODE'))
  1613.                 {
  1614.                     echo "\n-----------------------------------------------\n$m_idx\n";
  1615.                     echo "\tCLASS: ".get_class($m_val)."\n";
  1616.                     echo "\tID:    ".$m_val->getId()."\n";
  1617.                     if (method_exists($m_val,'getTitle'))
  1618.                     {
  1619.                         echo "\tTitle: ".$m_val->getTitle()."\n";
  1620.                     }
  1621.                     echo "\tParent:".$m_val->getParentId()."\n";
  1622.                 else if (is_array($m_val)) {
  1623.                     echo "\n_ ARRAY ________________________________________\n$m_idx\n";
  1624.                     switch($m_idx)
  1625.                     {
  1626.                         case "NODES":
  1627.                             foreach($m_val as $i_id => $o_node)
  1628.                             {
  1629.                                 echo "\nNode ID$i_id   -----------------------------------------------\n";
  1630.                                 echo "\tCLASS: ".get_class($o_node)."\n";
  1631.                                 echo "\tID:    ".$o_node->getId()."\n";
  1632.                                 if (method_exists($o_node,'getTitle'))
  1633.                                 {
  1634.                                     echo "\tTitle: ".$o_node->getTitle()."\n";
  1635.                                 }
  1636.                                 echo "\tParent:".$o_node->getParentId()."\n";
  1637.                             }
  1638.                             break;
  1639.                         default:
  1640.                             foreach($m_val as $m_subIdx => $m_subVal)
  1641.                             {
  1642.                                 echo "Index$m_subIdx Type".gettype($m_subVal)."\n";
  1643.                             }
  1644.                     }
  1645.                 else {
  1646.                     echo "\n_______________________________________________\n$m_idx\n";
  1647.                     echo "Type: ".gettype($m_val)."\n";
  1648.                     //echo substr(var_dump($o_node,TRUE),0,40)."\n";
  1649.                 }
  1650.             }
  1651.             echo "</pre>\n";
  1652.         }
  1653.     }
  1654. }
  1655. ?>

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