PageRenderTime 72ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/generator/lib/builder/om/PHP5ObjectBuilder.php

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