If you use Propel 1.2 with i18n, I think this patch can be util to improve your performace:
In PEER:
- public static function retrieveByPKWithI18n($pk, $culture = null, $con = null)
- public static function retrieveByPKsWithI18n($pks, $culture = null, $con = null)
In OBJECT:
- public function getSerialWithI18n($con = null)
- public function getFilesWithI18n($criteria = null, $con = null)
- hydate initialice culture by default
In file 'SfPeerBuilder?.php' add:
protected function addRetrieveByPKMethods(&$script)
{
parent::addRetrieveByPKMethods($script);
if ($this->getTable()->getAttribute('isI18N'))
{
if (count($this->getTable()->getPrimaryKey()) === 1) {
$this->addRetrieveByPKWithI18n_SinglePK($script);
$this->addRetrieveByPKsWithI18n_SinglePK($script);
} else {
$this->addRetrieveByPKWithI18n_MultiPK($script);
}
}
}
/**
* Adds the retrieveByPKWithI18n method for tables with single-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPKWithI18n_SinglePK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve a single object by pkey with their i18n objects.
*
* @param mixed \$pk the primary key.
* @param Connection \$con the connection to use
* @return " . $table->getPhpName() . "
*/
public static function ".$this->getRetrieveMethodName()."WithI18n(\$pk, \$culture = null, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
";
if (count($table->getPrimaryKey()) === 1) {
$pkey = $table->getPrimaryKey();
$col = array_shift($pkey);
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", \$pk);
";
} else {
// primary key is composite; we therefore, expect
// the primary key passed to be an array of pkey
// values
$i=0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", \$pk[$i]);";
$i++;
}
} /* if count(table.PrimaryKeys) */
$script .= "
\$v = ".$this->getPeerClassname()."::doSelectWithI18n(\$criteria, \$culture, \$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 addRetrieveByPKsWithI18n_SinglePK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve multiple objects by pkey.
*
* @param array \$pks List of primary keys with their i18n objects.
* @param Connection \$con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function ".$this->getRetrieveMethodName()."sWithI18n(\$pks, \$culture = null, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$objs = null;
if (empty(\$pks)) {
\$objs = array();
} else {
\$criteria = new Criteria();";
if (count($table->getPrimaryKey()) == 1) {
$k1 = $table->getPrimaryKey();
$script .= "
\$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);";
} else {
$script .= "
foreach(\$pks as \$pk) {";
$i = 0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$c{$i} = \$criteria->getNewCriterion(".$this->getPeerClassname($col).", \$pk[$i], Criteria::EQUAL);";
$j = $i - 1;
if ($i > 0) {
$script .= "
\$c{$j}->addAnd(\$c{$i});";
} /* if $i > 0 */
$i++;
} /* foreach */
$script .= "
\$criteria->addOr(\$c0);
}";
} /* if count prim keys == 1 */
$script .= "
\$objs = ".$this->getPeerClassname()."::doSelectWithI18n(\$criteria, \$culture, \$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 addRetrieveByPKWithI18n_MultiPK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve object using using composite pkey values.
* ";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$cptype = $col->getPhpNative();
$script .= "@param $cptype $".$clo."
";
}
$script .= "
* @param Connection \$con
* @return ".$table->getPhpName()."
*/
public static function ".$this->getRetrieveMethodName()."WithI18n(";
$co = 0;
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= ($co++ ? "," : "") . " $".$clo;
} /* foreach */
$script .= ", \$culture = null, \$con = null) {
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$criteria = new Criteria();";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", $".$clo.");";
}
$script .= "
\$v = ".$this->getPeerClassname()."::doSelectWithI18n(\$criteria, \$culture, \$con);
return !empty(\$v) ? \$v[0] : null;
}";
}
And in file 'SfObjectBuilder?.php' add:
/**
* Adds the hydrate() method, which sets attributes of the object based on a ResultSet.
*/
protected function addHydrate(&$script)
{
$tmp = '';
$new = (!$this->getTable()->getAttribute('isI18N'))?"\$this->setNew(false);":"\$this->setNew(false);
\$this->setCulture(sfContext::getInstance()->getUser()->getCulture());";
parent::addHydrate($tmp);
// add autosave to i18n object even if the base object is not changed
$tmp = str_replace('$this->setNew(false);', $new, $tmp);
$script .= $tmp;
}
/**
* Adds the methods that get & set objects related by foreign key to the current object.
* @param string &$script The script will be modified in this method.
*/
protected function addFKMethods(&$script)
{
foreach ($this->getTable()->getForeignKeys() as $fk) {
$this->addFKMutator($script, $fk);
$this->addFKAccessor($script, $fk);
if($this->getForeignTable($fk)->getAttribute('isI18N'))
{
$this->addFKAccessorWithI18n($script, $fk);
}
} // foreach fk
}
/**
* Adds the accessor (getter) method for getting an fkey related object.
* @param string &$script The script will be modified in this method.
*/
protected function addFKAccessorWithI18n(&$script, ForeignKey $fk)
{
$table = $this->getTable();
$className = $this->getForeignTable($fk)->getPhpName();
$varName = $this->getFKVarName($fk);
$and = "";
$comma = "";
$conditional = "";
$arglist = "";
$argsize = 0;
foreach ($fk->getLocalColumns() as $columnName) {
$column = $table->getColumn($columnName);
$cptype = $column->getPhpNative();
$clo = strtolower($column->getName());
// FIXME: is this correct? what about negative numbers?
if ($cptype == "integer" || $cptype == "float" || $cptype == "double") {
$conditional .= $and . "\$this->". $clo ." > 0";
} elseif($cptype == "string") {
$conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)";
} else {
$conditional .= $and . "\$this->" . $clo ." !== null";
}
$arglist .= $comma . "\$this->" . $clo;
$and = " && ";
$comma = ", ";
$argsize = $argsize + 1;
}
$pCollName = $this->getFKPhpNameAffix($fk, $plural = true);
$fkPeerBuilder = OMBuilder::getNewPeerBuilder($this->getForeignTable($fk));
$script .= "
/**
* Get the associated $className object
*
* @param Connection Optional Connection object.
* @return $className The associated $className object.
* @throws PropelException
*/
public function get".$this->getFKPhpNameAffix($fk, $plural = false)."WithI18n(\$con = null)
{
if (\$this->$varName === null && ($conditional)) {
// include the related Peer class
include_once '".$fkPeerBuilder->getClassFilePath()."';
";
$script .= "
\$this->$varName = ".$fkPeerBuilder->getPeerClassname()."::".$fkPeerBuilder->getRetrieveMethodName()."WithI18n($arglist, \$this->getCulture(), \$con);
/* The following can be used instead of the line above to
guarantee the related object contains a reference
to this object, but this level of coupling
may be undesirable in many circumstances.
As it can lead to a db query with many results that may
never be used.
\$obj = ".$fkPeerBuilder->getPeerClassname()."::retrieveByPKWithI18n($arglist, \$this->getCulture(), \$con);
\$obj->add$pCollName(\$this);
*/
}
return \$this->$varName;
}
";
} // addFKAccessor
/**
* Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys.
* @param string &$script The script will be modified in this method.
*/
protected function addRefFKMethods(&$script)
{
foreach($this->getTable()->getReferrers() as $refFK) {
// if ( $refFK->getTable()->getName() != $this->getTable()->getName() ) {
$this->addRefFKInit($script, $refFK);
$this->addRefFKGet($script, $refFK);
$this->addRefFKCount($script, $refFK);
$this->addRefFKAdd($script, $refFK);
$this->addRefFKGetJoinMethods($script, $refFK);
if($this->getTable()->getDatabase()->getTable($refFK->getTableName())->getAttribute('isI18N'))
{
$this->addRefFKGetWithI18n($script, $refFK);
}
// }
}
}
/**
* Adds the method that returns the referrer fkey collection.
* @param string &$script The script will be modified in this method.
*/
protected function addRefFKGetWithI18n(&$script, ForeignKey $refFK)
{
$table = $this->getTable();
$tblFK = $refFK->getTable();
$fkPeerBuilder = OMBuilder::getNewPeerBuilder($refFK->getTable());
$relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
$collName = $this->getRefFKCollVarName($refFK);
$lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK);
$script .= "
/**
* If this collection has already been initialized with
* an identical criteria, it returns the collection.
* Otherwise if this ".$table->getPhpName()." has previously
* been saved, it will retrieve related $relCol from storage.
* If this ".$table->getPhpName()." is new, it will return
* an empty collection or the current collection, the criteria
* is ignored on a new object.
*
* @param Connection \$con
* @param Criteria \$criteria
* @throws PropelException
*/
public function get${relCol}WithI18n(\$criteria = null, \$con = null)
{
// include the Peer class
include_once '".$fkPeerBuilder->getClassFilePath()."';
if (\$criteria === null) {
\$criteria = new Criteria();
}
elseif (\$criteria instanceof Criteria)
{
\$criteria = clone \$criteria;
}
if (\$this->$collName === null) {
if (\$this->isNew()) {
\$this->$collName = array();
} else {
";
foreach ($refFK->getLocalColumns() as $colFKName) {
// $colFKName is local to the referring table (i.e. foreign to this table)
$lfmap = $refFK->getLocalForeignMapping();
$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
$colFK = $refFK->getTable()->getColumn($colFKName);
$script .= "
\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."());
";
} // end foreach ($fk->getForeignColumns()
$script .= "
\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectWithI18n(\$criteria, \$this->getCulture(), \$con);
}
} else {
// criteria has no effect for a new object
if (!\$this->isNew()) {
// the following code is to determine if a new query is
// called for. If the criteria is the same as the last
// one, just return the collection.
";
foreach ($refFK->getLocalColumns() as $colFKName) {
// $colFKName is local to the referring table (i.e. foreign to this table)
$lfmap = $refFK->getLocalForeignMapping();
$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
$colFK = $refFK->getTable()->getColumn($colFKName);
$script .= "
\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."());
";
} // foreach ($fk->getForeignColumns()
$script .= "
if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) {
\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectWithI18n(\$criteria, \$this->getCulture(), \$con);
}
}
}
\$this->$lastCriteriaName = \$criteria;
return \$this->$collName;
}
";
} // addRefererGet()
Sorry for my English

