sintonia/library/propel/generator/lib/builder/om/PHP5PeerBuilder.php

2762 lines
91 KiB
PHP

<?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
*/
require_once 'builder/om/PeerBuilder.php';
/**
* 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>
* @package propel.generator.builder.om
*/
class PHP5PeerBuilder extends PeerBuilder
{
/**
* 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.
*/
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("One or more of your column names for [" . $table->getName() . "] table conflict with a PHP reserved word (" . implode(", ", $intersect) . ")");
}
}
/**
* Returns the name of the current class being built.
* @return string
*/
public function getUnprefixedClassname()
{
return $this->getBuildProperty('basePrefix') . $this->getStubPeerBuilder()->getUnprefixedClassname();
}
/**
* Gets the package for the [base] peer classes.
* @return string
*/
public function getPackage()
{
return parent::getPackage() . ".om";
}
public function getNamespace()
{
if ($namespace = parent::getNamespace()) {
if ($this->getGeneratorConfig() && $omns = $this->getGeneratorConfig()->getBuildProperty('namespaceOm')) {
return $namespace . '\\' . $omns;
} else {
return $namespace;
}
}
}
/**
* Adds the include() statements for files that this class depends on or utilizes.
* @param string &$script The script will be modified in this method.
*/
protected function addIncludes(&$script)
{
} // addIncludes()
/**
* Adds class phpdoc comment and openning of class.
* @param string &$script The script will be modified in this method.
*/
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 ($this->basePeerClassname !== 'BasePeer') {
$extendingPeerClass = ' extends ' . $this->basePeerClassname;
}
$script .= "
* @package propel.generator.".$this->getPackage()."
*/
abstract class ".$this->getClassname(). $extendingPeerClass . " {
";
}
protected function addClassBody(&$script)
{
$this->declareClassFromBuilder($this->getStubPeerBuilder());
$this->declareClassFromBuilder($this->getStubObjectBuilder());
parent::addClassBody($script);
$this->declareClasses('Propel', 'PropelException', 'PropelPDO', 'BasePeer', 'Criteria', 'PDO', 'PDOStatement');
}
/**
* 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)
{
// apply behaviors
$this->applyBehaviorModifier('staticMethods', $script, " ");
$script .= "
} // " . $this->getClassname() . "
";
$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)
{
$table = $this->getTable();
$script .= "
// This is the static code needed to register the TableMap for this table with the main Propel class.
//
".$this->getClassName()."::buildTableMap();
";
$this->applyBehaviorModifier('peerFilter', $script, "");
}
public function getTableMapClass()
{
return $this->getTablePhpName() . 'TableMap';
}
public function getTablePhpName()
{
return ($this->getTable()->isAbstract() ? '' : $this->getStubObjectBuilder()->getClassname());
}
/**
* 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().";
";
$this->addColumnNameConstants($script);
$this->addInheritanceColumnConstants($script);
$script .= "
/**
* An identiy 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()."[]
*/
public static \$instances = array();
";
// apply behaviors
$this->applyBehaviorModifier('staticAttributes', $script, " ");
$this->addFieldNamesAttribute($script);
$this->addFieldKeysAttribute($script);
}
/**
* Adds the COLUMN_NAME contants 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
}
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'
*/
private 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 .= ")
);
";
}
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
*/
private 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 .= ")
);
";
} // addFielKeysAttribute
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
*/
static public 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()
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.
*/
static public 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 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::getDatabaseMap(".$this->getClassname()."::DATABASE_NAME);
if (!\$dbMap->hasTable(".$this->getClassname()."::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 ($this->getTable()->getChildrenColumn()) {
$col = $this->getTable()->getChildrenColumn();
$cfc = $col->getPhpName();
if ($col->isEnumeratedClasses()) {
if ($col->isPhpPrimitiveNumericType()) $quote = "";
else $quote = '"';
foreach ($col->getChildren() as $child) {
$childBuilder = $this->getMultiExtendObjectBuilder();
$childBuilder->setChild($child);
$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())." = '" . $child->getKey() . "';
";
}
$script .= "
/** A class that can be returned by this peer. */
const CLASSNAME_".strtoupper($child->getKey())." = '". $childBuilder->getClasspath() . "';
";
} /* foreach children */
} /* if col->isenumerated...() */
} /* if table->getchildrencolumn() */
} //
/**
* 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()."::COLUMN_NAME).
* @return string
*/
public static function alias(\$alias, \$column)
{
return str_replace(".$this->getPeerClassname()."::TABLE_NAME.'.', \$alias.'.', \$column);
}
";
} // addAliasMethod
/**
* 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(".$this->getPeerClassname()."::".$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 PropelPDO \$con
* @return int Number of matching rows.
*/
public static function doCount(Criteria \$criteria, \$distinct = false, PropelPDO \$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(".$this->getPeerClassname()."::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
\$criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}";
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
// BasePeer returns a PDOStatement
\$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 .= "
/**
* Method to select one object from the DB.
*
* @param Criteria \$criteria object used to create the SELECT statement.
* @param PropelPDO \$con
* @return ".$this->getObjectClassname()."
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectOne(Criteria \$criteria, PropelPDO \$con = null)
{
\$critcopy = clone \$criteria;
\$critcopy->setLimit(1);
\$objects = ".$this->getPeerClassname()."::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 .= "
/**
* Method to do selects.
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO \$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, PropelPDO \$con = null)
{
return ".$this->getPeerClassname()."::populateObjects(".$this->getPeerClassname()."::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 PDOStatement.
*
* Use this method directly if you want to work with an executed statement durirectly (for example
* to perform your own object hydration).
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO \$con The connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return PDOStatement The executed PDOStatement object.
* @see ".$this->basePeerClassname."::doSelect()
*/
public static function doSelectStmt(Criteria \$criteria, PropelPDO \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
if (!\$criteria->hasSelectClause()) {
\$criteria = clone \$criteria;
".$this->getPeerClassname()."::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 PDOStatement
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.
*/
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)
{
$table = $this->getTable();
$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()." \$value 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(".$this->getObjectClassname()." \$obj, \$key = null)
{
if (Propel::isInstancePoolingEnabled()) {
if (\$key === null) {";
$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() && \$value !== null) {";
$pks = $table->getPrimaryKey();
$script .= "
if (is_object(\$value) && \$value instanceof ".$this->getObjectClassname().") {";
$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()
";
} // addRemoveFromInstancePool()
/**
* 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);
$tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage();
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 ($fk->getOnDelete() == ForeignKey::CASCADE || $fk->getOnDelete() == ForeignKey::SETNULL) {
$script .= "
// Invalidate objects in ".$joinedTablePeerBuilder->getClassname()." instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
".$joinedTablePeerBuilder->getClassname()."::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 PropelPDO 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).";
}
";
} // addGetPrimaryKeyHash
/**
* 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 PropelPDO 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 .= "
}
";
} // addGetPrimaryKeyFromRow
/**
* 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.
*
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(PDOStatement \$stmt)
{
\$results = array();
";
if (!$table->getChildrenColumn()) {
$script .= "
// set the class once to avoid overhead in the loop
\$cls = ".$this->getPeerClassname()."::getOMClass(false);";
}
$script .= "
// populate the object(s)
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj = ".$this->getPeerClassname()."::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 = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
\$obj->hydrate(\$row);
\$results[] = \$obj;
".$this->getPeerClassname()."::addInstanceToPool(\$obj, \$key);";
} else {
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
\$obj->hydrate(\$row);
\$results[] = \$obj;
".$this->getPeerClassname()."::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 PropelPDO 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->getStubObjectBuilder()->getClassName(). " object, last column rank)
*/
public static function populateObject(\$row, \$startcol = 0)
{
\$key = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, \$startcol);
if (null !== (\$obj = ".$this->getPeerClassname()."::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 + " . $this->getPeerClassname() . "::NUM_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 + " . $this->getPeerClassname() . "::NUM_COLUMNS;";
}
$script .= "
} else {";
if (!$table->getChildrenColumn()) {
$script .= "
\$cls = ".$this->getPeerClassname()."::OM_CLASS;";
} else {
$script .= "
\$cls = ".$this->getPeerClassname()."::getOMClass(\$row, \$startcol, false);";
}
$script .= "
\$obj = new \$cls();
\$col = \$obj->hydrate(\$row, \$startcol);
" . $this->getPeerClassname() . "::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 PropelPDO 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 = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
}
";
} else { /* if not enumerated */
$script .= "
\$omClass = \$row[\$colnum + ".($col->getPosition()-1)."];
\$omClass = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
}
$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 tranalted 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 ? ".$this->getPeerClassname()."::CLASS_DEFAULT : ".$this->getPeerClassname()."::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.
*/
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 .= "
/**
* Method perform 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 PropelPDO \$con the PropelPDO 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, PropelPDO \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
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) {
$cfc = $col->getPhpName();
if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none" && !$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() && $table->getIdMethod() != "none" && $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 .= "
/**
* Method perform 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 PropelPDO \$con The connection to use (specify PropelPDO 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, PropelPDO \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
\$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(".$this->getPeerClassname()."::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 .= "
/**
* Method to DELETE all rows from the ".$table->getName()." table.
*
* @return int The number of affected rows (if supported by underlying database driver).
*/
public static function doDeleteAll(\$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
\$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 += ".$this->getPeerClassname()."::doOnDeleteCascade(new Criteria(".$this->getPeerClassname()."::DATABASE_NAME), \$con);
";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= $this->getPeerClassname() . "::doOnDeleteSetNull(new Criteria(".$this->getPeerClassname() . "::DATABASE_NAME), \$con);
";
}
$script .= "\$affectedRows += {$this->basePeerClassname}::doDeleteAll(".$this->getPeerClassname()."::TABLE_NAME, \$con, ".$this->getPeerClassname()."::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).
".$this->getPeerClassname()."::clearInstancePool();
".$this->getPeerClassname()."::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 .= "
/**
* Method perform 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 PropelPDO \$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.
*/
public static function doDelete(\$values, PropelPDO \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
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.
".$this->getPeerClassname()."::clearInstancePool();";
}
$script .= "
// rename for clarity
\$criteria = clone \$values;
} elseif (\$values instanceof ".$this->getObjectClassname().") { // it's a model object";
if (!$emulateCascade) {
$script .= "
// invalidate the cache for this single object
".$this->getPeerClassname()."::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 (count($table->getPrimaryKey()) === 1) {
$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) {
".$this->getPeerClassname()."::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 ($i == 0) {
$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
".$this->getPeerClassname()."::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 += ".$this->getPeerClassname()."::doOnDeleteCascade(\$c, \$con);
";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= "
// cloning the Criteria in case it's modified by doSelect() or doSelectStmt()
\$c = clone \$criteria;
" . $this->getPeerClassname() . "::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) {
".$this->getPeerClassname()."::clearInstancePool();
} elseif (\$values instanceof ".$this->getObjectClassname().") { // it's a model object
".$this->getPeerClassname()."::removeInstanceFromPool(\$values);
} else { // it's a primary key, or an array of pks
foreach ((array) \$values as \$singleval) {
".$this->getPeerClassname()."::removeInstanceFromPool(\$singleval);
}
}
";
}
$script .= "
\$affectedRows += {$this->basePeerClassname}::doDelete(\$criteria, \$con);
".$this->getPeerClassname()."::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 PropelPDO \$con
* @return int The number of affected rows (if supported by underlying database driver).
*/
protected static function doOnDeleteCascade(Criteria \$criteria, PropelPDO \$con)
{
// initialize var to track total num of affected rows
\$affectedRows = 0;
// first find the objects that are implicated by the \$criteria
\$objects = ".$this->getPeerClassname()."::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);
$tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage();
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 ($fk->getOnDelete() == ForeignKey::CASCADE) {
// backwards on purpose
$columnNamesF = $fk->getLocalColumns();
$columnNamesL = $fk->getForeignColumns();
$script .= "
// delete related $fkClassName objects
\$criteria = new Criteria(".$joinedTablePeerBuilder->getPeerClassname()."::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()."::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 PropelPDO \$con
* @return void
*/
protected static function doOnDeleteSetNull(Criteria \$criteria, PropelPDO \$con)
{
// first find the objects that are implicated by the \$criteria
\$objects = ".$this->getPeerClassname()."::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 thigns 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 ($fk->getOnDelete() == ForeignKey::SETNULL) {
// 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(".$this->getPeerClassname()."::DATABASE_NAME);
\$updateValues = new Criteria(".$this->getPeerClassname()."::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 doValidate() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoValidate(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Validates all modified columns of given ".$this->getObjectClassname()." object.
* If parameter \$columns is either a single column name or an array of column names
* than only those columns are validated.
*
* NOTICE: This does not apply to primary or foreign keys for now.
*
* @param ".$this->getObjectClassname()." \$obj The object to validate.
* @param mixed \$cols Column name or array of column names.
*
* @return mixed TRUE if all columns are valid or the error message of the first invalid column.
*/
public static function doValidate(".$this->getObjectClassname()." \$obj, \$cols = null)
{
\$columns = array();
if (\$cols) {
\$dbMap = Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME);
\$tableMap = \$dbMap->getTable(".$this->getPeerClassname()."::TABLE_NAME);
if (! is_array(\$cols)) {
\$cols = array(\$cols);
}
foreach (\$cols as \$colName) {
if (\$tableMap->containsColumn(\$colName)) {
\$get = 'get' . \$tableMap->getColumn(\$colName)->getPhpName();
\$columns[\$colName] = \$obj->\$get();
}
}
} else {
";
foreach ($table->getValidators() as $val) {
$col = $val->getColumn();
if (!$col->isAutoIncrement()) {
$script .= "
if (\$obj->isNew() || \$obj->isColumnModified(".$this->getColumnConstant($col)."))
\$columns[".$this->getColumnConstant($col)."] = \$obj->get".$col->getPhpName()."();
";
} // if
} // foreach
$script .= "
}
return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);
}
";
} // end addDoValidate()
/**
* 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 PropelPDO \$con the connection to use
* @return " .$this->getObjectClassname(). "
*/
public static function ".$this->getRetrieveMethodName()."(\$pk, PropelPDO \$con = null)
{
if (null !== (\$obj = ".$this->getPeerClassname()."::getInstanceFromPool(".$this->getInstancePoolKeySnippet('$pk')."))) {
return \$obj;
}
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
\$criteria->add(".$this->getColumnConstant($col).", \$pk);
\$v = ".$this->getPeerClassname()."::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 PropelPDO \$con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function ".$this->getRetrieveMethodName()."s(\$pks, PropelPDO \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
\$objs = null;
if (empty(\$pks)) {
\$objs = array();
} else {
\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
$k1 = $table->getPrimaryKey();
$script .= "
\$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);";
$script .= "
\$objs = ".$this->getPeerClassname()."::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 PropelPDO \$con
* @return ".$this->getObjectClassname()."
*/
public static function ".$this->getRetrieveMethodName()."(";
$php = array();
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$php[] = '$' . $clo;
} /* foreach */
$script .= implode(', ', $php);
$script .= ", PropelPDO \$con = null) {
\$_instancePoolKey = ".$this->getInstancePoolKeySnippet($php).";";
$script .= "
if (null !== (\$obj = ".$this->getPeerClassname()."::getInstanceFromPool(\$_instancePoolKey))) {
return \$obj;
}
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", $".$clo.");";
}
$script .= "
\$v = ".$this->getPeerClassname()."::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::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;
}
public function addCriteriaJoin($fk, $table, $joinTable, $joinedTablePeerBuilder)
{
$script = '';
$lfMap = $fk->getLocalForeignMapping();
$lftCols = $fk->getLocalColumns();
if (count($lftCols) == 1)
{
// simple foreign key
$lftCol = $lftCols[0];
$script .= sprintf("
\$criteria->addJoin(%s, %s, \$join_behavior);\n",
$this->getColumnConstant($table->getColumn($lftCol) ),
$joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$lftCol] ) ));
}
else
{
// composite foreign key
$script .= "
\$criteria->addMultipleJoin(array(\n";
foreach ($lftCols as $columnName ) {
$script .= sprintf(" array(%s, %s),\n",
$this->getColumnConstant($table->getColumn($columnName) ),
$joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) )
);
}
$script .= " ), \$join_behavior);\n";
}
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());
$join_behavior = $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 PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @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, $plural = false)."(Criteria \$criteria, \$con = null, \$join_behavior = $join_behavior)
{
\$criteria = clone \$criteria;
// Set the correct dbName if it has not been overridden
if (\$criteria->getDbName() == Propel::getDefaultDB()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
\$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
".$joinedTablePeerBuilder->getPeerClassname()."::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 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = ".$this->getPeerClassname()."::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 = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$this->getPeerClassname()."::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
".$this->getPeerClassname()."::addInstanceToPool(\$obj1, \$key1);
} // if \$obj1 already loaded
\$key2 = ".$joinedTablePeerBuilder->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, \$startcol);
if (\$key2 !== null) {
\$obj2 = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key2);
if (!\$obj2) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj2', '$cls') . "
\$obj2->hydrate(\$row, \$startcol);
".$joinedTablePeerBuilder->getPeerClassname()."::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->getObjectClassname() . "(\$obj2);";
} else {
$script .= "
\$obj2->add" . $joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = 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();
$className = $this->getObjectClassname();
$countFK = count($table->getForeignKeys());
$join_behavior = $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);
$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
$joinClassName = $joinedTableObjectBuilder->getObjectClassname();
$script .= "
/**
* Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @return int Number of matching rows.
*/
public static function doCountJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
{
// 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(".$this->getPeerClassname()."::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
";
$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();
$join_behavior = $this->getJoinBehavior();
$script .= "
/**
* Selects a collection of $className objects pre-filled with all related objects.
*
* @param Criteria \$criteria
* @param PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @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, \$join_behavior = $join_behavior)
{
\$criteria = clone \$criteria;
// Set the correct dbName if it has not been overridden
if (\$criteria->getDbName() == Propel::getDefaultDB()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_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()."::addSelectColumns(\$criteria);
\$startcol$new_index = \$startcol$index + (".$joinedTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS - ".$joinedTablePeerBuilder->getPeerClassname()."::NUM_LAZY_LOAD_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 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = ".$this->getPeerClassname()."::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 = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$this->getPeerClassname()."::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
".$this->getPeerClassname()."::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());
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$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()."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
if (\$key$index !== null) {
\$obj$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key$index);
if (!\$obj$index) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol$index);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(false);
";
} /* $joinTable->getChildrenColumn() */
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
\$obj".$index."->hydrate(\$row, \$startcol$index);
".$joinedTablePeerBuilder->getPeerClassname()."::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->getObjectClassname()."(\$obj".$index.");";
} else {
$script .= "
\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1);";
}
$script .= "
} // if joined row not null
";
} // $fk->getForeignTableName() != $table->getName()
} //foreach foreign key
$script .= "
\$results[] = \$obj1;
}
\$stmt->closeCursor();
return \$results;
}
";
} // end addDoSelectJoinAll()
/**
* Adds the doCountJoinAll() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCountJoinAll(&$script)
{
$table = $this->getTable();
$className = $this->getObjectClassname();
$join_behavior = $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 PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @return int Number of matching rows.
*/
public static function doCountJoinAll(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
{
// 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(".$this->getPeerClassname()."::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
";
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();
$join_behavior = $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 ) {
$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
$excludedTablePeerBuilder = $this->getNewPeerBuilder($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 PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @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, $plural = false)."(Criteria \$criteria, \$con = null, \$join_behavior = $join_behavior)
{
\$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::getDefaultDB()) {
\$criteria->setDbName(self::DATABASE_NAME);
}
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_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()."::addSelectColumns(\$criteria);
\$startcol$new_index = \$startcol$index + (".$joinTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS - ".$joinTablePeerBuilder->getPeerClassname()."::NUM_LAZY_LOAD_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);
}
}
} // foreach fkeys
// apply behaviors
$this->applyBehaviorModifier('preSelect', $script);
$script .= "
\$stmt = ".$this->basePeerClassname ."::doSelect(\$criteria, \$con);
\$results = array();
while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
\$key1 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
if (null !== (\$obj1 = ".$this->getPeerClassname()."::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 = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$this->getPeerClassname()."::getOMClass(false);
";
}
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
\$obj1->hydrate(\$row);
".$this->getPeerClassname()."::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()."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
if (\$key$index !== null) {
\$obj$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key$index);
if (!\$obj$index) {
";
if ($joinTable->getChildrenColumn()) {
$script .= "
\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol$index);
\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
";
} else {
$script .= "
\$cls = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(false);
";
} /* $joinTable->getChildrenColumn() */
$script .= "
" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
\$obj".$index."->hydrate(\$row, \$startcol$index);
".$joinedTablePeerBuilder->getPeerClassname()."::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, $plural = 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
} // addDoSelectJoinAllExcept
/**
* Adds the doCountJoinAllExcept*() methods.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCountJoinAllExcept(&$script)
{
$table = $this->getTable();
$join_behavior = $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 ) {
$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
$excludedTablePeerBuilder = $this->getNewPeerBuilder($excludedTable);
$excludedClassName = $excludedTableObjectBuilder->getObjectClassname();
$script .= "
/**
* Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO \$con
* @param String \$join_behavior the type of joins to use, defaults to $join_behavior
* @return int Number of matching rows.
*/
public static function doCountJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
{
// 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(".$this->getPeerClassname()."::TABLE_NAME);
if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->setDistinct();
}
if (!\$criteria->hasSelectClause()) {
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
}
\$criteria->clearOrderByColumns(); // ORDER BY should not affect count
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
}
";
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);
}
}
} // foreach fkeys
// 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
} // addDoCountJoinAllExcept
/**
* returns the desired join behavior as set in the build properties
* see trac ticket #588, #491
*
*/
protected function getJoinBehavior()
{
return $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
}
} // PHP5PeerBuilder