Ticket #312: 1.2-nestedset.diff

File 1.2-nestedset.diff, 67.2 KB (added by heltem, 4 years ago)

Patch to support NestedSet in 1.2

  • generator/classes/propel/engine/builder/om/OMBuilder.php

     
    2727 *  
    2828 * OM-building classes are those that build a PHP (or other) class to service 
    2929 * a single table.  This includes Peer classes, Entity classes, Map classes,  
    30  * Node classes, etc. 
     30 * Node classes, Nested Set classes, etc. 
    3131 *  
    3232 * @author Hans Lellelid <hans@xmpl.org> 
    3333 * @package propel.engine.builder.om 
     
    100100         */ 
    101101        private $stubNodePeerBuilder; 
    102102         
    103          
    104103        /** 
     104         * NestedSet object builder for current table. 
     105         * @var DataModelBuilder 
     106         */ 
     107        private $nestedSetBuilder; 
     108 
     109        /** 
     110         * NestedSet peer builder for current table. 
     111         * @var DataModelBuilder 
     112         */ 
     113        private $nestedSetPeerBuilder; 
     114 
     115        /** 
     116         * Stub nested set object builder for current table. 
     117         * @var DataModelBuilder 
     118         */ 
     119        private $stubNestedSetBuilder; 
     120 
     121        /** 
     122         * Stub nested set peer builder for current table. 
     123         * @var DataModelBuilder 
     124         */ 
     125        private $stubNestedSetPeerBuilder; 
     126 
     127 
     128        /** 
    105129         * Returns new or existing Peer builder class for this table. 
    106130         * @return DataModelBuilder 
    107131         */ 
     
    233257                } 
    234258                return $this->stubNodePeerBuilder;       
    235259        } 
    236          
     260 
    237261        /** 
     262         * Returns new or existing nested set Object builder class for this table. 
     263         * @return DataModelBuilder 
     264         */ 
     265        public function getNestedSetBuilder() 
     266        { 
     267                if (!isset($this->nestedSetBuilder)) { 
     268                        $this->nestedSetBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nestedset'); 
     269                } 
     270                return $this->nestedSetBuilder; 
     271        } 
     272 
     273        /** 
     274         * Returns new or existing nested set Peer builder class for this table. 
     275         * @return DataModelBuilder 
     276         */ 
     277        public function getNestedSetPeerBuilder() 
     278        { 
     279                if (!isset($this->nestedSetPeerBuilder)) { 
     280                        $this->nestedSetPeerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nestedsetpeer'); 
     281                } 
     282                return $this->nestedSetPeerBuilder; 
     283        } 
     284 
     285        /** 
     286         * Returns new or existing stub nested set Object builder class for this table. 
     287         * @return DataModelBuilder 
     288         */ 
     289        public function getStubNestedSetBuilder() 
     290        { 
     291                if (!isset($this->stubNestedSetBuilder)) { 
     292                        $this->stubNestedSetBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nestedsetstub'); 
     293                } 
     294                return $this->stubNestedSetBuilder; 
     295        } 
     296 
     297        /** 
     298         * Returns new or existing stub nested set Peer builder class for this table. 
     299         * @return DataModelBuilder 
     300         */ 
     301        public function getStubNestedSetPeerBuilder() 
     302        { 
     303                if (!isset($this->stubNestedSetPeerBuilder)) { 
     304                        $this->stubNestedSetPeerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nestedsetpeerstub'); 
     305                } 
     306                return $this->stubNestedSetPeerBuilder; 
     307        } 
     308 
     309        /** 
    238310         * Convenience method to return a NEW Peer class builder instance. 
    239311         * This is used very frequently from the peer and object builders to get 
    240312         * a peer builder for a RELATED table. 
     
    406478        return $class; 
    407479    }    
    408480         
    409 } 
    410  No newline at end of file 
     481} 
  • generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNestedSetBuilder.php

     
     1<?php 
     2 
     3/* 
     4 *  $Id: PHP5BasicObjectBuilder.php 120 2005-06-17 02:18:41Z hans $ 
     5 * 
     6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     17 * 
     18 * This software consists of voluntary contributions made by many individuals 
     19 * and is licensed under the LGPL. For more information please see 
     20 * <http://propel.phpdb.org>. 
     21 */ 
     22 
     23require_once 'propel/engine/builder/om/ObjectBuilder.php'; 
     24 
     25/** 
     26 * Generates the empty PHP5 stub nested set object class for user object model (OM). 
     27 *  
     28 * This class produces the empty stub class that can be customized with application 
     29 * business logic, custom behavior, etc. 
     30 *  
     31 * @author Heltem <heltem@o2php.com> 
     32 * @package propel.engine.builder.om.php5 
     33 */ 
     34class PHP5ExtensionNestedSetBuilder extends ObjectBuilder { 
     35         
     36        /** 
     37         * Returns the name of the current class being built. 
     38         * @return string 
     39         */ 
     40        public function getClassname() 
     41        { 
     42                return $this->getTable()->getPhpName() . 'NestedSet'; 
     43        } 
     44         
     45        /** 
     46         * Adds the include() statements for files that this class depends on or utilizes. 
     47         * @param string &$script The script will be modified in this method. 
     48         */ 
     49        protected function addIncludes(&$script) 
     50        { 
     51         
     52                $script .= " 
     53require_once '".$this->getNestedSetBuilder()->getClassFilePath()."'; 
     54"; 
     55                 
     56        } // addIncludes() 
     57         
     58        /** 
     59         * Adds class phpdoc comment and openning of class. 
     60         * @param string &$script The script will be modified in this method. 
     61         */ 
     62        protected function addClassOpen(&$script) 
     63        { 
     64                 
     65                $table = $this->getTable(); 
     66                $tableName = $table->getName(); 
     67                $tableDesc = $table->getDescription(); 
     68                 
     69                $baseClassname = $this->getNestedSetBuilder()->getClassname(); 
     70                 
     71                $script .= " 
     72 
     73/** 
     74 * Skeleton subclass for representing a nested set from the '$tableName' table. 
     75 * 
     76 * $tableDesc 
     77 *"; 
     78                if ($this->getBuildProperty('addTimeStamp')) { 
     79                        $now = strftime('%c'); 
     80                        $script .= " 
     81 * This class was autogenerated by Propel on: 
     82 * 
     83 * $now 
     84 *"; 
     85                } 
     86                $script .= " 
     87 * You should add additional methods to this class to meet the 
     88 * application requirements.  This class will only be generated as 
     89 * long as it does not already exist in the output directory. 
     90 * 
     91 * @package ".$this->getPackage()." 
     92 */      
     93class ".$this->getClassname()." extends $baseClassname { 
     94"; 
     95        } 
     96         
     97        /** 
     98         * Specifies the methods that are added as part of the stub object class. 
     99         *  
     100         * By default there are no methods for the empty stub classes; override this method 
     101         * if you want to change that behavior. 
     102         *  
     103         * @see ObjectBuilder::addClassBody() 
     104         */ 
     105        protected function addClassBody(&$script) 
     106        { 
     107                // there is no class body 
     108        } 
     109         
     110        /** 
     111         * Closes class. 
     112         * @param string &$script The script will be modified in this method. 
     113         */      
     114        protected function addClassClose(&$script) 
     115        { 
     116                $script .= " 
     117} // " . $this->getClassname() . " 
     118"; 
     119        } 
     120         
     121} // PHP5ExtensionObjectBuilder 
  • generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNestedSetPeerBuilder.php

     
     1<?php 
     2 
     3/* 
     4 *  $Id: PHP5BasicObjectBuilder.php 120 2005-06-17 02:18:41Z hans $ 
     5 * 
     6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     17 * 
     18 * This software consists of voluntary contributions made by many individuals 
     19 * and is licensed under the LGPL. For more information please see 
     20 * <http://propel.phpdb.org>. 
     21 */ 
     22 
     23require_once 'propel/engine/builder/om/PeerBuilder.php'; 
     24 
     25/** 
     26 * Generates the empty PHP5 stub nested set peer class for user object model (OM). 
     27 *  
     28 * This class produces the empty stub class that can be customized with application 
     29 * business logic, custom behavior, etc. 
     30 *  
     31 * @author Heltem <heltem@o2php.com> 
     32 * @package propel.engine.builder.om.php5 
     33 */ 
     34class PHP5ExtensionNestedSetPeerBuilder extends PeerBuilder { 
     35         
     36        /** 
     37         * Returns the name of the current class being built. 
     38         * @return string 
     39         */ 
     40        public function getClassname() 
     41        { 
     42                return $this->getStubNestedSetBuilder()->getClassname() . 'Peer'; 
     43        } 
     44 
     45        /** 
     46         * Adds the include() statements for files that this class depends on or utilizes. 
     47         * @param string &$script The script will be modified in this method. 
     48         */ 
     49        protected function addIncludes(&$script) 
     50        { 
     51                $script .= " 
     52  // include base nested set peer class 
     53  require_once '".$this->getNestedSetPeerBuilder()->getClassFilePath()."'; 
     54   
     55  // include nested set class 
     56  include_once '".$this->getStubNestedSetBuilder()->getClassFilePath()."'; 
     57"; 
     58        } // addIncludes() 
     59         
     60        /** 
     61         * Adds class phpdoc comment and openning of class. 
     62         * @param string &$script The script will be modified in this method. 
     63         */ 
     64        protected function addClassOpen(&$script) 
     65        { 
     66                 
     67                $table = $this->getTable(); 
     68                $tableName = $table->getName(); 
     69                $tableDesc = $table->getDescription(); 
     70                 
     71                $baseClassname = $this->getNestedSetPeerBuilder()->getClassname(); 
     72                 
     73                $script .= " 
     74 
     75/** 
     76 * Skeleton subclass for performing query and update operations on nested set of the '$tableName' table. 
     77 * 
     78 * $tableDesc 
     79 *"; 
     80                if ($this->getBuildProperty('addTimeStamp')) { 
     81                        $now = strftime('%c'); 
     82                        $script .= " 
     83 * This class was autogenerated by Propel on: 
     84 * 
     85 * $now 
     86 *"; 
     87                } 
     88                $script .= " 
     89 * You should add additional methods to this class to meet the 
     90 * application requirements.  This class will only be generated as 
     91 * long as it does not already exist in the output directory. 
     92 * 
     93 * @package ".$this->getPackage()." 
     94 */      
     95class ".$this->getClassname()." extends $baseClassname { 
     96"; 
     97        } 
     98         
     99                /** 
     100         * Specifies the methods that are added as part of the stub peer class. 
     101         *  
     102         * By default there are no methods for the empty stub classes; override this method 
     103         * if you want to change that behavior. 
     104         *  
     105         * @see ObjectBuilder::addClassBody() 
     106         */ 
     107 
     108        protected function addClassBody(&$script) 
     109        { 
     110                // there is no class body 
     111        } 
     112         
     113        /** 
     114         * Closes class. 
     115         * @param string &$script The script will be modified in this method. 
     116         */      
     117        protected function addClassClose(&$script) 
     118        { 
     119                $script .= " 
     120} // " . $this->getClassname() . " 
     121"; 
     122        } 
     123         
     124} // PHP5ExtensionPeerBuilder 
  • generator/classes/propel/engine/builder/om/php5/PHP5NestedSetBuilder.php

     
     1<?php 
     2 
     3/* 
     4 *  $Id: PHP5BasicObjectBuilder.php 157 2005-08-10 19:16:22Z hans $ 
     5 * 
     6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     17 * 
     18 * This software consists of voluntary contributions made by many individuals 
     19 * and is licensed under the LGPL. For more information please see 
     20 * <http://propel.phpdb.org>. 
     21 */ 
     22 
     23require_once 'propel/engine/builder/om/ObjectBuilder.php'; 
     24 
     25/** 
     26 * Generates a PHP5 tree nested set Object class for user object model (OM). 
     27 *  
     28 * This class produces the base tree nested set object class (e.g. BaseMyTable) which contains all 
     29 * the custom-built accessor and setter methods. 
     30 *  
     31 * @author Heltem <heltem@o2php.com> 
     32 * @package propel.engine.builder.om.php5 
     33 */ 
     34class PHP5NestedSetBuilder extends ObjectBuilder { 
     35         
     36        /** 
     37         * Gets the package for the [base] object classes. 
     38         * @return string 
     39         */ 
     40        public function getPackage() 
     41        { 
     42                return parent::getPackage() . ".om"; 
     43        } 
     44         
     45        /** 
     46         * Returns the name of the current class being built. 
     47         * @return string 
     48         */ 
     49        public function getClassname() 
     50        { 
     51                return $this->getBuildProperty('basePrefix') . $this->getStubNestedSetBuilder()->getClassname(); 
     52        } 
     53         
     54        /** 
     55         * Adds the include() statements for files that this class depends on or utilizes. 
     56         * @param string &$script The script will be modified in this method. 
     57         */ 
     58        protected function addIncludes(&$script) 
     59        { 
     60                $script .= " 
     61require_once '".$this->getStubNestedSetPeerBuilder()->getClassFilePath()."'; 
     62require_once '".$this->getStubObjectBuilder()->getClassFilePath()."'; 
     63"; 
     64        } // addIncludes() 
     65         
     66        /** 
     67         * Adds class phpdoc comment and openning of class. 
     68         * @param string &$script The script will be modified in this method. 
     69         */ 
     70        protected function addClassOpen(&$script) 
     71        { 
     72                 
     73                $table = $this->getTable(); 
     74                $tableName = $table->getName(); 
     75                $tableDesc = $table->getDescription(); 
     76                 
     77                $script .= " 
     78/** 
     79 * Base class that represents a row from the '$tableName' table. 
     80 * 
     81 * $tableDesc 
     82 *"; 
     83                if ($this->getBuildProperty('addTimeStamp')) { 
     84                        $now = strftime('%c'); 
     85                        $script .= " 
     86 * This class was autogenerated by Propel on: 
     87 * 
     88 * $now 
     89 *"; 
     90                } 
     91                $script .= " 
     92 * @package ".$this->getPackage()." 
     93 */      
     94abstract class ".$this->getClassname()." extends ".$this->getStubObjectBuilder()->getClassname()." { 
     95"; 
     96        } 
     97         
     98        /** 
     99         * Specifies the methods that are added as part of the basic OM class. 
     100         * This can be overridden by subclasses that wish to add more methods. 
     101         * @see ObjectBuilder::addClassBody() 
     102         */ 
     103        protected function addClassBody(&$script) 
     104        { 
     105                $table = $this->getTable(); 
     106                 
     107                $this->addAttributes($script); 
     108                                 
     109                $this->addSave($script); 
     110                $this->addDelete($script); 
     111 
     112                $this->addLeftGetter($script); 
     113                $this->addRightGetter($script); 
     114                 
     115                $this->addLeftSetter($script); 
     116                $this->addRightSetter($script); 
     117 
     118                $this->addLevelGetter($script); 
     119                $this->addLevelSetter($script); 
     120                 
     121                $this->addPathGetter($script); 
     122                $this->addNumberOfChildrenGetter($script); 
     123                $this->addNumberOfDescendantsGetter($script); 
     124 
     125                $this->addChildrenGetter($script); 
     126                $this->addDescendantsGetter($script); 
     127 
     128                $this->addIsRoot($script); 
     129                $this->addIsLeaf($script); 
     130                $this->addHasChildren($script); 
     131                $this->addHasPrevSibling($script); 
     132                $this->addHasNextSibling($script); 
     133                 
     134                $this->addInsertAsFirstChildOf($script); 
     135                $this->addInsertAsLastChildOf($script); 
     136                 
     137                $this->addInsertAsPrevSiblingOf($script); 
     138                $this->addInsertAsNextSiblingOf($script); 
     139        } 
     140         
     141        /** 
     142         * Closes class. 
     143         * @param string &$script The script will be modified in this method. 
     144         */      
     145        protected function addClassClose(&$script) 
     146        { 
     147                $script .= " 
     148} // " . $this->getClassname() . " 
     149"; 
     150        } 
     151         
     152         
     153        /** 
     154         * Adds class attributes. 
     155         * @param string &$script The script will be modified in this method. 
     156         */ 
     157        protected function addAttributes(&$script) 
     158        { 
     159                $script .= " 
     160        /** 
     161         * Store level of node 
     162         * @var int 
     163         */ 
     164        protected \$level = null; 
     165 
     166        /** 
     167         * Store if node has prev sibling 
     168         * @var bool 
     169         */ 
     170        protected \$hasPrevSibling = null; 
     171 
     172        /** 
     173         * Store if node has next sibling 
     174         * @var bool 
     175         */ 
     176        protected \$hasNextSibling = null; 
     177 
     178        /** 
     179         * Store children of the node 
     180         * @var array 
     181         */ 
     182        public \$_children = null; 
     183"; 
     184        } 
     185 
     186        protected function addSave(&$script) 
     187        { 
     188            $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     189            $script .= " 
     190        /** 
     191         * If object is saved without left/right values, set them as undefined (0) 
     192         */ 
     193        public function save(\$con = null) 
     194        { 
     195                \$left = \$this->getLeftValue(); 
     196                \$right = \$this->getRightValue(); 
     197                if(empty(\$left) || empty(\$right)) { 
     198                        \$root = $nestedSetPeerClassname::retrieveRoot(\$con); 
     199                $nestedSetPeerClassname::insertAsLastChildOf(\$root, \$this, \$con); 
     200                } 
     201 
     202                return parent::save(\$con); 
     203        } 
     204"; 
     205        } 
     206 
     207        protected function addDelete(&$script) 
     208        { 
     209                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     210                $script .= " 
     211        /** 
     212         * Delete node and descendants 
     213         */ 
     214        public function delete(\$deleteDescendants = true, \$con = null) 
     215        { 
     216                \$right = \$this->getRightValue(); 
     217                \$left = \$this->getLeftValue(); 
     218 
     219                // delete node first 
     220                parent::delete(\$con); 
     221 
     222                if (\$deleteDescendants) { 
     223                        // delete descendants and then shift tree 
     224                        $nestedSetPeerClassname::deleteDescendants(\$left, \$right, \$con); 
     225                } 
     226        } 
     227"; 
     228        } 
     229 
     230        protected function addLeftGetter(&$script) 
     231        { 
     232                $script .= " 
     233        /** 
     234         * Wraps the getter for the left value, used by TreePeer 
     235         * 
     236         * @return int 
     237         */ 
     238        public function getLeftValue() 
     239        { 
     240                return \$this->getLft(); 
     241        } 
     242"; 
     243        } 
     244 
     245        protected function addRightGetter(&$script) 
     246        { 
     247                $script .= " 
     248        /** 
     249         * Wraps the getter for the right value, used by TreePeer 
     250         * 
     251         * @return int 
     252         */ 
     253        public function getRightValue() 
     254        { 
     255                return \$this->getRgt(); 
     256        } 
     257"; 
     258        } 
     259 
     260        protected function addLeftSetter(&$script) 
     261        { 
     262                $script .= " 
     263        /** 
     264         * Set the value left column 
     265         * 
     266         * @param int \$v new value 
     267         * @return void 
     268         */ 
     269        public function setLeftValue(\$v) 
     270        { 
     271                \$this->setLft(\$v); 
     272        } 
     273"; 
     274        } 
     275 
     276        protected function addRightSetter(&$script) 
     277        { 
     278                $script .= " 
     279        /** 
     280         * Set the value of right column 
     281         * 
     282         * @param int \$v new value 
     283         * @return void 
     284         */ 
     285        public function setRightValue(\$v) 
     286        { 
     287                \$this->setRgt(\$v); 
     288        } 
     289"; 
     290        } 
     291 
     292        protected function addLevelGetter(&$script) 
     293        { 
     294                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     295                $script .= " 
     296        /** 
     297         * Gets the level if set, otherwise calculates this and returns it 
     298         * 
     299         * @return int 
     300         */ 
     301        public function getLevel(\$con = null) 
     302        { 
     303                if(\$this->level === NULL) { 
     304                        \$this->level = $nestedSetPeerClassname::getLevel(\$this, \$con); 
     305                } 
     306                return \$this->level; 
     307        } 
     308"; 
     309        } 
     310 
     311        protected function addLevelSetter(&$script) 
     312        { 
     313                $script .= " 
     314        /** 
     315         * Sets the level of the node in the tree 
     316         * 
     317         * @param int \$v new value 
     318         * @return void 
     319         */ 
     320        public function setLevel(\$level) 
     321        { 
     322                \$this->level = \$level; 
     323        } 
     324"; 
     325        } 
     326 
     327        protected function addPathGetter(&$script) 
     328        { 
     329                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     330                $script .= " 
     331        /** 
     332         * Get the path to the node in the tree 
     333         * 
     334         * @return array 
     335         */ 
     336        public function getPath(\$con = null) 
     337        { 
     338                return $nestedSetPeerClassname::getPath(\$this); 
     339        } 
     340"; 
     341        } 
     342 
     343        protected function addNumberOfChildrenGetter(&$script) 
     344        { 
     345                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     346                $script .= " 
     347        /** 
     348         * Gets the number of children for the node (direct descendants) 
     349         * 
     350         * @return int 
     351         */ 
     352        public function getNumberOfChildren(\$con = null) 
     353        { 
     354                return $nestedSetPeerClassname::getNumberOfChildren(\$this, \$con); 
     355        } 
     356"; 
     357        } 
     358 
     359        protected function addNumberOfDescendantsGetter(&$script) 
     360        { 
     361                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     362                $script .= " 
     363        /** 
     364         * Gets the total number of desceandants for the node 
     365         * 
     366         * @return int 
     367         */ 
     368        public function getNumberOfDescendants(\$con = null) 
     369        { 
     370                return $nestedSetPeerClassname::getNumberOfDescendants(\$node, \$con); 
     371        } 
     372"; 
     373        } 
     374 
     375        protected function addChildrenGetter(&$script) 
     376        { 
     377                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     378                $script .= " 
     379        /** 
     380         * Gets the children for the node 
     381         * 
     382         * @return array 
     383         */ 
     384        public function getChildren(\$con = null) 
     385        { 
     386                return $nestedSetPeerClassname::retrieveChildren(\$this, false, \$con); 
     387        } 
     388"; 
     389        } 
     390 
     391        protected function addDescendantsGetter(&$script) 
     392        { 
     393                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     394                $script .= " 
     395        /** 
     396         * Gets the descendants for the node 
     397         * 
     398         * @return array 
     399         */ 
     400        public function getDescendants(\$con = null) 
     401        { 
     402                return $nestedSetPeerClassname::getDescendants(\$this, false, \$con); 
     403        } 
     404"; 
     405        } 
     406 
     407        protected function addIsRoot(&$script) 
     408        { 
     409                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     410                $script .= " 
     411        /** 
     412         * Determines if the node is the root node 
     413         * 
     414         * @return bool 
     415         */ 
     416        public function isRoot() 
     417        { 
     418                return $nestedSetPeerClassname::isRoot(\$this); 
     419        } 
     420"; 
     421        } 
     422 
     423        protected function addIsLeaf(&$script) 
     424        { 
     425                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     426                $script .= " 
     427        /** 
     428         * Determines if the node is a leaf node 
     429         * 
     430         * @return bool 
     431         */ 
     432        public function isLeaf() 
     433        { 
     434                return $nestedSetPeerClassname::isLeaf(\$this); 
     435        } 
     436"; 
     437        } 
     438 
     439        protected function addHasChildren(&$script) 
     440        { 
     441                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     442                $script .= " 
     443        /** 
     444         * Determines if the node has children / descendants 
     445         * 
     446         * @return bool 
     447         */ 
     448        public function hasChildren() 
     449        { 
     450                return  $nestedSetPeerClassname::hasChildren(\$this); 
     451        } 
     452"; 
     453        } 
     454 
     455        protected function addHasPrevSibling(&$script) 
     456        { 
     457                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     458                $script .= " 
     459        /** 
     460         * Determines if the node has previous sibling 
     461         * 
     462         * @return bool 
     463         */ 
     464        public function hasPrevSibling(\$con = null) 
     465        { 
     466                if(!\$this->hasPrevSibling) { 
     467                        \$this->hasPrevSibling = $nestedSetPeerClassname::hasPrevSibling(\$this, \$con); 
     468                } 
     469                return \$this->hasPrevSibling; 
     470        } 
     471"; 
     472        } 
     473 
     474        protected function addHasNextSibling(&$script) 
     475        { 
     476                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     477                $script .= " 
     478        /** 
     479         * Determines if the node has next sibling 
     480         * 
     481         * @return bool 
     482         */ 
     483        public function hasNextSibling(\$con = null) 
     484        { 
     485                if(!\$this->hasNextSibling) { 
     486                        \$this->hasNextSibling = $nestedSetPeerClassname::hasNextSibling(\$this, \$con); 
     487                } 
     488                return \$this->hasNextSibling; 
     489        } 
     490"; 
     491        } 
     492         
     493        protected function addInsertAsFirstChildOf(&$script) 
     494        { 
     495                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     496                $script .= " 
     497        /** 
     498         * Inserts as first child of destination node \$dest 
     499         * 
     500         * @param object \$dest Propel object for destination node 
     501         * @return object               Inserted propel object for model 
     502         */ 
     503        public function insertAsFirstChildOf(\$dest, \$con = null) 
     504        { 
     505            return $nestedSetPeerClassname::insertAsFirstChildOf(\$dest, \$this, \$con = null); 
     506        } 
     507"; 
     508        } 
     509 
     510        protected function addInsertAsLastChildOf(&$script) 
     511        { 
     512                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     513                $script .= " 
     514        /** 
     515         * Inserts as last child of destination node \$dest 
     516         * 
     517         * @param object \$dest Propel object for destination node 
     518         * @return object               Inserted propel object for model 
     519         */ 
     520        public function insertAsLastChildOf(\$dest, \$con = null) 
     521        { 
     522            return $nestedSetPeerClassname::insertAsLastChildOf(\$dest, \$this, \$con = null); 
     523        } 
     524"; 
     525        } 
     526 
     527        protected function addInsertAsPrevSiblingOf(&$script) 
     528        { 
     529                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     530                $script .= " 
     531        /** 
     532         * Inserts \$node as previous sibling to destination node \$dest 
     533         * 
     534         * @param object \$dest Propel object for destination node 
     535         * @return object               Inserted propel object for model 
     536         */ 
     537        public function insertAsPrevSiblingOf(\$dest, \$con = null) 
     538        { 
     539            return $nestedSetPeerClassname::insertAsPrevSiblingOf(\$dest, \$this, \$con = null); 
     540        } 
     541"; 
     542        } 
     543 
     544        protected function addInsertAsNextSiblingOf(&$script) 
     545        { 
     546                $nestedSetPeerClassname = $this->getStubNestedSetPeerBuilder()->getClassname(); 
     547                $script .= " 
     548        /** 
     549         * Inserts \$node as next sibling to destination node \$dest 
     550         * 
     551         * @param object \$dest Propel object for destination node 
     552         * @return object               Inserted propel object for model 
     553         */ 
     554        public function insertAsNextSiblingOf(\$dest, \$con = null) 
     555        { 
     556            return $nestedSetPeerClassname::insertAsNextSiblingOf(\$dest, \$this, \$con = null); 
     557        } 
     558"; 
     559        } 
     560 
     561} // PHP5NodeObjectBuilder 
  • generator/classes/propel/engine/builder/om/php5/PHP5NestedSetPeerBuilder.php

     
     1<?php 
     2 
     3/* 
     4 *  $Id: PHP5BasicObjectBuilder.php 157 2005-08-10 19:16:22Z hans $ 
     5 * 
     6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     17 * 
     18 * This software consists of voluntary contributions made by many individuals 
     19 * and is licensed under the LGPL. For more information please see 
     20 * <http://propel.phpdb.org>. 
     21 */ 
     22 
     23require_once 'propel/engine/builder/om/PeerBuilder.php'; 
     24 
     25/** 
     26 * Generates a PHP5 tree nested set Peer class for user object model (OM). 
     27 *  
     28 * This class produces the base tree nested set object class (e.g. BaseMyTable) which contains all 
     29 * the custom-built accessor and setter methods. 
     30 *  
     31 * This class replaces the Node.tpl, with the intent of being easier for users 
     32 * to customize (through extending & overriding). 
     33 *  
     34 * @author heltem <heltem@o2php.com> 
     35 * @package propel.engine.builder.om.php5 
     36 */ 
     37class PHP5NestedSetPeerBuilder extends PeerBuilder { 
     38         
     39        /** 
     40         * Gets the package for the [base] object classes. 
     41         * @return string 
     42         */ 
     43        public function getPackage() 
     44        { 
     45                return parent::getPackage() . ".om"; 
     46        } 
     47         
     48        /** 
     49         * Returns the name of the current class being built. 
     50         * @return string 
     51         */ 
     52        public function getClassname() 
     53        { 
     54                return $this->getBuildProperty('basePrefix') . $this->getStubNestedSetPeerBuilder()->getClassname(); 
     55        } 
     56         
     57        /** 
     58         * Adds the include() statements for files that this class depends on or utilizes. 
     59         * @param string &$script The script will be modified in this method. 
     60         */ 
     61        protected function addIncludes(&$script) 
     62        { 
     63                $script .= " 
     64require_once '".$this->getStubObjectBuilder()->getClassFilePath()."'; 
     65require_once '".$this->getStubPeerBuilder()->getClassFilePath()."'; 
     66"; 
     67        } // addIncludes() 
     68         
     69        /** 
     70         * Adds class phpdoc comment and openning of class. 
     71         * @param string &$script The script will be modified in this method. 
     72         */ 
     73        protected function addClassOpen(&$script) 
     74        { 
     75                 
     76                $table = $this->getTable(); 
     77                $tableName = $table->getName(); 
     78                $tableDesc = $table->getDescription(); 
     79                 
     80                $script .= " 
     81/** 
     82 * Base  static class for performing query operations on the nested set contained by the '$tableName' table. 
     83 * 
     84 * $tableDesc 
     85 *"; 
     86                if ($this->getBuildProperty('addTimeStamp')) { 
     87                        $now = strftime('%c'); 
     88                        $script .= " 
     89 * This class was autogenerated by Propel on: 
     90 * 
     91 * $now 
     92 *"; 
     93                } 
     94                $script .= " 
     95 * @package ".$this->getPackage()." 
     96 */      
     97abstract class ".$this->getClassname()." extends ".$this->getStubPeerBuilder()->getClassName()." { 
     98"; 
     99        } 
     100         
     101        /** 
     102         * Specifies the methods that are added as part of the basic OM class. 
     103         * This can be overridden by subclasses that wish to add more methods. 
     104         * @see ObjectBuilder::addClassBody() 
     105         */ 
     106        protected function addClassBody(&$script) 
     107        { 
     108                $table = $this->getTable(); 
     109                 
     110                // FIXME 
     111                // - Probably the build needs to be customized for supporting 
     112                // tables that are "aliases".  -- definitely a fringe usecase, though. 
     113                                                 
     114                $this->addConstants($script); 
     115                 
     116                $this->addCreateRoot($script); 
     117                 
     118                $this->addRetrieveRoot($script); 
     119 
     120                $this->addInsertAsFirstChildOf($script); 
     121                $this->addInsertAsLastChildOf($script); 
     122                $this->addInsertAsPrevSiblingOf($script); 
     123                $this->addInsertAsNextSiblingOf($script); 
     124 
     125                $this->addInsertRoot($script); 
     126                $this->addInsertParent($script); 
     127 
     128                $this->addDeleteRoot($script); 
     129                $this->addDeleteNode($script); 
     130 
     131                $this->addMoveToFirstChildOf($script); 
     132                $this->addMoveToLastChildOf($script); 
     133                $this->addMoveToPrevSiblingOf($script); 
     134                $this->addMoveToNextSiblingOf($script); 
     135                 
     136                $this->addRetrieveFirstChild($script); 
     137                $this->addRetrieveLastChild($script); 
     138                $this->addRetrievePrevSibling($script); 
     139                $this->addRetrieveNextSibling($script); 
     140 
     141                $this->addRetrieveTree($script); 
     142                $this->addRetrieveBranch($script); 
     143                $this->addRetrieveChildren($script); 
     144                $this->addRetrieveDescendants($script); 
     145                $this->addRetrieveSiblings($script); 
     146                $this->addRetrieveParent($script); 
     147                $this->addRetrieveUndefined($script); 
     148 
     149                $this->addHydrateDescendants($script); 
     150                $this->addHydrateChildren($script); 
     151                 
     152                $this->addLevelGetter($script); 
     153                $this->addNumberOfChildrenGetter($script); 
     154                $this->addNumberOfDescendantsGetter($script); 
     155                $this->addPathGetter($script); 
     156 
     157                $this->addIsValid($script); 
     158                $this->addIsRoot($script); 
     159                $this->addIsLeaf($script); 
     160                $this->addIsChildOf($script); 
     161                $this->addIsChildOfOrSiblingTo($script); 
     162                $this->addIsEqualTo($script); 
     163                 
     164                $this->addHasParent($script); 
     165                $this->addHasPrevSibling($script); 
     166                $this->addHasNextSibling($script); 
     167                $this->addHasChildren($script); 
     168 
     169                $this->addDeleteDescendants($script); 
     170                 
     171                $this->addInsertNode($script); 
     172                $this->addUpdateNode($script); 
     173                 
     174                $this->addShiftRLValues($script); 
     175                $this->addShiftRLRange($script); 
     176                 
     177                $this->AddNodeGetter($script); 
     178        } 
     179                 
     180        /** 
     181         * Closes class. 
     182         * @param string &$script The script will be modified in this method. 
     183         */      
     184        protected function addClassClose(&$script) 
     185        { 
     186                $script .= " 
     187} // " . $this->getClassname() . " 
     188"; 
     189        } 
     190         
     191        protected function addConstants(&$script) 
     192        { 
     193                $table = $this->getTable(); 
     194                $tableName = $table->getName(); 
     195                $dbName = $this->getDatabase()->getName(); 
     196 
     197                $left_colname = ''; 
     198                $right_colname = ''; 
     199 
     200                foreach ($table->getColumns() as $col) { 
     201                        if ($col->isNestedSetLeftKey()) { 
     202                                $left_colname = $tableName . '.' . strtoupper($col->getName()); 
     203                        } 
     204 
     205                        if ($col->isNestedSetRightKey()) { 
     206                                $right_colname = $tableName . '.' . strtoupper($col->getName()); 
     207                        } 
     208 
     209                        if(!empty($right_name) && !empty($left_colname)) { 
     210                            break; 
     211                        } 
     212                } 
     213                $script .= " 
     214        /** the default database name for this class */ 
     215        const DATABASE_NAME = '$dbName'; 
     216 
     217        /** the table name for this class */ 
     218        const TABLE_NAME = '$tableName'; 
     219 
     220        /** the left column for the set */ 
     221        const LEFT_COL = '$left_colname'; 
     222 
     223        /** the right column for the set */ 
     224        const RIGHT_COL = '$right_colname'; 
     225"; 
     226        } 
     227         
     228        protected function addCreateRoot(&$script) 
     229        { 
     230                $script .= " 
     231        /** 
     232         * Creates the supplied node as the root node. 
     233         * 
     234         * @param string \$node Propel object for model 
     235         * @return object               Inserted propel object for model 
     236         */ 
     237        static function createRoot(\$node, \$con = null) 
     238        { 
     239                \$newLeft = 1; 
     240                \$newRight = 2; 
     241                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     242        } 
     243"; 
     244        } 
     245         
     246        protected function addRetrieveRoot(&$script) 
     247        { 
     248                $script .= " 
     249        /** 
     250         * Returns the root node for a given root id 
     251         * 
     252         * @param int \$rootId          Root id to determine which root node to return 
     253         * @return object                       Propel object for root node 
     254         */ 
     255        static function retrieveRoot(\$con = null) 
     256        { 
     257                \$c = new Criteria(); 
     258                \$c->add(self::LEFT_COL, 1, Criteria::EQUAL); 
     259 
     260                return self::doSelect(\$c, 'doSelectOne', \$con); 
     261        } 
     262"; 
     263        } 
     264 
     265        protected function addInsertAsFirstChildOf(&$script) 
     266        { 
     267                $script .= " 
     268        /** 
     269         * Inserts \$node as first child of destination node \$dest 
     270         * 
     271         * @param object \$dest Propel object for destination node 
     272         * @param object \$node Propel object for source node 
     273         * @return object               Inserted propel object for model 
     274         */ 
     275        static function insertAsFirstChildOf(\$dest, \$node, \$con = null) 
     276        { 
     277                \$dest = self::getNode(\$dest, \$con); 
     278 
     279                \$newLeft = \$dest->getLeftValue() + 1; 
     280                \$newRight = \$dest->getLeftValue() + 2; 
     281                self::shiftRLValues(\$newLeft, 2, \$con); 
     282                \$dest->setRightValue(\$dest->getRightValue() + 2); 
     283                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     284        } 
     285"; 
     286        } 
     287 
     288        protected function addInsertAsLastChildOf(&$script) 
     289        { 
     290                $script .= " 
     291        /** 
     292         * Inserts \$node as last child of destination node \$dest 
     293         * 
     294         * @param object \$dest Propel object for destination node 
     295         * @param object \$node Propel object for source node 
     296         * @return object               Inserted propel object for model 
     297         */ 
     298        static function insertAsLastChildOf(\$dest, \$node, \$con = null) 
     299        { 
     300                if (!\$dest = self::getNode(\$dest, \$con)) { 
     301                        return false; 
     302                } 
     303 
     304                \$newLeft = \$dest->getRightValue(); 
     305                \$newRight = \$dest->getRightValue() + 1; 
     306                self::shiftRLValues(\$newLeft, 2, \$con); 
     307                \$dest->setRightValue(\$dest->getRightValue() + 2); 
     308                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     309        } 
     310"; 
     311        } 
     312 
     313        protected function addInsertAsPrevSiblingOf(&$script) 
     314        { 
     315                $script .= " 
     316        /** 
     317         * Inserts \$node as previous sibling to destination node \$dest 
     318         * 
     319         * @param object \$dest Propel object for destination node 
     320         * @param object \$node Propel object for source node 
     321         * @return object               Inserted propel object for model 
     322         */ 
     323        static function insertAsPrevSiblingOf(\$dest, \$node, \$con = null) 
     324        { 
     325                \$dest = self::getNode(\$dest, \$con); 
     326 
     327                \$newLeft = \$dest->getLeftValue(); 
     328                \$newRight = \$dest->getLeftValue() + 1; 
     329                self::shiftRLValues(\$newLeft, 2, \$con); 
     330                \$dest->setLeftValue(\$dest->getLeftValue() + 2); 
     331                \$dest->setRightValue(\$dest->getRightValue() + 2); 
     332                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     333        } 
     334"; 
     335        } 
     336 
     337        protected function addInsertAsNextSiblingOf(&$script) 
     338        { 
     339                $script .= " 
     340        /** 
     341         * Inserts \$node as next sibling to destination node \$dest 
     342         * 
     343         * @param object \$dest Propel object for destination node 
     344         * @param object \$node Propel object for source node 
     345         * @return object               Inserted propel object for model 
     346         */ 
     347        static function insertAsNextSiblingOf(\$dest, \$node, \$con = null) 
     348        { 
     349                \$dest = self::getNode(\$dest, \$con); 
     350 
     351                \$newLeft = \$dest->getRightValue() + 1; 
     352                \$newRight = \$dest->getRightValue() + 2; 
     353                self::shiftRLValues(\$newLeft, 2, \$con); 
     354                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     355        } 
     356"; 
     357        } 
     358 
     359        protected function addInsertRoot(&$script) 
     360        { 
     361                $script .= " 
     362        static function insertRoot(\$node, \$con = null) 
     363        { 
     364                return self::insertParent(self::retrieveRoot(\$con), \$node, \$con = null); 
     365        } 
     366"; 
     367        } 
     368 
     369        protected function addInsertParent(&$script) 
     370        { 
     371                $script .= " 
     372        static function insertParent(\$dest, \$node, \$con = null) 
     373        { 
     374                \$dest = self::getNode(\$dest, \$con); 
     375 
     376                self::shiftRLValues(\$dest->getLeftValue(), 1, \$con); 
     377                self::shiftRLValues(\$dest->getRightValue() + 2, 1, \$con); 
     378 
     379                \$newLeft = \$dest->getLeftValue(); 
     380                \$newRight = \$dest->getRightValue() + 2; 
     381                return self::insertNode(\$node, \$newLeft, \$newRight, \$con); 
     382        } 
     383"; 
     384        } 
     385         
     386        protected function addDeleteRoot(&$script) 
     387        { 
     388                $script .= " 
     389        static function deleteRoot(\$con = null) 
     390        { 
     391                \$root = self::retrieveRoot(\$con); 
     392                if (self::getNumberOfChildren(\$root) == 1) { 
     393                        return self::deleteNode(\$root, \$con); 
     394                } else { 
     395                        return false; 
     396                } 
     397        } 
     398"; 
     399        } 
     400 
     401        protected function addDeleteNode(&$script) 
     402        { 
     403                $script .= " 
     404        static function deleteNode(\$dest, \$con = null) 
     405        { 
     406                if (\$dest->getLeftValue() == 1) { 
     407                        return self::deleteRoot(\$con); // deleting root implies conditions (see deleteRoot() method) 
     408                } 
     409 
     410                \$dest = self::getNode(\$dest, \$con); 
     411 
     412                self::shiftRLRange(\$dest->getLeftValue(), \$dest->getRightValue(), -1, \$con); 
     413                self::shiftRLValues(\$dest->getRightValue() + 1, -2, \$con); 
     414                return \$dest->delete(false, \$con); 
     415        } 
     416"; 
     417        } 
     418 
     419        protected function addMoveToFirstChildOf(&$script) 
     420        { 
     421                $script .= " 
     422        /** 
     423         * Moves \$node to be first child of \$destNode 
     424         * 
     425         * @param object \$destNode     Propel object for destination node 
     426         * @param object \$node         Propel object for source node 
     427         */ 
     428        static function moveToFirstChildOf(\$dest, \$node, \$con = null) 
     429        { 
     430                \$dest = self::getNode(\$dest); 
     431 
     432                \$destLeft = \$dest->getLeftValue(); 
     433                \$destLeft = \$destLeft + 1; 
     434                self::updateNode(\$node, \$destLeft, \$con); 
     435        } 
     436"; 
     437        } 
     438         
     439        protected function addMoveToLastChildOf(&$script) 
     440        { 
     441                $script .= " 
     442        /** 
     443         * Moves \$node to be last child of \$destNode 
     444         * 
     445         * @param object \$destNode     Propel object for destination node 
     446         * @param object \$node         Propel object for source node 
     447         */ 
     448        static function moveToLastChildOf(\$dest, \$node, \$con = null) 
     449        { 
     450                \$dest = self::getNode(\$dest, \$con); 
     451 
     452                \$destLeft = \$dest->getRightValue(); 
     453                self::updateNode(\$node, \$destLeft, \$con); 
     454        } 
     455"; 
     456        } 
     457 
     458        protected function addMoveToPrevSiblingOf(&$script) 
     459        { 
     460                $script .= " 
     461        /** 
     462         * Moves \$node to be prev sibling to \$destNode 
     463         * 
     464         * @param object \$destNode     Propel object for destination node 
     465         * @param object \$node         Propel object for source node 
     466         */ 
     467        static function moveToPrevSiblingOf(\$dest, \$node, \$con = null) 
     468        { 
     469                \$dest = self::getNode(\$dest, \$con); 
     470 
     471                \$destLeft = \$dest->getLeftValue(); 
     472                self::updateNode(\$node, \$destLeft, \$con); 
     473        } 
     474"; 
     475        } 
     476 
     477        protected function addMoveToNextSiblingOf(&$script) 
     478        { 
     479                $script .= " 
     480        /** 
     481         * Moves \$node to be next sibling to \$destNode 
     482         * 
     483         * @param object \$destNode     Propel object for destination node 
     484         * @param object \$node         Propel object for source node 
     485         */ 
     486        static function moveToNextSiblingOf(\$dest, \$node, \$con = null) 
     487        { 
     488                \$dest = self::getNode(\$dest, \$con); 
     489 
     490                \$destLeft = \$dest->getRightValue(); 
     491                \$destLeft = \$destLeft + 1; 
     492                self::updateNode(\$node, \$destLeft, \$con); 
     493        } 
     494"; 
     495        } 
     496 
     497        protected function addRetrieveFirstChild(&$script) 
     498        { 
     499                $script .= " 
     500        /** 
     501         * Gets first child for the given node if it exists 
     502         * 
     503         * @param object \$node Propel object for src node 
     504         * @return mixed                Propel object if exists else false 
     505         */ 
     506        static function retrieveFirstChild(\$node, \$selectMethod = 'doSelectOne', \$con = null) 
     507        { 
     508                \$node = self::getNode(\$node, \$con); 
     509 
     510                \$c = new Criteria(); 
     511                \$c->add(self::LEFT_COL, \$node->getLeftValue() + 1, Criteria::EQUAL); 
     512 
     513                return self::doSelect(\$c, \$selectMethod, \$con); 
     514        } 
     515"; 
     516        } 
     517 
     518        protected function addRetrieveLastChild(&$script) 
     519        { 
     520                $script .= " 
     521        /** 
     522         * Gets last child for the given node if it exists 
     523         * 
     524         * @param object \$node Propel object for src node 
     525         * @return mixed                Propel object if exists else false 
     526         */ 
     527        static function retrieveLastChild(\$node, \$selectMethod = 'doSelectOne', \$con = null) 
     528        { 
     529                \$node = self::getNode(\$node, \$con); 
     530 
     531                \$c = new Criteria(); 
     532                \$c->add(self::RIGHT_COL, \$node->getRightValue() - 1, Criteria::EQUAL); 
     533 
     534                return self::doSelect(\$c, \$selectMethod, \$con); 
     535        } 
     536"; 
     537        } 
     538 
     539        protected function addRetrievePrevSibling(&$script) 
     540        { 
     541                $script .= " 
     542        /** 
     543         * Gets prev sibling for the given node if it exists 
     544         * 
     545         * @param object \$node Propel object for src node 
     546         * @return mixed                Propel object if exists else false 
     547         */ 
     548        static function retrievePrevSibling(\$node, \$selectMethod = 'doSelectOne', \$con = null) 
     549        { 
     550                \$node = self::getNode(\$node, \$con); 
     551 
     552                \$c = new Criteria(); 
     553                \$c->add(self::RIGHT_COL, \$node->getLeftValue() - 1, Criteria::EQUAL); 
     554 
     555                \$result = self::doSelect(\$c, \$selectMethod, \$con); 
     556 
     557                return \$result; 
     558        } 
     559"; 
     560        } 
     561 
     562        protected function addRetrieveNextSibling(&$script) 
     563        { 
     564                $script .= " 
     565        /** 
     566         * Gets next sibling for the given node if it exists 
     567         * 
     568         * @param object \$node Propel object for src node 
     569         * @return mixed                Propel object if exists else false 
     570         */ 
     571        static function retrieveNextSibling(\$node, \$selectMethod = 'doSelectOne', \$con = null) 
     572        { 
     573                \$node = self::getNode(\$node, \$con); 
     574 
     575                \$c = new Criteria(); 
     576                \$c->add(self::LEFT_COL, \$node->getRightValue() + 1, Criteria::EQUAL); 
     577 
     578                return self::doSelect(\$c, \$selectMethod, \$con); 
     579        } 
     580"; 
     581        } 
     582 
     583        protected function addRetrieveTree(&$script) 
     584        { 
     585                $objName = $this->getStubObjectBuilder()->getClassname(); 
     586                $script .= " 
     587        /** 
     588         * Retrieves the entire tree from root 
     589         * 
     590         */ 
     591        static function retrieveTree(\$selectMethod = 'doSelectRS', \$con = null) 
     592        { 
     593                \$c = new Criteria(); 
     594                \$c->addAscendingOrderByColumn(self::LEFT_COL); 
     595                \$rs = self::doSelect(\$c, \$selectMethod, \$con); 
     596 
     597                \$root = new $objName(); 
     598                \$rs->next(); 
     599                \$root->hydrate(\$rs); 
     600                \$root->setLevel(0); 
     601 
     602                self::hydrateDescendants(\$root, \$rs); 
     603 
     604                return \$root; 
     605        } 
     606"; 
     607        } 
     608 
     609        protected function addRetrieveBranch(&$script) 
     610        { 
     611                $script .= " 
     612        /** 
     613         * Retrieves the entire tree from root 
     614         * 
     615         */ 
     616        static function retrieveBranch(\$node, \$selectMethod = 'doSelectRS', \$con = null) 
     617        { 
     618                return self::retrieveDescendants(\$node, \$selectMethod, \$con); 
     619        } 
     620"; 
     621        } 
     622 
     623        protected function addRetrieveChildren(&$script) 
     624        { 
     625                $script .= " 
     626        /** 
     627         * Gets direct children for the node 
     628         * 
     629         */ 
     630        static function retrieveChildren(\$node, \$selectMethod = 'doSelectRS', \$con = null) 
     631        { 
     632                if (is_array(\$node->_children)) { 
     633                        return \$node->_children; 
     634                } 
     635 
     636                \$c = new Criteria(); 
     637                \$c->addAscendingOrderByColumn(self::LEFT_COL); 
     638                \$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN); 
     639                \$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN); 
     640                \$rs = self::doSelect(\$c, \$selectMethod, \$con); 
     641 
     642                self::hydrateChildren(\$node, \$rs); 
     643                return \$node->_children; 
     644        } 
     645"; 
     646        } 
     647 
     648        protected function addRetrieveDescendants(&$script) 
     649        { 
     650                $script .= " 
     651        /** 
     652         * Gets all descendants for the node 
     653         * 
     654         */ 
     655        static function retrieveDescendants(\$node, \$selectMethod = 'doSelectRS', \$con = null) 
     656        { 
     657                if (is_array(\$node->_children)) 
     658                return \$node->_children; 
     659 
     660                \$c = new Criteria(); 
     661                \$c->addAscendingOrderByColumn(self::LEFT_COL); 
     662                \$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN); 
     663                \$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN); 
     664                \$rs = self::doSelect(\$c, \$selectMethod, \$con); 
     665 
     666                self::hydrateDescendants(\$node, \$rs); 
     667                return \$node->_children; 
     668        } 
     669"; 
     670        } 
     671 
     672        protected function addRetrieveSiblings(&$script) 
     673        { 
     674                $script .= " 
     675        /** 
     676         * Gets all siblings for the node 
     677         * 
     678         */ 
     679        static function retrieveSiblings(\$node, \$selectMethod = 'doSelectRS', \$con = null) 
     680        { 
     681                \$parent = self::retrieveParent(\$node, \$con); 
     682                \$siblings = self::retrieveChildren(\$parent, \$con); 
     683 
     684                return \$siblings; 
     685        } 
     686"; 
     687        } 
     688 
     689        protected function addRetrieveParent(&$script) 
     690        { 
     691                $script .= " 
     692        /** 
     693         * Gets ancestor for the given node if it exists 
     694         * 
     695         * @param object \$node Propel object for src node 
     696         * @return mixed                Propel object if exists else false 
     697         */ 
     698        static function retrieveParent(\$node, \$con = null) 
     699        { 
     700                \$node = self::getNode(\$node); 
     701 
     702                \$c = new Criteria(); 
     703                \$c1 = \$c->getNewCriterion(self::LEFT_COL, \$node->getLeftValue(), Criteria::LESS_THAN); 
     704                \$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$node->getRightValue(), Criteria::GREATER_THAN); 
     705 
     706                \$c1->addAnd(\$c2); 
     707 
     708                \$c->add(\$c1); 
     709                \$c->addAscendingOrderByColumn(self::RIGHT_COL); 
     710 
     711                \$results = self::doSelect(\$c, 'doSelect', \$con); 
     712 
     713                return array_shift(\$results); 
     714        } 
     715"; 
     716        } 
     717 
     718        protected function addRetrieveUndefined(&$script) 
     719        { 
     720                $script .= " 
     721        /** 
     722         * Gets ancestor for the given node if it exists 
     723         * 
     724         * @param object \$node Propel object for src node 
     725         * @return mixed                Propel object if exists else false 
     726         */ 
     727        static function retrieveUndefined(\$con = null) 
     728        { 
     729                \$c = new Criteria(); 
     730                \$c1 = \$c->getNewCriterion(self::LEFT_COL, 0); 
     731                \$c2 = \$c->getNewCriterion(self::RIGHT_COL, 0); 
     732 
     733                \$c1->addAnd(\$c2); 
     734 
     735                \$c->add(\$c1); 
     736 
     737                \$results = self::doSelect(\$c, 'doSelect', \$con); 
     738 
     739                return \$results; 
     740        } 
     741"; 
     742        } 
     743 
     744        protected function addHydrateDescendants(&$script) 
     745        { 
     746                $objName = $this->getStubObjectBuilder()->getClassname(); 
     747                $script .= " 
     748        /** 
     749         * Hydrate recursively the descendants of the given node 
     750         * @param object \$node Propel object for src node 
     751         * @param object \$rs   Propel ResultSet 
     752         */ 
     753        static function hydrateDescendants(\$node, \$rs) 
     754        { 
     755                \$node->_children = array(); 
     756                while(\$rs->next()) { 
     757                        \$child = new $objName(); 
     758                        \$child->hydrate(\$rs); 
     759                        \$child->setLevel(\$node->getLevel() + 1); 
     760 
     761                        if (\$child->hasChildren()) { 
     762                                self::hydrateDescendants(\$child, \$rs); 
     763                        } 
     764 
     765                        \$node->_children[] = \$child; 
     766 
     767                        if (\$child->getRightValue() + 1 == \$node->getRightValue()) { 
     768                                break; 
     769                        } 
     770                } 
     771        } 
     772"; 
     773        } 
     774 
     775        protected function addHydrateChildren(&$script) 
     776        { 
     777                $objName = $this->getStubObjectBuilder()->getClassname(); 
     778                $script .= " 
     779        /** 
     780         * Hydrate the children of the given node 
     781         * @param object \$node Propel object for src node 
     782         * @param object \$rs Propel ResultSet 
     783         */ 
     784        static function hydrateChildren(\$node, \$rs) 
     785        { 
     786                \$node->_children = array(); 
     787                while(\$rs->next()) { 
     788                        \$child = new $objName(); 
     789                        \$child->hydrate(\$rs); 
     790                        \$child->setLevel(\$node->getLevel() + 1); 
     791 
     792                        \$node->_children[] = \$child; 
     793 
     794                        if (\$child->getRightValue() + 1 == \$node->getRightValue()) { 
     795                                break; 
     796                        } 
     797                } 
     798        } 
     799"; 
     800        } 
     801 
     802        protected function addLevelGetter(&$script) 
     803        { 
     804                $script .= " 
     805        /** 
     806         * Gets level for the given node 
     807         * 
     808         * @param object \$node Propel object for src node 
     809         * @return int                  Level for the given node 
     810         */ 
     811        static function getLevel(\$node, \$con = null) 
     812        { 
     813                \$node = self::getNode(\$node, \$con); 
     814 
     815                if (\$con === null) { 
     816                        \$con = Propel::getConnection(); 
     817                } 
     818                \$stmt = \$con->createStatement(); 
     819                \$sql = \"SELECT COUNT(*) AS level FROM \".self::TABLE_NAME .\" WHERE \".self::LEFT_COL.\"<\".\$node->getLeftValue().\" AND \".self::RIGHT_COL.\">\".\$node->getRightValue(); 
     820                \$rs = \$stmt->executeQuery(\$sql); 
     821                \$rs->next(); 
     822                return \$rs->getInt(\"level\"); 
     823        } 
     824"; 
     825        } 
     826 
     827        protected function addNumberOfChildrenGetter(&$script) 
     828        { 
     829                $script .= " 
     830        /** 
     831         * Gets number of direct children for given node 
     832         * 
     833         * @param object \$node Propel object for src node 
     834         * @return int                  Level for the given node 
     835         */ 
     836        static function getNumberOfChildren(\$node, \$con = null) 
     837        { 
     838                \$children = self::retrieveChildren(\$node); 
     839                return count(\$children); 
     840        } 
     841"; 
     842        } 
     843 
     844        protected function addNumberOfDescendantsGetter(&$script) 
     845        { 
     846                $script .= " 
     847        /** 
     848         * Gets number of descendants for given node 
     849         * 
     850         * @param object \$node Propel object for src node 
     851         * @return int                  Level for the given node 
     852         */ 
     853        static function getNumberOfDescendants(\$node, \$con = null) 
     854        { 
     855                \$node = self::getNode(\$node, \$con); 
     856 
     857                \$right = \$node->getRightValue(\$node); 
     858                \$left = \$node->getLeftValue(\$node); 
     859                \$num = (\$right - \$left - 1) / 2; 
     860                return \$num; 
     861        } 
     862"; 
     863        } 
     864 
     865        protected function addPathGetter(&$script) 
     866        { 
     867                $script .= " 
     868        /** 
     869         * Returns path to a specific node as an array, useful to create breadcrumbs 
     870         * 
     871         * @param object \$node         Propel object of node to create path to 
     872         * @return array                        Array in order of heirarchy 
     873         */ 
     874        static function getPath(\$node, \$con = null) { 
     875 
     876                \$node = self::getNode(\$node, \$con); 
     877 
     878                \$path = array(); 
     879                \$path[] = \$node; 
     880 
     881                while(\$parent = self::retrieveParent(\$node, \$con)) 
     882                { 
     883                        \$path[] = \$parent; 
     884                        \$node = \$parent; 
     885                } 
     886 
     887                return array_reverse(\$path); 
     888        } 
     889"; 
     890        } 
     891 
     892        protected function addIsValid(&$script) 
     893        { 
     894                $script .= " 
     895        /** 
     896         * Tests if node is valid 
     897         * 
     898         * @param object \$node Propel object for src node 
     899         * @return bool 
     900         */ 
     901        static function isValid(\$node, \$con = null) 
     902        { 
     903                \$node = self::getNode(\$node, \$con); 
     904                if (is_object(\$node) && \$node->getRightValue() > \$node->getLeftValue()) { 
     905                        return true; 
     906                } else { 
     907                        return false; 
     908                } 
     909        } 
     910"; 
     911        } 
     912 
     913        protected function addIsRoot(&$script) 
     914        { 
     915                $script .= " 
     916        /** 
     917         * Tests if node is a root 
     918         * 
     919         * @param object \$node Propel object for src node 
     920         * @return bool 
     921         */ 
     922        static function isRoot(\$node, \$con = null) 
     923        { 
     924                \$node = self::getNode(\$node, \$con); 
     925                return (\$node->getLeftValue()==1); 
     926        } 
     927"; 
     928        } 
     929 
     930        protected function addisLeaf(&$script) 
     931        { 
     932                $script .= " 
     933        /** 
     934         * Tests if node is a leaf 
     935         * 
     936         * @param object \$node Propel object for src node 
     937         * @return bool 
     938         */ 
     939        static function isLeaf(\$node, \$con = null) 
     940        { 
     941                \$node = self::getNode(\$node, \$con); 
     942                return ((\$node->getRightValue()-\$node->getLeftValue())==1); 
     943        } 
     944"; 
     945        } 
     946 
     947        protected function addisChildOf(&$script) 
     948        { 
     949                $script .= " 
     950        /** 
     951         * Tests if \$node1 is a child of \$node2 
     952         * 
     953         * @param object \$node1                Propel object for node 
     954         * @param object \$node2                Propel object for node 
     955         * @return bool 
     956         */ 
     957        static function isChildOf(\$node2, \$node1, \$con = null) 
     958        { 
     959                \$node1 = self::getNode(\$node1, \$con); 
     960                \$node2 = self::getNode(\$node2, \$con); 
     961 
     962                return ((\$node1->getLeftValue()>\$node2->getLeftValue()) and (\$node1->getRightValue()<\$node2->getRightValue())); 
     963        } 
     964"; 
     965        } 
     966 
     967        protected function addIsChildOfOrSiblingTo(&$script) 
     968        { 
     969                $script .= " 
     970        /** 
     971         * Tests if \$node1 is a child of or equal to \$node2 
     972         * 
     973         * @param object \$node1                Propel object for node 
     974         * @param object \$node2                Propel object for node 
     975         * @return bool 
     976         */ 
     977        static function isChildOfOrSiblingTo(\$node2, \$node1, \$con = null) 
     978        { 
     979                \$node1 = self::getNode(\$node1, \$con); 
     980                \$node2 = self::getNode(\$node2, \$con); 
     981 
     982                return ((\$node1->getLeftValue()>=\$node2->getLeftValue()) and (\$node1->getRightValue()<=\$node2->getRightValue())); 
     983        } 
     984"; 
     985        } 
     986 
     987        protected function addIsEqualTo(&$script) 
     988        { 
     989                $script .= " 
     990        /** 
     991         * Tests if \$node1 is equal to \$node2 
     992         * 
     993         * @param object \$node1                Propel object for node 
     994         * @param object \$node2                Propel object for node 
     995         * @return bool 
     996         */ 
     997        static function isEqualTo(\$node1, \$node2, \$con = null) 
     998        { 
     999                \$node1 = self::getNode(\$node1, \$con); 
     1000                \$node2 = self::getNode(\$node2, \$con); 
     1001 
     1002                return ((\$node1->getLeftValue() == \$node2->getLeftValue()) and (\$node1->getRightValue() == \$node2->getRightValue())); 
     1003        } 
     1004"; 
     1005        } 
     1006 
     1007        protected function addHasParent(&$script) 
     1008        { 
     1009                $script .= " 
     1010        /** 
     1011         * Tests if \$node has an ancestor 
     1012         * 
     1013         * @param object \$node         Propel object for node 
     1014         * @return bool 
     1015         */ 
     1016        static function hasParent(\$node, \$con = null) 
     1017        { 
     1018                \$node = self::getNode(\$node, \$con); 
     1019                return self::isValid(self::retrieveParent(\$node, \$con), \$con); 
     1020        } 
     1021"; 
     1022        } 
     1023 
     1024        protected function addHasPrevSibling(&$script) 
     1025        { 
     1026                $script .= " 
     1027        /** 
     1028         * Tests if \$node has prev sibling 
     1029         * 
     1030         * @param object \$node         Propel object for node 
     1031         * @return bool 
     1032         */ 
     1033        static function hasPrevSibling(\$node, \$con = null) 
     1034        { 
     1035                \$node = self::getNode(\$node, \$con); 
     1036                return self::isValid(self::retrievePrevSibling(\$node, \$con), \$con); 
     1037        } 
     1038"; 
     1039        } 
     1040 
     1041        protected function addHasNextSibling(&$script) 
     1042        { 
     1043                $script .= " 
     1044        /** 
     1045         * Tests if \$node has next sibling 
     1046         * 
     1047         * @param object \$node         Propel object for node 
     1048         * @return bool 
     1049         */ 
     1050        static function hasNextSibling(\$node, \$con = null) 
     1051        { 
     1052                \$node = self::getNode(\$node, \$con); 
     1053                return self::isValid(self::retrieveNextSibling(\$node, \$con), \$con); 
     1054        } 
     1055"; 
     1056        } 
     1057 
     1058        protected function addHasChildren(&$script) 
     1059        { 
     1060                $script .= " 
     1061        /** 
     1062         * Tests if \$node has children 
     1063         * 
     1064         * @param object \$node         Propel object for node 
     1065         * @return bool 
     1066         */ 
     1067        static function hasChildren(\$node, \$con = null) 
     1068        { 
     1069                \$node = self::getNode(\$node, \$con); 
     1070                return ((\$node->getRightValue()-\$node->getLeftValue())>1); 
     1071        } 
     1072"; 
     1073        } 
     1074 
     1075        protected function addDeleteDescendants(&$script) 
     1076        { 
     1077                $script .= " 
     1078        /** 
     1079         * Deletes \$node and all of its descendants 
     1080         * 
     1081         * @param object \$node         Propel object for source node 
     1082         */ 
     1083        static function deleteDescendants(\$left, \$right, \$con = null) 
     1084        { 
     1085                /*\$sql = \"DELETE FROM \" .self::TABLE_NAME. \" WHERE \" .self::LEFT_COL. \">\".\$left.\" AND \".self::RIGHT_COL.\"<\".\$right; 
     1086                \$stmt = Propel::getConnection()->createStatement(); 
     1087                \$result = \$stmt->executeQuery(\$sql, ResultSet::FETCHMODE_ASSOC);*/ 
     1088 
     1089                \$c = new Criteria(); 
     1090                \$c1 = \$c->getNewCriterion(self::LEFT_COL, \$left, Criteria::GREATER_THAN); 
     1091                \$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$right, Criteria::LESS_THAN); 
     1092 
     1093                \$c1->addAnd(\$c2); 
     1094 
     1095                \$c->add(\$c1); 
     1096                \$c->addAscendingOrderByColumn(self::RIGHT_COL); 
     1097 
     1098                \$result = self::doDelete(\$c, \$con); 
     1099 
     1100                self::shiftRLValues(\$right + 1, \$left - \$right -1, \$con); 
     1101 
     1102                return \$result; 
     1103        } 
     1104"; 
     1105        } 
     1106 
     1107        protected function addInsertNode(&$script) 
     1108        { 
     1109                $script .= " 
     1110        /** 
     1111         * Inserts a node with given Left and Right values and to the appropriate root 
     1112         * 
     1113         * @param object \$node         Propel object for model 
     1114         * @param int \$left                    Left Value 
     1115         * @param int \$right           Right Value 
     1116         * @param int \$right           Root Id 
     1117         * @return object                       Inserted propel object for model 
     1118         */ 
     1119        private static function insertNode(\$node, \$left, \$right, \$con = null) 
     1120        { 
     1121                if (!is_object(\$node)) { 
     1122                        return false; 
     1123                } 
     1124 
     1125                \$node->setLeftValue(\$left); 
     1126                \$node->setRightValue(\$right); 
     1127                \$node->save(\$con); 
     1128                return \$node; 
     1129        } 
     1130"; 
     1131        } 
     1132 
     1133        protected function addUpdateNode(&$script) 
     1134        { 
     1135                $script .= " 
     1136        /** 
     1137         * Move \$node and its children to location \$dest and updates rest of tree 
     1138         * 
     1139         * @param object Propel object for node to update 
     1140         * @param int    Destination left value 
     1141         */ 
     1142        private static function updateNode(\$node, \$destLeft, \$con = null) 
     1143        { 
     1144                if (!is_object(\$node)) { 
     1145                        return false; 
     1146                } 
     1147 
     1148                \$left = \$node->getLeftValue(); 
     1149                \$right = \$node->getRightValue(); 
     1150 
     1151                \$treeSize = \$right - \$left +1; 
     1152 
     1153                self::shiftRLValues(\$destLeft, \$treeSize, \$con); 
     1154 
     1155                if (\$left >= \$destLeft) { // src was shifted too? 
     1156                        \$left += \$treeSize; 
     1157                        \$right += \$treeSize; 
     1158                } 
     1159 
     1160                // now there's enough room next to target to move the subtree 
     1161                \$newPos = self::shiftRLRange(\$left, \$right, \$destLeft - \$left, \$con); 
     1162                // correct values after source 
     1163 
     1164                self::shiftRLValues(\$right + 1, -\$treeSize, \$con); 
     1165 
     1166                // don't get what this if for? 
     1167                if (\$left <= \$destLeft) { // dst was shifted too? 
     1168                        \$newPos['left'] -= \$treeSize; 
     1169                        \$newPos['right'] -= \$treeSize; 
     1170                } 
     1171        } 
     1172"; 
     1173        } 
     1174 
     1175        protected function addShiftRLValues(&$script) 
     1176        { 
     1177                $script .= " 
     1178        /** 
     1179         * Adds '\$delta' to all L and R values that are >= '\$first'. '\$delta' can also be negative. 
     1180         * 
     1181         * @param int \$first           First node to be shifted 
     1182         * @param int \$delta           Value to be shifted by, can be negative 
     1183         */ 
     1184        private static function shiftRLValues(\$first, \$delta, \$con = null) 
     1185        { 
     1186                if (\$con === null) { 
     1187                        \$con = Propel::getConnection(); 
     1188                } 
     1189                // do that prepared thing so they must both execute to work 
     1190                // Shift left column values 
     1191                \$sql = \"UPDATE \" .self::TABLE_NAME. \" SET \" .self::LEFT_COL. \"=\".self::LEFT_COL.\"+\$delta WHERE \".self::LEFT_COL.\">=\$first\"; 
     1192                \$stmt = \$con->createStatement(); 
     1193                \$result = \$stmt->executeQuery(\$sql); 
     1194 
     1195                // Shift right column values 
     1196                \$sql = \"UPDATE \" .self::TABLE_NAME. \" SET \" .self::RIGHT_COL. \"=\".self::RIGHT_COL.\"+\$delta WHERE \".self::RIGHT_COL.\">=\$first\"; 
     1197                \$stmt = \$con->createStatement(); 
     1198                \$result = \$stmt->executeQuery(\$sql); 
     1199 
     1200        } 
     1201"; 
     1202        } 
     1203 
     1204        protected function addShiftRLRange(&$script) 
     1205        { 
     1206                $script .= " 
     1207        /** 
     1208         * Adds '\$delta' to all L and R values that are >= '\$first' and <= '\$last'. 
     1209         * '\$delta' can also be negative. 
     1210         * 
     1211         * @param int \$first   First node to be shifted (L value) 
     1212         * @param int \$last    Last node to be shifted (L value) 
     1213         * @param int \$delta           Value to be shifted by, can be negative 
     1214         * @return array                Shifted L and R values 
     1215         */ 
     1216        private static function shiftRLRange(\$first, \$last, \$delta, \$con = null) 
     1217        { 
     1218                if (\$con === null) { 
     1219                        \$con = Propel::getConnection(); 
     1220                } 
     1221                // do that prepared thing so they must both execute to work 
     1222                // Shift left column values 
     1223                \$sql = \"UPDATE \" .self::TABLE_NAME. \" SET \" .self::LEFT_COL. \"=\".self::LEFT_COL.\"+\$delta WHERE \".self::LEFT_COL.\">=\$first AND \".self::LEFT_COL.\"<=\$last\"; 
     1224                \$stmt = \$con->createStatement(); 
     1225                \$result = \$stmt->executeQuery(\$sql, ResultSet::FETCHMODE_ASSOC); 
     1226 
     1227                // Shift right column values 
     1228                \$sql = \"UPDATE \" .self::TABLE_NAME. \" SET \" .self::RIGHT_COL. \"=\".self::RIGHT_COL.\"+\$delta WHERE \".self::RIGHT_COL.\">=\$first AND \".self::RIGHT_COL.\"<=\$last\"; 
     1229                \$stmt = \$con->createStatement(); 
     1230                \$result = \$stmt->executeQuery(\$sql, ResultSet::FETCHMODE_ASSOC); 
     1231 
     1232                return array('left' => \$first + \$delta, 'right' => \$last + \$delta); 
     1233        } 
     1234"; 
     1235        } 
     1236 
     1237        protected function addNodeGetter(&$script) 
     1238        { 
     1239                $script .= " 
     1240        /** 
     1241         * Returns a node given its primary key or the node itself 
     1242         * 
     1243         * @param int \$nodeId  Primary key of required node 
     1244         * @return object               Propel object for model 
     1245         */ 
     1246        static function getNode(\$node, \$con = null) 
     1247        { 
     1248                if (is_object(\$node)) { 
     1249                        return \$node; 
     1250                } else { 
     1251                        \$object = self::retrieveByPK(\$node, \$con); 
     1252                        \$rtn = is_object(\$object) ? \$object : false; 
     1253                        return \$rtn; 
     1254                } 
     1255        } 
     1256"; 
     1257        } 
     1258 
     1259} // PHP5NodePeerBuilder 
  • generator/classes/propel/engine/database/model/Column.php

     
    7777        private $isPrimaryKey = false; 
    7878        private $isNodeKey = false; 
    7979        private $nodeKeySep; 
     80        private $isNestedSetLeftKey = false; 
     81        private $isNestedSetRightKey = false; 
    8082        private $isUnique = false; 
    8183        private $isAutoIncrement = false; 
    8284        private $isLazyLoad = false; 
     
    163165                        $this->isNodeKey = $this->booleanValue($this->getAttribute("nodeKey")); 
    164166                        $this->nodeKeySep = $this->getAttribute("nodeKeySep", "."); 
    165167 
     168                        $this->isNestedSetLeftKey = $this->booleanValue($this->getAttribute("nestedSetLeftKey")); 
     169                        $this->isNestedSetRightKey = $this->booleanValue($this->getAttribute("nestedSetRightKey")); 
     170 
    166171                        $this->isNotNull = $this->booleanValue($this->getAttribute("required"), false); 
    167172 
    168173                        // Regardless of above, if this column is a primary key then it can't be null. 
     
    473478        } 
    474479 
    475480        /** 
     481         * Set if the column is the nested set left key of a tree 
     482         */ 
     483        public function setNestedSetLeftKey($nslk) 
     484        { 
     485                $this->isNestedSetLeftKey = (boolean) $nslk; 
     486        } 
     487 
     488        /** 
     489         * Return true if the column is a nested set key of a tree 
     490         */ 
     491        public function isNestedSetLeftKey() 
     492        { 
     493                return $this->isNestedSetLeftKey; 
     494        } 
     495 
     496        /** 
     497         * Set if the column is the nested set right key of a tree 
     498         */ 
     499        public function setNestedSetRightKey($nsrk) 
     500        { 
     501                $this->isNestedSetRightKey = (boolean) $nsrk; 
     502        } 
     503 
     504        /** 
     505         * Return true if the column is a nested set right key of a tree 
     506         */ 
     507        public function isNestedSetRightKey() 
     508        { 
     509                return $this->isNestedSetRightKey; 
     510        } 
     511 
     512        /** 
    476513         * Set true if the column is UNIQUE 
    477514         */ 
    478515        public function setUnique($u) 
  • generator/classes/propel/engine/database/model/Table.php

     
    7878    private $needsTransactionInPostgres;//maybe this can be retrieved from vendorSpecificInfo? 
    7979    private $heavyIndexing; 
    8080    private $forReferenceOnly; 
    81     private $isTree; 
     81    private $treeMode; 
    8282 
    8383    /** 
    8484     * Constructs a table object with a name 
     
    125125                                && $this->getDatabase()->isHeavyIndexing() ) ); 
    126126        $this->description = $this->getAttribute("description"); 
    127127        $this->enterface = $this->getAttribute("interface"); // sic ('interface' is reserved word) 
    128         $this->isTree = $this->booleanValue($this->getAttribute("isTree")); 
     128        $this->treeMode = $this->getAttribute("treeMode"); 
    129129    } 
    130130 
    131131    /** 
     
    951951    } 
    952952 
    953953   /** 
    954      * Flag to determine if tree node class should be generated for this table. 
    955      * @return valur of isTree 
     954     * Flag to determine if tree class should be generated for this table. 
     955     * @return valur of treeMode 
    956956    */ 
    957    public function isTree() 
     957   public function treeMode() 
    958958   { 
    959         return $this->isTree; 
     959        return $this->treeMode; 
    960960   } 
    961961 
    962962    /** 
    963      * Flag to determine if tree node class should be generated for this table. 
    964      * @param v  Value to assign to isTree. 
     963     * Flag to determine if tree class should be generated for this table. 
     964     * @param v  Value to assign to treeMode. 
    965965     */ 
    966     public function setIsTree($v) 
     966    public function setTreeMode($v) 
    967967    { 
    968         $this->isTree = (boolean) $v; 
     968        $this->treeMode = $v; 
    969969    } 
    970970 
    971971    /** 
     
    10011001                  . '"'; 
    10021002        } 
    10031003 
    1004         if ($this->isTree) { 
    1005             $result .= " isTree=\"" 
    1006                   . ($this->isTree ? "true" : "false") 
     1004        if ($this->treeMode) { 
     1005            $result .= " treeMode=\"" 
     1006                  . $this->treeMode 
    10071007                  . '"'; 
    10081008        } 
    10091009 
  • generator/classes/propel/phing/PropelOMTask.php

     
    184184                                                // Create tree Node classes 
    185185                                                // ----------------------------------------------------------------------------------------- 
    186186                                                 
    187                                                 if ($table->isTree()) { 
    188                                                          
    189                                                         foreach(array('nodepeer', 'node') as $target) {                                                  
    190                                                                 $builder = DataModelBuilder::builderFactory($table, $target); 
    191                                                                 $this->build($builder);                                                  
     187                                                if ($table->treeMode()) { 
     188                                                    switch($table->treeMode()) { 
     189                                                                case "NestedSet": 
     190                                                                        foreach(array('nestedsetpeer', 'nestedset') as $target) { 
     191                                                                                $builder = DataModelBuilder::builderFactory($table, $target); 
     192                                                                                $this->build($builder); 
     193                                                                        } 
     194 
     195                                                                        foreach(array('nestedsetpeerstub', 'nestedsetstub') as $target) { 
     196                                                                                $builder = DataModelBuilder::builderFactory($table, $target); 
     197                                                                                $this->build($builder, $overwrite=false); 
     198                                                                        } 
     199                                                                break; 
     200 
     201                                                                case "Node": 
     202                                                                default: 
     203                                                                        foreach(array('nodepeer', 'node') as $target) { 
     204                                                                                $builder = DataModelBuilder::builderFactory($table, $target); 
     205                                                                                $this->build($builder); 
     206                                                                        } 
     207 
     208                                                                        foreach(array('nodepeerstub', 'nodestub') as $target) { 
     209                                                                                $builder = DataModelBuilder::builderFactory($table, $target); 
     210                                                                                $this->build($builder, $overwrite=false); 
     211                                                                        } 
     212                                                                break; 
    192213                                                        } 
    193                                                          
    194                                                         foreach(array('nodepeerstub', 'nodestub') as $target) { 
    195                                                                 $builder = DataModelBuilder::builderFactory($table, $target); 
    196                                                                 $this->build($builder, $overwrite=false);                                                        
    197                                                         } 
    198                                                          
    199                                                 } // if Table->isTree() 
     214 
     215                                                } // if Table->treeMode() 
    200216                                                 
    201217                                                 
    202218                                        } // if !$table->isForReferenceOnly()                                                                            
     
    209225 
    210226         
    211227        } // main() 
    212 } 
    213  No newline at end of file 
     228} 
  • generator/default.properties

     
    209209propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder 
    210210propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder 
    211211 
     212propel.builder.nestedset.class = propel.engine.builder.om.php5.PHP5NestedSetBuilder 
     213propel.builder.nestedsetpeer.class = propel.engine.builder.om.php5.PHP5NestedSetPeerBuilder 
     214propel.builder.nestedsetstub.class = propel.engine.builder.om.php5.PHP5ExtensionNestedSetBuilder 
     215propel.builder.nestedsetpeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNestedSetPeerBuilder 
     216 
    212217# SQL builders 
    213218 
    214219propel.builder.ddl.class = propel.engine.builder.sql.${propel.database}.${propel.database}DDLBuilder 
     
    216221 
    217222# Platform classes 
    218223 
    219 propel.platform.class = propel.engine.platform.${propel.database}Platform 
    220  No newline at end of file 
     224propel.platform.class = propel.engine.platform.${propel.database}Platform 
  • generator/resources/xsd/database.xsd

     
    142142                </xs:restriction> 
    143143        </xs:simpleType> 
    144144 
     145        <xs:simpleType name="treemode"> 
     146                <xs:restriction base="xs:string"> 
     147                        <xs:enumeration value="Node"/> 
     148                        <xs:enumeration value="NestedSet"/> 
     149                </xs:restriction> 
     150        </xs:simpleType> 
     151 
    145152        <!-- Restrict column name to letters (upper- and lowercase), numbers and the _ --> 
    146153        <xs:simpleType name="column_name"> 
    147154                <xs:restriction base="xs:string"> 
     
    284291                <xs:attribute name="lazyLoad" type="xs:boolean" default="false"/> 
    285292                <xs:attribute name="nodeKeySep" type="xs:string" use="optional"/> <!-- missing in the old DTD, but required to keep the treetest example working --> 
    286293                <xs:attribute name="nodeKey" type="xs:string" use="optional"/> <!-- missing in the old DTD, but required to keep the treetest example working --> 
     294                <xs:attribute name="nestedSetLeftKey" type="xs:boolean" default="false"/> <!-- missing in the old DTD, but required to keep the nested set example working --> 
     295                <xs:attribute name="nestedSetRightKey" type="xs:boolean" default="false"/> <!-- missing in the old DTD, but required to keep the nested set example working --> 
    287296                <xs:attribute name="require" type="xs:string" use="optional"/> 
    288297        </xs:complexType> 
    289298 
     
    326335                <xs:attribute name="phpNamingMethod" type="phpnamingmethod" use='optional'/> 
    327336                <xs:attribute name="heavyIndexing" type="xs:boolean" use="optional"/> 
    328337                <xs:attribute name="description" type="xs:string"/> 
    329                 <xs:attribute name="isTree" type="xs:boolean" use="optional"/> <!-- missing in the old DTD, but required to keep the treetest example working --> 
     338                <xs:attribute name="treeMode" type="treemode" use="optional"/> <!-- missing in the old DTD, but required to keep the treetest example working --> 
    330339        </xs:complexType> 
    331340 
    332341        <xs:complexType name="database"> 
     
    343352                <xs:attribute name="defaultPhpNamingMethod" type="phpnamingmethod" default="underscore"/> 
    344353                <xs:attribute name="heavyIndexing" type="xs:boolean" default="false"/> 
    345354        </xs:complexType> 
    346 </xs:schema> 
    347  No newline at end of file 
     355</xs:schema>