Search code examples
symfony1symfony-1.4sfguard

Filter by UserProfile fields with sfGuard plugin


How do I filter by the sfGuardUserProfile fields, when using the sfGuard plugin in Symfony 1.4?

As I think is standard, I created a sf_guard_user_profile table to hold fields like first name, last name, and so on.

I have a fairly stock list of users for my admin index page. I can filter by the username just fine. But I cannot filter by a field that is in the sf_guard_user_profile table, like last_name.

My generator.yml looks like

generator:
  class: sfPropelGenerator
  param:
    model_class: sfGuardUser

    config:
      list:
        display: [=username, first_name, last_name, last_login, role]
        batch_actions: []

      filter:
        display: [username]

      form:
        class: myGuardUserAdminForm

I can get the fields to show up in the form on the page by changing to:

filter:
    class: sfGuardUserProfileFormFilter

but when I submit that form with a valid value for last_name, it doesn't filter. All records are returned.


Solution

  • Adding sfGuardUserProfileFormFilter as filter class isn't the right way to filter first_name, last_name and other profile fields.

    Instead you have to add a field, that you need to filter, in the filter display list like:

    filter:
        display: [username, first_name, last_name]
    

    Then you have to merge sfGuardUserProfileFormFilter in sfGuardUserFormFilter:

    public function configure()
    {
        parent::configure();
    
        $this->mergeForm(new sfGuardUserProfileFormFilter());
    }
    

    Finally add in sfGuardUserFormFilter a function addMyFieldColumnCriteria (Propel notation) for each field of the merged form sfGuardUserProfileFormFilter that you want to filter. For first_name we have:

        protected function addFirstNameColumnCriteria(Criteria $criteria, $field, $values)
        {
            if (!is_array($values))
                return;
    
            $criteria->addJoin(sfGuardUserPeer::ID, sfGuardUserProfilePeer::USER_ID, Criteria::INNER_JOIN);
    
            if (isset($values['is_empty']) && $values['is_empty'])
            {
                $criteria->add($field, null, Criteria::ISNULL);
                $criteria->addOr($field, '', Criteria::EQUAL);
            }
            else
            {
                $value = $values['text'];
                if ($value == '')
                    return;
                $criteria->add($field, '%'.$value.'%', Criteria::LIKE);
            }
        }