2013-04-09 3 views
5

Я использую SonataAdminBundle с FosUserBundle. У меня проблемы с моей панелью.Sonata Admin Bundle элемент фильтра панели управления из роли и разрешения DDBB

В моем приложении у меня есть ресурсы, компании и пользователи. Пользователь принадлежит компании и может создавать ресурсы, которые будут принадлежать его компании. Все это будет сделано на панели инструментов, доступной для всех ролей.

Что я хочу сделать, так это то, что каждый может получить доступ к панели управления, но когда пользователь выбирает объект (ресурс) для отображения в панели управления, будут показаны только сущности его компаний. Например, две компании могут создать транспортное средство (ресурс), но каждая компания увидит только свои транспортные средства (ресурсы).

В заключение, я хочу, чтобы панель инструментов фильтровала объекты компании пользователя, который подключен. Есть ли способ создать в Sonata запрос для показа только некоторых объектов в зависимости от Company_Id пользователя и Company_Id ресурса, отображаемого в BBDD?

ответ

4

Самый простой способ - отредактировать запрос и проверить доступ в действиях edit/show.

Что-то вроде этого:

Админ класс

/** 
* {@inheritdoc} 
*/ 
public function createQuery($context = 'list') 
{ 
    $user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser(); 

    /** @var \Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery @query */ 
    $query = $this->getModelManager()->createQuery($this->getClass(), 'o'); 
    if (!$this->isGranted('MASTER')) { 
     $query 
      ->where('entity.user = :user') 
      ->setParameter('user', $user) 
     ; 
    } 

    return $query; 
} 

Если пользователь не MASTER он будет видеть только свои собственные объекты.

Вы также можете реализовать hasSubjectAccess метод класса администратора, как:

/** 
* Check whether the user has access to the subject 
* 
* @return bool 
*/ 
protected function hasSubjectAccess() 
{ 
    $user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser(); 
    if (!$this->isGranted('MASTER') && $this->getSubject()->getUser() !== $user) { 
     return false; 
    } 

    return true; 
} 

и выполнять этот вид проверки в редактирование и шоу формы:

/** 
* {@inheritdoc} 
*/ 
protected function configureFormFields(FormMapper $formMapper) 
{ 
    if (!$this->hasSubjectAccess()) { 
     throw new AccessDeniedException(); 
    } 

    // ... 
} 

Другой способ заключается в реализации ACL. Вы можете прочитать больше о том, что в official documentation

+0

Спасибо, это я искал, но я до сих пор есть некоторые сомнения. Я написал их в новом ответе, потому что он слишком длинный. – Angel

1

Наконец, я понял, как это:

public function createQuery($context = 'list') 
    $query = $this->getModelManager()->createQuery($this->getClass(), 'entity'); 

    if (($this->getClass() instanceof \Sademer\CoreBundle\Entity\Resource) 
    || (is_subclass_of($this->getClass(), \Sademer\CoreBundle\Entity\Resource'))) 
    { 
      $query->select ('e'); 
      $query->from($this->getClass(), 'e'); 
      $query->from('CoreBundle\Entity\Resource', 'r'); 
      $query->where('e.id = r.id AND r.company = :company'); 
      $query->setParameter('company', 5); 
    } 
} 
1

Для меня функция CreateQuery() не работает. Может быть, из-за версии Sonata Admin. В любом случае, для меня работала функция configureDatagridFilters().

Это делает ту же работу, как CreateQuery и выглядит примерно так:

protected function configureDatagridFilters(DatagridMapper $datagridMapper) 
{ 
    $qb = $datagridMapper 
     ->getDatagrid() 
     ->getQuery() 
     ->getQueryBuilder(); 

    $qb->andWhere(
     // Your where clause here 
    ); 
    $qb->setParameter(); // Set Parameter 
}