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: 如果您使用奏鸣曲formMapperconfigureFormFields 方法,您可以在字段定义中传递自定义查询生成器。

$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-&gt;expr()-&gt;eq 应该从 select 移到 andWhere 子句。 所以表单元素查询应该类似于:$qb = $this-&gt;getConfigurationPool()-&gt;getContainer()-&gt;get('doctrine') -&gt;getRepository('ApplicationSonataUserBundle:UserPlaces')-&gt;createQueryBuilder('up'); $placesQuery = $qb -&gt;select('DISTINCT up.name') -&gt;leftJoin('up.places', 'places') -&gt;where($qb-&gt;expr()-&gt;eq('up.user', ':user')) -&gt;setParameter('user', $this-&gt;getConfigurationPool()-&gt;getContainer()-&gt;get('security.token_storage')-&gt;getToken()-&gt;getUser()) -&gt;getQuery(); 差不多了,但是...'你请求了一个不存在的服务“doctrine‌​”。'

以上是关于Sonata + Fos_user - 如何仅显示与用户相关的实体?的主要内容,如果未能解决你的问题,请参考以下文章

sonata_type_collection 字段仅适用于现有的父对象

Symfony 3 上的 Sonata Admin 实体翻译

如何过滤用户可以在 Sonata Admin 中看到的实体实例

当sonata_type_admin调用时如何在Sonata的Admin类中获取底层对象?

Sonata Admin Bundle:在列表视图中显示收藏总数

Sonata DateTimePickerType 类默认日期显示错误的日期时间格式