PageRenderTime 51ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/generator/lib/builder/om/PHP5NodeBuilder.php

https://github.com/1989gaurav/Propel
PHP | 1101 lines | 643 code | 146 blank | 312 comment | 79 complexity | a1aa475fefc1200230c11c849225b66e 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__) . '/ObjectBuilder.php';
  10. /**
  11. * Generates a PHP5 tree node Object class for user object model (OM).
  12. *
  13. * This class produces the base tree node object class (e.g. BaseMyTable) which contains all
  14. * the custom-built accessor and setter methods.
  15. *
  16. * @author Hans Lellelid <hans@xmpl.org>
  17. * @package propel.generator.builder.om
  18. */
  19. class PHP5NodeBuilder extends ObjectBuilder
  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->getStubNodeBuilder()->getUnprefixedClassname();
  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. } // addIncludes()
  44. /**
  45. * Adds class phpdoc comment and openning of class.
  46. * @param string &$script The script will be modified in this method.
  47. */
  48. protected function addClassOpen(&$script)
  49. {
  50. $table = $this->getTable();
  51. $tableName = $table->getName();
  52. $tableDesc = $table->getDescription();
  53. $script .= "
  54. /**
  55. * Base class that represents a row from the '$tableName' table.
  56. *
  57. * $tableDesc
  58. *";
  59. if ($this->getBuildProperty('addTimeStamp')) {
  60. $now = strftime('%c');
  61. $script .= "
  62. * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
  63. *
  64. * $now
  65. *";
  66. }
  67. $script .= "
  68. * @package propel.generator.".$this->getPackage()."
  69. */
  70. abstract class ".$this->getClassname()." implements IteratorAggregate {
  71. ";
  72. }
  73. /**
  74. * Specifies the methods that are added as part of the basic OM class.
  75. * This can be overridden by subclasses that wish to add more methods.
  76. * @see ObjectBuilder::addClassBody()
  77. */
  78. protected function addClassBody(&$script)
  79. {
  80. $table = $this->getTable();
  81. $this->addAttributes($script);
  82. $this->addConstructor($script);
  83. $this->addCallOverload($script);
  84. $this->addSetIteratorOptions($script);
  85. $this->addGetIterator($script);
  86. $this->addGetNodeObj($script);
  87. $this->addGetNodePath($script);
  88. $this->addGetNodeIndex($script);
  89. $this->addGetNodeLevel($script);
  90. $this->addHasChildNode($script);
  91. $this->addGetChildNodeAt($script);
  92. $this->addGetFirstChildNode($script);
  93. $this->addGetLastChildNode($script);
  94. $this->addGetSiblingNode($script);
  95. $this->addGetParentNode($script);
  96. $this->addGetAncestors($script);
  97. $this->addIsRootNode($script);
  98. $this->addSetNew($script);
  99. $this->addSetDeleted($script);
  100. $this->addAddChildNode($script);
  101. $this->addMoveChildNode($script);
  102. $this->addSave($script);
  103. $this->addDelete($script);
  104. $this->addEquals($script);
  105. $this->addAttachParentNode($script);
  106. $this->addAttachChildNode($script);
  107. $this->addDetachParentNode($script);
  108. $this->addDetachChildNode($script);
  109. $this->addShiftChildNodes($script);
  110. $this->addInsertNewChildNode($script);
  111. $this->addAdjustStatus($script);
  112. $this->addAdjustNodePath($script);
  113. }
  114. /**
  115. * Closes class.
  116. * @param string &$script The script will be modified in this method.
  117. */
  118. protected function addClassClose(&$script)
  119. {
  120. $script .= "
  121. } // " . $this->getClassname() . "
  122. ";
  123. }
  124. /**
  125. * Adds class attributes.
  126. * @param string &$script The script will be modified in this method.
  127. */
  128. protected function addAttributes(&$script)
  129. {
  130. $script .= "
  131. /**
  132. * @var ".$this->getStubObjectBuilder()->getClassname()." object wrapped by this node.
  133. */
  134. protected \$obj = null;
  135. /**
  136. * The parent node for this node.
  137. * @var ".$this->getStubNodeBuilder()->getClassname()."
  138. */
  139. protected \$parentNode = null;
  140. /**
  141. * Array of child nodes for this node. Nodes indexes are one-based.
  142. * @var array
  143. */
  144. protected \$childNodes = array();
  145. ";
  146. }
  147. /**
  148. * Adds the constructor.
  149. * @param string &$script The script will be modified in this method.
  150. */
  151. protected function addConstructor(&$script)
  152. {
  153. $script .= "
  154. /**
  155. * Constructor.
  156. *
  157. * @param ".$this->getStubObjectBuilder()->getClassname()." \$obj Object wrapped by this node.
  158. */
  159. public function __construct(\$obj = null)
  160. {
  161. if (\$obj !== null) {
  162. \$this->obj = \$obj;
  163. } else {
  164. \$setNodePath = 'set' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME;
  165. \$this->obj = new ".$this->getStubObjectBuilder()->getClassname()."();
  166. \$this->obj->\$setNodePath('0');
  167. }
  168. }
  169. ";
  170. }
  171. protected function addCallOverload(&$script)
  172. {
  173. $script .= "
  174. /**
  175. * Convenience overload for wrapped object methods.
  176. *
  177. * @param string Method name to call on wrapped object.
  178. * @param mixed Parameter accepted by wrapped object set method.
  179. * @return mixed Return value of wrapped object method.
  180. * @throws PropelException Fails if method is not defined for wrapped object.
  181. */
  182. public function __call(\$name, \$parms)
  183. {
  184. if (method_exists(\$this->obj, \$name))
  185. return call_user_func_array(array(\$this->obj, \$name), \$parms);
  186. else
  187. throw new PropelException('get method not defined: \$name');
  188. }
  189. ";
  190. }
  191. protected function addSetIteratorOptions(&$script)
  192. {
  193. $script .= "
  194. /**
  195. * Sets the default options for iterators created from this object.
  196. * The options are specified in map format. The following options
  197. * are supported by all iterators. Some iterators may support other
  198. * options:
  199. *
  200. * \"querydb\" - True if nodes should be retrieved from database.
  201. * \"con\" - Connection to use if retrieving from database.
  202. *
  203. * @param string Type of iterator to use (\"pre\", \"post\", \"level\").
  204. * @param array Map of option name => value.
  205. * @return void
  206. * @todo Implement other iterator types (i.e. post-order, level, etc.)
  207. */
  208. public function setIteratorOptions(\$type, \$opts)
  209. {
  210. \$this->itType = \$type;
  211. \$this->itOpts = \$opts;
  212. }
  213. ";
  214. }
  215. protected function addGetIterator(&$script)
  216. {
  217. $script .= "
  218. /**
  219. * Returns a pre-order iterator for this node and its children.
  220. *
  221. * @param string Type of iterator to use (\"pre\", \"post\", \"level\")
  222. * @param array Map of option name => value.
  223. * @return NodeIterator
  224. */
  225. public function getIterator(\$type = null, \$opts = null)
  226. {
  227. if (\$type === null)
  228. \$type = (isset(\$this->itType) ? \$this->itType : 'Pre');
  229. if (\$opts === null)
  230. \$opts = (isset(\$this->itOpts) ? \$this->itOpts : array());
  231. \$itclass = ucfirst(strtolower(\$type)) . 'OrderNodeIterator';
  232. require_once('propel/om/' . \$itclass . '.php');
  233. return new \$itclass(\$this, \$opts);
  234. }
  235. ";
  236. }
  237. protected function addGetNodeObj(&$script)
  238. {
  239. $script .= "
  240. /**
  241. * Returns the object wrapped by this class.
  242. * @return ".$this->getStubObjectBuilder()->getClassname()."
  243. */
  244. public function getNodeObj()
  245. {
  246. return \$this->obj;
  247. }
  248. ";
  249. }
  250. protected function addGetNodePath(&$script)
  251. {
  252. $script .= "
  253. /**
  254. * Convenience method for retrieving nodepath.
  255. * @return string
  256. */
  257. public function getNodePath()
  258. {
  259. \$getNodePath = 'get' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME;
  260. return \$this->obj->\$getNodePath();
  261. }
  262. ";
  263. }
  264. protected function addGetNodeIndex(&$script)
  265. {
  266. $script .= "
  267. /**
  268. * Returns one-based node index among siblings.
  269. * @return int
  270. */
  271. public function getNodeIndex()
  272. {
  273. \$npath =& \$this->getNodePath();
  274. \$sep = strrpos(\$npath, ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP);
  275. return (int) (\$sep !== false ? substr(\$npath, \$sep+1) : \$npath);
  276. }
  277. ";
  278. }
  279. protected function addGetNodeLevel(&$script)
  280. {
  281. $script .= "
  282. /**
  283. * Returns one-based node level within tree (root node is level 1).
  284. * @return int
  285. */
  286. public function getNodeLevel()
  287. {
  288. return (substr_count(\$this->getNodePath(), ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP) + 1);
  289. }
  290. ";
  291. }
  292. protected function addHasChildNode(&$script)
  293. {
  294. $script .= "
  295. /**
  296. * Returns true if specified node is a child of this node. If recurse is
  297. * true, checks if specified node is a descendant of this node.
  298. *
  299. * @param ".$this->getStubNodeBuilder()->getClassname()." Node to look for.
  300. * @param boolean True if strict comparison should be used.
  301. * @param boolean True if all descendants should be checked.
  302. * @return boolean
  303. */
  304. public function hasChildNode(\$node, \$strict = false, \$recurse = false)
  305. {
  306. foreach (\$this->childNodes as \$childNode)
  307. {
  308. if (\$childNode->equals(\$node, \$strict))
  309. return true;
  310. if (\$recurse && \$childNode->hasChildNode(\$node, \$recurse))
  311. return true;
  312. }
  313. return false;
  314. }
  315. ";
  316. }
  317. protected function addGetChildNodeAt(&$script)
  318. {
  319. $script .= "
  320. /**
  321. * Returns child node at one-based index. Retrieves from database if not
  322. * loaded yet.
  323. *
  324. * @param int One-based child node index.
  325. * @param boolean True if child should be retrieved from database.
  326. * @param PropelPDO Connection to use if retrieving from database.
  327. * @return ".$this->getStubNodeBuilder()->getClassname()."
  328. */
  329. public function getChildNodeAt(\$i, \$querydb = false, PropelPDO \$con = null)
  330. {
  331. if (\$querydb &&
  332. !\$this->obj->isNew() &&
  333. !\$this->obj->isDeleted() &&
  334. !isset(\$this->childNodes[\$i]))
  335. {
  336. \$criteria = new Criteria(".$this->getStubPeerBuilder()->getClassname()."::DATABASE_NAME);
  337. \$criteria->add(".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_COLNAME, \$this->getNodePath() . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP . \$i, Criteria::EQUAL);
  338. if (\$childObj = ".$this->getStubPeerBuilder()->getClassname()."::doSelectOne(\$criteria, \$con))
  339. \$this->attachChildNode(new ".$this->getStubNodeBuilder()->getClassname()."(\$childObj));
  340. }
  341. return (isset(\$this->childNodes[\$i]) ? \$this->childNodes[\$i] : null);
  342. }
  343. ";
  344. }
  345. protected function addGetFirstChildNode(&$script)
  346. {
  347. $script .= "
  348. /**
  349. * Returns first child node (if any). Retrieves from database if not loaded yet.
  350. *
  351. * @param boolean True if child should be retrieved from database.
  352. * @param PropelPDO Connection to use if retrieving from database.
  353. * @return ".$this->getStubNodeBuilder()->getClassname()."
  354. */
  355. public function getFirstChildNode(\$querydb = false, PropelPDO \$con = null)
  356. {
  357. return \$this->getChildNodeAt(1, \$querydb, \$con);
  358. }
  359. ";
  360. }
  361. protected function addGetLastChildNode(&$script)
  362. {
  363. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  364. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  365. $script .= "
  366. /**
  367. * Returns last child node (if any).
  368. *
  369. * @param boolean True if child should be retrieved from database.
  370. * @param PropelPDO Connection to use if retrieving from database.
  371. */
  372. public function getLastChildNode(\$querydb = false, PropelPDO \$con = null)
  373. {
  374. \$lastNode = null;
  375. if (\$this->obj->isNew() || \$this->obj->isDeleted())
  376. {
  377. end(\$this->childNodes);
  378. \$lastNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null);
  379. }
  380. else if (\$querydb)
  381. {
  382. \$db = Propel::getDb($peerClassname::DATABASE_NAME);
  383. \$criteria = new Criteria($peerClassname::DATABASE_NAME);
  384. \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%', Criteria::LIKE);
  385. \$criteria->addAnd($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%' . $nodePeerClassname::NPATH_SEP . '%', Criteria::NOT_LIKE);
  386. $peerClassname::addSelectColumns(\$criteria);
  387. \$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME));
  388. \$criteria->addDescendingOrderByColumn('npathlen');
  389. \$criteria->addDescendingOrderByColumn($nodePeerClassname::NPATH_COLNAME);
  390. \$lastObj = $peerClassname::doSelectOne(\$criteria, \$con);
  391. if (\$lastObj !== null)
  392. {
  393. \$lastNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$lastObj);
  394. end(\$this->childNodes);
  395. \$endNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null);
  396. if (\$endNode)
  397. {
  398. if (\$endNode->getNodePath() > \$lastNode->getNodePath())
  399. throw new PropelException('Cached child node inconsistent with database.');
  400. else if (\$endNode->getNodePath() == \$lastNode->getNodePath())
  401. \$lastNode = \$endNode;
  402. else
  403. \$this->attachChildNode(\$lastNode);
  404. }
  405. else
  406. {
  407. \$this->attachChildNode(\$lastNode);
  408. }
  409. }
  410. }
  411. return \$lastNode;
  412. }
  413. ";
  414. }
  415. protected function addGetSiblingNode(&$script)
  416. {
  417. $script .= "
  418. /**
  419. * Returns next (or previous) sibling node or null. Retrieves from database if
  420. * not loaded yet.
  421. *
  422. * @param boolean True if previous sibling should be returned.
  423. * @param boolean True if sibling should be retrieved from database.
  424. * @param PropelPDO Connection to use if retrieving from database.
  425. * @return ".$this->getStubNodeBuilder()->getClassname()."
  426. */
  427. public function getSiblingNode(\$prev = false, \$querydb = false, PropelPDO \$con = null)
  428. {
  429. \$nidx = \$this->getNodeIndex();
  430. if (\$this->isRootNode())
  431. {
  432. return null;
  433. }
  434. else if (\$prev)
  435. {
  436. if (\$nidx > 1 && (\$parentNode = \$this->getParentNode(\$querydb, \$con)))
  437. return \$parentNode->getChildNodeAt(\$nidx-1, \$querydb, \$con);
  438. else
  439. return null;
  440. }
  441. else
  442. {
  443. if (\$parentNode = \$this->getParentNode(\$querydb, \$con))
  444. return \$parentNode->getChildNodeAt(\$nidx+1, \$querydb, \$con);
  445. else
  446. return null;
  447. }
  448. }
  449. ";
  450. }
  451. protected function addGetParentNode(&$script)
  452. {
  453. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  454. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  455. $script .= "
  456. /**
  457. * Returns parent node. Loads from database if not cached yet.
  458. *
  459. * @param boolean True if parent should be retrieved from database.
  460. * @param PropelPDO Connection to use if retrieving from database.
  461. * @return ".$this->getStubNodeBuilder()->getClassname()."
  462. */
  463. public function getParentNode(\$querydb = true, PropelPDO \$con = null)
  464. {
  465. if (\$querydb &&
  466. \$this->parentNode === null &&
  467. !\$this->isRootNode() &&
  468. !\$this->obj->isNew() &&
  469. !\$this->obj->isDeleted())
  470. {
  471. \$npath =& \$this->getNodePath();
  472. \$sep = strrpos(\$npath, $nodePeerClassname::NPATH_SEP);
  473. \$ppath = substr(\$npath, 0, \$sep);
  474. \$criteria = new Criteria($peerClassname::DATABASE_NAME);
  475. \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$ppath, Criteria::EQUAL);
  476. if (\$parentObj = $peerClassname::doSelectOne(\$criteria, \$con))
  477. {
  478. \$parentNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$parentObj);
  479. \$parentNode->attachChildNode(\$this);
  480. }
  481. }
  482. return \$this->parentNode;
  483. }
  484. ";
  485. }
  486. protected function addGetAncestors(&$script)
  487. {
  488. $script .= "
  489. /**
  490. * Returns an array of all ancestor nodes, starting with the root node
  491. * first.
  492. *
  493. * @param boolean True if ancestors should be retrieved from database.
  494. * @param PropelPDO Connection to use if retrieving from database.
  495. * @return array
  496. */
  497. public function getAncestors(\$querydb = false, PropelPDO \$con = null)
  498. {
  499. \$ancestors = array();
  500. \$parentNode = \$this;
  501. while (\$parentNode = \$parentNode->getParentNode(\$querydb, \$con))
  502. array_unshift(\$ancestors, \$parentNode);
  503. return \$ancestors;
  504. }
  505. ";
  506. }
  507. protected function addIsRootNode(&$script)
  508. {
  509. $script .= "
  510. /**
  511. * Returns true if node is the root node of the tree.
  512. * @return boolean
  513. */
  514. public function isRootNode()
  515. {
  516. return (\$this->getNodePath() === '1');
  517. }
  518. ";
  519. }
  520. protected function addSetNew(&$script)
  521. {
  522. $script .= "
  523. /**
  524. * Changes the state of the object and its descendants to 'new'.
  525. * Also changes the node path to '0' to indicate that it is not a
  526. * stored node.
  527. *
  528. * @param boolean
  529. * @return void
  530. */
  531. public function setNew(\$b)
  532. {
  533. \$this->adjustStatus('new', \$b);
  534. \$this->adjustNodePath(\$this->getNodePath(), '0');
  535. }
  536. ";
  537. }
  538. protected function addSetDeleted(&$script)
  539. {
  540. $script .= "
  541. /**
  542. * Changes the state of the object and its descendants to 'deleted'.
  543. *
  544. * @param boolean
  545. * @return void
  546. */
  547. public function setDeleted(\$b)
  548. {
  549. \$this->adjustStatus('deleted', \$b);
  550. }
  551. ";
  552. }
  553. protected function addAddChildNode(&$script)
  554. {
  555. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  556. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  557. $script .= "
  558. /**
  559. * Adds the specified node (and its children) as a child to this node. If a
  560. * valid \$beforeNode is specified, the node will be inserted in front of
  561. * \$beforeNode. If \$beforeNode is not specified the node will be appended to
  562. * the end of the child nodes.
  563. *
  564. * @param ".$this->getStubNodeBuilder()->getClassname()." Node to add.
  565. * @param ".$this->getStubNodeBuilder()->getClassname()." Node to insert before.
  566. * @param PropelPDO Connection to use.
  567. */
  568. public function addChildNode(\$node, \$beforeNode = null, PropelPDO \$con = null)
  569. {
  570. if (\$this->obj->isNew() && !\$node->obj->isNew())
  571. throw new PropelException('Cannot add stored nodes to a new node.');
  572. if (\$this->obj->isDeleted() || \$node->obj->isDeleted())
  573. throw new PropelException('Cannot add children in a deleted state.');
  574. if (\$this->hasChildNode(\$node))
  575. throw new PropelException('Node is already a child of this node.');
  576. if (\$beforeNode && !\$this->hasChildNode(\$beforeNode))
  577. throw new PropelException('Invalid beforeNode.');
  578. if (\$con === null)
  579. \$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
  580. if (!\$this->obj->isNew()) \$con->beginTransaction();
  581. try {
  582. if (\$beforeNode)
  583. {
  584. // Inserting before a node.
  585. \$childIdx = \$beforeNode->getNodeIndex();
  586. \$this->shiftChildNodes(1, \$beforeNode->getNodeIndex(), \$con);
  587. }
  588. else
  589. {
  590. // Appending child node.
  591. if (\$lastNode = \$this->getLastChildNode(true, \$con))
  592. \$childIdx = \$lastNode->getNodeIndex()+1;
  593. else
  594. \$childIdx = 1;
  595. }
  596. // Add the child (and its children) at the specified index.
  597. if (!\$this->obj->isNew() && \$node->obj->isNew())
  598. {
  599. \$this->insertNewChildNode(\$node, \$childIdx, \$con);
  600. }
  601. else
  602. {
  603. // \$this->isNew() && \$node->isNew() ||
  604. // !\$this->isNew() && !node->isNew()
  605. \$srcPath = \$node->getNodePath();
  606. \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx;
  607. if (!\$node->obj->isNew())
  608. {
  609. $nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con);
  610. \$parentNode = \$node->getParentNode(true, \$con);
  611. }
  612. else
  613. {
  614. \$parentNode = \$node->getParentNode();
  615. }
  616. if (\$parentNode)
  617. {
  618. \$parentNode->detachChildNode(\$node);
  619. \$parentNode->shiftChildNodes(-1, \$node->getNodeIndex()+1, \$con);
  620. }
  621. \$node->adjustNodePath(\$srcPath, \$dstPath);
  622. }
  623. if (!\$this->obj->isNew()) \$con->commit();
  624. \$this->attachChildNode(\$node);
  625. } catch (SQLException \$e) {
  626. if (!\$this->obj->isNew()) \$con->rollBack();
  627. throw new PropelException(\$e);
  628. }
  629. }
  630. ";
  631. }
  632. protected function addMoveChildNode(&$script)
  633. {
  634. $script .= "
  635. /**
  636. * Moves the specified child node in the specified direction.
  637. *
  638. * @param ".$this->getStubNodeBuilder()->getClassname()." Node to move.
  639. * @param int Number of spaces to move among siblings (may be negative).
  640. * @param PropelPDO Connection to use.
  641. * @throws PropelException
  642. */
  643. public function moveChildNode(\$node, \$direction, PropelPDO \$con = null)
  644. {
  645. throw new PropelException('moveChildNode() not implemented yet.');
  646. }
  647. ";
  648. }
  649. protected function addSave(&$script)
  650. {
  651. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  652. $script .= "
  653. /**
  654. * Saves modified object data to the datastore.
  655. *
  656. * @param boolean If true, descendants will be saved as well.
  657. * @param PropelPDO Connection to use.
  658. */
  659. public function save(\$recurse = false, PropelPDO \$con = null)
  660. {
  661. if (\$this->obj->isDeleted())
  662. throw new PropelException('Cannot save deleted node.');
  663. if (substr(\$this->getNodePath(), 0, 1) == '0')
  664. throw new PropelException('Cannot save unattached node.');
  665. if (\$this->obj->isColumnModified($nodePeerClassname::NPATH_COLNAME))
  666. throw new PropelException('Cannot save manually modified node path.');
  667. \$this->obj->save(\$con);
  668. if (\$recurse)
  669. {
  670. foreach (\$this->childNodes as \$childNode)
  671. \$childNode->save(\$recurse, \$con);
  672. }
  673. }
  674. ";
  675. }
  676. protected function addDelete(&$script)
  677. {
  678. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  679. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  680. $script .= "
  681. /**
  682. * Removes this object and all descendants from datastore.
  683. *
  684. * @param PropelPDO Connection to use.
  685. * @return void
  686. * @throws PropelException
  687. */
  688. public function delete(PropelPDO \$con = null)
  689. {
  690. if (\$this->obj->isDeleted()) {
  691. throw new PropelException('This node has already been deleted.');
  692. }
  693. if (\$con === null) {
  694. \$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
  695. }
  696. if (!\$this->obj->isNew()) {
  697. $nodePeerClassname::deleteNodeSubTree(\$this->getNodePath(), \$con);
  698. }
  699. if (\$parentNode = \$this->getParentNode(true, \$con)) {
  700. \$parentNode->detachChildNode(\$this);
  701. \$parentNode->shiftChildNodes(-1, \$this->getNodeIndex()+1, \$con);
  702. }
  703. \$this->setDeleted(true);
  704. }
  705. ";
  706. }
  707. protected function addEquals(&$script)
  708. {
  709. $nodeClassname = $this->getStubNodeBuilder()->getClassname();
  710. $script .= "
  711. /**
  712. * Compares the object wrapped by this node with that of another node. Use
  713. * this instead of equality operators to prevent recursive dependency
  714. * errors.
  715. *
  716. * @param $nodeClassname Node to compare.
  717. * @param boolean True if strict comparison should be used.
  718. * @return boolean
  719. */
  720. public function equals(\$node, \$strict = false)
  721. {
  722. if (\$strict) {
  723. return (\$this->obj === \$node->obj);
  724. } else {
  725. return (\$this->obj == \$node->obj);
  726. }
  727. }
  728. ";
  729. }
  730. protected function addAttachParentNode(&$script)
  731. {
  732. $nodeClassname = $this->getStubNodeBuilder()->getClassname();
  733. $script .= "
  734. /**
  735. * This method is used internally when constructing the tree structure
  736. * from the database. To set the parent of a node, you should call
  737. * addChildNode() on the parent.
  738. *
  739. * @param $nodeClassname Parent node to attach.
  740. * @return void
  741. * @throws PropelException
  742. */
  743. public function attachParentNode(\$node)
  744. {
  745. if (!\$node->hasChildNode(\$this, true))
  746. throw new PropelException('Failed to attach parent node for non-child.');
  747. \$this->parentNode = \$node;
  748. }
  749. ";
  750. }
  751. protected function addAttachChildNode(&$script)
  752. {
  753. $nodeClassname = $this->getStubNodeBuilder()->getClassname();
  754. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  755. $script .= "
  756. /**
  757. * This method is used internally when constructing the tree structure
  758. * from the database. To add a child to a node you should call the
  759. * addChildNode() method instead.
  760. *
  761. * @param $nodeClassname Child node to attach.
  762. * @return void
  763. * @throws PropelException
  764. */
  765. public function attachChildNode(\$node)
  766. {
  767. if (\$this->hasChildNode(\$node))
  768. throw new PropelException('Failed to attach child node. Node already exists.');
  769. if (\$this->obj->isDeleted() || \$node->obj->isDeleted())
  770. throw new PropelException('Failed to attach node in deleted state.');
  771. if (\$this->obj->isNew() && !\$node->obj->isNew())
  772. throw new PropelException('Failed to attach non-new child to new node.');
  773. if (!\$this->obj->isNew() && \$node->obj->isNew())
  774. throw new PropelException('Failed to attach new child to non-new node.');
  775. if (\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$node->getNodeIndex() != \$node->getNodePath())
  776. throw new PropelException('Failed to attach child node. Node path mismatch.');
  777. \$this->childNodes[\$node->getNodeIndex()] = \$node;
  778. ksort(\$this->childNodes);
  779. \$node->attachParentNode(\$this);
  780. }
  781. ";
  782. }
  783. protected function addDetachParentNode(&$script)
  784. {
  785. $nodeClassname = $this->getStubNodeBuilder()->getClassname();
  786. $script .= "
  787. /**
  788. * This method is used internally when deleting nodes. It is used to break
  789. * the link to this node's parent.
  790. * @param $nodeClassname Parent node to detach from.
  791. * @return void
  792. * @throws PropelException
  793. */
  794. public function detachParentNode(\$node)
  795. {
  796. if (!\$node->hasChildNode(\$this, true))
  797. throw new PropelException('Failed to detach parent node from non-child.');
  798. unset(\$node->childNodes[\$this->getNodeIndex()]);
  799. \$this->parentNode = null;
  800. }
  801. ";
  802. }
  803. protected function addDetachChildNode(&$script)
  804. {
  805. $script .= "
  806. /**
  807. * This method is used internally when deleting nodes. It is used to break
  808. * the link to this between this node and the specified child.
  809. * @param ".$this->getStubNodeBuilder()->getClassname()." Child node to detach.
  810. * @return void
  811. * @throws PropelException
  812. */
  813. public function detachChildNode(\$node)
  814. {
  815. if (!\$this->hasChildNode(\$node, true))
  816. throw new PropelException('Failed to detach non-existent child node.');
  817. unset(\$this->childNodes[\$node->getNodeIndex()]);
  818. \$node->parentNode = null;
  819. }
  820. ";
  821. }
  822. protected function addShiftChildNodes(&$script)
  823. {
  824. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  825. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  826. $script .= "
  827. /**
  828. * Shifts child nodes in the specified direction and offset index. This
  829. * method assumes that there is already space available in the
  830. * direction/offset indicated.
  831. *
  832. * @param int Direction/# spaces to shift. 1=leftshift, 1=rightshift
  833. * @param int Node index to start shift at.
  834. * @param PropelPDO The connection to be used.
  835. * @return void
  836. * @throws PropelException
  837. */
  838. protected function shiftChildNodes(\$direction, \$offsetIdx, PropelPDO \$con)
  839. {
  840. if (\$this->obj->isDeleted())
  841. throw new PropelException('Cannot shift nodes for deleted object');
  842. \$lastNode = \$this->getLastChildNode(true, \$con);
  843. \$lastIdx = (\$lastNode !== null ? \$lastNode->getNodeIndex() : 0);
  844. if (\$lastNode === null || \$offsetIdx > \$lastIdx)
  845. return;
  846. if (\$con === null)
  847. \$con = Propel::getConnection($peerClassname::DATABASE_NAME);
  848. if (!\$this->obj->isNew())
  849. {
  850. // Shift nodes in database.
  851. \$con->beginTransaction();
  852. try {
  853. \$n = \$lastIdx - \$offsetIdx + 1;
  854. \$i = \$direction < 1 ? \$offsetIdx : \$lastIdx;
  855. while (\$n--)
  856. {
  857. \$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i; // 1.2.2
  858. \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3
  859. $nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con);
  860. \$i -= \$direction;
  861. }
  862. \$con->commit();
  863. } catch (SQLException \$e) {
  864. \$con->rollBack();
  865. throw new PropelException(\$e);
  866. }
  867. }
  868. // Shift the in-memory objects.
  869. \$n = \$lastIdx - \$offsetIdx + 1;
  870. \$i = \$direction < 1 ? \$offsetIdx : \$lastIdx;
  871. while (\$n--)
  872. {
  873. if (isset(\$this->childNodes[\$i]))
  874. {
  875. \$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i; // 1.2.2
  876. \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3
  877. \$this->childNodes[\$i+\$direction] = \$this->childNodes[\$i];
  878. \$this->childNodes[\$i+\$direction]->adjustNodePath(\$srcPath, \$dstPath);
  879. unset(\$this->childNodes[\$i]);
  880. }
  881. \$i -= \$direction;
  882. }
  883. ksort(\$this->childNodes);
  884. }
  885. ";
  886. }
  887. protected function addInsertNewChildNode(&$script)
  888. {
  889. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  890. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  891. $nodeClassname = $this->getStubNodePeerBuilder()->getClassname();
  892. $script .= "
  893. /**
  894. * Inserts the node and its children at the specified childIdx.
  895. *
  896. * @param $nodeClassname Node to insert.
  897. * @param int One-based child index to insert at.
  898. * @param PropelPDO Connection to use.
  899. * @param void
  900. */
  901. protected function insertNewChildNode(\$node, \$childIdx, PropelPDO \$con)
  902. {
  903. if (!\$node->obj->isNew())
  904. throw new PropelException('Failed to insert non-new node.');
  905. \$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME;
  906. \$node->obj->\$setNodePath(\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx);
  907. \$node->obj->save(\$con);
  908. \$i = 1;
  909. foreach (\$node->childNodes as \$childNode)
  910. \$node->insertNewChildNode(\$childNode, \$i++, \$con);
  911. }
  912. ";
  913. }
  914. protected function addAdjustStatus(&$script)
  915. {
  916. $script .= "
  917. /**
  918. * Adjust new/deleted status of node and all children.
  919. *
  920. * @param string Status to change ('New' or 'Deleted')
  921. * @param boolean Value for status.
  922. * @return void
  923. */
  924. protected function adjustStatus(\$status, \$b)
  925. {
  926. \$setStatus = 'set' . \$status;
  927. \$this->obj->\$setStatus(\$b);
  928. foreach (\$this->childNodes as \$childNode)
  929. \$childNode->obj->\$setStatus(\$b);
  930. }
  931. ";
  932. }
  933. protected function addAdjustNodePath(&$script)
  934. {
  935. $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
  936. $script .= "
  937. /**
  938. * Adjust path of node and all children. This is used internally when
  939. * inserting/moving nodes.
  940. *
  941. * @param string Section of old path to change.
  942. * @param string New section to replace old path with.
  943. * @return void
  944. */
  945. protected function adjustNodePath(\$oldBasePath, \$newBasePath)
  946. {
  947. \$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME;
  948. \$this->obj->\$setNodePath(\$newBasePath . substr(\$this->getNodePath(), strlen(\$oldBasePath)));
  949. \$this->obj->resetModified($nodePeerClassname::NPATH_COLNAME);
  950. foreach (\$this->childNodes as \$childNode)
  951. \$childNode->adjustNodePath(\$oldBasePath, \$newBasePath);
  952. }
  953. ";
  954. }
  955. } // PHP5NodeObjectBuilder