PageRenderTime 41ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/src/vendor/propel/generator/lib/builder/om/PHP5ObjectBuilder.php

https://github.com/vjousse/devorigin-symfony2
PHP | 4254 lines | 2412 code | 421 blank | 1421 comment | 319 complexity | 7960399720859539e954434173af5a0f MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, BSD-3-Clause, ISC
  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 'builder/om/ObjectBuilder.php';
  10. /**
  11. * Generates a PHP5 base Object class for user object model (OM).
  12. *
  13. * This class produces the base 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 PHP5ObjectBuilder 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. public function getNamespace()
  30. {
  31. if ($namespace = parent::getNamespace()) {
  32. if ($this->getGeneratorConfig() && $omns = $this->getGeneratorConfig()->getBuildProperty('namespaceOm')) {
  33. return $namespace . '\\' . $omns;
  34. } else {
  35. return $namespace;
  36. }
  37. }
  38. }
  39. /**
  40. * Returns the name of the current class being built.
  41. * @return string
  42. */
  43. public function getUnprefixedClassname()
  44. {
  45. return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname();
  46. }
  47. /**
  48. * Validates the current table to make sure that it won't
  49. * result in generated code that will not parse.
  50. *
  51. * This method may emit warnings for code which may cause problems
  52. * and will throw exceptions for errors that will definitely cause
  53. * problems.
  54. */
  55. protected function validateModel()
  56. {
  57. parent::validateModel();
  58. $table = $this->getTable();
  59. // Check to see whether any generated foreign key names
  60. // will conflict with column names.
  61. $colPhpNames = array();
  62. $fkPhpNames = array();
  63. foreach ($table->getColumns() as $col) {
  64. $colPhpNames[] = $col->getPhpName();
  65. }
  66. foreach ($table->getForeignKeys() as $fk) {
  67. $fkPhpNames[] = $this->getFKPhpNameAffix($fk, $plural = false);
  68. }
  69. $intersect = array_intersect($colPhpNames, $fkPhpNames);
  70. if (!empty($intersect)) {
  71. throw new EngineException("One or more of your column names for [" . $table->getName() . "] table conflict with foreign key names (" . implode(", ", $intersect) . ")");
  72. }
  73. // Check foreign keys to see if there are any foreign keys that
  74. // are also matched with an inversed referencing foreign key
  75. // (this is currently unsupported behavior)
  76. // see: http://propel.phpdb.org/trac/ticket/549
  77. foreach ($table->getForeignKeys() as $fk) {
  78. if ($fk->isMatchedByInverseFK()) {
  79. throw new EngineException("The 1:1 relationship expressed by foreign key " . $fk->getName() . " is defined in both directions; Propel does not currently support this (if you must have both foreign key constraints, consider adding this constraint with a custom SQL file.)" );
  80. }
  81. }
  82. }
  83. /**
  84. * Returns the appropriate formatter (from platform) for a date/time column.
  85. * @param Column $col
  86. * @return string
  87. */
  88. protected function getTemporalFormatter(Column $col)
  89. {
  90. $fmt = null;
  91. if ($col->getType() === PropelTypes::DATE) {
  92. $fmt = $this->getPlatform()->getDateFormatter();
  93. } elseif ($col->getType() === PropelTypes::TIME) {
  94. $fmt = $this->getPlatform()->getTimeFormatter();
  95. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  96. $fmt = $this->getPlatform()->getTimestampFormatter();
  97. }
  98. return $fmt;
  99. }
  100. /**
  101. * Returns the type-casted and stringified default value for the specified Column.
  102. * This only works for scalar default values currently.
  103. * @return string The default value or 'NULL' if there is none.
  104. */
  105. protected function getDefaultValueString(Column $col)
  106. {
  107. $defaultValue = var_export(null, true);
  108. if (($val = $col->getPhpDefaultValue()) !== null) {
  109. if ($col->isTemporalType()) {
  110. $fmt = $this->getTemporalFormatter($col);
  111. try {
  112. if (!($this->getPlatform() instanceof MysqlPlatform &&
  113. ($val === '0000-00-00 00:00:00' || $val === '0000-00-00'))) {
  114. // while technically this is not a default value of NULL,
  115. // this seems to be closest in meaning.
  116. $defDt = new DateTime($val);
  117. $defaultValue = var_export($defDt->format($fmt), true);
  118. }
  119. } catch (Exception $x) {
  120. // prevent endless loop when timezone is undefined
  121. date_default_timezone_set('America/Los_Angeles');
  122. throw new EngineException("Unable to parse default temporal value for " . $col->getFullyQualifiedName() . ": " .$this->getDefaultValueString($col), $x);
  123. }
  124. } else {
  125. if ($col->isPhpPrimitiveType()) {
  126. settype($val, $col->getPhpType());
  127. $defaultValue = var_export($val, true);
  128. } elseif ($col->isPhpObjectType()) {
  129. $defaultValue = 'new '.$col->getPhpType().'(' . var_export($val, true) . ')';
  130. } else {
  131. throw new EngineException("Cannot get default value string for " . $col->getFullyQualifiedName());
  132. }
  133. }
  134. }
  135. return $defaultValue;
  136. }
  137. /**
  138. * Adds the include() statements for files that this class depends on or utilizes.
  139. * @param string &$script The script will be modified in this method.
  140. */
  141. protected function addIncludes(&$script)
  142. {
  143. } // addIncludes()
  144. /**
  145. * Adds class phpdoc comment and openning of class.
  146. * @param string &$script The script will be modified in this method.
  147. */
  148. protected function addClassOpen(&$script)
  149. {
  150. $table = $this->getTable();
  151. $tableName = $table->getName();
  152. $tableDesc = $table->getDescription();
  153. $interface = $this->getInterface();
  154. $parentClass = $this->getBehaviorContent('parentClass');
  155. $parentClass = (null !== $parentClass) ? $parentClass : ClassTools::classname($this->getBaseClass());
  156. $script .= "
  157. /**
  158. * Base class that represents a row from the '$tableName' table.
  159. *
  160. * $tableDesc
  161. *";
  162. if ($this->getBuildProperty('addTimeStamp')) {
  163. $now = strftime('%c');
  164. $script .= "
  165. * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
  166. *
  167. * $now
  168. *";
  169. }
  170. $script .= "
  171. * @package propel.generator.".$this->getPackage()."
  172. */
  173. abstract class ".$this->getClassname()." extends ".$parentClass." ";
  174. $interface = ClassTools::getInterface($table);
  175. if ($interface) {
  176. $script .= " implements " . ClassTools::classname($interface);
  177. }
  178. if ($this->getTable()->getInterface()) {
  179. $this->declareClassFromBuilder($this->getInterfaceBuilder());
  180. }
  181. $script .= "
  182. {
  183. ";
  184. }
  185. /**
  186. * Specifies the methods that are added as part of the basic OM class.
  187. * This can be overridden by subclasses that wish to add more methods.
  188. * @see ObjectBuilder::addClassBody()
  189. */
  190. protected function addClassBody(&$script)
  191. {
  192. $this->declareClassFromBuilder($this->getStubPeerBuilder());
  193. $this->declareClassFromBuilder($this->getStubQueryBuilder());
  194. $this->declareClasses('Propel', 'PropelException', 'PDO', 'PropelPDO', 'Criteria', 'BaseObject', 'Persistent', 'BasePeer', 'PropelObjectcollection');
  195. $table = $this->getTable();
  196. if (!$table->isAlias()) {
  197. $this->addConstants($script);
  198. $this->addAttributes($script);
  199. }
  200. if ($this->hasDefaultValues()) {
  201. $this->addApplyDefaultValues($script);
  202. $this->addConstructor($script);
  203. }
  204. $this->addColumnAccessorMethods($script);
  205. $this->addColumnMutatorMethods($script);
  206. $this->addHasOnlyDefaultValues($script);
  207. $this->addHydrate($script);
  208. $this->addEnsureConsistency($script);
  209. if (!$table->isReadOnly()) {
  210. $this->addManipulationMethods($script);
  211. }
  212. if ($this->isAddValidateMethod()) {
  213. $this->addValidationMethods($script);
  214. }
  215. if ($this->isAddGenericAccessors()) {
  216. $this->addGetByName($script);
  217. $this->addGetByPosition($script);
  218. $this->addToArray($script);
  219. }
  220. if ($this->isAddGenericMutators()) {
  221. $this->addSetByName($script);
  222. $this->addSetByPosition($script);
  223. $this->addFromArray($script);
  224. }
  225. $this->addBuildCriteria($script);
  226. $this->addBuildPkeyCriteria($script);
  227. $this->addGetPrimaryKey($script);
  228. $this->addSetPrimaryKey($script);
  229. $this->addIsPrimaryKeyNull($script);
  230. $this->addCopy($script);
  231. if (!$table->isAlias()) {
  232. $this->addGetPeer($script);
  233. }
  234. $this->addFKMethods($script);
  235. $this->addRefFKMethods($script);
  236. $this->addCrossFKMethods($script);
  237. $this->addClear($script);
  238. $this->addClearAllReferences($script);
  239. $this->addPrimaryString($script);
  240. // apply behaviors
  241. $this->applyBehaviorModifier('objectMethods', $script, " ");
  242. $this->addMagicCall($script);
  243. }
  244. /**
  245. * Closes class.
  246. * @param string &$script The script will be modified in this method.
  247. */
  248. protected function addClassClose(&$script)
  249. {
  250. $script .= "
  251. } // " . $this->getClassname() . "
  252. ";
  253. $this->applyBehaviorModifier('objectFilter', $script, "");
  254. }
  255. /**
  256. * Adds any constants to the class.
  257. * @param string &$script The script will be modified in this method.
  258. */
  259. protected function addConstants(&$script)
  260. {
  261. $script .= "
  262. /**
  263. * Peer class name
  264. */
  265. const PEER = '" . addslashes($this->getStubPeerBuilder()->getFullyQualifiedClassname()) . "';
  266. ";
  267. }
  268. /**
  269. * Adds class attributes.
  270. * @param string &$script The script will be modified in this method.
  271. */
  272. protected function addAttributes(&$script)
  273. {
  274. $table = $this->getTable();
  275. $script .= "
  276. /**
  277. * The Peer class.
  278. * Instance provides a convenient way of calling static methods on a class
  279. * that calling code may not be able to identify.
  280. * @var ".$this->getPeerClassname()."
  281. */
  282. protected static \$peer;
  283. ";
  284. if (!$table->isAlias()) {
  285. $this->addColumnAttributes($script);
  286. }
  287. foreach ($table->getForeignKeys() as $fk) {
  288. $this->addFKAttributes($script, $fk);
  289. }
  290. foreach ($table->getReferrers() as $refFK) {
  291. $this->addRefFKAttributes($script, $refFK);
  292. }
  293. // many-to-many relationships
  294. foreach ($table->getCrossFks() as $fkList) {
  295. $crossFK = $fkList[1];
  296. $this->addCrossFKAttributes($script, $crossFK);
  297. }
  298. $this->addAlreadyInSaveAttribute($script);
  299. $this->addAlreadyInValidationAttribute($script);
  300. // apply behaviors
  301. $this->applyBehaviorModifier('objectAttributes', $script, " ");
  302. }
  303. /**
  304. * Adds variables that store column values.
  305. * @param string &$script The script will be modified in this method.
  306. * @see addColumnNameConstants()
  307. */
  308. protected function addColumnAttributes(&$script)
  309. {
  310. $table = $this->getTable();
  311. foreach ($table->getColumns() as $col) {
  312. $this->addColumnAttributeComment($script, $col);
  313. $this->addColumnAttributeDeclaration($script, $col);
  314. if ($col->isLazyLoad() ) {
  315. $this->addColumnAttributeLoaderComment($script, $col);
  316. $this->addColumnAttributeLoaderDeclaration($script, $col);
  317. }
  318. }
  319. }
  320. /**
  321. * Add comment about the attribute (variable) that stores column values
  322. * @param string &$script The script will be modified in this method.
  323. * @param Column $col
  324. **/
  325. protected function addColumnAttributeComment(&$script, Column $col)
  326. {
  327. $cptype = $col->getPhpType();
  328. $clo = strtolower($col->getName());
  329. $script .= "
  330. /**
  331. * The value for the $clo field.";
  332. if ($col->getDefaultValue()) {
  333. if ($col->getDefaultValue()->isExpression()) {
  334. $script .= "
  335. * Note: this column has a database default value of: (expression) ".$col->getDefaultValue()->getValue();
  336. } else {
  337. $script .= "
  338. * Note: this column has a database default value of: ". $this->getDefaultValueString($col);
  339. }
  340. }
  341. $script .= "
  342. * @var $cptype
  343. */";
  344. }
  345. /**
  346. * Adds the declaration of a column value storage attribute
  347. * @param string &$script The script will be modified in this method.
  348. * @param Column $col
  349. **/
  350. protected function addColumnAttributeDeclaration(&$script, Column $col)
  351. {
  352. $clo = strtolower($col->getName());
  353. $script .= "
  354. protected \$" . $clo . ";
  355. ";
  356. }
  357. /**
  358. * Adds the comment about the attribute keeping track if an attribute value has been loaded
  359. * @param string &$script The script will be modified in this method.
  360. * @param Column $col
  361. **/
  362. protected function addColumnAttributeLoaderComment(&$script, Column $col)
  363. {
  364. $clo = strtolower($col->getName());
  365. $script .= "
  366. /**
  367. * Whether the lazy-loaded \$$clo value has been loaded from database.
  368. * This is necessary to avoid repeated lookups if \$$clo column is NULL in the db.
  369. * @var boolean
  370. */";
  371. }
  372. /**
  373. * Adds the declaration of the attribute keeping track of an attribute's loaded state
  374. * @param string &$script The script will be modified in this method.
  375. * @param Column $col
  376. **/
  377. protected function addColumnAttributeLoaderDeclaration(&$script, Column $col)
  378. {
  379. $clo = strtolower($col->getName());
  380. $script .= "
  381. protected \$".$clo."_isLoaded = false;
  382. ";
  383. }
  384. /**
  385. * Adds the getPeer() method.
  386. * This is a convenient, non introspective way of getting the Peer class for a particular object.
  387. * @param string &$script The script will be modified in this method.
  388. */
  389. protected function addGetPeer(&$script)
  390. {
  391. $this->addGetPeerComment($script);
  392. $this->addGetPeerFunctionOpen($script);
  393. $this->addGetPeerFunctionBody($script);
  394. $this->addGetPeerFunctionClose($script);
  395. }
  396. /**
  397. * Add the comment for the getPeer method
  398. * @param string &$script The script will be modified in this method.
  399. **/
  400. protected function addGetPeerComment(&$script) {
  401. $script .= "
  402. /**
  403. * Returns a peer instance associated with this om.
  404. *
  405. * Since Peer classes are not to have any instance attributes, this method returns the
  406. * same instance for all member of this class. The method could therefore
  407. * be static, but this would prevent one from overriding the behavior.
  408. *
  409. * @return ".$this->getPeerClassname()."
  410. */";
  411. }
  412. /**
  413. * Adds the function declaration (function opening) for the getPeer method
  414. * @param string &$script The script will be modified in this method.
  415. **/
  416. protected function addGetPeerFunctionOpen(&$script) {
  417. $script .= "
  418. public function getPeer()
  419. {";
  420. }
  421. /**
  422. * Adds the body of the getPeer method
  423. * @param string &$script The script will be modified in this method.
  424. **/
  425. protected function addGetPeerFunctionBody(&$script) {
  426. $script .= "
  427. if (self::\$peer === null) {
  428. " . $this->buildObjectInstanceCreationCode('self::$peer', $this->getPeerClassname()) . "
  429. }
  430. return self::\$peer;";
  431. }
  432. /**
  433. * Add the function close for the getPeer method
  434. * Note: this is just a } and the body ends with a return statement, so it's quite useless. But it's here anyway for consisency, cause there's a close function for all functions and in some other instances, they are useful
  435. * @param string &$script The script will be modified in this method.
  436. **/
  437. protected function addGetPeerFunctionClose(&$script) {
  438. $script .= "
  439. }
  440. ";
  441. }
  442. /**
  443. * Adds the constructor for this object.
  444. * @param string &$script The script will be modified in this method.
  445. * @see addConstructor()
  446. */
  447. protected function addConstructor(&$script)
  448. {
  449. $this->addConstructorComment($script);
  450. $this->addConstructorOpen($script);
  451. $this->addConstructorBody($script);
  452. $this->addConstructorClose($script);
  453. }
  454. /**
  455. * Adds the comment for the constructor
  456. * @param string &$script The script will be modified in this method.
  457. **/
  458. protected function addConstructorComment(&$script) {
  459. $script .= "
  460. /**
  461. * Initializes internal state of ".$this->getClassname()." object.
  462. * @see applyDefaults()
  463. */";
  464. }
  465. /**
  466. * Adds the function declaration for the constructor
  467. * @param string &$script The script will be modified in this method.
  468. **/
  469. protected function addConstructorOpen(&$script) {
  470. $script .= "
  471. public function __construct()
  472. {";
  473. }
  474. /**
  475. * Adds the function body for the constructor
  476. * @param string &$script The script will be modified in this method.
  477. **/
  478. protected function addConstructorBody(&$script) {
  479. $script .= "
  480. parent::__construct();
  481. \$this->applyDefaultValues();";
  482. }
  483. /**
  484. * Adds the function close for the constructor
  485. * @param string &$script The script will be modified in this method.
  486. **/
  487. protected function addConstructorClose(&$script) {
  488. $script .= "
  489. }
  490. ";
  491. }
  492. /**
  493. * Adds the applyDefaults() method, which is called from the constructor.
  494. * @param string &$script The script will be modified in this method.
  495. * @see addConstructor()
  496. */
  497. protected function addApplyDefaultValues(&$script)
  498. {
  499. $this->addApplyDefaultValuesComment($script);
  500. $this->addApplyDefaultValuesOpen($script);
  501. $this->addApplyDefaultValuesBody($script);
  502. $this->addApplyDefaultValuesClose($script);
  503. }
  504. /**
  505. * Adds the comment for the applyDefaults method
  506. * @param string &$script The script will be modified in this method.
  507. * @see addApplyDefaultValues()
  508. **/
  509. protected function addApplyDefaultValuesComment(&$script) {
  510. $script .= "
  511. /**
  512. * Applies default values to this object.
  513. * This method should be called from the object's constructor (or
  514. * equivalent initialization method).
  515. * @see __construct()
  516. */";
  517. }
  518. /**
  519. * Adds the function declaration for the applyDefaults method
  520. * @param string &$script The script will be modified in this method.
  521. * @see addApplyDefaultValues()
  522. **/
  523. protected function addApplyDefaultValuesOpen(&$script) {
  524. $script .= "
  525. public function applyDefaultValues()
  526. {";
  527. }
  528. /**
  529. * Adds the function body of the applyDefault method
  530. * @param string &$script The script will be modified in this method.
  531. * @see addApplyDefaultValues()
  532. **/
  533. protected function addApplyDefaultValuesBody(&$script) {
  534. $table = $this->getTable();
  535. // FIXME - Apply support for PHP default expressions here
  536. // see: http://propel.phpdb.org/trac/ticket/378
  537. $colsWithDefaults = array();
  538. foreach ($table->getColumns() as $col) {
  539. $def = $col->getDefaultValue();
  540. if ($def !== null && !$def->isExpression()) {
  541. $colsWithDefaults[] = $col;
  542. }
  543. }
  544. $colconsts = array();
  545. foreach ($colsWithDefaults as $col) {
  546. $clo = strtolower($col->getName());
  547. $script .= "
  548. \$this->".$clo." = ".$this->getDefaultValueString($col).";";
  549. }
  550. }
  551. /**
  552. * Adds the function close for the applyDefaults method
  553. * @param string &$script The script will be modified in this method.
  554. * @see addApplyDefaultValues()
  555. **/
  556. protected function addApplyDefaultValuesClose(&$script) {
  557. $script .= "
  558. }
  559. ";
  560. }
  561. // --------------------------------------------------------------
  562. //
  563. // A C C E S S O R M E T H O D S
  564. //
  565. // --------------------------------------------------------------
  566. /**
  567. * Adds a date/time/timestamp getter method.
  568. * @param string &$script The script will be modified in this method.
  569. * @param Column $col The current column.
  570. * @see parent::addColumnAccessors()
  571. */
  572. protected function addTemporalAccessor(&$script, Column $col)
  573. {
  574. $this->addTemporalAccessorComment($script, $col);
  575. $this->addTemporalAccessorOpen($script, $col);
  576. $this->addTemporalAccessorBody($script, $col);
  577. $this->addTemporalAccessorClose($script, $col);
  578. } // addTemporalAccessor
  579. /**
  580. * Adds the comment for a temporal accessor
  581. * @param string &$script The script will be modified in this method.
  582. * @param Column $col The current column.
  583. * @see addTemporalAccessor
  584. **/
  585. protected function addTemporalAccessorComment(&$script, Column $col) {
  586. $clo = strtolower($col->getName());
  587. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  588. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  589. if (!$dateTimeClass) {
  590. $dateTimeClass = 'DateTime';
  591. }
  592. $handleMysqlDate = false;
  593. if ($this->getPlatform() instanceof MysqlPlatform) {
  594. if ($col->getType() === PropelTypes::TIMESTAMP) {
  595. $handleMysqlDate = true;
  596. $mysqlInvalidDateString = '0000-00-00 00:00:00';
  597. } elseif ($col->getType() === PropelTypes::DATE) {
  598. $handleMysqlDate = true;
  599. $mysqlInvalidDateString = '0000-00-00';
  600. }
  601. // 00:00:00 is a valid time, so no need to check for that.
  602. }
  603. $script .= "
  604. /**
  605. * Get the [optionally formatted] temporal [$clo] column value.
  606. * ".$col->getDescription();
  607. if (!$useDateTime) {
  608. $script .= "
  609. * This accessor only only work with unix epoch dates. Consider enabling the propel.useDateTimeClass
  610. * option in order to avoid converstions to integers (which are limited in the dates they can express).";
  611. }
  612. $script .= "
  613. *
  614. * @param string \$format The date/time format string (either date()-style or strftime()-style).
  615. * If format is NULL, then the raw ".($useDateTime ? 'DateTime object' : 'unix timestamp integer')." will be returned.";
  616. if ($useDateTime) {
  617. $script .= "
  618. * @return mixed Formatted date/time value as string or $dateTimeClass object (if format is NULL), NULL if column is NULL" .($handleMysqlDate ? ', and 0 if column value is ' . $mysqlInvalidDateString : '');
  619. } else {
  620. $script .= "
  621. * @return mixed Formatted date/time value as string or (integer) unix timestamp (if format is NULL), NULL if column is NULL".($handleMysqlDate ? ', and 0 if column value is ' . $mysqlInvalidDateString : '');
  622. }
  623. $script .= "
  624. * @throws PropelException - if unable to parse/validate the date/time value.
  625. */";
  626. }
  627. /**
  628. * Adds the function declaration for a temporal accessor
  629. * @param string &$script The script will be modified in this method.
  630. * @param Column $col The current column.
  631. * @see addTemporalAccessor
  632. **/
  633. protected function addTemporalAccessorOpen(&$script, Column $col) {
  634. $cfc = $col->getPhpName();
  635. $defaultfmt = null;
  636. $visibility = $col->getAccessorVisibility();
  637. // Default date/time formatter strings are specified in build.properties
  638. if ($col->getType() === PropelTypes::DATE) {
  639. $defaultfmt = $this->getBuildProperty('defaultDateFormat');
  640. } elseif ($col->getType() === PropelTypes::TIME) {
  641. $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
  642. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  643. $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
  644. }
  645. if (empty($defaultfmt)) { $defaultfmt = null; }
  646. $script .= "
  647. ".$visibility." function get$cfc(\$format = ".var_export($defaultfmt, true)."";
  648. if ($col->isLazyLoad()) $script .= ", \$con = null";
  649. $script .= ")
  650. {";
  651. }
  652. /**
  653. * Adds the body of the temporal accessor
  654. * @param string &$script The script will be modified in this method.
  655. * @param Column $col The current column.
  656. * @see addTemporalAccessor
  657. **/
  658. protected function addTemporalAccessorBody(&$script, Column $col) {
  659. $cfc = $col->getPhpName();
  660. $clo = strtolower($col->getName());
  661. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  662. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  663. if (!$dateTimeClass) {
  664. $dateTimeClass = 'DateTime';
  665. }
  666. $this->declareClasses($dateTimeClass);
  667. $defaultfmt = null;
  668. // Default date/time formatter strings are specified in build.properties
  669. if ($col->getType() === PropelTypes::DATE) {
  670. $defaultfmt = $this->getBuildProperty('defaultDateFormat');
  671. } elseif ($col->getType() === PropelTypes::TIME) {
  672. $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
  673. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  674. $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
  675. }
  676. if (empty($defaultfmt)) { $defaultfmt = null; }
  677. $handleMysqlDate = false;
  678. if ($this->getPlatform() instanceof MysqlPlatform) {
  679. if ($col->getType() === PropelTypes::TIMESTAMP) {
  680. $handleMysqlDate = true;
  681. $mysqlInvalidDateString = '0000-00-00 00:00:00';
  682. } elseif ($col->getType() === PropelTypes::DATE) {
  683. $handleMysqlDate = true;
  684. $mysqlInvalidDateString = '0000-00-00';
  685. }
  686. // 00:00:00 is a valid time, so no need to check for that.
  687. }
  688. if ($col->isLazyLoad()) {
  689. $script .= "
  690. if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
  691. \$this->load$cfc(\$con);
  692. }
  693. ";
  694. }
  695. $script .= "
  696. if (\$this->$clo === null) {
  697. return null;
  698. }
  699. ";
  700. if ($handleMysqlDate) {
  701. $script .= "
  702. if (\$this->$clo === '$mysqlInvalidDateString') {
  703. // while technically this is not a default value of NULL,
  704. // this seems to be closest in meaning.
  705. return null;
  706. } else {
  707. try {
  708. \$dt = new $dateTimeClass(\$this->$clo);
  709. } catch (Exception \$x) {
  710. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  711. }
  712. }
  713. ";
  714. } else {
  715. $script .= "
  716. try {
  717. \$dt = new $dateTimeClass(\$this->$clo);
  718. } catch (Exception \$x) {
  719. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  720. }
  721. ";
  722. } // if handleMyqlDate
  723. $script .= "
  724. if (\$format === null) {";
  725. if ($useDateTime) {
  726. $script .= "
  727. // Because propel.useDateTimeClass is TRUE, we return a $dateTimeClass object.
  728. return \$dt;";
  729. } else {
  730. $script .= "
  731. // We cast here to maintain BC in API; obviously we will lose data if we're dealing with pre-/post-epoch dates.
  732. return (int) \$dt->format('U');";
  733. }
  734. $script .= "
  735. } elseif (strpos(\$format, '%') !== false) {
  736. return strftime(\$format, \$dt->format('U'));
  737. } else {
  738. return \$dt->format(\$format);
  739. }";
  740. }
  741. /**
  742. * Adds the body of the temporal accessor
  743. * @param string &$script The script will be modified in this method.
  744. * @param Column $col The current column.
  745. * @see addTemporalAccessorClose
  746. **/
  747. protected function addTemporalAccessorClose(&$script, Column $col) {
  748. $script .= "
  749. }
  750. ";
  751. }
  752. /**
  753. * Adds a normal (non-temporal) getter method.
  754. * @param string &$script The script will be modified in this method.
  755. * @param Column $col The current column.
  756. * @see parent::addColumnAccessors()
  757. */
  758. protected function addDefaultAccessor(&$script, Column $col)
  759. {
  760. $this->addDefaultAccessorComment($script, $col);
  761. $this->addDefaultAccessorOpen($script, $col);
  762. $this->addDefaultAccessorBody($script, $col);
  763. $this->addDefaultAccessorClose($script, $col);
  764. }
  765. /**
  766. * Add the comment for a default accessor method (a getter)
  767. * @param string &$script The script will be modified in this method.
  768. * @param Column $col The current column.
  769. * @see addDefaultAccessor()
  770. **/
  771. protected function addDefaultAccessorComment(&$script, Column $col) {
  772. $clo=strtolower($col->getName());
  773. $script .= "
  774. /**
  775. * Get the [$clo] column value.
  776. * ".$col->getDescription();
  777. if ($col->isLazyLoad()) {
  778. $script .= "
  779. * @param PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  780. }
  781. $script .= "
  782. * @return ".$col->getPhpType()."
  783. */";
  784. }
  785. /**
  786. * Adds the function declaration for a default accessor
  787. * @param string &$script The script will be modified in this method.
  788. * @param Column $col The current column.
  789. * @see addDefaultAccessor()
  790. **/
  791. protected function addDefaultAccessorOpen(&$script, Column $col) {
  792. $cfc = $col->getPhpName();
  793. $visibility = $col->getAccessorVisibility();
  794. $script .= "
  795. ".$visibility." function get$cfc(";
  796. if ($col->isLazyLoad()) $script .= "PropelPDO \$con = null";
  797. $script .= ")
  798. {";
  799. }
  800. /**
  801. * Adds the function body for a default accessor method
  802. * @param string &$script The script will be modified in this method.
  803. * @param Column $col The current column.
  804. * @see addDefaultAccessor()
  805. **/
  806. protected function addDefaultAccessorBody(&$script, Column $col) {
  807. $cfc = $col->getPhpName();
  808. $clo = strtolower($col->getName());
  809. if ($col->isLazyLoad()) {
  810. $script .= "
  811. if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
  812. \$this->load$cfc(\$con);
  813. }
  814. ";
  815. }
  816. $script .= "
  817. return \$this->$clo;";
  818. }
  819. /**
  820. * Adds the function close for a default accessor method
  821. * @param string &$script The script will be modified in this method.
  822. * @param Column $col The current column.
  823. * @see addDefaultAccessor()
  824. **/
  825. protected function addDefaultAccessorClose(&$script, Column $col) {
  826. $script .= "
  827. }
  828. ";
  829. }
  830. /**
  831. * Adds the lazy loader method.
  832. * @param string &$script The script will be modified in this method.
  833. * @param Column $col The current column.
  834. * @see parent::addColumnAccessors()
  835. */
  836. protected function addLazyLoader(&$script, Column $col)
  837. {
  838. $this->addLazyLoaderComment($script, $col);
  839. $this->addLazyLoaderOpen($script, $col);
  840. $this->addLazyLoaderBody($script, $col);
  841. $this->addLazyLoaderClose($script, $col);
  842. }
  843. /**
  844. * Adds the comment for the lazy loader method
  845. * @param string &$script The script will be modified in this method.
  846. * @param Column $col The current column.
  847. * @see addLazyLoader()
  848. **/
  849. protected function addLazyLoaderComment(&$script, Column $col) {
  850. $clo = strtolower($col->getName());
  851. $script .= "
  852. /**
  853. * Load the value for the lazy-loaded [$clo] column.
  854. *
  855. * This method performs an additional query to return the value for
  856. * the [$clo] column, since it is not populated by
  857. * the hydrate() method.
  858. *
  859. * @param \$con PropelPDO (optional) The PropelPDO connection to use.
  860. * @return void
  861. * @throws PropelException - any underlying error will be wrapped and re-thrown.
  862. */";
  863. }
  864. /**
  865. * Adds the function declaration for the lazy loader method
  866. * @param string &$script The script will be modified in this method.
  867. * @param Column $col The current column.
  868. * @see addLazyLoader()
  869. **/
  870. protected function addLazyLoaderOpen(&$script, Column $col) {
  871. $cfc = $col->getPhpName();
  872. $script .= "
  873. protected function load$cfc(PropelPDO \$con = null)
  874. {";
  875. }
  876. /**
  877. * Adds the function body for the lazy loader method
  878. * @param string &$script The script will be modified in this method.
  879. * @param Column $col The current column.
  880. * @see addLazyLoader()
  881. **/
  882. protected function addLazyLoaderBody(&$script, Column $col) {
  883. $platform = $this->getPlatform();
  884. $clo = strtolower($col->getName());
  885. $script .= "
  886. \$c = \$this->buildPkeyCriteria();
  887. \$c->addSelectColumn(".$this->getColumnConstant($col).");
  888. try {
  889. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
  890. \$row = \$stmt->fetch(PDO::FETCH_NUM);
  891. \$stmt->closeCursor();";
  892. if ($col->getType() === PropelTypes::CLOB && $this->getPlatform() instanceof OraclePlatform) {
  893. // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
  894. $script .= "
  895. \$this->$clo = stream_get_contents(\$row[0]);";
  896. } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
  897. $script .= "
  898. if (\$row[0] !== null) {
  899. \$this->$clo = fopen('php://memory', 'r+');
  900. fwrite(\$this->$clo, \$row[0]);
  901. rewind(\$this->$clo);
  902. } else {
  903. \$this->$clo = null;
  904. }";
  905. } elseif ($col->isPhpPrimitiveType()) {
  906. $script .= "
  907. \$this->$clo = (\$row[0] !== null) ? (".$col->getPhpType().") \$row[0] : null;";
  908. } elseif ($col->isPhpObjectType()) {
  909. $script .= "
  910. \$this->$clo = (\$row[0] !== null) ? new ".$col->getPhpType()."(\$row[0]) : null;";
  911. } else {
  912. $script .= "
  913. \$this->$clo = \$row[0];";
  914. }
  915. $script .= "
  916. \$this->".$clo."_isLoaded = true;
  917. } catch (Exception \$e) {
  918. throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e);
  919. }";
  920. }
  921. /**
  922. * Adds the function close for the lazy loader
  923. * @param string &$script The script will be modified in this method.
  924. * @param Column $col The current column.
  925. * @see addLazyLoader()
  926. **/
  927. protected function addLazyLoaderClose(&$script, Column $col) {
  928. $script .= "
  929. }";
  930. } // addLazyLoader()
  931. // --------------------------------------------------------------
  932. //
  933. // M U T A T O R M E T H O D S
  934. //
  935. // --------------------------------------------------------------
  936. /**
  937. * Adds the open of the mutator (setter) method for a column.
  938. * @param string &$script The script will be modified in this method.
  939. * @param Column $col The current column.
  940. */
  941. protected function addMutatorOpen(&$script, Column $col)
  942. {
  943. $this->addMutatorComment($script, $col);
  944. $this->addMutatorOpenOpen($script, $col);
  945. $this->addMutatorOpenBody($script, $col);
  946. }
  947. /**
  948. * Adds the comment for a mutator
  949. * @param string &$script The script will be modified in this method.
  950. * @param Column $col The current column.
  951. * @see addMutatorOpen()
  952. **/
  953. protected function addMutatorComment(&$script, Column $col) {
  954. $clo = strtolower($col->getName());
  955. $script .= "
  956. /**
  957. * Set the value of [$clo] column.
  958. * ".$col->getDescription()."
  959. * @param ".$col->getPhpType()." \$v new value
  960. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  961. */";
  962. }
  963. /**
  964. * Adds the mutator function declaration
  965. * @param string &$script The script will be modified in this method.
  966. * @param Column $col The current column.
  967. * @see addMutatorOpen()
  968. **/
  969. protected function addMutatorOpenOpen(&$script, Column $col) {
  970. $cfc = $col->getPhpName();
  971. $visibility = $col->getMutatorVisibility();
  972. $script .= "
  973. ".$visibility." function set$cfc(\$v)
  974. {";
  975. }
  976. /**
  977. * Adds the mutator open body part
  978. * @param string &$script The script will be modified in this method.
  979. * @param Column $col The current column.
  980. * @see addMutatorOpen()
  981. **/
  982. protected function addMutatorOpenBody(&$script, Column $col) {
  983. $clo = strtolower($col->getName());
  984. $cfc = $col->getPhpName();
  985. if ($col->isLazyLoad()) {
  986. $script .= "
  987. // explicitly set the is-loaded flag to true for this lazy load col;
  988. // it doesn't matter if the value is actually set or not (logic below) as
  989. // any attempt to set the value means that no db lookup should be performed
  990. // when the get$cfc() method is called.
  991. \$this->".$clo."_isLoaded = true;
  992. ";
  993. }
  994. }
  995. /**
  996. * Adds the close of the mutator (setter) method for a column.
  997. *
  998. * @param string &$script The script will be modified in this method.
  999. * @param Column $col The current column.
  1000. */
  1001. protected function addMutatorClose(&$script, Column $col)
  1002. {
  1003. $this->addMutatorCloseBody($script, $col);
  1004. $this->addMutatorCloseClose($script, $col);
  1005. }
  1006. /**
  1007. * Adds the body of the close part of a mutator
  1008. * @param string &$script The script will be modified in this method.
  1009. * @param Column $col The current column.
  1010. * @see addMutatorClose()
  1011. **/
  1012. protected function addMutatorCloseBody(&$script, Column $col) {
  1013. $table = $this->getTable();
  1014. $cfc = $col->getPhpName();
  1015. $clo = strtolower($col->getName());
  1016. if ($col->isForeignKey()) {
  1017. foreach ($col->getForeignKeys() as $fk) {
  1018. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1019. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1020. $varName = $this->getFKVarName($fk);
  1021. $script .= "
  1022. if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) {
  1023. \$this->$varName = null;
  1024. }
  1025. ";
  1026. } // foreach fk
  1027. } /* if col is foreign key */
  1028. foreach ($col->getReferrers() as $refFK) {
  1029. $tblFK = $this->getDatabase()->getTable($refFK->getForeignTableName());
  1030. if ( $tblFK->getName() != $table->getName() ) {
  1031. foreach ($col->getForeignKeys() as $fk) {
  1032. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1033. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1034. if ($refFK->isLocalPrimaryKey()) {
  1035. $varName = $this->getPKRefFKVarName($refFK);
  1036. $script .= "
  1037. // update associated ".$tblFK->getPhpName()."
  1038. if (\$this->$varName !== null) {
  1039. \$this->{$varName}->set".$colFK->getPhpName()."(\$v);
  1040. }
  1041. ";
  1042. } else {
  1043. $collName = $this->getRefFKCollVarName($refFK);
  1044. $script .= "
  1045. // update associated ".$tblFK->getPhpName()."
  1046. if (\$this->$collName !== null) {
  1047. foreach (\$this->$collName as \$referrerObject) {
  1048. \$referrerObject->set".$colFK->getPhpName()."(\$v);
  1049. }
  1050. }
  1051. ";
  1052. } // if (isLocalPrimaryKey
  1053. } // foreach col->getPrimaryKeys()
  1054. } // if tablFk != table
  1055. } // foreach
  1056. }
  1057. /**
  1058. * Adds the close for the mutator close
  1059. * @param string &$script The script will be modified in this method.
  1060. * @param Column $col The current column.
  1061. * @see addMutatorClose()
  1062. **/
  1063. protected function addMutatorCloseClose(&$script, Column $col) {
  1064. $cfc = $col->getPhpName();
  1065. $script .= "
  1066. return \$this;
  1067. } // set$cfc()
  1068. ";
  1069. }
  1070. /**
  1071. * Adds a setter for BLOB columns.
  1072. * @param string &$script The script will be modified in this method.
  1073. * @param Column $col The current column.
  1074. * @see parent::addColumnMutators()
  1075. */
  1076. protected function addLobMutator(&$script, Column $col)
  1077. {
  1078. $this->addMutatorOpen($script, $col);
  1079. $clo = strtolower($col->getName());
  1080. $script .= "
  1081. // Because BLOB columns are streams in PDO we have to assume that they are
  1082. // always modified when a new value is passed in. For example, the contents
  1083. // of the stream itself may have changed externally.
  1084. if (!is_resource(\$v) && \$v !== null) {
  1085. \$this->$clo = fopen('php://memory', 'r+');
  1086. fwrite(\$this->$clo, \$v);
  1087. rewind(\$this->$clo);
  1088. } else { // it's already a stream
  1089. \$this->$clo = \$v;
  1090. }
  1091. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1092. ";
  1093. $this->addMutatorClose($script, $col);
  1094. } // addLobMutatorSnippet
  1095. /**
  1096. * Adds a setter method for date/time/timestamp columns.
  1097. * @param string &$script The script will be modified in this method.
  1098. * @param Column $col The current column.
  1099. * @see parent::addColumnMutators()
  1100. */
  1101. protected function addTemporalMutator(&$script, Column $col)
  1102. {
  1103. $cfc = $col->getPhpName();
  1104. $clo = strtolower($col->getName());
  1105. $visibility = $col->getMutatorVisibility();
  1106. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  1107. if (!$dateTimeClass) {
  1108. $dateTimeClass = 'DateTime';
  1109. }
  1110. $this->declareClasses($dateTimeClass);
  1111. $script .= "
  1112. /**
  1113. * Sets the value of [$clo] column to a normalized version of the date/time value specified.
  1114. * ".$col->getDescription()."
  1115. * @param mixed \$v string, integer (timestamp), or DateTime value. Empty string will
  1116. * be treated as NULL for temporal objects.
  1117. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1118. */
  1119. ".$visibility." function set$cfc(\$v)
  1120. {";
  1121. if ($col->isLazyLoad()) {
  1122. $script .= "
  1123. // explicitly set the is-loaded flag to true for this lazy load col;
  1124. // it doesn't matter if the value is actually set or not (logic below) as
  1125. // any attempt to set the value means that no db lookup should be performed
  1126. // when the get$cfc() method is called.
  1127. \$this->".$clo."_isLoaded = true;
  1128. ";
  1129. }
  1130. $fmt = var_export($this->getTemporalFormatter($col), true);
  1131. $script .= "
  1132. // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now')
  1133. // -- which is unexpected, to say the least.
  1134. if (\$v === null || \$v === '') {
  1135. \$dt = null;
  1136. } elseif (\$v instanceof DateTime) {
  1137. \$dt = \$v;
  1138. } else {
  1139. // some string/numeric value passed; we normalize that so that we can
  1140. // validate it.
  1141. try {
  1142. if (is_numeric(\$v)) { // if it's a unix timestamp
  1143. \$dt = new $dateTimeClass('@'.\$v, new DateTimeZone('UTC'));
  1144. // We have to explicitly specify and then change the time zone because of a
  1145. // DateTime bug: http://bugs.php.net/bug.php?id=43003
  1146. \$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
  1147. } else {
  1148. \$dt = new $dateTimeClass(\$v);
  1149. }
  1150. } catch (Exception \$x) {
  1151. throw new PropelException('Error parsing date/time value: ' . var_export(\$v, true), \$x);
  1152. }
  1153. }
  1154. if ( \$this->$clo !== null || \$dt !== null ) {
  1155. // (nested ifs are a little easier to read in this case)
  1156. \$currNorm = (\$this->$clo !== null && \$tmpDt = new $dateTimeClass(\$this->$clo)) ? \$tmpDt->format($fmt) : null;
  1157. \$newNorm = (\$dt !== null) ? \$dt->format($fmt) : null;
  1158. if ( (\$currNorm !== \$newNorm) // normalized values don't match ";
  1159. if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
  1160. $defaultValue = $this->getDefaultValueString($col);
  1161. $script .= "
  1162. || (\$dt->format($fmt) === $defaultValue) // or the entered value matches the default";
  1163. }
  1164. $script .= "
  1165. )
  1166. {
  1167. \$this->$clo = (\$dt ? \$dt->format($fmt) : null);
  1168. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1169. }
  1170. } // if either are not null
  1171. ";
  1172. $this->addMutatorClose($script, $col);
  1173. }
  1174. /**
  1175. * Adds setter method for "normal" columns.
  1176. * @param string &$script The script will be modified in this method.
  1177. * @param Column $col The current column.
  1178. * @see parent::addColumnMutators()
  1179. */
  1180. protected function addDefaultMutator(&$script, Column $col)
  1181. {
  1182. $clo = strtolower($col->getName());
  1183. $this->addMutatorOpen($script, $col);
  1184. // Perform type-casting to ensure that we can use type-sensitive
  1185. // checking in mutators.
  1186. if ($col->isPhpPrimitiveType()) {
  1187. $script .= "
  1188. if (\$v !== null) {
  1189. \$v = (".$col->getPhpType().") \$v;
  1190. }
  1191. ";
  1192. }
  1193. $script .= "
  1194. if (\$this->$clo !== \$v";
  1195. if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
  1196. $script .= " || \$this->isNew()";
  1197. }
  1198. $script .= ") {
  1199. \$this->$clo = \$v;
  1200. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1201. }
  1202. ";
  1203. $this->addMutatorClose($script, $col);
  1204. }
  1205. /**
  1206. * Adds the hasOnlyDefaultValues() method.
  1207. * @param string &$script The script will be modified in this method.
  1208. */
  1209. protected function addHasOnlyDefaultValues(&$script)
  1210. {
  1211. $this->addHasOnlyDefaultValuesComment($script);
  1212. $this->addHasOnlyDefaultValuesOpen($script);
  1213. $this->addHasOnlyDefaultValuesBody($script);
  1214. $this->addHasOnlyDefaultValuesClose($script);
  1215. }
  1216. /**
  1217. * Adds the comment for the hasOnlyDefaultValues method
  1218. * @param string &$script The script will be modified in this method.
  1219. * @see addHasOnlyDefaultValues
  1220. **/
  1221. protected function addHasOnlyDefaultValuesComment(&$script) {
  1222. $script .= "
  1223. /**
  1224. * Indicates whether the columns in this object are only set to default values.
  1225. *
  1226. * This method can be used in conjunction with isModified() to indicate whether an object is both
  1227. * modified _and_ has some values set which are non-default.
  1228. *
  1229. * @return boolean Whether the columns in this object are only been set with default values.
  1230. */";
  1231. }
  1232. /**
  1233. * Adds the function declaration for the hasOnlyDefaultValues method
  1234. * @param string &$script The script will be modified in this method.
  1235. * @see addHasOnlyDefaultValues
  1236. **/
  1237. protected function addHasOnlyDefaultValuesOpen(&$script) {
  1238. $script .= "
  1239. public function hasOnlyDefaultValues()
  1240. {";
  1241. }
  1242. /**
  1243. * Adds the function body for the hasOnlyDefaultValues method
  1244. * @param string &$script The script will be modified in this method.
  1245. * @see addHasOnlyDefaultValues
  1246. **/
  1247. protected function addHasOnlyDefaultValuesBody(&$script) {
  1248. $table = $this->getTable();
  1249. $colsWithDefaults = array();
  1250. foreach ($table->getColumns() as $col) {
  1251. $def = $col->getDefaultValue();
  1252. if ($def !== null && !$def->isExpression()) {
  1253. $colsWithDefaults[] = $col;
  1254. }
  1255. }
  1256. foreach ($colsWithDefaults as $col) {
  1257. $clo = strtolower($col->getName());
  1258. $def = $col->getDefaultValue();
  1259. $script .= "
  1260. if (\$this->$clo !== " . $this->getDefaultValueString($col).") {
  1261. return false;
  1262. }
  1263. ";
  1264. }
  1265. }
  1266. /**
  1267. * Adds the function close for the hasOnlyDefaultValues method
  1268. * @param string &$script The script will be modified in this method.
  1269. * @see addHasOnlyDefaultValues
  1270. **/
  1271. protected function addHasOnlyDefaultValuesClose(&$script) {
  1272. $script .= "
  1273. // otherwise, everything was equal, so return TRUE
  1274. return true;";
  1275. $script .= "
  1276. } // hasOnlyDefaultValues()
  1277. ";
  1278. }
  1279. /**
  1280. * Adds the hydrate() method, which sets attributes of the object based on a ResultSet.
  1281. * @param string &$script The script will be modified in this method.
  1282. */
  1283. protected function addHydrate(&$script)
  1284. {
  1285. $this->addHydrateComment($script);
  1286. $this->addHydrateOpen($script);
  1287. $this->addHydrateBody($script);
  1288. $this->addHydrateClose($script);
  1289. }
  1290. /**
  1291. * Adds the comment for the hydrate method
  1292. * @param string &$script The script will be modified in this method.
  1293. * @see addHydrate()
  1294. */
  1295. protected function addHydrateComment(&$script) {
  1296. $script .= "
  1297. /**
  1298. * Hydrates (populates) the object variables with values from the database resultset.
  1299. *
  1300. * An offset (0-based \"start column\") is specified so that objects can be hydrated
  1301. * with a subset of the columns in the resultset rows. This is needed, for example,
  1302. * for results of JOIN queries where the resultset row includes columns from two or
  1303. * more tables.
  1304. *
  1305. * @param array \$row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
  1306. * @param int \$startcol 0-based offset column which indicates which restultset column to start with.
  1307. * @param boolean \$rehydrate Whether this object is being re-hydrated from the database.
  1308. * @return int next starting column
  1309. * @throws PropelException - Any caught Exception will be rewrapped as a PropelException.
  1310. */";
  1311. }
  1312. /**
  1313. * Adds the function declaration for the hydrate method
  1314. * @param string &$script The script will be modified in this method.
  1315. * @see addHydrate()
  1316. */
  1317. protected function addHydrateOpen(&$script) {
  1318. $script .= "
  1319. public function hydrate(\$row, \$startcol = 0, \$rehydrate = false)
  1320. {";
  1321. }
  1322. /**
  1323. * Adds the function body for the hydrate method
  1324. * @param string &$script The script will be modified in this method.
  1325. * @see addHydrate()
  1326. */
  1327. protected function addHydrateBody(&$script) {
  1328. $table = $this->getTable();
  1329. $platform = $this->getPlatform();
  1330. $script .= "
  1331. try {
  1332. ";
  1333. $n = 0;
  1334. foreach ($table->getColumns() as $col) {
  1335. if (!$col->isLazyLoad()) {
  1336. $clo = strtolower($col->getName());
  1337. if ($col->getType() === PropelTypes::CLOB_EMU && $this->getPlatform() instanceof OraclePlatform) {
  1338. // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
  1339. $script .= "
  1340. \$this->$clo = stream_get_contents(\$row[\$startcol + $n]);";
  1341. } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
  1342. $script .= "
  1343. if (\$row[\$startcol + $n] !== null) {
  1344. \$this->$clo = fopen('php://memory', 'r+');
  1345. fwrite(\$this->$clo, \$row[\$startcol + $n]);
  1346. rewind(\$this->$clo);
  1347. } else {
  1348. \$this->$clo = null;
  1349. }";
  1350. } elseif ($col->isPhpPrimitiveType()) {
  1351. $script .= "
  1352. \$this->$clo = (\$row[\$startcol + $n] !== null) ? (".$col->getPhpType().") \$row[\$startcol + $n] : null;";
  1353. } elseif ($col->isPhpObjectType()) {
  1354. $script .= "
  1355. \$this->$clo = (\$row[\$startcol + $n] !== null) ? new ".$col->getPhpType()."(\$row[\$startcol + $n]) : null;";
  1356. } else {
  1357. $script .= "
  1358. \$this->$clo = \$row[\$startcol + $n];";
  1359. }
  1360. $n++;
  1361. } // if col->isLazyLoad()
  1362. } /* foreach */
  1363. if ($this->getBuildProperty("addSaveMethod")) {
  1364. $script .= "
  1365. \$this->resetModified();
  1366. ";
  1367. }
  1368. $script .= "
  1369. \$this->setNew(false);
  1370. if (\$rehydrate) {
  1371. \$this->ensureConsistency();
  1372. }
  1373. return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS).
  1374. } catch (Exception \$e) {
  1375. throw new PropelException(\"Error populating ".$this->getStubObjectBuilder()->getClassname()." object\", \$e);
  1376. }";
  1377. }
  1378. /**
  1379. * Adds the function close for the hydrate method
  1380. * @param string &$script The script will be modified in this method.
  1381. * @see addHydrate()
  1382. */
  1383. protected function addHydrateClose(&$script) {
  1384. $script .= "
  1385. }
  1386. ";
  1387. }
  1388. /**
  1389. * Adds the buildPkeyCriteria method
  1390. * @param string &$script The script will be modified in this method.
  1391. **/
  1392. protected function addBuildPkeyCriteria(&$script) {
  1393. $this->addBuildPkeyCriteriaComment($script);
  1394. $this->addBuildPkeyCriteriaOpen($script);
  1395. $this->addBuildPkeyCriteriaBody($script);
  1396. $this->addBuildPkeyCriteriaClose($script);
  1397. }
  1398. /**
  1399. * Adds the comment for the buildPkeyCriteria method
  1400. * @param string &$script The script will be modified in this method.
  1401. * @see addBuildPkeyCriteria()
  1402. **/
  1403. protected function addBuildPkeyCriteriaComment(&$script) {
  1404. $script .= "
  1405. /**
  1406. * Builds a Criteria object containing the primary key for this object.
  1407. *
  1408. * Unlike buildCriteria() this method includes the primary key values regardless
  1409. * of whether or not they have been modified.
  1410. *
  1411. * @return Criteria The Criteria object containing value(s) for primary key(s).
  1412. */";
  1413. }
  1414. /**
  1415. * Adds the function declaration for the buildPkeyCriteria method
  1416. * @param string &$script The script will be modified in this method.
  1417. * @see addBuildPkeyCriteria()
  1418. **/
  1419. protected function addBuildPkeyCriteriaOpen(&$script) {
  1420. $script .= "
  1421. public function buildPkeyCriteria()
  1422. {";
  1423. }
  1424. /**
  1425. * Adds the function body for the buildPkeyCriteria method
  1426. * @param string &$script The script will be modified in this method.
  1427. * @see addBuildPkeyCriteria()
  1428. **/
  1429. protected function addBuildPkeyCriteriaBody(&$script) {
  1430. $script .= "
  1431. \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
  1432. foreach ($this->getTable()->getPrimaryKey() as $col) {
  1433. $clo = strtolower($col->getName());
  1434. $script .= "
  1435. \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
  1436. }
  1437. }
  1438. /**
  1439. * Adds the function close for the buildPkeyCriteria method
  1440. * @param string &$script The script will be modified in this method.
  1441. * @see addBuildPkeyCriteria()
  1442. **/
  1443. protected function addBuildPkeyCriteriaClose(&$script) {
  1444. $script .= "
  1445. return \$criteria;
  1446. }
  1447. ";
  1448. }
  1449. /**
  1450. * Adds the buildCriteria method
  1451. * @param string &$script The script will be modified in this method.
  1452. **/
  1453. protected function addBuildCriteria(&$script)
  1454. {
  1455. $this->addBuildCriteriaComment($script);
  1456. $this->addBuildCriteriaOpen($script);
  1457. $this->addBuildCriteriaBody($script);
  1458. $this->addBuildCriteriaClose($script);
  1459. }
  1460. /**
  1461. * Adds comment for the buildCriteria method
  1462. * @param string &$script The script will be modified in this method.
  1463. * @see addBuildCriteria()
  1464. **/
  1465. protected function addBuildCriteriaComment(&$script) {
  1466. $script .= "
  1467. /**
  1468. * Build a Criteria object containing the values of all modified columns in this object.
  1469. *
  1470. * @return Criteria The Criteria object containing all modified values.
  1471. */";
  1472. }
  1473. /**
  1474. * Adds the function declaration of the buildCriteria method
  1475. * @param string &$script The script will be modified in this method.
  1476. * @see addBuildCriteria()
  1477. **/
  1478. protected function addBuildCriteriaOpen(&$script) {
  1479. $script .= "
  1480. public function buildCriteria()
  1481. {";
  1482. }
  1483. /**
  1484. * Adds the function body of the buildCriteria method
  1485. * @param string &$script The script will be modified in this method.
  1486. * @see addBuildCriteria()
  1487. **/
  1488. protected function addBuildCriteriaBody(&$script) {
  1489. $script .= "
  1490. \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
  1491. ";
  1492. foreach ($this->getTable()->getColumns() as $col) {
  1493. $clo = strtolower($col->getName());
  1494. $script .= "
  1495. if (\$this->isColumnModified(".$this->getColumnConstant($col).")) \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
  1496. }
  1497. }
  1498. /**
  1499. * Adds the function close of the buildCriteria method
  1500. * @param string &$script The script will be modified in this method.
  1501. * @see addBuildCriteria()
  1502. **/
  1503. protected function addBuildCriteriaClose(&$script) {
  1504. $script .= "
  1505. return \$criteria;
  1506. }
  1507. ";
  1508. }
  1509. /**
  1510. * Adds the toArray method
  1511. * @param string &$script The script will be modified in this method.
  1512. **/
  1513. protected function addToArray(&$script)
  1514. {
  1515. $fks = $this->getTable()->getForeignKeys();
  1516. $hasFks = count($fks) > 0;
  1517. $script .= "
  1518. /**
  1519. * Exports the object as an array.
  1520. *
  1521. * You can specify the key type of the array by passing one of the class
  1522. * type constants.
  1523. *
  1524. * @param string \$keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
  1525. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  1526. * Defaults to BasePeer::TYPE_PHPNAME.
  1527. * @param boolean \$includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE.";
  1528. if ($hasFks) {
  1529. $script .= "
  1530. * @param boolean \$includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE.";
  1531. }
  1532. $script .= "
  1533. *
  1534. * @return array an associative array containing the field names (as keys) and field values
  1535. */
  1536. public function toArray(\$keyType = BasePeer::TYPE_PHPNAME, \$includeLazyLoadColumns = true" . ($hasFks ? ", \$includeForeignObjects = false" : '') . ")
  1537. {
  1538. \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
  1539. \$result = array(";
  1540. foreach ($this->getTable()->getColumns() as $num => $col) {
  1541. if ($col->isLazyLoad()) {
  1542. $script .= "
  1543. \$keys[$num] => (\$includeLazyLoadColumns) ? \$this->get".$col->getPhpName()."() : null,";
  1544. } else {
  1545. $script .= "
  1546. \$keys[$num] => \$this->get".$col->getPhpName()."(),";
  1547. }
  1548. }
  1549. $script .= "
  1550. );";
  1551. if ($hasFks) {
  1552. $script .= "
  1553. if (\$includeForeignObjects) {";
  1554. foreach ($fks as $fk) {
  1555. $script .= "
  1556. if (null !== \$this->" . $this->getFKVarName($fk) . ") {
  1557. \$result['" . $this->getFKPhpNameAffix($fk, $plural = false) . "'] = \$this->" . $this->getFKVarName($fk) . "->toArray(\$keyType, \$includeLazyLoadColumns, true);
  1558. }";
  1559. }
  1560. $script .= "
  1561. }";
  1562. }
  1563. $script .= "
  1564. return \$result;
  1565. }
  1566. ";
  1567. } // addToArray()
  1568. /**
  1569. * Adds the getByName method
  1570. * @param string &$script The script will be modified in this method.
  1571. **/
  1572. protected function addGetByName(&$script)
  1573. {
  1574. $this->addGetByNameComment($script);
  1575. $this->addGetByNameOpen($script);
  1576. $this->addGetByNameBody($script);
  1577. $this->addGetByNameClose($script);
  1578. }
  1579. /**
  1580. * Adds the comment for the getByName method
  1581. * @param string &$script The script will be modified in this method.
  1582. * @see addGetByName
  1583. **/
  1584. protected function addGetByNameComment(&$script) {
  1585. $script .= "
  1586. /**
  1587. * Retrieves a field from the object by name passed in as a string.
  1588. *
  1589. * @param string \$name name
  1590. * @param string \$type The type of fieldname the \$name is of:
  1591. * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
  1592. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
  1593. * @return mixed Value of field.
  1594. */";
  1595. }
  1596. /**
  1597. * Adds the function declaration for the getByName method
  1598. * @param string &$script The script will be modified in this method.
  1599. * @see addGetByName
  1600. **/
  1601. protected function addGetByNameOpen(&$script) {
  1602. $script .= "
  1603. public function getByName(\$name, \$type = BasePeer::TYPE_PHPNAME)
  1604. {";
  1605. }
  1606. /**
  1607. * Adds the function body for the getByName method
  1608. * @param string &$script The script will be modified in this method.
  1609. * @see addGetByName
  1610. **/
  1611. protected function addGetByNameBody(&$script) {
  1612. $script .= "
  1613. \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
  1614. \$field = \$this->getByPosition(\$pos);";
  1615. }
  1616. /**
  1617. * Adds the function close for the getByName method
  1618. * @param string &$script The script will be modified in this method.
  1619. * @see addGetByName
  1620. **/
  1621. protected function addGetByNameClose(&$script) {
  1622. $script .= "
  1623. return \$field;
  1624. }
  1625. ";
  1626. }
  1627. /**
  1628. * Adds the getByPosition method
  1629. * @param string &$script The script will be modified in this method.
  1630. **/
  1631. protected function addGetByPosition(&$script)
  1632. {
  1633. $this->addGetByPositionComment($script);
  1634. $this->addGetByPositionOpen($script);
  1635. $this->addGetByPositionBody($script);
  1636. $this->addGetByPositionClose($script);
  1637. }
  1638. /**
  1639. * Adds comment for the getByPosition method
  1640. * @param string &$script The script will be modified in this method.
  1641. * @see addGetByPosition
  1642. **/
  1643. protected function addGetByPositionComment(&$script) {
  1644. $script .= "
  1645. /**
  1646. * Retrieves a field from the object by Position as specified in the xml schema.
  1647. * Zero-based.
  1648. *
  1649. * @param int \$pos position in xml schema
  1650. * @return mixed Value of field at \$pos
  1651. */";
  1652. }
  1653. /**
  1654. * Adds the function declaration for the getByPosition method
  1655. * @param string &$script The script will be modified in this method.
  1656. * @see addGetByPosition
  1657. **/
  1658. protected function addGetByPositionOpen(&$script) {
  1659. $script .= "
  1660. public function getByPosition(\$pos)
  1661. {";
  1662. }
  1663. /**
  1664. * Adds the function body for the getByPosition method
  1665. * @param string &$script The script will be modified in this method.
  1666. * @see addGetByPosition
  1667. **/
  1668. protected function addGetByPositionBody(&$script) {
  1669. $table = $this->getTable();
  1670. $script .= "
  1671. switch(\$pos) {";
  1672. $i = 0;
  1673. foreach ($table->getColumns() as $col) {
  1674. $cfc = $col->getPhpName();
  1675. $script .= "
  1676. case $i:
  1677. return \$this->get$cfc();
  1678. break;";
  1679. $i++;
  1680. } /* foreach */
  1681. $script .= "
  1682. default:
  1683. return null;
  1684. break;
  1685. } // switch()";
  1686. }
  1687. /**
  1688. * Adds the function close for the getByPosition method
  1689. * @param string &$script The script will be modified in this method.
  1690. * @see addGetByPosition
  1691. **/
  1692. protected function addGetByPositionClose(&$script) {
  1693. $script .= "
  1694. }
  1695. ";
  1696. }
  1697. protected function addSetByName(&$script)
  1698. {
  1699. $table = $this->getTable();
  1700. $script .= "
  1701. /**
  1702. * Sets a field from the object by name passed in as a string.
  1703. *
  1704. * @param string \$name peer name
  1705. * @param mixed \$value field value
  1706. * @param string \$type The type of fieldname the \$name is of:
  1707. * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
  1708. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
  1709. * @return void
  1710. */
  1711. public function setByName(\$name, \$value, \$type = BasePeer::TYPE_PHPNAME)
  1712. {
  1713. \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
  1714. return \$this->setByPosition(\$pos, \$value);
  1715. }
  1716. ";
  1717. }
  1718. protected function addSetByPosition(&$script)
  1719. {
  1720. $table = $this->getTable();
  1721. $script .= "
  1722. /**
  1723. * Sets a field from the object by Position as specified in the xml schema.
  1724. * Zero-based.
  1725. *
  1726. * @param int \$pos position in xml schema
  1727. * @param mixed \$value field value
  1728. * @return void
  1729. */
  1730. public function setByPosition(\$pos, \$value)
  1731. {
  1732. switch(\$pos) {";
  1733. $i = 0;
  1734. foreach ($table->getColumns() as $col) {
  1735. $cfc = $col->getPhpName();
  1736. $cptype = $col->getPhpType();
  1737. $script .= "
  1738. case $i:
  1739. \$this->set$cfc(\$value);
  1740. break;";
  1741. $i++;
  1742. } /* foreach */
  1743. $script .= "
  1744. } // switch()
  1745. }
  1746. ";
  1747. } // addSetByPosition()
  1748. protected function addFromArray(&$script)
  1749. {
  1750. $table = $this->getTable();
  1751. $script .= "
  1752. /**
  1753. * Populates the object using an array.
  1754. *
  1755. * This is particularly useful when populating an object from one of the
  1756. * request arrays (e.g. \$_POST). This method goes through the column
  1757. * names, checking to see whether a matching key exists in populated
  1758. * array. If so the setByName() method is called for that column.
  1759. *
  1760. * You can specify the key type of the array by additionally passing one
  1761. * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
  1762. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  1763. * The default key type is the column's phpname (e.g. 'AuthorId')
  1764. *
  1765. * @param array \$arr An array to populate the object from.
  1766. * @param string \$keyType The type of keys the array uses.
  1767. * @return void
  1768. */
  1769. public function fromArray(\$arr, \$keyType = BasePeer::TYPE_PHPNAME)
  1770. {
  1771. \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
  1772. ";
  1773. foreach ($table->getColumns() as $num => $col) {
  1774. $cfc = $col->getPhpName();
  1775. $cptype = $col->getPhpType();
  1776. $script .= "
  1777. if (array_key_exists(\$keys[$num], \$arr)) \$this->set$cfc(\$arr[\$keys[$num]]);";
  1778. } /* foreach */
  1779. $script .= "
  1780. }
  1781. ";
  1782. } // addFromArray
  1783. /**
  1784. * Adds a delete() method to remove the object form the datastore.
  1785. * @param string &$script The script will be modified in this method.
  1786. */
  1787. protected function addDelete(&$script)
  1788. {
  1789. $this->addDeleteComment($script);
  1790. $this->addDeleteOpen($script);
  1791. $this->addDeleteBody($script);
  1792. $this->addDeleteClose($script);
  1793. }
  1794. /**
  1795. * Adds the comment for the delete function
  1796. * @param string &$script The script will be modified in this method.
  1797. * @see addDelete()
  1798. **/
  1799. protected function addDeleteComment(&$script) {
  1800. $script .= "
  1801. /**
  1802. * Removes this object from datastore and sets delete attribute.
  1803. *
  1804. * @param PropelPDO \$con
  1805. * @return void
  1806. * @throws PropelException
  1807. * @see BaseObject::setDeleted()
  1808. * @see BaseObject::isDeleted()
  1809. */";
  1810. }
  1811. /**
  1812. * Adds the function declaration for the delete function
  1813. * @param string &$script The script will be modified in this method.
  1814. * @see addDelete()
  1815. **/
  1816. protected function addDeleteOpen(&$script) {
  1817. $script .= "
  1818. public function delete(PropelPDO \$con = null)
  1819. {";
  1820. }
  1821. /**
  1822. * Adds the function body for the delete function
  1823. * @param string &$script The script will be modified in this method.
  1824. * @see addDelete()
  1825. **/
  1826. protected function addDeleteBody(&$script) {
  1827. $script .= "
  1828. if (\$this->isDeleted()) {
  1829. throw new PropelException(\"This object has already been deleted.\");
  1830. }
  1831. if (\$con === null) {
  1832. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
  1833. }
  1834. \$con->beginTransaction();
  1835. try {";
  1836. if($this->getGeneratorConfig()->getBuildProperty('addHooks')) {
  1837. $script .= "
  1838. \$ret = \$this->preDelete(\$con);";
  1839. // apply behaviors
  1840. $this->applyBehaviorModifier('preDelete', $script, " ");
  1841. $script .= "
  1842. if (\$ret) {
  1843. ".$this->getQueryClassname()."::create()
  1844. ->filterByPrimaryKey(\$this->getPrimaryKey())
  1845. ->delete(\$con);
  1846. \$this->postDelete(\$con);";
  1847. // apply behaviors
  1848. $this->applyBehaviorModifier('postDelete', $script, " ");
  1849. $script .= "
  1850. \$con->commit();
  1851. \$this->setDeleted(true);
  1852. } else {
  1853. \$con->commit();
  1854. }";
  1855. } else {
  1856. // apply behaviors
  1857. $this->applyBehaviorModifier('preDelete', $script, " ");
  1858. $script .= "
  1859. ".$this->getPeerClassname()."::doDelete(\$this, \$con);";
  1860. // apply behaviors
  1861. $this->applyBehaviorModifier('postDelete', $script, " ");
  1862. $script .= "
  1863. \$con->commit();
  1864. \$this->setDeleted(true);";
  1865. }
  1866. $script .= "
  1867. } catch (PropelException \$e) {
  1868. \$con->rollBack();
  1869. throw \$e;
  1870. }";
  1871. }
  1872. /**
  1873. * Adds the function close for the delete function
  1874. * @param string &$script The script will be modified in this method.
  1875. * @see addDelete()
  1876. **/
  1877. protected function addDeleteClose(&$script) {
  1878. $script .= "
  1879. }
  1880. ";
  1881. } // addDelete()
  1882. /**
  1883. * Adds a reload() method to re-fetch the data for this object from the database.
  1884. * @param string &$script The script will be modified in this method.
  1885. */
  1886. protected function addReload(&$script)
  1887. {
  1888. $table = $this->getTable();
  1889. $script .= "
  1890. /**
  1891. * Reloads this object from datastore based on primary key and (optionally) resets all associated objects.
  1892. *
  1893. * This will only work if the object has been saved and has a valid primary key set.
  1894. *
  1895. * @param boolean \$deep (optional) Whether to also de-associated any related objects.
  1896. * @param PropelPDO \$con (optional) The PropelPDO connection to use.
  1897. * @return void
  1898. * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db
  1899. */
  1900. public function reload(\$deep = false, PropelPDO \$con = null)
  1901. {
  1902. if (\$this->isDeleted()) {
  1903. throw new PropelException(\"Cannot reload a deleted object.\");
  1904. }
  1905. if (\$this->isNew()) {
  1906. throw new PropelException(\"Cannot reload an unsaved object.\");
  1907. }
  1908. if (\$con === null) {
  1909. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
  1910. }
  1911. // We don't need to alter the object instance pool; we're just modifying this instance
  1912. // already in the pool.
  1913. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$this->buildPkeyCriteria(), \$con);
  1914. \$row = \$stmt->fetch(PDO::FETCH_NUM);
  1915. \$stmt->closeCursor();
  1916. if (!\$row) {
  1917. throw new PropelException('Cannot find matching row in the database to reload object values.');
  1918. }
  1919. \$this->hydrate(\$row, 0, true); // rehydrate
  1920. ";
  1921. // support for lazy load columns
  1922. foreach ($table->getColumns() as $col) {
  1923. if ($col->isLazyLoad()) {
  1924. $clo = strtolower($col->getName());
  1925. $script .= "
  1926. // Reset the $clo lazy-load column
  1927. \$this->" . $clo . " = null;
  1928. \$this->".$clo."_isLoaded = false;
  1929. ";
  1930. }
  1931. }
  1932. $script .= "
  1933. if (\$deep) { // also de-associate any related objects?";
  1934. foreach ($table->getForeignKeys() as $fk) {
  1935. $varName = $this->getFKVarName($fk);
  1936. $script .= "
  1937. \$this->".$varName." = null;";
  1938. }
  1939. foreach ($table->getReferrers() as $refFK) {
  1940. if ($refFK->isLocalPrimaryKey()) {
  1941. $script .= "
  1942. \$this->".$this->getPKRefFKVarName($refFK)." = null;";
  1943. } else {
  1944. $script .= "
  1945. \$this->".$this->getRefFKCollVarName($refFK)." = null;";
  1946. }
  1947. }
  1948. foreach ($table->getCrossFks() as $fkList) {
  1949. list($refFK, $crossFK) = $fkList;
  1950. $script .= "
  1951. \$this->" . $this->getCrossFKVarName($crossFK). " = null;";
  1952. }
  1953. $script .= "
  1954. } // if (deep)
  1955. }
  1956. ";
  1957. } // addReload()
  1958. /**
  1959. * Adds the methods related to refreshing, saving and deleting the object.
  1960. * @param string &$script The script will be modified in this method.
  1961. */
  1962. protected function addManipulationMethods(&$script)
  1963. {
  1964. $this->addReload($script);
  1965. $this->addDelete($script);
  1966. $this->addSave($script);
  1967. $this->addDoSave($script);
  1968. }
  1969. /**
  1970. * Adds the methods related to validationg the object.
  1971. * @param string &$script The script will be modified in this method.
  1972. */
  1973. protected function addValidationMethods(&$script)
  1974. {
  1975. $this->addValidationFailuresAttribute($script);
  1976. $this->addGetValidationFailures($script);
  1977. $this->addValidate($script);
  1978. $this->addDoValidate($script);
  1979. }
  1980. /**
  1981. * Adds the $validationFailures attribute to store ValidationFailed objects.
  1982. * @param string &$script The script will be modified in this method.
  1983. */
  1984. protected function addValidationFailuresAttribute(&$script)
  1985. {
  1986. $script .= "
  1987. /**
  1988. * Array of ValidationFailed objects.
  1989. * @var array ValidationFailed[]
  1990. */
  1991. protected \$validationFailures = array();
  1992. ";
  1993. }
  1994. /**
  1995. * Adds the getValidationFailures() method.
  1996. * @param string &$script The script will be modified in this method.
  1997. */
  1998. protected function addGetValidationFailures(&$script)
  1999. {
  2000. $script .= "
  2001. /**
  2002. * Gets any ValidationFailed objects that resulted from last call to validate().
  2003. *
  2004. *
  2005. * @return array ValidationFailed[]
  2006. * @see validate()
  2007. */
  2008. public function getValidationFailures()
  2009. {
  2010. return \$this->validationFailures;
  2011. }
  2012. ";
  2013. } // addGetValidationFailures()
  2014. /**
  2015. * Adds the correct getPrimaryKey() method for this object.
  2016. * @param string &$script The script will be modified in this method.
  2017. */
  2018. protected function addGetPrimaryKey(&$script)
  2019. {
  2020. $pkeys = $this->getTable()->getPrimaryKey();
  2021. if (count($pkeys) == 1) {
  2022. $this->addGetPrimaryKey_SinglePK($script);
  2023. } elseif (count($pkeys) > 1) {
  2024. $this->addGetPrimaryKey_MultiPK($script);
  2025. } else {
  2026. // no primary key -- this is deprecated, since we don't *need* this method anymore
  2027. $this->addGetPrimaryKey_NoPK($script);
  2028. }
  2029. }
  2030. /**
  2031. * Adds the getPrimaryKey() method for tables that contain a single-column primary key.
  2032. * @param string &$script The script will be modified in this method.
  2033. */
  2034. protected function addGetPrimaryKey_SinglePK(&$script)
  2035. {
  2036. $table = $this->getTable();
  2037. $pkeys = $table->getPrimaryKey();
  2038. $cptype = $pkeys[0]->getPhpType();
  2039. $script .= "
  2040. /**
  2041. * Returns the primary key for this object (row).
  2042. * @return $cptype
  2043. */
  2044. public function getPrimaryKey()
  2045. {
  2046. return \$this->get".$pkeys[0]->getPhpName()."();
  2047. }
  2048. ";
  2049. } // addetPrimaryKey_SingleFK
  2050. /**
  2051. * Adds the setPrimaryKey() method for tables that contain a multi-column primary key.
  2052. * @param string &$script The script will be modified in this method.
  2053. */
  2054. protected function addGetPrimaryKey_MultiPK(&$script)
  2055. {
  2056. $script .= "
  2057. /**
  2058. * Returns the composite primary key for this object.
  2059. * The array elements will be in same order as specified in XML.
  2060. * @return array
  2061. */
  2062. public function getPrimaryKey()
  2063. {
  2064. \$pks = array();";
  2065. $i = 0;
  2066. foreach ($this->getTable()->getPrimaryKey() as $pk) {
  2067. $script .= "
  2068. \$pks[$i] = \$this->get".$pk->getPhpName()."();";
  2069. $i++;
  2070. } /* foreach */
  2071. $script .= "
  2072. return \$pks;
  2073. }
  2074. ";
  2075. } // addGetPrimaryKey_MultiFK()
  2076. /**
  2077. * Adds the getPrimaryKey() method for objects that have no primary key.
  2078. * This "feature" is dreprecated, since the getPrimaryKey() method is not required
  2079. * by the Persistent interface (or used by the templates). Hence, this method is also
  2080. * deprecated.
  2081. * @param string &$script The script will be modified in this method.
  2082. * @deprecated
  2083. */
  2084. protected function addGetPrimaryKey_NoPK(&$script)
  2085. {
  2086. $script .= "
  2087. /**
  2088. * Returns NULL since this table doesn't have a primary key.
  2089. * This method exists only for BC and is deprecated!
  2090. * @return null
  2091. */
  2092. public function getPrimaryKey()
  2093. {
  2094. return null;
  2095. }
  2096. ";
  2097. }
  2098. /**
  2099. * Adds the correct setPrimaryKey() method for this object.
  2100. * @param string &$script The script will be modified in this method.
  2101. */
  2102. protected function addSetPrimaryKey(&$script)
  2103. {
  2104. $pkeys = $this->getTable()->getPrimaryKey();
  2105. if (count($pkeys) == 1) {
  2106. $this->addSetPrimaryKey_SinglePK($script);
  2107. } elseif (count($pkeys) > 1) {
  2108. $this->addSetPrimaryKey_MultiPK($script);
  2109. } else {
  2110. // no primary key -- this is deprecated, since we don't *need* this method anymore
  2111. $this->addSetPrimaryKey_NoPK($script);
  2112. }
  2113. }
  2114. /**
  2115. * Adds the setPrimaryKey() method for tables that contain a single-column primary key.
  2116. * @param string &$script The script will be modified in this method.
  2117. */
  2118. protected function addSetPrimaryKey_SinglePK(&$script)
  2119. {
  2120. $pkeys = $this->getTable()->getPrimaryKey();
  2121. $col = $pkeys[0];
  2122. $clo=strtolower($col->getName());
  2123. $ctype = $col->getPhpType();
  2124. $script .= "
  2125. /**
  2126. * Generic method to set the primary key ($clo column).
  2127. *
  2128. * @param $ctype \$key Primary key.
  2129. * @return void
  2130. */
  2131. public function setPrimaryKey(\$key)
  2132. {
  2133. \$this->set".$col->getPhpName()."(\$key);
  2134. }
  2135. ";
  2136. } // addSetPrimaryKey_SinglePK
  2137. /**
  2138. * Adds the setPrimaryKey() method for tables that contain a multi-columnprimary key.
  2139. * @param string &$script The script will be modified in this method.
  2140. */
  2141. protected function addSetPrimaryKey_MultiPK(&$script)
  2142. {
  2143. $script .="
  2144. /**
  2145. * Set the [composite] primary key.
  2146. *
  2147. * @param array \$keys The elements of the composite key (order must match the order in XML file).
  2148. * @return void
  2149. */
  2150. public function setPrimaryKey(\$keys)
  2151. {";
  2152. $i = 0;
  2153. foreach ($this->getTable()->getPrimaryKey() as $pk) {
  2154. $pktype = $pk->getPhpType();
  2155. $script .= "
  2156. \$this->set".$pk->getPhpName()."(\$keys[$i]);";
  2157. $i++;
  2158. } /* foreach ($table->getPrimaryKey() */
  2159. $script .= "
  2160. }
  2161. ";
  2162. } // addSetPrimaryKey_MultiPK
  2163. /**
  2164. * Adds the setPrimaryKey() method for objects that have no primary key.
  2165. * This "feature" is dreprecated, since the setPrimaryKey() method is not required
  2166. * by the Persistent interface (or used by the templates). Hence, this method is also
  2167. * deprecated.
  2168. * @param string &$script The script will be modified in this method.
  2169. * @deprecated
  2170. */
  2171. protected function addSetPrimaryKey_NoPK(&$script)
  2172. {
  2173. $script .="
  2174. /**
  2175. * Dummy primary key setter.
  2176. *
  2177. * This function only exists to preserve backwards compatibility. It is no longer
  2178. * needed or required by the Persistent interface. It will be removed in next BC-breaking
  2179. * release of Propel.
  2180. *
  2181. * @deprecated
  2182. */
  2183. public function setPrimaryKey(\$pk)
  2184. {
  2185. // do nothing, because this object doesn't have any primary keys
  2186. }
  2187. ";
  2188. }
  2189. /**
  2190. * Adds the isPrimaryKeyNull() method
  2191. * @param string &$script The script will be modified in this method.
  2192. */
  2193. protected function addIsPrimaryKeyNull(&$script)
  2194. {
  2195. $table = $this->getTable();
  2196. $pkeys = $table->getPrimaryKey();
  2197. $script .= "
  2198. /**
  2199. * Returns true if the primary key for this object is null.
  2200. * @return boolean
  2201. */
  2202. public function isPrimaryKeyNull()
  2203. {";
  2204. if (count($pkeys) == 1) {
  2205. $script .= "
  2206. return null === \$this->get" . $pkeys[0]->getPhpName() . "();";
  2207. } else {
  2208. $tests = array();
  2209. foreach ($pkeys as $pkey) {
  2210. $tests[]= "(null === \$this->get" . $pkey->getPhpName() . "())";
  2211. }
  2212. $script .= "
  2213. return " . join(' && ', $tests) . ";";
  2214. }
  2215. $script .= "
  2216. }
  2217. ";
  2218. } // addetPrimaryKey_SingleFK
  2219. // --------------------------------------------------------------------
  2220. // Complex OM Methods
  2221. // --------------------------------------------------------------------
  2222. /**
  2223. * Constructs variable name for fkey-related objects.
  2224. * @param ForeignKey $fk
  2225. * @return string
  2226. */
  2227. protected function getFKVarName(ForeignKey $fk)
  2228. {
  2229. return 'a' . $this->getFKPhpNameAffix($fk, $plural = false);
  2230. }
  2231. /**
  2232. * Constructs variable name for objects which referencing current table by specified foreign key.
  2233. * @param ForeignKey $fk
  2234. * @return string
  2235. */
  2236. protected function getRefFKCollVarName(ForeignKey $fk)
  2237. {
  2238. return 'coll' . $this->getRefFKPhpNameAffix($fk, $plural = true);
  2239. }
  2240. /**
  2241. * Constructs variable name for single object which references current table by specified foreign key
  2242. * which is ALSO a primary key (hence one-to-one relationship).
  2243. * @param ForeignKey $fk
  2244. * @return string
  2245. */
  2246. protected function getPKRefFKVarName(ForeignKey $fk)
  2247. {
  2248. return 'single' . $this->getRefFKPhpNameAffix($fk, $plural = false);
  2249. }
  2250. // ----------------------------------------------------------------
  2251. //
  2252. // F K M E T H O D S
  2253. //
  2254. // ----------------------------------------------------------------
  2255. /**
  2256. * Adds the methods that get & set objects related by foreign key to the current object.
  2257. * @param string &$script The script will be modified in this method.
  2258. */
  2259. protected function addFKMethods(&$script)
  2260. {
  2261. foreach ($this->getTable()->getForeignKeys() as $fk) {
  2262. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($fk->getForeignTable()));
  2263. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($fk->getForeignTable()));
  2264. $this->addFKMutator($script, $fk);
  2265. $this->addFKAccessor($script, $fk);
  2266. } // foreach fk
  2267. }
  2268. /**
  2269. * Adds the class attributes that are needed to store fkey related objects.
  2270. * @param string &$script The script will be modified in this method.
  2271. */
  2272. protected function addFKAttributes(&$script, ForeignKey $fk)
  2273. {
  2274. $className = $this->getForeignTable($fk)->getPhpName();
  2275. $varName = $this->getFKVarName($fk);
  2276. $script .= "
  2277. /**
  2278. * @var $className
  2279. */
  2280. protected $".$varName.";
  2281. ";
  2282. }
  2283. /**
  2284. * Adds the mutator (setter) method for setting an fkey related object.
  2285. * @param string &$script The script will be modified in this method.
  2286. */
  2287. protected function addFKMutator(&$script, ForeignKey $fk)
  2288. {
  2289. $table = $this->getTable();
  2290. $tblFK = $this->getForeignTable($fk);
  2291. $joinTableObjectBuilder = $this->getNewObjectBuilder($tblFK);
  2292. $className = $joinTableObjectBuilder->getObjectClassname();
  2293. $varName = $this->getFKVarName($fk);
  2294. $script .= "
  2295. /**
  2296. * Declares an association between this object and a $className object.
  2297. *
  2298. * @param $className \$v
  2299. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  2300. * @throws PropelException
  2301. */
  2302. public function set".$this->getFKPhpNameAffix($fk, $plural = false)."($className \$v = null)
  2303. {";
  2304. foreach ($fk->getLocalColumns() as $columnName) {
  2305. $column = $table->getColumn($columnName);
  2306. $lfmap = $fk->getLocalForeignMapping();
  2307. $colFKName = $lfmap[$columnName];
  2308. $colFK = $tblFK->getColumn($colFKName);
  2309. $script .= "
  2310. if (\$v === null) {
  2311. \$this->set".$column->getPhpName()."(".$this->getDefaultValueString($column).");
  2312. } else {
  2313. \$this->set".$column->getPhpName()."(\$v->get".$colFK->getPhpName()."());
  2314. }
  2315. ";
  2316. } /* foreach local col */
  2317. $script .= "
  2318. \$this->$varName = \$v;
  2319. ";
  2320. // Now add bi-directional relationship binding, taking into account whether this is
  2321. // a one-to-one relationship.
  2322. if ($fk->isLocalPrimaryKey()) {
  2323. $script .= "
  2324. // Add binding for other direction of this 1:1 relationship.
  2325. if (\$v !== null) {
  2326. \$v->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
  2327. }
  2328. ";
  2329. } else {
  2330. $script .= "
  2331. // Add binding for other direction of this n:n relationship.
  2332. // If this object has already been added to the $className object, it will not be re-added.
  2333. if (\$v !== null) {
  2334. \$v->add".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
  2335. }
  2336. ";
  2337. }
  2338. $script .= "
  2339. return \$this;
  2340. }
  2341. ";
  2342. }
  2343. /**
  2344. * Adds the accessor (getter) method for getting an fkey related object.
  2345. * @param string &$script The script will be modified in this method.
  2346. */
  2347. protected function addFKAccessor(&$script, ForeignKey $fk)
  2348. {
  2349. $table = $this->getTable();
  2350. $varName = $this->getFKVarName($fk);
  2351. $fkQueryBuilder = $this->getNewStubQueryBuilder($this->getForeignTable($fk));
  2352. $fkObjectBuilder = $this->getNewObjectBuilder($this->getForeignTable($fk))->getStubObjectBuilder();
  2353. $className = $fkObjectBuilder->getClassname(); // get the Classname that has maybe a prefix
  2354. $and = "";
  2355. $conditional = "";
  2356. $localColumns = array(); // foreign key local attributes names
  2357. // If the related columns are a primary key on the foreign table
  2358. // then use retrieveByPk() instead of doSelect() to take advantage
  2359. // of instance pooling
  2360. $useRetrieveByPk = $fk->isForeignPrimaryKey();
  2361. foreach ($fk->getLocalColumns() as $columnName) {
  2362. $lfmap = $fk->getLocalForeignMapping();
  2363. $localColumn = $table->getColumn($columnName);
  2364. $foreignColumn = $fk->getForeignTable()->getColumn($lfmap[$columnName]);
  2365. $column = $table->getColumn($columnName);
  2366. $cptype = $column->getPhpType();
  2367. $clo = strtolower($column->getName());
  2368. $localColumns[$foreignColumn->getPosition()] = '$this->'.$clo;
  2369. if ($cptype == "integer" || $cptype == "float" || $cptype == "double") {
  2370. $conditional .= $and . "\$this->". $clo ." != 0";
  2371. } elseif ($cptype == "string") {
  2372. $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)";
  2373. } else {
  2374. $conditional .= $and . "\$this->" . $clo ." !== null";
  2375. }
  2376. $and = " && ";
  2377. }
  2378. ksort($localColumns); // restoring the order of the foreign PK
  2379. $localColumns = count($localColumns) > 1 ?
  2380. ('array('.implode(', ', $localColumns).')') : reset($localColumns);
  2381. $script .= "
  2382. /**
  2383. * Get the associated $className object
  2384. *
  2385. * @param PropelPDO Optional Connection object.
  2386. * @return $className The associated $className object.
  2387. * @throws PropelException
  2388. */
  2389. public function get".$this->getFKPhpNameAffix($fk, $plural = false)."(PropelPDO \$con = null)
  2390. {";
  2391. $script .= "
  2392. if (\$this->$varName === null && ($conditional)) {";
  2393. if ($useRetrieveByPk) {
  2394. $script .= "
  2395. \$this->$varName = ".$fkQueryBuilder->getClassname()."::create()->findPk($localColumns, \$con);";
  2396. } else {
  2397. $script .= "
  2398. \$this->$varName = ".$fkQueryBuilder->getClassname()."::create()
  2399. ->filterBy" . $this->getRefFKPhpNameAffix($fk, $plural = false) . "(\$this) // here
  2400. ->findOne(\$con);";
  2401. }
  2402. if ($fk->isLocalPrimaryKey()) {
  2403. $script .= "
  2404. // Because this foreign key represents a one-to-one relationship, we will create a bi-directional association.
  2405. \$this->{$varName}->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);";
  2406. } else {
  2407. $script .= "
  2408. /* The following can be used additionally to
  2409. guarantee the related object contains a reference
  2410. to this object. This level of coupling may, however, be
  2411. undesirable since it could result in an only partially populated collection
  2412. in the referenced object.
  2413. \$this->{$varName}->add".$this->getRefFKPhpNameAffix($fk, $plural = true)."(\$this);
  2414. */";
  2415. }
  2416. $script .= "
  2417. }
  2418. return \$this->$varName;
  2419. }
  2420. ";
  2421. } // addFKAccessor
  2422. /**
  2423. * Adds a convenience method for setting a related object by specifying the primary key.
  2424. * This can be used in conjunction with the getPrimaryKey() for systems where nothing is known
  2425. * about the actual objects being related.
  2426. * @param string &$script The script will be modified in this method.
  2427. */
  2428. protected function addFKByKeyMutator(&$script, ForeignKey $fk)
  2429. {
  2430. $table = $this->getTable();
  2431. #$className = $this->getForeignTable($fk)->getPhpName();
  2432. $methodAffix = $this->getFKPhpNameAffix($fk);
  2433. #$varName = $this->getFKVarName($fk);
  2434. $script .= "
  2435. /**
  2436. * Provides convenient way to set a relationship based on a
  2437. * key. e.g.
  2438. * <code>\$bar->setFooKey(\$foo->getPrimaryKey())</code>
  2439. *";
  2440. if (count($fk->getLocalColumns()) > 1) {
  2441. $script .= "
  2442. * Note: It is important that the xml schema used to create this class
  2443. * maintains consistency in the order of related columns between
  2444. * ".$table->getName()." and ". $tblFK->getName().".
  2445. * If for some reason this is impossible, this method should be
  2446. * overridden in <code>".$table->getPhpName()."</code>.";
  2447. }
  2448. $script .= "
  2449. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  2450. * @throws PropelException
  2451. */
  2452. public function set".$methodAffix."Key(\$key)
  2453. {
  2454. ";
  2455. if (count($fk->getLocalColumns()) > 1) {
  2456. $i = 0;
  2457. foreach ($fk->getLocalColumns() as $colName) {
  2458. $col = $table->getColumn($colName);
  2459. $fktype = $col->getPhpType();
  2460. $script .= "
  2461. \$this->set".$col->getPhpName()."( ($fktype) \$key[$i] );
  2462. ";
  2463. $i++;
  2464. } /* foreach */
  2465. } else {
  2466. $lcols = $fk->getLocalColumns();
  2467. $colName = $lcols[0];
  2468. $col = $table->getColumn($colName);
  2469. $fktype = $col->getPhpType();
  2470. $script .= "
  2471. \$this->set".$col->getPhpName()."( ($fktype) \$key);
  2472. ";
  2473. }
  2474. $script .= "
  2475. return \$this;
  2476. }
  2477. ";
  2478. } // addFKByKeyMutator()
  2479. /**
  2480. * Adds the method that fetches fkey-related (referencing) objects but also joins in data from another table.
  2481. * @param string &$script The script will be modified in this method.
  2482. */
  2483. protected function addRefFKGetJoinMethods(&$script, ForeignKey $refFK)
  2484. {
  2485. $table = $this->getTable();
  2486. $tblFK = $refFK->getTable();
  2487. $join_behavior = $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
  2488. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  2489. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  2490. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural=true);
  2491. $collName = $this->getRefFKCollVarName($refFK);
  2492. $fkPeerBuilder = $this->getNewPeerBuilder($tblFK);
  2493. $className = $fkPeerBuilder->getObjectClassname();
  2494. $lastTable = "";
  2495. foreach ($tblFK->getForeignKeys() as $fk2) {
  2496. $tblFK2 = $this->getForeignTable($fk2);
  2497. $doJoinGet = !$tblFK2->isForReferenceOnly();
  2498. // it doesn't make sense to join in rows from the curent table, since we are fetching
  2499. // objects related to *this* table (i.e. the joined rows will all be the same row as current object)
  2500. if ($this->getTable()->getPhpName() == $tblFK2->getPhpName()) {
  2501. $doJoinGet = false;
  2502. }
  2503. $relCol2 = $this->getFKPhpNameAffix($fk2, $plural = false);
  2504. if ( $this->getRelatedBySuffix($refFK) != "" &&
  2505. ($this->getRelatedBySuffix($refFK) == $this->getRelatedBySuffix($fk2))) {
  2506. $doJoinGet = false;
  2507. }
  2508. if ($doJoinGet) {
  2509. $script .= "
  2510. /**
  2511. * If this collection has already been initialized with
  2512. * an identical criteria, it returns the collection.
  2513. * Otherwise if this ".$table->getPhpName()." is new, it will return
  2514. * an empty collection; or if this ".$table->getPhpName()." has previously
  2515. * been saved, it will retrieve related $relCol from storage.
  2516. *
  2517. * This method is protected by default in order to keep the public
  2518. * api reasonable. You can provide public methods for those you
  2519. * actually need in ".$table->getPhpName().".
  2520. *
  2521. * @param Criteria \$criteria optional Criteria object to narrow the query
  2522. * @param PropelPDO \$con optional connection object
  2523. * @param string \$join_behavior optional join type to use (defaults to $join_behavior)
  2524. * @return PropelCollection|array {$className}[] List of $className objects
  2525. */
  2526. public function get".$relCol."Join".$relCol2."(\$criteria = null, \$con = null, \$join_behavior = $join_behavior)
  2527. {";
  2528. $script .= "
  2529. \$query = $fkQueryClassname::create(null, \$criteria);
  2530. \$query->joinWith('" . $this->getFKPhpNameAffix($fk2, $plural=false) . "', \$join_behavior);
  2531. return \$this->get". $relCol . "(\$query, \$con);
  2532. }
  2533. ";
  2534. } /* end if ($doJoinGet) */
  2535. } /* end foreach ($tblFK->getForeignKeys() as $fk2) { */
  2536. } // function
  2537. // ----------------------------------------------------------------
  2538. //
  2539. // R E F E R R E R F K M E T H O D S
  2540. //
  2541. // ----------------------------------------------------------------
  2542. /**
  2543. * Adds the attributes used to store objects that have referrer fkey relationships to this object.
  2544. * <code>protected collVarName;</code>
  2545. * <code>private lastVarNameCriteria = null;</code>
  2546. * @param string &$script The script will be modified in this method.
  2547. */
  2548. protected function addRefFKAttributes(&$script, ForeignKey $refFK)
  2549. {
  2550. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2551. $className = $joinedTableObjectBuilder->getObjectClassname();
  2552. if ($refFK->isLocalPrimaryKey()) {
  2553. $script .= "
  2554. /**
  2555. * @var $className one-to-one related $className object
  2556. */
  2557. protected $".$this->getPKRefFKVarName($refFK).";
  2558. ";
  2559. } else {
  2560. $script .= "
  2561. /**
  2562. * @var array {$className}[] Collection to store aggregation of $className objects.
  2563. */
  2564. protected $".$this->getRefFKCollVarName($refFK).";
  2565. ";
  2566. }
  2567. }
  2568. /**
  2569. * Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys.
  2570. * @param string &$script The script will be modified in this method.
  2571. */
  2572. protected function addRefFKMethods(&$script)
  2573. {
  2574. foreach ($this->getTable()->getReferrers() as $refFK) {
  2575. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($refFK->getTable()));
  2576. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($refFK->getTable()));
  2577. if ($refFK->isLocalPrimaryKey()) {
  2578. $this->addPKRefFKGet($script, $refFK);
  2579. $this->addPKRefFKSet($script, $refFK);
  2580. } else {
  2581. $this->addRefFKClear($script, $refFK);
  2582. $this->addRefFKInit($script, $refFK);
  2583. $this->addRefFKGet($script, $refFK);
  2584. $this->addRefFKCount($script, $refFK);
  2585. $this->addRefFKAdd($script, $refFK);
  2586. $this->addRefFKGetJoinMethods($script, $refFK);
  2587. }
  2588. }
  2589. }
  2590. /**
  2591. * Adds the method that clears the referrer fkey collection.
  2592. * @param string &$script The script will be modified in this method.
  2593. */
  2594. protected function addRefFKClear(&$script, ForeignKey $refFK) {
  2595. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  2596. $collName = $this->getRefFKCollVarName($refFK);
  2597. $script .= "
  2598. /**
  2599. * Clears out the $collName collection
  2600. *
  2601. * This does not modify the database; however, it will remove any associated objects, causing
  2602. * them to be refetched by subsequent calls to accessor method.
  2603. *
  2604. * @return void
  2605. * @see add$relCol()
  2606. */
  2607. public function clear$relCol()
  2608. {
  2609. \$this->$collName = null; // important to set this to NULL since that means it is uninitialized
  2610. }
  2611. ";
  2612. } // addRefererClear()
  2613. /**
  2614. * Adds the method that initializes the referrer fkey collection.
  2615. * @param string &$script The script will be modified in this method.
  2616. */
  2617. protected function addRefFKInit(&$script, ForeignKey $refFK) {
  2618. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  2619. $collName = $this->getRefFKCollVarName($refFK);
  2620. $script .= "
  2621. /**
  2622. * Initializes the $collName collection.
  2623. *
  2624. * By default this just sets the $collName collection to an empty array (like clear$collName());
  2625. * however, you may wish to override this method in your stub class to provide setting appropriate
  2626. * to your application -- for example, setting the initial array to the values stored in database.
  2627. *
  2628. * @return void
  2629. */
  2630. public function init$relCol()
  2631. {
  2632. \$this->$collName = new PropelObjectCollection();
  2633. \$this->{$collName}->setModel('" . $this->getNewStubObjectBuilder($refFK->getTable())->getClassname() . "');
  2634. }
  2635. ";
  2636. } // addRefererInit()
  2637. /**
  2638. * Adds the method that adds an object into the referrer fkey collection.
  2639. * @param string &$script The script will be modified in this method.
  2640. */
  2641. protected function addRefFKAdd(&$script, ForeignKey $refFK)
  2642. {
  2643. $tblFK = $refFK->getTable();
  2644. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2645. $className = $joinedTableObjectBuilder->getObjectClassname();
  2646. $collName = $this->getRefFKCollVarName($refFK);
  2647. $script .= "
  2648. /**
  2649. * Method called to associate a $className object to this object
  2650. * through the $className foreign key attribute.
  2651. *
  2652. * @param $className \$l $className
  2653. * @return void
  2654. * @throws PropelException
  2655. */
  2656. public function add".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$l)
  2657. {
  2658. if (\$this->$collName === null) {
  2659. \$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."();
  2660. }
  2661. if (!\$this->{$collName}->contains(\$l)) { // only add it if the **same** object is not already associated
  2662. \$this->{$collName}[]= \$l;
  2663. \$l->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
  2664. }
  2665. }
  2666. ";
  2667. } // addRefererAdd
  2668. /**
  2669. * Adds the method that returns the size of the referrer fkey collection.
  2670. * @param string &$script The script will be modified in this method.
  2671. */
  2672. protected function addRefFKCount(&$script, ForeignKey $refFK)
  2673. {
  2674. $table = $this->getTable();
  2675. $tblFK = $refFK->getTable();
  2676. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  2677. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  2678. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  2679. $collName = $this->getRefFKCollVarName($refFK);
  2680. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2681. $className = $joinedTableObjectBuilder->getObjectClassname();
  2682. $script .= "
  2683. /**
  2684. * Returns the number of related $className objects.
  2685. *
  2686. * @param Criteria \$criteria
  2687. * @param boolean \$distinct
  2688. * @param PropelPDO \$con
  2689. * @return int Count of related $className objects.
  2690. * @throws PropelException
  2691. */
  2692. public function count$relCol(Criteria \$criteria = null, \$distinct = false, PropelPDO \$con = null)
  2693. {
  2694. if(null === \$this->$collName || null !== \$criteria) {
  2695. if (\$this->isNew() && null === \$this->$collName) {
  2696. return 0;
  2697. } else {
  2698. \$query = $fkQueryClassname::create(null, \$criteria);
  2699. if(\$distinct) {
  2700. \$query->distinct();
  2701. }
  2702. return \$query
  2703. ->filterBy" . $this->getFKPhpNameAffix($refFK) . "(\$this)
  2704. ->count(\$con);
  2705. }
  2706. } else {
  2707. return count(\$this->$collName);
  2708. }
  2709. }
  2710. ";
  2711. } // addRefererCount
  2712. /**
  2713. * Adds the method that returns the referrer fkey collection.
  2714. * @param string &$script The script will be modified in this method.
  2715. */
  2716. protected function addRefFKGet(&$script, ForeignKey $refFK)
  2717. {
  2718. $table = $this->getTable();
  2719. $tblFK = $refFK->getTable();
  2720. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  2721. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  2722. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  2723. $collName = $this->getRefFKCollVarName($refFK);
  2724. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2725. $className = $joinedTableObjectBuilder->getObjectClassname();
  2726. $script .= "
  2727. /**
  2728. * Gets an array of $className objects which contain a foreign key that references this object.
  2729. *
  2730. * If the \$criteria is not null, it is used to always fetch the results from the database.
  2731. * Otherwise the results are fetched from the database the first time, then cached.
  2732. * Next time the same method is called without \$criteria, the cached collection is returned.
  2733. * If this ".$this->getObjectClassname()." is new, it will return
  2734. * an empty collection or the current collection; the criteria is ignored on a new object.
  2735. *
  2736. * @param Criteria \$criteria optional Criteria object to narrow the query
  2737. * @param PropelPDO \$con optional connection object
  2738. * @return PropelCollection|array {$className}[] List of $className objects
  2739. * @throws PropelException
  2740. */
  2741. public function get$relCol(\$criteria = null, PropelPDO \$con = null)
  2742. {
  2743. if(null === \$this->$collName || null !== \$criteria) {
  2744. if (\$this->isNew() && null === \$this->$collName) {
  2745. // return empty collection
  2746. \$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."();
  2747. } else {
  2748. \$$collName = $fkQueryClassname::create(null, \$criteria)
  2749. ->filterBy" . $this->getFKPhpNameAffix($refFK) . "(\$this)
  2750. ->find(\$con);
  2751. if (null !== \$criteria) {
  2752. return \$$collName;
  2753. }
  2754. \$this->$collName = \$$collName;
  2755. }
  2756. }
  2757. return \$this->$collName;
  2758. }
  2759. ";
  2760. } // addRefererGet()
  2761. /**
  2762. * Adds the method that gets a one-to-one related referrer fkey.
  2763. * This is for one-to-one relationship special case.
  2764. * @param string &$script The script will be modified in this method.
  2765. */
  2766. protected function addPKRefFKGet(&$script, ForeignKey $refFK)
  2767. {
  2768. $table = $this->getTable();
  2769. $tblFK = $refFK->getTable();
  2770. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2771. $className = $joinedTableObjectBuilder->getObjectClassname();
  2772. $queryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  2773. $varName = $this->getPKRefFKVarName($refFK);
  2774. $script .= "
  2775. /**
  2776. * Gets a single $className object, which is related to this object by a one-to-one relationship.
  2777. *
  2778. * @param PropelPDO \$con optional connection object
  2779. * @return $className
  2780. * @throws PropelException
  2781. */
  2782. public function get".$this->getRefFKPhpNameAffix($refFK, $plural = false)."(PropelPDO \$con = null)
  2783. {
  2784. ";
  2785. $script .= "
  2786. if (\$this->$varName === null && !\$this->isNew()) {
  2787. \$this->$varName = $queryClassname::create()->findPk(\$this->getPrimaryKey(), \$con);
  2788. }
  2789. return \$this->$varName;
  2790. }
  2791. ";
  2792. } // addPKRefFKGet()
  2793. /**
  2794. * Adds the method that sets a one-to-one related referrer fkey.
  2795. * This is for one-to-one relationships special case.
  2796. * @param string &$script The script will be modified in this method.
  2797. * @param ForeignKey $refFK The referencing foreign key.
  2798. */
  2799. protected function addPKRefFKSet(&$script, ForeignKey $refFK)
  2800. {
  2801. $tblFK = $refFK->getTable();
  2802. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2803. $className = $joinedTableObjectBuilder->getObjectClassname();
  2804. $varName = $this->getPKRefFKVarName($refFK);
  2805. $script .= "
  2806. /**
  2807. * Sets a single $className object as related to this object by a one-to-one relationship.
  2808. *
  2809. * @param $className \$v $className
  2810. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  2811. * @throws PropelException
  2812. */
  2813. public function set".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$v = null)
  2814. {
  2815. \$this->$varName = \$v;
  2816. // Make sure that that the passed-in $className isn't already associated with this object
  2817. if (\$v !== null && \$v->get".$this->getFKPhpNameAffix($refFK, $plural = false)."() === null) {
  2818. \$v->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
  2819. }
  2820. return \$this;
  2821. }
  2822. ";
  2823. } // addPKRefFKSet
  2824. protected function addCrossFKAttributes(&$script, ForeignKey $crossFK)
  2825. {
  2826. $joinedTableObjectBuilder = $this->getNewObjectBuilder($crossFK->getForeignTable());
  2827. $className = $joinedTableObjectBuilder->getObjectClassname();
  2828. $script .= "
  2829. /**
  2830. * @var array {$className}[] Collection to store aggregation of $className objects.
  2831. */
  2832. protected $" . $this->getCrossFKVarName($crossFK) . ";
  2833. ";
  2834. }
  2835. protected function getCrossFKVarName(ForeignKey $crossFK)
  2836. {
  2837. return 'coll' . $this->getFKPhpNameAffix($crossFK, $plural = true);
  2838. }
  2839. protected function addCrossFKMethods(&$script)
  2840. {
  2841. foreach ($this->getTable()->getCrossFks() as $fkList) {
  2842. list($refFK, $crossFK) = $fkList;
  2843. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($crossFK->getForeignTable()));
  2844. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($crossFK->getForeignTable()));
  2845. $this->addCrossFKClear($script, $crossFK);
  2846. $this->addCrossFKInit($script, $crossFK);
  2847. $this->addCrossFKGet($script, $refFK, $crossFK);
  2848. $this->addCrossFKCount($script, $refFK, $crossFK);
  2849. $this->addCrossFKAdd($script, $refFK, $crossFK);
  2850. }
  2851. }
  2852. /**
  2853. * Adds the method that clears the referrer fkey collection.
  2854. * @param string &$script The script will be modified in this method.
  2855. */
  2856. protected function addCrossFKClear(&$script, ForeignKey $crossFK) {
  2857. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  2858. $collName = $this->getCrossFKVarName($crossFK);
  2859. $script .= "
  2860. /**
  2861. * Clears out the $collName collection
  2862. *
  2863. * This does not modify the database; however, it will remove any associated objects, causing
  2864. * them to be refetched by subsequent calls to accessor method.
  2865. *
  2866. * @return void
  2867. * @see add$relCol()
  2868. */
  2869. public function clear$relCol()
  2870. {
  2871. \$this->$collName = null; // important to set this to NULL since that means it is uninitialized
  2872. }
  2873. ";
  2874. } // addRefererClear()
  2875. /**
  2876. * Adds the method that initializes the referrer fkey collection.
  2877. * @param string &$script The script will be modified in this method.
  2878. */
  2879. protected function addCrossFKInit(&$script, ForeignKey $crossFK) {
  2880. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  2881. $collName = $this->getCrossFKVarName($crossFK);
  2882. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  2883. $script .= "
  2884. /**
  2885. * Initializes the $collName collection.
  2886. *
  2887. * By default this just sets the $collName collection to an empty collection (like clear$relCol());
  2888. * however, you may wish to override this method in your stub class to provide setting appropriate
  2889. * to your application -- for example, setting the initial array to the values stored in database.
  2890. *
  2891. * @return void
  2892. */
  2893. public function init$relCol()
  2894. {
  2895. \$this->$collName = new PropelObjectCollection();
  2896. \$this->{$collName}->setModel('$relatedObjectClassName');
  2897. }
  2898. ";
  2899. }
  2900. protected function addCrossFKGet(&$script, $refFK, $crossFK)
  2901. {
  2902. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  2903. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  2904. $selfRelationName = $this->getFKPhpNameAffix($refFK, $plural = false);
  2905. $relatedQueryClassName = $this->getNewStubQueryBuilder($crossFK->getForeignTable())->getClassname();
  2906. $crossRefTableName = $crossFK->getTableName();
  2907. $collName = $this->getCrossFKVarName($crossFK);
  2908. $script .= "
  2909. /**
  2910. * Gets a collection of $relatedObjectClassName objects related by a many-to-many relationship
  2911. * to the current object by way of the $crossRefTableName cross-reference table.
  2912. *
  2913. * If the \$criteria is not null, it is used to always fetch the results from the database.
  2914. * Otherwise the results are fetched from the database the first time, then cached.
  2915. * Next time the same method is called without \$criteria, the cached collection is returned.
  2916. * If this ".$this->getObjectClassname()." is new, it will return
  2917. * an empty collection or the current collection; the criteria is ignored on a new object.
  2918. *
  2919. * @param Criteria \$criteria Optional query object to filter the query
  2920. * @param PropelPDO \$con Optional connection object
  2921. *
  2922. * @return PropelCollection|array {$relatedObjectClassName}[] List of {$relatedObjectClassName} objects
  2923. */
  2924. public function get{$relatedName}(\$criteria = null, PropelPDO \$con = null)
  2925. {
  2926. if(null === \$this->$collName || null !== \$criteria) {
  2927. if (\$this->isNew() && null === \$this->$collName) {
  2928. // return empty collection
  2929. \$this->init{$relatedName}();
  2930. } else {
  2931. \$$collName = $relatedQueryClassName::create(null, \$criteria)
  2932. ->filterBy{$selfRelationName}(\$this)
  2933. ->find(\$con);
  2934. if (null !== \$criteria) {
  2935. return \$$collName;
  2936. }
  2937. \$this->$collName = \$$collName;
  2938. }
  2939. }
  2940. return \$this->$collName;
  2941. }
  2942. ";
  2943. }
  2944. protected function addCrossFKCount(&$script, $refFK, $crossFK)
  2945. {
  2946. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  2947. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  2948. $selfRelationName = $this->getFKPhpNameAffix($refFK, $plural = false);
  2949. $relatedQueryClassName = $this->getNewStubQueryBuilder($crossFK->getForeignTable())->getClassname();
  2950. $crossRefTableName = $refFK->getTableName();
  2951. $collName = $this->getCrossFKVarName($crossFK);
  2952. $script .= "
  2953. /**
  2954. * Gets the number of $relatedObjectClassName objects related by a many-to-many relationship
  2955. * to the current object by way of the $crossRefTableName cross-reference table.
  2956. *
  2957. * @param Criteria \$criteria Optional query object to filter the query
  2958. * @param boolean \$distinct Set to true to force count distinct
  2959. * @param PropelPDO \$con Optional connection object
  2960. *
  2961. * @return int the number of related $relatedObjectClassName objects
  2962. */
  2963. public function count{$relatedName}(\$criteria = null, \$distinct = false, PropelPDO \$con = null)
  2964. {
  2965. if(null === \$this->$collName || null !== \$criteria) {
  2966. if (\$this->isNew() && null === \$this->$collName) {
  2967. return 0;
  2968. } else {
  2969. \$query = $relatedQueryClassName::create(null, \$criteria);
  2970. if(\$distinct) {
  2971. \$query->distinct();
  2972. }
  2973. return \$query
  2974. ->filterBy{$selfRelationName}(\$this)
  2975. ->count(\$con);
  2976. }
  2977. } else {
  2978. return count(\$this->$collName);
  2979. }
  2980. }
  2981. ";
  2982. }
  2983. /**
  2984. * Adds the method that adds an object into the referrer fkey collection.
  2985. * @param string &$script The script will be modified in this method.
  2986. */
  2987. protected function addCrossFKAdd(&$script, ForeignKey $refFK, ForeignKey $crossFK)
  2988. {
  2989. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  2990. $collName = $this->getCrossFKVarName($crossFK);
  2991. $tblFK = $refFK->getTable();
  2992. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  2993. $className = $joinedTableObjectBuilder->getObjectClassname();
  2994. $foreignObjectName = '$' . $tblFK->getStudlyPhpName();
  2995. $crossObjectName = '$' . $crossFK->getForeignTable()->getStudlyPhpName();
  2996. $crossObjectClassName = $this->getNewObjectBuilder($crossFK->getForeignTable())->getObjectClassname();
  2997. $script .= "
  2998. /**
  2999. * Associate a " . $crossObjectClassName . " object to this object
  3000. * through the " . $tblFK->getName() . " cross reference table.
  3001. *
  3002. * @param " . $crossObjectClassName . " " . $crossObjectName . " The $className object to relate
  3003. * @return void
  3004. */
  3005. public function add" . $this->getFKPhpNameAffix($crossFK, $plural = false) . "(" . $crossObjectName. ")
  3006. {
  3007. if (\$this->" . $collName . " === null) {
  3008. \$this->init" . $relCol . "();
  3009. }
  3010. if (!\$this->" . $collName . "->contains(" . $crossObjectName . ")) { // only add it if the **same** object is not already associated
  3011. " . $foreignObjectName . " = new " . $className . "();
  3012. " . $foreignObjectName . "->set" . $this->getFKPhpNameAffix($crossFK, $plural = false) . "(" . $crossObjectName . ");
  3013. \$this->add" . $this->getRefFKPhpNameAffix($refFK, $plural = false) . "(" . $foreignObjectName . ");
  3014. \$this->" . $collName . "[]= " . $crossObjectName . ";
  3015. }
  3016. }
  3017. ";
  3018. }
  3019. // ----------------------------------------------------------------
  3020. //
  3021. // M A N I P U L A T I O N M E T H O D S
  3022. //
  3023. // ----------------------------------------------------------------
  3024. /**
  3025. * Adds the workhourse doSave() method.
  3026. * @param string &$script The script will be modified in this method.
  3027. */
  3028. protected function addDoSave(&$script)
  3029. {
  3030. $table = $this->getTable();
  3031. $reloadOnUpdate = $table->isReloadOnUpdate();
  3032. $reloadOnInsert = $table->isReloadOnInsert();
  3033. $script .= "
  3034. /**
  3035. * Performs the work of inserting or updating the row in the database.
  3036. *
  3037. * If the object is new, it inserts it; otherwise an update is performed.
  3038. * All related objects are also updated in this method.
  3039. *
  3040. * @param PropelPDO \$con";
  3041. if ($reloadOnUpdate || $reloadOnInsert) {
  3042. $script .= "
  3043. * @param boolean \$skipReload Whether to skip the reload for this object from database.";
  3044. }
  3045. $script .= "
  3046. * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations.
  3047. * @throws PropelException
  3048. * @see save()
  3049. */
  3050. protected function doSave(PropelPDO \$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
  3051. {
  3052. \$affectedRows = 0; // initialize var to track total num of affected rows
  3053. if (!\$this->alreadyInSave) {
  3054. \$this->alreadyInSave = true;
  3055. ";
  3056. if ($reloadOnInsert || $reloadOnUpdate) {
  3057. $script .= "
  3058. \$reloadObject = false;
  3059. ";
  3060. }
  3061. if (count($table->getForeignKeys())) {
  3062. $script .= "
  3063. // We call the save method on the following object(s) if they
  3064. // were passed to this object by their coresponding set
  3065. // method. This object relates to these object(s) by a
  3066. // foreign key reference.
  3067. ";
  3068. foreach ($table->getForeignKeys() as $fk) {
  3069. $aVarName = $this->getFKVarName($fk);
  3070. $script .= "
  3071. if (\$this->$aVarName !== null) {
  3072. if (\$this->" . $aVarName . "->isModified() || \$this->" . $aVarName . "->isNew()) {
  3073. \$affectedRows += \$this->" . $aVarName . "->save(\$con);
  3074. }
  3075. \$this->set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$this->$aVarName);
  3076. }
  3077. ";
  3078. } // foreach foreign k
  3079. } // if (count(foreign keys))
  3080. if ($table->hasAutoIncrementPrimaryKey() ) {
  3081. $script .= "
  3082. if (\$this->isNew() ) {
  3083. \$this->modifiedColumns[] = " . $this->getColumnConstant($table->getAutoIncrementPrimaryKey() ) . ";
  3084. }";
  3085. }
  3086. $script .= "
  3087. // If this object has been modified, then save it to the database.
  3088. if (\$this->isModified()) {
  3089. if (\$this->isNew()) {
  3090. \$criteria = \$this->buildCriteria();";
  3091. foreach ($table->getColumns() as $col) {
  3092. if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none" && !$table->isAllowPkInsert()) {
  3093. $colConst = $this->getColumnConstant($col);
  3094. $script .= "
  3095. if (\$criteria->keyContainsValue(" . $colConst . ") ) {
  3096. throw new PropelException('Cannot insert a value for auto-increment primary key ('." . $colConst . ".')');
  3097. }
  3098. ";
  3099. if (!$this->getPlatform()->supportsInsertNullPk()) {
  3100. $script .= "
  3101. // remove pkey col since this table uses auto-increment and passing a null value for it is not valid
  3102. \$criteria->remove(" . $colConst . ");
  3103. ";
  3104. }
  3105. } elseif ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none" && $table->isAllowPkInsert() && !$this->getPlatform()->supportsInsertNullPk()) {
  3106. $script .= "
  3107. // remove pkey col if it is null since this table does not accept that
  3108. if (\$criteria->containsKey(" . $colConst . ") && !\$criteria->keyContainsValue(" . $colConst . ") ) {
  3109. \$criteria->remove(" . $colConst . ");
  3110. }";
  3111. }
  3112. }
  3113. $script .= "
  3114. \$pk = " . $this->getNewPeerBuilder($table)->getBasePeerClassname() . "::doInsert(\$criteria, \$con);";
  3115. if ($reloadOnInsert) {
  3116. $script .= "
  3117. if (!\$skipReload) {
  3118. \$reloadObject = true;
  3119. }";
  3120. }
  3121. $operator = count($table->getForeignKeys()) ? '+=' : '=';
  3122. $script .= "
  3123. \$affectedRows " . $operator . " 1;";
  3124. if ($table->getIdMethod() != IDMethod::NO_ID_METHOD) {
  3125. if (count($pks = $table->getPrimaryKey())) {
  3126. foreach ($pks as $pk) {
  3127. if ($pk->isAutoIncrement()) {
  3128. if ($table->isAllowPkInsert()) {
  3129. $script .= "
  3130. if (\$pk !== null) {
  3131. \$this->set".$pk->getPhpName()."(\$pk); //[IMV] update autoincrement primary key
  3132. }";
  3133. } else {
  3134. $script .= "
  3135. \$this->set".$pk->getPhpName()."(\$pk); //[IMV] update autoincrement primary key";
  3136. }
  3137. }
  3138. }
  3139. }
  3140. } // if (id method != "none")
  3141. $script .= "
  3142. \$this->setNew(false);
  3143. } else {";
  3144. if ($reloadOnUpdate) {
  3145. $script .= "
  3146. if (!\$skipReload) {
  3147. \$reloadObject = true;
  3148. }";
  3149. }
  3150. $operator = count($table->getForeignKeys()) ? '+=' : '=';
  3151. $script .= "
  3152. \$affectedRows " . $operator . " ".$this->getPeerClassname()."::doUpdate(\$this, \$con);
  3153. }
  3154. ";
  3155. // We need to rewind any LOB columns
  3156. foreach ($table->getColumns() as $col) {
  3157. $clo = strtolower($col->getName());
  3158. if ($col->isLobType()) {
  3159. $script .= "
  3160. // Rewind the $clo LOB column, since PDO does not rewind after inserting value.
  3161. if (\$this->$clo !== null && is_resource(\$this->$clo)) {
  3162. rewind(\$this->$clo);
  3163. }
  3164. ";
  3165. }
  3166. }
  3167. $script .= "
  3168. \$this->resetModified(); // [HL] After being saved an object is no longer 'modified'
  3169. }
  3170. ";
  3171. foreach ($table->getReferrers() as $refFK) {
  3172. if ($refFK->isLocalPrimaryKey()) {
  3173. $varName = $this->getPKRefFKVarName($refFK);
  3174. $script .= "
  3175. if (\$this->$varName !== null) {
  3176. if (!\$this->{$varName}->isDeleted()) {
  3177. \$affectedRows += \$this->{$varName}->save(\$con);
  3178. }
  3179. }
  3180. ";
  3181. } else {
  3182. $collName = $this->getRefFKCollVarName($refFK);
  3183. $script .= "
  3184. if (\$this->$collName !== null) {
  3185. foreach (\$this->$collName as \$referrerFK) {
  3186. if (!\$referrerFK->isDeleted()) {
  3187. \$affectedRows += \$referrerFK->save(\$con);
  3188. }
  3189. }
  3190. }
  3191. ";
  3192. } // if refFK->isLocalPrimaryKey()
  3193. } /* foreach getReferrers() */
  3194. $script .= "
  3195. \$this->alreadyInSave = false;
  3196. ";
  3197. if ($reloadOnInsert || $reloadOnUpdate) {
  3198. $script .= "
  3199. if (\$reloadObject) {
  3200. \$this->reload(\$con);
  3201. }
  3202. ";
  3203. }
  3204. $script .= "
  3205. }
  3206. return \$affectedRows;
  3207. } // doSave()
  3208. ";
  3209. }
  3210. /**
  3211. * Adds the $alreadyInSave attribute, which prevents attempting to re-save the same object.
  3212. * @param string &$script The script will be modified in this method.
  3213. */
  3214. protected function addAlreadyInSaveAttribute(&$script)
  3215. {
  3216. $script .= "
  3217. /**
  3218. * Flag to prevent endless save loop, if this object is referenced
  3219. * by another object which falls in this transaction.
  3220. * @var boolean
  3221. */
  3222. protected \$alreadyInSave = false;
  3223. ";
  3224. }
  3225. /**
  3226. * Adds the save() method.
  3227. * @param string &$script The script will be modified in this method.
  3228. */
  3229. protected function addSave(&$script)
  3230. {
  3231. $this->addSaveComment($script);
  3232. $this->addSaveOpen($script);
  3233. $this->addSaveBody($script);
  3234. $this->addSaveClose($script);
  3235. }
  3236. /**
  3237. * Adds the comment for the save method
  3238. * @param string &$script The script will be modified in this method.
  3239. * @see addSave()
  3240. **/
  3241. protected function addSaveComment(&$script) {
  3242. $table = $this->getTable();
  3243. $reloadOnUpdate = $table->isReloadOnUpdate();
  3244. $reloadOnInsert = $table->isReloadOnInsert();
  3245. $script .= "
  3246. /**
  3247. * Persists this object to the database.
  3248. *
  3249. * If the object is new, it inserts it; otherwise an update is performed.
  3250. * All modified related objects will also be persisted in the doSave()
  3251. * method. This method wraps all precipitate database operations in a
  3252. * single transaction.";
  3253. if ($reloadOnUpdate) {
  3254. $script .= "
  3255. *
  3256. * Since this table was configured to reload rows on update, the object will
  3257. * be reloaded from the database if an UPDATE operation is performed (unless
  3258. * the \$skipReload parameter is TRUE).";
  3259. }
  3260. if ($reloadOnInsert) {
  3261. $script .= "
  3262. *
  3263. * Since this table was configured to reload rows on insert, the object will
  3264. * be reloaded from the database if an INSERT operation is performed (unless
  3265. * the \$skipReload parameter is TRUE).";
  3266. }
  3267. $script .= "
  3268. *
  3269. * @param PropelPDO \$con";
  3270. if ($reloadOnUpdate || $reloadOnInsert) {
  3271. $script .= "
  3272. * @param boolean \$skipReload Whether to skip the reload for this object from database.";
  3273. }
  3274. $script .= "
  3275. * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations.
  3276. * @throws PropelException
  3277. * @see doSave()
  3278. */";
  3279. }
  3280. /**
  3281. * Adds the function declaration for the save method
  3282. * @param string &$script The script will be modified in this method.
  3283. * @see addSave()
  3284. **/
  3285. protected function addSaveOpen(&$script) {
  3286. $table = $this->getTable();
  3287. $reloadOnUpdate = $table->isReloadOnUpdate();
  3288. $reloadOnInsert = $table->isReloadOnInsert();
  3289. $script .= "
  3290. public function save(PropelPDO \$con = null".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
  3291. {";
  3292. }
  3293. /**
  3294. * Adds the function body for the save method
  3295. * @param string &$script The script will be modified in this method.
  3296. * @see addSave()
  3297. **/
  3298. protected function addSaveBody(&$script) {
  3299. $table = $this->getTable();
  3300. $reloadOnUpdate = $table->isReloadOnUpdate();
  3301. $reloadOnInsert = $table->isReloadOnInsert();
  3302. $script .= "
  3303. if (\$this->isDeleted()) {
  3304. throw new PropelException(\"You cannot save an object that has been deleted.\");
  3305. }
  3306. if (\$con === null) {
  3307. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
  3308. }
  3309. \$con->beginTransaction();
  3310. \$isInsert = \$this->isNew();
  3311. try {";
  3312. if($this->getGeneratorConfig()->getBuildProperty('addHooks')) {
  3313. // save with runtime hools
  3314. $script .= "
  3315. \$ret = \$this->preSave(\$con);";
  3316. $this->applyBehaviorModifier('preSave', $script, " ");
  3317. $script .= "
  3318. if (\$isInsert) {
  3319. \$ret = \$ret && \$this->preInsert(\$con);";
  3320. $this->applyBehaviorModifier('preInsert', $script, " ");
  3321. $script .= "
  3322. } else {
  3323. \$ret = \$ret && \$this->preUpdate(\$con);";
  3324. $this->applyBehaviorModifier('preUpdate', $script, " ");
  3325. $script .= "
  3326. }
  3327. if (\$ret) {
  3328. \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");
  3329. if (\$isInsert) {
  3330. \$this->postInsert(\$con);";
  3331. $this->applyBehaviorModifier('postInsert', $script, " ");
  3332. $script .= "
  3333. } else {
  3334. \$this->postUpdate(\$con);";
  3335. $this->applyBehaviorModifier('postUpdate', $script, " ");
  3336. $script .= "
  3337. }
  3338. \$this->postSave(\$con);";
  3339. $this->applyBehaviorModifier('postSave', $script, " ");
  3340. $script .= "
  3341. ".$this->getPeerClassname()."::addInstanceToPool(\$this);
  3342. } else {
  3343. \$affectedRows = 0;
  3344. }
  3345. \$con->commit();
  3346. return \$affectedRows;";
  3347. } else {
  3348. // save without runtime hooks
  3349. $this->applyBehaviorModifier('preSave', $script, " ");
  3350. if ($this->hasBehaviorModifier('preUpdate'))
  3351. {
  3352. $script .= "
  3353. if(!\$isInsert) {";
  3354. $this->applyBehaviorModifier('preUpdate', $script, " ");
  3355. $script .= "
  3356. }";
  3357. }
  3358. if ($this->hasBehaviorModifier('preInsert'))
  3359. {
  3360. $script .= "
  3361. if(\$isInsert) {";
  3362. $this->applyBehaviorModifier('preInsert', $script, " ");
  3363. $script .= "
  3364. }";
  3365. }
  3366. $script .= "
  3367. \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");";
  3368. $this->applyBehaviorModifier('postSave', $script, " ");
  3369. if ($this->hasBehaviorModifier('postUpdate'))
  3370. {
  3371. $script .= "
  3372. if(!\$isInsert) {";
  3373. $this->applyBehaviorModifier('postUpdate', $script, " ");
  3374. $script .= "
  3375. }";
  3376. }
  3377. if ($this->hasBehaviorModifier('postInsert'))
  3378. {
  3379. $script .= "
  3380. if(\$isInsert) {";
  3381. $this->applyBehaviorModifier('postInsert', $script, " ");
  3382. $script .= "
  3383. }";
  3384. }
  3385. $script .= "
  3386. \$con->commit();
  3387. ".$this->getPeerClassname()."::addInstanceToPool(\$this);
  3388. return \$affectedRows;";
  3389. }
  3390. $script .= "
  3391. } catch (PropelException \$e) {
  3392. \$con->rollBack();
  3393. throw \$e;
  3394. }";
  3395. }
  3396. /**
  3397. * Adds the function close for the save method
  3398. * @param string &$script The script will be modified in this method.
  3399. * @see addSave()
  3400. **/
  3401. protected function addSaveClose(&$script) {
  3402. $script .= "
  3403. }
  3404. ";
  3405. }
  3406. /**
  3407. * Adds the $alreadyInValidation attribute, which prevents attempting to re-validate the same object.
  3408. * @param string &$script The script will be modified in this method.
  3409. */
  3410. protected function addAlreadyInValidationAttribute(&$script)
  3411. {
  3412. $script .= "
  3413. /**
  3414. * Flag to prevent endless validation loop, if this object is referenced
  3415. * by another object which falls in this transaction.
  3416. * @var boolean
  3417. */
  3418. protected \$alreadyInValidation = false;
  3419. ";
  3420. }
  3421. /**
  3422. * Adds the validate() method.
  3423. * @param string &$script The script will be modified in this method.
  3424. */
  3425. protected function addValidate(&$script)
  3426. {
  3427. $script .= "
  3428. /**
  3429. * Validates the objects modified field values and all objects related to this table.
  3430. *
  3431. * If \$columns is either a column name or an array of column names
  3432. * only those columns are validated.
  3433. *
  3434. * @param mixed \$columns Column name or an array of column names.
  3435. * @return boolean Whether all columns pass validation.
  3436. * @see doValidate()
  3437. * @see getValidationFailures()
  3438. */
  3439. public function validate(\$columns = null)
  3440. {
  3441. \$res = \$this->doValidate(\$columns);
  3442. if (\$res === true) {
  3443. \$this->validationFailures = array();
  3444. return true;
  3445. } else {
  3446. \$this->validationFailures = \$res;
  3447. return false;
  3448. }
  3449. }
  3450. ";
  3451. } // addValidate()
  3452. /**
  3453. * Adds the workhourse doValidate() method.
  3454. * @param string &$script The script will be modified in this method.
  3455. */
  3456. protected function addDoValidate(&$script)
  3457. {
  3458. $table = $this->getTable();
  3459. $script .= "
  3460. /**
  3461. * This function performs the validation work for complex object models.
  3462. *
  3463. * In addition to checking the current object, all related objects will
  3464. * also be validated. If all pass then <code>true</code> is returned; otherwise
  3465. * an aggreagated array of ValidationFailed objects will be returned.
  3466. *
  3467. * @param array \$columns Array of column names to validate.
  3468. * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise.
  3469. */
  3470. protected function doValidate(\$columns = null)
  3471. {
  3472. if (!\$this->alreadyInValidation) {
  3473. \$this->alreadyInValidation = true;
  3474. \$retval = null;
  3475. \$failureMap = array();
  3476. ";
  3477. if (count($table->getForeignKeys()) != 0) {
  3478. $script .= "
  3479. // We call the validate method on the following object(s) if they
  3480. // were passed to this object by their coresponding set
  3481. // method. This object relates to these object(s) by a
  3482. // foreign key reference.
  3483. ";
  3484. foreach ($table->getForeignKeys() as $fk) {
  3485. $aVarName = $this->getFKVarName($fk);
  3486. $script .= "
  3487. if (\$this->".$aVarName." !== null) {
  3488. if (!\$this->".$aVarName."->validate(\$columns)) {
  3489. \$failureMap = array_merge(\$failureMap, \$this->".$aVarName."->getValidationFailures());
  3490. }
  3491. }
  3492. ";
  3493. } /* for () */
  3494. } /* if count(fkeys) */
  3495. $script .= "
  3496. if ((\$retval = ".$this->getPeerClassname()."::doValidate(\$this, \$columns)) !== true) {
  3497. \$failureMap = array_merge(\$failureMap, \$retval);
  3498. }
  3499. ";
  3500. foreach ($table->getReferrers() as $refFK) {
  3501. if ($refFK->isLocalPrimaryKey()) {
  3502. $varName = $this->getPKRefFKVarName($refFK);
  3503. $script .= "
  3504. if (\$this->$varName !== null) {
  3505. if (!\$this->".$varName."->validate(\$columns)) {
  3506. \$failureMap = array_merge(\$failureMap, \$this->".$varName."->getValidationFailures());
  3507. }
  3508. }
  3509. ";
  3510. } else {
  3511. $collName = $this->getRefFKCollVarName($refFK);
  3512. $script .= "
  3513. if (\$this->$collName !== null) {
  3514. foreach (\$this->$collName as \$referrerFK) {
  3515. if (!\$referrerFK->validate(\$columns)) {
  3516. \$failureMap = array_merge(\$failureMap, \$referrerFK->getValidationFailures());
  3517. }
  3518. }
  3519. }
  3520. ";
  3521. }
  3522. } /* foreach getReferrers() */
  3523. $script .= "
  3524. \$this->alreadyInValidation = false;
  3525. }
  3526. return (!empty(\$failureMap) ? \$failureMap : true);
  3527. }
  3528. ";
  3529. } // addDoValidate()
  3530. /**
  3531. * Adds the ensureConsistency() method to ensure that internal state is correct.
  3532. * @param string &$script The script will be modified in this method.
  3533. */
  3534. protected function addEnsureConsistency(&$script)
  3535. {
  3536. $table = $this->getTable();
  3537. $script .= "
  3538. /**
  3539. * Checks and repairs the internal consistency of the object.
  3540. *
  3541. * This method is executed after an already-instantiated object is re-hydrated
  3542. * from the database. It exists to check any foreign keys to make sure that
  3543. * the objects related to the current object are correct based on foreign key.
  3544. *
  3545. * You can override this method in the stub class, but you should always invoke
  3546. * the base method from the overridden method (i.e. parent::ensureConsistency()),
  3547. * in case your model changes.
  3548. *
  3549. * @throws PropelException
  3550. */
  3551. public function ensureConsistency()
  3552. {
  3553. ";
  3554. foreach ($table->getColumns() as $col) {
  3555. $clo=strtolower($col->getName());
  3556. if ($col->isForeignKey()) {
  3557. foreach ($col->getForeignKeys() as $fk) {
  3558. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  3559. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  3560. $varName = $this->getFKVarName($fk);
  3561. $script .= "
  3562. if (\$this->".$varName." !== null && \$this->$clo !== \$this->".$varName."->get".$colFK->getPhpName()."()) {
  3563. \$this->$varName = null;
  3564. }";
  3565. } // foraech
  3566. } /* if col is foreign key */
  3567. } // foreach
  3568. $script .= "
  3569. } // ensureConsistency
  3570. ";
  3571. } // addCheckRelConsistency
  3572. /**
  3573. * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects.
  3574. * @param string &$script The script will be modified in this method.
  3575. */
  3576. protected function addCopy(&$script)
  3577. {
  3578. $this->addCopyInto($script);
  3579. $table = $this->getTable();
  3580. $script .= "
  3581. /**
  3582. * Makes a copy of this object that will be inserted as a new row in table when saved.
  3583. * It creates a new object filling in the simple attributes, but skipping any primary
  3584. * keys that are defined for the table.
  3585. *
  3586. * If desired, this method can also make copies of all associated (fkey referrers)
  3587. * objects.
  3588. *
  3589. * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
  3590. * @return ".$this->getObjectClassname()." Clone of current object.
  3591. * @throws PropelException
  3592. */
  3593. public function copy(\$deepCopy = false)
  3594. {
  3595. // we use get_class(), because this might be a subclass
  3596. \$clazz = get_class(\$this);
  3597. " . $this->buildObjectInstanceCreationCode('$copyObj', '$clazz') . "
  3598. \$this->copyInto(\$copyObj, \$deepCopy);
  3599. return \$copyObj;
  3600. }
  3601. ";
  3602. } // addCopy()
  3603. /**
  3604. * Adds the copyInto() method, which takes an object and sets contents to match current object.
  3605. * In complex OM this method includes the $deepCopy param for making copies of related objects.
  3606. * @param string &$script The script will be modified in this method.
  3607. */
  3608. protected function addCopyInto(&$script)
  3609. {
  3610. $table = $this->getTable();
  3611. $script .= "
  3612. /**
  3613. * Sets contents of passed object to values from current object.
  3614. *
  3615. * If desired, this method can also make copies of all associated (fkey referrers)
  3616. * objects.
  3617. *
  3618. * @param object \$copyObj An object of ".$this->getObjectClassname()." (or compatible) type.
  3619. * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
  3620. * @throws PropelException
  3621. */
  3622. public function copyInto(\$copyObj, \$deepCopy = false)
  3623. {";
  3624. $autoIncCols = array();
  3625. foreach ($table->getColumns() as $col) {
  3626. /* @var $col Column */
  3627. if ($col->isAutoIncrement()) {
  3628. $autoIncCols[] = $col;
  3629. }
  3630. }
  3631. foreach ($table->getColumns() as $col) {
  3632. if (!in_array($col, $autoIncCols, true)) {
  3633. $script .= "
  3634. \$copyObj->set".$col->getPhpName()."(\$this->".strtolower($col->getName()).");";
  3635. }
  3636. } // foreach
  3637. // Avoid useless code by checking to see if there are any referrers
  3638. // to this table:
  3639. if (count($table->getReferrers()) > 0) {
  3640. $script .= "
  3641. if (\$deepCopy) {
  3642. // important: temporarily setNew(false) because this affects the behavior of
  3643. // the getter/setter methods for fkey referrer objects.
  3644. \$copyObj->setNew(false);
  3645. ";
  3646. foreach ($table->getReferrers() as $fk) {
  3647. //HL: commenting out self-referrential check below
  3648. // it seems to work as expected and is probably desireable to have those referrers from same table deep-copied.
  3649. //if ( $fk->getTable()->getName() != $table->getName() ) {
  3650. if ($fk->isLocalPrimaryKey()) {
  3651. $afx = $this->getRefFKPhpNameAffix($fk, $plural = false);
  3652. $script .= "
  3653. \$relObj = \$this->get$afx();
  3654. if (\$relObj) {
  3655. \$copyObj->set$afx(\$relObj->copy(\$deepCopy));
  3656. }
  3657. ";
  3658. } else {
  3659. $script .= "
  3660. foreach (\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {
  3661. if (\$relObj !== \$this) { // ensure that we don't try to copy a reference to ourselves
  3662. \$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy));
  3663. }
  3664. }
  3665. ";
  3666. }
  3667. // HL: commenting out close of self-referential check
  3668. // } /* if tblFK != table */
  3669. } /* foreach */
  3670. $script .= "
  3671. } // if (\$deepCopy)
  3672. ";
  3673. } /* if (count referrers > 0 ) */
  3674. $script .= "
  3675. \$copyObj->setNew(true);";
  3676. // Note: we're no longer resetting non-autoincrement primary keys to default values
  3677. // due to: http://propel.phpdb.org/trac/ticket/618
  3678. foreach ($autoIncCols as $col) {
  3679. $coldefval = $col->getPhpDefaultValue();
  3680. $coldefval = var_export($coldefval, true);
  3681. $script .= "
  3682. \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a auto-increment column, so set to default value";
  3683. } // foreach
  3684. $script .= "
  3685. }
  3686. ";
  3687. } // addCopyInto()
  3688. /**
  3689. * Adds clear method
  3690. * @param string &$script The script will be modified in this method.
  3691. */
  3692. protected function addClear(&$script)
  3693. {
  3694. $table = $this->getTable();
  3695. $script .= "
  3696. /**
  3697. * Clears the current object and sets all attributes to their default values
  3698. */
  3699. public function clear()
  3700. {";
  3701. foreach ($table->getColumns() as $col) {
  3702. $script .= "
  3703. \$this->" . strtolower($col->getName()) . " = null;";
  3704. }
  3705. $script .= "
  3706. \$this->alreadyInSave = false;
  3707. \$this->alreadyInValidation = false;
  3708. \$this->clearAllReferences();";
  3709. if ($this->hasDefaultValues()) {
  3710. $script .= "
  3711. \$this->applyDefaultValues();";
  3712. }
  3713. $script .= "
  3714. \$this->resetModified();
  3715. \$this->setNew(true);
  3716. \$this->setDeleted(false);
  3717. }
  3718. ";
  3719. }
  3720. /**
  3721. * Adds clearAllReferencers() method which resets all the collections of referencing
  3722. * fk objects.
  3723. * @param string &$script The script will be modified in this method.
  3724. */
  3725. protected function addClearAllReferences(&$script)
  3726. {
  3727. $table = $this->getTable();
  3728. $script .= "
  3729. /**
  3730. * Resets all collections of referencing foreign keys.
  3731. *
  3732. * This method is a user-space workaround for PHP's inability to garbage collect objects
  3733. * with circular references. This is currently necessary when using Propel in certain
  3734. * daemon or large-volumne/high-memory operations.
  3735. *
  3736. * @param boolean \$deep Whether to also clear the references on all associated objects.
  3737. */
  3738. public function clearAllReferences(\$deep = false)
  3739. {
  3740. if (\$deep) {";
  3741. $vars = array();
  3742. foreach ($this->getTable()->getReferrers() as $refFK) {
  3743. if ($refFK->isLocalPrimaryKey()) {
  3744. $varName = $this->getPKRefFKVarName($refFK);
  3745. $vars[] = $varName;
  3746. $script .= "
  3747. if (\$this->$varName) {
  3748. \$this->{$varName}->clearAllReferences(\$deep);
  3749. }";
  3750. } else {
  3751. $varName = $this->getRefFKCollVarName($refFK);
  3752. $vars[] = $varName;
  3753. $script .= "
  3754. if (\$this->$varName) {
  3755. foreach ((array) \$this->$varName as \$o) {
  3756. \$o->clearAllReferences(\$deep);
  3757. }
  3758. }";
  3759. }
  3760. }
  3761. $script .= "
  3762. } // if (\$deep)
  3763. ";
  3764. $this->applyBehaviorModifier('objectClearReferences', $script, " ");
  3765. foreach ($vars as $varName) {
  3766. $script .= "
  3767. \$this->$varName = null;";
  3768. }
  3769. foreach ($table->getForeignKeys() as $fk) {
  3770. $className = $this->getForeignTable($fk)->getPhpName();
  3771. $varName = $this->getFKVarName($fk);
  3772. $script .= "
  3773. \$this->$varName = null;";
  3774. }
  3775. $script .= "
  3776. }
  3777. ";
  3778. }
  3779. /**
  3780. * Adds a magic __toString() method if a string column was defined as primary string
  3781. * @param string &$script The script will be modified in this method.
  3782. */
  3783. protected function addPrimaryString(&$script)
  3784. {
  3785. foreach ($this->getTable()->getColumns() as $column) {
  3786. if ($column->isPrimaryString()) {
  3787. $script .= "
  3788. /**
  3789. * Return the string representation of this object
  3790. *
  3791. * @return string The value of the '{$column->getName()}' column
  3792. */
  3793. public function __toString()
  3794. {
  3795. return (string) \$this->get{$column->getPhpName()}();
  3796. }
  3797. ";
  3798. break;
  3799. }
  3800. }
  3801. }
  3802. /**
  3803. * Adds a magic __call() method
  3804. * @param string &$script The script will be modified in this method.
  3805. */
  3806. protected function addMagicCall(&$script)
  3807. {
  3808. $script .= "
  3809. /**
  3810. * Catches calls to virtual methods
  3811. */
  3812. public function __call(\$name, \$params)
  3813. {";
  3814. $this->applyBehaviorModifier('objectCall', $script, " ");
  3815. $script .= "
  3816. if (preg_match('/get(\w+)/', \$name, \$matches)) {
  3817. \$virtualColumn = \$matches[1];
  3818. if (\$this->hasVirtualColumn(\$virtualColumn)) {
  3819. return \$this->getVirtualColumn(\$virtualColumn);
  3820. }
  3821. // no lcfirst in php<5.3...
  3822. \$virtualColumn[0] = strtolower(\$virtualColumn[0]);
  3823. if (\$this->hasVirtualColumn(\$virtualColumn)) {
  3824. return \$this->getVirtualColumn(\$virtualColumn);
  3825. }
  3826. }
  3827. return parent::__call(\$name, \$params);
  3828. }
  3829. ";
  3830. }
  3831. } // PHP5ObjectBuilder