Sonata + Fos_user - 如何仅显示与用户相关的实体?
Posted
技术标签:
【中文标题】Sonata + Fos_user - 如何仅显示与用户相关的实体?【英文标题】:Sonata + Fos_user - How to display only entities related to the user? 【发布时间】:2017-10-05 20:53:10 【问题描述】:我的用户是场地管理员。我希望他们能够管理他们的地方和在这些地方发生的事件。
我创建了 fos_user_user 并在那里建立了与地点的关系:
<entity name="Application\Sonata\UserBundle\Entity\User" table="fos_user_user">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<many-to-many field="places" target-entity="EchoBundle\Entity\Place">
<join-table name="users_places">
<join-columns>
<join-column name="user_id" referenced-column-name="id" />
</join-columns>
<inverse-join-columns>
<join-column name="place_id" referenced-column-name="id" />
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
所以现在,我可以管理用户并添加他们管理的地点。它工作正常。
问题:
如何进行过滤,以便他们登录后只能看到自己的位置?
我怎样才能让他们只将活动添加到自己的位置?目前,当您添加活动时,您有一个完整的地点列表可供选择。
如何过滤所有事件,以便他们只看到与其管理的地点相关的事件?
我查看了 Sonata 文档中的“自定义用于生成列表的查询”,但不知道如何使用它。我试图添加 4 年前在 *** 上的答案中找到的安全查询,但没有奏效。
【问题讨论】:
【参考方案1】:在您的 Admin 类中,您可以覆盖 createQuery
(您应该检查并修复下面的示例以满足您的应用模型);)
此解决方案将涵盖问题 1 和 3。
public function createQuery($context = 'list')
$query = parent::createQuery($context);
$aliases = $query->getRootAliases();
$query
->leftJoin($aliases[0] . '.users_places', 'users_places')
->andWhere($query->expr()->eq('users_places.user_id', ':user') )
->setParameter('user', $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser());
return $query;
问题 2:
如果您使用奏鸣曲formMapper
和configureFormFields
方法,您可以在字段定义中传递自定义查询生成器。
$formMapper
->add('events', 'sonata_type_model', [
'label' => 'Events',
'placeholder' => 'Select ...',
'required' => true,
'query' => $blQueryBuilder,
]);
【讨论】:
谢谢。我快到了。关于第二个,我在添加事件表单中有类似的内容: ->add('place', 'sonata_type_model', array( 'class' => 'EchoBundle:Place', 'property' => 'name', 'label' => 'Place', 'query' => $placeQuery, ))' 但是我在构建仅属于用户的地方的查询时遇到了问题。在“原始”SQL 中,它将是:SELECT DISTINCT p.name FROM users_places u LEFT JOIN places p ON u.places_id=p.id... 关于第一个 - 我添加了它但收到:尝试调用类“Doctrine\ORM\Query\Expr\Comparison”的名为“andWhere”的未定义方法。 您好,很抱歉我的回答有误。 Query expr builder$query->expr()->eq
应该从 select 移到 andWhere 子句。
所以表单元素查询应该类似于:$qb = $this->getConfigurationPool()->getContainer()->get('doctrine') ->getRepository('ApplicationSonataUserBundle:UserPlaces')->createQueryBuilder('up'); $placesQuery = $qb ->select('DISTINCT up.name') ->leftJoin('up.places', 'places') ->where($qb->expr()->eq('up.user', ':user')) ->setParameter('user', $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser()) ->getQuery();
差不多了,但是...'你请求了一个不存在的服务“doctrine”。'以上是关于Sonata + Fos_user - 如何仅显示与用户相关的实体?的主要内容,如果未能解决你的问题,请参考以下文章
sonata_type_collection 字段仅适用于现有的父对象
Symfony 3 上的 Sonata Admin 实体翻译
如何过滤用户可以在 Sonata Admin 中看到的实体实例
当sonata_type_admin调用时如何在Sonata的Admin类中获取底层对象?