I must recognize that I don´t really know how to introduce this post (and I am not really sure if the post title fits) so I just going to tell you my situation.

We have installed the sfDoctrineGuardPlugin plugin but we need to save some “extra” information for the users, for example, full name and email data. According to @jwage’s instructions we must create a new model objetc, Profile, having a 1:1 relation with sfGuardUser, like this:

Profile:
  columns:
    sf_guard_user_id: integer(4)
    full_name: string(255)
    email_address: string(255)
  relations:
    User:
      class: sfGuardUser
      local: sf_guard_user_id
      foreign: id
      foreignType: one

Nothing remarkable up to now. But now, let´s suppose we want to access, let´s say full name. The code neccesary is:

  $user->Profile->full_name;

Easy, isn’t it? But deep down in our hearts we’d rather prefer just writing that:

  $user->full_name;

Can we achieve that? Let´s do it!

The Easy-peasy solution
There is a straight forward way to do it. You just need to define a new getter in the sfGuardUser class

// lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUser.class.php
 
  public function getFullName()
  {
    return $this->Profile->full_name;
  }

but, what will happen if we want to get the email, ¿and the phone number?¿and the address?¿and …? According to this, we should define a new getter for every attribute in the Profile class. Fortunately, there is a better solution.

The “magic” solution
PHP has something really cool called magic methods. The solution below takes adventage of Doctrine_Record use of __get($fieldname) magic method.

// lib/model/sfGuardUser.class.php
class sfGuardUser extends sfDoctrineRecord
{
  public function get($fieldName, $type = true)
  {
    try{
      parent::get($fieldName, $type = true);
    }catch(exception $e){
      $this->Profile->$fieldName;
    }
  }
}

Although I am not going to explain in depth what´s going on under the hood, grosso modo, every time you ask the object for an attribute, first, it looks inside its own attributes and if it doesn´t find it then it will looks inside its Profile attributes. In case the attribute is not neither in sfGuardUser nor in Profile an expection will be thrown.

An interesting consecuence
In the list view in the admin generator you can use those attributes directly, like this:

  list:
    display: [username, full_name, email]

Compártelo:
  • Print this article!
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Ping.fm
  • RSS
  • Twitter