PageRenderTime 31ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/generator/lib/builder/om/PHP5NestedSetPeerBuilder.php

https://github.com/1989gaurav/Propel
PHP | 1670 lines | 1053 code | 179 blank | 438 comment | 91 complexity | d248d149ce6a7ba09d2fa7b1f776d188 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/PeerBuilder.php';
  10. /**
  11. * Generates a PHP5 tree nested set Peer class for user object model (OM).
  12. *
  13. * This class produces the base tree nested set object class (e.g. BaseMyTable) which contains all
  14. * the custom-built accessor and setter methods.
  15. *
  16. * @author heltem <heltem@o2php.com>
  17. * @package propel.generator.builder.om
  18. */
  19. class PHP5NestedSetPeerBuilder extends PeerBuilder
  20. {
  21. /**
  22. * Gets the package for the [base] object classes.
  23. * @return string
  24. */
  25. public function getPackage()
  26. {
  27. return parent::getPackage() . ".om";
  28. }
  29. /**
  30. * Returns the name of the current class being built.
  31. * @return string
  32. */
  33. public function getUnprefixedClassname()
  34. {
  35. return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname() . 'NestedSetPeer';
  36. }
  37. /**
  38. * Adds the include() statements for files that this class depends on or utilizes.
  39. * @param string &$script The script will be modified in this method.
  40. */
  41. protected function addIncludes(&$script)
  42. {
  43. $script .="
  44. require '".$this->getPeerBuilder()->getClassFilePath()."';
  45. ";
  46. } // addIncludes()
  47. /**
  48. * Adds class phpdoc comment and openning of class.
  49. * @param string &$script The script will be modified in this method.
  50. */
  51. protected function addClassOpen(&$script)
  52. {
  53. $table = $this->getTable();
  54. $tableName = $table->getName();
  55. $tableDesc = $table->getDescription();
  56. $script .= "
  57. /**
  58. * Base static class for performing query operations on the tree contained by the '$tableName' table.
  59. *
  60. * $tableDesc
  61. *";
  62. if ($this->getBuildProperty('addTimeStamp')) {
  63. $now = strftime('%c');
  64. $script .= "
  65. * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
  66. *
  67. * $now
  68. *";
  69. }
  70. $script .= "
  71. * @deprecated Since Propel 1.5. Use the nested_set behavior instead of the NestedSet treeMode
  72. * @package propel.generator.".$this->getPackage()."
  73. */
  74. abstract class ".$this->getClassname()." extends ".$this->getPeerBuilder()->getClassName()." implements NodePeer {
  75. ";
  76. }
  77. /**
  78. * Specifies the methods that are added as part of the basic OM class.
  79. * This can be overridden by subclasses that wish to add more methods.
  80. * @see ObjectBuilder::addClassBody()
  81. */
  82. protected function addClassBody(&$script)
  83. {
  84. $table = $this->getTable();
  85. // FIXME
  86. // - Probably the build needs to be customized for supporting
  87. // tables that are "aliases". -- definitely a fringe usecase, though.
  88. $this->addConstants($script);
  89. $this->addCreateRoot($script);
  90. $this->addRetrieveRoot($script);
  91. $this->addInsertAsFirstChildOf($script);
  92. $this->addInsertAsLastChildOf($script);
  93. $this->addInsertAsPrevSiblingOf($script);
  94. $this->addInsertAsNextSiblingOf($script);
  95. $this->addInsertAsParentOf($script);
  96. $this->addInsertRoot($script);
  97. $this->addInsertParent($script);
  98. $this->addDeleteRoot($script);
  99. $this->addDeleteNode($script);
  100. $this->addMoveToFirstChildOf($script);
  101. $this->addMoveToLastChildOf($script);
  102. $this->addMoveToPrevSiblingOf($script);
  103. $this->addMoveToNextSiblingOf($script);
  104. $this->addRetrieveFirstChild($script);
  105. $this->addRetrieveLastChild($script);
  106. $this->addRetrievePrevSibling($script);
  107. $this->addRetrieveNextSibling($script);
  108. $this->addRetrieveTree($script);
  109. $this->addRetrieveBranch($script);
  110. $this->addRetrieveChildren($script);
  111. $this->addRetrieveDescendants($script);
  112. $this->addRetrieveSiblings($script);
  113. $this->addRetrieveParent($script);
  114. $this->addGetLevel($script);
  115. $this->addGetNumberOfChildren($script);
  116. $this->addGetNumberOfDescendants($script);
  117. $this->addGetPath($script);
  118. $this->addIsValid($script);
  119. $this->addIsRoot($script);
  120. $this->addIsLeaf($script);
  121. $this->addIsChildOf($script);
  122. $this->addIsChildOfOrSiblingTo($script);
  123. $this->addIsEqualTo($script);
  124. $this->addHasParent($script);
  125. $this->addHasPrevSibling($script);
  126. $this->addHasNextSibling($script);
  127. $this->addHasChildren($script);
  128. $this->addDeleteDescendants($script);
  129. $this->addGetNode($script);
  130. $this->addHydrateDescendants($script);
  131. $this->addHydrateChildren($script);
  132. $this->addShiftRParent($script);
  133. $this->addUpdateLoadedNode($script);
  134. $this->addUpdateDBNode($script);
  135. $this->addShiftRLValues($script);
  136. $this->addShiftRLRange($script);
  137. }
  138. /**
  139. * Closes class.
  140. * @param string &$script The script will be modified in this method.
  141. */
  142. protected function addClassClose(&$script)
  143. {
  144. $script .= "
  145. } // " . $this->getClassname() . "
  146. ";
  147. }
  148. protected function addConstants(&$script)
  149. {
  150. $table = $this->getTable();
  151. $tableName = $table->getName();
  152. $colname = array();
  153. foreach ($table->getColumns() as $col) {
  154. if ($col->isNestedSetLeftKey()) {
  155. $colname['left'] = $tableName . '.' . strtoupper($col->getName());
  156. }
  157. if ($col->isNestedSetRightKey()) {
  158. $colname['right'] = $tableName . '.' . strtoupper($col->getName());
  159. }
  160. if ($col->isTreeScopeKey()) {
  161. $colname['scope'] = $tableName . '.' . strtoupper($col->getName());
  162. }
  163. if (3 == count($colname)) {
  164. break;
  165. }
  166. }
  167. if(!isset($colname['left'])) {
  168. throw new EngineException("One column must have nestedSetLeftKey attribute set to true for [" . $table->getName() . "] table");
  169. }
  170. if(!isset($colname['right'])) {
  171. throw new EngineException("One column must have nestedSetRightKey attribute set to true for [" . $table->getName() . "] table");
  172. }
  173. $colname['scope'] = isset($colname['scope']) ? $colname['scope'] : null;
  174. $script .= "
  175. /**
  176. * Left column for the set
  177. */
  178. const LEFT_COL = " . var_export($colname['left'], true) . ";
  179. /**
  180. * Right column for the set
  181. */
  182. const RIGHT_COL = " . var_export($colname['right'], true) . ";
  183. /**
  184. * Scope column for the set
  185. */
  186. const SCOPE_COL = " . var_export($colname['scope'], true) . ";
  187. ";
  188. }
  189. protected function addCreateRoot(&$script)
  190. {
  191. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  192. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  193. $script .= "
  194. /**
  195. * Creates the supplied node as the root node.
  196. *
  197. * @param $objectClassname \$node Propel object for model
  198. * @throws PropelException
  199. */
  200. public static function createRoot(NodeObject \$node)
  201. {
  202. if (\$node->getLeftValue()) {
  203. throw new PropelException('Cannot turn an existing node into a root node.');
  204. }
  205. \$node->setLeftValue(1);
  206. \$node->setRightValue(2);
  207. }
  208. ";
  209. }
  210. protected function addRetrieveRoot(&$script)
  211. {
  212. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  213. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  214. $script .= "
  215. /**
  216. * Returns the root node for a given scope id
  217. *
  218. * @param int \$scopeId Scope id to determine which root node to return
  219. * @param PropelPDO \$con Connection to use.
  220. * @return $objectClassname Propel object for root node
  221. */
  222. public static function retrieveRoot(\$scopeId = null, PropelPDO \$con = null)
  223. {
  224. \$c = new Criteria($peerClassname::DATABASE_NAME);
  225. \$c->add(self::LEFT_COL, 1, Criteria::EQUAL);
  226. if (self::SCOPE_COL) {
  227. \$c->add(self::SCOPE_COL, \$scopeId, Criteria::EQUAL);
  228. }
  229. return $peerClassname::doSelectOne(\$c, \$con);
  230. }
  231. ";
  232. }
  233. protected function addInsertAsFirstChildOf(&$script)
  234. {
  235. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  236. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  237. $script .= "
  238. /**
  239. * Inserts \$child as first child of given \$parent node
  240. *
  241. * @param $objectClassname \$child Propel object for child node
  242. * @param $objectClassname \$parent Propel object for parent node
  243. * @param PropelPDO \$con Connection to use.
  244. * @return void
  245. */
  246. public static function insertAsFirstChildOf(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
  247. {
  248. // Update \$child node properties
  249. \$child->setLeftValue(\$parent->getLeftValue() + 1);
  250. \$child->setRightValue(\$parent->getLeftValue() + 2);
  251. \$child->setParentNode(\$parent);
  252. \$sidv = null;
  253. if (self::SCOPE_COL) {
  254. \$child->setScopeIdValue(\$sidv = \$parent->getScopeIdValue());
  255. }
  256. // Update database nodes
  257. self::shiftRLValues(\$child->getLeftValue(), 2, \$con, \$sidv);
  258. // Update all loaded nodes
  259. self::updateLoadedNode(\$parent, 2, \$con);
  260. }
  261. ";
  262. }
  263. protected function addInsertAsLastChildOf(&$script)
  264. {
  265. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  266. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  267. $script .= "
  268. /**
  269. * Inserts \$child as last child of destination node \$parent
  270. *
  271. * @param $objectClassname \$child Propel object for child node
  272. * @param $objectClassname \$parent Propel object for parent node
  273. * @param PropelPDO \$con Connection to use.
  274. * @return void
  275. */
  276. public static function insertAsLastChildOf(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
  277. {
  278. // Update \$child node properties
  279. \$child->setLeftValue(\$parent->getRightValue());
  280. \$child->setRightValue(\$parent->getRightValue() + 1);
  281. \$child->setParentNode(\$parent);
  282. \$sidv = null;
  283. if (self::SCOPE_COL) {
  284. \$child->setScopeIdValue(\$sidv = \$parent->getScopeIdValue());
  285. }
  286. // Update database nodes
  287. self::shiftRLValues(\$child->getLeftValue(), 2, \$con, \$sidv);
  288. // Update all loaded nodes
  289. self::updateLoadedNode(\$parent, 2, \$con);
  290. }
  291. ";
  292. }
  293. protected function addInsertAsPrevSiblingOf(&$script)
  294. {
  295. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  296. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  297. $script .= "
  298. /**
  299. * Inserts \$sibling as previous sibling to destination node \$node
  300. *
  301. * @param $objectClassname \$node Propel object for destination node
  302. * @param $objectClassname \$sibling Propel object for source node
  303. * @param PropelPDO \$con Connection to use.
  304. * @return void
  305. */
  306. public static function insertAsPrevSiblingOf(NodeObject \$node, NodeObject \$sibling, PropelPDO \$con = null)
  307. {
  308. if (\$sibling->isRoot()) {
  309. throw new PropelException('Root nodes cannot have siblings');
  310. }
  311. \$node->setLeftValue(\$sibling->getLeftValue());
  312. \$node->setRightValue(\$sibling->getLeftValue() + 1);
  313. \$node->setParentNode(\$sibling->retrieveParent());
  314. \$sidv = null;
  315. if (self::SCOPE_COL) {
  316. \$node->setScopeIdValue(\$sidv = \$sibling->getScopeIdValue());
  317. }
  318. // Update database nodes
  319. self::shiftRLValues(\$node->getLeftValue(), 2, \$con, \$sidv);
  320. // Update all loaded nodes
  321. self::updateLoadedNode(\$sibling->retrieveParent(), 2, \$con);
  322. }
  323. ";
  324. }
  325. protected function addInsertAsNextSiblingOf(&$script)
  326. {
  327. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  328. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  329. $script .= "
  330. /**
  331. * Inserts \$sibling as next sibling to destination node \$node
  332. *
  333. * @param $objectClassname \$node Propel object for destination node
  334. * @param $objectClassname \$sibling Propel object for source node
  335. * @param PropelPDO \$con Connection to use.
  336. * @return void
  337. */
  338. public static function insertAsNextSiblingOf(NodeObject \$node, NodeObject \$sibling, PropelPDO \$con = null)
  339. {
  340. if (\$sibling->isRoot()) {
  341. throw new PropelException('Root nodes cannot have siblings');
  342. }
  343. \$node->setLeftValue(\$sibling->getRightValue() + 1);
  344. \$node->setRightValue(\$sibling->getRightValue() + 2);
  345. \$node->setParentNode(\$sibling->retrieveParent());
  346. \$sidv = null;
  347. if (self::SCOPE_COL) {
  348. \$node->setScopeIdValue(\$sidv = \$sibling->getScopeIdValue());
  349. }
  350. // Update database nodes
  351. self::shiftRLValues(\$node->getLeftValue(), 2, \$con, \$sidv);
  352. // Update all loaded nodes
  353. self::updateLoadedNode(\$sibling->retrieveParent(), 2, \$con);
  354. }
  355. ";
  356. }
  357. protected function addInsertAsParentOf(&$script)
  358. {
  359. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  360. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  361. $script .= "
  362. /**
  363. * Inserts \$parent as parent of given node.
  364. *
  365. * @param $objectClassname \$parent Propel object for given parent node
  366. * @param $objectClassname \$node Propel object for given destination node
  367. * @param PropelPDO \$con Connection to use.
  368. * @return void
  369. */
  370. public static function insertAsParentOf(NodeObject \$parent, NodeObject \$node, PropelPDO \$con = null)
  371. {
  372. \$sidv = null;
  373. if (self::SCOPE_COL) {
  374. \$sidv = \$node->getScopeIdValue();
  375. }
  376. self::shiftRLValues(\$node->getLeftValue(), 1, \$con, \$sidv);
  377. self::shiftRLValues(\$node->getRightValue() + 2, 1, \$con, \$sidv);
  378. if (self::SCOPE_COL) {
  379. \$parent->setScopeIdValue(\$sidv);
  380. }
  381. \$parent->setLeftValue(\$node->getLeftValue());
  382. \$parent->setRightValue(\$node->getRightValue() + 2);
  383. \$previous_parent = \$node->retrieveParent();
  384. \$parent->setParentNode(\$previous_parent);
  385. \$node->setParentNode(\$parent);
  386. \$node->save(\$con);
  387. // Update all loaded nodes
  388. self::updateLoadedNode(\$previous_parent, 2, \$con);
  389. }
  390. ";
  391. }
  392. protected function addInsertRoot(&$script)
  393. {
  394. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  395. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  396. $script .= "
  397. /**
  398. * Inserts \$node as root node
  399. *
  400. * @param $objectClassname \$node Propel object as root node
  401. * @param PropelPDO \$con Connection to use.
  402. * @return void
  403. */
  404. public static function insertRoot(NodeObject \$node, PropelPDO \$con = null)
  405. {
  406. \$sidv = null;
  407. if (self::SCOPE_COL) {
  408. \$sidv = \$node->getScopeIdValue();
  409. }
  410. $peerClassname::insertAsParentOf($peerClassname::retrieveRoot(\$sidv, \$con), \$node, \$con);
  411. }
  412. ";
  413. }
  414. protected function addInsertParent(&$script)
  415. {
  416. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  417. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  418. $script .= "
  419. /**
  420. * Inserts \$parent as parent to destination node \$child
  421. *
  422. * @deprecated 1.3 - 2007/11/06
  423. * @see insertAsParentOf()
  424. * @param $objectClassname \$child Propel object to become child node
  425. * @param $objectClassname \$parent Propel object as parent node
  426. * @param PropelPDO \$con Connection to use.
  427. * @return void
  428. */
  429. public static function insertParent(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
  430. {
  431. self::insertAsParentOf(\$parent, \$child, \$con);
  432. }
  433. ";
  434. }
  435. protected function addDeleteRoot(&$script)
  436. {
  437. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  438. $script .= "
  439. /**
  440. * Delete root node
  441. *
  442. * @param PropelPDO \$con Connection to use.
  443. * @return boolean Deletion status
  444. */
  445. public static function deleteRoot(\$scopeId = null, PropelPDO \$con = null)
  446. {
  447. if (!self::SCOPE_COL) {
  448. \$scopeId = null;
  449. }
  450. \$root = $peerClassname::retrieveRoot(\$scopeId, \$con);
  451. if ($peerClassname::getNumberOfChildren(\$root) == 1) {
  452. return $peerClassname::deleteNode(\$root, \$con);
  453. } else {
  454. return false;
  455. }
  456. }
  457. ";
  458. }
  459. protected function addDeleteNode(&$script)
  460. {
  461. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  462. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  463. $script .= "
  464. /**
  465. * Delete \$dest node
  466. *
  467. * @param $objectClassname \$dest Propel object node to delete
  468. * @param PropelPDO \$con Connection to use.
  469. * @return boolean Deletion status
  470. */
  471. public static function deleteNode(NodeObject \$dest, PropelPDO \$con = null)
  472. {
  473. if (\$dest->getLeftValue() == 1) {
  474. // deleting root implies conditions (see deleteRoot() method)
  475. return $peerClassname::deleteRoot(\$con);
  476. }
  477. \$sidv = null;
  478. if (self::SCOPE_COL) {
  479. \$sidv = \$dest->getScopeIdValue();
  480. }
  481. self::shiftRLRange(\$dest->getLeftValue(), \$dest->getRightValue(), -1, \$con, \$sidv);
  482. self::shiftRLValues(\$dest->getRightValue() + 1, -2, \$con, \$sidv);
  483. return \$dest->delete(\$con);
  484. }
  485. ";
  486. }
  487. protected function addMoveToFirstChildOf(&$script)
  488. {
  489. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  490. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  491. $script .= "
  492. /**
  493. * Moves \$child to be first child of \$parent
  494. *
  495. * @param $objectClassname \$parent Propel object for parent node
  496. * @param $objectClassname \$child Propel object for child node
  497. * @param PropelPDO \$con Connection to use.
  498. * @return void
  499. */
  500. public static function moveToFirstChildOf(NodeObject \$parent, NodeObject \$child, PropelPDO \$con = null)
  501. {
  502. if (\$parent->getScopeIdValue() != \$child->getScopeIdValue()) {
  503. throw new PropelException('Moving nodes across trees is not supported');
  504. }
  505. \$destLeft = \$parent->getLeftValue() + 1;
  506. self::updateDBNode(\$child, \$destLeft, \$con);
  507. // Update all loaded nodes
  508. self::updateLoadedNode(\$parent, 2, \$con);
  509. }
  510. ";
  511. }
  512. protected function addMoveToLastChildOf(&$script)
  513. {
  514. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  515. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  516. $script .= "
  517. /**
  518. * Moves \$child to be last child of \$parent
  519. *
  520. * @param $objectClassname \$parent Propel object for parent node
  521. * @param $objectClassname \$child Propel object for child node
  522. * @param PropelPDO \$con Connection to use.
  523. * @return void
  524. */
  525. public static function moveToLastChildOf(NodeObject \$parent, NodeObject \$child, PropelPDO \$con = null)
  526. {
  527. if (\$parent->getScopeIdValue() != \$child->getScopeIdValue()) {
  528. throw new PropelException('Moving nodes across trees is not supported');
  529. }
  530. \$destLeft = \$parent->getRightValue();
  531. self::updateDBNode(\$child, \$destLeft, \$con);
  532. // Update all loaded nodes
  533. self::updateLoadedNode(\$parent, 2, \$con);
  534. }
  535. ";
  536. }
  537. protected function addMoveToPrevSiblingOf(&$script)
  538. {
  539. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  540. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  541. $script .= "
  542. /**
  543. * Moves \$node to be prev sibling to \$dest
  544. *
  545. * @param $objectClassname \$dest Propel object for destination node
  546. * @param $objectClassname \$node Propel object for source node
  547. * @param PropelPDO \$con Connection to use.
  548. * @return void
  549. */
  550. public static function moveToPrevSiblingOf(NodeObject \$dest, NodeObject \$node, PropelPDO \$con = null)
  551. {
  552. if (\$dest->getScopeIdValue() != \$node->getScopeIdValue()) {
  553. throw new PropelException('Moving nodes across trees is not supported');
  554. }
  555. \$destLeft = \$dest->getLeftValue();
  556. self::updateDBNode(\$node, \$destLeft, \$con);
  557. // Update all loaded nodes
  558. self::updateLoadedNode(\$dest->retrieveParent(), 2, \$con);
  559. }
  560. ";
  561. }
  562. protected function addMoveToNextSiblingOf(&$script)
  563. {
  564. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  565. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  566. $script .= "
  567. /**
  568. * Moves \$node to be next sibling to \$dest
  569. *
  570. * @param $objectClassname \$dest Propel object for destination node
  571. * @param $objectClassname \$node Propel object for source node
  572. * @param PropelPDO \$con Connection to use.
  573. * @return void
  574. */
  575. public static function moveToNextSiblingOf(NodeObject \$dest, NodeObject \$node, PropelPDO \$con = null)
  576. {
  577. if (\$dest->getScopeIdValue() != \$node->getScopeIdValue()) {
  578. throw new PropelException('Moving nodes across trees is not supported');
  579. }
  580. \$destLeft = \$dest->getRightValue();
  581. \$destLeft = \$destLeft + 1;
  582. self::updateDBNode(\$node, \$destLeft, \$con);
  583. // Update all loaded nodes
  584. self::updateLoadedNode(\$dest->retrieveParent(), 2, \$con);
  585. }
  586. ";
  587. }
  588. protected function addRetrieveFirstChild(&$script)
  589. {
  590. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  591. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  592. $script .= "
  593. /**
  594. * Gets first child for the given node if it exists
  595. *
  596. * @param $objectClassname \$node Propel object for src node
  597. * @param PropelPDO \$con Connection to use.
  598. * @return mixed Propel object if exists else false
  599. */
  600. public static function retrieveFirstChild(NodeObject \$node, PropelPDO \$con = null)
  601. {
  602. \$c = new Criteria($peerClassname::DATABASE_NAME);
  603. \$c->add(self::LEFT_COL, \$node->getLeftValue() + 1, Criteria::EQUAL);
  604. if (self::SCOPE_COL) {
  605. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  606. }
  607. return $peerClassname::doSelectOne(\$c, \$con);
  608. }
  609. ";
  610. }
  611. protected function addRetrieveLastChild(&$script)
  612. {
  613. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  614. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  615. $script .= "
  616. /**
  617. * Gets last child for the given node if it exists
  618. *
  619. * @param $objectClassname \$node Propel object for src node
  620. * @param PropelPDO \$con Connection to use.
  621. * @return mixed Propel object if exists else false
  622. */
  623. public static function retrieveLastChild(NodeObject \$node, PropelPDO \$con = null)
  624. {
  625. \$c = new Criteria($peerClassname::DATABASE_NAME);
  626. \$c->add(self::RIGHT_COL, \$node->getRightValue() - 1, Criteria::EQUAL);
  627. if (self::SCOPE_COL) {
  628. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  629. }
  630. return $peerClassname::doSelectOne(\$c, \$con);
  631. }
  632. ";
  633. }
  634. protected function addRetrievePrevSibling(&$script)
  635. {
  636. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  637. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  638. $script .= "
  639. /**
  640. * Gets prev sibling for the given node if it exists
  641. *
  642. * @param $objectClassname \$node Propel object for src node
  643. * @param PropelPDO \$con Connection to use.
  644. * @return mixed Propel object if exists else null
  645. */
  646. public static function retrievePrevSibling(NodeObject \$node, PropelPDO \$con = null)
  647. {
  648. \$c = new Criteria($peerClassname::DATABASE_NAME);
  649. \$c->add(self::RIGHT_COL, \$node->getLeftValue() - 1, Criteria::EQUAL);
  650. if (self::SCOPE_COL) {
  651. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  652. }
  653. \$prevSibling = $peerClassname::doSelectOne(\$c, \$con);
  654. \$node->setPrevSibling(\$prevSibling);
  655. return \$prevSibling;
  656. }
  657. ";
  658. }
  659. protected function addRetrieveNextSibling(&$script)
  660. {
  661. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  662. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  663. $script .= "
  664. /**
  665. * Gets next sibling for the given node if it exists
  666. *
  667. * @param $objectClassname \$node Propel object for src node
  668. * @param PropelPDO \$con Connection to use.
  669. * @return mixed Propel object if exists else false
  670. */
  671. public static function retrieveNextSibling(NodeObject \$node, PropelPDO \$con = null)
  672. {
  673. \$c = new Criteria($peerClassname::DATABASE_NAME);
  674. \$c->add(self::LEFT_COL, \$node->getRightValue() + 1, Criteria::EQUAL);
  675. if (self::SCOPE_COL) {
  676. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  677. }
  678. \$nextSibling = $peerClassname::doSelectOne(\$c, \$con);
  679. \$node->setNextSibling(\$nextSibling);
  680. return \$nextSibling;
  681. }
  682. ";
  683. }
  684. protected function addRetrieveTree(&$script)
  685. {
  686. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  687. $script .= "
  688. /**
  689. * Retrieves the entire tree from root
  690. *
  691. * @param PropelPDO \$con Connection to use.
  692. */
  693. public static function retrieveTree(\$scopeId = null, PropelPDO \$con = null)
  694. {
  695. \$c = new Criteria($peerClassname::DATABASE_NAME);
  696. \$c->addAscendingOrderByColumn(self::LEFT_COL);
  697. if (self::SCOPE_COL) {
  698. \$c->add(self::SCOPE_COL, \$scopeId, Criteria::EQUAL);
  699. }
  700. \$stmt = $peerClassname::doSelectStmt(\$c, \$con);
  701. if (false !== (\$row = \$stmt->fetch(PDO::FETCH_NUM))) {
  702. \$omClass = $peerClassname::getOMClass(\$row, 0);
  703. \$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
  704. \$key = ".$peerClassname."::getPrimaryKeyHashFromRow(\$row, 0);
  705. if (null === (\$root = ".$peerClassname."::getInstanceFromPool(\$key))) {
  706. " . $this->buildObjectInstanceCreationCode('$root', '$cls') . "
  707. \$root->hydrate(\$row);
  708. }
  709. \$root->setLevel(0);
  710. $peerClassname::hydrateDescendants(\$root, \$stmt);
  711. $peerClassname::addInstanceToPool(\$root);
  712. \$stmt->closeCursor();
  713. return \$root;
  714. }
  715. return false;
  716. }
  717. ";
  718. }
  719. protected function addRetrieveBranch(&$script)
  720. {
  721. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  722. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  723. $script .= "
  724. /**
  725. * Retrieves the entire tree from parent \$node
  726. *
  727. * @param $objectClassname \$node Propel object for parent node
  728. * @param PropelPDO \$con Connection to use.
  729. */
  730. public static function retrieveBranch(NodeObject \$node, PropelPDO \$con = null)
  731. {
  732. return $peerClassname::retrieveDescendants(\$node, \$con);
  733. }
  734. ";
  735. }
  736. protected function addRetrieveChildren(&$script)
  737. {
  738. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  739. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  740. $script .= "
  741. /**
  742. * Gets direct children for the node
  743. *
  744. * @param $objectClassname \$node Propel object for parent node
  745. * @param PropelPDO \$con Connection to use.
  746. */
  747. public static function retrieveChildren(NodeObject \$node, PropelPDO \$con = null)
  748. {
  749. \$c = new Criteria($peerClassname::DATABASE_NAME);
  750. \$c->addAscendingOrderByColumn(self::LEFT_COL);
  751. if (self::SCOPE_COL) {
  752. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  753. }
  754. \$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN);
  755. \$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN);
  756. \$stmt = $peerClassname::doSelectStmt(\$c, \$con);
  757. return $peerClassname::hydrateChildren(\$node, \$stmt);
  758. }
  759. ";
  760. }
  761. protected function addRetrieveDescendants(&$script)
  762. {
  763. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  764. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  765. $script .= "
  766. /**
  767. * Gets all descendants for the node
  768. *
  769. * @param $objectClassname \$node Propel object for parent node
  770. * @param PropelPDO \$con Connection to use.
  771. */
  772. public static function retrieveDescendants(NodeObject \$node, PropelPDO \$con = null)
  773. {
  774. \$c = new Criteria($peerClassname::DATABASE_NAME);
  775. \$c->addAscendingOrderByColumn(self::LEFT_COL);
  776. if (self::SCOPE_COL) {
  777. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  778. }
  779. \$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN);
  780. \$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN);
  781. \$stmt = $peerClassname::doSelectStmt(\$c, \$con);
  782. return $peerClassname::hydrateDescendants(\$node, \$stmt);
  783. }
  784. ";
  785. }
  786. protected function addRetrieveSiblings(&$script)
  787. {
  788. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  789. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  790. $script .= "
  791. /**
  792. * Gets all siblings for the node
  793. *
  794. * @param $objectClassname \$node Propel object for src node
  795. * @param PropelPDO \$con Connection to use.
  796. */
  797. public static function retrieveSiblings(NodeObject \$node, PropelPDO \$con = null)
  798. {
  799. \$parent = $peerClassname::retrieveParent(\$node, \$con);
  800. \$siblings = $peerClassname::retrieveChildren(\$parent, \$con);
  801. return \$siblings;
  802. }
  803. ";
  804. }
  805. protected function addRetrieveParent(&$script)
  806. {
  807. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  808. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  809. $script .= "
  810. /**
  811. * Gets immediate ancestor for the given node if it exists
  812. *
  813. * @param $objectClassname \$node Propel object for src node
  814. * @param PropelPDO \$con Connection to use.
  815. * @return mixed Propel object if exists else null
  816. */
  817. public static function retrieveParent(NodeObject \$node, PropelPDO \$con = null)
  818. {
  819. \$c = new Criteria($peerClassname::DATABASE_NAME);
  820. \$c1 = \$c->getNewCriterion(self::LEFT_COL, \$node->getLeftValue(), Criteria::LESS_THAN);
  821. \$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$node->getRightValue(), Criteria::GREATER_THAN);
  822. \$c1->addAnd(\$c2);
  823. \$c->add(\$c1);
  824. if (self::SCOPE_COL) {
  825. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  826. }
  827. \$c->addAscendingOrderByColumn(self::RIGHT_COL);
  828. \$parent = $peerClassname::doSelectOne(\$c, \$con);
  829. \$node->setParentNode(\$parent);
  830. return \$parent;
  831. }
  832. ";
  833. }
  834. protected function addGetLevel(&$script)
  835. {
  836. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  837. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  838. $script .= "
  839. /**
  840. * Gets level for the given node
  841. *
  842. * @param $objectClassname \$node Propel object for src node
  843. * @param PropelPDO \$con Connection to use.
  844. * @return int Level for the given node
  845. */
  846. public static function getLevel(NodeObject \$node, PropelPDO \$con = null)
  847. {
  848. if (\$con === null) {
  849. \$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_READ);
  850. }
  851. \$sql = \"SELECT COUNT(*) AS lvl FROM \" . self::TABLE_NAME . \" WHERE \" . self::LEFT_COL . \" < :left AND \" . self::RIGHT_COL . \" > :right\";
  852. if (self::SCOPE_COL) {
  853. \$sql .= ' AND ' . self::SCOPE_COL . ' = :scope';
  854. }
  855. \$stmt = \$con->prepare(\$sql);
  856. \$stmt->bindValue(':left', \$node->getLeftValue(), PDO::PARAM_INT);
  857. \$stmt->bindValue(':right', \$node->getRightValue(), PDO::PARAM_INT);
  858. if (self::SCOPE_COL) {
  859. \$stmt->bindValue(':scope', \$node->getScopeIdValue());
  860. }
  861. \$stmt->execute();
  862. \$row = \$stmt->fetch();
  863. return \$row['lvl'];
  864. }
  865. ";
  866. }
  867. protected function addGetNumberOfChildren(&$script)
  868. {
  869. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  870. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  871. $script .= "
  872. /**
  873. * Gets number of direct children for given node
  874. *
  875. * @param $objectClassname \$node Propel object for src node
  876. * @param PropelPDO \$con Connection to use.
  877. * @return int Level for the given node
  878. */
  879. public static function getNumberOfChildren(NodeObject \$node, PropelPDO \$con = null)
  880. {
  881. \$children = $peerClassname::retrieveChildren(\$node);
  882. return count(\$children);
  883. }
  884. ";
  885. }
  886. protected function addGetNumberOfDescendants(&$script)
  887. {
  888. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  889. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  890. $script .= "
  891. /**
  892. * Gets number of descendants for given node
  893. *
  894. * @param $objectClassname \$node Propel object for src node
  895. * @param PropelPDO \$con Connection to use.
  896. * @return int Level for the given node
  897. */
  898. public static function getNumberOfDescendants(NodeObject \$node, PropelPDO \$con = null)
  899. {
  900. \$right = \$node->getRightValue();
  901. \$left = \$node->getLeftValue();
  902. \$num = (\$right - \$left - 1) / 2;
  903. return \$num;
  904. }
  905. ";
  906. }
  907. protected function addGetPath(&$script)
  908. {
  909. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  910. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  911. $script .= "
  912. /**
  913. * Returns path to a specific node as an array, useful to create breadcrumbs
  914. *
  915. * @param $objectClassname \$node Propel object of node to create path to
  916. * @param PropelPDO \$con Connection to use.
  917. * @return array Array in order of heirarchy
  918. */
  919. public static function getPath(NodeObject \$node, PropelPDO \$con = null)
  920. {
  921. \$criteria = new Criteria();
  922. if (self::SCOPE_COL) {
  923. \$criteria->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  924. }
  925. \$criteria->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::LESS_EQUAL);
  926. \$criteria->add(self::RIGHT_COL, \$node->getRightValue(), Criteria::GREATER_EQUAL);
  927. \$criteria->addAscendingOrderByColumn(self::LEFT_COL);
  928. return self::doSelect(\$criteria, \$con);
  929. }
  930. ";
  931. }
  932. protected function addIsValid(&$script)
  933. {
  934. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  935. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  936. $script .= "
  937. /**
  938. * Tests if node is valid
  939. *
  940. * @param $objectClassname \$node Propel object for src node
  941. * @return bool
  942. */
  943. public static function isValid(NodeObject \$node = null)
  944. {
  945. if (is_object(\$node) && \$node->getRightValue() > \$node->getLeftValue()) {
  946. return true;
  947. } else {
  948. return false;
  949. }
  950. }
  951. ";
  952. }
  953. protected function addIsRoot(&$script)
  954. {
  955. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  956. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  957. $script .= "
  958. /**
  959. * Tests if node is a root
  960. *
  961. * @param $objectClassname \$node Propel object for src node
  962. * @return bool
  963. */
  964. public static function isRoot(NodeObject \$node)
  965. {
  966. return (\$node->getLeftValue()==1);
  967. }
  968. ";
  969. }
  970. protected function addIsLeaf(&$script)
  971. {
  972. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  973. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  974. $script .= "
  975. /**
  976. * Tests if node is a leaf
  977. *
  978. * @param $objectClassname \$node Propel object for src node
  979. * @return bool
  980. */
  981. public static function isLeaf(NodeObject \$node)
  982. {
  983. return ((\$node->getRightValue()-\$node->getLeftValue())==1);
  984. }
  985. ";
  986. }
  987. protected function addIsChildOf(&$script)
  988. {
  989. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  990. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  991. $script .= "
  992. /**
  993. * Tests if \$child is a child of \$parent
  994. *
  995. * @param $objectClassname \$child Propel object for node
  996. * @param $objectClassname \$parent Propel object for node
  997. * @return bool
  998. */
  999. public static function isChildOf(NodeObject \$child, NodeObject \$parent)
  1000. {
  1001. return ((\$child->getLeftValue()>\$parent->getLeftValue()) && (\$child->getRightValue()<\$parent->getRightValue()));
  1002. }
  1003. ";
  1004. }
  1005. protected function addIsChildOfOrSiblingTo(&$script)
  1006. {
  1007. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1008. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1009. $script .= "
  1010. /**
  1011. * Tests if \$node1 is a child of or equal to \$node2
  1012. *
  1013. * @deprecated 1.3 - 2007/11/09
  1014. * @param $objectClassname \$node1 Propel object for node
  1015. * @param $objectClassname \$node2 Propel object for node
  1016. * @return bool
  1017. */
  1018. public static function isChildOfOrSiblingTo(NodeObject \$node1, NodeObject \$node2)
  1019. {
  1020. return ((\$node1->getLeftValue()>=\$node2->getLeftValue()) and (\$node1->getRightValue()<=\$node2->getRightValue()));
  1021. }
  1022. ";
  1023. }
  1024. protected function addIsEqualTo(&$script)
  1025. {
  1026. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1027. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1028. $script .= "
  1029. /**
  1030. * Tests if \$node1 is equal to \$node2
  1031. *
  1032. * @param $objectClassname \$node1 Propel object for node
  1033. * @param $objectClassname \$node2 Propel object for node
  1034. * @return bool
  1035. */
  1036. public static function isEqualTo(NodeObject \$node1, NodeObject \$node2)
  1037. {
  1038. \$also = true;
  1039. if (self::SCOPE_COL) {
  1040. \$also = (\$node1->getScopeIdValue() === \$node2->getScopeIdValue());
  1041. }
  1042. return \$node1->getLeftValue() == \$node2->getLeftValue() && \$node1->getRightValue() == \$node2->getRightValue() && \$also;
  1043. }
  1044. ";
  1045. }
  1046. protected function addHasParent(&$script)
  1047. {
  1048. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1049. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1050. $script .= "
  1051. /**
  1052. * Tests if \$node has an ancestor
  1053. *
  1054. * @param $objectClassname \$node Propel object for node
  1055. * @param PropelPDO \$con Connection to use.
  1056. * @return bool
  1057. */
  1058. public static function hasParent(NodeObject \$node, PropelPDO \$con = null)
  1059. {
  1060. return $peerClassname::isValid($peerClassname::retrieveParent(\$node, \$con));
  1061. }
  1062. ";
  1063. }
  1064. protected function addHasPrevSibling(&$script)
  1065. {
  1066. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1067. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1068. $script .= "
  1069. /**
  1070. * Tests if \$node has prev sibling
  1071. *
  1072. * @param $objectClassname \$node Propel object for node
  1073. * @param PropelPDO \$con Connection to use.
  1074. * @return bool
  1075. */
  1076. public static function hasPrevSibling(NodeObject \$node, PropelPDO \$con = null)
  1077. {
  1078. return $peerClassname::isValid($peerClassname::retrievePrevSibling(\$node, \$con));
  1079. }
  1080. ";
  1081. }
  1082. protected function addHasNextSibling(&$script)
  1083. {
  1084. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1085. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1086. $script .= "
  1087. /**
  1088. * Tests if \$node has next sibling
  1089. *
  1090. * @param $objectClassname \$node Propel object for node
  1091. * @param PropelPDO \$con Connection to use.
  1092. * @return bool
  1093. */
  1094. public static function hasNextSibling(NodeObject \$node, PropelPDO \$con = null)
  1095. {
  1096. return $peerClassname::isValid($peerClassname::retrieveNextSibling(\$node, \$con));
  1097. }
  1098. ";
  1099. }
  1100. protected function addHasChildren(&$script)
  1101. {
  1102. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1103. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1104. $script .= "
  1105. /**
  1106. * Tests if \$node has children
  1107. *
  1108. * @param $objectClassname \$node Propel object for node
  1109. * @return bool
  1110. */
  1111. public static function hasChildren(NodeObject \$node)
  1112. {
  1113. return ((\$node->getRightValue()-\$node->getLeftValue())>1);
  1114. }
  1115. ";
  1116. }
  1117. protected function addDeleteDescendants(&$script)
  1118. {
  1119. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1120. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1121. $script .= "
  1122. /**
  1123. * Deletes \$node and all of its descendants
  1124. *
  1125. * @param $objectClassname \$node Propel object for source node
  1126. * @param PropelPDO \$con Connection to use.
  1127. */
  1128. public static function deleteDescendants(NodeObject \$node, PropelPDO \$con = null)
  1129. {
  1130. \$left = \$node->getLeftValue();
  1131. \$right = \$node->getRightValue();
  1132. \$c = new Criteria($peerClassname::DATABASE_NAME);
  1133. \$c1 = \$c->getNewCriterion(self::LEFT_COL, \$left, Criteria::GREATER_THAN);
  1134. \$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$right, Criteria::LESS_THAN);
  1135. \$c1->addAnd(\$c2);
  1136. \$c->add(\$c1);
  1137. if (self::SCOPE_COL) {
  1138. \$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
  1139. }
  1140. \$c->addAscendingOrderByColumn(self::RIGHT_COL);
  1141. \$result = $peerClassname::doDelete(\$c, \$con);
  1142. self::shiftRLValues(\$right + 1, \$left - \$right -1, \$con, \$node->getScopeIdValue());
  1143. return \$result;
  1144. }
  1145. ";
  1146. }
  1147. protected function addGetNode(&$script)
  1148. {
  1149. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1150. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1151. $script .= "
  1152. /**
  1153. * Returns a node given its primary key or the node itself
  1154. *
  1155. * @param int/$objectClassname \$node Primary key/instance of required node
  1156. * @param PropelPDO \$con Connection to use.
  1157. * @return object Propel object for model
  1158. */
  1159. public static function getNode(\$node, PropelPDO \$con = null)
  1160. {
  1161. if (is_object(\$node)) {
  1162. return \$node;
  1163. } else {
  1164. \$object = $peerClassname::retrieveByPK(\$node, \$con);
  1165. \$rtn = is_object(\$object) ? \$object : false;
  1166. return \$rtn;
  1167. }
  1168. }
  1169. ";
  1170. }
  1171. protected function addHydrateDescendants(&$script)
  1172. {
  1173. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1174. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1175. $table = $this->getTable();
  1176. $script .= "
  1177. /**
  1178. * Hydrate recursively the descendants of the given node
  1179. * @param $objectClassname \$node Propel object for src node
  1180. * @param PDOStatement \$stmt Executed PDOStatement
  1181. */
  1182. protected static function hydrateDescendants(NodeObject \$node, PDOStatement \$stmt)
  1183. {
  1184. \$descendants = array();
  1185. \$children = array();
  1186. \$prevSibling = null;
  1187. ";
  1188. if (!$table->getChildrenColumn()) {
  1189. $script .= "
  1190. // set the class once to avoid overhead in the loop
  1191. \$cls = $peerClassname::getOMClass();
  1192. \$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
  1193. ";
  1194. }
  1195. $script .= "
  1196. while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
  1197. \$key = ".$peerClassname."::getPrimaryKeyHashFromRow(\$row, 0);
  1198. if (null === (\$child = ".$peerClassname."::getInstanceFromPool(\$key))) {";
  1199. if ($table->getChildrenColumn()) {
  1200. $script .= "
  1201. // class must be set each time from the record row
  1202. \$cls = ".$peerClassname."::getOMClass(\$row, 0);
  1203. \$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
  1204. ";
  1205. }
  1206. $script .= "
  1207. " . $this->buildObjectInstanceCreationCode('$child', '$cls') . "
  1208. \$child->hydrate(\$row);
  1209. }
  1210. \$child->setLevel(\$node->getLevel() + 1);
  1211. \$child->setParentNode(\$node);
  1212. if (!empty(\$prevSibling)) {
  1213. \$child->setPrevSibling(\$prevSibling);
  1214. \$prevSibling->setNextSibling(\$child);
  1215. }
  1216. \$descendants[] = \$child;
  1217. if (\$child->hasChildren()) {
  1218. \$descendants = array_merge(\$descendants, $peerClassname::hydrateDescendants(\$child, \$stmt));
  1219. } else {
  1220. \$child->setChildren(array());
  1221. }
  1222. \$children[] = \$child;
  1223. \$prevSibling = \$child;
  1224. $peerClassname::addInstanceToPool(\$child);
  1225. if (\$child->getRightValue() + 1 == \$node->getRightValue()) {
  1226. \$child->setNextSibling(null);
  1227. break;
  1228. }
  1229. }
  1230. \$node->setChildren(\$children);
  1231. return \$descendants;
  1232. }
  1233. ";
  1234. }
  1235. protected function addHydrateChildren(&$script)
  1236. {
  1237. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1238. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1239. $table = $this->getTable();
  1240. $script .= "
  1241. /**
  1242. * Hydrate the children of the given node
  1243. * @param $objectClassname \$node Propel object for src node
  1244. * @param PDOStatement \$stmt Executed PDOStatement
  1245. */
  1246. protected static function hydrateChildren(NodeObject \$node, PDOStatement \$stmt)
  1247. {
  1248. \$children = array();
  1249. \$prevRight = 0;
  1250. ";
  1251. if (!$table->getChildrenColumn()) {
  1252. $script .= "
  1253. // set the class once to avoid overhead in the loop
  1254. \$cls = $peerClassname::getOMClass();
  1255. \$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
  1256. ";
  1257. }
  1258. $script .= "
  1259. while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
  1260. \$key = ".$peerClassname."::getPrimaryKeyHashFromRow(\$row, 0);
  1261. if (null === (\$child = ".$peerClassname."::getInstanceFromPool(\$key))) {";
  1262. if ($table->getChildrenColumn()) {
  1263. $script .= "
  1264. // class must be set each time from the record row
  1265. \$cls = ".$peerClassname."::getOMClass(\$row, 0);
  1266. \$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
  1267. ";
  1268. }
  1269. $script .= "
  1270. " . $this->buildObjectInstanceCreationCode('$child', '$cls') . "
  1271. \$child->hydrate(\$row);
  1272. }
  1273. \$child->setLevel(\$node->getLevel() + 1);
  1274. if (\$child->getRightValue() > \$prevRight) {
  1275. \$children[] = \$child;
  1276. \$prevRight = \$child->getRightValue();
  1277. }
  1278. if (\$child->getRightValue() + 1 == \$node->getRightValue()) {
  1279. break;
  1280. }
  1281. }
  1282. \$node->setChildren(\$children);
  1283. return \$children;
  1284. }
  1285. ";
  1286. }
  1287. /**
  1288. * @deprecated 1.3 - 2008/03/11
  1289. * Won't be fixed, defect by design
  1290. * Never trust it
  1291. */
  1292. protected function addShiftRParent(&$script)
  1293. {
  1294. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1295. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1296. $script .= "
  1297. /**
  1298. * Adds '\$delta' to all parent R values.
  1299. * '\$delta' can also be negative.
  1300. *
  1301. * @deprecated 1.3 - 2008/03/11
  1302. * @param $objectClassname \$node Propel object for parent node
  1303. * @param int \$delta Value to be shifted by, can be negative
  1304. * @param PropelPDO \$con Connection to use.
  1305. */
  1306. protected static function shiftRParent(NodeObject \$node, \$delta, PropelPDO \$con = null)
  1307. {
  1308. if (\$node->hasParent(\$con)) {
  1309. \$parent = \$node->retrieveParent();
  1310. self::shiftRParent(\$parent, \$delta, \$con);
  1311. }
  1312. \$node->setRightValue(\$node->getRightValue() + \$delta);
  1313. }
  1314. ";
  1315. }
  1316. protected function addUpdateLoadedNode(&$script)
  1317. {
  1318. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1319. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1320. $table = $this->getTable();
  1321. $script .= "
  1322. /**
  1323. * Reload all already loaded nodes to sync them with updated db
  1324. *
  1325. * @param $objectClassname \$node Propel object for parent node
  1326. * @param int \$delta Value to be shifted by, can be negative
  1327. * @param PropelPDO \$con Connection to use.
  1328. */
  1329. protected static function updateLoadedNode(NodeObject \$node, \$delta, PropelPDO \$con = null)
  1330. {
  1331. if (Propel::isInstancePoolingEnabled()) {
  1332. \$keys = array();
  1333. foreach (self::\$instances as \$obj) {
  1334. \$keys[] = \$obj->getPrimaryKey();
  1335. }
  1336. if (!empty(\$keys)) {
  1337. // We don't need to alter the object instance pool; we're just modifying these ones
  1338. // already in the pool.
  1339. \$criteria = new Criteria(self::DATABASE_NAME);";
  1340. if (count($table->getPrimaryKey()) === 1) {
  1341. $pkey = $table->getPrimaryKey();
  1342. $col = array_shift($pkey);
  1343. $script .= "
  1344. \$criteria->add(".$this->getColumnConstant($col).", \$keys, Criteria::IN);
  1345. ";
  1346. } else {
  1347. $fields = array();
  1348. foreach ($table->getPrimaryKey() as $k => $col) {
  1349. $fields[] = $this->getColumnConstant($col);
  1350. };
  1351. $script .= "
  1352. // Loop on each instances in pool
  1353. foreach (\$keys as \$values) {
  1354. // Create initial Criterion
  1355. \$cton = \$criteria->getNewCriterion(" . $fields[0] . ", \$values[0]);";
  1356. unset($fields[0]);
  1357. foreach ($fields as $k => $col) {
  1358. $script .= "
  1359. // Create next criterion
  1360. \$nextcton = \$criteria->getNewCriterion(" . $col . ", \$values[$k]);
  1361. // And merge it with the first
  1362. \$cton->addAnd(\$nextcton);";
  1363. }
  1364. $script .= "
  1365. // Add final Criterion to Criteria
  1366. \$criteria->addOr(\$cton);
  1367. }";
  1368. }
  1369. $script .= "
  1370. \$stmt = $peerClassname::doSelectStmt(\$criteria, \$con);
  1371. while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
  1372. \$key = $peerClassname::getPrimaryKeyHashFromRow(\$row, 0);
  1373. if (null !== (\$object = $peerClassname::getInstanceFromPool(\$key))) {";
  1374. $n = 0;
  1375. foreach ($table->getColumns() as $col) {
  1376. if ($col->isNestedSetLeftKey()) {
  1377. $script .= "
  1378. \$object->setLeftValue(\$row[$n]);";
  1379. } else if ($col->isNestedSetRightKey()) {
  1380. $script .= "
  1381. \$object->setRightValue(\$row[$n]);";
  1382. }
  1383. $n++;
  1384. }
  1385. $script .= "
  1386. }
  1387. }
  1388. \$stmt->closeCursor();
  1389. }
  1390. }
  1391. }
  1392. ";
  1393. }
  1394. protected function addUpdateDBNode(&$script)
  1395. {
  1396. $objectClassname = $this->getStubObjectBuilder()->getClassname();
  1397. $script .= "
  1398. /**
  1399. * Move \$node and its children to location \$destLeft and updates rest of tree
  1400. *
  1401. * @param $objectClassname \$node Propel object for node to update
  1402. * @param int \$destLeft Destination left value
  1403. * @param PropelPDO \$con Connection to use.
  1404. */
  1405. protected static function updateDBNode(NodeObject \$node, \$destLeft, PropelPDO \$con = null)
  1406. {
  1407. \$left = \$node->getLeftValue();
  1408. \$right = \$node->getRightValue();
  1409. \$treeSize = \$right - \$left +1;
  1410. self::shiftRLValues(\$destLeft, \$treeSize, \$con, \$node->getScopeIdValue());
  1411. if (\$left >= \$destLeft) { // src was shifted too?
  1412. \$left += \$treeSize;
  1413. \$right += \$treeSize;
  1414. }
  1415. // now there's enough room next to target to move the subtree
  1416. self::shiftRLRange(\$left, \$right, \$destLeft - \$left, \$con, \$node->getScopeIdValue());
  1417. // correct values after source
  1418. self::shiftRLValues(\$right + 1, -\$treeSize, \$con, \$node->getScopeIdValue());
  1419. }
  1420. ";
  1421. }
  1422. protected function addShiftRLValues(&$script)
  1423. {
  1424. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1425. $script .= "
  1426. /**
  1427. * Adds '\$delta' to all L and R values that are >= '\$first'. '\$delta' can also be negative.
  1428. *
  1429. * @param int \$first First node to be shifted
  1430. * @param int \$delta Value to be shifted by, can be negative
  1431. * @param PropelPDO \$con Connection to use.
  1432. */
  1433. protected static function shiftRLValues(\$first, \$delta, PropelPDO \$con = null, \$scopeId = null)
  1434. {
  1435. if (\$con === null) {
  1436. \$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
  1437. }
  1438. \$leftUpdateCol = self::LEFT_COL;
  1439. \$rightUpdateCol = self::RIGHT_COL;
  1440. // Shift left column values
  1441. \$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
  1442. \$criterion = \$whereCriteria->getNewCriterion(
  1443. self::LEFT_COL,
  1444. \$first,
  1445. Criteria::GREATER_EQUAL);
  1446. if (self::SCOPE_COL) {
  1447. \$criterion->addAnd(
  1448. \$whereCriteria->getNewCriterion(
  1449. self::SCOPE_COL,
  1450. \$scopeId,
  1451. Criteria::EQUAL));
  1452. }
  1453. \$whereCriteria->add(\$criterion);
  1454. \$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
  1455. \$valuesCriteria->add(
  1456. self::LEFT_COL,
  1457. array('raw' => \$leftUpdateCol . ' + ?', 'value' => \$delta),
  1458. Criteria::CUSTOM_EQUAL);
  1459. {$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
  1460. // Shift right column values
  1461. \$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
  1462. \$criterion = \$whereCriteria->getNewCriterion(
  1463. self::RIGHT_COL,
  1464. \$first,
  1465. Criteria::GREATER_EQUAL);
  1466. if (self::SCOPE_COL) {
  1467. \$criterion->addAnd(
  1468. \$whereCriteria->getNewCriterion(
  1469. self::SCOPE_COL,
  1470. \$scopeId,
  1471. Criteria::EQUAL));
  1472. }
  1473. \$whereCriteria->add(\$criterion);
  1474. \$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
  1475. \$valuesCriteria->add(
  1476. self::RIGHT_COL,
  1477. array('raw' => \$rightUpdateCol . ' + ?', 'value' => \$delta),
  1478. Criteria::CUSTOM_EQUAL);
  1479. {$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
  1480. }
  1481. ";
  1482. }
  1483. protected function addShiftRLRange(&$script)
  1484. {
  1485. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  1486. $script .= "
  1487. /**
  1488. * Adds '\$delta' to all L and R values that are >= '\$first' and <= '\$last'.
  1489. * '\$delta' can also be negative.
  1490. *
  1491. * @p