With SonataAdminBundle. Configure filter on a two step related entity

javigzz picture javigzz · Nov 9, 2012 · Viewed 9.5k times · Source

I'd like to know weather is possible and how to configure a filter for the list view as the following with SonataAdminBundle in Symfony 2

Say I have entities Order, pointing to entities User, pointing to entities Company. I want to configure filters both for filtering by User and also for filtering by Company (User's Company) The first is straight forward. The second is what I try to clearify.

In the class OrderAdmin I would overwrite configureDatagridFilters as:

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
     $datagridMapper
         ->add('created_at')
         //... some other filters on Order fields, as usual

         // the filter on User, provided 'user', no ploblem
         ->add('user')

         // and the filter by Company 
         ->add('user.company') // this doesn't work, of course
    ;
}

That syntax for the company filter is inpired by sonta docs: http://sonata-project.org/bundles/doctrine-orm-admin/2-0/doc/reference/filter_field_definition.html

Is not intended for what I try to acomplish, but cannot find where to look at.

Hope someone has a clue on this.

Thanks

Answer

javigzz picture javigzz · Nov 14, 2012

Finally I found an answer guided by this other question: How can I create a custom DataGrid filter in SonataAdmin and a closer read of the sonata admin docs link I pasted in my question.

In case someone have this issue and taking the previous example:

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
   $datagridMapper

      //... whatever filter

      // and the filter by Company 

      ->add('company', 'doctrine_orm_callback', array(
            'callback'   => array($this, 'callbackFilterCompany'),
            'field_type' => 'checkbox'
            ),
    'choice', 
    array('choices' => $this -> getCompanyChoices())
;
}

where the method getCompanyChoices retrieves an associative array of company ids => company names (for instance). And the method callbackFilterCompany is as follows

public function callbackFilterCompany ($queryBuilder, $alias, $field, $value)
{
    if(!is_array($value) or !array_key_exists('value', $value) 
        or empty($value['value'])){

        return;

    }

    $queryBuilder
    ->leftJoin(sprintf('%s.user', $alias), 'u')
    ->leftJoin('u.company', 'c')
    ->andWhere('c.id = :id')
    ->setParameter('id', $value['value'])
    ;

    return true;
}