[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/ -> PHP5NodePeerBuilder.php (source)

   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  
  23  require_once 'propel/engine/builder/om/PeerBuilder.php';
  24  
  25  /**
  26   * Generates a PHP5 tree node Peer class for user object model (OM).
  27   * 
  28   * This class produces the base tree node 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 Hans Lellelid <hans@xmpl.org>
  35   * @package propel.engine.builder.om.php5
  36   */
  37  class PHP5NodePeerBuilder 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->getStubNodePeerBuilder()->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 .= "
  64  require_once '".$this->getStubObjectBuilder()->getClassFilePath()."';
  65  require_once '".$this->getStubNodeBuilder()->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 tree 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   */    
  97  abstract class ".$this->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->addIsCodeBase($script);
 117                  
 118          $this->addRetrieveMethods($script);
 119          
 120          $this->addCreateNewRootNode($script);
 121          $this->addInsertNewRootNode($script);
 122          $this->addMoveNodeSubTree($script);
 123          $this->addDeleteNodeSubTree($script);
 124          
 125          $this->addBuildFamilyCriteria($script);
 126          $this->addBuildTree($script);
 127          
 128          $this->addPopulateNodes($script);
 129          
 130      }
 131          
 132      /**
 133       * Closes class.
 134       * @param string &$script The script will be modified in this method.
 135       */    
 136  	protected function addClassClose(&$script)
 137      {
 138          $script .= "
 139  } // " . $this->getClassname() . "
 140  ";
 141      }
 142      
 143  	protected function addConstants(&$script)
 144      {
 145          $table = $this->getTable();
 146          
 147          $npath_colname = '';
 148          $npath_phpname = '';
 149          $npath_len = 0;
 150          $npath_sep = '';
 151          foreach ($table->getColumns() as $col) {
 152              if ($col->isNodeKey()) {
 153                  $npath_colname = $table->getName() . '.' . strtoupper($col->getName());
 154                  $npath_phpname = $col->getPhpName();
 155                  $npath_len = $col->getSize();
 156                  $npath_sep = $col->getNodeKeySep();
 157                  break;
 158              }
 159          }
 160          $script .= "
 161      const NPATH_COLNAME = '$npath_colname';
 162      const NPATH_PHPNAME = '$npath_phpname';
 163      const NPATH_SEP        = '$npath_sep';
 164      const NPATH_LEN        = $npath_len;
 165  ";
 166      }
 167      
 168      
 169  	protected function addIsCodeBase(&$script)
 170      {
 171          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 172          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 173          
 174          $script .= "
 175      /** 
 176       * Temp function for CodeBase hacks that will go away.
 177       */
 178      public static function isCodeBase(\$con = null)
 179      {
 180          if (\$con === null)
 181              \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
 182              
 183          return (get_class(\$con) == 'ODBCConnection' && 
 184                  get_class(\$con->getAdapter()) == 'CodeBaseAdapter');
 185      }
 186  ";
 187      }
 188      
 189      
 190  	protected function addCreateNewRootNode(&$script)
 191      {
 192          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 193          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 194          
 195          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 196          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 197          
 198          $script .= "
 199      /**
 200       * Create a new Node at the top of tree. This method will destroy any 
 201       * existing root node (along with its children). 
 202       *
 203       * Use at your own risk!
 204       *
 205       * @param $objectClassname Object wrapped by new node.
 206       * @param Connection Connection to use.
 207       * @return $nodeObjectClassname
 208       * @throws PropelException
 209       */
 210      public static function createNewRootNode(\$obj, \$con = null)
 211      {
 212          if (\$con === null)
 213              \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
 214          
 215          try {
 216  
 217              \$con->begin();
 218  
 219              self::deleteNodeSubTree('1', \$con);
 220              
 221              \$setNodePath = 'set' . self::NPATH_PHPNAME;
 222  
 223              \$obj->\$setNodePath('1');
 224              \$obj->save(\$con);
 225  
 226              \$con->commit();
 227              
 228          } catch (PropelException \$e) {
 229              \$con->rollback();
 230              throw \$e;
 231          }            
 232  
 233          return new $nodeObjectClassname(\$obj);
 234      }
 235  ";
 236      }
 237      
 238  	protected function addInsertNewRootNode(&$script)
 239      {
 240          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 241          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 242          
 243          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 244          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 245          
 246          $script .= "
 247      /**
 248       * Inserts a new Node at the top of tree. Any existing root node (along with
 249       * its children) will be made a child of the new root node. This is a 
 250       * safer alternative to createNewRootNode().
 251       *
 252       * @param $objectClassname Object wrapped by new node.
 253       * @param Connection Connection to use.
 254       * @return $nodeObjectClassname
 255       * @throws PropelException
 256       */
 257      public static function insertNewRootNode(\$obj, \$con = null)
 258      {
 259          if (\$con === null)
 260              \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
 261          
 262          try {
 263              
 264              \$con->begin();
 265              
 266              // Move root tree to an invalid node path.
 267              $nodePeerClassname::moveNodeSubTree('1', '0', \$con);
 268  
 269              \$setNodePath = 'set' . self::NPATH_PHPNAME;
 270              
 271              // Insert the new root node.
 272              \$obj->\$setNodePath('1');
 273              \$obj->save(\$con);
 274  
 275              // Move the old root tree as a child of the new root.
 276              $nodePeerClassname::moveNodeSubTree('0', '1' . self::NPATH_SEP . '1', \$con);
 277              
 278              \$con->commit();
 279                          
 280          } catch (PropelException \$e) {
 281              \$con->rollback();
 282              throw \$e;
 283          }            
 284          
 285          return new $nodeObjectClassname(\$obj);
 286      }
 287  ";
 288      }
 289      
 290      /**
 291       * Adds the methods for retrieving nodes.
 292       */    
 293  	protected function addRetrieveMethods(&$script)
 294      {
 295          $this->addRetrieveNodes($script);
 296          $this->addRetrieveNodeByPK($script);
 297          $this->addRetrieveNodeByNP($script);
 298          $this->addRetrieveRootNode($script);
 299      
 300      }
 301      
 302  	protected function addRetrieveNodes(&$script)
 303      {
 304          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 305          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 306          
 307          $script .= "
 308      /**
 309       * Retrieves an array of tree nodes based on specified criteria. Optionally 
 310       * includes all parent and/or child nodes of the matching nodes.
 311       *
 312       * @param Criteria Criteria to use.
 313       * @param boolean True if ancestors should also be retrieved.
 314       * @param boolean True if descendants should also be retrieved.
 315       * @param Connection Connection to use.
 316       * @return array Array of root nodes.
 317       */
 318      public static function retrieveNodes(\$criteria, \$ancestors = false, \$descendants = false, \$con = null)
 319      {
 320          \$criteria = $nodePeerClassname::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants);
 321          \$rs = ".$this->getStubPeerBuilder()->getClassname()."::doSelectRS(\$criteria, \$con);
 322          return self::populateNodes(\$rs, \$criteria);
 323      }
 324  ";
 325      }
 326      
 327  	protected function addRetrieveNodeByPK(&$script)
 328      {
 329          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 330          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 331          
 332          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 333          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 334          
 335          $script .= "
 336      /**
 337       * Retrieves a tree node based on a primary key. Optionally includes all 
 338       * parent and/or child nodes of the matching node.
 339       *
 340       * @param mixed $objectClassname primary key (array for composite keys)
 341       * @param boolean True if ancestors should also be retrieved.
 342       * @param boolean True if descendants should also be retrieved.
 343       * @param Connection Connection to use.
 344       * @return $nodeObjectClassname
 345       */
 346      public static function retrieveNodeByPK(\$pk, \$ancestors = false, \$descendants = false, \$con = null)
 347      {
 348          throw new PropelException('retrieveNodeByPK() not implemented yet.');
 349      }
 350  ";
 351      }
 352      
 353  	protected function addRetrieveNodeByNP(&$script)
 354      {
 355          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 356          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 357          
 358          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 359          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 360          
 361          $script .= "
 362      /**
 363       * Retrieves a tree node based on a node path. Optionally includes all 
 364       * parent and/or child nodes of the matching node.
 365       *
 366       * @param string Node path to retrieve.
 367       * @param boolean True if ancestors should also be retrieved.
 368       * @param boolean True if descendants should also be retrieved.
 369       * @param Connection Connection to use.
 370       * @return $objectClassname
 371       */
 372      public static function retrieveNodeByNP(\$np, \$ancestors = false, \$descendants = false, \$con = null)
 373      {
 374          \$criteria = new Criteria($peerClassname::DATABASE_NAME);
 375          \$criteria->add(self::NPATH_COLNAME, \$np, Criteria::EQUAL);
 376          \$criteria = self::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants);
 377          \$rs = $peerClassname::doSelectRS(\$criteria, \$con);
 378          \$nodes = self::populateNodes(\$rs, \$criteria);
 379          return (count(\$nodes) == 1 ? \$nodes[0] : null);
 380      }
 381  ";
 382      }
 383      
 384  	protected function addRetrieveRootNode(&$script)
 385      {        
 386          $script .= "
 387      /**
 388       * Retrieves the root node.
 389       *
 390       * @param string Node path to retrieve.
 391       * @param boolean True if descendants should also be retrieved.
 392       * @param Connection Connection to use.
 393       * @return ".$this->getStubNodeBuilder()->getClassname()."
 394       */ 
 395      public static function retrieveRootNode(\$descendants = false, \$con = null)
 396      {
 397          return self::retrieveNodeByNP('1', false, \$descendants, \$con);
 398      }
 399  ";
 400      }
 401      
 402  	protected function addMoveNodeSubTree(&$script)
 403      {
 404          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 405          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 406          
 407          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 408          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 409  
 410          $script .= "
 411      /**
 412       * Moves the node subtree at srcpath to the dstpath. This method is intended
 413       * for internal use by the BaseNode object. Note that it does not check for 
 414       * preexisting nodes at the dstpath. It also does not update the  node path 
 415       * of any Node objects that might currently be in memory. 
 416       *
 417       * Use at your own risk!
 418       *
 419       * @param string Source node path to move (root of the src subtree).
 420       * @param string Destination node path to move to (root of the dst subtree).
 421       * @param Connection Connection to use.
 422       * @return void
 423       * @throws PropelException
 424       * @todo This is currently broken for simulated 'onCascadeDelete's. 
 425       * @todo Need to abstract the SQL better. The CONCAT sql function doesn't 
 426       *       seem to be standardized (i.e. mssql), so maybe it needs to be moved
 427       *       to DBAdapter.
 428       */    
 429      public static function moveNodeSubTree(\$srcPath, \$dstPath, \$con = null)
 430      {
 431          if (substr(\$dstPath, 0, strlen(\$srcPath)) == \$srcPath)
 432              throw new PropelException('Cannot move a node subtree within itself.');
 433      
 434          if (\$con === null)
 435              \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
 436  
 437          /**
 438           * Example:
 439           * UPDATE table 
 440           * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74)) 
 441           * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%'
 442           */
 443           
 444          \$npath = $nodePeerClassname::NPATH_COLNAME;
 445          //the following dot isn`t mean`t a nodeKeySeperator
 446          \$setcol = substr(\$npath, strpos(\$npath, '.')+1);
 447          \$setcollen = $nodePeerClassname::NPATH_LEN;
 448          \$db = Propel::getDb($peerClassname::DATABASE_NAME);
 449          
 450          // <hack> 
 451          if ($nodePeerClassname::isCodeBase(\$con))
 452          {
 453              // This is a hack to get CodeBase working. It will eventually be removed.
 454              // It is a workaround for the following CodeBase bug:
 455              //   -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT)
 456              \$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" .
 457                     \"SET \$setcol=\" . \$db->concatString(\"'\$dstPath'\", \$db->subString(\$npath, strlen(\$srcPath)+1, \$setcollen)) . \" \" . 
 458                     \"WHERE \$npath = '\$srcPath' OR \$npath LIKE '\" . \$srcPath . $nodePeerClassname::NPATH_SEP . \"%'\";
 459  
 460              \$con->executeUpdate(\$sql);
 461          }
 462          else
 463          {
 464          // </hack>
 465              \$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" .
 466                     \"SET \$setcol=\" . \$db->concatString('?', \$db->subString(\$npath, '?', '?')) . \" \" . 
 467                     \"WHERE \$npath = ? OR \$npath LIKE ?\";
 468  
 469              \$stmt = \$con->prepareStatement(\$sql);
 470              \$stmt->setString(1, \$dstPath);
 471              \$stmt->setInt(2, strlen(\$srcPath)+1);
 472              \$stmt->setInt(3, \$setcollen);
 473              \$stmt->setString(4, \$srcPath);
 474              \$stmt->setString(5, \$srcPath . $nodePeerClassname::NPATH_SEP . '%');
 475              \$stmt->executeUpdate();
 476          // <hack>
 477          }
 478          // </hack>
 479      }
 480  ";
 481      }
 482      
 483  	protected function addDeleteNodeSubTree(&$script)
 484      {
 485          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 486          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 487          
 488          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 489          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 490          
 491          $script .= "
 492      /**
 493       * Deletes the node subtree at the specified node path from the database.
 494       *
 495       * @param string Node path to delete
 496       * @param Connection Connection to use.
 497       * @return void
 498       * @throws PropelException
 499       * @todo This is currently broken for simulated 'onCascadeDelete's. 
 500       */
 501      public static function deleteNodeSubTree(\$nodePath, \$con = null)
 502      {
 503          if (\$con === null)
 504              \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
 505  
 506          /**
 507           * DELETE FROM table
 508           * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%'
 509           */
 510          
 511          \$criteria = new Criteria($peerClassname::DATABASE_NAME);
 512          \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$nodePath, Criteria::EQUAL);
 513          \$criteria->addOr($nodePeerClassname::NPATH_COLNAME, \$nodePath . self::NPATH_SEP . '%', Criteria::LIKE);
 514  // For now, we call BasePeer directly since $peerClassname tries to 
 515  // do a cascade delete.
 516  //          $peerClassname::doDelete(\$criteria, \$con);
 517          BasePeer::doDelete(\$criteria, \$con);
 518      }
 519  ";
 520      }
 521      
 522  	protected function addBuildFamilyCriteria(&$script)
 523      {
 524          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 525          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 526          
 527          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 528          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 529      
 530          $script .= "
 531      /** 
 532       * Builds the criteria needed to retrieve node ancestors and/or descendants.
 533       *
 534       * @param Criteria Criteria to start with
 535       * @param boolean True if ancestors should be retrieved.
 536       * @param boolean True if descendants should be retrieved.
 537       * @return Criteria
 538       */
 539      public static function buildFamilyCriteria(\$criteria, \$ancestors = false, \$descendants = false)
 540      {
 541          /*
 542              Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants:
 543              
 544              SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH) 
 545              FROM test L, test 
 546              WHERE test.NPATH='1.2.3' AND 
 547                   (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR 
 548                    test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH))) 
 549              ORDER BY UCASE(L.NPATH) ASC
 550          */
 551  
 552          if (\$criteria === null)
 553              \$criteria = new Criteria($peerClassname::DATABASE_NAME);
 554  
 555          if (!\$criteria->getSelectColumns())
 556              $peerClassname::addSelectColumns(\$criteria);
 557  
 558          \$db = Propel::getDb(\$criteria->getDbName());
 559  
 560          if ((\$ancestors || \$descendants) && \$criteria->size())
 561          {
 562              // If we are retrieving ancestors/descendants, we need to do a 
 563              // self-join to locate them. The exception to this is if no search
 564              // criteria is specified. In this case we're retrieving all nodes 
 565              // anyway, so there is no need to do a self-join. 
 566              
 567              // The left-side of the self-join will contain the columns we'll
 568              // use to build node objects (target node records along with their
 569              // ancestors and/or descendants). The right-side of the join will
 570              // contain the target node records specified by the initial criteria.
 571              // These are used to match the appropriate ancestor/descendant on
 572              // the left. 
 573  
 574              // Specify an alias for the left-side table to use.
 575              \$criteria->addAlias('L', $peerClassname::TABLE_NAME);
 576              
 577              // Make sure we have select columns to begin with.
 578              if (!\$criteria->getSelectColumns())
 579                  $peerClassname::addSelectColumns(\$criteria);
 580              
 581              // Replace any existing columns for the right-side table with the 
 582              // left-side alias.
 583              \$selectColumns = \$criteria->getSelectColumns();
 584              \$criteria->clearSelectColumns();
 585              foreach (\$selectColumns as \$colName)
 586                  \$criteria->addSelectColumn(str_replace($peerClassname::TABLE_NAME, 'L', \$colName));
 587  
 588              \$a = null;
 589              \$d = null;
 590              
 591              \$npathL = $peerClassname::alias('L', $nodePeerClassname::NPATH_COLNAME);
 592              \$npathR = $nodePeerClassname::NPATH_COLNAME;
 593              \$npath_len = $nodePeerClassname::NPATH_LEN;
 594              
 595              if (\$ancestors)
 596              {
 597                  // For ancestors, match left-side node paths which are contained 
 598                  // by right-side node paths.
 599                  \$a = \$criteria->getNewCriterion(\$npathL, 
 600                                                  \"\$npathL=\" . \$db->subString(\$npathR, 1, \$db->strLength(\$npathL), \$npath_len),
 601                                                  Criteria::CUSTOM);                                                        
 602              }
 603              
 604              if (\$descendants)
 605              {
 606                  // For descendants, match left-side node paths which contain 
 607                  // right-side node paths.
 608                  \$d = \$criteria->getNewCriterion(\$npathR,
 609                                                  \"\$npathR=\" . \$db->subString(\$npathL, 1, \$db->strLength(\$npathR), \$npath_len),
 610                                                  Criteria::CUSTOM);
 611              }
 612  
 613              if (\$a)
 614              {
 615                  if (\$d) \$a->addOr(\$d);
 616                  \$criteria->addAnd(\$a);
 617              }
 618              else if (\$d)
 619              {
 620                  \$criteria->addAnd(\$d);
 621              }
 622              
 623              // Add the target node path column. This is used by populateNodes().
 624              \$criteria->addSelectColumn(\$npathR);
 625              
 626              // Sort by node path to speed up tree construction in populateNodes()
 627              \$criteria->addAsColumn('npathlen', \$db->strLength(\$npathL));
 628              \$criteria->addAscendingOrderByColumn('npathlen');
 629              \$criteria->addAscendingOrderByColumn(\$npathL);
 630          }
 631          else
 632          {
 633              // Add the target node path column. This is used by populateNodes().
 634              \$criteria->addSelectColumn($nodePeerClassname::NPATH_COLNAME);
 635  
 636              // Sort by node path to speed up tree construction in populateNodes()
 637              \$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME));
 638              \$criteria->addAscendingOrderByColumn('npathlen');
 639              \$criteria->addAscendingOrderByColumn($nodePeerClassname::NPATH_COLNAME);
 640          }
 641          
 642          return \$criteria;
 643      }
 644  ";
 645      }
 646      
 647  	protected function addBuildTree(&$script)
 648      {
 649          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 650          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 651          
 652          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 653          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 654      
 655          $script .= "
 656      /**
 657       * This method reconstructs as much of the tree structure as possible from
 658       * the given array of objects. Depending on how you execute your query, it 
 659       * is possible for the ResultSet to contain multiple tree fragments (i.e.
 660       * subtrees). The array returned by this method will contain one entry
 661       * for each subtree root node it finds. The remaining subtree nodes are
 662       * accessible from the $nodeObjectClassname methods of the 
 663       * subtree root nodes.
 664       *
 665       * @param array Array of $nodeObjectClassname objects
 666       * @return array Array of $nodeObjectClassname objects
 667       */
 668      public static function buildTree(\$nodes)
 669      {
 670          // Subtree root nodes to return
 671          \$rootNodes = array();
 672  
 673          // Build the tree relations
 674          foreach (\$nodes as \$node)
 675          {
 676              \$sep = strrpos(\$node->getNodePath(), $nodePeerClassname::NPATH_SEP);
 677              \$parentPath = (\$sep !== false ? substr(\$node->getNodePath(), 0, \$sep) : '');
 678              \$parentNode = null;
 679  
 680              // Scan other nodes for parent.
 681              foreach (\$nodes as \$pnode)
 682              {
 683                  if (\$pnode->getNodePath() === \$parentPath)
 684                  {
 685                      \$parentNode = \$pnode;
 686                      break;
 687                  }
 688              }
 689  
 690              // If parent was found, attach as child, otherwise its a subtree root
 691              if (\$parentNode)
 692                  \$parentNode->attachChildNode(\$node);
 693              else
 694                  \$rootNodes[] = \$node;
 695          }
 696  
 697          return \$rootNodes;
 698      }
 699  ";
 700      }
 701      
 702  	protected function addPopulateNodes(&$script)
 703      {
 704          $table = $this->getTable();
 705          
 706          $peerClassname = $this->getStubPeerBuilder()->getClassname();
 707          $objectClassname = $this->getStubObjectBuilder()->getClassname();
 708          
 709          $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
 710          $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
 711      
 712          $script .= "
 713      /**
 714       * Populates the $objectClassname objects from the 
 715       * specified ResultSet, wraps them in $nodeObjectClassname
 716       * objects and build the appropriate node relationships.
 717       * The array returned by this method will only include the initial targets 
 718       * of the query, even if ancestors/descendants were also requested. 
 719       * The ancestors/descendants will be cached in memory and are accessible via
 720       * the getNode() methods. 
 721       *
 722       * @param ResultSet 
 723       * @param Criteria
 724       * @return array Array of $nodeObjectClassname objects.
 725       */
 726      public static function populateNodes(\$rs, \$criteria)
 727      {
 728          \$nodes = array();
 729          \$targets = array();
 730          \$targetfld = count(\$criteria->getSelectColumns());
 731  ";
 732  
 733          if (!$table->getChildrenColumn()) {
 734              $script .= "
 735          // set the class once to avoid overhead in the loop
 736          \$cls = Propel::import($peerClassname::getOMClass());
 737  ";
 738          }
 739          
 740          $script .= "
 741          // populate the object(s)
 742          while(\$rs->next()) 
 743          {
 744              if (!isset(\$nodes[\$rs->getString(1)]))
 745              {
 746  ";
 747          if ($table->getChildrenColumn()) {
 748              $script .= "
 749                  // class must be set each time from the record row
 750                  $cls = Propel::import($peerClassname::getOMClass($rs, 1));
 751  ";
 752          }
 753          
 754          $script .= "
 755                  \$obj = new \$cls();
 756                  \$obj->hydrate(\$rs);
 757  
 758                  \$nodes[\$rs->getString(1)] = new $nodeObjectClassname(\$obj);
 759              }
 760  
 761              \$node = \$nodes[\$rs->getString(1)];
 762              
 763              if (\$node->getNodePath() === \$rs->getString(\$targetfld))
 764                  \$targets[\$node->getNodePath()] = \$node;
 765          }
 766  
 767          $nodePeerClassname::buildTree(\$nodes);
 768          
 769          return array_values(\$targets);
 770      }
 771  ";
 772      }
 773      
 774  } // PHP5NodePeerBuilder


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7