[ Index ] |
|
Code source de Symfony 1.0.0 |
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
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |