getDispatcher()->notifyUntil(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.' . \$method, array('arguments' => \$arguments, 'method' => \$method))); if (\$event->isProcessed()) { return \$event->getReturnValue(); } if (!\$callable = sfMixer::getCallable('{$this->getClassname()}:'.\$method)) { throw new sfException(sprintf('Call to undefined method {$this->getClassname()}::%s', \$method)); } array_unshift(\$arguments, \$this); return call_user_func_array(\$callable, \$arguments); } "; } public function build() { // Get original built code $objectCode = parent::build(); // Remove useless includes if (!DataModelBuilder::getBuildProperty('builderAddIncludes')) { //remove all inline includes: //peer class include inline the mapbuilder classes $objectCode = preg_replace("/include_once\s*.*Base.*Peer\.php.*\s*/", "", $objectCode); } return $objectCode; } protected function addFKAccessor(&$script, ForeignKey $fk) { // Make original modifications parent::addFKAccessor($script, $fk); // With the explicit joins support, the related object returned can be hydrated with all NULL values, in this case we could simply return NULL if (!DataModelBuilder::getBuildProperty('builderHydrateNULLs')) { $varName = $this->getFKVarName($fk); $return = 'return $this->' . $varName . ';'; $check_null_hydrated_script = ' if (!is_null($this->' . $varName . ') && !$this->' . $varName . '->isNew() && is_null($this->' . $varName . '->getPrimaryKey())) { return NULL; } ' . $return; $script = str_replace($return, $check_null_hydrated_script, $script); } } /** * Adds setter method for "normal" columns. * @param string &$script The script will be modified in this method. * @param Column $col The current column. * @see parent::addColumnMutators() */ protected function addDefaultMutator(&$script, Column $col) { $clo = strtolower($col->getName()); // FIXME: refactor this $defaultValue = null; if (($val = $col->getPhpDefaultValue()) !== null) { settype($val, $col->getPhpNative()); $defaultValue = var_export($val, true); } $this->addMutatorOpen($script, $col); // Perform some smart checking here to handle possible type discrepancies // between the passed-in value and the value from the DB if ($col->getPhpType() != 'object' && $col->getPhpType() != 'array') { if ($col->getPhpNative() === "int") { $script .= " if (\$v !== null && !is_int(\$v) && is_numeric(\$v)) { \$v = (int) \$v; } "; } elseif ($col->getPhpNative() === "string") { $script .= " if (\$v !== null && !is_string(\$v)) { \$v = (string) \$v; } "; } elseif ($col->getPhpNative() === "boolean") { $script .= " if (\$v !== null && !is_bool(\$v)) { \$v = (bool) \$v; } "; } elseif ($col->getPhpNative() === "float" || $col->getPhpNative() === "double") { $script .= " if (\$v !== null && !is_float(\$v) && is_numeric(\$v)) { \$v = (float) \$v; } "; } } $script .= " if (\$this->$clo !== \$v"; if ($defaultValue !== null) { $script .= " || \$v === $defaultValue"; } $script .= ") { \$this->$clo = \$v; \$this->modifiedColumns[] = ".$this->getColumnConstant($col)."; } "; $this->addMutatorClose($script, $col); } /** * Adds a normal (non-temporal) getter method. * @param string &$script The script will be modified in this method. * @param Column $col The current column. * @see parent::addColumnAccessors() */ protected function addGenericAccessor(&$script, $col) { $cfc=$col->getPhpName(); $clo=strtolower($col->getName()); $script .= " /** * Get the [$clo] column value. * ".$col->getDescription()." * @return ".$col->getPhpNative()." */ public function get$cfc("; if ($col->isLazyLoad()) $script .= "\$con = null"; $script .= ") { "; if ($col->isLazyLoad()) { $script .= " if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) { \$this->load$cfc(\$con); } "; } if ($col->getType() == PropelTypes::DECIMAL) { $script .= " return null !== \$this->$clo ? (string)\$this->$clo : null; } "; } else { $script .= " return \$this->$clo; } "; } } protected function addDelete(&$script) { $script .= " /** * Removes this object from datastore and sets delete attribute. * * @param Connection \$con * @return void * @throws PropelException * @see BaseObject::setDeleted() * @see BaseObject::isDeleted() */ public function delete(\$con = null) { if (\$this->isDeleted()) { throw new PropelException(\"This object has already been deleted.\"); } if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.preDelete')) { \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.preDelete', array('con' => \$con))); } if (sfMixer::hasCallables('{$this->getClassname()}:delete:pre')) { foreach (sfMixer::getCallables('{$this->getClassname()}:delete:pre') as \$callable) { \$ret = call_user_func(\$callable, \$this, \$con); if (\$ret) { return; } } } if (\$con === null) { \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); } try { \$con->begin(); ".$this->getPeerClassname()."::doDelete(\$this, \$con); \$this->setDeleted(true); \$con->commit(); } catch (PropelException \$e) { \$con->rollback(); throw \$e; } if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.postDelete')) { \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.postDelete', array('con' => \$con))); } if (sfMixer::hasCallables('{$this->getClassname()}:delete:post')) { foreach (sfMixer::getCallables('{$this->getClassname()}:delete:post') as \$callable) { call_user_func(\$callable, \$this, \$con); } } } "; } // addDelete() /** * Adds the save() method. * @param string &$script The script will be modified in this method. */ protected function addSave(&$script) { $updated = false; $created = false; $date_script = ''; foreach ($this->getTable()->getColumns() as $col) { $clo = strtolower($col->getName()); if (!$updated && in_array($clo, array('updated_at', 'updated_on'))) { $updated = true; $date_script .= " if (\$this->isModified() && !\$this->isColumnModified(".$this->getColumnConstant($col).")) { \$this->set".$col->getPhpName()."(time()); } "; } else if (!$created && in_array($clo, array('created_at', 'created_on'))) { $created = true; $date_script .= " if (\$this->isNew() && !\$this->isColumnModified(".$this->getColumnConstant($col).")) { \$this->set".$col->getPhpName()."(time()); } "; } } $script .= " /** * Stores the object in the database. If the object is new, * it inserts it; otherwise an update is performed. This method * wraps the doSave() worker method in a transaction. * * @param Connection \$con * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. * @throws PropelException * @see doSave() */ public function save(\$con = null) { if (\$this->isDeleted()) { throw new PropelException(\"You cannot save an object that has been deleted.\"); } if (!\$this->alreadyInSave) { if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.preSave')) { \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.preSave', array('con' => \$con))); } foreach (sfMixer::getCallables('{$this->getClassname()}:save:pre') as \$callable) { \$affectedRows = call_user_func(\$callable, \$this, \$con); if (is_int(\$affectedRows)) { return \$affectedRows; } } } $date_script if (\$con === null) { \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); } try { \$con->begin(); \$affectedRows = \$this->doSave(\$con); \$con->commit(); if (!\$this->alreadyInSave) { if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.postSave')) { \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.postSave', array('con' => \$con))); } foreach (sfMixer::getCallables('{$this->getClassname()}:save:post') as \$callable) { call_user_func(\$callable, \$this, \$con, \$affectedRows); } } return \$affectedRows; } catch (PropelException \$e) { \$con->rollback(); throw \$e; } } "; } /** * Adds the hydrate() method, which sets attributes of the object based on a ResultSet. */ protected function addHydrate(&$script) { $table = $this->getTable(); $script .= " /** * Hydrates (populates) the object variables with values from the database resultset. * * An offset (1-based \"start column\") is specified so that objects can be hydrated * with a subset of the columns in the resultset rows. This is needed, for example, * for results of JOIN queries where the resultset row includes columns from two or * more tables. * * @param ResultSet \$rs The ResultSet class with cursor advanced to desired record pos. * @param int \$startcol 1-based offset column which indicates which restultset column to start with. * @return int next starting column * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. */ public function hydrate(ResultSet \$rs, \$startcol = 1) { try { if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.preHydrate')) { \$event = \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.preHydrate', array('resultset' => \$rs, 'startcol' => \$startcol))); \$startcol = \$event['startcol']; } "; $n = 0; foreach($table->getColumns() as $col) { if(!$col->isLazyLoad()) { $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType())); $clo = strtolower($col->getName()); switch($col->getType()) { case PropelTypes::DATE: case PropelTypes::TIME: case PropelTypes::TIMESTAMP: $script .= " \$this->$clo = \$rs->get$affix(\$startcol + $n, null); "; break; case PropelTypes::DECIMAL: $script .= " \$this->$clo = \$rs->getString(\$startcol + $n); if (null !== \$this->$clo && \$this->$clo == intval(\$this->$clo)) { \$this->$clo = (string)intval(\$this->$clo); } "; break; default: if ($col->getPhpType() == 'array' || $col->getPhpType() == 'object') { $script .= " \$this->$clo = \$rs->get$affix(\$startcol + $n) ? unserialize(\$rs->get$affix(\$startcol + $n)) : null; "; } else { $script .= " \$this->$clo = \$rs->get$affix(\$startcol + $n); "; } } $n++; } // if col->isLazyLoad() } /* foreach */ if ($this->getBuildProperty("addSaveMethod")) { $script .= " \$this->resetModified(); "; } $script .= " \$this->setNew(false); if (\$this->getDispatcher()->getListeners('{$this->getStubObjectBuilder()->getClassname()}.postHydrate')) { \$event = \$this->getDispatcher()->notify(new sfEvent(\$this, '{$this->getStubObjectBuilder()->getClassname()}.postHydrate', array('resultset' => \$rs, 'startcol' => \$startcol + $n))); return \$event['startcol']; } // FIXME - using NUM_COLUMNS may be clearer. return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS). } catch (Exception \$e) { throw new PropelException(\"Error populating ".$table->getPhpName()." object\", \$e); } } "; } // addHydrate() }