Hello,
Today I was needing some performance optimization (multiple joins) in my application so I started to look out for propel plugins.
I've found sfPropelImpersonatorPlugin which is perfectly what I needed but something was wrong. It wasn't working (why if it's for symfony 1.2?).
On plugins homepage I found info that it's for Propel 1.2:
sfPropelImpersonator is a symfony plugin that uses DatabaseMaps to fetch any propel 1.2 criteria based request and fill in relations between related objects.
It was strange that such a great plugin isn't updated, so I did some digging and found two branches [1.0 and 1.3] in repository:
http://svn.symfony-project.com/plugins/sfPropelImpersonatorP lugin/branches/
1.3 looked really interesting so I decided to check it out.
Following basic example in here:
http://dakrazy.net/document/sf_propel_impersonator_documenta tion/quick_examples.html
gave me an error:
Fatal error: Call to a member function getTable() on a non-object in /home/sfprojects/projectX/plugins/sfPropelImpersonatorPlugin/lib/sfPropelObjectPeerImpersonator.class.php on line 188
But there was no error about ResultSet like in 1.0 branch so it was good.
After little debugging I fixed that bug so, here you've got a little howTo:
Get plugin via svn:
svn co http://svn.symfony-project.com/plugins/sfPropelImpersonatorPlugin/branches/1.3 sfPropel13ImpersonatorPlugin
Then add in file sfPropelImpersonatorPlugin/lib/sfPropelObjectPeerImpersonato r.class.php on line 180:
if (!$oFrom->getPeer()->getMapBuilder()->isBuilt())
{
$oFrom->getPeer()->getMapBuilder()->doBuild();
}
so it will look like this:
(...)
protected function initializeRelations()
{
$this->relations = array();
foreach ($this->objects as $iFrom => $oFrom)
{
if (null !== ($peer = $oFrom->getPeer()))
{
$_class_from = get_class($oFrom);
////////* rozwells fix */
if (!$oFrom->getPeer()->getMapBuilder()->isBuilt())
{
$oFrom->getPeer()->getMapBuilder()->doBuild();
}
////////* fix end */
$databaseMap = $oFrom->getPeer()->getMapBuilder()->getDatabaseMap();
foreach ($databaseMap->getTable(constant($_class_from.'Peer::TABLE_NAME'))->getColumns() as $c)
{
if ($c->isForeignKey())
{
$relatedTableName = $c->getRelatedTableName();
(...)
This will do the job and plugin will work.
Unfortunately I had an issue (propel bug) with one-to-many relations - propel was still generating queries despite object already had it's relations.
So next "fix" was needed, I'll show you my example:
(sorry, but I don't use yml schema)
<database>
<table name="member" phpName="Member">
<column name="id" primaryKey="true" autoIncrement="true" type="INTEGER" required="true" />
<column name="name" type="VARCHAR" size="100" required="true" />
</table>
<table name="event" phpName="Event">
<column name="id" primaryKey="true" autoIncrement="true" type="INTEGER" required="true" />
<column name="name" type="VARCHAR" size="250" required="true" />
<foreign-key foreignTable="registration" onDelete="SETNULL">
<reference local="registration_id" foreign="id" />
</foreign-key>
</table>
<table name="member_in_event" phpName="MemberInEvent">
<column name="member_id" primaryKey="true" type="INTEGER" required="true" />
<column name="event_id" primaryKey="true" type="INTEGER" required="true" />
<foreign-key foreignTable="member" onDelete="CASCADE">
<reference local="member_id" foreign="id" />
</foreign-key>
<foreign-key foreignTable="event" onDelete="CASCADE">
<reference local="event_id" foreign="id" />
</foreign-key>
</table>
</database>
So the theres method which generates unnecessary queries:
$member->getMemberInEvents()
but Member Object already has filled property collMemberInEvents so in /lib/Member.php I just added:
public function getMemberInEvents($criteria = null, PropelPDO $con = null)
{
if ($this->collMemberInEvents === null)
return parent::getMemberInEvents($criteria, $con);
return $this->collMemberInEvents;
}
Voila!
It's not well tested so if you find any bugs or problems - post it!
And I hope it's not too long and understandable 
rozwell
p.s.
If you find some language/code errors/mistakes - let me know.