[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 // Template for creating base node Peer class on tree table. 4 // 5 // $Id: NodePeer.tpl,v 1.6 2004/11/24 13:09:52 kasparsj Exp $ 6 7 require_once 'propel/engine/builder/om/ClassTools.php'; 8 require_once 'propel/engine/builder/om/PeerBuilder.php'; 9 10 $npath_colname = ''; 11 $npath_phpname = ''; 12 $npath_len = 0; 13 $npath_sep = ''; 14 15 foreach ($table->getColumns() as $col) { 16 if ($col->isNodeKey()) { 17 $npath_colname = $table->getName() . '.' . strtoupper($col->getName()); 18 $npath_phpname = $col->getPhpName(); 19 $npath_len = $col->getSize(); 20 $npath_sep = $col->getNodeKeySep(); 21 break; 22 } 23 } 24 25 $db = $table->getDatabase(); 26 if($table->getPackage()) { 27 $package = $table->getPackage(); 28 } else { 29 $package = $targetPackage; 30 } 31 32 echo '<' . '?' . 'php'; 33 34 ?> 35 36 37 require_once '<?php echo ClassTools::getFilePath($package, $table->getPhpName()) ?>'; 38 require_once '<?php echo ClassTools::getFilePath($package, $table->getPhpName() . 'Node') ?>'; 39 40 41 /** 42 * Base static class for performing query operations on the tree contained by the 43 * '<?php echo $table->getPhpName() ?>' table. 44 * 45 <?php if ($addTimeStamp) { ?> 46 * This class was autogenerated by Propel on: 47 * 48 * [<?php echo $now ?>] 49 * 50 <?php } ?> 51 * @package <?php echo $package ?> 52 */ 53 class <?php echo $basePrefix . $table->getPhpName() ?>NodePeer 54 { 55 const NPATH_COLNAME = '<?php echo $npath_colname ?>'; 56 const NPATH_PHPNAME = '<?php echo $npath_phpname ?>'; 57 const NPATH_SEP = '<?php echo $npath_sep ?>'; 58 59 /** 60 * Temp function for CodeBase hacks that will go away. 61 */ 62 public static function isCodeBase($con = null) 63 { 64 if ($con === null) 65 $con = Propel::getConnection(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 66 67 return (get_class($con) == 'ODBCConnection' && 68 get_class($con->getAdapter()) == 'CodeBaseAdapter'); 69 } 70 71 /** 72 * Create a new Node at the top of tree. This method will destroy any 73 * existing root node (along with its children). 74 * 75 * Use at your own risk! 76 * 77 * @param <?php echo $table->getPhpName() ?> Object wrapped by new node. 78 * @param Connection Connection to use. 79 * @return <?php echo $table->getPhpName() ?>Node 80 * @throws PropelException 81 */ 82 public static function createNewRootNode($obj, $con = null) 83 { 84 if ($con === null) 85 $con = Propel::getConnection(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 86 87 try { 88 89 $con->begin(); 90 91 self::deleteNodeSubTree('1', $con); 92 93 $setNodePath = 'set' . self::NPATH_PHPNAME; 94 95 $obj->$setNodePath('1'); 96 $obj->save($con); 97 98 $con->commit(); 99 100 } catch (PropelException $e) { 101 $con->rollback(); 102 throw $e; 103 } 104 105 return new <?php echo $table->getPhpName() ?>Node($obj); 106 } 107 108 /** 109 * Inserts a new Node at the top of tree. Any existing root node (along with 110 * its children) will be made a child of the new root node. This is a 111 * safer alternative to createNewRootNode(). 112 * 113 * @param <?php echo $table->getPhpName() ?> Object wrapped by new node. 114 * @param Connection Connection to use. 115 * @return <?php echo $table->getPhpName() ?>Node 116 * @throws PropelException 117 */ 118 public static function insertNewRootNode($obj, $con = null) 119 { 120 if ($con === null) 121 $con = Propel::getConnection(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 122 123 try { 124 125 $con->begin(); 126 127 // Move root tree to an invalid node path. 128 self::moveNodeSubTree('1', '0', $con); 129 130 $setNodePath = 'set' . self::NPATH_PHPNAME; 131 132 // Insert the new root node. 133 $obj->$setNodePath('1'); 134 $obj->save($con); 135 136 // Move the old root tree as a child of the new root. 137 self::moveNodeSubTree('0', '1' . self::NPATH_SEP . '1', $con); 138 139 $con->commit(); 140 141 } catch (PropelException $e) { 142 $con->rollback(); 143 throw $e; 144 } 145 146 return new <?php echo $table->getPhpName() ?>Node($obj); 147 } 148 149 /** 150 * Retrieves an array of tree nodes based on specified criteria. Optionally 151 * includes all parent and/or child nodes of the matching nodes. 152 * 153 * @param Criteria Criteria to use. 154 * @param boolean True if ancestors should also be retrieved. 155 * @param boolean True if descendants should also be retrieved. 156 * @param Connection Connection to use. 157 * @return array Array of root nodes. 158 */ 159 public static function retrieveNodes($criteria, $ancestors = false, $descendants = false, $con = null) 160 { 161 $criteria = self::buildFamilyCriteria($criteria, $ancestors, $descendants); 162 $rs = <?php echo $table->getPhpName() ?>Peer::doSelectRS($criteria, $con); 163 return self::populateNodes($rs, $criteria); 164 } 165 166 /** 167 * Retrieves a tree node based on a primary key. Optionally includes all 168 * parent and/or child nodes of the matching node. 169 * 170 * @param mixed <?php echo $table->getPhpName() ?> primary key (array for composite keys) 171 * @param boolean True if ancestors should also be retrieved. 172 * @param boolean True if descendants should also be retrieved. 173 * @param Connection Connection to use. 174 * @return <?php echo $table->getPhpName() ?>Node 175 */ 176 public static function retrieveNodeByPK($pk, $ancestors = false, $descendants = false, $con = null) 177 { 178 throw new PropelException('retrieveNodeByPK() not implemented yet.'); 179 } 180 181 /** 182 * Retrieves a tree node based on a node path. Optionally includes all 183 * parent and/or child nodes of the matching node. 184 * 185 * @param string Node path to retrieve. 186 * @param boolean True if ancestors should also be retrieved. 187 * @param boolean True if descendants should also be retrieved. 188 * @param Connection Connection to use. 189 * @return <?php echo $table->getPhpName() ?>Node 190 */ 191 public static function retrieveNodeByNP($np, $ancestors = false, $descendants = false, $con = null) 192 { 193 $criteria = new Criteria(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 194 $criteria->add(self::NPATH_COLNAME, $np, Criteria::EQUAL); 195 $criteria = self::buildFamilyCriteria($criteria, $ancestors, $descendants); 196 $rs = <?php echo $table->getPhpName() ?>Peer::doSelectRS($criteria, $con); 197 $nodes = self::populateNodes($rs, $criteria); 198 return (count($nodes) == 1 ? $nodes[0] : null); 199 } 200 201 /** 202 * Retrieves the root node. 203 * 204 * @param string Node path to retrieve. 205 * @param boolean True if descendants should also be retrieved. 206 * @param Connection Connection to use. 207 * @return <?php echo $table->getPhpName() ?>Node 208 */ 209 public static function retrieveRootNode($descendants = false, $con = null) 210 { 211 return self::retrieveNodeByNP('1', false, $descendants, $con); 212 } 213 214 /** 215 * Moves the node subtree at srcpath to the dstpath. This method is intended 216 * for internal use by the BaseNode object. Note that it does not check for 217 * preexisting nodes at the dstpath. It also does not update the node path 218 * of any Node objects that might currently be in memory. 219 * 220 * Use at your own risk! 221 * 222 * @param string Source node path to move (root of the src subtree). 223 * @param string Destination node path to move to (root of the dst subtree). 224 * @param Connection Connection to use. 225 * @return void 226 * @throws PropelException 227 * @todo This is currently broken for simulated "onCascadeDelete"s. 228 * @todo Need to abstract the SQL better. The CONCAT sql function doesn't 229 * seem to be standardized (i.e. mssql), so maybe it needs to be moved 230 * to DBAdapter. 231 */ 232 public static function moveNodeSubTree($srcPath, $dstPath, $con = null) 233 { 234 if (substr($dstPath, 0, strlen($srcPath)) == $srcPath) 235 throw new PropelException('Cannot move a node subtree within itself.'); 236 237 if ($con === null) 238 $con = Propel::getConnection(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 239 240 /** 241 * Example: 242 * UPDATE table 243 * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74)) 244 * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' 245 */ 246 247 $npath = self::NPATH_COLNAME; 248 //the following dot isn`t mean`t a nodeKeySeperator 249 $setcol = substr($npath, strpos($npath, '.')+1); 250 $setcollen = <?php echo $npath_len ?>; 251 $db = Propel::getDb(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 252 253 // <hack> 254 if (<?php echo $table->getPhpName() ?>NodePeer::isCodeBase($con)) 255 { 256 // This is a hack to get CodeBase working. It will eventually be removed. 257 // It is a workaround for the following CodeBase bug: 258 // -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT) 259 $sql = "UPDATE " . <?php echo $table->getPhpName() ?>Peer::TABLE_NAME . " " . 260 "SET $setcol=" . $db->concatString("'$dstPath'", $db->subString($npath, strlen($srcPath)+1, $setcollen)) . " " . 261 "WHERE $npath = '$srcPath' OR $npath LIKE '" . $srcPath . self::NPATH_SEP . "%'"; 262 263 $con->executeUpdate($sql); 264 } 265 else 266 { 267 // </hack> 268 $sql = "UPDATE " . <?php echo $table->getPhpName() ?>Peer::TABLE_NAME . " " . 269 "SET $setcol=" . $db->concatString('?', $db->subString($npath, '?', '?')) . " " . 270 "WHERE $npath = ? OR $npath LIKE ?"; 271 272 $stmt = $con->prepareStatement($sql); 273 $stmt->setString(1, $dstPath); 274 $stmt->setInt(2, strlen($srcPath)+1); 275 $stmt->setInt(3, $setcollen); 276 $stmt->setString(4, $srcPath); 277 $stmt->setString(5, $srcPath . self::NPATH_SEP . '%'); 278 $stmt->executeUpdate(); 279 // <hack> 280 } 281 // </hack> 282 } 283 284 /** 285 * Deletes the node subtree at the specified node path from the database. 286 * 287 * @param string Node path to delete 288 * @param Connection Connection to use. 289 * @return void 290 * @throws PropelException 291 * @todo This is currently broken for simulated "onCascadeDelete"s. 292 */ 293 public static function deleteNodeSubTree($nodePath, $con = null) 294 { 295 if ($con === null) 296 $con = Propel::getConnection(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 297 298 /** 299 * DELETE FROM table 300 * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' 301 */ 302 303 $criteria = new Criteria(<?php echo $table->getPhpName() ?>Peer::DATABASE_NAME); 304 $criteria->add(self::NPATH_COLNAME, $nodePath, Criteria::EQUAL); 305 $criteria->addOr(self::NPATH_COLNAME, $nodePath . self::NPATH_SEP . '%', Criteria::LIKE); 306 // For now, we call BasePeer directly since <?php echo $table->getPhpName() ?>Peer tries to 307 // do a cascade delete. 308 // <?php echo $table->getPhpName() ?>Peer::doDelete($criteria, $con); 309 BasePeer::doDelete($criteria, $con); 310 } 311 312 /** 313 * Builds the criteria needed to retrieve node ancestors and/or descendants. 314 * 315 * @param Criteria Criteria to start with 316 * @param boolean True if ancestors should be retrieved. 317 * @param boolean True if descendants should be retrieved. 318 * @return Criteria 319 */ 320 public static function buildFamilyCriteria($criteria, $ancestors = false, $descendants = false) 321 { 322 /* 323 Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants: 324 325 SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH) 326 FROM test L, test 327 WHERE test.NPATH='1.2.3' AND 328 (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR 329 test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH))) 330 ORDER BY UCASE(L.NPATH) ASC 331 */ 332 333 if ($criteria === null) 334 $criteria = new Criteria(<?php echo $table->getPhpName() ?>::DATABASE_NAME); 335 336 if (!$criteria->getSelectColumns()) 337 <?php echo $table->getPhpName() ?>Peer::addSelectColumns($criteria); 338 339 $db = Propel::getDb($criteria->getDbName()); 340 341 if (($ancestors || $descendants) && $criteria->size()) 342 { 343 // If we are retrieving ancestors/descendants, we need to do a 344 // self-join to locate them. The exception to this is if no search 345 // criteria is specified. In this case we're retrieving all nodes 346 // anyway, so there is no need to do a self-join. 347 348 // The left-side of the self-join will contain the columns we'll 349 // use to build node objects (target node records along with their 350 // ancestors and/or descendants). The right-side of the join will 351 // contain the target node records specified by the initial criteria. 352 // These are used to match the appropriate ancestor/descendant on 353 // the left. 354 355 // Specify an alias for the left-side table to use. 356 $criteria->addAlias('L', <?php echo $table->getPhpName() ?>Peer::TABLE_NAME); 357 358 // Make sure we have select columns to begin with. 359 if (!$criteria->getSelectColumns()) 360 <?php echo $table->getPhpName() ?>Peer::addSelectColumns($criteria); 361 362 // Replace any existing columns for the right-side table with the 363 // left-side alias. 364 $selectColumns = $criteria->getSelectColumns(); 365 $criteria->clearSelectColumns(); 366 foreach ($selectColumns as $colName) 367 $criteria->addSelectColumn(str_replace(<?php echo $table->getPhpName() ?>Peer::TABLE_NAME, 'L', $colName)); 368 369 $a = null; 370 $d = null; 371 372 $npathL = <?php echo $table->getPhpName() ?>Peer::alias('L', self::NPATH_COLNAME); 373 $npathR = self::NPATH_COLNAME; 374 $npath_len = <?php echo $npath_len ?>; 375 376 if ($ancestors) 377 { 378 // For ancestors, match left-side node paths which are contained 379 // by right-side node paths. 380 $a = $criteria->getNewCriterion($npathL, 381 "$npathL=" . $db->subString($npathR, 1, $db->strLength($npathL), $npath_len), 382 Criteria::CUSTOM); 383 } 384 385 if ($descendants) 386 { 387 // For descendants, match left-side node paths which contain 388 // right-side node paths. 389 $d = $criteria->getNewCriterion($npathR, 390 "$npathR=" . $db->subString($npathL, 1, $db->strLength($npathR), $npath_len), 391 Criteria::CUSTOM); 392 } 393 394 if ($a) 395 { 396 if ($d) $a->addOr($d); 397 $criteria->addAnd($a); 398 } 399 else if ($d) 400 { 401 $criteria->addAnd($d); 402 } 403 404 // Add the target node path column. This is used by populateNodes(). 405 $criteria->addSelectColumn($npathR); 406 407 // Sort by node path to speed up tree construction in populateNodes() 408 $criteria->addAsColumn('npathlen', $db->strLength($npathL)); 409 $criteria->addAscendingOrderByColumn('npathlen'); 410 $criteria->addAscendingOrderByColumn($npathL); 411 } 412 else 413 { 414 // Add the target node path column. This is used by populateNodes(). 415 $criteria->addSelectColumn(self::NPATH_COLNAME); 416 417 // Sort by node path to speed up tree construction in populateNodes() 418 $criteria->addAsColumn('npathlen', $db->strLength(self::NPATH_COLNAME)); 419 $criteria->addAscendingOrderByColumn('npathlen'); 420 $criteria->addAscendingOrderByColumn(self::NPATH_COLNAME); 421 } 422 423 return $criteria; 424 } 425 426 /** 427 * This method reconstructs as much of the tree structure as possible from 428 * the given array of objects. Depending on how you execute your query, it 429 * is possible for the ResultSet to contain multiple tree fragments (i.e. 430 * subtrees). The array returned by this method will contain one entry 431 * for each subtree root node it finds. The remaining subtree nodes are 432 * accessible from the <?php echo $table->getPhpName() ?>Node methods of the 433 * subtree root nodes. 434 * 435 * @param array Array of <?php echo $table->getPhpName() ?>Node objects 436 * @return array Array of <?php echo $table->getPhpName() ?>Node objects 437 */ 438 public static function buildTree($nodes) 439 { 440 // Subtree root nodes to return 441 $rootNodes = array(); 442 443 // Build the tree relations 444 foreach ($nodes as $node) 445 { 446 $sep = strrpos($node->getNodePath(), self::NPATH_SEP); 447 $parentPath = ($sep !== false ? substr($node->getNodePath(), 0, $sep) : ''); 448 $parentNode = null; 449 450 // Scan other nodes for parent. 451 foreach ($nodes as $pnode) 452 { 453 if ($pnode->getNodePath() == $parentPath) 454 { 455 $parentNode = $pnode; 456 break; 457 } 458 } 459 460 // If parent was found, attach as child, otherwise its a subtree root 461 if ($parentNode) 462 $parentNode->attachChildNode($node); 463 else 464 $rootNodes[] = $node; 465 } 466 467 return $rootNodes; 468 } 469 470 /** 471 * Populates the <?php echo $table->getPhpName() ?> objects from the 472 * specified ResultSet, wraps them in <?php echo $table->getPhpName() ?>Node 473 * objects and build the appropriate node relationships. 474 * The array returned by this method will only include the initial targets 475 * of the query, even if ancestors/descendants were also requested. 476 * The ancestors/descendants will be cached in memory and are accessible via 477 * the getNode() methods. 478 * 479 * @param ResultSet 480 * @param Criteria 481 * @return array Array of <?php $table->getPhpName() ?>Node objects. 482 */ 483 public static function populateNodes($rs, $criteria) 484 { 485 $nodes = array(); 486 $targets = array(); 487 $targetfld = count($criteria->getSelectColumns()); 488 489 <?php if (!$table->getChildrenColumn()) { ?> 490 // set the class once to avoid overhead in the loop 491 $cls = Propel::import(<?php echo $table->getPhpName() ?>Peer::getOMClass()); 492 <?php } ?> 493 494 // populate the object(s) 495 while($rs->next()) 496 { 497 if (!isset($nodes[$rs->getString(1)])) 498 { 499 <?php if ($table->getChildrenColumn()) { ?> 500 // class must be set each time from the record row 501 $cls = Propel::import(<?php echo $table->getPhpName() ?>Peer::getOMClass($rs, 1)); 502 <?php } ?> 503 $obj = new $cls(); 504 $obj->hydrate($rs); 505 506 $nodes[$rs->getString(1)] = new <?php echo $table->getPhpName() ?>Node($obj); 507 } 508 509 $node = $nodes[$rs->getString(1)]; 510 511 if ($node->getNodePath() == $rs->getString($targetfld)) 512 $targets[$node->getNodePath()] = $node; 513 } 514 515 self::buildTree($nodes); 516 517 return array_values($targets); 518 } 519 520 } 521 522 ?>
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 |