Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 99e125ebc6
Fetching contributors…

Cannot retrieve contributors at this time

2858 lines (2517 sloc) 106.452 kb
<?php
/**
* This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/
namespace Propel\Generator\Builder\Om;
use Propel\Generator\Model\Table;
use Propel\Generator\Model\ForeignKey;
use Propel\Generator\Exception\EngineException;
/**
* Generates a PHP5 base Peer class for user object model (OM).
*
* This class produces the base peer class (e.g. BaseMyPeer) which contains all
* the custom-built query and manipulator methods.
*
* @author Hans Lellelid <hans@xmpl.org>
*/
class PeerBuilder extends AbstractPeerBuilder
{
/**
* Validates the current table to make sure that it won't
* result in generated code that will not parse.
*
* This method may emit warnings for code which may cause problems
* and will throw exceptions for errors that will definitely cause
* problems.
*
* @throws EngineException
*/
protected function validateModel()
{
parent::validateModel();
$table = $this->getTable();
// Check to see if any of the column constants are PHP reserved words.
$colConstants = array();
foreach ($table->getColumns() as $col) {
$colConstants[] = $this->getColumnName($col);
}
$reservedConstants = array_map('strtoupper', ClassTools::getPhpReservedWords());
$intersect = array_intersect($reservedConstants, $colConstants);
if (!empty($intersect)) {
throw new EngineException(sprintf('One or more of your column names for [%s] table conflict with a PHP reserved word (%s).', $table->getName(), implode(', ', $intersect)));
}
}
/**
* Returns the name of the current class being built.
*
* @return string
*/
public function getUnprefixedClassName()
{
return $this->getStubPeerBuilder()->getUnprefixedClassName();
}
/**
* Returns the package for the [base] peer classes.
*
* @return string
*/
public function getPackage()
{
return parent::getPackage() . ".Base";
}
/**
* Returns the namespace for the [base] peer classes.
*
* @return string
*/
public function getNamespace()
{
if ($namespace = parent::getNamespace()) {
return $namespace . '\\Base';
}
return 'Base';
}
/**
* Adds class phpdoc comment and opening of class.
*
* @param string &$script
*/
protected function addClassOpen(&$script)
{
$tableName = $this->getTable()->getName();
$tableDesc = $this->getTable()->getDescription();
$script .= "
/**
* Base static class for performing query and update operations on the '$tableName' table.
*
* $tableDesc
*";
if ($this->getBuildProperty('addTimeStamp')) {
$now = strftime('%c');
$script .= "
* This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
*
* $now
*";
}
$extendingPeerClass = '';
$parentClass = $this->getBehaviorContent('parentClass');
if (null !== $parentClass) {
$extendingPeerClass = ' extends '.$parentClass;
} elseif ('BasePeer' !== $this->basePeerClassName) {
$extendingPeerClass = ' extends '.$this->basePeerClassName;
}
$script .= "
*/
abstract class ".$this->getUnqualifiedClassName(). $extendingPeerClass . " {
";
}
/**
* @param string &$script
*/
protected function addClassBody(&$script)
{
$this->declareClassFromBuilder($this->getStubObjectBuilder());
parent::addClassBody($script);
$this->declareClasses(
'\Propel\Runtime\Propel',
'\Propel\Runtime\Connection\ConnectionInterface',
'\Propel\Runtime\Connection\StatementInterface',
'\Propel\Runtime\Exception\PropelException',
'\Propel\Runtime\Util\BasePeer',
'\Propel\Runtime\ActiveQuery\Criteria',
'\PDO'
);
}
/**
* Closes class.
* Adds closing brace at end of class and the static
* map builder registration code.
* @param string &$script The script will be modified in this method.
* @see addStaticTableMapRegistration()
*/
protected function addClassClose(&$script)
{
$this->applyBehaviorModifier('staticMethods', $script, ' ');
$script .= "
} // " . $this->getUnqualifiedClassName() . "
";
$this->addStaticTableMapRegistration($script);
}
/**
* Adds the static map builder registration code.
* @param string &$script The script will be modified in this method.
*/
protected function addStaticTableMapRegistration(&$script)
{
$script .= "
// This is the static code needed to register the TableMap for this table with the main Propel class.
//
".$this->getUnqualifiedClassName()."::buildTableMap();
";
$this->applyBehaviorModifier('peerFilter', $script, '');
}
/**
* @return string
*/
public function getTableMapClass()
{
return $this->getStubObjectBuilder()->getUnqualifiedClassName() . 'TableMap';
}
/**
* @return string
*/
public function getTablePhpName()
{
return ($this->getTable()->isAbstract() ? '' : $this->getClassNameFromBuilder($this->getStubObjectBuilder()));
}
/**
* Adds constant and variable declarations that go at the top of the class.
* @param string &$script The script will be modified in this method.
* @see addColumnNameConstants()
*/
protected function addConstantsAndAttributes(&$script)
{
$dbName = $this->getDatabase()->getName();
$tableName = $this->getTable()->getName();
$tablePhpName = $this->getTable()->isAbstract() ? '' : addslashes($this->getStubObjectBuilder()->getFullyQualifiedClassName());
$script .= "
/** the default database name for this class */
const DATABASE_NAME = '$dbName';
/** the table name for this class */
const TABLE_NAME = '$tableName';
/** the related Propel class for this table */
const OM_CLASS = '$tablePhpName';
/** A class that can be returned by this peer. */
const CLASS_DEFAULT = '".$this->getStubObjectBuilder()->getClasspath()."';
/** the related TableMap class for this table */
const TM_CLASS = '".$this->getTableMapClass()."';
/** The total number of columns. */
const NUM_COLUMNS = ".$this->getTable()->getNumColumns().";
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = ".$this->getTable()->getNumLazyLoadColumns().";
/** The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */
const NUM_HYDRATE_COLUMNS = ". ($this->getTable()->getNumColumns() - $this->getTable()->getNumLazyLoadColumns()) .";
";
$this->addColumnNameConstants($script);
$this->addInheritanceColumnConstants($script);
if ($this->getTable()->hasEnumColumns()) {
$this->addEnumColumnConstants($script);
}
$script .= "
/** The default string format for model objects of the related table **/
const DEFAULT_STRING_FORMAT = '" . $this->getTable()->getDefaultStringFormat() . "';
/**
* An identity map to hold any loaded instances of ".$this->getObjectClassName()." objects.
* This must be public so that other peer classes can access this when hydrating from JOIN
* queries.
* @var array ".$this->getObjectClassName()."[]
*/
static public \$instances = array();
";
// apply behaviors
$this->applyBehaviorModifier('staticConstants', $script, " ");
$this->applyBehaviorModifier('staticAttributes', $script, " ");
$this->addFieldNamesAttribute($script);
$this->addFieldKeysAttribute($script);
if ($this->getTable()->hasEnumColumns()) {
$this->addEnumColumnAttributes($script);
}
}
/**
* Adds the COLUMN_NAME constant to the class definition.
* @param string &$script The script will be modified in this method.
*/
protected function addColumnNameConstants(&$script)
{
foreach ($this->getTable()->getColumns() as $col) {
$script .= "
/** the column name for the " . strtoupper($col->getName()) ." field */
const ".$this->getColumnName($col) ." = '" . $this->getTable()->getName() . ".".strtoupper($col->getName())."';
";
} // foreach
}
/**
* Adds the valueSet constants for ENUM columns.
* @param string &$script The script will be modified in this method.
*/
protected function addEnumColumnConstants(&$script)
{
foreach ($this->getTable()->getColumns() as $col) {
if ($col->isEnumType()) {
$script .= "
/** The enumerated values for the " . strtoupper($col->getName()) . " field */";
foreach ($col->getValueSet() as $value) {
$script .= "
const " . $this->getColumnName($col) . '_' . $this->getEnumValueConstant($value) . " = '" . $value . "';";
}
$script .= "
";
}
}
}
/**
* @param string $value
* @return string
*/
protected function getEnumValueConstant($value)
{
return strtoupper(preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '_', $value));
}
/**
* @param string &$script
*/
protected function addFieldNamesAttribute(&$script)
{
$table = $this->getTable();
$tableColumns = $table->getColumns();
$script .= "
/**
* holds an array of fieldnames
*
* first dimension keys are the type constants
* e.g. self::\$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
protected static \$fieldNames = array (
BasePeer::TYPE_PHPNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'".$col->getPhpName()."', ";
}
$script .= "),
BasePeer::TYPE_STUDLYPHPNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'".$col->getStudlyPhpName()."', ";
}
$script .= "),
BasePeer::TYPE_COLNAME => array (";
foreach ($tableColumns as $col) {
$script .= $this->getColumnConstant($col, 'self').", ";
}
$script .= "),
BasePeer::TYPE_RAW_COLNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'" . $col->getConstantColumnName() . "', ";
}
$script .= "),
BasePeer::TYPE_FIELDNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'".$col->getName()."', ";
}
$script .= "),
BasePeer::TYPE_NUM => array (";
foreach ($tableColumns as $num => $col) {
$script .= "$num, ";
}
$script .= ")
);
";
}
/**
* @param string &$script
*/
protected function addFieldKeysAttribute(&$script)
{
$table = $this->getTable();
$tableColumns = $table->getColumns();
$script .= "
/**
* holds an array of keys for quick access to the fieldnames array
*
* first dimension keys are the type constants
* e.g. self::\$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
protected static \$fieldKeys = array (
BasePeer::TYPE_PHPNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'".$col->getPhpName()."' => $num, ";
}
$script .= "),
BasePeer::TYPE_STUDLYPHPNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'".$col->getStudlyPhpName()."' => $num, ";
}
$script .= "),
BasePeer::TYPE_COLNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= $this->getColumnConstant($col, 'self')." => $num, ";
}
$script .= "),
BasePeer::TYPE_RAW_COLNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'" . $col->getConstantColumnName() . "' => $num, ";
}
$script .= "),
BasePeer::TYPE_FIELDNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'".$col->getName()."' => $num, ";
}
$script .= "),
BasePeer::TYPE_NUM => array (";
foreach ($tableColumns as $num => $col) {
$script .= "$num, ";
}
$script .= ")
);
";
} // addFieldKeysAttribute
/**
* Adds the valueSet attributes for ENUM columns.
* @param string &$script The script will be modified in this method.
*/
protected function addEnumColumnAttributes(&$script)
{
$script .= "
/** The enumerated values for this table */
protected static \$enumValueSets = array(";
foreach ($this->getTable()->getColumns() as $col) {
if ($col->isEnumType()) {
$script .= "
self::" . $this->getColumnName($col) ." => array(
";
foreach ($col->getValueSet() as $value) {
$script .= " self::" . $this->getColumnName($col) . '_' . $this->getEnumValueConstant($value) . ",
";
}
$script .= " ),";
}
}
$script .= "
);
";
}
/**
* @param string &$script
*/
protected function addGetFieldNames(&$script)
{
$script .= "
/**
* Returns an array of field names.
*
* @param string \$type The type of fieldnames to return:
* One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @return array A list of field names
* @throws PropelException
*/
public static function getFieldNames(\$type = BasePeer::TYPE_PHPNAME)
{
if (!array_key_exists(\$type, self::\$fieldNames)) {
throw new PropelException('Method getFieldNames() expects the parameter \$type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . \$type . ' was given.');
}
return self::\$fieldNames[\$type];
}
";
} // addGetFieldNames()
/**
* @param string &$script
*/
protected function addTranslateFieldName(&$script)
{
$script .= "
/**
* Translates a fieldname to another type
*
* @param string \$name field name
* @param string \$fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @param string \$toType One of the class type constants
* @return string translated name of the field.
* @throws PropelException - if the specified name could not be found in the fieldname mappings.
*/
public static function translateFieldName(\$name, \$fromType, \$toType)
{
\$toNames = self::getFieldNames(\$toType);
\$key = isset(self::\$fieldKeys[\$fromType][\$name]) ? self::\$fieldKeys[\$fromType][\$name] : null;
if (\$key === null) {
throw new PropelException(\"'\$name' could not be found in the field names of type '\$fromType'. These are: \" . print_r(self::\$fieldKeys[\$fromType], true));
}
return \$toNames[\$key];
}
";
} // addTranslateFieldName()
/**
* Adds the getValueSets() method.
* @param string &$script The script will be modified in this method.
*/
protected function addGetValueSets(&$script)
{
$script .= "
/**
* Gets the list of values for all ENUM columns
* @return array
*/
public static function getValueSets()
{
return static::\$enumValueSets;
}
";
}
/**
* Adds the getValueSet() method.
* @param string &$script The script will be modified in this method.
*/
protected function addGetValueSet(&$script)
{
$script .= "
/**
* Gets the list of values for an ENUM column
* @param string \$colname
* @return array list of possible values for the column
*/
public static function getValueSet(\$colname)
{
\$valueSets = self::getValueSets();
return \$valueSets[\$colname];
}
";
}
/**
* Adds the buildTableMap() method.
* @param string &$script The script will be modified in this method.
*/
protected function addBuildTableMap(&$script)
{
$this->declareClassFromBuilder($this->getTableMapBuilder());
$script .= "
/**
* Add a TableMap instance to the database for this peer class.
*/
public static function buildTableMap()
{
\$dbMap = Propel::getServiceContainer()->getDatabaseMap(static::DATABASE_NAME);
if (!\$dbMap->hasTable(static::TABLE_NAME)) {
\$dbMap->addTableObject(new ".$this->getTableMapClass()."());
}
}
";
}
/**
* Adds the CLASSKEY_* and CLASSNAME_* constants used for inheritance.
* @param string &$script The script will be modified in this method.
*/
public function addInheritanceColumnConstants(&$script)
{
if (!$col = $this->getTable()->getChildrenColumn()) {
return;
}
if (!$col->isEnumeratedClasses()) {
return;
}
foreach ($col->getChildren() as $child) {
$childBuilder = $this->getMultiExtendObjectBuilder();
$childBuilder->setChild($child);
$fqcn = addslashes($childBuilder->getFullyQualifiedClassName());
$script .= "
/** A key representing a particular subclass */
const CLASSKEY_".strtoupper($child->getKey())." = '" . $child->getKey() . "';
";
if (strtoupper($child->getClassName()) != strtoupper($child->getKey())) {
$script .= "
/** A key representing a particular subclass */
const CLASSKEY_".strtoupper($child->getClassname())." = '" . $fqcn . "';
";
}
$script .= "
/** A class that can be returned by this peer. */
const CLASSNAME_".strtoupper($child->getKey())." = '". $fqcn . "';
";
}
}
/**
* Adds the alias() utility method.
* @param string &$script The script will be modified in this method.
*/
protected function addAlias(&$script)
{
$script .= "
/**
* Convenience method which changes table.column to alias.column.
*
* Using this method you can maintain SQL abstraction while using column aliases.
* <code>
* \$c->addAlias(\"alias1\", TablePeer::TABLE_NAME);
* \$c->addJoin(TablePeer::alias(\"alias1\", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN);
* </code>
* @param string \$alias The alias for the current table.
* @param string \$column The column name for current table. (i.e. ".$this->getPeerClassName(true)."::COLUMN_NAME).
* @return string
*/
public static function alias(\$alias, \$column)
{
return str_replace(static::TABLE_NAME.'.', \$alias.'.', \$column);
}
";
}
/**
* Adds the addSelectColumns() method.
* @param string &$script The script will be modified in this method.
*/
protected function addAddSelectColumns(&$script)
{
$script .= "
/**
* Add all the columns needed to create a new object.
*
* Note: any columns that were marked with lazyLoad=\"true\" in the
* XML schema will not be added to the select list and only loaded
* on demand.
*
* @param Criteria \$criteria object containing the columns to add.
* @param string \$alias optional table alias
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function addSelectColumns(Criteria \$criteria, \$alias = null)
{
if (null === \$alias) {";
foreach ($this->getTable()->getColumns() as $col) {
if (!$col->isLazyLoad()) {
$script .= "
\$criteria->addSelectColumn(static::".$this->getColumnName($col).");";
} // if !col->isLazyLoad
} // foreach
$script .= "
} else {";
foreach ($this->getTable()->getColumns() as $col) {
if (!$col->isLazyLoad()) {
$script .= "
\$criteria->addSelectColumn(\$alias . '." . $col->getConstantColumnName()."');";
} // if !col->isLazyLoad
} // foreach
$script .= "
}";
$script .="
}
";
} // addAddSelectColumns()
/**
* Adds the doCount() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCount(&$script)
{
$script .= "
/**
* Returns the number of rows matching criteria.
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param ConnectionInterface \$con
* @return int Number of matching rows.
*/
public static function doCount(Criteria \$criteria, \$distinct = false, ConnectionInterface \$con = null)
{
// we may modify criteria, so copy it first
\$criteria = clone \$criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
\$criteria->setPrimaryTableName(static::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
static::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
\$criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}";
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
// BasePeer returns a Statement
\$stmt = ".$this->basePeerClassName."::doCount(\$criteria, \$con);
if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$count = (int) \$row[0];
} else {
\$count = 0; // no rows returned; we infer that means 0 matches.
}
\$stmt->closeCursor();
return \$count;
}";
}
/**
* Adds the doSelectOne() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectOne(&$script)
{
$script .= "
/**
* Selects one object from the DB.
*
* @param Criteria \$criteria object used to create the SELECT statement.
* @param ConnectionInterface \$con
* @return ".$this->getObjectClassName()."
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectOne(Criteria \$criteria, ConnectionInterface \$con = null)
{
\$critcopy = clone \$criteria;
\$critcopy->setLimit(1);
\$objects = static::doSelect(\$critcopy, \$con);
if (\$objects) {
return \$objects[0];
}
return null;
}";
}
/**
* Adds the doSelect() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelect(&$script)
{
$script .= "
/**
* Selects several row from the DB.
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param ConnectionInterface \$con
* @return array Array of selected Objects
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelect(Criteria \$criteria, ConnectionInterface \$con = null)
{
return static::populateObjects(static::doSelectStmt(\$criteria, \$con));
}";
}
/**
* Adds the doSelectStmt() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectStmt(&$script)
{
$script .= "
/**
* Prepares the Criteria object and uses the parent doSelect() method to execute a Statement.
*
* Use this method directly if you want to work with an executed statement directly (for example
* to perform your own object hydration).
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param ConnectionInterface \$con The connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return StatementInterface The executed Statement object.
* @see ".$this->basePeerClassName."::doSelect()
*/
public static function doSelectStmt(Criteria \$criteria, ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
if (!\$criteria->hasSelectClause()) {
\$criteria = clone \$criteria;
static::addSelectColumns(\$criteria);
}
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);";
// apply behaviors
if ($this->hasBehaviorModifier('preSelect')) {
$this->applyBehaviorModifier('preSelect', $script);
}
$script .= "
// BasePeer returns a Statement
return ".$this->basePeerClassName."::doSelect(\$criteria, \$con);
}";
}
/**
* Adds the PHP code to return a instance pool key for the passed-in primary key variable names.
*
* @param array $pkphp An array of PHP var names / method calls representing complete pk.
* @return string
*/
public function getInstancePoolKeySnippet($pkphp)
{
$pkphp = (array) $pkphp; // make it an array if it is not.
$script = '';
if (count($pkphp) > 1) {
$script .= "serialize(array(";
$i = 0;
foreach ($pkphp as $pkvar) {
$script .= ($i++ ? ', ' : '') . "(string) $pkvar";
}
$script .= "))";
} else {
$script .= "(string) " . $pkphp[0];
}
return $script;
}
/**
* Creates a convenience method to add objects to an instance pool.
* @param string &$script The script will be modified in this method.
*/
protected function addAddInstanceToPool(&$script)
{
$script .= "
/**
* Adds an object to the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doSelect*()
* methods in your stub classes -- you may need to explicitly add objects
* to the cache in order to ensure that the same objects are always returned by doSelect*()
* and retrieveByPK*() calls.
*
* @param ".$this->getObjectClassName()." \$obj A ".$this->getObjectClassName()." object.
* @param string \$key (optional) key to use for instance map (for performance boost if key was already calculated externally).
*/
public static function addInstanceToPool(\$obj, \$key = null)
{
if (Propel::isInstancePoolingEnabled()) {
if (null === \$key) {";
$pks = $this->getTable()->getPrimaryKey();
$php = array();
foreach ($pks as $pk) {
$php[] = '$obj->get' . $pk->getPhpName() . '()';
}
$script .= "
\$key = ".$this->getInstancePoolKeySnippet($php).";";
$script .= "
} // if key === null
self::\$instances[\$key] = \$obj;
}
}
";
} // addAddInstanceToPool()
/**
* Creates a convenience method to remove objects form an instance pool.
* @param string &$script The script will be modified in this method.
*/
protected function addRemoveInstanceFromPool(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Removes an object from the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doDelete
* methods in your stub classes -- you may need to explicitly remove objects
* from the cache in order to prevent returning objects that no longer exist.
*
* @param mixed \$value A ".$this->getObjectClassName()." object or a primary key value.
*/
public static function removeInstanceFromPool(\$value)
{";
$script .= "
if (Propel::isInstancePoolingEnabled() && null !== \$value) {";
$pks = $table->getPrimaryKey();
$script .= "
if (is_object(\$value) && \$value instanceof \\".$this->getStubObjectBuilder()->getQualifiedClassName().") {";
$php = array();
foreach ($pks as $pk) {
$php[] = '$value->get' . $pk->getPhpName() . '()';
}
$script .= "
\$key = ".$this->getInstancePoolKeySnippet($php).";";
$script .= "
} elseif (".(count($pks) > 1 ? "is_array(\$value) && count(\$value) === " . count($pks) : "is_scalar(\$value)").") {
// assume we've been passed a primary key";
if (count($pks) > 1) {
$php = array();
for ($i = 0; $i < count($pks); $i++) {
$php[] = "\$value[$i]";
}
} else {
$php = '$value';
}
$script .= "
\$key = ".$this->getInstancePoolKeySnippet($php).";";
$script .= "
} else {
\$e = new PropelException(\"Invalid value passed to removeInstanceFromPool(). Expected primary key or ".$this->getObjectClassName()." object; got \" . (is_object(\$value) ? get_class(\$value) . ' object.' : var_export(\$value,true)));
throw \$e;
}
unset(self::\$instances[\$key]);
}
} // removeInstanceFromPool()
";
}
/**
* Adds method to clear the instance pool.
* @param string &$script The script will be modified in this method.
*/
protected function addClearInstancePool(&$script)
{
$script .= "
/**
* Clear the instance pool.
*
* @return void
*/
public static function clearInstancePool()
{
self::\$instances = array();
}
";
}
/**
* Adds method to clear the instance pool of related tables.
* @param string &$script The script will be modified in this method.
*/
protected function addClearRelatedInstancePool(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Method to invalidate the instance pool of all tables related to " . $table->getName() . "
* by a foreign key with ON DELETE CASCADE
*/
public static function clearRelatedInstancePool()
{";
// Handle ON DELETE CASCADE for updating instance pool
foreach ($table->getReferrers() as $fk) {
// $fk is the foreign key in the other table, so localTableName will
// actually be the table name of other table
$tblFK = $fk->getTable();
$joinedTablePeerBuilder = $this->getNewStubPeerBuilder($tblFK);
$this->declareClassFromBuilder($joinedTablePeerBuilder);
if (!$tblFK->isForReferenceOnly()) {
// we can't perform operations on tables that are
// not within the schema (i.e. that we have no map for, etc.)
if (ForeignKey::CASCADE === $fk->getOnDelete() || ForeignKey::SETNULL === $fk->getOnDelete()) {
$script .= "
// Invalidate objects in ".$this->getClassNameFromBuilder($joinedTablePeerBuilder)." instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
".$this->getClassNameFromBuilder($joinedTablePeerBuilder)."::clearInstancePool();";
} // if fk is on delete cascade
} // if (! for ref only)
} // foreach
$script .= "
}
";
}
/**
* Adds method to get an the instance from the pool, given a key.
* @param string &$script The script will be modified in this method.
*/
protected function addGetInstanceFromPool(&$script)
{
$script .= "
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param string \$key The key (@see getPrimaryKeyHash()) for this instance.
* @return ".$this->getObjectClassName()." Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled.
* @see getPrimaryKeyHash()
*/
public static function getInstanceFromPool(\$key)
{
if (Propel::isInstancePoolingEnabled()) {
if (isset(self::\$instances[\$key])) {
return self::\$instances[\$key];
}
}
return null; // just to be explicit
}
";
}
/**
* Adds method to get a version of the primary key that can be used as a unique key for identifier map.
* @param string &$script The script will be modified in this method.
*/
protected function addGetPrimaryKeyHash(&$script)
{
$script .= "
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param array \$row ConnectionInterface resultset row.
* @param int \$startcol The 0-based offset for reading from the resultset row.
* @return string A string version of PK or NULL if the components of primary key in result array are all null.
*/
public static function getPrimaryKeyHashFromRow(\$row, \$startcol = 0)
{";
// We have to iterate through all the columns so that we know the offset of the primary
// key columns.
$n = 0;
$pk = array();
$cond = array();
foreach ($this->getTable()->getColumns() as $col) {
if (!$col->isLazyLoad()) {
if ($col->isPrimaryKey()) {
$part = $n ? "\$row[\$startcol + $n]" : "\$row[\$startcol]";
$cond[] = $part . " === null";
$pk[] = $part;
}
$n++;
}
}
$script .= "
// If the PK cannot be derived from the row, return NULL.
if (".implode(' && ', $cond).") {
return null;
}
return ".$this->getInstancePoolKeySnippet($pk).";
}
";
}
/**
* Adds method to get the primary key from a row
* @param string &$script The script will be modified in this method.
*/
protected function addGetPrimaryKeyFromRow(&$script)
{
$script .= "
/**
* Retrieves the primary key from the DB resultset row
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, an array of the primary key columns will be returned.
*
* @param array \$row ConnectionInterface resultset row.
* @param int \$startcol The 0-based offset for reading from the resultset row.
* @return mixed The primary key of the row
*/
public static function getPrimaryKeyFromRow(\$row, \$startcol = 0)
{";
// We have to iterate through all the columns so that we
// know the offset of the primary key columns.
$table = $this->getTable();
$n = 0;
$pks = array();
foreach ($table->getColumns() as $col) {
if (!$col->isLazyLoad()) {
if ($col->isPrimaryKey()) {
$pk = '(' . $col->getPhpType() . ') ' . ($n ? "\$row[\$startcol + $n]" : "\$row[\$startcol]");
if ($table->hasCompositePrimaryKey()) {
$pks[] = $pk;
}
}
$n++;
}
}
if ($table->hasCompositePrimaryKey()) {
$script .= "
return array(" . implode($pks, ', '). ");";
} else {
$script .= "
return " . $pk . ";";
}
$script .= "
}
";
}
/**
* Adds the populateObjects() method.
* @param string &$script The script will be modified in this method.
*/
protected function addPopulateObjects(&$script)
{
$table = $this->getTable();
$script .= "
/**
* The returned array will contain objects of the default type or
* objects that inherit from the default.
*
* @param StatementInterface \$stmt
* @return array
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(StatementInterface \$stmt)
{
\$results = array();
";
if (!$table->getChildrenColumn()) {
$script .= "
// set the class once to avoid overhead in the loop
\$cls = static::getOMClass(false);";
}
$script .= "
// populate the object(s)
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key = static::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj = static::getInstanceFromPool(\$key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// \$obj->hydrate(\$row, 0, true); // rehydrate
\$results[] = \$obj;
} else {"
;
if ($table->getChildrenColumn()) {
$script .= "
// class must be set each time from the record row
\$cls = static::getOMClass(\$row, 0);
\$cls = preg_replace('#\.#', '\\\\', \$cls);
" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
\$obj->hydrate(\$row);
\$results[] = \$obj;
static::addInstanceToPool(\$obj, \$key);";
} else {
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
\$obj->hydrate(\$row);
\$results[] = \$obj;
static::addInstanceToPool(\$obj, \$key);";
}
$script .= "
} // if key exists
}
\$stmt->closeCursor();
return \$results;
}";
}
/**
* Adds the populateObject() method.
* @param string &$script The script will be modified in this method.
*/
protected function addPopulateObject(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Populates an object of the default type or an object that inherit from the default.
*
* @param array \$row ConnectionInterface resultset row.
* @param int \$startcol The 0-based offset for reading from the resultset row.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return array (" . $this->getObjectClassName(). " object, last column rank)
*/
public static function populateObject(\$row, \$startcol = 0)
{
\$key = static::getPrimaryKeyHashFromRow(\$row, \$startcol);
if (null !== (\$obj = static::getInstanceFromPool(\$key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// \$obj->hydrate(\$row, \$startcol, true); // rehydrate
\$col = \$startcol + static::NUM_HYDRATE_COLUMNS;";
if ($table->isAbstract()) {
$script .= "
} elseif (null == \$key) {
// empty resultset, probably from a left join
// since this table is abstract, we can't hydrate an empty object
\$obj = null;
\$col = \$startcol + static::NUM_HYDRATE_COLUMNS;";
}
$script .= "
} else {";
if (!$table->getChildrenColumn()) {
$script .= "
\$cls = static::OM_CLASS;";
} else {
$script .= "
\$cls = static::getOMClass(\$row, \$startcol, false);";
}
$script .= "
\$obj = new \$cls();
\$col = \$obj->hydrate(\$row, \$startcol);
static::addInstanceToPool(\$obj, \$key);
}
return array(\$obj, \$col);
}
";
}
/**
* Adds a getOMClass() for non-abstract tables that have inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_Inheritance(&$script)
{
$col = $this->getTable()->getChildrenColumn();
$script .= "
/**
* The returned Class will contain objects of the default type or
* objects that inherit from the default.
*
* @param array \$row ConnectionInterface result row.
* @param int \$colnum Column to examine for OM class information (first is 0).
* @param boolean \$withPrefix Whether or not to return the path with the class name
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getOMClass(\$row, \$colnum, \$withPrefix = true)
{
try {
";
if ($col->isEnumeratedClasses()) {
$script .= "
\$omClass = null;
\$classKey = \$row[\$colnum + " . ($col->getPosition() - 1) . "];
switch (\$classKey) {
";
foreach ($col->getChildren() as $child) {
$script .= "
case self::CLASSKEY_".strtoupper($child->getKey()).":
\$omClass = self::CLASSNAME_".strtoupper($child->getKey()).";
break;
";
} /* foreach */
$script .= "
default:
\$omClass = self::CLASS_DEFAULT;
";
$script .= "
} // switch
if (!\$withPrefix) {
\$omClass = preg_replace('#\.#', '\\\\', \$omClass);
}
";
} else { /* if not enumerated */
$script .= "
\$omClass = \$row[\$colnum + ".($col->getPosition()-1)."];
\$omClass = preg_replace('#\.#', '\\\\', '.'.\$omClass);
";
}
$script .= "
} catch (\Exception \$e) {
throw new PropelException('Unable to get OM class.', \$e);
}
return \$omClass;
}
";
}
/**
* Adds a getOMClass() for non-abstract tables that do note use inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_NoInheritance(&$script)
{
$script .= "
/**
* The class that the Peer will make instances of.
*
* If \$withPrefix is true, the returned path
* uses a dot-path notation which is translated into a path
* relative to a location on the PHP include_path.
* (e.g. path.to.MyClass -> 'path/to/MyClass.php')
*
* @param boolean \$withPrefix Whether or not to return the path with the class name
* @return string path.to.ClassName
*/
public static function getOMClass(\$withPrefix = true)
{
return \$withPrefix ? static::CLASS_DEFAULT : static::OM_CLASS;
}
";
}
/**
* Adds a getOMClass() signature for abstract tables that do not have inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_NoInheritance_Abstract(&$script)
{
$script .= "
/**
* The class that the Peer will make instances of.
*
* This method must be overridden by the stub subclass, because
* ".$this->getObjectClassName()." is declared abstract in the schema.
*
* @param boolean \$withPrefix
*/
abstract public static function getOMClass(\$withPrefix = true);
";
}
/**
* Adds the doInsert() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoInsert(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Performs an INSERT on the database, given a ".$this->getObjectClassName()." or Criteria object.
*
* @param mixed \$values Criteria or ".$this->getObjectClassName()." object containing data that is used to create the INSERT statement.
* @param ConnectionInterface \$con the ConnectionInterface connection to use
* @return mixed The new primary key.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doInsert(\$values, ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getWriteConnection(static::DATABASE_NAME);
}
if (\$values instanceof Criteria) {
\$criteria = clone \$values; // rename for clarity
} else {
\$criteria = \$values->buildCriteria(); // build Criteria from ".$this->getObjectClassName()." object
}
";
foreach ($table->getColumns() as $col) {
if ($col->isPrimaryKey()
&& $col->isAutoIncrement()
&& 'none' !== $table->getIdMethod()
&& !$table->isAllowPkInsert()
) {
$script .= "
if (\$criteria->containsKey(".$this->getColumnConstant($col).") && \$criteria->keyContainsValue(" . $this->getColumnConstant($col) . ") ) {
throw new PropelException('Cannot insert a value for auto-increment primary key ('.".$this->getColumnConstant($col).".')');
}
";
if (!$this->getPlatform()->supportsInsertNullPk()) {
$script .= "
// remove pkey col since this table uses auto-increment and passing a null value for it is not valid
\$criteria->remove(".$this->getColumnConstant($col).");
";
}
} elseif ($col->isPrimaryKey()
&& $col->isAutoIncrement()
&& 'none' !== $table->getIdMethod()
&& $table->isAllowPkInsert()
&& !$this->getPlatform()->supportsInsertNullPk()
) {
$script .= "
// remove pkey col if it is null since this table does not accept that
if (\$criteria->containsKey(".$this->getColumnConstant($col).") && !\$criteria->keyContainsValue(" . $this->getColumnConstant($col) . ") ) {
\$criteria->remove(".$this->getColumnConstant($col).");
}
";
}
}
$script .= "
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
try {
// use transaction because \$criteria could contain info
// for more than one table (I guess, conceivably)
\$con->beginTransaction();
\$pk = ".$this->basePeerClassName."::doInsert(\$criteria, \$con);
\$con->commit();
} catch (PropelException \$e) {
\$con->rollBack();
throw \$e;
}
return \$pk;
}
";
}
/**
* Adds the doUpdate() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoUpdate(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Performs an UPDATE on the database, given a ".$this->getObjectClassName()." or Criteria object.
*
* @param mixed \$values Criteria or ".$this->getObjectClassName()." object containing data that is used to create the UPDATE statement.
* @param ConnectionInterface \$con The connection to use (specify ConnectionInterface connection object to exert more control over transactions).
* @return int The number of affected rows (if supported by underlying database driver).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doUpdate(\$values, ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getWriteConnection(static::DATABASE_NAME);
}
\$selectCriteria = new Criteria(self::DATABASE_NAME);
if (\$values instanceof Criteria) {
\$criteria = clone \$values; // rename for clarity
";
foreach ($table->getColumns() as $col) {
if ($col->isPrimaryKey()) {
$script .= "
\$comparison = \$criteria->getComparison(".$this->getColumnConstant($col).");
\$value = \$criteria->remove(".$this->getColumnConstant($col).");
if (\$value) {
\$selectCriteria->add(".$this->getColumnConstant($col).", \$value, \$comparison);
} else {
\$selectCriteria->setPrimaryTableName(static::TABLE_NAME);
}
";
} /* if col is prim key */
} /* foreach */
$script .= "
} else { // \$values is ".$this->getObjectClassName()." object
\$criteria = \$values->buildCriteria(); // gets full criteria
\$selectCriteria = \$values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
}
// set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
return {$this->basePeerClassName}::doUpdate(\$selectCriteria, \$criteria, \$con);
}
";
}
/**
* Adds the doDeleteAll() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoDeleteAll(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Deletes all rows from the ".$table->getName()." table.
*
* @param ConnectionInterface \$con the connection to use
* @return int The number of affected rows (if supported by underlying database driver).
*/
public static function doDeleteAll(ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getWriteConnection(static::DATABASE_NAME);
}
\$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because \$criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
\$con->beginTransaction();
";
if ($this->isDeleteCascadeEmulationNeeded()) {
$script .="\$affectedRows += static::doOnDeleteCascade(new Criteria(static::DATABASE_NAME), \$con);
";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= "static::doOnDeleteSetNull(new Criteria(static::DATABASE_NAME), \$con);
";
}
$script .= "\$affectedRows += {$this->basePeerClassName}::doDeleteAll(static::TABLE_NAME, \$con, static::DATABASE_NAME);
// Because this db requires some delete cascade/set null emulation, we have to
// clear the cached instance *after* the emulation has happened (since
// instances get re-added by the select statement contained therein).
static::clearInstancePool();
static::clearRelatedInstancePool();
\$con->commit();
return \$affectedRows;
} catch (PropelException \$e) {
\$con->rollBack();
throw \$e;
}
}
";
}
/**
* Adds the doDelete() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoDelete(&$script)
{
$table = $this->getTable();
$emulateCascade = $this->isDeleteCascadeEmulationNeeded() || $this->isDeleteSetNullEmulationNeeded();
$script .= "
/**
* Performs a DELETE on the database, given a ".$this->getObjectClassName()." or Criteria object OR a primary key value.
*
* @param mixed \$values Criteria or ".$this->getObjectClassName()." object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param ConnectionInterface \$con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
static public function doDelete(\$values, ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getWriteConnection(static::DATABASE_NAME);
}
if (\$values instanceof Criteria) {";
if (!$emulateCascade) {
$script .= "
// invalidate the cache for all objects of this type, since we have no
// way of knowing (without running a query) what objects should be invalidated
// from the cache based on this Criteria.
static::clearInstancePool();";
}
$script .= "
// rename for clarity
\$criteria = clone \$values;
} elseif (\$values instanceof \\".$this->getStubObjectBuilder()->getQualifiedClassName().") { // it's a model object";
if (!$emulateCascade) {
$script .= "
// invalidate the cache for this single object
static::removeInstanceFromPool(\$values);";
}
if (count($table->getPrimaryKey()) > 0) {
$script .= "
// create criteria based on pk values
\$criteria = \$values->buildPkeyCriteria();";
} else {
$script .= "
// create criteria based on pk value
\$criteria = \$values->buildCriteria();";
}
$script .= "
} else { // it's a primary key, or an array of pks";
$script .= "
\$criteria = new Criteria(self::DATABASE_NAME);";
if (1 === count($table->getPrimaryKey())) {
$pkey = $table->getPrimaryKey();
$col = array_shift($pkey);
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", (array) \$values, Criteria::IN);";
if (!$emulateCascade) {
$script .= "
// invalidate the cache for this object(s)
foreach ((array) \$values as \$singleval) {
static::removeInstanceFromPool(\$singleval);
}";
}
} else {
$script .= "
// primary key is composite; we therefore, expect
// the primary key passed to be an array of pkey values
if (count(\$values) == count(\$values, COUNT_RECURSIVE)) {
// array is not multi-dimensional
\$values = array(\$values);
}
foreach (\$values as \$value) {";
$i = 0;
foreach ($table->getPrimaryKey() as $col) {
if (0 === $i) {
$script .= "
\$criterion = \$criteria->getNewCriterion(".$this->getColumnConstant($col).", \$value[$i]);";
} else {
$script .= "
\$criterion->addAnd(\$criteria->getNewCriterion(".$this->getColumnConstant($col).", \$value[$i]));";
}
$i++;
}
$script .= "
\$criteria->addOr(\$criterion);";
if (!$emulateCascade) {
$script .= "
// we can invalidate the cache for this single PK
static::removeInstanceFromPool(\$value);";
}
$script .= "
}";
} /* if count(table->getPrimaryKeys()) */
$script .= "
}
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
\$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because \$criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
\$con->beginTransaction();
";
if ($this->isDeleteCascadeEmulationNeeded()) {
$script .= "
// cloning the Criteria in case it's modified by doSelect() or doSelectStmt()
\$c = clone \$criteria;
\$affectedRows += static::doOnDeleteCascade(\$c, \$con);
";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= "
// cloning the Criteria in case it's modified by doSelect() or doSelectStmt()
\$c = clone \$criteria;
static::doOnDeleteSetNull(\$c, \$con);
";
}
if ($emulateCascade) {
$script .= "
// Because this db requires some delete cascade/set null emulation, we have to
// clear the cached instance *after* the emulation has happened (since
// instances get re-added by the select statement contained therein).
if (\$values instanceof Criteria) {
static::clearInstancePool();
} elseif (\$values instanceof \\".$this->getStubObjectBuilder()->getQualifiedClassName().") { // it's a model object
static::removeInstanceFromPool(\$values);
} else { // it's a primary key, or an array of pks
foreach ((array) \$values as \$singleval) {
static::removeInstanceFromPool(\$singleval);
}
}
";
}
$script .= "
\$affectedRows += {$this->basePeerClassName}::doDelete(\$criteria, \$con);
static::clearRelatedInstancePool();
\$con->commit();
return \$affectedRows;
} catch (PropelException \$e) {
\$con->rollBack();
throw \$e;
}
}
";
}
/**
* Adds the doOnDeleteCascade() method, which provides ON DELETE CASCADE emulation.
* @param string &$script The script will be modified in this method.
*/
protected function addDoOnDeleteCascade(&$script)
{
$table = $this->getTable();
$script .= "
/**
* This is a method for emulating ON DELETE CASCADE for DBs that don't support this
* feature (like MySQL or SQLite).
*
* This method is not very speedy because it must perform a query first to get
* the implicated records and then perform the deletes by calling those Peer classes.
*
* This method should be used within a transaction if possible.
*
* @param Criteria \$criteria
* @param ConnectionInterface \$con
* @return int The number of affected rows (if supported by underlying database driver).
*/
protected static function doOnDeleteCascade(Criteria \$criteria, ConnectionInterface \$con)
{
// initialize var to track total num of affected rows
\$affectedRows = 0;
// first find the objects that are implicated by the \$criteria
\$objects = static::doSelect(\$criteria, \$con);
foreach (\$objects as \$obj) {
";
foreach ($table->getReferrers() as $fk) {
// $fk is the foreign key in the other table, so localTableName will
// actually be the table name of other table
$tblFK = $fk->getTable();
$joinedTablePeerBuilder = $this->getNewPeerBuilder($tblFK);
if (!$tblFK->isForReferenceOnly()) {
// we can't perform operations on tables that are
// not within the schema (i.e. that we have no map for, etc.)
$fkClassName = $joinedTablePeerBuilder->getObjectClassName();
if (ForeignKey::CASCADE === $fk->getOnDelete()) {
// backwards on purpose
$columnNamesF = $fk->getLocalColumns();
$columnNamesL = $fk->getForeignColumns();
$script .= "
// delete related $fkClassName objects
\$criteria = new Criteria(".$joinedTablePeerBuilder->getPeerClassName(true)."::DATABASE_NAME);
";
for ($x = 0, $xlen = count($columnNamesF); $x < $xlen; $x++) {
$columnFK = $tblFK->getColumn($columnNamesF[$x]);
$columnL = $table->getColumn($columnNamesL[$x]);
$script .= "
\$criteria->add(".$joinedTablePeerBuilder->getColumnConstant($columnFK) .", \$obj->get".$columnL->getPhpName()."());";
}
$script .= "
\$affectedRows += ".$joinedTablePeerBuilder->getPeerClassName(true)."::doDelete(\$criteria, \$con);";
} // if cascade && fkey table name != curr table name
} // if not for ref only
} // foreach foreign keys
$script .= "
}
return \$affectedRows;
}
";
} // end addDoOnDeleteCascade
/**
* Adds the doOnDeleteSetNull() method, which provides ON DELETE SET NULL emulation.
* @param string &$script The script will be modified in this method.
*/
protected function addDoOnDeleteSetNull(&$script)
{
$table = $this->getTable();
$script .= "
/**
* This is a method for emulating ON DELETE SET NULL DBs that don't support this
* feature (like MySQL or SQLite).
*
* This method is not very speedy because it must perform a query first to get
* the implicated records and then perform the deletes by calling those Peer classes.
*
* This method should be used within a transaction if possible.
*
* @param Criteria \$criteria
* @param ConnectionInterface \$con
* @return void
*/
protected static function doOnDeleteSetNull(Criteria \$criteria, ConnectionInterface \$con)
{
// first find the objects that are implicated by the \$criteria
\$objects = static::doSelect(\$criteria, \$con);
foreach (\$objects as \$obj) {
";
// This logic is almost exactly the same as that in doOnDeleteCascade()
// it may make sense to refactor this, provided that things don't
// get too complicated.
foreach ($table->getReferrers() as $fk) {
// $fk is the foreign key in the other table, so localTableName will
// actually be the table name of other table
$tblFK = $fk->getTable();
$refTablePeerBuilder = $this->getNewPeerBuilder($tblFK);
if (!$tblFK->isForReferenceOnly()) {
// we can't perform operations on tables that are
// not within the schema (i.e. that we have no map for, etc.)
$fkClassName = $refTablePeerBuilder->getObjectClassName();
if (ForeignKey::SETNULL === $fk->getOnDelete()) {
// backwards on purpose
$columnNamesF = $fk->getLocalColumns();
$columnNamesL = $fk->getForeignColumns(); // should be same num as foreign
$script .= "
// set fkey col in related $fkClassName rows to NULL
\$selectCriteria = new Criteria(static::DATABASE_NAME);
\$updateValues = new Criteria(static::DATABASE_NAME);";
for ($x = 0, $xlen = count($columnNamesF); $x < $xlen; $x++) {
$columnFK = $tblFK->getColumn($columnNamesF[$x]);
$columnL = $table->getColumn($columnNamesL[$x]);
$script .= "
\$selectCriteria->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", \$obj->get".$columnL->getPhpName()."());
\$updateValues->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", null);
";
}
$script .= "
{$this->basePeerClassName}::doUpdate(\$selectCriteria, \$updateValues, \$con); // use BasePeer because generated Peer doUpdate() methods only update using pkey
";
} // if setnull && fkey table name != curr table name
} // if not for ref only
} // foreach foreign keys
$script .= "
}
}
";
}
/**
* Adds the retrieveByPK method for tables with single-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPK_SinglePK(&$script)
{
$table = $this->getTable();
$pks = $table->getPrimaryKey();
$col = $pks[0];
$script .= "
/**
* Retrieve a single object by pkey.
*
* @param ".$col->getPhpType()." \$pk the primary key.
* @param ConnectionInterface \$con the connection to use
* @return ".$this->getObjectClassName()."
*/
static public function ".$this->getRetrieveMethodName()."(\$pk, ConnectionInterface \$con = null)
{
if (null !== (\$obj = static::getInstanceFromPool(".$this->getInstancePoolKeySnippet('$pk')."))) {
return \$obj;
}
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
\$criteria = new Criteria(static::DATABASE_NAME);
\$criteria->add(".$this->getColumnConstant($col).", \$pk);
\$v = static::doSelect(\$criteria, \$con);
return !empty(\$v) > 0 ? \$v[0] : null;
}
";
}
/**
* Adds the retrieveByPKs method for tables with single-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPKs_SinglePK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve multiple objects by pkey.
*
* @param array \$pks List of primary keys
* @param ConnectionInterface \$con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
static public function ".$this->getRetrieveMethodName()."s(\$pks, ConnectionInterface \$con = null)
{
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
\$objs = null;
if (empty(\$pks)) {
\$objs = array();
} else {
\$criteria = new Criteria(static::DATABASE_NAME);";
$k1 = $table->getPrimaryKey();
$script .= "
\$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);";
$script .= "
\$objs = static::doSelect(\$criteria, \$con);
}
return \$objs;
}
";
}
/**
* Adds the retrieveByPK method for tables with multi-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPK_MultiPK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve object using using composite pkey values.";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$cptype = $col->getPhpType();
$script .= "
* @param $cptype $".$clo;
}
$script .= "
* @param ConnectionInterface \$con
* @return ".$this->getObjectClassName()."
*/
static public function ".$this->getRetrieveMethodName()."(";
$php = array();
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$php[] = '$' . $clo;
} /* foreach */
$script .= implode(', ', $php);
$script .= ", ConnectionInterface \$con = null) {
\$_instancePoolKey = ".$this->getInstancePoolKeySnippet($php).";";
$script .= "
if (null !== (\$obj = static::getInstanceFromPool(\$_instancePoolKey))) {
return \$obj;
}
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
\$criteria = new Criteria(static::DATABASE_NAME);";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", $".$clo.");";
}
$script .= "
\$v = static::doSelect(\$criteria, \$con);
return !empty(\$v) ? \$v[0] : null;
}";
}
/**
* Adds the getTableMap() method which is a convenience method for apps to get DB metadata.
* @param string &$script The script will be modified in this method.
*/
protected function addGetTableMap(&$script)
{
$script .= "
/**
* Returns the TableMap related to this peer.
* This method is not needed for general use but a specific application could have a need.
* @return TableMap
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getTableMap()
{
return Propel::getServiceContainer()->getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
}
";
}
/**
* Adds the complex OM methods to the base addSelectMethods() function.
* @param string &$script The script will be modified in this method.
* @see PeerBuilder::addSelectMethods()
*/
protected function addSelectMethods(&$script)
{
$table = $this->getTable();
parent::addSelectMethods($script);
$this->addDoCountJoin($script);
$this->addDoSelectJoin($script);
$countFK = count($table->getForeignKeys());
$includeJoinAll = true;
foreach ($this->getTable()->getForeignKeys() as $fk) {
$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
$this->declareClassFromBuilder($this->getNewStubPeerBuilder($tblFK));
if ($tblFK->isForReferenceOnly()) {
$includeJoinAll = false;
}
}
if ($includeJoinAll) {
if ($countFK > 0) {
$this->addDoCountJoinAll($script);
$this->addDoSelectJoinAll($script);
}
if ($countFK > 1) {
$this->addDoCountJoinAllExcept($script);
$this->addDoSelectJoinAllExcept($script);
}
}
}
/**
* Get the column offsets of the primary key(s) for specified table.
*
* @param Table $tbl
* @return array int[] The column offsets of the primary key(s).
*/
protected function getPrimaryKeyColOffsets(Table $tbl)
{
$offsets = array();
$idx = 0;
foreach ($tbl->getColumns() as $col) {
if ($col->isPrimaryKey()) {
$offsets[] = $idx;
}
$idx++;
}
return $offsets;
}
/**
* @param ForeignKey $fk
* @param Table $table
* @param Table $joinTable
* @param PeerBuilder $joinedTablePeerBuilder
* @return string
*/
public function addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder)
{
$script = '';
$lfMap = $fk->getLocalForeignMapping();
$lftCols = $fk->getLocalColumns();
if (1 === count($lftCols)) {
// simple foreign key
$lftCol = $lftCols[0];
$script .= sprintf(
"
\$criteria->addJoin(%s, %s, \$joinBehavior);
",
$this->getColumnConstant($table->getColumn($lftCol)),
$joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn($lfMap[$lftCol]))
);
} else {
// composite foreign key
$script .= "
\$criteria->addMultipleJoin(array(
";
foreach ($lftCols as $columnName) {
$script .= sprintf(
" array(%s, %s),
",
$this->getColumnConstant($table->getColumn($columnName)),
$joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn($lfMap[$columnName]))
);
}
$script .= " ), \$joinBehavior);
";
}
return $script;
}
/**
* Adds the doSelectJoin*() methods.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectJoin(&$script)
{
$table = $this->getTable();
$className = $this->getObjectClassName();
$countFK = count($table->getForeignKeys());
$joinBehavior = $this->getJoinBehavior();
if ($countFK >= 1) {
foreach ($table->getForeignKeys() as $fk) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
if (!$joinTable->isForReferenceOnly()) {
// This condition is necessary because Propel lacks
// a system for aliasing the table if it is the same table.
if ($fk->getForeignTableName() != $table->getName()) {
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTableObjectBuilder->getObjectClassName();
$script .= "
/**
* Selects a collection of $className objects pre-filled with their $joinClassName objects.
* @param Criteria \$criteria
* @param ConnectionInterface \$con
* @param String \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return array Array of $className objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)."(Criteria \$criteria, \$con = null, \$joinBehavior = $joinBehavior)
{
\$criteria = clone \$criteria;
// Set the correct dbName if it has not been overridden
if (\$criteria->getDbName() == Propel::getServiceContainer()->getDefaultDatasource()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
static::addSelectColumns(\$criteria);
\$startcol = static::NUM_HYDRATE_COLUMNS;
".$joinedTablePeerBuilder->getPeerClassName(true)."::addSelectColumns(\$criteria);
";
$script .= $this->addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder);
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName."::doSelect(\$criteria, \$con);
\$results = array();
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key1 = static::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = static::getInstanceFromPool(\$key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// \$obj1->hydrate(\$row, 0, true); // rehydrate
} else {
";
if ($table->getChildrenColumn()) {
$script .= "
\$omClass = static::getOMClass(\$row, 0);
\$omClass = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = static::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
static::addInstanceToPool(\$obj1, \$key1);
} // if \$obj1 already loaded
\$key2 = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getPrimaryKeyHashFromRow(\$row, \$startcol);
if (\$key2 !== null) {
\$obj2 = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getInstanceFromPool(\$key2);
if (!\$obj2) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(\$row, \$startcol);
\$cls = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj2', '$cls') . "
\$obj2->hydrate(\$row, \$startcol);
".$joinedTablePeerBuilder->getPeerClassName(true)."::addInstanceToPool(\$obj2, \$key2);
} // if obj2 already loaded
// Add the \$obj1 (".$this->getObjectClassName().") to \$obj2 (".$joinedTablePeerBuilder->getObjectClassName().")";
if ($fk->isLocalPrimaryKey()) {
$script .= "
// one to one relationship
\$obj1->set" . $joinedTablePeerBuilder->getStubObjectBuilder()->getUnqualifiedClassName() . "(\$obj2);";
} else {
$script .= "
\$obj2->add" . $joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, false)."(\$obj1);";
}
$script .= "
} // if joined row was not null
\$results[] = \$obj1;
}
\$stmt->closeCursor();
return \$results;
}
";
} // if fk table name != this table name
} // if ! is reference only
} // foreach column
} // if count(fk) > 1
} // addDoSelectJoin()
/**
* Adds the doCountJoin*() methods.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCountJoin(&$script)
{
$table = $this->getTable();
$countFK = count($table->getForeignKeys());
$joinBehavior = $this->getJoinBehavior();
if ($countFK >= 1) {
foreach ($table->getForeignKeys() as $fk) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
if (!$joinTable->isForReferenceOnly()) {
if ($fk->getForeignTableName() != $table->getName()) {
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$script .= "
/**
* Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)." table
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param ConnectionInterface \$con
* @param string \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return int Number of matching rows.
*/
public static function doCountJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)."(Criteria \$criteria, \$distinct = false, ConnectionInterface \$con = null, \$joinBehavior = $joinBehavior)
{
// we're going to modify criteria, so copy it first
\$criteria = clone \$criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
\$criteria->setPrimaryTableName(static::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
static::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
";
$script .= $this->addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder);
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName."::doCount(\$criteria, \$con);
if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$count = (int) \$row[0];
} else {
\$count = 0; // no rows returned; we infer that means 0 matches.
}
\$stmt->closeCursor();
return \$count;
}
";
} // if fk table name != this table name
} // if ! is reference only
} // foreach column
} // if count(fk) > 1
} // addDoCountJoin()
/**
* Adds the doSelectJoinAll() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectJoinAll(&$script)
{
$table = $this->getTable();
$className = $this->getObjectClassName();
$joinBehavior = $this->getJoinBehavior();
$script .= "
/**
* Selects a collection of $className objects pre-filled with all related objects.
*
* @param Criteria \$criteria
* @param ConnectionInterface \$con
* @param string \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return array Array of $className objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAll(Criteria \$criteria, \$con = null, \$joinBehavior = $joinBehavior)
{
\$criteria = clone \$criteria;
// Set the correct dbName if it has not been overridden
if (\$criteria->getDbName() == Propel::getServiceContainer()->getDefaultDatasource()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
static::addSelectColumns(\$criteria);
\$startcol2 = static::NUM_HYDRATE_COLUMNS;
";
$index = 2;
foreach ($table->getForeignKeys() as $fk) {
// Want to cover this case, but the code is not there yet.
// Propel lacks a system for aliasing tables of the same name.
if ($fk->getForeignTableName() !== $table->getName()) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$new_index = $index + 1;
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTablePeerBuilder->getObjectClassName();
$script .= "
".$joinedTablePeerBuilder->getPeerClassName(true)."::addSelectColumns(\$criteria);
\$startcol$new_index = \$startcol$index + ".$joinedTablePeerBuilder->getPeerClassName(true)."::NUM_HYDRATE_COLUMNS;
";
$index = $new_index;
} // if fk->getForeignTableName != table->getName
} // foreach [sub] foreign keys
foreach ($table->getForeignKeys() as $fk) {
// want to cover this case, but the code is not there yet.
if ($fk->getForeignTableName() !== $table->getName()) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$script .= $this->addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder);
}
}
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName."::doSelect(\$criteria, \$con);
\$results = array();
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key1 = static::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = static::getInstanceFromPool(\$key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// \$obj1->hydrate(\$row, 0, true); // rehydrate
} else {";
if ($table->getChildrenColumn()) {
$script .= "
\$omClass = static::getOMClass(\$row, 0);
\$omClass = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = static::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
static::addInstanceToPool(\$obj1, \$key1);
} // if obj1 already loaded
";
$index = 1;
foreach ($table->getForeignKeys() as $fk) {
// want to cover this case, but the code is not there yet.
// Why not? -because we'd have to alias the tables in the JOIN
if ($fk->getForeignTableName() != $table->getName()) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTableObjectBuilder->getObjectClassName();
$interfaceName = $joinClassName;
if ($joinTable->getInterface()) {
$interfaceName = $this->prefixClassName($joinTable->getInterface());
}
$index++;
$script .= "
// Add objects for joined $joinClassName rows
\$key$index = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
if (\$key$index !== null) {
\$obj$index = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getInstanceFromPool(\$key$index);
if (!\$obj$index) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(\$row, \$startcol$index);
\$cls = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(false);
";
} /* $joinTable->getChildrenColumn() */
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
\$obj".$index."->hydrate(\$row, \$startcol$index);
".$joinedTablePeerBuilder->getPeerClassName(true)."::addInstanceToPool(\$obj$index, \$key$index);
} // if obj$index loaded
// Add the \$obj1 (".$this->getObjectClassName().") to the collection in \$obj".$index." (".$joinedTablePeerBuilder->getObjectClassName().")";
if ($fk->isLocalPrimaryKey()) {
$script .= "
\$obj1->set".$joinedTablePeerBuilder->getStubObjectBuilder()->getUnqualifiedClassName()."(\$obj".$index.");";
} else {
$script .= "
\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, false)."(\$obj1);";
}
$script .= "
} // if joined row not null
";
} // $fk->getForeignTableName() != $table->getName()
} //foreach foreign key
$script .= "
\$results[] = \$obj1;
}
\$stmt->closeCursor();
return \$results;
}
";
}
/**
* Adds the doCountJoinAll() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCountJoinAll(&$script)
{
$table = $this->getTable();
$joinBehavior = $this->getJoinBehavior();
$script .= "
/**
* Returns the number of rows matching criteria, joining all related tables
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param ConnectionInterface \$con
* @param string \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return int Number of matching rows.
*/
public static function doCountJoinAll(Criteria \$criteria, \$distinct = false, ConnectionInterface \$con = null, \$joinBehavior = $joinBehavior)
{
// we're going to modify criteria, so copy it first
\$criteria = clone \$criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
\$criteria->setPrimaryTableName(static::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
static::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
";
foreach ($table->getForeignKeys() as $fk) {
// want to cover this case, but the code is not there yet.
if ($fk->getForeignTableName() != $table->getName()) {
$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$script .= $this->addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder);
} // if fk->getForeignTableName != table->getName
} // foreach [sub] foreign keys
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName."::doCount(\$criteria, \$con);
if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$count = (int) \$row[0];
} else {
\$count = 0; // no rows returned; we infer that means 0 matches.
}
\$stmt->closeCursor();
return \$count;
}";
} // end addDoCountJoinAll()
/**
* Adds the doSelectJoinAllExcept*() methods.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectJoinAllExcept(&$script)
{
$table = $this->getTable();
$joinBehavior = $this->getJoinBehavior();
// ------------------------------------------------------------------------
// doSelectJoinAllExcept*()
// ------------------------------------------------------------------------
// 2) create a bunch of doSelectJoinAllExcept*() methods
// -- these were existing in original Torque, so we should keep them for compatibility
$fkeys = $table->getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over
// getForeignKeys() will cause this to only execute one time.
foreach ($fkeys as $fk) {
$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
$excludedClassName = $excludedTableObjectBuilder->getObjectClassName();
$script .= "
/**
* Selects a collection of ".$this->getObjectClassName()." objects pre-filled with all related objects except ".$thisTableObjectBuilder->getFKPhpNameAffix($fk).".
*
* @param Criteria \$criteria
* @param ConnectionInterface \$con
* @param string \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return array Array of ".$this->getObjectClassName()." objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)."(Criteria \$criteria, \$con = null, \$joinBehavior = $joinBehavior)
{
\$criteria = clone \$criteria;
// Set the correct dbName if it has not been overridden
// \$criteria->getDbName() will return the same object if not set to another value
// so == check is okay and faster
if (\$criteria->getDbName() == Propel::getServiceContainer()->getDefaultDatasource()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
static::addSelectColumns(\$criteria);
\$startcol2 = static::NUM_HYDRATE_COLUMNS;
";
$index = 2;
foreach ($table->getForeignKeys() as $subfk) {
// want to cover this case, but the code is not there yet.
// Why not? - because we would have to alias the tables in the join
if (!($subfk->getForeignTableName() == $table->getName())) {
$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
$joinTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinTablePeerBuilder->getObjectClassName();
if ($joinClassName !== $excludedClassName) {
$new_index = $index + 1;
$script .= "
".$joinTablePeerBuilder->getPeerClassName(true)."::addSelectColumns(\$criteria);
\$startcol$new_index = \$startcol$index + ".$joinTablePeerBuilder->getPeerClassName(true)."::NUM_HYDRATE_COLUMNS;
";
$index = $new_index;
} // if joinClassName not excludeClassName
} // if subfk is not curr table
} // foreach [sub] foreign keys
foreach ($table->getForeignKeys() as $subfk) {
// want to cover this case, but the code is not there yet.
if ($subfk->getForeignTableName() != $table->getName()) {
$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTablePeerBuilder->getObjectClassName();
if ($joinClassName !== $excludedClassName) {
$script .= $this->addCriteriaJoin($subfk, $table, $joinTable, $joinedTablePeerBuilder);
}
}
}
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName ."::doSelect(\$criteria, \$con);
\$results = array();
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key1 = static::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = static::getInstanceFromPool(\$key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// \$obj1->hydrate(\$row, 0, true); // rehydrate
} else {";
if ($table->getChildrenColumn()) {
$script .= "
\$omClass = static::getOMClass(\$row, 0);
\$cls = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = static::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
static::addInstanceToPool(\$obj1, \$key1);
} // if obj1 already loaded
";
$index = 1;
foreach ($table->getForeignKeys() as $subfk) {
// want to cover this case, but the code is not there yet.
if ($subfk->getForeignTableName() !== $table->getName()) {
$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTableObjectBuilder->getObjectClassName();
$interfaceName = $joinClassName;
if ($joinTable->getInterface()) {
$interfaceName = $this->prefixClassName($joinTable->getInterface());
}
if ($joinClassName !== $excludedClassName) {
$index++;
$script .= "
// Add objects for joined $joinClassName rows
\$key$index = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
if (null !== \$key$index) {
\$obj$index = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getInstanceFromPool(\$key$index);
if (!\$obj$index) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(\$row, \$startcol$index);
\$cls = preg_replace('#\.#', '\\\\', \$omClass);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassName(true)."::getOMClass(false);
";
} /* $joinTable->getChildrenColumn() */
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
\$obj".$index."->hydrate(\$row, \$startcol$index);
".$joinedTablePeerBuilder->getPeerClassName(true)."::addInstanceToPool(\$obj$index, \$key$index);
} // if \$obj$index already loaded
// Add the \$obj1 (".$this->getObjectClassName().") to the collection in \$obj".$index." (".$joinedTablePeerBuilder->getObjectClassName().")";
if ($subfk->isLocalPrimaryKey()) {
$script .= "
\$obj1->set".$joinedTablePeerBuilder->getObjectClassName()."(\$obj".$index.");";
} else {
$script .= "
\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, false)."(\$obj1);";
}
$script .= "
} // if joined row is not null
";
} // if ($joinClassName != $excludedClassName) {
} // $subfk->getForeignTableName() != $table->getName()
} // foreach
$script .= "
\$results[] = \$obj1;
}
\$stmt->closeCursor();
return \$results;
}
";
} // foreach fk
}
/**
* Adds the doCountJoinAllExcept*() methods.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCountJoinAllExcept(&$script)
{
$table = $this->getTable();
$joinBehavior = $this->getJoinBehavior();
$fkeys = $table->getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over
// getForeignKeys() will cause this to only execute one time.
foreach ($fkeys as $fk) {
$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
$excludedClassName = $excludedTableObjectBuilder->getObjectClassName();
$script .= "
/**
* Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)." table
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param ConnectionInterface \$con
* @param string \$joinBehavior the type of joins to use, defaults to $joinBehavior
* @return int Number of matching rows.
*/
public static function doCountJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, false)."(Criteria \$criteria, \$distinct = false, ConnectionInterface \$con = null, \$joinBehavior = $joinBehavior)
{
// we're going to modify criteria, so copy it first
\$criteria = clone \$criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
\$criteria->setPrimaryTableName(static::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
static::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY should not affect count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (null === \$con) {
\$con = Propel::getServiceContainer()->getReadConnection(static::DATABASE_NAME);
}
";
foreach ($table->getForeignKeys() as $subfk) {
// want to cover this case, but the code is not there yet.
if ($subfk->getForeignTableName() !== $table->getName()) {
$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTablePeerBuilder->getObjectClassName();
if ($joinClassName !== $excludedClassName) {
$script .= $this->addCriteriaJoin($subfk, $table, $joinTable, $joinedTablePeerBuilder);
}
}
}
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassName."::doCount(\$criteria, \$con);
if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$count = (int) \$row[0];
} else {
\$count = 0; // no rows returned; we infer that means 0 matches.
}
\$stmt->closeCursor();
return \$count;
}
";
} // foreach fk
}
/**
* returns the desired join behavior as set in the build properties
* see trac ticket #588, #491
* @return string
*/
protected function getJoinBehavior()
{
return $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
}
}
Jump to Line
Something went wrong with that request. Please try again.