This forum is in READ-ONLY mode.
You can look around, but if you want to ask a new question, please use the new forum.
Home » plugins » General plug-ins » [howTo] make sfPropelImpersonatorPlugin working with Propel 1.3
[howTo] make sfPropelImpersonatorPlugin working with Propel 1.3 [message #88410] Sat, 14 November 2009 20:40 Go to next message
rozwell  is currently offline rozwell
Messages: 12
Registered: September 2008
Location: Poland
Junior Member

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 Wink

rozwell

p.s.
If you find some language/code errors/mistakes - let me know.

[Updated on: Sun, 15 November 2009 18:00]

Re: [howTo] make sfPropelImpersonatorPlugin working with Propel 1.3 [message #88450 is a reply to message #88410 ] Sun, 15 November 2009 20:20 Go to previous messageGo to next message
halfer  is currently offline halfer
Messages: 9535
Registered: January 2006
Location: West Midlands, UK
Faithful Member
That's great. If you get in touch with the plugin author, via the plugins page, you can ask for svn access - perhaps they will be happy for you to submit this as a version suitable for symfony 1.2+.

Alternatively drop them a line on the main plugins page via email, perhaps attaching your new plugin.


Remember Palestine
Re: [howTo] make sfPropelImpersonatorPlugin working with Propel 1.3 [message #88468 is a reply to message #88410 ] Mon, 16 November 2009 00:42 Go to previous message
rozwell  is currently offline rozwell
Messages: 12
Registered: September 2008
Location: Poland
Junior Member

I've already received an answer from author and he'll take a closer look at this "fix" soon.

But propel 1.4 is coming and it will be fixed:
http://propel.phpdb.org/trac/wiki/Users/Documentation/1.4/Wh atsNew#ForeignKeyRetrieversNowUseInstancePool
so.. plugin won't be needed anymore then.

Until that I can try to test and make it "stable" if there are a few people who needs it... (for me it's sufficient now)

And symfony is going to use doctrine so I'll need to do some tests to find what works better for me.
If I choose doctrine it's obvious I won't use propel anymore but.. we'll see.

p.s.
Thanks for the reply =)

EDIT:
A little notice: only basic functionality works fine. Additional methods can work but probably they will fail.

[Updated on: Thu, 19 November 2009 23:46]

Previous Topic:[solved] sfGuardPlugin + Last Alpha(0.9.2397)
Next Topic:Can“t Install sfGuardPlugin
Goto Forum:
  

powered by FUDforum - copyright ©2001-2004 FUD Forum Bulletin Board Software