PageRenderTime 44ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/bayrock/gw2spidy
PHP | 5550 lines | 3375 code | 526 blank | 1649 comment | 396 complexity | 7ded4b9b240204e5f107edf31b0b2cf0 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/ObjectBuilder.php';
  10. /**
  11. * Generates a PHP5 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 default key type. if not presented in configuration default will be 'TYPE_PHPNAME'
  41. * @return string
  42. */
  43. public function getDefaultKeyType()
  44. {
  45. $defaultKeyType = $this->getBuildProperty('defaultKeyType') ? $this->getBuildProperty('defaultKeyType') : 'phpName';
  46. return "TYPE_".strtoupper($defaultKeyType);
  47. }
  48. /**
  49. * Returns the name of the current class being built.
  50. * @return string
  51. */
  52. public function getUnprefixedClassname()
  53. {
  54. return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname();
  55. }
  56. /**
  57. * Validates the current table to make sure that it won't
  58. * result in generated code that will not parse.
  59. *
  60. * This method may emit warnings for code which may cause problems
  61. * and will throw exceptions for errors that will definitely cause
  62. * problems.
  63. */
  64. protected function validateModel()
  65. {
  66. parent::validateModel();
  67. $table = $this->getTable();
  68. // Check to see whether any generated foreign key names
  69. // will conflict with column names.
  70. $colPhpNames = array();
  71. $fkPhpNames = array();
  72. foreach ($table->getColumns() as $col) {
  73. $colPhpNames[] = $col->getPhpName();
  74. }
  75. foreach ($table->getForeignKeys() as $fk) {
  76. $fkPhpNames[] = $this->getFKPhpNameAffix($fk, $plural = false);
  77. }
  78. $intersect = array_intersect($colPhpNames, $fkPhpNames);
  79. if (!empty($intersect)) {
  80. throw new EngineException("One or more of your column names for [" . $table->getName() . "] table conflict with foreign key names (" . implode(", ", $intersect) . ")");
  81. }
  82. // Check foreign keys to see if there are any foreign keys that
  83. // are also matched with an inversed referencing foreign key
  84. // (this is currently unsupported behavior)
  85. // see: http://propel.phpdb.org/trac/ticket/549
  86. foreach ($table->getForeignKeys() as $fk) {
  87. if ($fk->isMatchedByInverseFK()) {
  88. 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.)" );
  89. }
  90. }
  91. }
  92. /**
  93. * Returns the appropriate formatter (from platform) for a date/time column.
  94. * @param Column $col
  95. * @return string
  96. */
  97. protected function getTemporalFormatter(Column $col)
  98. {
  99. $fmt = null;
  100. if ($col->getType() === PropelTypes::DATE) {
  101. $fmt = $this->getPlatform()->getDateFormatter();
  102. } elseif ($col->getType() === PropelTypes::TIME) {
  103. $fmt = $this->getPlatform()->getTimeFormatter();
  104. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  105. $fmt = $this->getPlatform()->getTimestampFormatter();
  106. }
  107. return $fmt;
  108. }
  109. /**
  110. * Returns the type-casted and stringified default value for the specified Column.
  111. * This only works for scalar default values currently.
  112. * @return string The default value or 'NULL' if there is none.
  113. * @throws EngineException
  114. */
  115. protected function getDefaultValueString(Column $col)
  116. {
  117. $defaultValue = var_export(null, true);
  118. $val = $col->getPhpDefaultValue();
  119. if ($val === null) {
  120. return $defaultValue;
  121. }
  122. if ($col->isTemporalType()) {
  123. $fmt = $this->getTemporalFormatter($col);
  124. try {
  125. if (!($this->getPlatform() instanceof MysqlPlatform &&
  126. ($val === '0000-00-00 00:00:00' || $val === '0000-00-00'))) {
  127. // while technically this is not a default value of NULL,
  128. // this seems to be closest in meaning.
  129. $defDt = new DateTime($val);
  130. $defaultValue = var_export($defDt->format($fmt), true);
  131. }
  132. } catch (Exception $x) {
  133. // prevent endless loop when timezone is undefined
  134. date_default_timezone_set('America/Los_Angeles');
  135. throw new EngineException(sprintf('Unable to parse default temporal value "%s" for column "%s"', $col->getDefaultValueString(), $col->getFullyQualifiedName()), $x);
  136. }
  137. } elseif ($col->isEnumType()) {
  138. $valueSet = $col->getValueSet();
  139. if (!in_array($val, $valueSet)) {
  140. throw new EngineException(sprintf('Default Value "%s" is not among the enumerated values', $val));
  141. }
  142. $defaultValue = array_search($val, $valueSet);
  143. } elseif ($col->isPhpPrimitiveType()) {
  144. settype($val, $col->getPhpType());
  145. $defaultValue = var_export($val, true);
  146. } elseif ($col->isPhpObjectType()) {
  147. $defaultValue = 'new '.$col->getPhpType().'(' . var_export($val, true) . ')';
  148. } elseif ($col->isPhpArrayType()) {
  149. $defaultValue = var_export($val, true);
  150. } else {
  151. throw new EngineException("Cannot get default value string for " . $col->getFullyQualifiedName());
  152. }
  153. return $defaultValue;
  154. }
  155. /**
  156. * Adds the include() statements for files that this class depends on or utilizes.
  157. * @param string &$script The script will be modified in this method.
  158. */
  159. protected function addIncludes(&$script)
  160. {
  161. } // addIncludes()
  162. /**
  163. * Adds class phpdoc comment and openning of class.
  164. * @param string &$script The script will be modified in this method.
  165. */
  166. protected function addClassOpen(&$script)
  167. {
  168. $table = $this->getTable();
  169. $tableName = $table->getName();
  170. $tableDesc = $table->getDescription();
  171. $interface = $this->getInterface();
  172. $parentClass = $this->getBehaviorContent('parentClass');
  173. $parentClass = (null !== $parentClass) ? $parentClass : ClassTools::classname($this->getBaseClass());
  174. $script .= "
  175. /**
  176. * Base class that represents a row from the '$tableName' table.
  177. *
  178. * $tableDesc
  179. *";
  180. if ($this->getBuildProperty('addTimeStamp')) {
  181. $now = strftime('%c');
  182. $script .= "
  183. * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
  184. *
  185. * $now
  186. *";
  187. }
  188. $script .= "
  189. * @package propel.generator.".$this->getPackage()."
  190. */
  191. abstract class ".$this->getClassname()." extends ".$parentClass." ";
  192. if ($interface = $this->getTable()->getInterface()) {
  193. $script .= "implements " . ClassTools::classname($interface);
  194. if ($interface !== ClassTools::classname($interface)) {
  195. $this->declareClass($interface);
  196. } else {
  197. $this->declareClassFromBuilder($this->getInterfaceBuilder());
  198. }
  199. } elseif ($interface = ClassTools::getInterface($table)) {
  200. $script .= "implements " . ClassTools::classname($interface);
  201. }
  202. $script .= "
  203. {
  204. ";
  205. }
  206. /**
  207. * Specifies the methods that are added as part of the basic OM class.
  208. * This can be overridden by subclasses that wish to add more methods.
  209. * @see ObjectBuilder::addClassBody()
  210. */
  211. protected function addClassBody(&$script)
  212. {
  213. $this->declareClassFromBuilder($this->getStubObjectBuilder());
  214. $this->declareClassFromBuilder($this->getStubPeerBuilder());
  215. $this->declareClassFromBuilder($this->getStubQueryBuilder());
  216. $this->declareClasses('Propel', 'PropelException', 'PDO', 'PropelPDO', 'Criteria', 'BaseObject', 'Persistent', 'BasePeer', 'PropelCollection', 'PropelObjectCollection', 'Exception');
  217. $table = $this->getTable();
  218. if (!$table->isAlias()) {
  219. $this->addConstants($script);
  220. $this->addAttributes($script);
  221. }
  222. if ($table->hasCrossForeignKeys()) {
  223. foreach ($table->getCrossFks() as $fkList) {
  224. list($refFK, $crossFK) = $fkList;
  225. $fkName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  226. $this->addScheduledForDeletionAttribute($script, $fkName);
  227. }
  228. }
  229. foreach ($table->getReferrers() as $refFK) {
  230. $fkName = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  231. $this->addScheduledForDeletionAttribute($script, $fkName);
  232. }
  233. if ($this->hasDefaultValues()) {
  234. $this->addApplyDefaultValues($script);
  235. $this->addConstructor($script);
  236. }
  237. $this->addColumnAccessorMethods($script);
  238. $this->addColumnMutatorMethods($script);
  239. $this->addHasOnlyDefaultValues($script);
  240. $this->addHydrate($script);
  241. $this->addEnsureConsistency($script);
  242. if (!$table->isReadOnly()) {
  243. $this->addManipulationMethods($script);
  244. }
  245. if ($this->isAddValidateMethod()) {
  246. $this->addValidationMethods($script);
  247. }
  248. if ($this->isAddGenericAccessors()) {
  249. $this->addGetByName($script);
  250. $this->addGetByPosition($script);
  251. $this->addToArray($script);
  252. }
  253. if ($this->isAddGenericMutators()) {
  254. $this->addSetByName($script);
  255. $this->addSetByPosition($script);
  256. $this->addFromArray($script);
  257. }
  258. $this->addBuildCriteria($script);
  259. $this->addBuildPkeyCriteria($script);
  260. $this->addGetPrimaryKey($script);
  261. $this->addSetPrimaryKey($script);
  262. $this->addIsPrimaryKeyNull($script);
  263. $this->addCopy($script);
  264. if (!$table->isAlias()) {
  265. $this->addGetPeer($script);
  266. }
  267. $this->addFKMethods($script);
  268. $this->addRefFKMethods($script);
  269. $this->addCrossFKMethods($script);
  270. $this->addClear($script);
  271. $this->addClearAllReferences($script);
  272. $this->addPrimaryString($script);
  273. $this->addIsAlreadyInSave($script);
  274. // apply behaviors
  275. $this->applyBehaviorModifier('objectMethods', $script, " ");
  276. $this->addMagicCall($script);
  277. }
  278. /**
  279. * Closes class.
  280. * @param string &$script The script will be modified in this method.
  281. */
  282. protected function addClassClose(&$script)
  283. {
  284. $script .= "
  285. } // " . $this->getClassname() . "
  286. ";
  287. $this->applyBehaviorModifier('objectFilter', $script, "");
  288. }
  289. /**
  290. * Adds any constants to the class.
  291. * @param string &$script The script will be modified in this method.
  292. */
  293. protected function addConstants(&$script)
  294. {
  295. $script .= "
  296. /**
  297. * Peer class name
  298. */
  299. const PEER = '" . addslashes($this->getStubPeerBuilder()->getFullyQualifiedClassname()) . "';
  300. ";
  301. }
  302. /**
  303. * Adds class attributes.
  304. * @param string &$script The script will be modified in this method.
  305. */
  306. protected function addAttributes(&$script)
  307. {
  308. $table = $this->getTable();
  309. $script .= "
  310. /**
  311. * The Peer class.
  312. * Instance provides a convenient way of calling static methods on a class
  313. * that calling code may not be able to identify.
  314. * @var ".$this->getPeerClassname()."
  315. */
  316. protected static \$peer;
  317. /**
  318. * The flag var to prevent infinit loop in deep copy
  319. * @var boolean
  320. */
  321. protected \$startCopy = false;
  322. ";
  323. if (!$table->isAlias()) {
  324. $this->addColumnAttributes($script);
  325. }
  326. foreach ($table->getForeignKeys() as $fk) {
  327. $this->addFKAttributes($script, $fk);
  328. }
  329. foreach ($table->getReferrers() as $refFK) {
  330. $this->addRefFKAttributes($script, $refFK);
  331. }
  332. // many-to-many relationships
  333. foreach ($table->getCrossFks() as $fkList) {
  334. $crossFK = $fkList[1];
  335. $this->addCrossFKAttributes($script, $crossFK);
  336. }
  337. $this->addAlreadyInSaveAttribute($script);
  338. $this->addAlreadyInValidationAttribute($script);
  339. // apply behaviors
  340. $this->applyBehaviorModifier('objectAttributes', $script, " ");
  341. }
  342. /**
  343. * Adds variables that store column values.
  344. * @param string &$script The script will be modified in this method.
  345. * @see addColumnNameConstants()
  346. */
  347. protected function addColumnAttributes(&$script)
  348. {
  349. $table = $this->getTable();
  350. foreach ($table->getColumns() as $col) {
  351. $this->addColumnAttributeComment($script, $col);
  352. $this->addColumnAttributeDeclaration($script, $col);
  353. if ($col->isLazyLoad() ) {
  354. $this->addColumnAttributeLoaderComment($script, $col);
  355. $this->addColumnAttributeLoaderDeclaration($script, $col);
  356. }
  357. if ($col->getType() == PropelTypes::OBJECT || $col->getType() == PropelTypes::PHP_ARRAY) {
  358. $this->addColumnAttributeUnserializedComment($script, $col);
  359. $this->addColumnAttributeUnserializedDeclaration($script, $col);
  360. }
  361. }
  362. }
  363. /**
  364. * Add comment about the attribute (variable) that stores column values
  365. * @param string &$script The script will be modified in this method.
  366. * @param Column $col
  367. **/
  368. protected function addColumnAttributeComment(&$script, Column $col)
  369. {
  370. $cptype = $col->getPhpType();
  371. $clo = strtolower($col->getName());
  372. $script .= "
  373. /**
  374. * The value for the $clo field.";
  375. if ($col->getDefaultValue()) {
  376. if ($col->getDefaultValue()->isExpression()) {
  377. $script .= "
  378. * Note: this column has a database default value of: (expression) ".$col->getDefaultValue()->getValue();
  379. } else {
  380. $script .= "
  381. * Note: this column has a database default value of: ". $this->getDefaultValueString($col);
  382. }
  383. }
  384. $script .= "
  385. * @var $cptype
  386. */";
  387. }
  388. /**
  389. * Adds the declaration of a column value storage attribute
  390. * @param string &$script The script will be modified in this method.
  391. * @param Column $col
  392. **/
  393. protected function addColumnAttributeDeclaration(&$script, Column $col)
  394. {
  395. $clo = strtolower($col->getName());
  396. $script .= "
  397. protected \$" . $clo . ";
  398. ";
  399. }
  400. /**
  401. * Adds the comment about the attribute keeping track if an attribute value has been loaded
  402. * @param string &$script The script will be modified in this method.
  403. * @param Column $col
  404. **/
  405. protected function addColumnAttributeLoaderComment(&$script, Column $col)
  406. {
  407. $clo = strtolower($col->getName());
  408. $script .= "
  409. /**
  410. * Whether the lazy-loaded \$$clo value has been loaded from database.
  411. * This is necessary to avoid repeated lookups if \$$clo column is NULL in the db.
  412. * @var boolean
  413. */";
  414. }
  415. /**
  416. * Adds the declaration of the attribute keeping track of an attribute's loaded state
  417. * @param string &$script The script will be modified in this method.
  418. * @param Column $col
  419. **/
  420. protected function addColumnAttributeLoaderDeclaration(&$script, Column $col)
  421. {
  422. $clo = strtolower($col->getName());
  423. $script .= "
  424. protected \$".$clo."_isLoaded = false;
  425. ";
  426. }
  427. /**
  428. * Adds the comment about the serialized attribute
  429. * @param string &$script The script will be modified in this method.
  430. * @param Column $col
  431. **/
  432. protected function addColumnAttributeUnserializedComment(&$script, Column $col)
  433. {
  434. $clo = strtolower($col->getName());
  435. $script .= "
  436. /**
  437. * The unserialized \$$clo value - i.e. the persisted object.
  438. * This is necessary to avoid repeated calls to unserialize() at runtime.
  439. * @var object
  440. */";
  441. }
  442. /**
  443. * Adds the declaration of the serialized attribute
  444. * @param string &$script The script will be modified in this method.
  445. * @param Column $col
  446. **/
  447. protected function addColumnAttributeUnserializedDeclaration(&$script, Column $col)
  448. {
  449. $clo = strtolower($col->getName()) . "_unserialized";
  450. $script .= "
  451. protected \$" . $clo . ";
  452. ";
  453. }
  454. /**
  455. * Adds the getPeer() method.
  456. * This is a convenient, non introspective way of getting the Peer class for a particular object.
  457. * @param string &$script The script will be modified in this method.
  458. */
  459. protected function addGetPeer(&$script)
  460. {
  461. $this->addGetPeerComment($script);
  462. $this->addGetPeerFunctionOpen($script);
  463. $this->addGetPeerFunctionBody($script);
  464. $this->addGetPeerFunctionClose($script);
  465. }
  466. /**
  467. * Add the comment for the getPeer method
  468. * @param string &$script The script will be modified in this method.
  469. **/
  470. protected function addGetPeerComment(&$script)
  471. {
  472. $script .= "
  473. /**
  474. * Returns a peer instance associated with this om.
  475. *
  476. * Since Peer classes are not to have any instance attributes, this method returns the
  477. * same instance for all member of this class. The method could therefore
  478. * be static, but this would prevent one from overriding the behavior.
  479. *
  480. * @return ".$this->getPeerClassname()."
  481. */";
  482. }
  483. /**
  484. * Adds the function declaration (function opening) for the getPeer method
  485. * @param string &$script The script will be modified in this method.
  486. **/
  487. protected function addGetPeerFunctionOpen(&$script)
  488. {
  489. $script .= "
  490. public function getPeer()
  491. {";
  492. }
  493. /**
  494. * Adds the body of the getPeer method
  495. * @param string &$script The script will be modified in this method.
  496. **/
  497. protected function addGetPeerFunctionBody(&$script)
  498. {
  499. $script .= "
  500. if (self::\$peer === null) {
  501. " . $this->buildObjectInstanceCreationCode('self::$peer', $this->getPeerClassname()) . "
  502. }
  503. return self::\$peer;";
  504. }
  505. /**
  506. * Add the function close for the getPeer method
  507. * 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
  508. * @param string &$script The script will be modified in this method.
  509. **/
  510. protected function addGetPeerFunctionClose(&$script)
  511. {
  512. $script .= "
  513. }
  514. ";
  515. }
  516. /**
  517. * Adds the constructor for this object.
  518. * @param string &$script The script will be modified in this method.
  519. * @see addConstructor()
  520. */
  521. protected function addConstructor(&$script)
  522. {
  523. $this->addConstructorComment($script);
  524. $this->addConstructorOpen($script);
  525. $this->addConstructorBody($script);
  526. $this->addConstructorClose($script);
  527. }
  528. /**
  529. * Adds the comment for the constructor
  530. * @param string &$script The script will be modified in this method.
  531. **/
  532. protected function addConstructorComment(&$script)
  533. {
  534. $script .= "
  535. /**
  536. * Initializes internal state of ".$this->getClassname()." object.
  537. * @see applyDefaults()
  538. */";
  539. }
  540. /**
  541. * Adds the function declaration for the constructor
  542. * @param string &$script The script will be modified in this method.
  543. **/
  544. protected function addConstructorOpen(&$script)
  545. {
  546. $script .= "
  547. public function __construct()
  548. {";
  549. }
  550. /**
  551. * Adds the function body for the constructor
  552. * @param string &$script The script will be modified in this method.
  553. **/
  554. protected function addConstructorBody(&$script)
  555. {
  556. $script .= "
  557. parent::__construct();
  558. \$this->applyDefaultValues();";
  559. }
  560. /**
  561. * Adds the function close for the constructor
  562. * @param string &$script The script will be modified in this method.
  563. **/
  564. protected function addConstructorClose(&$script)
  565. {
  566. $script .= "
  567. }
  568. ";
  569. }
  570. /**
  571. * Adds the applyDefaults() method, which is called from the constructor.
  572. * @param string &$script The script will be modified in this method.
  573. * @see addConstructor()
  574. */
  575. protected function addApplyDefaultValues(&$script)
  576. {
  577. $this->addApplyDefaultValuesComment($script);
  578. $this->addApplyDefaultValuesOpen($script);
  579. $this->addApplyDefaultValuesBody($script);
  580. $this->addApplyDefaultValuesClose($script);
  581. }
  582. /**
  583. * Adds the comment for the applyDefaults method
  584. * @param string &$script The script will be modified in this method.
  585. * @see addApplyDefaultValues()
  586. **/
  587. protected function addApplyDefaultValuesComment(&$script)
  588. {
  589. $script .= "
  590. /**
  591. * Applies default values to this object.
  592. * This method should be called from the object's constructor (or
  593. * equivalent initialization method).
  594. * @see __construct()
  595. */";
  596. }
  597. /**
  598. * Adds the function declaration for the applyDefaults method
  599. * @param string &$script The script will be modified in this method.
  600. * @see addApplyDefaultValues()
  601. **/
  602. protected function addApplyDefaultValuesOpen(&$script)
  603. {
  604. $script .= "
  605. public function applyDefaultValues()
  606. {";
  607. }
  608. /**
  609. * Adds the function body of the applyDefault method
  610. * @param string &$script The script will be modified in this method.
  611. * @see addApplyDefaultValues()
  612. **/
  613. protected function addApplyDefaultValuesBody(&$script)
  614. {
  615. $table = $this->getTable();
  616. // FIXME - Apply support for PHP default expressions here
  617. // see: http://propel.phpdb.org/trac/ticket/378
  618. $colsWithDefaults = array();
  619. foreach ($table->getColumns() as $col) {
  620. $def = $col->getDefaultValue();
  621. if ($def !== null && !$def->isExpression()) {
  622. $colsWithDefaults[] = $col;
  623. }
  624. }
  625. $colconsts = array();
  626. foreach ($colsWithDefaults as $col) {
  627. $clo = strtolower($col->getName());
  628. $defaultValue = $this->getDefaultValueString($col);
  629. $script .= "
  630. \$this->".$clo." = $defaultValue;";
  631. }
  632. }
  633. /**
  634. * Adds the function close for the applyDefaults method
  635. * @param string &$script The script will be modified in this method.
  636. * @see addApplyDefaultValues()
  637. **/
  638. protected function addApplyDefaultValuesClose(&$script)
  639. {
  640. $script .= "
  641. }
  642. ";
  643. }
  644. // --------------------------------------------------------------
  645. //
  646. // A C C E S S O R M E T H O D S
  647. //
  648. // --------------------------------------------------------------
  649. /**
  650. * Adds a date/time/timestamp getter method.
  651. * @param string &$script The script will be modified in this method.
  652. * @param Column $col The current column.
  653. * @see parent::addColumnAccessors()
  654. */
  655. protected function addTemporalAccessor(&$script, Column $col)
  656. {
  657. $this->addTemporalAccessorComment($script, $col);
  658. $this->addTemporalAccessorOpen($script, $col);
  659. $this->addTemporalAccessorBody($script, $col);
  660. $this->addTemporalAccessorClose($script, $col);
  661. } // addTemporalAccessor
  662. /**
  663. * Adds the comment for a temporal accessor
  664. * @param string &$script The script will be modified in this method.
  665. * @param Column $col The current column.
  666. * @see addTemporalAccessor
  667. **/
  668. public function addTemporalAccessorComment(&$script, Column $col)
  669. {
  670. $clo = strtolower($col->getName());
  671. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  672. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  673. if (!$dateTimeClass) {
  674. $dateTimeClass = 'DateTime';
  675. }
  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. $script .= "
  688. /**
  689. * Get the [optionally formatted] temporal [$clo] column value.
  690. * ".$col->getDescription();
  691. if (!$useDateTime) {
  692. $script .= "
  693. * This accessor only only work with unix epoch dates. Consider enabling the propel.useDateTimeClass
  694. * option in order to avoid converstions to integers (which are limited in the dates they can express).";
  695. }
  696. $script .= "
  697. *
  698. * @param string \$format The date/time format string (either date()-style or strftime()-style).
  699. * If format is NULL, then the raw ".($useDateTime ? 'DateTime object' : 'unix timestamp integer')." will be returned.";
  700. if ($useDateTime) {
  701. $script .= "
  702. * @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 : '');
  703. } else {
  704. $script .= "
  705. * @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 : '');
  706. }
  707. $script .= "
  708. * @throws PropelException - if unable to parse/validate the date/time value.
  709. */";
  710. }
  711. /**
  712. * Adds the function declaration for a temporal accessor
  713. * @param string &$script The script will be modified in this method.
  714. * @param Column $col The current column.
  715. * @see addTemporalAccessor
  716. **/
  717. public function addTemporalAccessorOpen(&$script, Column $col)
  718. {
  719. $cfc = $col->getPhpName();
  720. $defaultfmt = null;
  721. $visibility = $col->getAccessorVisibility();
  722. // Default date/time formatter strings are specified in build.properties
  723. if ($col->getType() === PropelTypes::DATE) {
  724. $defaultfmt = $this->getBuildProperty('defaultDateFormat');
  725. } elseif ($col->getType() === PropelTypes::TIME) {
  726. $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
  727. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  728. $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
  729. }
  730. if (empty($defaultfmt)) { $defaultfmt = null; }
  731. $script .= "
  732. ".$visibility." function get$cfc(\$format = ".var_export($defaultfmt, true)."";
  733. if ($col->isLazyLoad()) $script .= ", \$con = null";
  734. $script .= ")
  735. {";
  736. }
  737. protected function getAccessorLazyLoadSnippet(Column $col)
  738. {
  739. if ($col->isLazyLoad()) {
  740. $clo = strtolower($col->getName());
  741. $defaultValueString = 'null';
  742. $def = $col->getDefaultValue();
  743. if ($def !== null && !$def->isExpression()) {
  744. $defaultValueString = $this->getDefaultValueString($col);
  745. }
  746. return "
  747. if (!\$this->{$clo}_isLoaded && \$this->{$clo} === {$defaultValueString} && !\$this->isNew()) {
  748. \$this->load{$col->getPhpName()}(\$con);
  749. }
  750. ";
  751. }
  752. }
  753. /**
  754. * Adds the body of the temporal accessor
  755. * @param string &$script The script will be modified in this method.
  756. * @param Column $col The current column.
  757. * @see addTemporalAccessor
  758. **/
  759. protected function addTemporalAccessorBody(&$script, Column $col)
  760. {
  761. $cfc = $col->getPhpName();
  762. $clo = strtolower($col->getName());
  763. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  764. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  765. if (!$dateTimeClass) {
  766. $dateTimeClass = 'DateTime';
  767. }
  768. $this->declareClasses($dateTimeClass);
  769. $defaultfmt = null;
  770. // Default date/time formatter strings are specified in build.properties
  771. if ($col->getType() === PropelTypes::DATE) {
  772. $defaultfmt = $this->getBuildProperty('defaultDateFormat');
  773. } elseif ($col->getType() === PropelTypes::TIME) {
  774. $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
  775. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  776. $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
  777. }
  778. if (empty($defaultfmt)) { $defaultfmt = null; }
  779. $handleMysqlDate = false;
  780. if ($this->getPlatform() instanceof MysqlPlatform) {
  781. if ($col->getType() === PropelTypes::TIMESTAMP) {
  782. $handleMysqlDate = true;
  783. $mysqlInvalidDateString = '0000-00-00 00:00:00';
  784. } elseif ($col->getType() === PropelTypes::DATE) {
  785. $handleMysqlDate = true;
  786. $mysqlInvalidDateString = '0000-00-00';
  787. }
  788. // 00:00:00 is a valid time, so no need to check for that.
  789. }
  790. if ($col->isLazyLoad()) {
  791. $script .= $this->getAccessorLazyLoadSnippet($col);
  792. }
  793. $script .= "
  794. if (\$this->$clo === null) {
  795. return null;
  796. }
  797. ";
  798. if ($handleMysqlDate) {
  799. $script .= "
  800. if (\$this->$clo === '$mysqlInvalidDateString') {
  801. // while technically this is not a default value of NULL,
  802. // this seems to be closest in meaning.
  803. return null;
  804. } else {
  805. try {
  806. \$dt = new $dateTimeClass(\$this->$clo);
  807. } catch (Exception \$x) {
  808. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  809. }
  810. }
  811. ";
  812. } else {
  813. $script .= "
  814. try {
  815. \$dt = new $dateTimeClass(\$this->$clo);
  816. } catch (Exception \$x) {
  817. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  818. }
  819. ";
  820. } // if handleMyqlDate
  821. $script .= "
  822. if (\$format === null) {";
  823. if ($useDateTime) {
  824. $script .= "
  825. // Because propel.useDateTimeClass is TRUE, we return a $dateTimeClass object.
  826. return \$dt;";
  827. } else {
  828. $script .= "
  829. // We cast here to maintain BC in API; obviously we will lose data if we're dealing with pre-/post-epoch dates.
  830. return (int) \$dt->format('U');";
  831. }
  832. $script .= "
  833. } elseif (strpos(\$format, '%') !== false) {
  834. return strftime(\$format, \$dt->format('U'));
  835. } else {
  836. return \$dt->format(\$format);
  837. }";
  838. }
  839. /**
  840. * Adds the body of the temporal accessor
  841. * @param string &$script The script will be modified in this method.
  842. * @param Column $col The current column.
  843. * @see addTemporalAccessorClose
  844. **/
  845. protected function addTemporalAccessorClose(&$script, Column $col)
  846. {
  847. $script .= "
  848. }
  849. ";
  850. }
  851. /**
  852. * Adds an object getter method.
  853. * @param string &$script The script will be modified in this method.
  854. * @param Column $col The current column.
  855. * @see parent::addColumnAccessors()
  856. */
  857. protected function addObjectAccessor(&$script, Column $col)
  858. {
  859. $this->addDefaultAccessorComment($script, $col);
  860. $this->addDefaultAccessorOpen($script, $col);
  861. $this->addObjectAccessorBody($script, $col);
  862. $this->addDefaultAccessorClose($script, $col);
  863. }
  864. /**
  865. * Adds the function body for an object accessor method
  866. * @param string &$script The script will be modified in this method.
  867. * @param Column $col The current column.
  868. * @see addDefaultAccessor()
  869. **/
  870. protected function addObjectAccessorBody(&$script, Column $col)
  871. {
  872. $cfc = $col->getPhpName();
  873. $clo = strtolower($col->getName());
  874. $cloUnserialized = $clo.'_unserialized';
  875. if ($col->isLazyLoad()) {
  876. $script .= $this->getAccessorLazyLoadSnippet($col);
  877. }
  878. $script .= "
  879. if (null == \$this->$cloUnserialized && null !== \$this->$clo) {
  880. \$this->$cloUnserialized = unserialize(\$this->$clo);
  881. }
  882. return \$this->$cloUnserialized;";
  883. }
  884. /**
  885. * Adds an array getter method.
  886. * @param string &$script The script will be modified in this method.
  887. * @param Column $col The current column.
  888. * @see parent::addColumnAccessors()
  889. */
  890. protected function addArrayAccessor(&$script, Column $col)
  891. {
  892. $this->addDefaultAccessorComment($script, $col);
  893. $this->addDefaultAccessorOpen($script, $col);
  894. $this->addArrayAccessorBody($script, $col);
  895. $this->addDefaultAccessorClose($script, $col);
  896. }
  897. /**
  898. * Adds the function body for an array accessor method
  899. * @param string &$script The script will be modified in this method.
  900. * @param Column $col The current column.
  901. * @see addDefaultAccessor()
  902. **/
  903. protected function addArrayAccessorBody(&$script, Column $col)
  904. {
  905. $cfc = $col->getPhpName();
  906. $clo = strtolower($col->getName());
  907. $cloUnserialized = $clo.'_unserialized';
  908. if ($col->isLazyLoad()) {
  909. $script .= $this->getAccessorLazyLoadSnippet($col);
  910. }
  911. $script .= "
  912. if (null === \$this->$cloUnserialized) {
  913. \$this->$cloUnserialized = array();
  914. }
  915. if (!\$this->$cloUnserialized && null !== \$this->$clo) {
  916. \$$cloUnserialized = substr(\$this->$clo, 2, -2);
  917. \$this->$cloUnserialized = \$$cloUnserialized ? explode(' | ', \$$cloUnserialized) : array();
  918. }
  919. return \$this->$cloUnserialized;";
  920. }
  921. /**
  922. * Adds an enum getter method.
  923. * @param string &$script The script will be modified in this method.
  924. * @param Column $col The current column.
  925. * @see parent::addColumnAccessors()
  926. */
  927. protected function addEnumAccessor(&$script, Column $col)
  928. {
  929. $clo = strtolower($col->getName());
  930. $script .= "
  931. /**
  932. * Get the [$clo] column value.
  933. * ".$col->getDescription();
  934. if ($col->isLazyLoad()) {
  935. $script .= "
  936. * @param PropelPDO \$con An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  937. }
  938. $script .= "
  939. * @return ".$col->getPhpType()."
  940. * @throws PropelException - if the stored enum key is unknown.
  941. */";
  942. $this->addDefaultAccessorOpen($script, $col);
  943. $this->addEnumAccessorBody($script, $col);
  944. $this->addDefaultAccessorClose($script, $col);
  945. }
  946. /**
  947. * Adds the function body for an enum accessor method
  948. * @param string &$script The script will be modified in this method.
  949. * @param Column $col The current column.
  950. * @see addDefaultAccessor()
  951. **/
  952. protected function addEnumAccessorBody(&$script, Column $col)
  953. {
  954. $cfc = $col->getPhpName();
  955. $clo = strtolower($col->getName());
  956. if ($col->isLazyLoad()) {
  957. $script .= $this->getAccessorLazyLoadSnippet($col);
  958. }
  959. $script .= "
  960. if (null === \$this->$clo) {
  961. return null;
  962. }
  963. \$valueSet = " . $this->getPeerClassname() . "::getValueSet(" . $this->getColumnConstant($col) . ");
  964. if (!isset(\$valueSet[\$this->$clo])) {
  965. throw new PropelException('Unknown stored enum key: ' . \$this->$clo);
  966. }
  967. return \$valueSet[\$this->$clo];";
  968. }
  969. /**
  970. * Adds a tester method for an array column.
  971. * @param string &$script The script will be modified in this method.
  972. * @param Column $col The current column.
  973. */
  974. protected function addHasArrayElement(&$script, Column $col)
  975. {
  976. $clo = strtolower($col->getName());
  977. $cfc = $col->getPhpName();
  978. $visibility = $col->getAccessorVisibility();
  979. $singularPhpName = rtrim($cfc, 's');
  980. $script .= "
  981. /**
  982. * Test the presence of a value in the [$clo] array column value.
  983. * @param mixed \$value
  984. * ".$col->getDescription();
  985. if ($col->isLazyLoad()) {
  986. $script .= "
  987. * @param PropelPDO \$con An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  988. }
  989. $script .= "
  990. * @return boolean
  991. */
  992. $visibility function has$singularPhpName(\$value";
  993. if ($col->isLazyLoad()) $script .= ", PropelPDO \$con = null";
  994. $script .= ")
  995. {
  996. return in_array(\$value, \$this->get$cfc(";
  997. if ($col->isLazyLoad()) $script .= "\$con";
  998. $script .= "));
  999. } // has$singularPhpName()
  1000. ";
  1001. }
  1002. /**
  1003. * Adds a normal (non-temporal) getter method.
  1004. * @param string &$script The script will be modified in this method.
  1005. * @param Column $col The current column.
  1006. * @see parent::addColumnAccessors()
  1007. */
  1008. protected function addDefaultAccessor(&$script, Column $col)
  1009. {
  1010. $this->addDefaultAccessorComment($script, $col);
  1011. $this->addDefaultAccessorOpen($script, $col);
  1012. $this->addDefaultAccessorBody($script, $col);
  1013. $this->addDefaultAccessorClose($script, $col);
  1014. }
  1015. /**
  1016. * Add the comment for a default accessor method (a getter)
  1017. * @param string &$script The script will be modified in this method.
  1018. * @param Column $col The current column.
  1019. * @see addDefaultAccessor()
  1020. **/
  1021. public function addDefaultAccessorComment(&$script, Column $col)
  1022. {
  1023. $clo=strtolower($col->getName());
  1024. $script .= "
  1025. /**
  1026. * Get the [$clo] column value.
  1027. * ".$col->getDescription();
  1028. if ($col->isLazyLoad()) {
  1029. $script .= "
  1030. * @param PropelPDO \$con An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  1031. }
  1032. $script .= "
  1033. * @return ".$col->getPhpType()."
  1034. */";
  1035. }
  1036. /**
  1037. * Adds the function declaration for a default accessor
  1038. * @param string &$script The script will be modified in this method.
  1039. * @param Column $col The current column.
  1040. * @see addDefaultAccessor()
  1041. **/
  1042. public function addDefaultAccessorOpen(&$script, Column $col)
  1043. {
  1044. $cfc = $col->getPhpName();
  1045. $visibility = $col->getAccessorVisibility();
  1046. $script .= "
  1047. ".$visibility." function get$cfc(";
  1048. if ($col->isLazyLoad()) $script .= "PropelPDO \$con = null";
  1049. $script .= ")
  1050. {";
  1051. }
  1052. /**
  1053. * Adds the function body for a default accessor method
  1054. * @param string &$script The script will be modified in this method.
  1055. * @param Column $col The current column.
  1056. * @see addDefaultAccessor()
  1057. **/
  1058. protected function addDefaultAccessorBody(&$script, Column $col)
  1059. {
  1060. $cfc = $col->getPhpName();
  1061. $clo = strtolower($col->getName());
  1062. if ($col->isLazyLoad()) {
  1063. $script .= $this->getAccessorLazyLoadSnippet($col);
  1064. }
  1065. $script .= "
  1066. return \$this->$clo;";
  1067. }
  1068. /**
  1069. * Adds the function close for a default accessor method
  1070. * @param string &$script The script will be modified in this method.
  1071. * @param Column $col The current column.
  1072. * @see addDefaultAccessor()
  1073. **/
  1074. protected function addDefaultAccessorClose(&$script, Column $col)
  1075. {
  1076. $script .= "
  1077. }
  1078. ";
  1079. }
  1080. /**
  1081. * Adds the lazy loader method.
  1082. * @param string &$script The script will be modified in this method.
  1083. * @param Column $col The current column.
  1084. * @see parent::addColumnAccessors()
  1085. */
  1086. protected function addLazyLoader(&$script, Column $col)
  1087. {
  1088. $this->addLazyLoaderComment($script, $col);
  1089. $this->addLazyLoaderOpen($script, $col);
  1090. $this->addLazyLoaderBody($script, $col);
  1091. $this->addLazyLoaderClose($script, $col);
  1092. }
  1093. /**
  1094. * Adds the comment for the lazy loader method
  1095. * @param string &$script The script will be modified in this method.
  1096. * @param Column $col The current column.
  1097. * @see addLazyLoader()
  1098. **/
  1099. protected function addLazyLoaderComment(&$script, Column $col)
  1100. {
  1101. $clo = strtolower($col->getName());
  1102. $script .= "
  1103. /**
  1104. * Load the value for the lazy-loaded [$clo] column.
  1105. *
  1106. * This method performs an additional query to return the value for
  1107. * the [$clo] column, since it is not populated by
  1108. * the hydrate() method.
  1109. *
  1110. * @param PropelPDO \$con (optional) The PropelPDO connection to use.
  1111. * @return void
  1112. * @throws PropelException - any underlying error will be wrapped and re-thrown.
  1113. */";
  1114. }
  1115. /**
  1116. * Adds the function declaration for the lazy loader method
  1117. * @param string &$script The script will be modified in this method.
  1118. * @param Column $col The current column.
  1119. * @see addLazyLoader()
  1120. **/
  1121. protected function addLazyLoaderOpen(&$script, Column $col)
  1122. {
  1123. $cfc = $col->getPhpName();
  1124. $script .= "
  1125. protected function load$cfc(PropelPDO \$con = null)
  1126. {";
  1127. }
  1128. /**
  1129. * Adds the function body for the lazy loader method
  1130. * @param string &$script The script will be modified in this method.
  1131. * @param Column $col The current column.
  1132. * @see addLazyLoader()
  1133. **/
  1134. protected function addLazyLoaderBody(&$script, Column $col)
  1135. {
  1136. $platform = $this->getPlatform();
  1137. $clo = strtolower($col->getName());
  1138. // pdo_sqlsrv driver requires the use of PDOStatement::bindColumn() or a hex string will be returned
  1139. if ($col->getType() === PropelTypes::BLOB && $platform instanceof SqlsrvPlatform) {
  1140. $script .= "
  1141. \$c = \$this->buildPkeyCriteria();
  1142. \$c->addSelectColumn(".$this->getColumnConstant($col).");
  1143. try {
  1144. \$row = array(0 => null);
  1145. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
  1146. \$stmt->bindColumn(1, \$row[0], PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
  1147. \$stmt->fetch(PDO::FETCH_BOUND);
  1148. \$stmt->closeCursor();";
  1149. } else {
  1150. $script .= "
  1151. \$c = \$this->buildPkeyCriteria();
  1152. \$c->addSelectColumn(".$this->getColumnConstant($col).");
  1153. try {
  1154. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
  1155. \$row = \$stmt->fetch(PDO::FETCH_NUM);
  1156. \$stmt->closeCursor();";
  1157. }
  1158. if ($col->getType() === PropelTypes::CLOB && $platform instanceof OraclePlatform) {
  1159. // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
  1160. $script .= "
  1161. \$this->$clo = stream_get_contents(\$row[0]);";
  1162. } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
  1163. $script .= "
  1164. if (\$row[0] !== null) {
  1165. \$this->$clo = fopen('php://memory', 'r+');
  1166. fwrite(\$this->$clo, \$row[0]);
  1167. rewind(\$this->$clo);
  1168. } else {
  1169. \$this->$clo = null;
  1170. }";
  1171. } elseif ($col->isPhpPrimitiveType()) {
  1172. $script .= "
  1173. \$this->$clo = (\$row[0] !== null) ? (".$col->getPhpType().") \$row[0] : null;";
  1174. } elseif ($col->isPhpObjectType()) {
  1175. $script .= "
  1176. \$this->$clo = (\$row[0] !== null) ? new ".$col->getPhpType()."(\$row[0]) : null;";
  1177. } else {
  1178. $script .= "
  1179. \$this->$clo = \$row[0];";
  1180. }
  1181. $script .= "
  1182. \$this->".$clo."_isLoaded = true;
  1183. } catch (Exception \$e) {
  1184. throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e);
  1185. }";
  1186. }
  1187. /**
  1188. * Adds the function close for the lazy loader
  1189. * @param string &$script The script will be modified in this method.
  1190. * @param Column $col The current column.
  1191. * @see addLazyLoader()
  1192. **/
  1193. protected function addLazyLoaderClose(&$script, Column $col)
  1194. {
  1195. $script .= "
  1196. }";
  1197. } // addLazyLoader()
  1198. // --------------------------------------------------------------
  1199. //
  1200. // M U T A T O R M E T H O D S
  1201. //
  1202. // --------------------------------------------------------------
  1203. /**
  1204. * Adds the open of the mutator (setter) method for a column.
  1205. * @param string &$script The script will be modified in this method.
  1206. * @param Column $col The current column.
  1207. */
  1208. protected function addMutatorOpen(&$script, Column $col)
  1209. {
  1210. $this->addMutatorComment($script, $col);
  1211. $this->addMutatorOpenOpen($script, $col);
  1212. $this->addMutatorOpenBody($script, $col);
  1213. }
  1214. /**
  1215. * Adds the comment for a mutator
  1216. * @param string &$script The script will be modified in this method.
  1217. * @param Column $col The current column.
  1218. * @see addMutatorOpen()
  1219. **/
  1220. public function addMutatorComment(&$script, Column $col)
  1221. {
  1222. $clo = strtolower($col->getName());
  1223. $script .= "
  1224. /**
  1225. * Set the value of [$clo] column.
  1226. * ".$col->getDescription()."
  1227. * @param ".$col->getPhpType()." \$v new value
  1228. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1229. */";
  1230. }
  1231. /**
  1232. * Adds the mutator function declaration
  1233. * @param string &$script The script will be modified in this method.
  1234. * @param Column $col The current column.
  1235. * @see addMutatorOpen()
  1236. **/
  1237. public function addMutatorOpenOpen(&$script, Column $col)
  1238. {
  1239. $cfc = $col->getPhpName();
  1240. $visibility = $col->getMutatorVisibility();
  1241. $script .= "
  1242. ".$visibility." function set$cfc(\$v)
  1243. {";
  1244. }
  1245. /**
  1246. * Adds the mutator open body part
  1247. * @param string &$script The script will be modified in this method.
  1248. * @param Column $col The current column.
  1249. * @see addMutatorOpen()
  1250. **/
  1251. protected function addMutatorOpenBody(&$script, Column $col)
  1252. {
  1253. $clo = strtolower($col->getName());
  1254. $cfc = $col->getPhpName();
  1255. if ($col->isLazyLoad()) {
  1256. $script .= "
  1257. // explicitly set the is-loaded flag to true for this lazy load col;
  1258. // it doesn't matter if the value is actually set or not (logic below) as
  1259. // any attempt to set the value means that no db lookup should be performed
  1260. // when the get$cfc() method is called.
  1261. \$this->".$clo."_isLoaded = true;
  1262. ";
  1263. }
  1264. }
  1265. /**
  1266. * Adds the close of the mutator (setter) method for a column.
  1267. *
  1268. * @param string &$script The script will be modified in this method.
  1269. * @param Column $col The current column.
  1270. */
  1271. protected function addMutatorClose(&$script, Column $col)
  1272. {
  1273. $this->addMutatorCloseBody($script, $col);
  1274. $this->addMutatorCloseClose($script, $col);
  1275. }
  1276. /**
  1277. * Adds the body of the close part of a mutator
  1278. * @param string &$script The script will be modified in this method.
  1279. * @param Column $col The current column.
  1280. * @see addMutatorClose()
  1281. **/
  1282. protected function addMutatorCloseBody(&$script, Column $col)
  1283. {
  1284. $table = $this->getTable();
  1285. $cfc = $col->getPhpName();
  1286. $clo = strtolower($col->getName());
  1287. if ($col->isForeignKey()) {
  1288. foreach ($col->getForeignKeys() as $fk) {
  1289. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1290. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1291. $varName = $this->getFKVarName($fk);
  1292. $script .= "
  1293. if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) {
  1294. \$this->$varName = null;
  1295. }
  1296. ";
  1297. } // foreach fk
  1298. } /* if col is foreign key */
  1299. foreach ($col->getReferrers() as $refFK) {
  1300. $tblFK = $this->getDatabase()->getTable($refFK->getForeignTableName());
  1301. if ( $tblFK->getName() != $table->getName() ) {
  1302. foreach ($col->getForeignKeys() as $fk) {
  1303. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1304. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1305. if ($refFK->isLocalPrimaryKey()) {
  1306. $varName = $this->getPKRefFKVarName($refFK);
  1307. $script .= "
  1308. // update associated ".$tblFK->getPhpName()."
  1309. if (\$this->$varName !== null) {
  1310. \$this->{$varName}->set".$colFK->getPhpName()."(\$v);
  1311. }
  1312. ";
  1313. } else {
  1314. $collName = $this->getRefFKCollVarName($refFK);
  1315. $script .= "
  1316. // update associated ".$tblFK->getPhpName()."
  1317. if (\$this->$collName !== null) {
  1318. foreach (\$this->$collName as \$referrerObject) {
  1319. \$referrerObject->set".$colFK->getPhpName()."(\$v);
  1320. }
  1321. }
  1322. ";
  1323. } // if (isLocalPrimaryKey
  1324. } // foreach col->getPrimaryKeys()
  1325. } // if tablFk != table
  1326. } // foreach
  1327. }
  1328. /**
  1329. * Adds the close for the mutator close
  1330. * @param string &$script The script will be modified in this method.
  1331. * @param Column $col The current column.
  1332. * @see addMutatorClose()
  1333. **/
  1334. protected function addMutatorCloseClose(&$script, Column $col)
  1335. {
  1336. $cfc = $col->getPhpName();
  1337. $script .= "
  1338. return \$this;
  1339. } // set$cfc()
  1340. ";
  1341. }
  1342. /**
  1343. * Adds a setter for BLOB columns.
  1344. * @param string &$script The script will be modified in this method.
  1345. * @param Column $col The current column.
  1346. * @see parent::addColumnMutators()
  1347. */
  1348. protected function addLobMutator(&$script, Column $col)
  1349. {
  1350. $this->addMutatorOpen($script, $col);
  1351. $clo = strtolower($col->getName());
  1352. $script .= "
  1353. // Because BLOB columns are streams in PDO we have to assume that they are
  1354. // always modified when a new value is passed in. For example, the contents
  1355. // of the stream itself may have changed externally.
  1356. if (!is_resource(\$v) && \$v !== null) {
  1357. \$this->$clo = fopen('php://memory', 'r+');
  1358. fwrite(\$this->$clo, \$v);
  1359. rewind(\$this->$clo);
  1360. } else { // it's already a stream
  1361. \$this->$clo = \$v;
  1362. }
  1363. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1364. ";
  1365. $this->addMutatorClose($script, $col);
  1366. } // addLobMutatorSnippet
  1367. /**
  1368. * Adds a setter method for date/time/timestamp columns.
  1369. * @param string &$script The script will be modified in this method.
  1370. * @param Column $col The current column.
  1371. * @see parent::addColumnMutators()
  1372. */
  1373. protected function addTemporalMutator(&$script, Column $col)
  1374. {
  1375. $cfc = $col->getPhpName();
  1376. $clo = strtolower($col->getName());
  1377. $visibility = $col->getMutatorVisibility();
  1378. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  1379. if (!$dateTimeClass) {
  1380. $dateTimeClass = 'DateTime';
  1381. }
  1382. $this->declareClasses($dateTimeClass, 'DateTimeZone', 'PropelDateTime');
  1383. $this->addTemporalMutatorComment($script, $col);
  1384. $this->addMutatorOpenOpen($script, $col);
  1385. $this->addMutatorOpenBody($script, $col);
  1386. $fmt = var_export($this->getTemporalFormatter($col), true);
  1387. $script .= "
  1388. \$dt = PropelDateTime::newInstance(\$v, null, '$dateTimeClass');
  1389. if (\$this->$clo !== null || \$dt !== null) {
  1390. \$currentDateAsString = (\$this->$clo !== null && \$tmpDt = new $dateTimeClass(\$this->$clo)) ? \$tmpDt->format($fmt) : null;
  1391. \$newDateAsString = \$dt ? \$dt->format($fmt) : null;";
  1392. if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
  1393. $defaultValue = $this->getDefaultValueString($col);
  1394. $script .= "
  1395. if ( (\$currentDateAsString !== \$newDateAsString) // normalized values don't match
  1396. || (\$dt->format($fmt) === $defaultValue) // or the entered value matches the default
  1397. ) {";
  1398. } else {
  1399. $script .= "
  1400. if (\$currentDateAsString !== \$newDateAsString) {";
  1401. }
  1402. $script .= "
  1403. \$this->$clo = \$newDateAsString;
  1404. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1405. }
  1406. } // if either are not null
  1407. ";
  1408. $this->addMutatorClose($script, $col);
  1409. }
  1410. public function addTemporalMutatorComment(&$script, Column $col)
  1411. {
  1412. $cfc = $col->getPhpName();
  1413. $clo = strtolower($col->getName());
  1414. $script .= "
  1415. /**
  1416. * Sets the value of [$clo] column to a normalized version of the date/time value specified.
  1417. * ".$col->getDescription()."
  1418. * @param mixed \$v string, integer (timestamp), or DateTime value.
  1419. * Empty strings are treated as NULL.
  1420. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1421. */";
  1422. }
  1423. /**
  1424. * Adds a setter for Object columns.
  1425. * @param string &$script The script will be modified in this method.
  1426. * @param Column $col The current column.
  1427. * @see parent::addColumnMutators()
  1428. */
  1429. protected function addObjectMutator(&$script, Column $col)
  1430. {
  1431. $clo = strtolower($col->getName());
  1432. $cloUnserialized = $clo.'_unserialized';
  1433. $this->addMutatorOpen($script, $col);
  1434. $script .= "
  1435. if (\$this->$cloUnserialized !== \$v) {
  1436. \$this->$cloUnserialized = \$v;
  1437. \$this->$clo = serialize(\$v);
  1438. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1439. }
  1440. ";
  1441. $this->addMutatorClose($script, $col);
  1442. }
  1443. /**
  1444. * Adds a setter for Array columns.
  1445. * @param string &$script The script will be modified in this method.
  1446. * @param Column $col The current column.
  1447. * @see parent::addColumnMutators()
  1448. */
  1449. protected function addArrayMutator(&$script, Column $col)
  1450. {
  1451. $clo = strtolower($col->getName());
  1452. $cloUnserialized = $clo.'_unserialized';
  1453. $this->addMutatorOpen($script, $col);
  1454. $script .= "
  1455. if (\$this->$cloUnserialized !== \$v) {
  1456. \$this->$cloUnserialized = \$v;
  1457. \$this->$clo = '| ' . implode(' | ', \$v) . ' |';
  1458. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1459. }
  1460. ";
  1461. $this->addMutatorClose($script, $col);
  1462. }
  1463. /**
  1464. * Adds a push method for an array column.
  1465. * @param string &$script The script will be modified in this method.
  1466. * @param Column $col The current column.
  1467. */
  1468. protected function addAddArrayElement(&$script, Column $col)
  1469. {
  1470. $clo = strtolower($col->getName());
  1471. $cfc = $col->getPhpName();
  1472. $visibility = $col->getAccessorVisibility();
  1473. $singularPhpName = rtrim($cfc, 's');
  1474. $script .= "
  1475. /**
  1476. * Adds a value to the [$clo] array column value.
  1477. * @param mixed \$value
  1478. * ".$col->getDescription();
  1479. if ($col->isLazyLoad()) {
  1480. $script .= "
  1481. * @param PropelPDO \$con An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  1482. }
  1483. $script .= "
  1484. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1485. */
  1486. $visibility function add$singularPhpName(\$value";
  1487. if ($col->isLazyLoad()) $script .= ", PropelPDO \$con = null";
  1488. $script .= ")
  1489. {
  1490. \$currentArray = \$this->get$cfc(";
  1491. if ($col->isLazyLoad()) $script .= "\$con";
  1492. $script .= ");
  1493. \$currentArray []= \$value;
  1494. \$this->set$cfc(\$currentArray);
  1495. return \$this;
  1496. } // add$singularPhpName()
  1497. ";
  1498. }
  1499. /**
  1500. * Adds a remove method for an array column.
  1501. * @param string &$script The script will be modified in this method.
  1502. * @param Column $col The current column.
  1503. */
  1504. protected function addRemoveArrayElement(&$script, Column $col)
  1505. {
  1506. $clo = strtolower($col->getName());
  1507. $cfc = $col->getPhpName();
  1508. $visibility = $col->getAccessorVisibility();
  1509. $singularPhpName = rtrim($cfc, 's');
  1510. $script .= "
  1511. /**
  1512. * Removes a value from the [$clo] array column value.
  1513. * @param mixed \$value
  1514. * ".$col->getDescription();
  1515. if ($col->isLazyLoad()) {
  1516. $script .= "
  1517. * @param PropelPDO \$con An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  1518. }
  1519. $script .= "
  1520. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1521. */
  1522. $visibility function remove$singularPhpName(\$value";
  1523. if ($col->isLazyLoad()) $script .= ", PropelPDO \$con = null";
  1524. // we want to reindex the array, so array_ functions are not the best choice
  1525. $script .= ")
  1526. {
  1527. \$targetArray = array();
  1528. foreach (\$this->get$cfc(";
  1529. if ($col->isLazyLoad()) $script .= "\$con";
  1530. $script .= ") as \$element) {
  1531. if (\$element != \$value) {
  1532. \$targetArray []= \$element;
  1533. }
  1534. }
  1535. \$this->set$cfc(\$targetArray);
  1536. return \$this;
  1537. } // remove$singularPhpName()
  1538. ";
  1539. }
  1540. /**
  1541. * Adds a setter for Enum columns.
  1542. * @param string &$script The script will be modified in this method.
  1543. * @param Column $col The current column.
  1544. * @see parent::addColumnMutators()
  1545. */
  1546. protected function addEnumMutator(&$script, Column $col)
  1547. {
  1548. $clo = strtolower($col->getName());
  1549. $script .= "
  1550. /**
  1551. * Set the value of [$clo] column.
  1552. * ".$col->getDescription()."
  1553. * @param ".$col->getPhpType()." \$v new value
  1554. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1555. * @throws PropelException - if the value is not accepted by this enum.
  1556. */";
  1557. $this->addMutatorOpenOpen($script, $col);
  1558. $this->addMutatorOpenBody($script, $col);
  1559. $script .= "
  1560. if (\$v !== null) {
  1561. \$valueSet = " . $this->getPeerClassname() . "::getValueSet(" . $this->getColumnConstant($col) . ");
  1562. if (!in_array(\$v, \$valueSet)) {
  1563. throw new PropelException(sprintf('Value \"%s\" is not accepted in this enumerated column', \$v));
  1564. }
  1565. \$v = array_search(\$v, \$valueSet);
  1566. }
  1567. if (\$this->$clo !== \$v) {
  1568. \$this->$clo = \$v;
  1569. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1570. }
  1571. ";
  1572. $this->addMutatorClose($script, $col);
  1573. }
  1574. /**
  1575. * Adds setter method for boolean columns.
  1576. * @param string &$script The script will be modified in this method.
  1577. * @param Column $col The current column.
  1578. * @see parent::addColumnMutators()
  1579. */
  1580. protected function addBooleanMutator(&$script, Column $col)
  1581. {
  1582. $clo = strtolower($col->getName());
  1583. $this->addBooleanMutatorComment($script, $col);
  1584. $this->addMutatorOpenOpen($script, $col);
  1585. $this->addMutatorOpenBody($script, $col);
  1586. $script .= "
  1587. if (\$v !== null) {
  1588. if (is_string(\$v)) {
  1589. \$v = in_array(strtolower(\$v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
  1590. } else {
  1591. \$v = (boolean) \$v;
  1592. }
  1593. }
  1594. ";
  1595. $script .= "
  1596. if (\$this->$clo !== \$v) {
  1597. \$this->$clo = \$v;
  1598. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1599. }
  1600. ";
  1601. $this->addMutatorClose($script, $col);
  1602. }
  1603. public function addBooleanMutatorComment(&$script, Column $col)
  1604. {
  1605. $cfc = $col->getPhpName();
  1606. $clo = strtolower($col->getName());
  1607. $script .= "
  1608. /**
  1609. * Sets the value of the [$clo] column.
  1610. * Non-boolean arguments are converted using the following rules:
  1611. * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true
  1612. * * 0, '0', 'false', 'off', and 'no' are converted to boolean false
  1613. * Check on string values is case insensitive (so 'FaLsE' is seen as 'false').
  1614. * ".$col->getDescription()."
  1615. * @param boolean|integer|string \$v The new value
  1616. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1617. */";
  1618. }
  1619. /**
  1620. * Adds setter method for "normal" columns.
  1621. * @param string &$script The script will be modified in this method.
  1622. * @param Column $col The current column.
  1623. * @see parent::addColumnMutators()
  1624. */
  1625. protected function addDefaultMutator(&$script, Column $col)
  1626. {
  1627. $clo = strtolower($col->getName());
  1628. $this->addMutatorOpen($script, $col);
  1629. // Perform type-casting to ensure that we can use type-sensitive
  1630. // checking in mutators.
  1631. if ($col->isPhpPrimitiveType()) {
  1632. $script .= "
  1633. if (\$v !== null) {
  1634. \$v = (".$col->getPhpType().") \$v;
  1635. }
  1636. ";
  1637. }
  1638. $script .= "
  1639. if (\$this->$clo !== \$v) {
  1640. \$this->$clo = \$v;
  1641. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1642. }
  1643. ";
  1644. $this->addMutatorClose($script, $col);
  1645. }
  1646. /**
  1647. * Adds the hasOnlyDefaultValues() method.
  1648. * @param string &$script The script will be modified in this method.
  1649. */
  1650. protected function addHasOnlyDefaultValues(&$script)
  1651. {
  1652. $this->addHasOnlyDefaultValuesComment($script);
  1653. $this->addHasOnlyDefaultValuesOpen($script);
  1654. $this->addHasOnlyDefaultValuesBody($script);
  1655. $this->addHasOnlyDefaultValuesClose($script);
  1656. }
  1657. /**
  1658. * Adds the comment for the hasOnlyDefaultValues method
  1659. * @param string &$script The script will be modified in this method.
  1660. * @see addHasOnlyDefaultValues
  1661. **/
  1662. protected function addHasOnlyDefaultValuesComment(&$script)
  1663. {
  1664. $script .= "
  1665. /**
  1666. * Indicates whether the columns in this object are only set to default values.
  1667. *
  1668. * This method can be used in conjunction with isModified() to indicate whether an object is both
  1669. * modified _and_ has some values set which are non-default.
  1670. *
  1671. * @return boolean Whether the columns in this object are only been set with default values.
  1672. */";
  1673. }
  1674. /**
  1675. * Adds the function declaration for the hasOnlyDefaultValues method
  1676. * @param string &$script The script will be modified in this method.
  1677. * @see addHasOnlyDefaultValues
  1678. **/
  1679. protected function addHasOnlyDefaultValuesOpen(&$script)
  1680. {
  1681. $script .= "
  1682. public function hasOnlyDefaultValues()
  1683. {";
  1684. }
  1685. /**
  1686. * Adds the function body for the hasOnlyDefaultValues method
  1687. * @param string &$script The script will be modified in this method.
  1688. * @see addHasOnlyDefaultValues
  1689. **/
  1690. protected function addHasOnlyDefaultValuesBody(&$script)
  1691. {
  1692. $table = $this->getTable();
  1693. $colsWithDefaults = array();
  1694. foreach ($table->getColumns() as $col) {
  1695. $def = $col->getDefaultValue();
  1696. if ($def !== null && !$def->isExpression()) {
  1697. $colsWithDefaults[] = $col;
  1698. }
  1699. }
  1700. foreach ($colsWithDefaults as $col) {
  1701. $clo = strtolower($col->getName());
  1702. $def = $col->getDefaultValue();
  1703. $script .= "
  1704. if (\$this->$clo !== " . $this->getDefaultValueString($col).") {
  1705. return false;
  1706. }
  1707. ";
  1708. }
  1709. }
  1710. /**
  1711. * Adds the function close for the hasOnlyDefaultValues method
  1712. * @param string &$script The script will be modified in this method.
  1713. * @see addHasOnlyDefaultValues
  1714. **/
  1715. protected function addHasOnlyDefaultValuesClose(&$script)
  1716. {
  1717. $script .= "
  1718. // otherwise, everything was equal, so return TRUE
  1719. return true;";
  1720. $script .= "
  1721. } // hasOnlyDefaultValues()
  1722. ";
  1723. }
  1724. /**
  1725. * Adds the hydrate() method, which sets attributes of the object based on a ResultSet.
  1726. * @param string &$script The script will be modified in this method.
  1727. */
  1728. protected function addHydrate(&$script)
  1729. {
  1730. $this->addHydrateComment($script);
  1731. $this->addHydrateOpen($script);
  1732. $this->addHydrateBody($script);
  1733. $this->addHydrateClose($script);
  1734. }
  1735. /**
  1736. * Adds the comment for the hydrate method
  1737. * @param string &$script The script will be modified in this method.
  1738. * @see addHydrate()
  1739. */
  1740. protected function addHydrateComment(&$script)
  1741. {
  1742. $script .= "
  1743. /**
  1744. * Hydrates (populates) the object variables with values from the database resultset.
  1745. *
  1746. * An offset (0-based \"start column\") is specified so that objects can be hydrated
  1747. * with a subset of the columns in the resultset rows. This is needed, for example,
  1748. * for results of JOIN queries where the resultset row includes columns from two or
  1749. * more tables.
  1750. *
  1751. * @param array \$row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
  1752. * @param int \$startcol 0-based offset column which indicates which restultset column to start with.
  1753. * @param boolean \$rehydrate Whether this object is being re-hydrated from the database.
  1754. * @return int next starting column
  1755. * @throws PropelException - Any caught Exception will be rewrapped as a PropelException.
  1756. */";
  1757. }
  1758. /**
  1759. * Adds the function declaration for the hydrate method
  1760. * @param string &$script The script will be modified in this method.
  1761. * @see addHydrate()
  1762. */
  1763. protected function addHydrateOpen(&$script)
  1764. {
  1765. $script .= "
  1766. public function hydrate(\$row, \$startcol = 0, \$rehydrate = false)
  1767. {";
  1768. }
  1769. /**
  1770. * Adds the function body for the hydrate method
  1771. * @param string &$script The script will be modified in this method.
  1772. * @see addHydrate()
  1773. */
  1774. protected function addHydrateBody(&$script)
  1775. {
  1776. $table = $this->getTable();
  1777. $platform = $this->getPlatform();
  1778. $script .= "
  1779. try {
  1780. ";
  1781. $n = 0;
  1782. foreach ($table->getColumns() as $col) {
  1783. if (!$col->isLazyLoad()) {
  1784. $clo = strtolower($col->getName());
  1785. if ($col->getType() === PropelTypes::CLOB_EMU && $this->getPlatform() instanceof OraclePlatform) {
  1786. // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
  1787. $script .= "
  1788. \$this->$clo = stream_get_contents(\$row[\$startcol + $n]);";
  1789. } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
  1790. $script .= "
  1791. if (\$row[\$startcol + $n] !== null) {
  1792. \$this->$clo = fopen('php://memory', 'r+');
  1793. fwrite(\$this->$clo, \$row[\$startcol + $n]);
  1794. rewind(\$this->$clo);
  1795. } else {
  1796. \$this->$clo = null;
  1797. }";
  1798. } elseif ($col->isPhpPrimitiveType()) {
  1799. $script .= "
  1800. \$this->$clo = (\$row[\$startcol + $n] !== null) ? (".$col->getPhpType().") \$row[\$startcol + $n] : null;";
  1801. } elseif ($col->getType() === PropelTypes::OBJECT) {
  1802. $script .= "
  1803. \$this->$clo = \$row[\$startcol + $n];";
  1804. } elseif ($col->getType() === PropelTypes::PHP_ARRAY) {
  1805. $cloUnserialized = $clo . '_unserialized';
  1806. $script .= "
  1807. \$this->$clo = \$row[\$startcol + $n];
  1808. \$this->$cloUnserialized = null;";
  1809. } elseif ($col->isPhpObjectType()) {
  1810. $script .= "
  1811. \$this->$clo = (\$row[\$startcol + $n] !== null) ? new ".$col->getPhpType()."(\$row[\$startcol + $n]) : null;";
  1812. } else {
  1813. $script .= "
  1814. \$this->$clo = \$row[\$startcol + $n];";
  1815. }
  1816. $n++;
  1817. } // if col->isLazyLoad()
  1818. } /* foreach */
  1819. if ($this->getBuildProperty("addSaveMethod")) {
  1820. $script .= "
  1821. \$this->resetModified();
  1822. ";
  1823. }
  1824. $script .= "
  1825. \$this->setNew(false);
  1826. if (\$rehydrate) {
  1827. \$this->ensureConsistency();
  1828. }
  1829. return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_HYDRATE_COLUMNS.
  1830. } catch (Exception \$e) {
  1831. throw new PropelException(\"Error populating ".$this->getStubObjectBuilder()->getClassname()." object\", \$e);
  1832. }";
  1833. }
  1834. /**
  1835. * Adds the function close for the hydrate method
  1836. * @param string &$script The script will be modified in this method.
  1837. * @see addHydrate()
  1838. */
  1839. protected function addHydrateClose(&$script)
  1840. {
  1841. $script .= "
  1842. }
  1843. ";
  1844. }
  1845. /**
  1846. * Adds the buildPkeyCriteria method
  1847. * @param string &$script The script will be modified in this method.
  1848. **/
  1849. protected function addBuildPkeyCriteria(&$script)
  1850. {
  1851. $this->addBuildPkeyCriteriaComment($script);
  1852. $this->addBuildPkeyCriteriaOpen($script);
  1853. $this->addBuildPkeyCriteriaBody($script);
  1854. $this->addBuildPkeyCriteriaClose($script);
  1855. }
  1856. /**
  1857. * Adds the comment for the buildPkeyCriteria method
  1858. * @param string &$script The script will be modified in this method.
  1859. * @see addBuildPkeyCriteria()
  1860. **/
  1861. protected function addBuildPkeyCriteriaComment(&$script)
  1862. {
  1863. $script .= "
  1864. /**
  1865. * Builds a Criteria object containing the primary key for this object.
  1866. *
  1867. * Unlike buildCriteria() this method includes the primary key values regardless
  1868. * of whether or not they have been modified.
  1869. *
  1870. * @return Criteria The Criteria object containing value(s) for primary key(s).
  1871. */";
  1872. }
  1873. /**
  1874. * Adds the function declaration for the buildPkeyCriteria method
  1875. * @param string &$script The script will be modified in this method.
  1876. * @see addBuildPkeyCriteria()
  1877. **/
  1878. protected function addBuildPkeyCriteriaOpen(&$script)
  1879. {
  1880. $script .= "
  1881. public function buildPkeyCriteria()
  1882. {";
  1883. }
  1884. /**
  1885. * Adds the function body for the buildPkeyCriteria method
  1886. * @param string &$script The script will be modified in this method.
  1887. * @see addBuildPkeyCriteria()
  1888. **/
  1889. protected function addBuildPkeyCriteriaBody(&$script)
  1890. {
  1891. $script .= "
  1892. \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
  1893. foreach ($this->getTable()->getPrimaryKey() as $col) {
  1894. $clo = strtolower($col->getName());
  1895. $script .= "
  1896. \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
  1897. }
  1898. }
  1899. /**
  1900. * Adds the function close for the buildPkeyCriteria method
  1901. * @param string &$script The script will be modified in this method.
  1902. * @see addBuildPkeyCriteria()
  1903. **/
  1904. protected function addBuildPkeyCriteriaClose(&$script)
  1905. {
  1906. $script .= "
  1907. return \$criteria;
  1908. }
  1909. ";
  1910. }
  1911. /**
  1912. * Adds the buildCriteria method
  1913. * @param string &$script The script will be modified in this method.
  1914. **/
  1915. protected function addBuildCriteria(&$script)
  1916. {
  1917. $this->addBuildCriteriaComment($script);
  1918. $this->addBuildCriteriaOpen($script);
  1919. $this->addBuildCriteriaBody($script);
  1920. $this->addBuildCriteriaClose($script);
  1921. }
  1922. /**
  1923. * Adds comment for the buildCriteria method
  1924. * @param string &$script The script will be modified in this method.
  1925. * @see addBuildCriteria()
  1926. **/
  1927. protected function addBuildCriteriaComment(&$script)
  1928. {
  1929. $script .= "
  1930. /**
  1931. * Build a Criteria object containing the values of all modified columns in this object.
  1932. *
  1933. * @return Criteria The Criteria object containing all modified values.
  1934. */";
  1935. }
  1936. /**
  1937. * Adds the function declaration of the buildCriteria method
  1938. * @param string &$script The script will be modified in this method.
  1939. * @see addBuildCriteria()
  1940. **/
  1941. protected function addBuildCriteriaOpen(&$script)
  1942. {
  1943. $script .= "
  1944. public function buildCriteria()
  1945. {";
  1946. }
  1947. /**
  1948. * Adds the function body of the buildCriteria method
  1949. * @param string &$script The script will be modified in this method.
  1950. * @see addBuildCriteria()
  1951. **/
  1952. protected function addBuildCriteriaBody(&$script)
  1953. {
  1954. $script .= "
  1955. \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
  1956. ";
  1957. foreach ($this->getTable()->getColumns() as $col) {
  1958. $clo = strtolower($col->getName());
  1959. $script .= "
  1960. if (\$this->isColumnModified(".$this->getColumnConstant($col).")) \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
  1961. }
  1962. }
  1963. /**
  1964. * Adds the function close of the buildCriteria method
  1965. * @param string &$script The script will be modified in this method.
  1966. * @see addBuildCriteria()
  1967. **/
  1968. protected function addBuildCriteriaClose(&$script)
  1969. {
  1970. $script .= "
  1971. return \$criteria;
  1972. }
  1973. ";
  1974. }
  1975. /**
  1976. * Adds the toArray method
  1977. * @param string &$script The script will be modified in this method.
  1978. **/
  1979. protected function addToArray(&$script)
  1980. {
  1981. $fks = $this->getTable()->getForeignKeys();
  1982. $referrers = $this->getTable()->getReferrers();
  1983. $hasFks = count($fks) > 0 || count($referrers) > 0;
  1984. $objectClassName = $this->getObjectClassname();
  1985. $pkGetter = $this->getTable()->hasCompositePrimaryKey() ? 'serialize($this->getPrimaryKey())' : '$this->getPrimaryKey()';
  1986. $defaultKeyType = $this->getDefaultKeyType();
  1987. $script .= "
  1988. /**
  1989. * Exports the object as an array.
  1990. *
  1991. * You can specify the key type of the array by passing one of the class
  1992. * type constants.
  1993. *
  1994. * @param string \$keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
  1995. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  1996. * Defaults to BasePeer::$defaultKeyType.
  1997. * @param boolean \$includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE.
  1998. * @param array \$alreadyDumpedObjects List of objects to skip to avoid recursion";
  1999. if ($hasFks) {
  2000. $script .= "
  2001. * @param boolean \$includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE.";
  2002. }
  2003. $script .= "
  2004. *
  2005. * @return array an associative array containing the field names (as keys) and field values
  2006. */
  2007. public function toArray(\$keyType = BasePeer::$defaultKeyType, \$includeLazyLoadColumns = true, \$alreadyDumpedObjects = array()" . ($hasFks ? ", \$includeForeignObjects = false" : '') . ")
  2008. {
  2009. if (isset(\$alreadyDumpedObjects['$objectClassName'][$pkGetter])) {
  2010. return '*RECURSION*';
  2011. }
  2012. \$alreadyDumpedObjects['$objectClassName'][$pkGetter] = true;
  2013. \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
  2014. \$result = array(";
  2015. foreach ($this->getTable()->getColumns() as $num => $col) {
  2016. if ($col->isLazyLoad()) {
  2017. $script .= "
  2018. \$keys[$num] => (\$includeLazyLoadColumns) ? \$this->get".$col->getPhpName()."() : null,";
  2019. } else {
  2020. $script .= "
  2021. \$keys[$num] => \$this->get".$col->getPhpName()."(),";
  2022. }
  2023. }
  2024. $script .= "
  2025. );";
  2026. if ($hasFks) {
  2027. $script .= "
  2028. if (\$includeForeignObjects) {";
  2029. foreach ($fks as $fk) {
  2030. $script .= "
  2031. if (null !== \$this->" . $this->getFKVarName($fk) . ") {
  2032. \$result['" . $this->getFKPhpNameAffix($fk, $plural = false) . "'] = \$this->" . $this->getFKVarName($fk) . "->toArray(\$keyType, \$includeLazyLoadColumns, \$alreadyDumpedObjects, true);
  2033. }";
  2034. }
  2035. foreach ($referrers as $fk) {
  2036. if ($fk->isLocalPrimaryKey()) {
  2037. $script .= "
  2038. if (null !== \$this->" . $this->getPKRefFKVarName($fk) . ") {
  2039. \$result['" . $this->getRefFKPhpNameAffix($fk, $plural = false) . "'] = \$this->" . $this->getPKRefFKVarName($fk) . "->toArray(\$keyType, \$includeLazyLoadColumns, \$alreadyDumpedObjects, true);
  2040. }";
  2041. } else {
  2042. $script .= "
  2043. if (null !== \$this->" . $this->getRefFKCollVarName($fk) . ") {
  2044. \$result['" . $this->getRefFKPhpNameAffix($fk, $plural = true) . "'] = \$this->" . $this->getRefFKCollVarName($fk) . "->toArray(null, true, \$keyType, \$includeLazyLoadColumns, \$alreadyDumpedObjects);
  2045. }";
  2046. }
  2047. }
  2048. $script .= "
  2049. }";
  2050. }
  2051. $script .= "
  2052. return \$result;
  2053. }
  2054. ";
  2055. } // addToArray()
  2056. /**
  2057. * Adds the getByName method
  2058. * @param string &$script The script will be modified in this method.
  2059. **/
  2060. protected function addGetByName(&$script)
  2061. {
  2062. $this->addGetByNameComment($script);
  2063. $this->addGetByNameOpen($script);
  2064. $this->addGetByNameBody($script);
  2065. $this->addGetByNameClose($script);
  2066. }
  2067. /**
  2068. * Adds the comment for the getByName method
  2069. * @param string &$script The script will be modified in this method.
  2070. * @see addGetByName
  2071. **/
  2072. protected function addGetByNameComment(&$script)
  2073. {
  2074. $defaultKeyType = $this->getDefaultKeyType();
  2075. $script .= "
  2076. /**
  2077. * Retrieves a field from the object by name passed in as a string.
  2078. *
  2079. * @param string \$name name
  2080. * @param string \$type The type of fieldname the \$name is of:
  2081. * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
  2082. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  2083. * Defaults to BasePeer::$defaultKeyType
  2084. * @return mixed Value of field.
  2085. */";
  2086. }
  2087. /**
  2088. * Adds the function declaration for the getByName method
  2089. * @param string &$script The script will be modified in this method.
  2090. * @see addGetByName
  2091. **/
  2092. protected function addGetByNameOpen(&$script)
  2093. {
  2094. $defaultKeyType = $this->getDefaultKeyType();
  2095. $script .= "
  2096. public function getByName(\$name, \$type = BasePeer::$defaultKeyType)
  2097. {";
  2098. }
  2099. /**
  2100. * Adds the function body for the getByName method
  2101. * @param string &$script The script will be modified in this method.
  2102. * @see addGetByName
  2103. **/
  2104. protected function addGetByNameBody(&$script)
  2105. {
  2106. $script .= "
  2107. \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
  2108. \$field = \$this->getByPosition(\$pos);";
  2109. }
  2110. /**
  2111. * Adds the function close for the getByName method
  2112. * @param string &$script The script will be modified in this method.
  2113. * @see addGetByName
  2114. **/
  2115. protected function addGetByNameClose(&$script)
  2116. {
  2117. $script .= "
  2118. return \$field;
  2119. }
  2120. ";
  2121. }
  2122. /**
  2123. * Adds the getByPosition method
  2124. * @param string &$script The script will be modified in this method.
  2125. **/
  2126. protected function addGetByPosition(&$script)
  2127. {
  2128. $this->addGetByPositionComment($script);
  2129. $this->addGetByPositionOpen($script);
  2130. $this->addGetByPositionBody($script);
  2131. $this->addGetByPositionClose($script);
  2132. }
  2133. /**
  2134. * Adds comment for the getByPosition method
  2135. * @param string &$script The script will be modified in this method.
  2136. * @see addGetByPosition
  2137. **/
  2138. protected function addGetByPositionComment(&$script)
  2139. {
  2140. $script .= "
  2141. /**
  2142. * Retrieves a field from the object by Position as specified in the xml schema.
  2143. * Zero-based.
  2144. *
  2145. * @param int \$pos position in xml schema
  2146. * @return mixed Value of field at \$pos
  2147. */";
  2148. }
  2149. /**
  2150. * Adds the function declaration for the getByPosition method
  2151. * @param string &$script The script will be modified in this method.
  2152. * @see addGetByPosition
  2153. **/
  2154. protected function addGetByPositionOpen(&$script)
  2155. {
  2156. $script .= "
  2157. public function getByPosition(\$pos)
  2158. {";
  2159. }
  2160. /**
  2161. * Adds the function body for the getByPosition method
  2162. * @param string &$script The script will be modified in this method.
  2163. * @see addGetByPosition
  2164. **/
  2165. protected function addGetByPositionBody(&$script)
  2166. {
  2167. $table = $this->getTable();
  2168. $script .= "
  2169. switch (\$pos) {";
  2170. $i = 0;
  2171. foreach ($table->getColumns() as $col) {
  2172. $cfc = $col->getPhpName();
  2173. $script .= "
  2174. case $i:
  2175. return \$this->get$cfc();
  2176. break;";
  2177. $i++;
  2178. } /* foreach */
  2179. $script .= "
  2180. default:
  2181. return null;
  2182. break;
  2183. } // switch()";
  2184. }
  2185. /**
  2186. * Adds the function close for the getByPosition method
  2187. * @param string &$script The script will be modified in this method.
  2188. * @see addGetByPosition
  2189. **/
  2190. protected function addGetByPositionClose(&$script)
  2191. {
  2192. $script .= "
  2193. }
  2194. ";
  2195. }
  2196. protected function addSetByName(&$script)
  2197. {
  2198. $table = $this->getTable();
  2199. $defaultKeyType = $this->getDefaultKeyType();
  2200. $script .= "
  2201. /**
  2202. * Sets a field from the object by name passed in as a string.
  2203. *
  2204. * @param string \$name peer name
  2205. * @param mixed \$value field value
  2206. * @param string \$type The type of fieldname the \$name is of:
  2207. * one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
  2208. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  2209. * Defaults to BasePeer::$defaultKeyType
  2210. * @return void
  2211. */
  2212. public function setByName(\$name, \$value, \$type = BasePeer::$defaultKeyType)
  2213. {
  2214. \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
  2215. \$this->setByPosition(\$pos, \$value);
  2216. }
  2217. ";
  2218. }
  2219. protected function addSetByPosition(&$script)
  2220. {
  2221. $table = $this->getTable();
  2222. $script .= "
  2223. /**
  2224. * Sets a field from the object by Position as specified in the xml schema.
  2225. * Zero-based.
  2226. *
  2227. * @param int \$pos position in xml schema
  2228. * @param mixed \$value field value
  2229. * @return void
  2230. */
  2231. public function setByPosition(\$pos, \$value)
  2232. {
  2233. switch (\$pos) {";
  2234. $i = 0;
  2235. foreach ($table->getColumns() as $col) {
  2236. $cfc = $col->getPhpName();
  2237. $cptype = $col->getPhpType();
  2238. $script .= "
  2239. case $i:";
  2240. if (PropelTypes::ENUM === $col->getType()) {
  2241. $script .= "
  2242. \$valueSet = " . $this->getPeerClassname() . "::getValueSet(" . $this->getColumnConstant($col) . ");
  2243. if (isset(\$valueSet[\$value])) {
  2244. \$value = \$valueSet[\$value];
  2245. }";
  2246. } elseif (PropelTypes::PHP_ARRAY === $col->getType()) {
  2247. $script .= "
  2248. if (!is_array(\$value)) {
  2249. \$v = trim(substr(\$value, 2, -2));
  2250. \$value = \$v ? explode(' | ', \$v) : array();
  2251. }";
  2252. }
  2253. $script .= "
  2254. \$this->set$cfc(\$value);
  2255. break;";
  2256. $i++;
  2257. } /* foreach */
  2258. $script .= "
  2259. } // switch()
  2260. }
  2261. ";
  2262. } // addSetByPosition()
  2263. protected function addFromArray(&$script)
  2264. {
  2265. $defaultKeyType = $this->getDefaultKeyType();
  2266. $table = $this->getTable();
  2267. $script .= "
  2268. /**
  2269. * Populates the object using an array.
  2270. *
  2271. * This is particularly useful when populating an object from one of the
  2272. * request arrays (e.g. \$_POST). This method goes through the column
  2273. * names, checking to see whether a matching key exists in populated
  2274. * array. If so the setByName() method is called for that column.
  2275. *
  2276. * You can specify the key type of the array by additionally passing one
  2277. * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
  2278. * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
  2279. * The default key type is the column's BasePeer::$defaultKeyType
  2280. *
  2281. * @param array \$arr An array to populate the object from.
  2282. * @param string \$keyType The type of keys the array uses.
  2283. * @return void
  2284. */
  2285. public function fromArray(\$arr, \$keyType = BasePeer::$defaultKeyType)
  2286. {
  2287. \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
  2288. ";
  2289. foreach ($table->getColumns() as $num => $col) {
  2290. $cfc = $col->getPhpName();
  2291. //TODO: remove. not used
  2292. $cptype = $col->getPhpType();
  2293. $script .= "
  2294. if (array_key_exists(\$keys[$num], \$arr)) \$this->set$cfc(\$arr[\$keys[$num]]);";
  2295. } /* foreach */
  2296. $script .= "
  2297. }
  2298. ";
  2299. } // addFromArray
  2300. /**
  2301. * Adds a delete() method to remove the object form the datastore.
  2302. * @param string &$script The script will be modified in this method.
  2303. */
  2304. protected function addDelete(&$script)
  2305. {
  2306. $this->addDeleteComment($script);
  2307. $this->addDeleteOpen($script);
  2308. $this->addDeleteBody($script);
  2309. $this->addDeleteClose($script);
  2310. }
  2311. /**
  2312. * Adds the comment for the delete function
  2313. * @param string &$script The script will be modified in this method.
  2314. * @see addDelete()
  2315. **/
  2316. protected function addDeleteComment(&$script)
  2317. {
  2318. $script .= "
  2319. /**
  2320. * Removes this object from datastore and sets delete attribute.
  2321. *
  2322. * @param PropelPDO \$con
  2323. * @return void
  2324. * @throws PropelException
  2325. * @throws Exception
  2326. * @see BaseObject::setDeleted()
  2327. * @see BaseObject::isDeleted()
  2328. */";
  2329. }
  2330. /**
  2331. * Adds the function declaration for the delete function
  2332. * @param string &$script The script will be modified in this method.
  2333. * @see addDelete()
  2334. **/
  2335. protected function addDeleteOpen(&$script)
  2336. {
  2337. $script .= "
  2338. public function delete(PropelPDO \$con = null)
  2339. {";
  2340. }
  2341. /**
  2342. * Adds the function body for the delete function
  2343. * @param string &$script The script will be modified in this method.
  2344. * @see addDelete()
  2345. **/
  2346. protected function addDeleteBody(&$script)
  2347. {
  2348. $script .= "
  2349. if (\$this->isDeleted()) {
  2350. throw new PropelException(\"This object has already been deleted.\");
  2351. }
  2352. if (\$con === null) {
  2353. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
  2354. }
  2355. \$con->beginTransaction();
  2356. try {
  2357. \$deleteQuery = ".$this->getQueryClassname()."::create()
  2358. ->filterByPrimaryKey(\$this->getPrimaryKey());";
  2359. if ($this->getGeneratorConfig()->getBuildProperty('addHooks')) {
  2360. $script .= "
  2361. \$ret = \$this->preDelete(\$con);";
  2362. // apply behaviors
  2363. $this->applyBehaviorModifier('preDelete', $script, " ");
  2364. $script .= "
  2365. if (\$ret) {
  2366. \$deleteQuery->delete(\$con);
  2367. \$this->postDelete(\$con);";
  2368. // apply behaviors
  2369. $this->applyBehaviorModifier('postDelete', $script, " ");
  2370. $script .= "
  2371. \$con->commit();
  2372. \$this->setDeleted(true);
  2373. } else {
  2374. \$con->commit();
  2375. }";
  2376. } else {
  2377. // apply behaviors
  2378. $this->applyBehaviorModifier('preDelete', $script, " ");
  2379. $script .= "
  2380. \$deleteQuery->delete(\$con);";
  2381. // apply behaviors
  2382. $this->applyBehaviorModifier('postDelete', $script, " ");
  2383. $script .= "
  2384. \$con->commit();
  2385. \$this->setDeleted(true);";
  2386. }
  2387. $script .= "
  2388. } catch (Exception \$e) {
  2389. \$con->rollBack();
  2390. throw \$e;
  2391. }";
  2392. }
  2393. /**
  2394. * Adds the function close for the delete function
  2395. * @param string &$script The script will be modified in this method.
  2396. * @see addDelete()
  2397. **/
  2398. protected function addDeleteClose(&$script)
  2399. {
  2400. $script .= "
  2401. }
  2402. ";
  2403. } // addDelete()
  2404. /**
  2405. * Adds a reload() method to re-fetch the data for this object from the database.
  2406. * @param string &$script The script will be modified in this method.
  2407. */
  2408. protected function addReload(&$script)
  2409. {
  2410. $table = $this->getTable();
  2411. $script .= "
  2412. /**
  2413. * Reloads this object from datastore based on primary key and (optionally) resets all associated objects.
  2414. *
  2415. * This will only work if the object has been saved and has a valid primary key set.
  2416. *
  2417. * @param boolean \$deep (optional) Whether to also de-associated any related objects.
  2418. * @param PropelPDO \$con (optional) The PropelPDO connection to use.
  2419. * @return void
  2420. * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db
  2421. */
  2422. public function reload(\$deep = false, PropelPDO \$con = null)
  2423. {
  2424. if (\$this->isDeleted()) {
  2425. throw new PropelException(\"Cannot reload a deleted object.\");
  2426. }
  2427. if (\$this->isNew()) {
  2428. throw new PropelException(\"Cannot reload an unsaved object.\");
  2429. }
  2430. if (\$con === null) {
  2431. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
  2432. }
  2433. // We don't need to alter the object instance pool; we're just modifying this instance
  2434. // already in the pool.
  2435. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$this->buildPkeyCriteria(), \$con);
  2436. \$row = \$stmt->fetch(PDO::FETCH_NUM);
  2437. \$stmt->closeCursor();
  2438. if (!\$row) {
  2439. throw new PropelException('Cannot find matching row in the database to reload object values.');
  2440. }
  2441. \$this->hydrate(\$row, 0, true); // rehydrate
  2442. ";
  2443. // support for lazy load columns
  2444. foreach ($table->getColumns() as $col) {
  2445. if ($col->isLazyLoad()) {
  2446. $clo = strtolower($col->getName());
  2447. $script .= "
  2448. // Reset the $clo lazy-load column
  2449. \$this->" . $clo . " = null;
  2450. \$this->".$clo."_isLoaded = false;
  2451. ";
  2452. }
  2453. }
  2454. $script .= "
  2455. if (\$deep) { // also de-associate any related objects?
  2456. ";
  2457. foreach ($table->getForeignKeys() as $fk) {
  2458. $varName = $this->getFKVarName($fk);
  2459. $script .= "
  2460. \$this->".$varName." = null;";
  2461. }
  2462. foreach ($table->getReferrers() as $refFK) {
  2463. if ($refFK->isLocalPrimaryKey()) {
  2464. $script .= "
  2465. \$this->".$this->getPKRefFKVarName($refFK)." = null;
  2466. ";
  2467. } else {
  2468. $script .= "
  2469. \$this->".$this->getRefFKCollVarName($refFK)." = null;
  2470. ";
  2471. }
  2472. }
  2473. foreach ($table->getCrossFks() as $fkList) {
  2474. list($refFK, $crossFK) = $fkList;
  2475. $script .= "
  2476. \$this->" . $this->getCrossFKVarName($crossFK). " = null;";
  2477. }
  2478. $script .= "
  2479. } // if (deep)
  2480. }
  2481. ";
  2482. } // addReload()
  2483. /**
  2484. * Adds the methods related to refreshing, saving and deleting the object.
  2485. * @param string &$script The script will be modified in this method.
  2486. */
  2487. protected function addManipulationMethods(&$script)
  2488. {
  2489. $this->addReload($script);
  2490. $this->addDelete($script);
  2491. $this->addSave($script);
  2492. $this->addDoSave($script);
  2493. $script .= $this->addDoInsert();
  2494. $script .= $this->addDoUpdate();
  2495. }
  2496. /**
  2497. * Adds the methods related to validationg the object.
  2498. * @param string &$script The script will be modified in this method.
  2499. */
  2500. protected function addValidationMethods(&$script)
  2501. {
  2502. $this->addValidationFailuresAttribute($script);
  2503. $this->addGetValidationFailures($script);
  2504. $this->addValidate($script);
  2505. $this->addDoValidate($script);
  2506. }
  2507. /**
  2508. * Adds the $validationFailures attribute to store ValidationFailed objects.
  2509. * @param string &$script The script will be modified in this method.
  2510. */
  2511. protected function addValidationFailuresAttribute(&$script)
  2512. {
  2513. $script .= "
  2514. /**
  2515. * Array of ValidationFailed objects.
  2516. * @var array ValidationFailed[]
  2517. */
  2518. protected \$validationFailures = array();
  2519. ";
  2520. }
  2521. /**
  2522. * Adds the getValidationFailures() method.
  2523. * @param string &$script The script will be modified in this method.
  2524. */
  2525. protected function addGetValidationFailures(&$script)
  2526. {
  2527. $script .= "
  2528. /**
  2529. * Gets any ValidationFailed objects that resulted from last call to validate().
  2530. *
  2531. *
  2532. * @return array ValidationFailed[]
  2533. * @see validate()
  2534. */
  2535. public function getValidationFailures()
  2536. {
  2537. return \$this->validationFailures;
  2538. }
  2539. ";
  2540. } // addGetValidationFailures()
  2541. /**
  2542. * Adds the correct getPrimaryKey() method for this object.
  2543. * @param string &$script The script will be modified in this method.
  2544. */
  2545. protected function addGetPrimaryKey(&$script)
  2546. {
  2547. $pkeys = $this->getTable()->getPrimaryKey();
  2548. if (count($pkeys) == 1) {
  2549. $this->addGetPrimaryKey_SinglePK($script);
  2550. } elseif (count($pkeys) > 1) {
  2551. $this->addGetPrimaryKey_MultiPK($script);
  2552. } else {
  2553. // no primary key -- this is deprecated, since we don't *need* this method anymore
  2554. $this->addGetPrimaryKey_NoPK($script);
  2555. }
  2556. }
  2557. /**
  2558. * Adds the getPrimaryKey() method for tables that contain a single-column primary key.
  2559. * @param string &$script The script will be modified in this method.
  2560. */
  2561. protected function addGetPrimaryKey_SinglePK(&$script)
  2562. {
  2563. $table = $this->getTable();
  2564. $pkeys = $table->getPrimaryKey();
  2565. $cptype = $pkeys[0]->getPhpType();
  2566. $script .= "
  2567. /**
  2568. * Returns the primary key for this object (row).
  2569. * @return $cptype
  2570. */
  2571. public function getPrimaryKey()
  2572. {
  2573. return \$this->get".$pkeys[0]->getPhpName()."();
  2574. }
  2575. ";
  2576. } // addetPrimaryKey_SingleFK
  2577. /**
  2578. * Adds the setPrimaryKey() method for tables that contain a multi-column primary key.
  2579. * @param string &$script The script will be modified in this method.
  2580. */
  2581. protected function addGetPrimaryKey_MultiPK(&$script)
  2582. {
  2583. $script .= "
  2584. /**
  2585. * Returns the composite primary key for this object.
  2586. * The array elements will be in same order as specified in XML.
  2587. * @return array
  2588. */
  2589. public function getPrimaryKey()
  2590. {
  2591. \$pks = array();";
  2592. $i = 0;
  2593. foreach ($this->getTable()->getPrimaryKey() as $pk) {
  2594. $script .= "
  2595. \$pks[$i] = \$this->get".$pk->getPhpName()."();";
  2596. $i++;
  2597. } /* foreach */
  2598. $script .= "
  2599. return \$pks;
  2600. }
  2601. ";
  2602. } // addGetPrimaryKey_MultiFK()
  2603. /**
  2604. * Adds the getPrimaryKey() method for objects that have no primary key.
  2605. * This "feature" is dreprecated, since the getPrimaryKey() method is not required
  2606. * by the Persistent interface (or used by the templates). Hence, this method is also
  2607. * deprecated.
  2608. * @param string &$script The script will be modified in this method.
  2609. * @deprecated
  2610. */
  2611. protected function addGetPrimaryKey_NoPK(&$script)
  2612. {
  2613. $script .= "
  2614. /**
  2615. * Returns NULL since this table doesn't have a primary key.
  2616. * This method exists only for BC and is deprecated!
  2617. * @return null
  2618. */
  2619. public function getPrimaryKey()
  2620. {
  2621. return null;
  2622. }
  2623. ";
  2624. }
  2625. /**
  2626. * Adds the correct setPrimaryKey() method for this object.
  2627. * @param string &$script The script will be modified in this method.
  2628. */
  2629. protected function addSetPrimaryKey(&$script)
  2630. {
  2631. $pkeys = $this->getTable()->getPrimaryKey();
  2632. if (count($pkeys) == 1) {
  2633. $this->addSetPrimaryKey_SinglePK($script);
  2634. } elseif (count($pkeys) > 1) {
  2635. $this->addSetPrimaryKey_MultiPK($script);
  2636. } else {
  2637. // no primary key -- this is deprecated, since we don't *need* this method anymore
  2638. $this->addSetPrimaryKey_NoPK($script);
  2639. }
  2640. }
  2641. /**
  2642. * Adds the setPrimaryKey() method for tables that contain a single-column primary key.
  2643. * @param string &$script The script will be modified in this method.
  2644. */
  2645. protected function addSetPrimaryKey_SinglePK(&$script)
  2646. {
  2647. $pkeys = $this->getTable()->getPrimaryKey();
  2648. $col = $pkeys[0];
  2649. $clo=strtolower($col->getName());
  2650. $ctype = $col->getPhpType();
  2651. $script .= "
  2652. /**
  2653. * Generic method to set the primary key ($clo column).
  2654. *
  2655. * @param $ctype \$key Primary key.
  2656. * @return void
  2657. */
  2658. public function setPrimaryKey(\$key)
  2659. {
  2660. \$this->set".$col->getPhpName()."(\$key);
  2661. }
  2662. ";
  2663. } // addSetPrimaryKey_SinglePK
  2664. /**
  2665. * Adds the setPrimaryKey() method for tables that contain a multi-columnprimary key.
  2666. * @param string &$script The script will be modified in this method.
  2667. */
  2668. protected function addSetPrimaryKey_MultiPK(&$script)
  2669. {
  2670. $script .="
  2671. /**
  2672. * Set the [composite] primary key.
  2673. *
  2674. * @param array \$keys The elements of the composite key (order must match the order in XML file).
  2675. * @return void
  2676. */
  2677. public function setPrimaryKey(\$keys)
  2678. {";
  2679. $i = 0;
  2680. foreach ($this->getTable()->getPrimaryKey() as $pk) {
  2681. $pktype = $pk->getPhpType();
  2682. $script .= "
  2683. \$this->set".$pk->getPhpName()."(\$keys[$i]);";
  2684. $i++;
  2685. } /* foreach ($table->getPrimaryKey() */
  2686. $script .= "
  2687. }
  2688. ";
  2689. } // addSetPrimaryKey_MultiPK
  2690. /**
  2691. * Adds the setPrimaryKey() method for objects that have no primary key.
  2692. * This "feature" is dreprecated, since the setPrimaryKey() method is not required
  2693. * by the Persistent interface (or used by the templates). Hence, this method is also
  2694. * deprecated.
  2695. * @param string &$script The script will be modified in this method.
  2696. * @deprecated
  2697. */
  2698. protected function addSetPrimaryKey_NoPK(&$script)
  2699. {
  2700. $script .="
  2701. /**
  2702. * Dummy primary key setter.
  2703. *
  2704. * This function only exists to preserve backwards compatibility. It is no longer
  2705. * needed or required by the Persistent interface. It will be removed in next BC-breaking
  2706. * release of Propel.
  2707. *
  2708. * @deprecated
  2709. */
  2710. public function setPrimaryKey(\$pk)
  2711. {
  2712. // do nothing, because this object doesn't have any primary keys
  2713. }
  2714. ";
  2715. }
  2716. /**
  2717. * Adds the isPrimaryKeyNull() method
  2718. * @param string &$script The script will be modified in this method.
  2719. */
  2720. protected function addIsPrimaryKeyNull(&$script)
  2721. {
  2722. $table = $this->getTable();
  2723. $pkeys = $table->getPrimaryKey();
  2724. $script .= "
  2725. /**
  2726. * Returns true if the primary key for this object is null.
  2727. * @return boolean
  2728. */
  2729. public function isPrimaryKeyNull()
  2730. {";
  2731. if (count($pkeys) == 1) {
  2732. $script .= "
  2733. return null === \$this->get" . $pkeys[0]->getPhpName() . "();";
  2734. } else {
  2735. $tests = array();
  2736. foreach ($pkeys as $pkey) {
  2737. $tests[]= "(null === \$this->get" . $pkey->getPhpName() . "())";
  2738. }
  2739. $script .= "
  2740. return " . join(' && ', $tests) . ";";
  2741. }
  2742. $script .= "
  2743. }
  2744. ";
  2745. } // addetPrimaryKey_SingleFK
  2746. // --------------------------------------------------------------------
  2747. // Complex OM Methods
  2748. // --------------------------------------------------------------------
  2749. /**
  2750. * Constructs variable name for fkey-related objects.
  2751. * @param ForeignKey $fk
  2752. * @return string
  2753. */
  2754. public function getFKVarName(ForeignKey $fk)
  2755. {
  2756. return 'a' . $this->getFKPhpNameAffix($fk, $plural = false);
  2757. }
  2758. /**
  2759. * Constructs variable name for objects which referencing current table by specified foreign key.
  2760. * @param ForeignKey $fk
  2761. * @return string
  2762. */
  2763. public function getRefFKCollVarName(ForeignKey $fk)
  2764. {
  2765. return 'coll' . $this->getRefFKPhpNameAffix($fk, $plural = true);
  2766. }
  2767. /**
  2768. * Constructs variable name for single object which references current table by specified foreign key
  2769. * which is ALSO a primary key (hence one-to-one relationship).
  2770. * @param ForeignKey $fk
  2771. * @return string
  2772. */
  2773. public function getPKRefFKVarName(ForeignKey $fk)
  2774. {
  2775. return 'single' . $this->getRefFKPhpNameAffix($fk, $plural = false);
  2776. }
  2777. // ----------------------------------------------------------------
  2778. //
  2779. // F K M E T H O D S
  2780. //
  2781. // ----------------------------------------------------------------
  2782. /**
  2783. * Adds the methods that get & set objects related by foreign key to the current object.
  2784. * @param string &$script The script will be modified in this method.
  2785. */
  2786. protected function addFKMethods(&$script)
  2787. {
  2788. foreach ($this->getTable()->getForeignKeys() as $fk) {
  2789. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($fk->getForeignTable()));
  2790. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($fk->getForeignTable()));
  2791. $this->addFKMutator($script, $fk);
  2792. $this->addFKAccessor($script, $fk);
  2793. } // foreach fk
  2794. }
  2795. /**
  2796. * Adds the class attributes that are needed to store fkey related objects.
  2797. * @param string &$script The script will be modified in this method.
  2798. */
  2799. protected function addFKAttributes(&$script, ForeignKey $fk)
  2800. {
  2801. $className = $this->getForeignTable($fk)->getPhpName();
  2802. $varName = $this->getFKVarName($fk);
  2803. $script .= "
  2804. /**
  2805. * @var $className
  2806. */
  2807. protected $".$varName.";
  2808. ";
  2809. }
  2810. /**
  2811. * Adds the mutator (setter) method for setting an fkey related object.
  2812. * @param string &$script The script will be modified in this method.
  2813. */
  2814. protected function addFKMutator(&$script, ForeignKey $fk)
  2815. {
  2816. $table = $this->getTable();
  2817. $tblFK = $this->getForeignTable($fk);
  2818. $joinTableObjectBuilder = $this->getNewObjectBuilder($tblFK);
  2819. $className = $joinTableObjectBuilder->getObjectClassname();
  2820. $varName = $this->getFKVarName($fk);
  2821. $script .= "
  2822. /**
  2823. * Declares an association between this object and a $className object.
  2824. *
  2825. * @param $className \$v
  2826. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  2827. * @throws PropelException
  2828. */
  2829. public function set".$this->getFKPhpNameAffix($fk, $plural = false)."($className \$v = null)
  2830. {";
  2831. foreach ($fk->getLocalColumns() as $columnName) {
  2832. $column = $table->getColumn($columnName);
  2833. $lfmap = $fk->getLocalForeignMapping();
  2834. $colFKName = $lfmap[$columnName];
  2835. $colFK = $tblFK->getColumn($colFKName);
  2836. $script .= "
  2837. if (\$v === null) {
  2838. \$this->set".$column->getPhpName()."(".$this->getDefaultValueString($column).");
  2839. } else {
  2840. \$this->set".$column->getPhpName()."(\$v->get".$colFK->getPhpName()."());
  2841. }
  2842. ";
  2843. } /* foreach local col */
  2844. $script .= "
  2845. \$this->$varName = \$v;
  2846. ";
  2847. // Now add bi-directional relationship binding, taking into account whether this is
  2848. // a one-to-one relationship.
  2849. if ($fk->isLocalPrimaryKey()) {
  2850. $script .= "
  2851. // Add binding for other direction of this 1:1 relationship.
  2852. if (\$v !== null) {
  2853. \$v->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
  2854. }
  2855. ";
  2856. } else {
  2857. $script .= "
  2858. // Add binding for other direction of this n:n relationship.
  2859. // If this object has already been added to the $className object, it will not be re-added.
  2860. if (\$v !== null) {
  2861. \$v->add".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
  2862. }
  2863. ";
  2864. }
  2865. $script .= "
  2866. return \$this;
  2867. }
  2868. ";
  2869. }
  2870. /**
  2871. * Adds the accessor (getter) method for getting an fkey related object.
  2872. * @param string &$script The script will be modified in this method.
  2873. */
  2874. protected function addFKAccessor(&$script, ForeignKey $fk)
  2875. {
  2876. $table = $this->getTable();
  2877. $varName = $this->getFKVarName($fk);
  2878. $fkQueryBuilder = $this->getNewStubQueryBuilder($this->getForeignTable($fk));
  2879. $fkObjectBuilder = $this->getNewObjectBuilder($this->getForeignTable($fk))->getStubObjectBuilder();
  2880. $className = $fkObjectBuilder->getClassname(); // get the Classname that has maybe a prefix
  2881. $and = "";
  2882. $conditional = "";
  2883. $localColumns = array(); // foreign key local attributes names
  2884. // If the related columns are a primary key on the foreign table
  2885. // then use retrieveByPk() instead of doSelect() to take advantage
  2886. // of instance pooling
  2887. $useRetrieveByPk = $fk->isForeignPrimaryKey();
  2888. foreach ($fk->getLocalColumns() as $columnName) {
  2889. $lfmap = $fk->getLocalForeignMapping();
  2890. $localColumn = $table->getColumn($columnName);
  2891. $foreignColumn = $fk->getForeignTable()->getColumn($lfmap[$columnName]);
  2892. $column = $table->getColumn($columnName);
  2893. $cptype = $column->getPhpType();
  2894. $clo = strtolower($column->getName());
  2895. $localColumns[$foreignColumn->getPosition()] = '$this->'.$clo;
  2896. if ($cptype == "integer" || $cptype == "float" || $cptype == "double") {
  2897. $conditional .= $and . "\$this->". $clo ." != 0";
  2898. } elseif ($cptype == "string") {
  2899. $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)";
  2900. } else {
  2901. $conditional .= $and . "\$this->" . $clo ." !== null";
  2902. }
  2903. $and = " && ";
  2904. }
  2905. ksort($localColumns); // restoring the order of the foreign PK
  2906. $localColumns = count($localColumns) > 1 ?
  2907. ('array('.implode(', ', $localColumns).')') : reset($localColumns);
  2908. $script .= "
  2909. /**
  2910. * Get the associated $className object
  2911. *
  2912. * @param PropelPDO \$con Optional Connection object.
  2913. * @return $className The associated $className object.
  2914. * @throws PropelException
  2915. */
  2916. public function get".$this->getFKPhpNameAffix($fk, $plural = false)."(PropelPDO \$con = null)
  2917. {";
  2918. $script .= "
  2919. if (\$this->$varName === null && ($conditional)) {";
  2920. if ($useRetrieveByPk) {
  2921. $script .= "
  2922. \$this->$varName = ".$fkQueryBuilder->getClassname()."::create()->findPk($localColumns, \$con);";
  2923. } else {
  2924. $script .= "
  2925. \$this->$varName = ".$fkQueryBuilder->getClassname()."::create()
  2926. ->filterBy" . $this->getRefFKPhpNameAffix($fk, $plural = false) . "(\$this) // here
  2927. ->findOne(\$con);";
  2928. }
  2929. if ($fk->isLocalPrimaryKey()) {
  2930. $script .= "
  2931. // Because this foreign key represents a one-to-one relationship, we will create a bi-directional association.
  2932. \$this->{$varName}->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);";
  2933. } else {
  2934. $script .= "
  2935. /* The following can be used additionally to
  2936. guarantee the related object contains a reference
  2937. to this object. This level of coupling may, however, be
  2938. undesirable since it could result in an only partially populated collection
  2939. in the referenced object.
  2940. \$this->{$varName}->add".$this->getRefFKPhpNameAffix($fk, $plural = true)."(\$this);
  2941. */";
  2942. }
  2943. $script .= "
  2944. }
  2945. return \$this->$varName;
  2946. }
  2947. ";
  2948. } // addFKAccessor
  2949. /**
  2950. * Adds a convenience method for setting a related object by specifying the primary key.
  2951. * This can be used in conjunction with the getPrimaryKey() for systems where nothing is known
  2952. * about the actual objects being related.
  2953. * @param string &$script The script will be modified in this method.
  2954. */
  2955. protected function addFKByKeyMutator(&$script, ForeignKey $fk)
  2956. {
  2957. $table = $this->getTable();
  2958. #$className = $this->getForeignTable($fk)->getPhpName();
  2959. $methodAffix = $this->getFKPhpNameAffix($fk);
  2960. #$varName = $this->getFKVarName($fk);
  2961. $script .= "
  2962. /**
  2963. * Provides convenient way to set a relationship based on a
  2964. * key. e.g.
  2965. * <code>\$bar->setFooKey(\$foo->getPrimaryKey())</code>
  2966. *";
  2967. if (count($fk->getLocalColumns()) > 1) {
  2968. $script .= "
  2969. * Note: It is important that the xml schema used to create this class
  2970. * maintains consistency in the order of related columns between
  2971. * ".$table->getName()." and ". $tblFK->getName().".
  2972. * If for some reason this is impossible, this method should be
  2973. * overridden in <code>".$table->getPhpName()."</code>.";
  2974. }
  2975. $script .= "
  2976. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  2977. * @throws PropelException
  2978. */
  2979. public function set".$methodAffix."Key(\$key)
  2980. {
  2981. ";
  2982. if (count($fk->getLocalColumns()) > 1) {
  2983. $i = 0;
  2984. foreach ($fk->getLocalColumns() as $colName) {
  2985. $col = $table->getColumn($colName);
  2986. $fktype = $col->getPhpType();
  2987. $script .= "
  2988. \$this->set".$col->getPhpName()."( ($fktype) \$key[$i] );
  2989. ";
  2990. $i++;
  2991. } /* foreach */
  2992. } else {
  2993. $lcols = $fk->getLocalColumns();
  2994. $colName = $lcols[0];
  2995. $col = $table->getColumn($colName);
  2996. $fktype = $col->getPhpType();
  2997. $script .= "
  2998. \$this->set".$col->getPhpName()."( ($fktype) \$key);
  2999. ";
  3000. }
  3001. $script .= "
  3002. return \$this;
  3003. }
  3004. ";
  3005. } // addFKByKeyMutator()
  3006. /**
  3007. * Adds the method that fetches fkey-related (referencing) objects but also joins in data from another table.
  3008. * @param string &$script The script will be modified in this method.
  3009. */
  3010. protected function addRefFKGetJoinMethods(&$script, ForeignKey $refFK)
  3011. {
  3012. $table = $this->getTable();
  3013. $tblFK = $refFK->getTable();
  3014. $join_behavior = $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
  3015. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  3016. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  3017. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural=true);
  3018. $collName = $this->getRefFKCollVarName($refFK);
  3019. $fkPeerBuilder = $this->getNewPeerBuilder($tblFK);
  3020. $className = $fkPeerBuilder->getObjectClassname();
  3021. $lastTable = "";
  3022. foreach ($tblFK->getForeignKeys() as $fk2) {
  3023. $tblFK2 = $this->getForeignTable($fk2);
  3024. $doJoinGet = !$tblFK2->isForReferenceOnly();
  3025. // it doesn't make sense to join in rows from the curent table, since we are fetching
  3026. // objects related to *this* table (i.e. the joined rows will all be the same row as current object)
  3027. if ($this->getTable()->getPhpName() == $tblFK2->getPhpName()) {
  3028. $doJoinGet = false;
  3029. }
  3030. $relCol2 = $this->getFKPhpNameAffix($fk2, $plural = false);
  3031. if ( $this->getRelatedBySuffix($refFK) != "" &&
  3032. ($this->getRelatedBySuffix($refFK) == $this->getRelatedBySuffix($fk2))) {
  3033. $doJoinGet = false;
  3034. }
  3035. if ($doJoinGet) {
  3036. $script .= "
  3037. /**
  3038. * If this collection has already been initialized with
  3039. * an identical criteria, it returns the collection.
  3040. * Otherwise if this ".$table->getPhpName()." is new, it will return
  3041. * an empty collection; or if this ".$table->getPhpName()." has previously
  3042. * been saved, it will retrieve related $relCol from storage.
  3043. *
  3044. * This method is protected by default in order to keep the public
  3045. * api reasonable. You can provide public methods for those you
  3046. * actually need in ".$table->getPhpName().".
  3047. *
  3048. * @param Criteria \$criteria optional Criteria object to narrow the query
  3049. * @param PropelPDO \$con optional connection object
  3050. * @param string \$join_behavior optional join type to use (defaults to $join_behavior)
  3051. * @return PropelObjectCollection|{$className}[] List of $className objects
  3052. */
  3053. public function get".$relCol."Join".$relCol2."(\$criteria = null, \$con = null, \$join_behavior = $join_behavior)
  3054. {";
  3055. $script .= "
  3056. \$query = $fkQueryClassname::create(null, \$criteria);
  3057. \$query->joinWith('" . $this->getFKPhpNameAffix($fk2, $plural=false) . "', \$join_behavior);
  3058. return \$this->get". $relCol . "(\$query, \$con);
  3059. }
  3060. ";
  3061. } /* end if ($doJoinGet) */
  3062. } /* end foreach ($tblFK->getForeignKeys() as $fk2) { */
  3063. } // function
  3064. // ----------------------------------------------------------------
  3065. //
  3066. // R E F E R R E R F K M E T H O D S
  3067. //
  3068. // ----------------------------------------------------------------
  3069. /**
  3070. * Adds the attributes used to store objects that have referrer fkey relationships to this object.
  3071. * <code>protected collVarName;</code>
  3072. * <code>private lastVarNameCriteria = null;</code>
  3073. * @param string &$script The script will be modified in this method.
  3074. */
  3075. protected function addRefFKAttributes(&$script, ForeignKey $refFK)
  3076. {
  3077. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3078. $className = $joinedTableObjectBuilder->getObjectClassname();
  3079. if ($refFK->isLocalPrimaryKey()) {
  3080. $script .= "
  3081. /**
  3082. * @var $className one-to-one related $className object
  3083. */
  3084. protected $".$this->getPKRefFKVarName($refFK).";
  3085. ";
  3086. } else {
  3087. $script .= "
  3088. /**
  3089. * @var PropelObjectCollection|{$className}[] Collection to store aggregation of $className objects.
  3090. */
  3091. protected $".$this->getRefFKCollVarName($refFK).";
  3092. protected $".$this->getRefFKCollVarName($refFK)."Partial;
  3093. ";
  3094. }
  3095. }
  3096. /**
  3097. * Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys.
  3098. * @param string &$script The script will be modified in this method.
  3099. */
  3100. protected function addRefFKMethods(&$script)
  3101. {
  3102. if (!$referrers = $this->getTable()->getReferrers()) {
  3103. return;
  3104. }
  3105. $this->addInitRelations($script, $referrers);
  3106. foreach ($referrers as $refFK) {
  3107. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($refFK->getTable()));
  3108. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($refFK->getTable()));
  3109. if ($refFK->isLocalPrimaryKey()) {
  3110. $this->addPKRefFKGet($script, $refFK);
  3111. $this->addPKRefFKSet($script, $refFK);
  3112. } else {
  3113. $this->addRefFKClear($script, $refFK);
  3114. $this->addRefFKPartial($script, $refFK);
  3115. $this->addRefFKInit($script, $refFK);
  3116. $this->addRefFKGet($script, $refFK);
  3117. $this->addRefFKSet($script, $refFK);
  3118. $this->addRefFKCount($script, $refFK);
  3119. $this->addRefFKAdd($script, $refFK);
  3120. $this->addRefFKDoAdd($script, $refFK);
  3121. $this->addRefFKRemove($script, $refFK);
  3122. $this->addRefFKGetJoinMethods($script, $refFK);
  3123. }
  3124. }
  3125. }
  3126. protected function addInitRelations(&$script, $referrers)
  3127. {
  3128. $script .= "
  3129. /**
  3130. * Initializes a collection based on the name of a relation.
  3131. * Avoids crafting an 'init[\$relationName]s' method name
  3132. * that wouldn't work when StandardEnglishPluralizer is used.
  3133. *
  3134. * @param string \$relationName The name of the relation to initialize
  3135. * @return void
  3136. */
  3137. public function initRelation(\$relationName)
  3138. {";
  3139. foreach ($referrers as $refFK) {
  3140. if (!$refFK->isLocalPrimaryKey()) {
  3141. $relationName = $this->getRefFKPhpNameAffix($refFK);
  3142. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3143. $script .= "
  3144. if ('$relationName' == \$relationName) {
  3145. \$this->init$relCol();
  3146. }";
  3147. }
  3148. }
  3149. $script .= "
  3150. }
  3151. ";
  3152. }
  3153. /**
  3154. * Adds the method that clears the referrer fkey collection.
  3155. * @param string &$script The script will be modified in this method.
  3156. */
  3157. protected function addRefFKClear(&$script, ForeignKey $refFK)
  3158. {
  3159. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3160. $collName = $this->getRefFKCollVarName($refFK);
  3161. $script .= "
  3162. /**
  3163. * Clears out the $collName collection
  3164. *
  3165. * This does not modify the database; however, it will remove any associated objects, causing
  3166. * them to be refetched by subsequent calls to accessor method.
  3167. *
  3168. * @return void
  3169. * @see add$relCol()
  3170. */
  3171. public function clear$relCol()
  3172. {
  3173. \$this->$collName = null; // important to set this to NULL since that means it is uninitialized
  3174. \$this->{$collName}Partial = null;
  3175. }
  3176. ";
  3177. } // addRefererClear()
  3178. /**
  3179. * Adds the method that clears the referrer fkey collection.
  3180. * @param string &$script The script will be modified in this method.
  3181. */
  3182. protected function addRefFKPartial(&$script, ForeignKey $refFK)
  3183. {
  3184. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3185. $collName = $this->getRefFKCollVarName($refFK);
  3186. $script .= "
  3187. /**
  3188. * reset is the $collName collection loaded partially
  3189. *
  3190. * @return void
  3191. */
  3192. public function resetPartial{$relCol}(\$v = true)
  3193. {
  3194. \$this->{$collName}Partial = \$v;
  3195. }
  3196. ";
  3197. } // addRefFKPartial()
  3198. /**
  3199. * Adds the method that initializes the referrer fkey collection.
  3200. * @param string &$script The script will be modified in this method.
  3201. */
  3202. protected function addRefFKInit(&$script, ForeignKey $refFK)
  3203. {
  3204. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3205. $collName = $this->getRefFKCollVarName($refFK);
  3206. $script .= "
  3207. /**
  3208. * Initializes the $collName collection.
  3209. *
  3210. * By default this just sets the $collName collection to an empty array (like clear$collName());
  3211. * however, you may wish to override this method in your stub class to provide setting appropriate
  3212. * to your application -- for example, setting the initial array to the values stored in database.
  3213. *
  3214. * @param boolean \$overrideExisting If set to true, the method call initializes
  3215. * the collection even if it is not empty
  3216. *
  3217. * @return void
  3218. */
  3219. public function init$relCol(\$overrideExisting = true)
  3220. {
  3221. if (null !== \$this->$collName && !\$overrideExisting) {
  3222. return;
  3223. }
  3224. \$this->$collName = new PropelObjectCollection();
  3225. \$this->{$collName}->setModel('" . $this->getNewStubObjectBuilder($refFK->getTable())->getClassname() . "');
  3226. }
  3227. ";
  3228. } // addRefererInit()
  3229. /**
  3230. * Adds the method that adds an object into the referrer fkey collection.
  3231. * @param string &$script The script will be modified in this method.
  3232. */
  3233. protected function addRefFKAdd(&$script, ForeignKey $refFK)
  3234. {
  3235. $tblFK = $refFK->getTable();
  3236. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3237. $className = $joinedTableObjectBuilder->getObjectClassname();
  3238. if ($tblFK->getChildrenColumn()) {
  3239. $className = 'Base' . $className;
  3240. $namespace = $joinedTableObjectBuilder->getNamespace();
  3241. $this->declareClass($namespace.'\\'.$className);
  3242. }
  3243. $collName = $this->getRefFKCollVarName($refFK);
  3244. $script .= "
  3245. /**
  3246. * Method called to associate a $className object to this object
  3247. * through the $className foreign key attribute.
  3248. *
  3249. * @param $className \$l $className
  3250. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  3251. */
  3252. public function add".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$l)
  3253. {
  3254. if (\$this->$collName === null) {
  3255. \$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."();
  3256. \$this->{$collName}Partial = true;
  3257. }
  3258. if (!\$this->{$collName}->contains(\$l)) { // only add it if the **same** object is not already associated
  3259. \$this->doAdd" . $this->getRefFKPhpNameAffix($refFK, $plural = false) . "(\$l);
  3260. }
  3261. return \$this;
  3262. }
  3263. ";
  3264. } // addRefererAdd
  3265. /**
  3266. * Adds the method that returns the size of the referrer fkey collection.
  3267. * @param string &$script The script will be modified in this method.
  3268. */
  3269. protected function addRefFKCount(&$script, ForeignKey $refFK)
  3270. {
  3271. $table = $this->getTable();
  3272. $tblFK = $refFK->getTable();
  3273. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  3274. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  3275. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3276. $collName = $this->getRefFKCollVarName($refFK);
  3277. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3278. $className = $joinedTableObjectBuilder->getObjectClassname();
  3279. $script .= "
  3280. /**
  3281. * Returns the number of related $className objects.
  3282. *
  3283. * @param Criteria \$criteria
  3284. * @param boolean \$distinct
  3285. * @param PropelPDO \$con
  3286. * @return int Count of related $className objects.
  3287. * @throws PropelException
  3288. */
  3289. public function count$relCol(Criteria \$criteria = null, \$distinct = false, PropelPDO \$con = null)
  3290. {
  3291. \$partial = \$this->{$collName}Partial && !\$this->isNew();
  3292. if (null === \$this->$collName || null !== \$criteria || \$partial) {
  3293. if (\$this->isNew() && null === \$this->$collName) {
  3294. return 0;
  3295. } else {
  3296. if(\$partial && !\$criteria) {
  3297. return count(\$this->get$relCol());
  3298. }
  3299. \$query = $fkQueryClassname::create(null, \$criteria);
  3300. if (\$distinct) {
  3301. \$query->distinct();
  3302. }
  3303. return \$query
  3304. ->filterBy" . $this->getFKPhpNameAffix($refFK) . "(\$this)
  3305. ->count(\$con);
  3306. }
  3307. } else {
  3308. return count(\$this->$collName);
  3309. }
  3310. }
  3311. ";
  3312. } // addRefererCount
  3313. /**
  3314. * Adds the method that returns the referrer fkey collection.
  3315. * @param string &$script The script will be modified in this method.
  3316. */
  3317. protected function addRefFKGet(&$script, ForeignKey $refFK)
  3318. {
  3319. $table = $this->getTable();
  3320. $tblFK = $refFK->getTable();
  3321. $peerClassname = $this->getStubPeerBuilder()->getClassname();
  3322. $fkQueryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  3323. $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3324. $collName = $this->getRefFKCollVarName($refFK);
  3325. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3326. $className = $joinedTableObjectBuilder->getObjectClassname();
  3327. $script .= "
  3328. /**
  3329. * Gets an array of $className objects which contain a foreign key that references this object.
  3330. *
  3331. * If the \$criteria is not null, it is used to always fetch the results from the database.
  3332. * Otherwise the results are fetched from the database the first time, then cached.
  3333. * Next time the same method is called without \$criteria, the cached collection is returned.
  3334. * If this ".$this->getObjectClassname()." is new, it will return
  3335. * an empty collection or the current collection; the criteria is ignored on a new object.
  3336. *
  3337. * @param Criteria \$criteria optional Criteria object to narrow the query
  3338. * @param PropelPDO \$con optional connection object
  3339. * @return PropelObjectCollection|{$className}[] List of $className objects
  3340. * @throws PropelException
  3341. */
  3342. public function get$relCol(\$criteria = null, PropelPDO \$con = null)
  3343. {
  3344. \$partial = \$this->{$collName}Partial && !\$this->isNew();
  3345. if (null === \$this->$collName || null !== \$criteria || \$partial) {
  3346. if (\$this->isNew() && null === \$this->$collName) {
  3347. // return empty collection
  3348. \$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."();
  3349. } else {
  3350. \$$collName = $fkQueryClassname::create(null, \$criteria)
  3351. ->filterBy" . $this->getFKPhpNameAffix($refFK) . "(\$this)
  3352. ->find(\$con);
  3353. if (null !== \$criteria) {
  3354. if (false !== \$this->{$collName}Partial && count(\$$collName)) {
  3355. \$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."(false);
  3356. foreach(\$$collName as \$obj) {
  3357. if (false == \$this->{$collName}->contains(\$obj)) {
  3358. \$this->{$collName}->append(\$obj);
  3359. }
  3360. }
  3361. \$this->{$collName}Partial = true;
  3362. }
  3363. return \$$collName;
  3364. }
  3365. if(\$partial && \$this->$collName) {
  3366. foreach(\$this->$collName as \$obj) {
  3367. if(\$obj->isNew()) {
  3368. \${$collName}[] = \$obj;
  3369. }
  3370. }
  3371. }
  3372. \$this->$collName = \$$collName;
  3373. \$this->{$collName}Partial = false;
  3374. }
  3375. }
  3376. return \$this->$collName;
  3377. }
  3378. ";
  3379. } // addRefererGet()
  3380. protected function addRefFKSet(&$script, $refFK)
  3381. {
  3382. $relatedName = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3383. $relatedObjectClassName = $this->getRefFKPhpNameAffix($refFK, $plural = false);
  3384. // No lcfirst() in PHP < 5.3
  3385. $inputCollection = $relatedName;
  3386. $inputCollection[0] = strtolower($inputCollection[0]);
  3387. // No lcfirst() in PHP < 5.3
  3388. $inputCollectionEntry = $this->getRefFKPhpNameAffix($refFK, $plural = false);
  3389. $inputCollectionEntry[0] = strtolower($inputCollectionEntry[0]);
  3390. $collName = $this->getRefFKCollVarName($refFK);
  3391. $relCol = $this->getFKPhpNameAffix($refFK, $plural = false);
  3392. $script .= "
  3393. /**
  3394. * Sets a collection of $relatedObjectClassName objects related by a one-to-many relationship
  3395. * to the current object.
  3396. * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
  3397. * and new objects from the given Propel collection.
  3398. *
  3399. * @param PropelCollection \${$inputCollection} A Propel collection.
  3400. * @param PropelPDO \$con Optional connection object
  3401. */
  3402. public function set{$relatedName}(PropelCollection \${$inputCollection}, PropelPDO \$con = null)
  3403. {
  3404. \$this->{$inputCollection}ScheduledForDeletion = \$this->get{$relatedName}(new Criteria(), \$con)->diff(\${$inputCollection});
  3405. foreach (\$this->{$inputCollection}ScheduledForDeletion as \${$inputCollectionEntry}Removed) {
  3406. \${$inputCollectionEntry}Removed->set{$relCol}(null);
  3407. }
  3408. \$this->{$collName} = null;
  3409. foreach (\${$inputCollection} as \${$inputCollectionEntry}) {
  3410. \$this->add{$relatedObjectClassName}(\${$inputCollectionEntry});
  3411. }
  3412. \$this->{$collName} = \${$inputCollection};
  3413. \$this->{$collName}Partial = false;
  3414. }
  3415. ";
  3416. }
  3417. /**
  3418. * @param string &$script The script will be modified in this method.
  3419. * @param ForeignKey $refFK
  3420. * @param ForeignKey $crossFK
  3421. */
  3422. protected function addRefFKDoAdd(&$script, $refFK)
  3423. {
  3424. $relatedObjectClassName = $this->getRefFKPhpNameAffix($refFK, $plural = false);
  3425. // lcfirst() doesn't exist in PHP < 5.3
  3426. $lowerRelatedObjectClassName = $relatedObjectClassName;
  3427. $lowerRelatedObjectClassName[0] = strtolower($lowerRelatedObjectClassName[0]);
  3428. $collName = $this->getRefFKCollVarName($refFK);
  3429. $script .= "
  3430. /**
  3431. * @param {$relatedObjectClassName} \${$lowerRelatedObjectClassName} The $lowerRelatedObjectClassName object to add.
  3432. */
  3433. protected function doAdd{$relatedObjectClassName}(\${$lowerRelatedObjectClassName})
  3434. {
  3435. \$this->{$collName}[]= \${$lowerRelatedObjectClassName};
  3436. \${$lowerRelatedObjectClassName}->set" . $this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
  3437. }
  3438. ";
  3439. }
  3440. /**
  3441. * @param string &$script The script will be modified in this method.
  3442. * @param ForeignKey $refFK
  3443. * @param ForeignKey $crossFK
  3444. */
  3445. protected function addRefFKRemove(&$script, $refFK)
  3446. {
  3447. $relatedName = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3448. $relatedObjectClassName = $this->getRefFKPhpNameAffix($refFK, $plural = false);
  3449. // No lcfirst() in PHP < 5.3
  3450. $inputCollection = $relatedName . 'ScheduledForDeletion';
  3451. $inputCollection[0] = strtolower($inputCollection[0]);
  3452. // lcfirst() doesn't exist in PHP < 5.3
  3453. $lowerRelatedObjectClassName = $relatedObjectClassName;
  3454. $lowerRelatedObjectClassName[0] = strtolower($lowerRelatedObjectClassName[0]);
  3455. $collName = $this->getRefFKCollVarName($refFK);
  3456. $relCol = $this->getFKPhpNameAffix($refFK, $plural = false);
  3457. $script .= "
  3458. /**
  3459. * @param {$relatedObjectClassName} \${$lowerRelatedObjectClassName} The $lowerRelatedObjectClassName object to remove.
  3460. */
  3461. public function remove{$relatedObjectClassName}(\${$lowerRelatedObjectClassName})
  3462. {
  3463. if (\$this->get{$relatedName}()->contains(\${$lowerRelatedObjectClassName})) {
  3464. \$this->{$collName}->remove(\$this->{$collName}->search(\${$lowerRelatedObjectClassName}));
  3465. if (null === \$this->{$inputCollection}) {
  3466. \$this->{$inputCollection} = clone \$this->{$collName};
  3467. \$this->{$inputCollection}->clear();
  3468. }
  3469. \$this->{$inputCollection}[]= \${$lowerRelatedObjectClassName};
  3470. \${$lowerRelatedObjectClassName}->set{$relCol}(null);
  3471. }
  3472. }
  3473. ";
  3474. }
  3475. /**
  3476. * Adds the method that gets a one-to-one related referrer fkey.
  3477. * This is for one-to-one relationship special case.
  3478. * @param string &$script The script will be modified in this method.
  3479. */
  3480. protected function addPKRefFKGet(&$script, ForeignKey $refFK)
  3481. {
  3482. $table = $this->getTable();
  3483. $tblFK = $refFK->getTable();
  3484. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3485. $className = $joinedTableObjectBuilder->getObjectClassname();
  3486. $queryClassname = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  3487. $varName = $this->getPKRefFKVarName($refFK);
  3488. $script .= "
  3489. /**
  3490. * Gets a single $className object, which is related to this object by a one-to-one relationship.
  3491. *
  3492. * @param PropelPDO \$con optional connection object
  3493. * @return $className
  3494. * @throws PropelException
  3495. */
  3496. public function get".$this->getRefFKPhpNameAffix($refFK, $plural = false)."(PropelPDO \$con = null)
  3497. {
  3498. ";
  3499. $script .= "
  3500. if (\$this->$varName === null && !\$this->isNew()) {
  3501. \$this->$varName = $queryClassname::create()->findPk(\$this->getPrimaryKey(), \$con);
  3502. }
  3503. return \$this->$varName;
  3504. }
  3505. ";
  3506. } // addPKRefFKGet()
  3507. /**
  3508. * Adds the method that sets a one-to-one related referrer fkey.
  3509. * This is for one-to-one relationships special case.
  3510. * @param string &$script The script will be modified in this method.
  3511. * @param ForeignKey $refFK The referencing foreign key.
  3512. */
  3513. protected function addPKRefFKSet(&$script, ForeignKey $refFK)
  3514. {
  3515. $tblFK = $refFK->getTable();
  3516. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3517. $className = $joinedTableObjectBuilder->getObjectClassname();
  3518. $varName = $this->getPKRefFKVarName($refFK);
  3519. $script .= "
  3520. /**
  3521. * Sets a single $className object as related to this object by a one-to-one relationship.
  3522. *
  3523. * @param $className \$v $className
  3524. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  3525. * @throws PropelException
  3526. */
  3527. public function set".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$v = null)
  3528. {
  3529. \$this->$varName = \$v;
  3530. // Make sure that that the passed-in $className isn't already associated with this object
  3531. if (\$v !== null && \$v->get".$this->getFKPhpNameAffix($refFK, $plural = false)."() === null) {
  3532. \$v->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
  3533. }
  3534. return \$this;
  3535. }
  3536. ";
  3537. } // addPKRefFKSet
  3538. protected function addCrossFKAttributes(&$script, ForeignKey $crossFK)
  3539. {
  3540. $joinedTableObjectBuilder = $this->getNewObjectBuilder($crossFK->getForeignTable());
  3541. $className = $joinedTableObjectBuilder->getObjectClassname();
  3542. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3543. $script .= "
  3544. /**
  3545. * @var PropelObjectCollection|{$className}[] Collection to store aggregation of $className objects.
  3546. */
  3547. protected $" . $this->getCrossFKVarName($crossFK) . ";
  3548. ";
  3549. }
  3550. protected function addScheduledForDeletionAttribute(&$script, $fkName)
  3551. {
  3552. // No lcfirst() in PHP < 5.3
  3553. $fkName[0] = strtolower($fkName[0]);
  3554. $script .= "
  3555. /**
  3556. * An array of objects scheduled for deletion.
  3557. * @var PropelObjectCollection
  3558. */
  3559. protected \${$fkName}ScheduledForDeletion = null;
  3560. ";
  3561. }
  3562. protected function addCrossFkScheduledForDeletion(&$script, $refFK, $crossFK)
  3563. {
  3564. $queryClassName = $this->getRefFKPhpNameAffix($refFK, $plural = false) . 'Query';
  3565. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3566. // No lcfirst() in PHP < 5.3
  3567. $lowerRelatedName = $relatedName;
  3568. $lowerRelatedName[0] = strtolower($lowerRelatedName[0]);
  3569. // No lcfirst() in PHP < 5.3
  3570. $lowerSingleRelatedName = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3571. $lowerSingleRelatedName[0] = strtolower($lowerSingleRelatedName[0]);
  3572. $middelFks = $refFK->getTable()->getForeignKeys();
  3573. $isFirstPk = ($middelFks[0]->getForeignTableCommonName() == $this->getTable()->getCommonName());
  3574. $script .= "
  3575. if (\$this->{$lowerRelatedName}ScheduledForDeletion !== null) {
  3576. if (!\$this->{$lowerRelatedName}ScheduledForDeletion->isEmpty()) {
  3577. \$pks = array();
  3578. \$pk = \$this->getPrimaryKey();
  3579. foreach (\$this->{$lowerRelatedName}ScheduledForDeletion->getPrimaryKeys(false) as \$remotePk) {";
  3580. if ($isFirstPk) {
  3581. $script .= "
  3582. \$pks[] = array(\$pk, \$remotePk);";
  3583. } else {
  3584. $script .= "
  3585. \$pks[] = array(\$remotePk, \$pk);";
  3586. }
  3587. $script .= "
  3588. }
  3589. $queryClassName::create()
  3590. ->filterByPrimaryKeys(\$pks)
  3591. ->delete(\$con);
  3592. \$this->{$lowerRelatedName}ScheduledForDeletion = null;
  3593. }
  3594. foreach (\$this->get{$relatedName}() as \${$lowerSingleRelatedName}) {
  3595. if (\${$lowerSingleRelatedName}->isModified()) {
  3596. \${$lowerSingleRelatedName}->save(\$con);
  3597. }
  3598. }
  3599. }
  3600. ";
  3601. }
  3602. protected function addRefFkScheduledForDeletion(&$script, $refFK)
  3603. {
  3604. $relatedName = $this->getRefFKPhpNameAffix($refFK, $plural = true);
  3605. // No lcfirst() in PHP < 5.3
  3606. $lowerRelatedName = $relatedName;
  3607. $lowerRelatedName[0] = strtolower($lowerRelatedName[0]);
  3608. // No lcfirst() in PHP < 5.3
  3609. $lowerSingleRelatedName = $this->getRefFKPhpNameAffix($refFK, $plural = false);
  3610. $lowerSingleRelatedName[0] = strtolower($lowerSingleRelatedName[0]);
  3611. $queryClassName = $this->getNewStubQueryBuilder($refFK->getTable())->getClassname();
  3612. $localColumn = $refFK->getLocalColumn();
  3613. $script .= "
  3614. if (\$this->{$lowerRelatedName}ScheduledForDeletion !== null) {
  3615. if (!\$this->{$lowerRelatedName}ScheduledForDeletion->isEmpty()) {";
  3616. if (!$refFK->isComposite() && !$localColumn->isNotNull()) {
  3617. $script .= "
  3618. foreach (\$this->{$lowerRelatedName}ScheduledForDeletion as \${$lowerSingleRelatedName}) {
  3619. // need to save related object because we set the relation to null
  3620. \${$lowerSingleRelatedName}->save(\$con);
  3621. }";
  3622. } else {
  3623. $script .= "
  3624. $queryClassName::create()
  3625. ->filterByPrimaryKeys(\$this->{$lowerRelatedName}ScheduledForDeletion->getPrimaryKeys(false))
  3626. ->delete(\$con);";
  3627. }
  3628. $script .= "
  3629. \$this->{$lowerRelatedName}ScheduledForDeletion = null;
  3630. }
  3631. }
  3632. ";
  3633. }
  3634. protected function getCrossFKVarName(ForeignKey $crossFK)
  3635. {
  3636. return 'coll' . $this->getFKPhpNameAffix($crossFK, $plural = true);
  3637. }
  3638. protected function addCrossFKMethods(&$script)
  3639. {
  3640. foreach ($this->getTable()->getCrossFks() as $fkList) {
  3641. list($refFK, $crossFK) = $fkList;
  3642. $this->declareClassFromBuilder($this->getNewStubObjectBuilder($crossFK->getForeignTable()));
  3643. $this->declareClassFromBuilder($this->getNewStubQueryBuilder($crossFK->getForeignTable()));
  3644. $this->addCrossFKClear($script, $crossFK);
  3645. $this->addCrossFKInit($script, $crossFK);
  3646. $this->addCrossFKGet($script, $refFK, $crossFK);
  3647. $this->addCrossFKSet($script, $refFK, $crossFK);
  3648. $this->addCrossFKCount($script, $refFK, $crossFK);
  3649. $this->addCrossFKAdd($script, $refFK, $crossFK);
  3650. $this->addCrossFKDoAdd($script, $refFK, $crossFK);
  3651. $this->addCrossFKRemove($script, $refFK, $crossFK);
  3652. }
  3653. }
  3654. /**
  3655. * Adds the method that clears the referrer fkey collection.
  3656. * @param string &$script The script will be modified in this method.
  3657. */
  3658. protected function addCrossFKClear(&$script, ForeignKey $crossFK)
  3659. {
  3660. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3661. $collName = $this->getCrossFKVarName($crossFK);
  3662. $script .= "
  3663. /**
  3664. * Clears out the $collName collection
  3665. *
  3666. * This does not modify the database; however, it will remove any associated objects, causing
  3667. * them to be refetched by subsequent calls to accessor method.
  3668. *
  3669. * @return void
  3670. * @see add$relCol()
  3671. */
  3672. public function clear$relCol()
  3673. {
  3674. \$this->$collName = null; // important to set this to NULL since that means it is uninitialized
  3675. \$this->{$collName}Partial = null;
  3676. }
  3677. ";
  3678. } // addRefererClear()
  3679. /**
  3680. * Adds the method that initializes the referrer fkey collection.
  3681. * @param string &$script The script will be modified in this method.
  3682. */
  3683. protected function addCrossFKInit(&$script, ForeignKey $crossFK)
  3684. {
  3685. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3686. $collName = $this->getCrossFKVarName($crossFK);
  3687. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  3688. $script .= "
  3689. /**
  3690. * Initializes the $collName collection.
  3691. *
  3692. * By default this just sets the $collName collection to an empty collection (like clear$relCol());
  3693. * however, you may wish to override this method in your stub class to provide setting appropriate
  3694. * to your application -- for example, setting the initial array to the values stored in database.
  3695. *
  3696. * @return void
  3697. */
  3698. public function init$relCol()
  3699. {
  3700. \$this->$collName = new PropelObjectCollection();
  3701. \$this->{$collName}->setModel('$relatedObjectClassName');
  3702. }
  3703. ";
  3704. }
  3705. protected function addCrossFKGet(&$script, $refFK, $crossFK)
  3706. {
  3707. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3708. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  3709. $selfRelationName = $this->getFKPhpNameAffix($refFK, $plural = false);
  3710. $relatedQueryClassName = $this->getNewStubQueryBuilder($crossFK->getForeignTable())->getClassname();
  3711. $crossRefTableName = $crossFK->getTableName();
  3712. $collName = $this->getCrossFKVarName($crossFK);
  3713. $script .= "
  3714. /**
  3715. * Gets a collection of $relatedObjectClassName objects related by a many-to-many relationship
  3716. * to the current object by way of the $crossRefTableName cross-reference table.
  3717. *
  3718. * If the \$criteria is not null, it is used to always fetch the results from the database.
  3719. * Otherwise the results are fetched from the database the first time, then cached.
  3720. * Next time the same method is called without \$criteria, the cached collection is returned.
  3721. * If this ".$this->getObjectClassname()." is new, it will return
  3722. * an empty collection or the current collection; the criteria is ignored on a new object.
  3723. *
  3724. * @param Criteria \$criteria Optional query object to filter the query
  3725. * @param PropelPDO \$con Optional connection object
  3726. *
  3727. * @return PropelObjectCollection|{$relatedObjectClassName}[] List of {$relatedObjectClassName} objects
  3728. */
  3729. public function get{$relatedName}(\$criteria = null, PropelPDO \$con = null)
  3730. {
  3731. if (null === \$this->$collName || null !== \$criteria) {
  3732. if (\$this->isNew() && null === \$this->$collName) {
  3733. // return empty collection
  3734. \$this->init{$relatedName}();
  3735. } else {
  3736. \$$collName = $relatedQueryClassName::create(null, \$criteria)
  3737. ->filterBy{$selfRelationName}(\$this)
  3738. ->find(\$con);
  3739. if (null !== \$criteria) {
  3740. return \$$collName;
  3741. }
  3742. \$this->$collName = \$$collName;
  3743. }
  3744. }
  3745. return \$this->$collName;
  3746. }
  3747. ";
  3748. }
  3749. protected function addCrossFKSet(&$script, $refFK, $crossFK)
  3750. {
  3751. $relatedNamePlural = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3752. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3753. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  3754. $crossRefTableName = $crossFK->getTableName();
  3755. $collName = $this->getCrossFKVarName($crossFK);
  3756. // No lcfirst() in PHP < 5.3
  3757. $inputCollection = $relatedNamePlural;
  3758. $inputCollection[0] = strtolower($inputCollection[0]);
  3759. // No lcfirst() in PHP < 5.3
  3760. $inputCollectionEntry = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3761. $inputCollectionEntry[0] = strtolower($inputCollectionEntry[0]);
  3762. $script .= "
  3763. /**
  3764. * Sets a collection of $relatedObjectClassName objects related by a many-to-many relationship
  3765. * to the current object by way of the $crossRefTableName cross-reference table.
  3766. * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
  3767. * and new objects from the given Propel collection.
  3768. *
  3769. * @param PropelCollection \${$inputCollection} A Propel collection.
  3770. * @param PropelPDO \$con Optional connection object
  3771. */
  3772. public function set{$relatedNamePlural}(PropelCollection \${$inputCollection}, PropelPDO \$con = null)
  3773. {
  3774. \$this->clear{$relatedNamePlural}();
  3775. \$current{$relatedNamePlural} = \$this->get{$relatedNamePlural}();
  3776. \$this->{$inputCollection}ScheduledForDeletion = \$current{$relatedNamePlural}->diff(\${$inputCollection});
  3777. foreach (\${$inputCollection} as \${$inputCollectionEntry}) {
  3778. if (!\$current{$relatedNamePlural}->contains(\${$inputCollectionEntry})) {
  3779. \$this->doAdd{$relatedName}(\${$inputCollectionEntry});
  3780. }
  3781. }
  3782. \$this->$collName = \${$inputCollection};
  3783. }
  3784. ";
  3785. }
  3786. protected function addCrossFKCount(&$script, $refFK, $crossFK)
  3787. {
  3788. $relatedName = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3789. $relatedObjectClassName = $this->getNewStubObjectBuilder($crossFK->getForeignTable())->getClassname();
  3790. $selfRelationName = $this->getFKPhpNameAffix($refFK, $plural = false);
  3791. $relatedQueryClassName = $this->getNewStubQueryBuilder($crossFK->getForeignTable())->getClassname();
  3792. $crossRefTableName = $refFK->getTableName();
  3793. $collName = $this->getCrossFKVarName($crossFK);
  3794. $script .= "
  3795. /**
  3796. * Gets the number of $relatedObjectClassName objects related by a many-to-many relationship
  3797. * to the current object by way of the $crossRefTableName cross-reference table.
  3798. *
  3799. * @param Criteria \$criteria Optional query object to filter the query
  3800. * @param boolean \$distinct Set to true to force count distinct
  3801. * @param PropelPDO \$con Optional connection object
  3802. *
  3803. * @return int the number of related $relatedObjectClassName objects
  3804. */
  3805. public function count{$relatedName}(\$criteria = null, \$distinct = false, PropelPDO \$con = null)
  3806. {
  3807. if (null === \$this->$collName || null !== \$criteria) {
  3808. if (\$this->isNew() && null === \$this->$collName) {
  3809. return 0;
  3810. } else {
  3811. \$query = $relatedQueryClassName::create(null, \$criteria);
  3812. if (\$distinct) {
  3813. \$query->distinct();
  3814. }
  3815. return \$query
  3816. ->filterBy{$selfRelationName}(\$this)
  3817. ->count(\$con);
  3818. }
  3819. } else {
  3820. return count(\$this->$collName);
  3821. }
  3822. }
  3823. ";
  3824. }
  3825. /**
  3826. * Adds the method that adds an object into the referrer fkey collection.
  3827. * @param string &$script The script will be modified in this method.
  3828. */
  3829. protected function addCrossFKAdd(&$script, ForeignKey $refFK, ForeignKey $crossFK)
  3830. {
  3831. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3832. $collName = $this->getCrossFKVarName($crossFK);
  3833. $tblFK = $refFK->getTable();
  3834. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3835. $className = $joinedTableObjectBuilder->getObjectClassname();
  3836. $crossObjectName = '$' . $crossFK->getForeignTable()->getStudlyPhpName();
  3837. $crossObjectClassName = $this->getNewObjectBuilder($crossFK->getForeignTable())->getObjectClassname();
  3838. $relatedObjectClassName = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3839. $script .= "
  3840. /**
  3841. * Associate a " . $crossObjectClassName . " object to this object
  3842. * through the " . $tblFK->getName() . " cross reference table.
  3843. *
  3844. * @param " . $crossObjectClassName . " " . $crossObjectName . " The $className object to relate
  3845. * @return void
  3846. */
  3847. public function add{$relatedObjectClassName}($crossObjectClassName $crossObjectName)
  3848. {
  3849. if (\$this->" . $collName . " === null) {
  3850. \$this->init" . $relCol . "();
  3851. }
  3852. if (!\$this->" . $collName . "->contains(" . $crossObjectName . ")) { // only add it if the **same** object is not already associated
  3853. \$this->doAdd{$relatedObjectClassName}($crossObjectName);
  3854. \$this->" . $collName . "[]= " . $crossObjectName . ";
  3855. }
  3856. }
  3857. ";
  3858. }
  3859. /**
  3860. * @param string &$script The script will be modified in this method.
  3861. * @param ForeignKey $refFK
  3862. * @param ForeignKey $crossFK
  3863. */
  3864. protected function addCrossFKDoAdd(&$script, ForeignKey $refFK, ForeignKey $crossFK)
  3865. {
  3866. $relatedObjectClassName = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3867. // lcfirst() doesn't exist in PHP < 5.3
  3868. $lowerRelatedObjectClassName = $relatedObjectClassName;
  3869. $lowerRelatedObjectClassName[0] = strtolower($lowerRelatedObjectClassName[0]);
  3870. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3871. $className = $joinedTableObjectBuilder->getObjectClassname();
  3872. $tblFK = $refFK->getTable();
  3873. $foreignObjectName = '$' . $tblFK->getStudlyPhpName();
  3874. $script .= "
  3875. /**
  3876. * @param {$relatedObjectClassName} \${$lowerRelatedObjectClassName} The $lowerRelatedObjectClassName object to add.
  3877. */
  3878. protected function doAdd{$relatedObjectClassName}(\${$lowerRelatedObjectClassName})
  3879. {
  3880. {$foreignObjectName} = new {$className}();
  3881. {$foreignObjectName}->set{$relatedObjectClassName}(\${$lowerRelatedObjectClassName});
  3882. \$this->add{$className}({$foreignObjectName});
  3883. }
  3884. ";
  3885. }
  3886. /**
  3887. * Adds the method that remove an object from the referrer fkey collection.
  3888. * @param string $script The script will be modified in this method.
  3889. */
  3890. protected function addCrossFKRemove(&$script, ForeignKey $refFK, ForeignKey $crossFK)
  3891. {
  3892. $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
  3893. $collName = 'coll' . $relCol;
  3894. $tblFK = $refFK->getTable();
  3895. $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
  3896. $className = $joinedTableObjectBuilder->getObjectClassname();
  3897. $M2MScheduledForDeletion = lcfirst($relCol) . "ScheduledForDeletion";
  3898. $crossObjectName = '$' . $crossFK->getForeignTable()->getStudlyPhpName();
  3899. $crossObjectClassName = $this->getNewObjectBuilder($crossFK->getForeignTable())->getObjectClassname();
  3900. $relatedObjectClassName = $this->getFKPhpNameAffix($crossFK, $plural = false);
  3901. $script .= "
  3902. /**
  3903. * Remove a {$crossObjectClassName} object to this object
  3904. * through the {$tblFK->getName()} cross reference table.
  3905. *
  3906. * @param {$crossObjectClassName} {$crossObjectName} The $className object to relate
  3907. * @return void
  3908. */
  3909. public function remove{$relatedObjectClassName}($crossObjectClassName $crossObjectName)
  3910. {
  3911. if (\$this->get{$relCol}()->contains({$crossObjectName})) {
  3912. \$this->{$collName}->remove(\$this->{$collName}->search({$crossObjectName}));
  3913. if (null === \$this->{$M2MScheduledForDeletion}) {
  3914. \$this->{$M2MScheduledForDeletion} = clone \$this->{$collName};
  3915. \$this->{$M2MScheduledForDeletion}->clear();
  3916. }
  3917. \$this->{$M2MScheduledForDeletion}[]= {$crossObjectName};
  3918. }
  3919. }
  3920. ";
  3921. }
  3922. // ----------------------------------------------------------------
  3923. //
  3924. // M A N I P U L A T I O N M E T H O D S
  3925. //
  3926. // ----------------------------------------------------------------
  3927. /**
  3928. * Adds the workhourse doSave() method.
  3929. * @param string &$script The script will be modified in this method.
  3930. */
  3931. protected function addDoSave(&$script)
  3932. {
  3933. $table = $this->getTable();
  3934. $reloadOnUpdate = $table->isReloadOnUpdate();
  3935. $reloadOnInsert = $table->isReloadOnInsert();
  3936. $script .= "
  3937. /**
  3938. * Performs the work of inserting or updating the row in the database.
  3939. *
  3940. * If the object is new, it inserts it; otherwise an update is performed.
  3941. * All related objects are also updated in this method.
  3942. *
  3943. * @param PropelPDO \$con";
  3944. if ($reloadOnUpdate || $reloadOnInsert) {
  3945. $script .= "
  3946. * @param boolean \$skipReload Whether to skip the reload for this object from database.";
  3947. }
  3948. $script .= "
  3949. * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations.
  3950. * @throws PropelException
  3951. * @see save()
  3952. */
  3953. protected function doSave(PropelPDO \$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
  3954. {
  3955. \$affectedRows = 0; // initialize var to track total num of affected rows
  3956. if (!\$this->alreadyInSave) {
  3957. \$this->alreadyInSave = true;
  3958. ";
  3959. if ($reloadOnInsert || $reloadOnUpdate) {
  3960. $script .= "
  3961. \$reloadObject = false;
  3962. ";
  3963. }
  3964. if (count($table->getForeignKeys())) {
  3965. $script .= "
  3966. // We call the save method on the following object(s) if they
  3967. // were passed to this object by their coresponding set
  3968. // method. This object relates to these object(s) by a
  3969. // foreign key reference.
  3970. ";
  3971. foreach ($table->getForeignKeys() as $fk) {
  3972. $aVarName = $this->getFKVarName($fk);
  3973. $script .= "
  3974. if (\$this->$aVarName !== null) {
  3975. if (\$this->" . $aVarName . "->isModified() || \$this->" . $aVarName . "->isNew()) {
  3976. \$affectedRows += \$this->" . $aVarName . "->save(\$con);
  3977. }
  3978. \$this->set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$this->$aVarName);
  3979. }
  3980. ";
  3981. } // foreach foreign k
  3982. } // if (count(foreign keys))
  3983. $script .= "
  3984. if (\$this->isNew() || \$this->isModified()) {
  3985. // persist changes
  3986. if (\$this->isNew()) {
  3987. \$this->doInsert(\$con);";
  3988. if ($reloadOnInsert) {
  3989. $script .= "
  3990. if (!\$skipReload) {
  3991. \$reloadObject = true;
  3992. }";
  3993. }
  3994. $script .= "
  3995. } else {
  3996. \$this->doUpdate(\$con);";
  3997. if ($reloadOnUpdate) {
  3998. $script .= "
  3999. if (!\$skipReload) {
  4000. \$reloadObject = true;
  4001. }";
  4002. }
  4003. $script .= "
  4004. }
  4005. \$affectedRows += 1;";
  4006. // We need to rewind any LOB columns
  4007. foreach ($table->getColumns() as $col) {
  4008. $clo = strtolower($col->getName());
  4009. if ($col->isLobType()) {
  4010. $script .= "
  4011. // Rewind the $clo LOB column, since PDO does not rewind after inserting value.
  4012. if (\$this->$clo !== null && is_resource(\$this->$clo)) {
  4013. rewind(\$this->$clo);
  4014. }
  4015. ";
  4016. }
  4017. }
  4018. $script .= "
  4019. \$this->resetModified();
  4020. }
  4021. ";
  4022. if ($table->hasCrossForeignKeys()) {
  4023. foreach ($table->getCrossFks() as $fkList) {
  4024. list($refFK, $crossFK) = $fkList;
  4025. $this->addCrossFkScheduledForDeletion($script, $refFK, $crossFK);
  4026. }
  4027. }
  4028. foreach ($table->getReferrers() as $refFK) {
  4029. $this->addRefFkScheduledForDeletion($script, $refFK);
  4030. if ($refFK->isLocalPrimaryKey()) {
  4031. $varName = $this->getPKRefFKVarName($refFK);
  4032. $script .= "
  4033. if (\$this->$varName !== null) {
  4034. if (!\$this->{$varName}->isDeleted()) {
  4035. \$affectedRows += \$this->{$varName}->save(\$con);
  4036. }
  4037. }
  4038. ";
  4039. } else {
  4040. $collName = $this->getRefFKCollVarName($refFK);
  4041. $script .= "
  4042. if (\$this->$collName !== null) {
  4043. foreach (\$this->$collName as \$referrerFK) {
  4044. if (!\$referrerFK->isDeleted()) {
  4045. \$affectedRows += \$referrerFK->save(\$con);
  4046. }
  4047. }
  4048. }
  4049. ";
  4050. } // if refFK->isLocalPrimaryKey()
  4051. } /* foreach getReferrers() */
  4052. $script .= "
  4053. \$this->alreadyInSave = false;
  4054. ";
  4055. if ($reloadOnInsert || $reloadOnUpdate) {
  4056. $script .= "
  4057. if (\$reloadObject) {
  4058. \$this->reload(\$con);
  4059. }
  4060. ";
  4061. }
  4062. $script .= "
  4063. }
  4064. return \$affectedRows;
  4065. } // doSave()
  4066. ";
  4067. }
  4068. /**
  4069. * get the doInsert() method code
  4070. *
  4071. * @return string the doInsert() method code
  4072. */
  4073. protected function addDoInsert()
  4074. {
  4075. $table = $this->getTable();
  4076. $script = "
  4077. /**
  4078. * Insert the row in the database.
  4079. *
  4080. * @param PropelPDO \$con
  4081. *
  4082. * @throws PropelException
  4083. * @see doSave()
  4084. */
  4085. protected function doInsert(PropelPDO \$con)
  4086. {";
  4087. if ($this->getPlatform() instanceof MssqlPlatform) {
  4088. if ($table->hasAutoIncrementPrimaryKey() ) {
  4089. $script .= "
  4090. \$this->modifiedColumns[] = " . $this->getColumnConstant($table->getAutoIncrementPrimaryKey() ) . ";";
  4091. }
  4092. $script .= "
  4093. \$criteria = \$this->buildCriteria();";
  4094. if ($this->getTable()->getIdMethod() != IDMethod::NO_ID_METHOD) {
  4095. $script .= $this->addDoInsertBodyWithIdMethod();
  4096. } else {
  4097. $script .= $this->addDoInsertBodyStandard();
  4098. }
  4099. } else {
  4100. $script .= $this->addDoInsertBodyRaw();
  4101. }
  4102. $script .= "
  4103. \$this->setNew(false);
  4104. }
  4105. ";
  4106. return $script;
  4107. }
  4108. protected function addDoInsertBodyStandard()
  4109. {
  4110. return "
  4111. \$pk = " . $this->getNewPeerBuilder($this->getTable())->getBasePeerClassname() . "::doInsert(\$criteria, \$con);";
  4112. }
  4113. protected function addDoInsertBodyWithIdMethod()
  4114. {
  4115. $table = $this->getTable();
  4116. $reloadOnInsert = $table->isReloadOnInsert();
  4117. $basePeerClassname = $this->getNewPeerBuilder($table)->getBasePeerClassname();
  4118. $script = '';
  4119. foreach ($table->getPrimaryKey() as $col) {
  4120. if (!$col->isAutoIncrement()) {
  4121. continue;
  4122. }
  4123. $colConst = $this->getColumnConstant($col);
  4124. if (!$table->isAllowPkInsert()) {
  4125. $script .= "
  4126. if (\$criteria->keyContainsValue($colConst) ) {
  4127. throw new PropelException('Cannot insert a value for auto-increment primary key (' . $colConst . ')');
  4128. }";
  4129. if (!$this->getPlatform()->supportsInsertNullPk()) {
  4130. $script .= "
  4131. // remove pkey col since this table uses auto-increment and passing a null value for it is not valid
  4132. \$criteria->remove($colConst);";
  4133. }
  4134. } elseif (!$this->getPlatform()->supportsInsertNullPk()) {
  4135. $script .= "
  4136. // remove pkey col if it is null since this table does not accept that
  4137. if (\$criteria->containsKey($colConst) && !\$criteria->keyContainsValue($colConst) ) {
  4138. \$criteria->remove($colConst);
  4139. }";
  4140. }
  4141. }
  4142. $script .= $this->addDoInsertBodyStandard();
  4143. foreach ($table->getPrimaryKey() as $col) {
  4144. if (!$col->isAutoIncrement()) {
  4145. continue;
  4146. }
  4147. if ($table->isAllowPkInsert()) {
  4148. $script .= "
  4149. if (\$pk !== null) {
  4150. \$this->set".$col->getPhpName()."(\$pk); //[IMV] update autoincrement primary key
  4151. }";
  4152. } else {
  4153. $script .= "
  4154. \$this->set".$col->getPhpName()."(\$pk); //[IMV] update autoincrement primary key";
  4155. }
  4156. }
  4157. return $script;
  4158. }
  4159. /**
  4160. * Boosts ActiveRecord::doInsert() by doing more calculations at buildtime.
  4161. */
  4162. protected function addDoInsertBodyRaw()
  4163. {
  4164. $this->declareClasses('Propel', 'PDO');
  4165. $table = $this->getTable();
  4166. $peerClassname = $this->getPeerClassname();
  4167. $platform = $this->getPlatform();
  4168. $primaryKeyMethodInfo = '';
  4169. if ($table->getIdMethodParameters()) {
  4170. $params = $table->getIdMethodParameters();
  4171. $imp = $params[0];
  4172. $primaryKeyMethodInfo = $imp->getValue();
  4173. } elseif ($table->getIdMethod() == IDMethod::NATIVE && ($platform->getNativeIdMethod() == PropelPlatformInterface::SEQUENCE || $platform->getNativeIdMethod() == PropelPlatformInterface::SERIAL)) {
  4174. $primaryKeyMethodInfo = $platform->getSequenceName($table);
  4175. }
  4176. $query = 'INSERT INTO ' . $platform->quoteIdentifier($table->getName()) . ' (%s) VALUES (%s)';
  4177. $script = "
  4178. \$modifiedColumns = array();
  4179. \$index = 0;
  4180. ";
  4181. foreach ($table->getPrimaryKey() as $column) {
  4182. if (!$column->isAutoIncrement()) {
  4183. continue;
  4184. }
  4185. $constantName = $this->getColumnConstant($column);
  4186. if ($platform->supportsInsertNullPk()) {
  4187. $script .= "
  4188. \$this->modifiedColumns[] = $constantName;";
  4189. }
  4190. $columnProperty = strtolower($column->getName());
  4191. if (!$table->isAllowPkInsert()) {
  4192. $script .= "
  4193. if (null !== \$this->{$columnProperty}) {
  4194. throw new PropelException('Cannot insert a value for auto-increment primary key (' . $constantName . ')');
  4195. }";
  4196. } elseif (!$platform->supportsInsertNullPk()) {
  4197. $script .= "
  4198. // add primary key column only if it is not null since this database does not accept that
  4199. if (null !== \$this->{$columnProperty}) {
  4200. \$this->modifiedColumns[] = $constantName;
  4201. }";
  4202. }
  4203. }
  4204. // if non auto-increment but using sequence, get the id first
  4205. if (!$platform->isNativeIdMethodAutoIncrement() && $table->getIdMethod() == "native") {
  4206. $column = $table->getFirstPrimaryKeyColumn();
  4207. $columnProperty = strtolower($column->getName());
  4208. $script .= "
  4209. if (null === \$this->{$columnProperty}) {
  4210. try {";
  4211. $script .= $platform->getIdentifierPhp('$this->'. $columnProperty, '$con', $primaryKeyMethodInfo, ' ');
  4212. $script .= "
  4213. } catch (Exception \$e) {
  4214. throw new PropelException('Unable to get sequence id.', \$e);
  4215. }
  4216. }
  4217. ";
  4218. }
  4219. $script .= "
  4220. // check the columns in natural order for more readable SQL queries";
  4221. foreach ($table->getColumns() as $column) {
  4222. $constantName = $this->getColumnConstant($column);
  4223. $identifier = var_export($platform->quoteIdentifier(strtoupper($column->getName())), true);
  4224. $script .= "
  4225. if (\$this->isColumnModified($constantName)) {
  4226. \$modifiedColumns[':p' . \$index++] = $identifier;
  4227. }";
  4228. }
  4229. $script .= "
  4230. \$sql = sprintf(
  4231. '$query',
  4232. implode(', ', \$modifiedColumns),
  4233. implode(', ', array_keys(\$modifiedColumns))
  4234. );
  4235. try {
  4236. \$stmt = \$con->prepare(\$sql);
  4237. foreach (\$modifiedColumns as \$identifier => \$columnName) {
  4238. switch (\$columnName) {";
  4239. foreach ($table->getColumns() as $column) {
  4240. $columnNameCase = var_export($platform->quoteIdentifier(strtoupper($column->getName())), true);
  4241. $script .= "
  4242. case $columnNameCase:";
  4243. $script .= $platform->getColumnBindingPHP($column, "\$identifier", '$this->' . strtolower($column->getName()), ' ');
  4244. $script .= "
  4245. break;";
  4246. }
  4247. $script .= "
  4248. }
  4249. }
  4250. \$stmt->execute();
  4251. } catch (Exception \$e) {
  4252. Propel::log(\$e->getMessage(), Propel::LOG_ERR);
  4253. throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', \$sql), \$e);
  4254. }
  4255. ";
  4256. // if auto-increment, get the id after
  4257. if ($platform->isNativeIdMethodAutoIncrement() && $table->getIdMethod() == "native") {
  4258. $column = $table->getFirstPrimaryKeyColumn();
  4259. $columnProperty = strtolower($column->getName());
  4260. $script .= "
  4261. try {";
  4262. $script .= $platform->getIdentifierPhp('$pk', '$con', $primaryKeyMethodInfo);
  4263. $script .= "
  4264. } catch (Exception \$e) {
  4265. throw new PropelException('Unable to get autoincrement id.', \$e);
  4266. }";
  4267. if ($table->isAllowPkInsert()) {
  4268. $script .= "
  4269. if (\$pk !== null) {
  4270. \$this->set".$column->getPhpName()."(\$pk);
  4271. }";
  4272. } else {
  4273. $script .= "
  4274. \$this->set".$column->getPhpName()."(\$pk);";
  4275. }
  4276. $script .= "
  4277. ";
  4278. }
  4279. return $script;
  4280. }
  4281. /**
  4282. * get the doUpdate() method code
  4283. *
  4284. * @return string the doUpdate() method code
  4285. */
  4286. protected function addDoUpdate()
  4287. {
  4288. $basePeerClassname = $this->getNewPeerBuilder($this->getTable())->getBasePeerClassname();
  4289. return "
  4290. /**
  4291. * Update the row in the database.
  4292. *
  4293. * @param PropelPDO \$con
  4294. *
  4295. * @see doSave()
  4296. */
  4297. protected function doUpdate(PropelPDO \$con)
  4298. {
  4299. \$selectCriteria = \$this->buildPkeyCriteria();
  4300. \$valuesCriteria = \$this->buildCriteria();
  4301. {$basePeerClassname}::doUpdate(\$selectCriteria, \$valuesCriteria, \$con);
  4302. }
  4303. ";
  4304. }
  4305. /**
  4306. * Adds the $alreadyInSave attribute, which prevents attempting to re-save the same object.
  4307. * @param string &$script The script will be modified in this method.
  4308. */
  4309. protected function addAlreadyInSaveAttribute(&$script)
  4310. {
  4311. $script .= "
  4312. /**
  4313. * Flag to prevent endless save loop, if this object is referenced
  4314. * by another object which falls in this transaction.
  4315. * @var boolean
  4316. */
  4317. protected \$alreadyInSave = false;
  4318. ";
  4319. }
  4320. /**
  4321. * Adds the save() method.
  4322. * @param string &$script The script will be modified in this method.
  4323. */
  4324. protected function addSave(&$script)
  4325. {
  4326. $this->addSaveComment($script);
  4327. $this->addSaveOpen($script);
  4328. $this->addSaveBody($script);
  4329. $this->addSaveClose($script);
  4330. }
  4331. /**
  4332. * Adds the comment for the save method
  4333. * @param string &$script The script will be modified in this method.
  4334. * @see addSave()
  4335. **/
  4336. protected function addSaveComment(&$script)
  4337. {
  4338. $table = $this->getTable();
  4339. $reloadOnUpdate = $table->isReloadOnUpdate();
  4340. $reloadOnInsert = $table->isReloadOnInsert();
  4341. $script .= "
  4342. /**
  4343. * Persists this object to the database.
  4344. *
  4345. * If the object is new, it inserts it; otherwise an update is performed.
  4346. * All modified related objects will also be persisted in the doSave()
  4347. * method. This method wraps all precipitate database operations in a
  4348. * single transaction.";
  4349. if ($reloadOnUpdate) {
  4350. $script .= "
  4351. *
  4352. * Since this table was configured to reload rows on update, the object will
  4353. * be reloaded from the database if an UPDATE operation is performed (unless
  4354. * the \$skipReload parameter is TRUE).";
  4355. }
  4356. if ($reloadOnInsert) {
  4357. $script .= "
  4358. *
  4359. * Since this table was configured to reload rows on insert, the object will
  4360. * be reloaded from the database if an INSERT operation is performed (unless
  4361. * the \$skipReload parameter is TRUE).";
  4362. }
  4363. $script .= "
  4364. *
  4365. * @param PropelPDO \$con";
  4366. if ($reloadOnUpdate || $reloadOnInsert) {
  4367. $script .= "
  4368. * @param boolean \$skipReload Whether to skip the reload for this object from database.";
  4369. }
  4370. $script .= "
  4371. * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations.
  4372. * @throws PropelException
  4373. * @throws Exception
  4374. * @see doSave()
  4375. */";
  4376. }
  4377. /**
  4378. * Adds the function declaration for the save method
  4379. * @param string &$script The script will be modified in this method.
  4380. * @see addSave()
  4381. **/
  4382. protected function addSaveOpen(&$script)
  4383. {
  4384. $table = $this->getTable();
  4385. $reloadOnUpdate = $table->isReloadOnUpdate();
  4386. $reloadOnInsert = $table->isReloadOnInsert();
  4387. $script .= "
  4388. public function save(PropelPDO \$con = null".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
  4389. {";
  4390. }
  4391. /**
  4392. * Adds the function body for the save method
  4393. * @param string &$script The script will be modified in this method.
  4394. * @see addSave()
  4395. **/
  4396. protected function addSaveBody(&$script)
  4397. {
  4398. $table = $this->getTable();
  4399. $reloadOnUpdate = $table->isReloadOnUpdate();
  4400. $reloadOnInsert = $table->isReloadOnInsert();
  4401. $script .= "
  4402. if (\$this->isDeleted()) {
  4403. throw new PropelException(\"You cannot save an object that has been deleted.\");
  4404. }
  4405. if (\$con === null) {
  4406. \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
  4407. }
  4408. \$con->beginTransaction();
  4409. \$isInsert = \$this->isNew();
  4410. try {";
  4411. if ($this->getGeneratorConfig()->getBuildProperty('addHooks')) {
  4412. // save with runtime hools
  4413. $script .= "
  4414. \$ret = \$this->preSave(\$con);";
  4415. $this->applyBehaviorModifier('preSave', $script, " ");
  4416. $script .= "
  4417. if (\$isInsert) {
  4418. \$ret = \$ret && \$this->preInsert(\$con);";
  4419. $this->applyBehaviorModifier('preInsert', $script, " ");
  4420. $script .= "
  4421. } else {
  4422. \$ret = \$ret && \$this->preUpdate(\$con);";
  4423. $this->applyBehaviorModifier('preUpdate', $script, " ");
  4424. $script .= "
  4425. }
  4426. if (\$ret) {
  4427. \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");
  4428. if (\$isInsert) {
  4429. \$this->postInsert(\$con);";
  4430. $this->applyBehaviorModifier('postInsert', $script, " ");
  4431. $script .= "
  4432. } else {
  4433. \$this->postUpdate(\$con);";
  4434. $this->applyBehaviorModifier('postUpdate', $script, " ");
  4435. $script .= "
  4436. }
  4437. \$this->postSave(\$con);";
  4438. $this->applyBehaviorModifier('postSave', $script, " ");
  4439. $script .= "
  4440. ".$this->getPeerClassname()."::addInstanceToPool(\$this);
  4441. } else {
  4442. \$affectedRows = 0;
  4443. }
  4444. \$con->commit();
  4445. return \$affectedRows;";
  4446. } else {
  4447. // save without runtime hooks
  4448. $this->applyBehaviorModifier('preSave', $script, " ");
  4449. if ($this->hasBehaviorModifier('preUpdate')) {
  4450. $script .= "
  4451. if (!\$isInsert) {";
  4452. $this->applyBehaviorModifier('preUpdate', $script, " ");
  4453. $script .= "
  4454. }";
  4455. }
  4456. if ($this->hasBehaviorModifier('preInsert')) {
  4457. $script .= "
  4458. if (\$isInsert) {";
  4459. $this->applyBehaviorModifier('preInsert', $script, " ");
  4460. $script .= "
  4461. }";
  4462. }
  4463. $script .= "
  4464. \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");";
  4465. $this->applyBehaviorModifier('postSave', $script, " ");
  4466. if ($this->hasBehaviorModifier('postUpdate')) {
  4467. $script .= "
  4468. if (!\$isInsert) {";
  4469. $this->applyBehaviorModifier('postUpdate', $script, " ");
  4470. $script .= "
  4471. }";
  4472. }
  4473. if ($this->hasBehaviorModifier('postInsert')) {
  4474. $script .= "
  4475. if (\$isInsert) {";
  4476. $this->applyBehaviorModifier('postInsert', $script, " ");
  4477. $script .= "
  4478. }";
  4479. }
  4480. $script .= "
  4481. \$con->commit();
  4482. ".$this->getPeerClassname()."::addInstanceToPool(\$this);
  4483. return \$affectedRows;";
  4484. }
  4485. $script .= "
  4486. } catch (Exception \$e) {
  4487. \$con->rollBack();
  4488. throw \$e;
  4489. }";
  4490. }
  4491. /**
  4492. * Adds the function close for the save method
  4493. * @param string &$script The script will be modified in this method.
  4494. * @see addSave()
  4495. **/
  4496. protected function addSaveClose(&$script)
  4497. {
  4498. $script .= "
  4499. }
  4500. ";
  4501. }
  4502. /**
  4503. * Adds the $alreadyInValidation attribute, which prevents attempting to re-validate the same object.
  4504. * @param string &$script The script will be modified in this method.
  4505. */
  4506. protected function addAlreadyInValidationAttribute(&$script)
  4507. {
  4508. $script .= "
  4509. /**
  4510. * Flag to prevent endless validation loop, if this object is referenced
  4511. * by another object which falls in this transaction.
  4512. * @var boolean
  4513. */
  4514. protected \$alreadyInValidation = false;
  4515. ";
  4516. }
  4517. /**
  4518. * Adds the validate() method.
  4519. * @param string &$script The script will be modified in this method.
  4520. */
  4521. protected function addValidate(&$script)
  4522. {
  4523. $script .= "
  4524. /**
  4525. * Validates the objects modified field values and all objects related to this table.
  4526. *
  4527. * If \$columns is either a column name or an array of column names
  4528. * only those columns are validated.
  4529. *
  4530. * @param mixed \$columns Column name or an array of column names.
  4531. * @return boolean Whether all columns pass validation.
  4532. * @see doValidate()
  4533. * @see getValidationFailures()
  4534. */
  4535. public function validate(\$columns = null)
  4536. {
  4537. \$res = \$this->doValidate(\$columns);
  4538. if (\$res === true) {
  4539. \$this->validationFailures = array();
  4540. return true;
  4541. } else {
  4542. \$this->validationFailures = \$res;
  4543. return false;
  4544. }
  4545. }
  4546. ";
  4547. } // addValidate()
  4548. /**
  4549. * Adds the workhourse doValidate() method.
  4550. * @param string &$script The script will be modified in this method.
  4551. */
  4552. protected function addDoValidate(&$script)
  4553. {
  4554. $table = $this->getTable();
  4555. $script .= "
  4556. /**
  4557. * This function performs the validation work for complex object models.
  4558. *
  4559. * In addition to checking the current object, all related objects will
  4560. * also be validated. If all pass then <code>true</code> is returned; otherwise
  4561. * an aggreagated array of ValidationFailed objects will be returned.
  4562. *
  4563. * @param array \$columns Array of column names to validate.
  4564. * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise.
  4565. */
  4566. protected function doValidate(\$columns = null)
  4567. {
  4568. if (!\$this->alreadyInValidation) {
  4569. \$this->alreadyInValidation = true;
  4570. \$retval = null;
  4571. \$failureMap = array();
  4572. ";
  4573. if (count($table->getForeignKeys()) != 0) {
  4574. $script .= "
  4575. // We call the validate method on the following object(s) if they
  4576. // were passed to this object by their coresponding set
  4577. // method. This object relates to these object(s) by a
  4578. // foreign key reference.
  4579. ";
  4580. foreach ($table->getForeignKeys() as $fk) {
  4581. $aVarName = $this->getFKVarName($fk);
  4582. $script .= "
  4583. if (\$this->".$aVarName." !== null) {
  4584. if (!\$this->".$aVarName."->validate(\$columns)) {
  4585. \$failureMap = array_merge(\$failureMap, \$this->".$aVarName."->getValidationFailures());
  4586. }
  4587. }
  4588. ";
  4589. } /* for () */
  4590. } /* if count(fkeys) */
  4591. $script .= "
  4592. if ((\$retval = ".$this->getPeerClassname()."::doValidate(\$this, \$columns)) !== true) {
  4593. \$failureMap = array_merge(\$failureMap, \$retval);
  4594. }
  4595. ";
  4596. foreach ($table->getReferrers() as $refFK) {
  4597. if ($refFK->isLocalPrimaryKey()) {
  4598. $varName = $this->getPKRefFKVarName($refFK);
  4599. $script .= "
  4600. if (\$this->$varName !== null) {
  4601. if (!\$this->".$varName."->validate(\$columns)) {
  4602. \$failureMap = array_merge(\$failureMap, \$this->".$varName."->getValidationFailures());
  4603. }
  4604. }
  4605. ";
  4606. } else {
  4607. $collName = $this->getRefFKCollVarName($refFK);
  4608. $script .= "
  4609. if (\$this->$collName !== null) {
  4610. foreach (\$this->$collName as \$referrerFK) {
  4611. if (!\$referrerFK->validate(\$columns)) {
  4612. \$failureMap = array_merge(\$failureMap, \$referrerFK->getValidationFailures());
  4613. }
  4614. }
  4615. }
  4616. ";
  4617. }
  4618. } /* foreach getReferrers() */
  4619. $script .= "
  4620. \$this->alreadyInValidation = false;
  4621. }
  4622. return (!empty(\$failureMap) ? \$failureMap : true);
  4623. }
  4624. ";
  4625. } // addDoValidate()
  4626. /**
  4627. * Adds the ensureConsistency() method to ensure that internal state is correct.
  4628. * @param string &$script The script will be modified in this method.
  4629. */
  4630. protected function addEnsureConsistency(&$script)
  4631. {
  4632. $table = $this->getTable();
  4633. $script .= "
  4634. /**
  4635. * Checks and repairs the internal consistency of the object.
  4636. *
  4637. * This method is executed after an already-instantiated object is re-hydrated
  4638. * from the database. It exists to check any foreign keys to make sure that
  4639. * the objects related to the current object are correct based on foreign key.
  4640. *
  4641. * You can override this method in the stub class, but you should always invoke
  4642. * the base method from the overridden method (i.e. parent::ensureConsistency()),
  4643. * in case your model changes.
  4644. *
  4645. * @throws PropelException
  4646. */
  4647. public function ensureConsistency()
  4648. {
  4649. ";
  4650. foreach ($table->getColumns() as $col) {
  4651. $clo=strtolower($col->getName());
  4652. if ($col->isForeignKey()) {
  4653. foreach ($col->getForeignKeys() as $fk) {
  4654. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  4655. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  4656. $varName = $this->getFKVarName($fk);
  4657. $script .= "
  4658. if (\$this->".$varName." !== null && \$this->$clo !== \$this->".$varName."->get".$colFK->getPhpName()."()) {
  4659. \$this->$varName = null;
  4660. }";
  4661. } // foraech
  4662. } /* if col is foreign key */
  4663. } // foreach
  4664. $script .= "
  4665. } // ensureConsistency
  4666. ";
  4667. } // addCheckRelConsistency
  4668. /**
  4669. * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects.
  4670. * @param string &$script The script will be modified in this method.
  4671. */
  4672. protected function addCopy(&$script)
  4673. {
  4674. $this->addCopyInto($script);
  4675. $table = $this->getTable();
  4676. $script .= "
  4677. /**
  4678. * Makes a copy of this object that will be inserted as a new row in table when saved.
  4679. * It creates a new object filling in the simple attributes, but skipping any primary
  4680. * keys that are defined for the table.
  4681. *
  4682. * If desired, this method can also make copies of all associated (fkey referrers)
  4683. * objects.
  4684. *
  4685. * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
  4686. * @return ".$this->getObjectClassname()." Clone of current object.
  4687. * @throws PropelException
  4688. */
  4689. public function copy(\$deepCopy = false)
  4690. {
  4691. // we use get_class(), because this might be a subclass
  4692. \$clazz = get_class(\$this);
  4693. " . $this->buildObjectInstanceCreationCode('$copyObj', '$clazz') . "
  4694. \$this->copyInto(\$copyObj, \$deepCopy);
  4695. return \$copyObj;
  4696. }
  4697. ";
  4698. } // addCopy()
  4699. /**
  4700. * Adds the copyInto() method, which takes an object and sets contents to match current object.
  4701. * In complex OM this method includes the $deepCopy param for making copies of related objects.
  4702. * @param string &$script The script will be modified in this method.
  4703. */
  4704. protected function addCopyInto(&$script)
  4705. {
  4706. $table = $this->getTable();
  4707. $script .= "
  4708. /**
  4709. * Sets contents of passed object to values from current object.
  4710. *
  4711. * If desired, this method can also make copies of all associated (fkey referrers)
  4712. * objects.
  4713. *
  4714. * @param object \$copyObj An object of ".$this->getObjectClassname()." (or compatible) type.
  4715. * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
  4716. * @param boolean \$makeNew Whether to reset autoincrement PKs and make the object new.
  4717. * @throws PropelException
  4718. */
  4719. public function copyInto(\$copyObj, \$deepCopy = false, \$makeNew = true)
  4720. {";
  4721. $autoIncCols = array();
  4722. if ($table->hasCompositePrimaryKey()) {
  4723. foreach ($table->getColumns() as $col) {
  4724. /* @var $col Column */
  4725. if ($col->isAutoIncrement()) {
  4726. $autoIncCols[] = $col;
  4727. }
  4728. }
  4729. } else {
  4730. $autoIncCols = $table->getPrimaryKey();
  4731. }
  4732. foreach ($table->getColumns() as $col) {
  4733. if (!in_array($col, $autoIncCols, true)) {
  4734. $script .= "
  4735. \$copyObj->set".$col->getPhpName()."(\$this->get".$col->getPhpName()."());";
  4736. }
  4737. } // foreach
  4738. // Avoid useless code by checking to see if there are any referrers
  4739. // to this table:
  4740. if (count($table->getReferrers()) > 0 || count($table->getForeignKeys()) > 0 ) {
  4741. $script .= "
  4742. if (\$deepCopy && !\$this->startCopy) {
  4743. // important: temporarily setNew(false) because this affects the behavior of
  4744. // the getter/setter methods for fkey referrer objects.
  4745. \$copyObj->setNew(false);
  4746. // store object hash to prevent cycle
  4747. \$this->startCopy = true;
  4748. ";
  4749. foreach ($table->getReferrers() as $fk) {
  4750. //HL: commenting out self-referrential check below
  4751. // it seems to work as expected and is probably desireable to have those referrers from same table deep-copied.
  4752. //if ( $fk->getTable()->getName() != $table->getName() ) {
  4753. if ($fk->isLocalPrimaryKey()) {
  4754. $afx = $this->getRefFKPhpNameAffix($fk, $plural = false);
  4755. $script .= "
  4756. \$relObj = \$this->get$afx();
  4757. if (\$relObj) {
  4758. \$copyObj->set$afx(\$relObj->copy(\$deepCopy));
  4759. }
  4760. ";
  4761. } else {
  4762. $script .= "
  4763. foreach (\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {
  4764. if (\$relObj !== \$this) { // ensure that we don't try to copy a reference to ourselves
  4765. \$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy));
  4766. }
  4767. }
  4768. ";
  4769. }
  4770. // HL: commenting out close of self-referential check
  4771. // } /* if tblFK != table */
  4772. } /* foreach */
  4773. // do deep copy for one to one relation
  4774. foreach ($table->getForeignKeys() as $fk) {
  4775. if ($fk->isLocalPrimaryKey()) {
  4776. $afx = $this->getFKPhpNameAffix($fk, $plural = false);
  4777. $script .= "
  4778. \$relObj = \$this->get$afx();
  4779. if (\$relObj) {
  4780. \$copyObj->set$afx(\$relObj->copy(\$deepCopy));
  4781. }
  4782. ";
  4783. }
  4784. }
  4785. $script .= "
  4786. //unflag object copy
  4787. \$this->startCopy = false;
  4788. } // if (\$deepCopy)
  4789. ";
  4790. } /* if (count referrers > 0 ) */
  4791. $script .= "
  4792. if (\$makeNew) {
  4793. \$copyObj->setNew(true);";
  4794. // Note: we're no longer resetting non-autoincrement primary keys to default values
  4795. // due to: http://propel.phpdb.org/trac/ticket/618
  4796. foreach ($autoIncCols as $col) {
  4797. $coldefval = $col->getPhpDefaultValue();
  4798. $coldefval = var_export($coldefval, true);
  4799. $script .= "
  4800. \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a auto-increment column, so set to default value";
  4801. } // foreach
  4802. $script .= "
  4803. }
  4804. }
  4805. ";
  4806. } // addCopyInto()
  4807. /**
  4808. * Adds clear method
  4809. * @param string &$script The script will be modified in this method.
  4810. */
  4811. protected function addClear(&$script)
  4812. {
  4813. $table = $this->getTable();
  4814. $script .= "
  4815. /**
  4816. * Clears the current object and sets all attributes to their default values
  4817. */
  4818. public function clear()
  4819. {";
  4820. foreach ($table->getColumns() as $col) {
  4821. $clo = strtolower($col->getName());
  4822. $script .= "
  4823. \$this->".$clo." = null;";
  4824. if ($col->isLazyLoad()) {
  4825. $script .= "
  4826. \$this->".$clo."_isLoaded = false;";
  4827. }
  4828. if ($col->getType() == PropelTypes::OBJECT || $col->getType() == PropelTypes::PHP_ARRAY) {
  4829. $cloUnserialized = $clo.'_unserialized';
  4830. $script .="
  4831. \$this->$cloUnserialized = null;";
  4832. }
  4833. }
  4834. $script .= "
  4835. \$this->alreadyInSave = false;
  4836. \$this->alreadyInValidation = false;
  4837. \$this->clearAllReferences();";
  4838. if ($this->hasDefaultValues()) {
  4839. $script .= "
  4840. \$this->applyDefaultValues();";
  4841. }
  4842. $script .= "
  4843. \$this->resetModified();
  4844. \$this->setNew(true);
  4845. \$this->setDeleted(false);
  4846. }
  4847. ";
  4848. }
  4849. /**
  4850. * Adds clearAllReferencers() method which resets all the collections of referencing
  4851. * fk objects.
  4852. * @param string &$script The script will be modified in this method.
  4853. */
  4854. protected function addClearAllReferences(&$script)
  4855. {
  4856. $table = $this->getTable();
  4857. $script .= "
  4858. /**
  4859. * Resets all references to other model objects or collections of model objects.
  4860. *
  4861. * This method is a user-space workaround for PHP's inability to garbage collect
  4862. * objects with circular references (even in PHP 5.3). This is currently necessary
  4863. * when using Propel in certain daemon or large-volumne/high-memory operations.
  4864. *
  4865. * @param boolean \$deep Whether to also clear the references on all referrer objects.
  4866. */
  4867. public function clearAllReferences(\$deep = false)
  4868. {
  4869. if (\$deep) {";
  4870. $vars = array();
  4871. foreach ($this->getTable()->getReferrers() as $refFK) {
  4872. if ($refFK->isLocalPrimaryKey()) {
  4873. $varName = $this->getPKRefFKVarName($refFK);
  4874. $script .= "
  4875. if (\$this->$varName) {
  4876. \$this->{$varName}->clearAllReferences(\$deep);
  4877. }";
  4878. } else {
  4879. $varName = $this->getRefFKCollVarName($refFK);
  4880. $script .= "
  4881. if (\$this->$varName) {
  4882. foreach (\$this->$varName as \$o) {
  4883. \$o->clearAllReferences(\$deep);
  4884. }
  4885. }";
  4886. }
  4887. $vars[] = $varName;
  4888. }
  4889. foreach ($this->getTable()->getCrossFks() as $fkList) {
  4890. list($refFK, $crossFK) = $fkList;
  4891. $varName = $this->getCrossFKVarName($crossFK);
  4892. $script .= "
  4893. if (\$this->$varName) {
  4894. foreach (\$this->$varName as \$o) {
  4895. \$o->clearAllReferences(\$deep);
  4896. }
  4897. }";
  4898. $vars[] = $varName;
  4899. }
  4900. $script .= "
  4901. } // if (\$deep)
  4902. ";
  4903. $this->applyBehaviorModifier('objectClearReferences', $script, " ");
  4904. foreach ($vars as $varName) {
  4905. $script .= "
  4906. if (\$this->$varName instanceof PropelCollection) {
  4907. \$this->{$varName}->clearIterator();
  4908. }
  4909. \$this->$varName = null;";
  4910. }
  4911. foreach ($table->getForeignKeys() as $fk) {
  4912. $varName = $this->getFKVarName($fk);
  4913. $script .= "
  4914. \$this->$varName = null;";
  4915. }
  4916. $script .= "
  4917. }
  4918. ";
  4919. }
  4920. /**
  4921. * Adds a magic __toString() method if a string column was defined as primary string
  4922. * @param string &$script The script will be modified in this method.
  4923. */
  4924. protected function addPrimaryString(&$script)
  4925. {
  4926. foreach ($this->getTable()->getColumns() as $column) {
  4927. if ($column->isPrimaryString()) {
  4928. $script .= "
  4929. /**
  4930. * Return the string representation of this object
  4931. *
  4932. * @return string The value of the '{$column->getName()}' column
  4933. */
  4934. public function __toString()
  4935. {
  4936. return (string) \$this->get{$column->getPhpName()}();
  4937. }
  4938. ";
  4939. return;
  4940. }
  4941. }
  4942. // no primary string column, falling back to default string format
  4943. $script .= "
  4944. /**
  4945. * Return the string representation of this object
  4946. *
  4947. * @return string
  4948. */
  4949. public function __toString()
  4950. {
  4951. return (string) \$this->exportTo(" . $this->getPeerClassname() . "::DEFAULT_STRING_FORMAT);
  4952. }
  4953. ";
  4954. }
  4955. /**
  4956. * Adds a magic __call() method
  4957. * @param string &$script The script will be modified in this method.
  4958. */
  4959. protected function addMagicCall(&$script)
  4960. {
  4961. $behaviorCallScript = '';
  4962. $this->applyBehaviorModifier('objectCall', $behaviorCallScript, " ");
  4963. if ($behaviorCallScript) {
  4964. $script .= "
  4965. /**
  4966. * Catches calls to virtual methods
  4967. */
  4968. public function __call(\$name, \$params)
  4969. {
  4970. $behaviorCallScript
  4971. return parent::__call(\$name, \$params);
  4972. }
  4973. ";
  4974. }
  4975. }
  4976. protected function addIsAlreadyInSave(&$script)
  4977. {
  4978. $script .= "
  4979. /**
  4980. * return true is the object is in saving state
  4981. *
  4982. * @return boolean
  4983. */
  4984. public function isAlreadyInSave()
  4985. {
  4986. return \$this->alreadyInSave;
  4987. }
  4988. ";
  4989. }
  4990. } // PHP5ObjectBuilder