source: branches/1.3/generator/classes/propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php @ 491

Revision 491, 36.7 KB checked in by hans, 4 years ago (diff)
  • ticket:280 - Added object pool registration in the save() method
  • Updated tests for instance pool to reflect new behavior
  • Added tests for inheritance
  • Property svn:keywords set to Id Rev Date
Line 
1<?php
2
3/*
4 *  $Id$
5 *
6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 *
18 * This software consists of voluntary contributions made by many individuals
19 * and is licensed under the LGPL. For more information please see
20 * <http://propel.phpdb.org>.
21 */
22
23require_once 'propel/engine/builder/om/ObjectBuilder.php';
24
25/**
26 * Generates a PHP5 base Object class for user object model (OM).
27 *
28 * This class produces the base object class (e.g. BaseMyTable) which contains all
29 * the custom-built accessor and setter methods.
30 *
31 * This class replaces the Object.tpl, with the intent of being easier for users
32 * to customize (through extending & overriding).
33 *
34 * @author Hans Lellelid <hans@xmpl.org>
35 * @package propel.engine.builder.om.php5
36 */
37class PHP5BasicObjectBuilder extends ObjectBuilder {
38
39        /**
40         * Gets the package for the [base] object classes.
41         * @return string
42         */
43        public function getPackage()
44        {
45                return parent::getPackage() . ".om";
46        }
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        /**
58         * Adds the include() statements for files that this class depends on or utilizes.
59         * @param string &$script The script will be modified in this method.
60         */
61        protected function addIncludes(&$script)
62        {
63        } // addIncludes()
64
65        /**
66         * Adds class phpdoc comment and openning of class.
67         * @param string &$script The script will be modified in this method.
68         */
69        protected function addClassOpen(&$script)
70        {
71
72                $table = $this->getTable();
73                $tableName = $table->getName();
74                $tableDesc = $table->getDescription();
75                $interface = $this->getInterface();
76
77                $script .= "
78/**
79 * Base class that represents a row from the '$tableName' table.
80 *
81 * $tableDesc
82 *";
83                if ($this->getBuildProperty('addTimeStamp')) {
84                        $now = strftime('%c');
85                        $script .= "
86 * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
87 *
88 * $now
89 *";
90                }
91                $script .= "
92 * @package ".$this->getPackage()."
93 */
94abstract class ".$this->getClassname()." extends ".ClassTools::classname($this->getBaseClass())." ";
95
96                $interface = ClassTools::getInterface($table);
97                if ($interface) {
98                    $script .= " implements " . ClassTools::classname($interface);
99                }
100
101                $script .= " {
102
103";
104        }
105
106        /**
107         * Specifies the methods that are added as part of the basic OM class.
108         * This can be overridden by subclasses that wish to add more methods.
109         * @see ObjectBuilder::addClassBody()
110         */
111        protected function addClassBody(&$script)
112        {
113                $table = $this->getTable();
114                if (!$table->isAlias()) {
115                        $this->addConstants($script);
116                        $this->addAttributes($script);
117                }
118
119                $this->addColumnAccessorMethods($script);
120                $this->addColumnMutatorMethods($script);
121
122                $this->addHydrate($script);
123
124                $this->addManipulationMethods($script);
125                $this->addValidationMethods($script);
126
127                if ($this->isAddGenericAccessors()) {
128                        $this->addGetByName($script);
129                        $this->addGetByPosition($script);
130                        $this->addToArray($script);
131                }
132
133                if ($this->isAddGenericMutators()) {
134                    $this->addSetByName($script);
135                        $this->addSetByPosition($script);
136                        $this->addFromArray($script);
137                }
138
139                $this->addBuildCriteria($script);
140                $this->addBuildPkeyCriteria($script);
141                $this->addGetPrimaryKey($script);
142                $this->addSetPrimaryKey($script);
143
144                $this->addCopy($script);
145
146                if (!$table->isAlias()) {
147                        $this->addGetPeer($script);
148                }
149        }
150
151        /**
152         * Closes class.
153         * @param string &$script The script will be modified in this method.
154         */
155        protected function addClassClose(&$script)
156        {
157                $script .= "
158} // " . $this->getClassname() . "
159";
160        }
161
162        /**
163         * Adds any constants to the class.
164         * @param string &$script The script will be modified in this method.
165         */
166        protected function addConstants(&$script)
167        {
168                // nothing to do here any more
169                // fieldnameTypeConstants have been moved to class BasePeer [sv]
170        }
171
172        /**
173         * Adds class attributes.
174         * @param string &$script The script will be modified in this method.
175         */
176        protected function addAttributes(&$script)
177        {
178                $script .= "
179        /**
180         * The Peer class.
181         * Instance provides a convenient way of calling static methods on a class
182         * that calling code may not be able to identify.
183         * @var ".$this->getPeerClassname()."
184         */
185        protected static \$peer;
186";
187                if (!$this->getTable()->isAlias()) {
188                    $this->addColumnAttributes($script);
189                }
190        }
191
192        /**
193         * Adds variables that store column values.
194         * @param string &$script The script will be modified in this method.
195         * @see addColumnNameConstants()
196         */
197        protected function addColumnAttributes(&$script) {
198
199                $table = $this->getTable();
200
201                foreach ($table->getColumns() as $col) {
202
203                        $cptype = $col->getPhpNative();
204                        $clo=strtolower($col->getName());
205                        $defVal = "";
206                        if (($val = $col->getPhpDefaultValue()) !== null) {
207                                settype($val, $cptype);
208                                $defaultValue = var_export($val, true);
209                                $defVal = " = " . $defaultValue;
210                        }
211
212                        $script .= "
213
214        /**
215         * The value for the $clo field.
216         * @var $cptype
217         */
218        protected \$" . $clo . $defVal . ";
219";
220
221                        if ($col->isLazyLoad()) {
222                                $script .= "
223        /**
224         * Whether the lazy-loaded $clo value has been loaded from database.
225         * This is necessary to avoid repeated lookups if $clo column is NULL in the db.
226         * @var boolean
227         */
228        protected \$".$clo."_isLoaded = false;
229";
230                        }
231
232                }  // foreach col
233
234        } // addColumnAttributes()
235
236        /**
237         * Adds the getPeer() method.
238         * This is a convenient, non introspective way of getting the Peer class for a particular object.
239         * @param string &$script The script will be modified in this method.
240         */
241        protected function addGetPeer(&$script)
242        {
243                $script .= "
244        /**
245         * Returns a peer instance associated with this om.
246         *
247         * Since Peer classes are not to have any instance attributes, this method returns the
248         * same instance for all member of this class. The method could therefore
249         * be static, but this would prevent one from overriding the behavior.
250         *
251         * @return ".$this->getPeerClassname()."
252         */
253        public function getPeer()
254        {
255                if (self::\$peer === null) {
256                        self::\$peer = new ".$this->getPeerClassname()."();
257                }
258                return self::\$peer;
259        }
260";
261        }
262
263        // --------------------------------------------------------------
264        //
265        // A C C E S S O R    M E T H O D S
266        //
267        // --------------------------------------------------------------
268
269        /**
270         * Adds a date/time/timestamp getter method.
271         * @param string &$script The script will be modified in this method.
272         * @param Column $col The current column.
273         * @see parent::addColumnAccessors()
274         */
275        protected function addTemporalAccessor(&$script, $col)
276        {
277                $cfc=$col->getPhpName();
278                $clo=strtolower($col->getName());
279
280                // these default values are based on the Creole defaults
281                // the date and time default formats are locale-sensitive
282                if ($col->getType() === PropelTypes::DATE) {
283                        $defaultfmt = $this->getBuildProperty('defaultDateFormat');
284                } elseif ($col->getType() === PropelTypes::TIME) {
285                        $defaultfmt = $this->getBuildProperty('defaultTimeFormat');
286                } elseif ($col->getType() === PropelTypes::TIMESTAMP) {
287                        $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
288                }
289
290                // if the default format property was an empty string, then we'll set it
291                // to NULL, which will return the "native" integer timestamp
292                if (empty($defaultfmt)) { $defaultfmt = null; }
293
294                $script .= "
295        /**
296         * Get the [optionally formatted] [$clo] column value.
297         * ".$col->getDescription()."
298         * @param string \$format The date/time format string (either date()-style or strftime()-style).
299         *                                                      If format is NULL, then the integer unix timestamp will be returned.
300         * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL).
301         * @throws PropelException - if unable to convert the date/time to timestamp.
302         */
303        public function get$cfc(\$format = ".var_export($defaultfmt, true)."";
304                if ($col->isLazyLoad()) $script .= ", \$con = null";
305                $script .= ")
306        {
307";
308                if ($col->isLazyLoad()) {
309                        $script .= "
310                if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
311                        \$this->load$cfc(\$con);
312                }
313";
314                }
315                $script .= "
316                if (\$this->$clo === null || \$this->$clo === '') {
317                        return null;
318                } elseif (!is_int(\$this->$clo)) {
319                        // a non-timestamp value was set externally, so we convert it
320                        \$ts = strtotime(\$this->$clo);
321                        if (\$ts === -1 || \$ts === false) { // in PHP 5.1 return value changes to FALSE
322                                throw new PropelException(\"Unable to parse value of [$clo] as date/time value: \" . var_export(\$this->$clo, true));
323                        }
324                } else {
325                        \$ts = \$this->$clo;
326                }
327                if (\$format === null) {
328                        return \$ts;
329                } elseif (strpos(\$format, '%') !== false) {
330                        return strftime(\$format, \$ts);
331                } else {
332                        return date(\$format, \$ts);
333                }
334        }
335";
336        } // addTemporalAccessor
337
338        /**
339         * Adds a normal (non-temporal) getter method.
340         * @param string &$script The script will be modified in this method.
341         * @param Column $col The current column.
342         * @see parent::addColumnAccessors()
343         */
344        protected function addGenericAccessor(&$script, $col)
345        {
346                $cfc=$col->getPhpName();
347                $clo=strtolower($col->getName());
348
349                $script .= "
350        /**
351         * Get the [$clo] column value.
352         * ".$col->getDescription()."
353         * @return ".$col->getPhpNative()."
354         */
355        public function get$cfc(";
356                if ($col->isLazyLoad()) $script .= "\$con = null";
357                $script .= ")
358        {
359";
360                if ($col->isLazyLoad()) {
361                        $script .= "
362                if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
363                        \$this->load$cfc(\$con);
364                }
365";
366                }
367                $script .= "
368                return \$this->$clo;
369        }
370";
371        }
372
373        /**
374         * Adds the lazy loader method.
375         * @param string &$script The script will be modified in this method.
376         * @param Column $col The current column.
377         * @see parent::addColumnAccessors()
378         */
379        protected function addLazyLoader(&$script, $col)
380        {
381                $cfc=$col->getPhpName();
382                $clo=strtolower($col->getName());
383
384                $script .= "
385        /**
386         * Load the value for the lazy-loaded [$clo] column.
387         *
388         * This method performs an additional query to return the value for
389         * the [$clo] column, since it is not populated by
390         * the hydrate() method.
391         *
392         * @param \$con PDO
393         * @return void
394         * @throws PropelException - any underlying error will be wrapped and re-thrown.
395         */
396        protected function load$cfc(\$con = null)
397        {
398                \$c = \$this->buildPkeyCriteria();
399                \$c->addSelectColumn(".$this->getColumnConstant($col).");
400                try {
401                        \$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
402                        \$row = \$stmt->fetch(PDO::FETCH_NUM);
403";
404                $clo = strtolower($col->getName());
405                switch($col->getType()) {
406                         case PropelTypes::DATE:
407                         case PropelTypes::TIME:
408                         case PropelTypes::TIMESTAMP:
409                                $script .= "
410                        \$this->$clo = \$row[0]; // FIXME - it's a timestamp ... we may wish to format it ...
411";
412                                break;
413                        default:
414                                $script .= "
415                        \$this->$clo = \$row[0];
416";
417                } // switch
418                $script .= "
419                        \$this->".$clo."_isLoaded = true;
420                } catch (Exception \$e) {
421                        throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e);
422                }
423        }
424";
425
426        } // addLazyLoader()
427
428
429
430        // --------------------------------------------------------------
431        //
432        // M U T A T O R    M E T H O D S
433        //
434        // --------------------------------------------------------------
435
436        /**
437         * Adds the open of the mutator (setter) method for a column.
438         * @param string &$script The script will be modified in this method.
439         * @param Column $col The current column.
440         */
441        protected function addMutatorOpen(&$script, Column $col)
442        {
443                $cfc=$col->getPhpName();
444                $clo=strtolower($col->getName());
445
446                $script .= "
447        /**
448         * Set the value of [$clo] column.
449         * ".$col->getDescription()."
450         * @param ".$col->getPhpNative()." \$v new value
451         * @return void
452         */
453        public function set$cfc(\$v)
454        {
455";
456                if ($col->isLazyLoad()) {
457                        $script .= "
458                // explicitly set the is-loaded flag to true for this lazy load col;
459                // it doesn't matter if the value is actually set or not (logic below) as
460                // any attempt to set the value means that no db lookup should be performed
461                // when the get$cfc() method is called.
462                \$this->".$clo."_isLoaded = true;
463";
464                }
465
466        }
467
468        /**
469         * Adds the close of the mutator (setter) method for a column.
470         * This can be overridden (e.g. by PHP5ComplexObjectBuilder) if additional functionality is needed.
471         * @param string &$script The script will be modified in this method.
472         * @param Column $col The current column.
473         */
474        protected function addMutatorClose(&$script, Column $col)
475        {
476                                $script .= "
477        } // set".$col->getPhpName()."()
478";
479        }
480
481        /**
482         * Adds a setter for date/time/timestamp columns.
483         * @param string &$script The script will be modified in this method.
484         * @param Column $col The current column.
485         * @see parent::addColumnMutators()
486         */
487        protected function addLobMutator(&$script, Column $col)
488        {
489                $this->addMutatorOpen($script, $col);
490                $clo = strtolower($col->getName());
491                // Setting of LOB columns gets some special handling
492
493                if ($col->getPropelType() === PropelTypes::BLOB || $col->getPropelType() === PropelTypes::LONGVARBINARY ) {
494                        $lobClass = 'Blob';
495                } else {
496                        $lobClass = 'Clob';
497                }
498                $script .= "
499                // FIXME - LOBs need to be streams in PDO; I'm sure there will be special handling here.
500                if (\$this->$clo !== \$v) {
501                        \$this->$clo = \$v;
502                        \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
503                }
504";
505                $this->addMutatorClose($script, $col);
506
507        } // addLobMutatorSnippet
508
509
510        /**
511         * Adds a setter method for date/time/timestamp columns.
512         * @param string &$script The script will be modified in this method.
513         * @param Column $col The current column.
514         * @see parent::addColumnMutators()
515         */
516        protected function addTemporalMutator(&$script, Column $col)
517        {
518                $clo = strtolower($col->getName());
519
520                $defaultValue = null;
521                if (($val = $col->getPhpDefaultValue()) !== null) {
522                        settype($val, $col->getPhpNative());
523                        $defaultValue = var_export($val, true);
524                }
525
526                $this->addMutatorOpen($script, $col);
527
528                $script .= "
529                if (\$v !== null && !is_int(\$v)) {
530                        \$ts = strtotime(\$v);
531                        if (\$ts === -1 || \$ts === false) { // in PHP 5.1 return value changes to FALSE
532                                throw new PropelException(\"Unable to parse date/time value for [$clo] from input: \" . var_export(\$v, true));
533                        }
534                } else {
535                        \$ts = \$v;
536                }
537                if (\$this->$clo !== \$ts";
538                if ($defaultValue !== null) {
539                        $script .= " || \$ts === $defaultValue";
540                }
541                $script .= ") {
542                        \$this->$clo = \$ts;
543                        \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
544                }
545";
546                $this->addMutatorClose($script, $col);
547        }
548
549        /**
550         * Adds setter method for "normal" columns.
551         * @param string &$script The script will be modified in this method.
552         * @param Column $col The current column.
553         * @see parent::addColumnMutators()
554         */
555        protected function addDefaultMutator(&$script, Column $col)
556        {
557                $clo = strtolower($col->getName());
558
559                // FIXME: refactor this
560                $defaultValue = null;
561                if (($val = $col->getPhpDefaultValue()) !== null) {
562                        settype($val, $col->getPhpNative());
563                        $defaultValue = var_export($val, true);
564                }
565
566                $this->addMutatorOpen($script, $col);
567                $script .= "
568                if (\$this->$clo !== \$v";
569                if ($defaultValue !== null) {
570                        $script .= " || \$v === $defaultValue";
571                }
572                $script .= ") {
573                        \$this->$clo = \$v;
574                        \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
575                }
576";
577                $this->addMutatorClose($script, $col);
578        }
579
580        /**
581         * Adds the hydrate() method, which sets attributes of the object based on a ResultSet.
582         */
583        protected function addHydrate(&$script)
584        {
585                $table = $this->getTable();
586
587                $script .= "
588        /**
589         * Hydrates (populates) the object variables with values from the database resultset.
590         *
591         * An offset (0-based \"start column\") is specified so that objects can be hydrated
592         * with a subset of the columns in the resultset rows.  This is needed, for example,
593         * for results of JOIN queries where the resultset row includes columns from two or
594         * more tables.
595         *
596         * @param array \$row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
597         * @param int \$startcol 0-based offset column which indicates which restultset column to start with.
598         * @return int next starting column
599         * @throws PropelException  - Any caught Exception will be rewrapped as a PropelException.
600         */
601        public function hydrate(\$row, \$startcol = 0)
602        {
603                try {
604";
605                        $n = 0;
606                        foreach($table->getColumns() as $col) {
607                                if(!$col->isLazyLoad()) {
608                                        // $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType()));
609                                        $clo = strtolower($col->getName());
610                                        switch($col->getType()) {
611
612                                                case PropelTypes::DATE:
613                                                case PropelTypes::TIME:
614                                                case PropelTypes::TIMESTAMP:
615                                                        $script .= "
616                        \$this->$clo = \$row[\$startcol + $n]; // FIXME - this is a timestamp, we should maybe convert it (?)
617";
618                                                        break;
619                                                default:
620                                                        $script .= "
621                        \$this->$clo = \$row[\$startcol + $n];
622";
623                                        }
624                                        $n++;
625                                } // if col->isLazyLoad()
626                        } /* foreach */
627
628                        if ($this->getBuildProperty("addSaveMethod")) {
629                                $script .= "
630                        \$this->resetModified();
631";
632                        }
633
634                        $script .= "
635                        \$this->setNew(false);
636
637                        // FIXME - using NUM_COLUMNS may be clearer.
638                        return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS).
639
640                } catch (Exception \$e) {
641                        throw new PropelException(\"Error populating ".$table->getPhpName()." object\", \$e);
642                }
643        }
644";
645
646        } // addHydrate()
647
648
649        /**
650         *
651         */
652        protected function addBuildPkeyCriteria(&$script) {
653
654
655                $script .= "
656        /**
657         * Builds a Criteria object containing the primary key for this object.
658         *
659         * Unlike buildCriteria() this method includes the primary key values regardless
660         * of whether or not they have been modified.
661         *
662         * @return Criteria The Criteria object containing value(s) for primary key(s).
663         */
664        public function buildPkeyCriteria()
665        {
666                \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
667";
668                foreach ($this->getTable()->getColumns() as $col) {
669                        $clo = strtolower($col->getName());
670                        if ($col->isPrimaryKey()) {
671                                $script .= "
672                \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
673                        }
674                }
675
676                $script .= "
677
678                return \$criteria;
679        }
680";
681
682        }
683
684        /**
685         *
686         */
687        protected function addBuildCriteria(&$script)
688        {
689                $script .= "
690        /**
691         * Build a Criteria object containing the values of all modified columns in this object.
692         *
693         * @return Criteria The Criteria object containing all modified values.
694         */
695        public function buildCriteria()
696        {
697                \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
698";
699                foreach ($this->getTable()->getColumns() as $col) {
700                        $clo = strtolower($col->getName());
701                        $script .= "
702                if (\$this->isColumnModified(".$this->getColumnConstant($col).")) \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
703                }
704                $script .= "
705
706                return \$criteria;
707        }
708";
709        } // addBuildCriteria()
710
711        protected function addToArray(&$script)
712        {
713                $script .= "
714        /**
715         * Exports the object as an array.
716         *
717         * You can specify the key type of the array by passing one of the class
718         * type constants.
719         *
720         * @param string \$keyType One of the class type constants TYPE_PHPNAME,
721         *                        TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM
722         * @return an associative array containing the field names (as keys) and field values
723         */
724        public function toArray(\$keyType = BasePeer::TYPE_PHPNAME)
725        {
726                \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
727                \$result = array(";
728                foreach ($this->getTable()->getColumns() as $num => $col) {
729                        $script .= "
730                        \$keys[$num] => \$this->get".$col->getPhpName()."(),";
731                }
732                $script .= "
733                );
734                return \$result;
735        }
736";
737        } // addToArray()
738
739        protected function addGetByName(&$script)
740        {
741                $script .= "
742        /**
743         * Retrieves a field from the object by name passed in as a string.
744         *
745         * @param string \$name name
746         * @param string \$type The type of fieldname the \$name is of:
747         *                     one of the class type constants TYPE_PHPNAME,
748         *                     TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM
749         * @return mixed Value of field.
750         */
751        public function getByName(\$name, \$type = BasePeer::TYPE_PHPNAME)
752        {
753                \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
754                return \$this->getByPosition(\$pos);
755        }
756";
757        }
758
759        protected function addGetByPosition(&$script)
760        {
761                $table = $this->getTable();
762                $script .= "
763        /**
764         * Retrieves a field from the object by Position as specified in the xml schema.
765         * Zero-based.
766         *
767         * @param int \$pos position in xml schema
768         * @return mixed Value of field at \$pos
769         */
770        public function getByPosition(\$pos)
771        {
772                switch(\$pos) {";
773        $i = 0;
774        foreach ($table->getColumns() as $col) {
775                $cfc = $col->getPhpName();
776                $cptype = $col->getPhpNative();// not safe to use it because some methods may return objects (Blob)
777$script .= "
778                        case $i:
779                                return \$this->get$cfc();
780                                break;";
781                $i++;
782        } /* foreach */
783$script .= "
784                        default:
785                                return null;
786                                break;
787                } // switch()
788        }
789";
790        }
791
792        protected function addSetByName(&$script)
793        {
794                $table = $this->getTable();
795                $script .= "
796        /**
797         * Sets a field from the object by name passed in as a string.
798         *
799         * @param string \$name peer name
800         * @param mixed \$value field value
801         * @param string \$type The type of fieldname the \$name is of:
802         *                     one of the class type constants TYPE_PHPNAME,
803         *                     TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM
804         * @return void
805         */
806        public function setByName(\$name, \$value, \$type = BasePeer::TYPE_PHPNAME)
807        {
808                \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
809                return \$this->setByPosition(\$pos, \$value);
810        }
811";
812        }
813
814        protected function addSetByPosition(&$script)
815        {
816                $table = $this->getTable();
817                $script .= "
818        /**
819         * Sets a field from the object by Position as specified in the xml schema.
820         * Zero-based.
821         *
822         * @param int \$pos position in xml schema
823         * @param mixed \$value field value
824         * @return void
825         */
826        public function setByPosition(\$pos, \$value)
827        {
828                switch(\$pos) {";
829                $i = 0;
830                foreach ($table->getColumns() as $col) {
831                        $cfc = $col->getPhpName();
832                        $cptype = $col->getPhpNative();
833                        $script .= "
834                        case $i:
835                                \$this->set$cfc(\$value);
836                                break;";
837                        $i++;
838                } /* foreach */
839                $script .= "
840                } // switch()
841        }
842";
843        } // addSetByPosition()
844
845        protected function addFromArray(&$script)
846        {
847                $table = $this->getTable();
848                $script .= "
849        /**
850         * Populates the object using an array.
851         *
852         * This is particularly useful when populating an object from one of the
853         * request arrays (e.g. \$_POST).  This method goes through the column
854         * names, checking to see whether a matching key exists in populated
855         * array. If so the setByName() method is called for that column.
856         *
857         * You can specify the key type of the array by additionally passing one
858         * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME,
859         * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId')
860         *
861         * @param array  \$arr     An array to populate the object from.
862         * @param string \$keyType The type of keys the array uses.
863         * @return void
864         */
865        public function fromArray(\$arr, \$keyType = BasePeer::TYPE_PHPNAME)
866        {
867                \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
868";
869                foreach ($table->getColumns() as $num => $col) {
870                        $cfc = $col->getPhpName();
871                        $cptype = $col->getPhpNative();
872                        $script .= "
873                if (array_key_exists(\$keys[$num], \$arr)) \$this->set$cfc(\$arr[\$keys[$num]]);";
874                } /* foreach */
875                $script .= "
876        }
877";
878        } // addFromArray
879
880
881
882        protected function addDelete(&$script)
883        {
884                $script .= "
885        /**
886         * Removes this object from datastore and sets delete attribute.
887         *
888         * @param PDO \$con
889         * @return void
890         * @throws PropelException
891         * @see BaseObject::setDeleted()
892         * @see BaseObject::isDeleted()
893         */
894        public function delete(PDO \$con = null)
895        {
896                if (\$this->isDeleted()) {
897                        throw new PropelException(\"This object has already been deleted.\");
898                }
899
900                if (\$con === null) {
901                        \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME);
902                }
903
904                try {
905                        \$con->beginTransaction();
906                        ".$this->getPeerClassname()."::doDelete(\$this, \$con);
907                        \$this->setDeleted(true);
908                        \$con->commit();
909                } catch (PropelException \$e) {
910                        \$con->rollback();
911                        throw \$e;
912                }
913        }
914";
915        } // addDelete()
916
917        /**
918         * Adds the methods related to saving and deleting the object.
919         * @param string &$script The script will be modified in this method.
920         */
921        protected function addManipulationMethods(&$script)
922        {
923                $this->addDelete($script);
924                $this->addSave($script);
925        }
926
927        /**
928         * Adds the methods related to validationg the object.
929         * @param string &$script The script will be modified in this method.
930         */
931        protected function addValidationMethods(&$script)
932        {
933                $this->addValidationFailuresAttribute($script);
934                $this->addGetValidationFailures($script);
935                $this->addValidate($script);
936        }
937
938        /**
939         * Adds the save() method.
940         * @param string &$script The script will be modified in this method.
941         */
942        protected function addSave(&$script)
943        {
944                $table = $this->getTable();
945                $script .= "
946        /**
947         * Stores the object in the database.
948         *
949         * If the object is new, it inserts it; otherwise an update is performed.
950         *
951         * @param PDO \$con
952         * @return int The number of rows affected by this insert/update operation (for non-complex OM this will be at most 1).
953         * @throws PropelException
954         */
955        public function save(\$con = null)
956        {
957                \$affectedRows = 0; // initialize var to track total num of affected rows
958
959                // If this object has been modified, then save it to the database.
960                if (\$this->isModified()) {
961                        if (\$this->isNew()) {
962                                \$pk = ".$this->getPeerClassname()."::doInsert(\$this, \$con);
963                                \$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which
964                                                                         // should always be true here (even though technically
965                                                                         // BasePeer::doInsert() can insert multiple rows).
966";
967                if ($table->getIdMethod() != "none") {
968                        if (count($pks = $table->getPrimaryKey())) {
969                                foreach ($pks as $pk) {
970                                        if ($pk->isAutoIncrement()) {
971                                                $script .= "
972                                        \$this->set".$pk->getPhpName()."(\$pk);  //[IMV] update autoincrement primary key
973";
974                                        }
975                                }
976                        }
977                }
978                $script .= "
979                                        \$this->setNew(false);
980                        } else {
981                                        \$affectedRows += ".$this->getPeerClassname()."::doUpdate(\$this, \$con);
982                        }
983                        \$this->resetModified(); // [HL] After being saved an object is no longer 'modified'
984                        ".$this->getPeerClassname()."::addInstanceToPool(\$this);
985                } // if \$this->isModified()
986
987                return \$affectedRows;
988        } // save()
989";
990
991        } // addSave()
992
993        /**
994         * Adds the $validationFailures attribute to store ValidationFailed objects.
995         * @param string &$script The script will be modified in this method.
996         */
997        protected function addValidationFailuresAttribute(&$script)
998        {
999                $script .= "
1000        /**
1001         * Array of ValidationFailed objects.
1002         * @var array ValidationFailed[]
1003         */
1004        protected \$validationFailures = array();
1005";
1006        }
1007
1008        /**
1009         * Adds the validate() method.
1010         * @param string &$script The script will be modified in this method.
1011         */
1012        protected function addValidate(&$script)
1013        {
1014                $script .= "
1015        /**
1016         * Validates the objects modified field values.
1017         *
1018         * If \$columns is either a column name or an array of column names
1019         * only those columns are validated.
1020         *
1021         * @param mixed \$columns Column name or an array of column names.
1022         *
1023         * @return mixed <code>true</code> if all columns pass validation
1024         *                        or an array of <code>ValidationFailed</code> objects for columns that fail.
1025         */
1026        public function validate(\$columns = null)
1027        {
1028                if (\$columns) {
1029                        return ".$this->getPeerClassname()."::doValidate(\$this, \$columns);
1030                }
1031                return ".$this->getPeerClassname()."::doValidate(\$this);
1032        }
1033";
1034
1035        } // addValidate()
1036
1037        /**
1038         * Adds the getValidationFailures() method.
1039         * @param string &$script The script will be modified in this method.
1040         */
1041        protected function addGetValidationFailures(&$script)
1042        {
1043                $script .= "
1044        /**
1045         * Gets any ValidationFailed objects that resulted from last call to validate().
1046         *
1047         *
1048         * @return array ValidationFailed[]
1049         * @see validate()
1050         */
1051        public function getValidationFailures()
1052        {
1053                return \$this->validationFailures;
1054        }
1055";
1056        } // addGetValidationFailures()
1057
1058        /**
1059         * Adds the correct getPrimaryKey() method for this object.
1060         * @param string &$script The script will be modified in this method.
1061         */
1062        protected function addGetPrimaryKey(&$script)
1063        {
1064                $pkeys = $this->getTable()->getPrimaryKey();
1065                if (count($pkeys) == 1) {
1066                    $this->addGetPrimaryKey_SinglePK($script);
1067                } elseif (count($pkeys) > 1) {
1068                        $this->addGetPrimaryKey_MultiPK($script);
1069                } else {
1070                        // no primary key -- this is deprecated, since we don't *need* this method anymore
1071                        $this->addGetPrimaryKey_NoPK($script);
1072                }
1073        }
1074
1075        /**
1076         * Adds the getPrimaryKey() method for tables that contain a single-column primary key.
1077         * @param string &$script The script will be modified in this method.
1078         */
1079        protected function addGetPrimaryKey_SinglePK(&$script)
1080        {
1081                $table = $this->getTable();
1082                $pkeys = $table->getPrimaryKey();
1083                $cptype = $pkeys[0]->getPhpType();
1084
1085                $script .= "
1086        /**
1087         * Returns the primary key for this object (row).
1088         * @return $cptype
1089         */
1090        public function getPrimaryKey()
1091        {
1092                return \$this->get".$pkeys[0]->getPhpName()."();
1093        }
1094";
1095        } // addetPrimaryKey_SingleFK
1096
1097        /**
1098         * Adds the setPrimaryKey() method for tables that contain a multi-column primary key.
1099         * @param string &$script The script will be modified in this method.
1100         */
1101        protected function addGetPrimaryKey_MultiPK(&$script)
1102        {
1103
1104                $script .= "
1105        /**
1106         * Returns the composite primary key for this object.
1107         * The array elements will be in same order as specified in XML.
1108         * @return array
1109         */
1110        public function getPrimaryKey()
1111        {
1112                \$pks = array();
1113";
1114                $i = 0;
1115                foreach ($this->getTable()->getPrimaryKey() as $pk) {
1116                        $script .= "
1117                \$pks[$i] = \$this->get".$pk->getPhpName()."();
1118";
1119                        $i++;
1120                } /* foreach */
1121                $script .= "
1122                return \$pks;
1123        }
1124";
1125        } // addGetPrimaryKey_MultiFK()
1126
1127        /**
1128         * Adds the getPrimaryKey() method for objects that have no primary key.
1129         * This "feature" is dreprecated, since the getPrimaryKey() method is not required
1130         * by the Persistent interface (or used by the templates).  Hence, this method is also
1131         * deprecated.
1132         * @param string &$script The script will be modified in this method.
1133         * @deprecated
1134         */
1135        protected function addGetPrimaryKey_NoPK(&$script)
1136        {
1137                $script .= "
1138        /**
1139         * Returns NULL since this table doesn't have a primary key.
1140         * This method exists only for BC and is deprecated!
1141         * @return null
1142         */
1143        public function getPrimaryKey()
1144        {
1145                return null;
1146        }
1147";
1148        }
1149        /**
1150         * Adds the correct setPrimaryKey() method for this object.
1151         * @param string &$script The script will be modified in this method.
1152         */
1153        protected function addSetPrimaryKey(&$script)
1154        {
1155                $pkeys = $this->getTable()->getPrimaryKey();
1156                if (count($pkeys) == 1) {
1157                    $this->addSetPrimaryKey_SinglePK($script);
1158                } elseif (count($pkeys) > 1) {
1159                        $this->addSetPrimaryKey_MultiPK($script);
1160                } else {
1161                        // no primary key -- this is deprecated, since we don't *need* this method anymore
1162                        $this->addSetPrimaryKey_NoPK($script);
1163                }
1164        }
1165
1166        /**
1167         * Adds the setPrimaryKey() method for tables that contain a single-column primary key.
1168         * @param string &$script The script will be modified in this method.
1169         */
1170        protected function addSetPrimaryKey_SinglePK(&$script)
1171        {
1172
1173                $pkeys = $this->getTable()->getPrimaryKey();
1174                $col = $pkeys[0];
1175                $clo=strtolower($col->getName());
1176                $ctype = $col->getPhpNative();
1177
1178                $script .= "
1179        /**
1180         * Generic method to set the primary key ($clo column).
1181         *
1182         * @param $ctype \$key Primary key.
1183         * @return void
1184         */
1185        public function setPrimaryKey(\$key)
1186        {
1187                \$this->set".$col->getPhpName()."(\$key);
1188        }
1189";
1190        } // addSetPrimaryKey_SinglePK
1191
1192        /**
1193         * Adds the setPrimaryKey() method for tables that contain a multi-columnprimary key.
1194         * @param string &$script The script will be modified in this method.
1195         */
1196        protected function addSetPrimaryKey_MultiPK(&$script)
1197        {
1198
1199                $script .="
1200        /**
1201         * Set the [composite] primary key.
1202         *
1203         * @param array \$keys The elements of the composite key (order must match the order in XML file).
1204         * @return void
1205         */
1206        public function setPrimaryKey(\$keys)
1207        {
1208";
1209                        $i = 0;
1210                        foreach ($this->getTable()->getPrimaryKey() as $pk) {
1211                                $pktype = $pk->getPhpNative();
1212                                $script .= "
1213                \$this->set".$pk->getPhpName()."(\$keys[$i]);
1214";
1215                                $i++;
1216                        } /* foreach ($table->getPrimaryKey() */
1217                        $script .= "
1218        }
1219";
1220        } // addSetPrimaryKey_MultiPK
1221
1222        /**
1223         * Adds the setPrimaryKey() method for objects that have no primary key.
1224         * This "feature" is dreprecated, since the setPrimaryKey() method is not required
1225         * by the Persistent interface (or used by the templates).  Hence, this method is also
1226         * deprecated.
1227         * @param string &$script The script will be modified in this method.
1228         * @deprecated
1229         */
1230        protected function addSetPrimaryKey_NoPK(&$script)
1231        {
1232                $script .="
1233        /**
1234         * Dummy primary key setter.
1235         *
1236         * This function only exists to preserve backwards compatibility.  It is no longer
1237         * needed or required by the Persistent interface.  It will be removed in next BC-breaking
1238         * release of Propel.
1239         *
1240         * @deprecated
1241         */
1242         public function setPrimaryKey(\$pk)
1243         {
1244                 // do nothing, because this object doesn't have any primary keys
1245         }
1246";
1247        }
1248
1249        /**
1250         * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects.
1251         * @param string &$script The script will be modified in this method.
1252         */
1253        protected function addCopy(&$script)
1254        {
1255                $this->addCopyInto($script);
1256
1257                $table = $this->getTable();
1258
1259                $script .= "
1260        /**
1261         * Makes a copy of this object that will be inserted as a new row in table when saved.
1262         * It creates a new object filling in the simple attributes, but skipping any primary
1263         * keys that are defined for the table.
1264         *
1265         * @return ".$this->getObjectClassname()." Clone of current object.
1266         * @throws PropelException
1267         */
1268        public function copy()
1269        {
1270                // we use get_class(), because this might be a subclass
1271                \$clazz = get_class(\$this);
1272                \$copyObj = new \$clazz();
1273                \$this->copyInto(\$copyObj);
1274                return \$copyObj;
1275        }
1276";
1277        } // addCopy()
1278
1279        /**
1280         * Adds the copy() method.
1281         */
1282        protected function addCopyInto(&$script)
1283        {
1284                $table = $this->getTable();
1285
1286                $script .= "
1287        /**
1288         * Sets contents of passed object to values from current object.
1289         *
1290         * @param object \$copyObj An object of ".$this->getObjectClassname()." (or compatible) type.
1291         * @return ".$this->getObjectClassname()." Clone of current object.
1292         * @throws PropelException
1293         */
1294        public function copyInto(\$copyObj)
1295        {
1296";
1297
1298                $pkcols = array();
1299                foreach ($table->getColumns() as $pkcol) {
1300                        if ($pkcol->isPrimaryKey()) {
1301                                $pkcols[] = $pkcol->getName();
1302                        }
1303                }
1304
1305                foreach ($table->getColumns() as $col) {
1306                        if (!in_array($col->getName(), $pkcols)) {
1307                                $script .= "
1308                \$copyObj->set<?php echo $col->getPhpName()?>(\$this-><?php echo strtolower($col->getName()) ?>);";
1309                        }
1310                } // foreach
1311
1312                $script .= "
1313
1314                \$copyObj->setNew(true);";
1315
1316                foreach ($table->getColumns() as $col) {
1317                        if ($col->isPrimaryKey()) {
1318                                $coldefval = $col->getPhpDefaultValue();
1319                                $coldefval = var_export($coldefval, true);
1320                                $script .= "
1321                \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a pkey column, so set to default value";
1322                        } // if col->isPrimaryKey
1323                } // foreach
1324                $script .= "
1325                return \$copyObj;
1326        }
1327";
1328        } // addCopy()
1329
1330} // PHP5BasicObjectBuilder
Note: See TracBrowser for help on using the repository browser.