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

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

https://github.com/1989gaurav/Propel
PHP | 1613 lines | 897 code | 165 blank | 551 comment | 114 complexity | e0faddfe758dfd1f6d7831f39452696a MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/ObjectBuilder.php';
  10. /**
  11. * Generates a PHP5 base Object class for user object model (OM).
  12. *
  13. * This class produces the base object class (e.g. BaseMyTable) which contains all
  14. * the custom-built accessor and setter methods.
  15. *
  16. * @author Hans Lellelid <hans@xmpl.org>
  17. * @package propel.generator.builder.om
  18. */
  19. class PHP5ObjectBuilder extends ObjectBuilder
  20. {
  21. /**
  22. * Gets the package for the [base] object classes.
  23. * @return string
  24. */
  25. public function getPackage()
  26. {
  27. return parent::getPackage() . ".om";
  28. }
  29. public function getNamespace()
  30. {
  31. if ($namespace = parent::getNamespace()) {
  32. if ($this->getGeneratorConfig() && $omns = $this->getGeneratorConfig()->getBuildProperty('namespaceOm')) {
  33. return $namespace . '\\' . $omns;
  34. } else {
  35. return $namespace;
  36. }
  37. }
  38. }
  39. /**
  40. * Returns the name of the current class being built.
  41. * @return string
  42. */
  43. public function getUnprefixedClassname()
  44. {
  45. return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname();
  46. }
  47. /**
  48. * Validates the current table to make sure that it won't
  49. * result in generated code that will not parse.
  50. *
  51. * This method may emit warnings for code which may cause problems
  52. * and will throw exceptions for errors that will definitely cause
  53. * problems.
  54. */
  55. protected function validateModel()
  56. {
  57. parent::validateModel();
  58. $table = $this->getTable();
  59. // Check to see whether any generated foreign key names
  60. // will conflict with column names.
  61. $colPhpNames = array();
  62. $fkPhpNames = array();
  63. foreach ($table->getColumns() as $col) {
  64. $colPhpNames[] = $col->getPhpName();
  65. }
  66. foreach ($table->getForeignKeys() as $fk) {
  67. $fkPhpNames[] = $this->getFKPhpNameAffix($fk, $plural = false);
  68. }
  69. $intersect = array_intersect($colPhpNames, $fkPhpNames);
  70. if (!empty($intersect)) {
  71. throw new EngineException("One or more of your column names for [" . $table->getName() . "] table conflict with foreign key names (" . implode(", ", $intersect) . ")");
  72. }
  73. // Check foreign keys to see if there are any foreign keys that
  74. // are also matched with an inversed referencing foreign key
  75. // (this is currently unsupported behavior)
  76. // see: http://propel.phpdb.org/trac/ticket/549
  77. foreach ($table->getForeignKeys() as $fk) {
  78. if ($fk->isMatchedByInverseFK()) {
  79. throw new EngineException("The 1:1 relationship expressed by foreign key " . $fk->getName() . " is defined in both directions; Propel does not currently support this (if you must have both foreign key constraints, consider adding this constraint with a custom SQL file.)" );
  80. }
  81. }
  82. }
  83. /**
  84. * Returns the appropriate formatter (from platform) for a date/time column.
  85. * @param Column $col
  86. * @return string
  87. */
  88. protected function getTemporalFormatter(Column $col)
  89. {
  90. $fmt = null;
  91. if ($col->getType() === PropelTypes::DATE) {
  92. $fmt = $this->getPlatform()->getDateFormatter();
  93. } elseif ($col->getType() === PropelTypes::TIME) {
  94. $fmt = $this->getPlatform()->getTimeFormatter();
  95. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  96. $fmt = $this->getPlatform()->getTimestampFormatter();
  97. }
  98. return $fmt;
  99. }
  100. /**
  101. * Returns the type-casted and stringified default value for the specified Column.
  102. * This only works for scalar default values currently.
  103. * @return string The default value or 'NULL' if there is none.
  104. */
  105. protected function getDefaultValueString(Column $col)
  106. {
  107. $defaultValue = var_export(null, true);
  108. $val = $col->getPhpDefaultValue();
  109. if ($val === null) {
  110. return $defaultValue;
  111. }
  112. if ($col->isTemporalType()) {
  113. $fmt = $this->getTemporalFormatter($col);
  114. try {
  115. if (!($this->getPlatform() instanceof MysqlPlatform &&
  116. ($val === '0000-00-00 00:00:00' || $val === '0000-00-00'))) {
  117. // while technically this is not a default value of NULL,
  118. // this seems to be closest in meaning.
  119. $defDt = new DateTime($val);
  120. $defaultValue = var_export($defDt->format($fmt), true);
  121. }
  122. } catch (Exception $x) {
  123. // prevent endless loop when timezone is undefined
  124. date_default_timezone_set('America/Los_Angeles');
  125. throw new EngineException(sprintf('Unable to parse default temporal value "%s" for column "%s"', $col->getDefaultValueString(), $col->getFullyQualifiedName()), $x);
  126. }
  127. } elseif ($col->isEnumType()) {
  128. $valueSet = $col->getValueSet();
  129. if (!in_array($val, $valueSet)) {
  130. throw new EngineException(sprintf('Default Value "%s" is not among the enumerated values', $val));
  131. }
  132. $defaultValue = array_search($val, $valueSet);
  133. } else if ($col->isPhpPrimitiveType()) {
  134. settype($val, $col->getPhpType());
  135. $defaultValue = var_export($val, true);
  136. } elseif ($col->isPhpObjectType()) {
  137. $defaultValue = 'new '.$col->getPhpType().'(' . var_export($val, true) . ')';
  138. } else {
  139. throw new EngineException("Cannot get default value string for " . $col->getFullyQualifiedName());
  140. }
  141. return $defaultValue;
  142. }
  143. /**
  144. * Adds the include() statements for files that this class depends on or utilizes.
  145. * @param string &$script The script will be modified in this method.
  146. */
  147. protected function addIncludes(&$script)
  148. {
  149. } // addIncludes()
  150. /**
  151. * Adds class phpdoc comment and openning of class.
  152. * @param string &$script The script will be modified in this method.
  153. */
  154. protected function addClassOpen(&$script)
  155. {
  156. $table = $this->getTable();
  157. $tableName = $table->getName();
  158. $tableDesc = $table->getDescription();
  159. $interface = $this->getInterface();
  160. $parentClass = $this->getBehaviorContent('parentClass');
  161. $parentClass = (null !== $parentClass) ? $parentClass : ClassTools::classname($this->getBaseClass());
  162. $script .= "
  163. /**
  164. * Base class that represents a row from the '$tableName' table.
  165. *
  166. * $tableDesc
  167. *";
  168. if ($this->getBuildProperty('addTimeStamp')) {
  169. $now = strftime('%c');
  170. $script .= "
  171. * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
  172. *
  173. * $now
  174. *";
  175. }
  176. $script .= "
  177. * @package propel.generator.".$this->getPackage()."
  178. */
  179. abstract class ".$this->getClassname()." extends ".$parentClass." ";
  180. $interface = ClassTools::getInterface($table);
  181. if ($interface) {
  182. $script .= " implements " . ClassTools::classname($interface);
  183. }
  184. if ($this->getTable()->getInterface()) {
  185. $this->declareClassFromBuilder($this->getInterfaceBuilder());
  186. }
  187. $script .= "
  188. {
  189. ";
  190. }
  191. /**
  192. * Specifies the methods that are added as part of the basic OM class.
  193. * This can be overridden by subclasses that wish to add more methods.
  194. * @see ObjectBuilder::addClassBody()
  195. */
  196. protected function addClassBody(&$script)
  197. {
  198. $this->declareClassFromBuilder($this->getStubPeerBuilder());
  199. $this->declareClassFromBuilder($this->getStubQueryBuilder());
  200. $this->declareClasses('Propel', 'PropelException', 'PDO', 'PropelPDO', 'Criteria', 'BaseObject', 'Persistent', 'BasePeer', 'PropelObjectCollection');
  201. $table = $this->getTable();
  202. if (!$table->isAlias()) {
  203. $this->addConstants($script);
  204. $this->addAttributes($script);
  205. }
  206. if ($this->hasDefaultValues()) {
  207. $this->addApplyDefaultValues($script);
  208. $this->addConstructor($script);
  209. }
  210. $this->addColumnAccessorMethods($script);
  211. $this->addColumnMutatorMethods($script);
  212. $this->addHasOnlyDefaultValues($script);
  213. $this->addHydrate($script);
  214. $this->addEnsureConsistency($script);
  215. if (!$table->isReadOnly()) {
  216. $this->addManipulationMethods($script);
  217. }
  218. if ($this->isAddValidateMethod()) {
  219. $this->addValidationMethods($script);
  220. }
  221. if ($this->isAddGenericAccessors()) {
  222. $this->addGetByName($script);
  223. $this->addGetByPosition($script);
  224. $this->addToArray($script);
  225. }
  226. if ($this->isAddGenericMutators()) {
  227. $this->addSetByName($script);
  228. $this->addSetByPosition($script);
  229. $this->addFromArray($script);
  230. }
  231. $this->addBuildCriteria($script);
  232. $this->addBuildPkeyCriteria($script);
  233. $this->addGetPrimaryKey($script);
  234. $this->addSetPrimaryKey($script);
  235. $this->addIsPrimaryKeyNull($script);
  236. $this->addCopy($script);
  237. if (!$table->isAlias()) {
  238. $this->addGetPeer($script);
  239. }
  240. $this->addFKMethods($script);
  241. $this->addRefFKMethods($script);
  242. $this->addCrossFKMethods($script);
  243. $this->addClear($script);
  244. $this->addClearAllReferences($script);
  245. $this->addPrimaryString($script);
  246. // apply behaviors
  247. $this->applyBehaviorModifier('objectMethods', $script, " ");
  248. $this->addMagicCall($script);
  249. }
  250. /**
  251. * Closes class.
  252. * @param string &$script The script will be modified in this method.
  253. */
  254. protected function addClassClose(&$script)
  255. {
  256. $script .= "
  257. } // " . $this->getClassname() . "
  258. ";
  259. $this->applyBehaviorModifier('objectFilter', $script, "");
  260. }
  261. /**
  262. * Adds any constants to the class.
  263. * @param string &$script The script will be modified in this method.
  264. */
  265. protected function addConstants(&$script)
  266. {
  267. $script .= "
  268. /**
  269. * Peer class name
  270. */
  271. const PEER = '" . addslashes($this->getStubPeerBuilder()->getFullyQualifiedClassname()) . "';
  272. ";
  273. }
  274. /**
  275. * Adds class attributes.
  276. * @param string &$script The script will be modified in this method.
  277. */
  278. protected function addAttributes(&$script)
  279. {
  280. $table = $this->getTable();
  281. $script .= "
  282. /**
  283. * The Peer class.
  284. * Instance provides a convenient way of calling static methods on a class
  285. * that calling code may not be able to identify.
  286. * @var ".$this->getPeerClassname()."
  287. */
  288. protected static \$peer;
  289. ";
  290. if (!$table->isAlias()) {
  291. $this->addColumnAttributes($script);
  292. }
  293. foreach ($table->getForeignKeys() as $fk) {
  294. $this->addFKAttributes($script, $fk);
  295. }
  296. foreach ($table->getReferrers() as $refFK) {
  297. $this->addRefFKAttributes($script, $refFK);
  298. }
  299. // many-to-many relationships
  300. foreach ($table->getCrossFks() as $fkList) {
  301. $crossFK = $fkList[1];
  302. $this->addCrossFKAttributes($script, $crossFK);
  303. }
  304. $this->addAlreadyInSaveAttribute($script);
  305. $this->addAlreadyInValidationAttribute($script);
  306. // apply behaviors
  307. $this->applyBehaviorModifier('objectAttributes', $script, " ");
  308. }
  309. /**
  310. * Adds variables that store column values.
  311. * @param string &$script The script will be modified in this method.
  312. * @see addColumnNameConstants()
  313. */
  314. protected function addColumnAttributes(&$script)
  315. {
  316. $table = $this->getTable();
  317. foreach ($table->getColumns() as $col) {
  318. $this->addColumnAttributeComment($script, $col);
  319. $this->addColumnAttributeDeclaration($script, $col);
  320. if ($col->isLazyLoad() ) {
  321. $this->addColumnAttributeLoaderComment($script, $col);
  322. $this->addColumnAttributeLoaderDeclaration($script, $col);
  323. }
  324. if ($col->getType() == PropelTypes::OBJECT || $col->getType() == PropelTypes::PHP_ARRAY) {
  325. $this->addColumnAttributeUnserializedComment($script, $col);
  326. $this->addColumnAttributeUnserializedDeclaration($script, $col);
  327. }
  328. }
  329. }
  330. /**
  331. * Add comment about the attribute (variable) that stores column values
  332. * @param string &$script The script will be modified in this method.
  333. * @param Column $col
  334. **/
  335. protected function addColumnAttributeComment(&$script, Column $col)
  336. {
  337. $cptype = $col->getPhpType();
  338. $clo = strtolower($col->getName());
  339. $script .= "
  340. /**
  341. * The value for the $clo field.";
  342. if ($col->getDefaultValue()) {
  343. if ($col->getDefaultValue()->isExpression()) {
  344. $script .= "
  345. * Note: this column has a database default value of: (expression) ".$col->getDefaultValue()->getValue();
  346. } else {
  347. $script .= "
  348. * Note: this column has a database default value of: ". $this->getDefaultValueString($col);
  349. }
  350. }
  351. $script .= "
  352. * @var $cptype
  353. */";
  354. }
  355. /**
  356. * Adds the declaration of a column value storage attribute
  357. * @param string &$script The script will be modified in this method.
  358. * @param Column $col
  359. **/
  360. protected function addColumnAttributeDeclaration(&$script, Column $col)
  361. {
  362. $clo = strtolower($col->getName());
  363. $script .= "
  364. protected \$" . $clo . ";
  365. ";
  366. }
  367. /**
  368. * Adds the comment about the attribute keeping track if an attribute value has been loaded
  369. * @param string &$script The script will be modified in this method.
  370. * @param Column $col
  371. **/
  372. protected function addColumnAttributeLoaderComment(&$script, Column $col)
  373. {
  374. $clo = strtolower($col->getName());
  375. $script .= "
  376. /**
  377. * Whether the lazy-loaded \$$clo value has been loaded from database.
  378. * This is necessary to avoid repeated lookups if \$$clo column is NULL in the db.
  379. * @var boolean
  380. */";
  381. }
  382. /**
  383. * Adds the declaration of the attribute keeping track of an attribute's loaded state
  384. * @param string &$script The script will be modified in this method.
  385. * @param Column $col
  386. **/
  387. protected function addColumnAttributeLoaderDeclaration(&$script, Column $col)
  388. {
  389. $clo = strtolower($col->getName());
  390. $script .= "
  391. protected \$".$clo."_isLoaded = false;
  392. ";
  393. }
  394. /**
  395. * Adds the comment about the serialized attribute
  396. * @param string &$script The script will be modified in this method.
  397. * @param Column $col
  398. **/
  399. protected function addColumnAttributeUnserializedComment(&$script, Column $col)
  400. {
  401. $clo = strtolower($col->getName());
  402. $script .= "
  403. /**
  404. * The unserialized \$$clo value - i.e. the persisted object.
  405. * This is necessary to avoid repeated calls to unserialize() at runtime.
  406. * @var object
  407. */";
  408. }
  409. /**
  410. * Adds the declaration of the serialized attribute
  411. * @param string &$script The script will be modified in this method.
  412. * @param Column $col
  413. **/
  414. protected function addColumnAttributeUnserializedDeclaration(&$script, Column $col)
  415. {
  416. $clo = strtolower($col->getName()) . "_unserialized";
  417. $script .= "
  418. protected \$" . $clo . ";
  419. ";
  420. }
  421. /**
  422. * Adds the getPeer() method.
  423. * This is a convenient, non introspective way of getting the Peer class for a particular object.
  424. * @param string &$script The script will be modified in this method.
  425. */
  426. protected function addGetPeer(&$script)
  427. {
  428. $this->addGetPeerComment($script);
  429. $this->addGetPeerFunctionOpen($script);
  430. $this->addGetPeerFunctionBody($script);
  431. $this->addGetPeerFunctionClose($script);
  432. }
  433. /**
  434. * Add the comment for the getPeer method
  435. * @param string &$script The script will be modified in this method.
  436. **/
  437. protected function addGetPeerComment(&$script) {
  438. $script .= "
  439. /**
  440. * Returns a peer instance associated with this om.
  441. *
  442. * Since Peer classes are not to have any instance attributes, this method returns the
  443. * same instance for all member of this class. The method could therefore
  444. * be static, but this would prevent one from overriding the behavior.
  445. *
  446. * @return ".$this->getPeerClassname()."
  447. */";
  448. }
  449. /**
  450. * Adds the function declaration (function opening) for the getPeer method
  451. * @param string &$script The script will be modified in this method.
  452. **/
  453. protected function addGetPeerFunctionOpen(&$script) {
  454. $script .= "
  455. public function getPeer()
  456. {";
  457. }
  458. /**
  459. * Adds the body of the getPeer method
  460. * @param string &$script The script will be modified in this method.
  461. **/
  462. protected function addGetPeerFunctionBody(&$script) {
  463. $script .= "
  464. if (self::\$peer === null) {
  465. " . $this->buildObjectInstanceCreationCode('self::$peer', $this->getPeerClassname()) . "
  466. }
  467. return self::\$peer;";
  468. }
  469. /**
  470. * Add the function close for the getPeer method
  471. * 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
  472. * @param string &$script The script will be modified in this method.
  473. **/
  474. protected function addGetPeerFunctionClose(&$script) {
  475. $script .= "
  476. }
  477. ";
  478. }
  479. /**
  480. * Adds the constructor for this object.
  481. * @param string &$script The script will be modified in this method.
  482. * @see addConstructor()
  483. */
  484. protected function addConstructor(&$script)
  485. {
  486. $this->addConstructorComment($script);
  487. $this->addConstructorOpen($script);
  488. $this->addConstructorBody($script);
  489. $this->addConstructorClose($script);
  490. }
  491. /**
  492. * Adds the comment for the constructor
  493. * @param string &$script The script will be modified in this method.
  494. **/
  495. protected function addConstructorComment(&$script) {
  496. $script .= "
  497. /**
  498. * Initializes internal state of ".$this->getClassname()." object.
  499. * @see applyDefaults()
  500. */";
  501. }
  502. /**
  503. * Adds the function declaration for the constructor
  504. * @param string &$script The script will be modified in this method.
  505. **/
  506. protected function addConstructorOpen(&$script) {
  507. $script .= "
  508. public function __construct()
  509. {";
  510. }
  511. /**
  512. * Adds the function body for the constructor
  513. * @param string &$script The script will be modified in this method.
  514. **/
  515. protected function addConstructorBody(&$script) {
  516. $script .= "
  517. parent::__construct();
  518. \$this->applyDefaultValues();";
  519. }
  520. /**
  521. * Adds the function close for the constructor
  522. * @param string &$script The script will be modified in this method.
  523. **/
  524. protected function addConstructorClose(&$script) {
  525. $script .= "
  526. }
  527. ";
  528. }
  529. /**
  530. * Adds the applyDefaults() method, which is called from the constructor.
  531. * @param string &$script The script will be modified in this method.
  532. * @see addConstructor()
  533. */
  534. protected function addApplyDefaultValues(&$script)
  535. {
  536. $this->addApplyDefaultValuesComment($script);
  537. $this->addApplyDefaultValuesOpen($script);
  538. $this->addApplyDefaultValuesBody($script);
  539. $this->addApplyDefaultValuesClose($script);
  540. }
  541. /**
  542. * Adds the comment for the applyDefaults method
  543. * @param string &$script The script will be modified in this method.
  544. * @see addApplyDefaultValues()
  545. **/
  546. protected function addApplyDefaultValuesComment(&$script) {
  547. $script .= "
  548. /**
  549. * Applies default values to this object.
  550. * This method should be called from the object's constructor (or
  551. * equivalent initialization method).
  552. * @see __construct()
  553. */";
  554. }
  555. /**
  556. * Adds the function declaration for the applyDefaults method
  557. * @param string &$script The script will be modified in this method.
  558. * @see addApplyDefaultValues()
  559. **/
  560. protected function addApplyDefaultValuesOpen(&$script) {
  561. $script .= "
  562. public function applyDefaultValues()
  563. {";
  564. }
  565. /**
  566. * Adds the function body of the applyDefault method
  567. * @param string &$script The script will be modified in this method.
  568. * @see addApplyDefaultValues()
  569. **/
  570. protected function addApplyDefaultValuesBody(&$script) {
  571. $table = $this->getTable();
  572. // FIXME - Apply support for PHP default expressions here
  573. // see: http://propel.phpdb.org/trac/ticket/378
  574. $colsWithDefaults = array();
  575. foreach ($table->getColumns() as $col) {
  576. $def = $col->getDefaultValue();
  577. if ($def !== null && !$def->isExpression()) {
  578. $colsWithDefaults[] = $col;
  579. }
  580. }
  581. $colconsts = array();
  582. foreach ($colsWithDefaults as $col) {
  583. $clo = strtolower($col->getName());
  584. $defaultValue = $this->getDefaultValueString($col);
  585. $script .= "
  586. \$this->".$clo." = $defaultValue;";
  587. }
  588. }
  589. /**
  590. * Adds the function close for the applyDefaults method
  591. * @param string &$script The script will be modified in this method.
  592. * @see addApplyDefaultValues()
  593. **/
  594. protected function addApplyDefaultValuesClose(&$script) {
  595. $script .= "
  596. }
  597. ";
  598. }
  599. // --------------------------------------------------------------
  600. //
  601. // A C C E S S O R M E T H O D S
  602. //
  603. // --------------------------------------------------------------
  604. /**
  605. * Adds a date/time/timestamp getter method.
  606. * @param string &$script The script will be modified in this method.
  607. * @param Column $col The current column.
  608. * @see parent::addColumnAccessors()
  609. */
  610. protected function addTemporalAccessor(&$script, Column $col)
  611. {
  612. $this->addTemporalAccessorComment($script, $col);
  613. $this->addTemporalAccessorOpen($script, $col);
  614. $this->addTemporalAccessorBody($script, $col);
  615. $this->addTemporalAccessorClose($script, $col);
  616. } // addTemporalAccessor
  617. /**
  618. * Adds the comment for a temporal accessor
  619. * @param string &$script The script will be modified in this method.
  620. * @param Column $col The current column.
  621. * @see addTemporalAccessor
  622. **/
  623. public function addTemporalAccessorComment(&$script, Column $col) {
  624. $clo = strtolower($col->getName());
  625. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  626. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  627. if (!$dateTimeClass) {
  628. $dateTimeClass = 'DateTime';
  629. }
  630. $handleMysqlDate = false;
  631. if ($this->getPlatform() instanceof MysqlPlatform) {
  632. if ($col->getType() === PropelTypes::TIMESTAMP) {
  633. $handleMysqlDate = true;
  634. $mysqlInvalidDateString = '0000-00-00 00:00:00';
  635. } elseif ($col->getType() === PropelTypes::DATE) {
  636. $handleMysqlDate = true;
  637. $mysqlInvalidDateString = '0000-00-00';
  638. }
  639. // 00:00:00 is a valid time, so no need to check for that.
  640. }
  641. $script .= "
  642. /**
  643. * Get the [optionally formatted] temporal [$clo] column value.
  644. * ".$col->getDescription();
  645. if (!$useDateTime) {
  646. $script .= "
  647. * This accessor only only work with unix epoch dates. Consider enabling the propel.useDateTimeClass
  648. * option in order to avoid converstions to integers (which are limited in the dates they can express).";
  649. }
  650. $script .= "
  651. *
  652. * @param string \$format The date/time format string (either date()-style or strftime()-style).
  653. * If format is NULL, then the raw ".($useDateTime ? 'DateTime object' : 'unix timestamp integer')." will be returned.";
  654. if ($useDateTime) {
  655. $script .= "
  656. * @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 : '');
  657. } else {
  658. $script .= "
  659. * @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 : '');
  660. }
  661. $script .= "
  662. * @throws PropelException - if unable to parse/validate the date/time value.
  663. */";
  664. }
  665. /**
  666. * Adds the function declaration for a temporal accessor
  667. * @param string &$script The script will be modified in this method.
  668. * @param Column $col The current column.
  669. * @see addTemporalAccessor
  670. **/
  671. public function addTemporalAccessorOpen(&$script, Column $col) {
  672. $cfc = $col->getPhpName();
  673. $defaultfmt = null;
  674. $visibility = $col->getAccessorVisibility();
  675. // Default date/time formatter strings are specified in build.properties
  676. if ($col->getType() === PropelTypes::DATE) {
  677. $defaultfmt = $this->getBuildProperty('defaultDateFormat');
  678. } elseif ($col->getType() === PropelTypes::TIME) {
  679. $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
  680. } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
  681. $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
  682. }
  683. if (empty($defaultfmt)) { $defaultfmt = null; }
  684. $script .= "
  685. ".$visibility." function get$cfc(\$format = ".var_export($defaultfmt, true)."";
  686. if ($col->isLazyLoad()) $script .= ", \$con = null";
  687. $script .= ")
  688. {";
  689. }
  690. protected function getAccessorLazyLoadSnippet(Column $col)
  691. {
  692. if ($col->isLazyLoad()) {
  693. $clo = strtolower($col->getName());
  694. $defaultValueString = 'null';
  695. $def = $col->getDefaultValue();
  696. if ($def !== null && !$def->isExpression()) {
  697. $defaultValueString = $this->getDefaultValueString($col);
  698. }
  699. return "
  700. if (!\$this->{$clo}_isLoaded && \$this->{$clo} === {$defaultValueString} && !\$this->isNew()) {
  701. \$this->load{$col->getPhpName()}(\$con);
  702. }
  703. ";
  704. }
  705. }
  706. /**
  707. * Adds the body of the temporal accessor
  708. * @param string &$script The script will be modified in this method.
  709. * @param Column $col The current column.
  710. * @see addTemporalAccessor
  711. **/
  712. protected function addTemporalAccessorBody(&$script, Column $col) {
  713. $cfc = $col->getPhpName();
  714. $clo = strtolower($col->getName());
  715. $useDateTime = $this->getBuildProperty('useDateTimeClass');
  716. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  717. if (!$dateTimeClass) {
  718. $dateTimeClass = 'DateTime';
  719. }
  720. $this->declareClasses($dateTimeClass);
  721. $defaultfmt = null;
  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. $handleMysqlDate = false;
  732. if ($this->getPlatform() instanceof MysqlPlatform) {
  733. if ($col->getType() === PropelTypes::TIMESTAMP) {
  734. $handleMysqlDate = true;
  735. $mysqlInvalidDateString = '0000-00-00 00:00:00';
  736. } elseif ($col->getType() === PropelTypes::DATE) {
  737. $handleMysqlDate = true;
  738. $mysqlInvalidDateString = '0000-00-00';
  739. }
  740. // 00:00:00 is a valid time, so no need to check for that.
  741. }
  742. if ($col->isLazyLoad()) {
  743. $script .= $this->getAccessorLazyLoadSnippet($col);
  744. }
  745. $script .= "
  746. if (\$this->$clo === null) {
  747. return null;
  748. }
  749. ";
  750. if ($handleMysqlDate) {
  751. $script .= "
  752. if (\$this->$clo === '$mysqlInvalidDateString') {
  753. // while technically this is not a default value of NULL,
  754. // this seems to be closest in meaning.
  755. return null;
  756. } else {
  757. try {
  758. \$dt = new $dateTimeClass(\$this->$clo);
  759. } catch (Exception \$x) {
  760. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  761. }
  762. }
  763. ";
  764. } else {
  765. $script .= "
  766. try {
  767. \$dt = new $dateTimeClass(\$this->$clo);
  768. } catch (Exception \$x) {
  769. throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
  770. }
  771. ";
  772. } // if handleMyqlDate
  773. $script .= "
  774. if (\$format === null) {";
  775. if ($useDateTime) {
  776. $script .= "
  777. // Because propel.useDateTimeClass is TRUE, we return a $dateTimeClass object.
  778. return \$dt;";
  779. } else {
  780. $script .= "
  781. // We cast here to maintain BC in API; obviously we will lose data if we're dealing with pre-/post-epoch dates.
  782. return (int) \$dt->format('U');";
  783. }
  784. $script .= "
  785. } elseif (strpos(\$format, '%') !== false) {
  786. return strftime(\$format, \$dt->format('U'));
  787. } else {
  788. return \$dt->format(\$format);
  789. }";
  790. }
  791. /**
  792. * Adds the body of the temporal accessor
  793. * @param string &$script The script will be modified in this method.
  794. * @param Column $col The current column.
  795. * @see addTemporalAccessorClose
  796. **/
  797. protected function addTemporalAccessorClose(&$script, Column $col) {
  798. $script .= "
  799. }
  800. ";
  801. }
  802. /**
  803. * Adds an object getter method.
  804. * @param string &$script The script will be modified in this method.
  805. * @param Column $col The current column.
  806. * @see parent::addColumnAccessors()
  807. */
  808. protected function addObjectAccessor(&$script, Column $col)
  809. {
  810. $this->addDefaultAccessorComment($script, $col);
  811. $this->addDefaultAccessorOpen($script, $col);
  812. $this->addObjectAccessorBody($script, $col);
  813. $this->addDefaultAccessorClose($script, $col);
  814. }
  815. /**
  816. * Adds the function body for an object accessor method
  817. * @param string &$script The script will be modified in this method.
  818. * @param Column $col The current column.
  819. * @see addDefaultAccessor()
  820. **/
  821. protected function addObjectAccessorBody(&$script, Column $col)
  822. {
  823. $cfc = $col->getPhpName();
  824. $clo = strtolower($col->getName());
  825. $cloUnserialized = $clo.'_unserialized';
  826. if ($col->isLazyLoad()) {
  827. $script .= $this->getAccessorLazyLoadSnippet($col);
  828. }
  829. $script .= "
  830. if (null == \$this->$cloUnserialized && null !== \$this->$clo) {
  831. \$this->$cloUnserialized = unserialize(\$this->$clo);
  832. }
  833. return \$this->$cloUnserialized;";
  834. }
  835. /**
  836. * Adds an array getter method.
  837. * @param string &$script The script will be modified in this method.
  838. * @param Column $col The current column.
  839. * @see parent::addColumnAccessors()
  840. */
  841. protected function addArrayAccessor(&$script, Column $col)
  842. {
  843. $this->addDefaultAccessorComment($script, $col);
  844. $this->addDefaultAccessorOpen($script, $col);
  845. $this->addArrayAccessorBody($script, $col);
  846. $this->addDefaultAccessorClose($script, $col);
  847. }
  848. /**
  849. * Adds the function body for an array accessor method
  850. * @param string &$script The script will be modified in this method.
  851. * @param Column $col The current column.
  852. * @see addDefaultAccessor()
  853. **/
  854. protected function addArrayAccessorBody(&$script, Column $col)
  855. {
  856. $cfc = $col->getPhpName();
  857. $clo = strtolower($col->getName());
  858. $cloUnserialized = $clo.'_unserialized';
  859. if ($col->isLazyLoad()) {
  860. $script .= $this->getAccessorLazyLoadSnippet($col);
  861. }
  862. $script .= "
  863. if (null === \$this->$cloUnserialized) {
  864. \$this->$cloUnserialized = array();
  865. }
  866. if (!\$this->$cloUnserialized && null !== \$this->$clo) {
  867. \$$cloUnserialized = substr(\$this->$clo, 2, -2);
  868. \$this->$cloUnserialized = \$$cloUnserialized ? explode(' | ', \$$cloUnserialized) : array();
  869. }
  870. return \$this->$cloUnserialized;";
  871. }
  872. /**
  873. * Adds an enum getter method.
  874. * @param string &$script The script will be modified in this method.
  875. * @param Column $col The current column.
  876. * @see parent::addColumnAccessors()
  877. */
  878. protected function addEnumAccessor(&$script, Column $col)
  879. {
  880. $this->addDefaultAccessorComment($script, $col);
  881. $this->addDefaultAccessorOpen($script, $col);
  882. $this->addEnumAccessorBody($script, $col);
  883. $this->addDefaultAccessorClose($script, $col);
  884. }
  885. /**
  886. * Adds the function body for an enum accessor method
  887. * @param string &$script The script will be modified in this method.
  888. * @param Column $col The current column.
  889. * @see addDefaultAccessor()
  890. **/
  891. protected function addEnumAccessorBody(&$script, Column $col)
  892. {
  893. $cfc = $col->getPhpName();
  894. $clo = strtolower($col->getName());
  895. if ($col->isLazyLoad()) {
  896. $script .= $this->getAccessorLazyLoadSnippet($col);
  897. }
  898. $script .= "
  899. if (null === \$this->$clo) {
  900. return null;
  901. }
  902. \$valueSet = " . $this->getPeerClassname() . "::getValueSet(" . $this->getColumnConstant($col) . ");
  903. if (!isset(\$valueSet[\$this->$clo])) {
  904. throw new PropelException('Unknown stored enum key: ' . \$this->$clo);
  905. }
  906. return \$valueSet[\$this->$clo];";
  907. }
  908. /**
  909. * Adds a tester method for an array column.
  910. * @param string &$script The script will be modified in this method.
  911. * @param Column $col The current column.
  912. */
  913. protected function addHasArrayElement(&$script, Column $col)
  914. {
  915. $clo = strtolower($col->getName());
  916. $cfc = $col->getPhpName();
  917. $visibility = $col->getAccessorVisibility();
  918. $singularPhpName = rtrim($cfc, 's');
  919. $script .= "
  920. /**
  921. * Test the presence of a value in the [$clo] array column value.
  922. * @param mixed \$value
  923. * ".$col->getDescription();
  924. if ($col->isLazyLoad()) {
  925. $script .= "
  926. * @param PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  927. }
  928. $script .= "
  929. * @return Boolean
  930. */
  931. $visibility function has$singularPhpName(\$value";
  932. if ($col->isLazyLoad()) $script .= ", PropelPDO \$con = null";
  933. $script .= ")
  934. {
  935. return in_array(\$value, \$this->get$cfc(";
  936. if ($col->isLazyLoad()) $script .= "\$con";
  937. $script .= "));
  938. } // has$singularPhpName()
  939. ";
  940. }
  941. /**
  942. * Adds a normal (non-temporal) getter method.
  943. * @param string &$script The script will be modified in this method.
  944. * @param Column $col The current column.
  945. * @see parent::addColumnAccessors()
  946. */
  947. protected function addDefaultAccessor(&$script, Column $col)
  948. {
  949. $this->addDefaultAccessorComment($script, $col);
  950. $this->addDefaultAccessorOpen($script, $col);
  951. $this->addDefaultAccessorBody($script, $col);
  952. $this->addDefaultAccessorClose($script, $col);
  953. }
  954. /**
  955. * Add the comment for a default accessor method (a getter)
  956. * @param string &$script The script will be modified in this method.
  957. * @param Column $col The current column.
  958. * @see addDefaultAccessor()
  959. **/
  960. public function addDefaultAccessorComment(&$script, Column $col) {
  961. $clo=strtolower($col->getName());
  962. $script .= "
  963. /**
  964. * Get the [$clo] column value.
  965. * ".$col->getDescription();
  966. if ($col->isLazyLoad()) {
  967. $script .= "
  968. * @param PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  969. }
  970. $script .= "
  971. * @return ".$col->getPhpType()."
  972. */";
  973. }
  974. /**
  975. * Adds the function declaration for a default accessor
  976. * @param string &$script The script will be modified in this method.
  977. * @param Column $col The current column.
  978. * @see addDefaultAccessor()
  979. **/
  980. public function addDefaultAccessorOpen(&$script, Column $col) {
  981. $cfc = $col->getPhpName();
  982. $visibility = $col->getAccessorVisibility();
  983. $script .= "
  984. ".$visibility." function get$cfc(";
  985. if ($col->isLazyLoad()) $script .= "PropelPDO \$con = null";
  986. $script .= ")
  987. {";
  988. }
  989. /**
  990. * Adds the function body for a default accessor method
  991. * @param string &$script The script will be modified in this method.
  992. * @param Column $col The current column.
  993. * @see addDefaultAccessor()
  994. **/
  995. protected function addDefaultAccessorBody(&$script, Column $col) {
  996. $cfc = $col->getPhpName();
  997. $clo = strtolower($col->getName());
  998. if ($col->isLazyLoad()) {
  999. $script .= $this->getAccessorLazyLoadSnippet($col);
  1000. }
  1001. $script .= "
  1002. return \$this->$clo;";
  1003. }
  1004. /**
  1005. * Adds the function close for a default accessor method
  1006. * @param string &$script The script will be modified in this method.
  1007. * @param Column $col The current column.
  1008. * @see addDefaultAccessor()
  1009. **/
  1010. protected function addDefaultAccessorClose(&$script, Column $col) {
  1011. $script .= "
  1012. }
  1013. ";
  1014. }
  1015. /**
  1016. * Adds the lazy loader method.
  1017. * @param string &$script The script will be modified in this method.
  1018. * @param Column $col The current column.
  1019. * @see parent::addColumnAccessors()
  1020. */
  1021. protected function addLazyLoader(&$script, Column $col)
  1022. {
  1023. $this->addLazyLoaderComment($script, $col);
  1024. $this->addLazyLoaderOpen($script, $col);
  1025. $this->addLazyLoaderBody($script, $col);
  1026. $this->addLazyLoaderClose($script, $col);
  1027. }
  1028. /**
  1029. * Adds the comment for the lazy loader method
  1030. * @param string &$script The script will be modified in this method.
  1031. * @param Column $col The current column.
  1032. * @see addLazyLoader()
  1033. **/
  1034. protected function addLazyLoaderComment(&$script, Column $col) {
  1035. $clo = strtolower($col->getName());
  1036. $script .= "
  1037. /**
  1038. * Load the value for the lazy-loaded [$clo] column.
  1039. *
  1040. * This method performs an additional query to return the value for
  1041. * the [$clo] column, since it is not populated by
  1042. * the hydrate() method.
  1043. *
  1044. * @param \$con PropelPDO (optional) The PropelPDO connection to use.
  1045. * @return void
  1046. * @throws PropelException - any underlying error will be wrapped and re-thrown.
  1047. */";
  1048. }
  1049. /**
  1050. * Adds the function declaration for the lazy loader method
  1051. * @param string &$script The script will be modified in this method.
  1052. * @param Column $col The current column.
  1053. * @see addLazyLoader()
  1054. **/
  1055. protected function addLazyLoaderOpen(&$script, Column $col) {
  1056. $cfc = $col->getPhpName();
  1057. $script .= "
  1058. protected function load$cfc(PropelPDO \$con = null)
  1059. {";
  1060. }
  1061. /**
  1062. * Adds the function body for the lazy loader method
  1063. * @param string &$script The script will be modified in this method.
  1064. * @param Column $col The current column.
  1065. * @see addLazyLoader()
  1066. **/
  1067. protected function addLazyLoaderBody(&$script, Column $col) {
  1068. $platform = $this->getPlatform();
  1069. $clo = strtolower($col->getName());
  1070. // pdo_sqlsrv driver requires the use of PDOStatement::bindColumn() or a hex string will be returned
  1071. if ($col->getType() === PropelTypes::BLOB && $platform instanceof SqlsrvPlatform) {
  1072. $script .= "
  1073. \$c = \$this->buildPkeyCriteria();
  1074. \$c->addSelectColumn(".$this->getColumnConstant($col).");
  1075. try {
  1076. \$row = array(0 => null);
  1077. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
  1078. \$stmt->bindColumn(1, \$row[0], PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
  1079. \$stmt->fetch(PDO::FETCH_BOUND);
  1080. \$stmt->closeCursor();";
  1081. } else {
  1082. $script .= "
  1083. \$c = \$this->buildPkeyCriteria();
  1084. \$c->addSelectColumn(".$this->getColumnConstant($col).");
  1085. try {
  1086. \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
  1087. \$row = \$stmt->fetch(PDO::FETCH_NUM);
  1088. \$stmt->closeCursor();";
  1089. }
  1090. if ($col->getType() === PropelTypes::CLOB && $platform instanceof OraclePlatform) {
  1091. // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
  1092. $script .= "
  1093. \$this->$clo = stream_get_contents(\$row[0]);";
  1094. } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
  1095. $script .= "
  1096. if (\$row[0] !== null) {
  1097. \$this->$clo = fopen('php://memory', 'r+');
  1098. fwrite(\$this->$clo, \$row[0]);
  1099. rewind(\$this->$clo);
  1100. } else {
  1101. \$this->$clo = null;
  1102. }";
  1103. } elseif ($col->isPhpPrimitiveType()) {
  1104. $script .= "
  1105. \$this->$clo = (\$row[0] !== null) ? (".$col->getPhpType().") \$row[0] : null;";
  1106. } elseif ($col->isPhpObjectType()) {
  1107. $script .= "
  1108. \$this->$clo = (\$row[0] !== null) ? new ".$col->getPhpType()."(\$row[0]) : null;";
  1109. } else {
  1110. $script .= "
  1111. \$this->$clo = \$row[0];";
  1112. }
  1113. $script .= "
  1114. \$this->".$clo."_isLoaded = true;
  1115. } catch (Exception \$e) {
  1116. throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e);
  1117. }";
  1118. }
  1119. /**
  1120. * Adds the function close for the lazy loader
  1121. * @param string &$script The script will be modified in this method.
  1122. * @param Column $col The current column.
  1123. * @see addLazyLoader()
  1124. **/
  1125. protected function addLazyLoaderClose(&$script, Column $col) {
  1126. $script .= "
  1127. }";
  1128. } // addLazyLoader()
  1129. // --------------------------------------------------------------
  1130. //
  1131. // M U T A T O R M E T H O D S
  1132. //
  1133. // --------------------------------------------------------------
  1134. /**
  1135. * Adds the open of the mutator (setter) method for a column.
  1136. * @param string &$script The script will be modified in this method.
  1137. * @param Column $col The current column.
  1138. */
  1139. protected function addMutatorOpen(&$script, Column $col)
  1140. {
  1141. $this->addMutatorComment($script, $col);
  1142. $this->addMutatorOpenOpen($script, $col);
  1143. $this->addMutatorOpenBody($script, $col);
  1144. }
  1145. /**
  1146. * Adds the comment for a mutator
  1147. * @param string &$script The script will be modified in this method.
  1148. * @param Column $col The current column.
  1149. * @see addMutatorOpen()
  1150. **/
  1151. public function addMutatorComment(&$script, Column $col) {
  1152. $clo = strtolower($col->getName());
  1153. $script .= "
  1154. /**
  1155. * Set the value of [$clo] column.
  1156. * ".$col->getDescription()."
  1157. * @param ".$col->getPhpType()." \$v new value
  1158. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1159. */";
  1160. }
  1161. /**
  1162. * Adds the mutator function declaration
  1163. * @param string &$script The script will be modified in this method.
  1164. * @param Column $col The current column.
  1165. * @see addMutatorOpen()
  1166. **/
  1167. public function addMutatorOpenOpen(&$script, Column $col) {
  1168. $cfc = $col->getPhpName();
  1169. $visibility = $col->getMutatorVisibility();
  1170. $script .= "
  1171. ".$visibility." function set$cfc(\$v)
  1172. {";
  1173. }
  1174. /**
  1175. * Adds the mutator open body part
  1176. * @param string &$script The script will be modified in this method.
  1177. * @param Column $col The current column.
  1178. * @see addMutatorOpen()
  1179. **/
  1180. protected function addMutatorOpenBody(&$script, Column $col)
  1181. {
  1182. $clo = strtolower($col->getName());
  1183. $cfc = $col->getPhpName();
  1184. if ($col->isLazyLoad()) {
  1185. $script .= "
  1186. // explicitly set the is-loaded flag to true for this lazy load col;
  1187. // it doesn't matter if the value is actually set or not (logic below) as
  1188. // any attempt to set the value means that no db lookup should be performed
  1189. // when the get$cfc() method is called.
  1190. \$this->".$clo."_isLoaded = true;
  1191. ";
  1192. }
  1193. }
  1194. /**
  1195. * Adds the close of the mutator (setter) method for a column.
  1196. *
  1197. * @param string &$script The script will be modified in this method.
  1198. * @param Column $col The current column.
  1199. */
  1200. protected function addMutatorClose(&$script, Column $col)
  1201. {
  1202. $this->addMutatorCloseBody($script, $col);
  1203. $this->addMutatorCloseClose($script, $col);
  1204. }
  1205. /**
  1206. * Adds the body of the close part of a mutator
  1207. * @param string &$script The script will be modified in this method.
  1208. * @param Column $col The current column.
  1209. * @see addMutatorClose()
  1210. **/
  1211. protected function addMutatorCloseBody(&$script, Column $col) {
  1212. $table = $this->getTable();
  1213. $cfc = $col->getPhpName();
  1214. $clo = strtolower($col->getName());
  1215. if ($col->isForeignKey()) {
  1216. foreach ($col->getForeignKeys() as $fk) {
  1217. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1218. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1219. $varName = $this->getFKVarName($fk);
  1220. $script .= "
  1221. if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) {
  1222. \$this->$varName = null;
  1223. }
  1224. ";
  1225. } // foreach fk
  1226. } /* if col is foreign key */
  1227. foreach ($col->getReferrers() as $refFK) {
  1228. $tblFK = $this->getDatabase()->getTable($refFK->getForeignTableName());
  1229. if ( $tblFK->getName() != $table->getName() ) {
  1230. foreach ($col->getForeignKeys() as $fk) {
  1231. $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
  1232. $colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
  1233. if ($refFK->isLocalPrimaryKey()) {
  1234. $varName = $this->getPKRefFKVarName($refFK);
  1235. $script .= "
  1236. // update associated ".$tblFK->getPhpName()."
  1237. if (\$this->$varName !== null) {
  1238. \$this->{$varName}->set".$colFK->getPhpName()."(\$v);
  1239. }
  1240. ";
  1241. } else {
  1242. $collName = $this->getRefFKCollVarName($refFK);
  1243. $script .= "
  1244. // update associated ".$tblFK->getPhpName()."
  1245. if (\$this->$collName !== null) {
  1246. foreach (\$this->$collName as \$referrerObject) {
  1247. \$referrerObject->set".$colFK->getPhpName()."(\$v);
  1248. }
  1249. }
  1250. ";
  1251. } // if (isLocalPrimaryKey
  1252. } // foreach col->getPrimaryKeys()
  1253. } // if tablFk != table
  1254. } // foreach
  1255. }
  1256. /**
  1257. * Adds the close for the mutator close
  1258. * @param string &$script The script will be modified in this method.
  1259. * @param Column $col The current column.
  1260. * @see addMutatorClose()
  1261. **/
  1262. protected function addMutatorCloseClose(&$script, Column $col) {
  1263. $cfc = $col->getPhpName();
  1264. $script .= "
  1265. return \$this;
  1266. } // set$cfc()
  1267. ";
  1268. }
  1269. /**
  1270. * Adds a setter for BLOB columns.
  1271. * @param string &$script The script will be modified in this method.
  1272. * @param Column $col The current column.
  1273. * @see parent::addColumnMutators()
  1274. */
  1275. protected function addLobMutator(&$script, Column $col)
  1276. {
  1277. $this->addMutatorOpen($script, $col);
  1278. $clo = strtolower($col->getName());
  1279. $script .= "
  1280. // Because BLOB columns are streams in PDO we have to assume that they are
  1281. // always modified when a new value is passed in. For example, the contents
  1282. // of the stream itself may have changed externally.
  1283. if (!is_resource(\$v) && \$v !== null) {
  1284. \$this->$clo = fopen('php://memory', 'r+');
  1285. fwrite(\$this->$clo, \$v);
  1286. rewind(\$this->$clo);
  1287. } else { // it's already a stream
  1288. \$this->$clo = \$v;
  1289. }
  1290. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1291. ";
  1292. $this->addMutatorClose($script, $col);
  1293. } // addLobMutatorSnippet
  1294. /**
  1295. * Adds a setter method for date/time/timestamp columns.
  1296. * @param string &$script The script will be modified in this method.
  1297. * @param Column $col The current column.
  1298. * @see parent::addColumnMutators()
  1299. */
  1300. protected function addTemporalMutator(&$script, Column $col)
  1301. {
  1302. $cfc = $col->getPhpName();
  1303. $clo = strtolower($col->getName());
  1304. $visibility = $col->getMutatorVisibility();
  1305. $dateTimeClass = $this->getBuildProperty('dateTimeClass');
  1306. if (!$dateTimeClass) {
  1307. $dateTimeClass = 'DateTime';
  1308. }
  1309. $this->declareClasses($dateTimeClass, 'DateTimeZone', 'PropelDateTime');
  1310. $this->addTemporalMutatorComment($script, $col);
  1311. $this->addMutatorOpenOpen($script, $col);
  1312. $this->addMutatorOpenBody($script, $col);
  1313. $fmt = var_export($this->getTemporalFormatter($col), true);
  1314. $script .= "
  1315. \$dt = PropelDateTime::newInstance(\$v, null, '$dateTimeClass');
  1316. if (\$this->$clo !== null || \$dt !== null) {
  1317. \$currentDateAsString = (\$this->$clo !== null && \$tmpDt = new $dateTimeClass(\$this->$clo)) ? \$tmpDt->format($fmt) : null;
  1318. \$newDateAsString = \$dt ? \$dt->format($fmt) : null;";
  1319. if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
  1320. $defaultValue = $this->getDefaultValueString($col);
  1321. $script .= "
  1322. if ( (\$currentDateAsString !== \$newDateAsString) // normalized values don't match
  1323. || (\$dt->format($fmt) === $defaultValue) // or the entered value matches the default
  1324. ) {";
  1325. } else {
  1326. $script .= "
  1327. if (\$currentDateAsString !== \$newDateAsString) {";
  1328. }
  1329. $script .= "
  1330. \$this->$clo = \$newDateAsString;
  1331. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1332. }
  1333. } // if either are not null
  1334. ";
  1335. $this->addMutatorClose($script, $col);
  1336. }
  1337. public function addTemporalMutatorComment(&$script, Column $col)
  1338. {
  1339. $cfc = $col->getPhpName();
  1340. $clo = strtolower($col->getName());
  1341. $script .= "
  1342. /**
  1343. * Sets the value of [$clo] column to a normalized version of the date/time value specified.
  1344. * ".$col->getDescription()."
  1345. * @param mixed \$v string, integer (timestamp), or DateTime value.
  1346. * Empty strings are treated as NULL.
  1347. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1348. */";
  1349. }
  1350. /**
  1351. * Adds a setter for Object columns.
  1352. * @param string &$script The script will be modified in this method.
  1353. * @param Column $col The current column.
  1354. * @see parent::addColumnMutators()
  1355. */
  1356. protected function addObjectMutator(&$script, Column $col)
  1357. {
  1358. $clo = strtolower($col->getName());
  1359. $cloUnserialized = $clo.'_unserialized';
  1360. $this->addMutatorOpen($script, $col);
  1361. $script .= "
  1362. if (\$this->$cloUnserialized !== \$v) {
  1363. \$this->$cloUnserialized = \$v;
  1364. \$this->$clo = serialize(\$v);
  1365. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1366. }
  1367. ";
  1368. $this->addMutatorClose($script, $col);
  1369. }
  1370. /**
  1371. * Adds a setter for Array columns.
  1372. * @param string &$script The script will be modified in this method.
  1373. * @param Column $col The current column.
  1374. * @see parent::addColumnMutators()
  1375. */
  1376. protected function addArrayMutator(&$script, Column $col)
  1377. {
  1378. $clo = strtolower($col->getName());
  1379. $cloUnserialized = $clo.'_unserialized';
  1380. $this->addMutatorOpen($script, $col);
  1381. $script .= "
  1382. if (\$this->$cloUnserialized !== \$v) {
  1383. \$this->$cloUnserialized = \$v;
  1384. \$this->$clo = '| ' . implode(' | ', \$v) . ' |';
  1385. \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
  1386. }
  1387. ";
  1388. $this->addMutatorClose($script, $col);
  1389. }
  1390. /**
  1391. * Adds a push method for an array column.
  1392. * @param string &$script The script will be modified in this method.
  1393. * @param Column $col The current column.
  1394. */
  1395. protected function addAddArrayElement(&$script, Column $col)
  1396. {
  1397. $clo = strtolower($col->getName());
  1398. $cfc = $col->getPhpName();
  1399. $visibility = $col->getAccessorVisibility();
  1400. $singularPhpName = rtrim($cfc, 's');
  1401. $script .= "
  1402. /**
  1403. * Adds a value to the [$clo] array column value.
  1404. * @param mixed \$value
  1405. * ".$col->getDescription();
  1406. if ($col->isLazyLoad()) {
  1407. $script .= "
  1408. * @param PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  1409. }
  1410. $script .= "
  1411. * @return ".$this->getObjectClassname()." The current object (for fluent API support)
  1412. */
  1413. $visibility function add$singularPhpName(\$value";
  1414. if ($col->isLazyLoad()) $script .= ", PropelPDO \$con = null";
  1415. $script .= ")
  1416. {
  1417. \$currentArray = \$this->get$cfc(";
  1418. if ($col->isLazyLoad()) $script .= "\$con";
  1419. $script .= ");
  1420. \$currentArray []= \$value;
  1421. \$this->set$cfc(\$currentArray);
  1422. return \$this;
  1423. } // add$singularPhpName()
  1424. ";
  1425. }
  1426. /**
  1427. * Adds a remove method for an array column.
  1428. * @param string &$script The script will be modified in this method.
  1429. * @param Column $col The current column.
  1430. */
  1431. protected function addRemoveArrayElement(&$script, Column $col)
  1432. {
  1433. $clo = strtolower($col->getName());
  1434. $cfc = $col->getPhpName();
  1435. $visibility = $col->getAccessorVisibility();
  1436. $singularPhpName = rtrim($cfc, 's');
  1437. $script .= "
  1438. /**
  1439. * Removes a value from the [$clo] array column value.
  1440. * @param mixed \$value
  1441. * ".$col->getDescription();
  1442. if ($col->isLazyLoad()) {
  1443. $script .= "
  1444. * @param PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
  1445. }
  1446. $script .= "