doctrine教程13---自动修改查询

Mario Sanchez

18 people read
Thumbnail

doctrine教程13---自动修改查询

如果我们已经完成了项目,但是甲方又增加了需求,难道我们每一个页面都去修改吗?为了演示更方便的方法,我们恢复一下首页的twig代码

我们新建一个DiscontinuedFilter的类,放在src/Doctrine中

<?php

namespace App\Doctrine;

use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\Filter\SQLFilter;

class DiscontinuedFilter extends SQLFilter
{

    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        dd($targetEntity, $targetTableAlias);
    }
}

这就是Doctrine过滤器,但是如果我们刷新页面,什么都没发生,因为激活过滤器需要两步:

首先修改config/packages/doctrine.yaml,我们需要告诉 Doctrine 过滤器存在。在 orm 键正下方的任意位置添加 filters ,然后添加 fortuneCookie_discontinued 。该字符串可以是任何东西......您很快就会看到我们如何使用它。将其设置为类: App\Doctrine\DiscontinuedFilter

        filters:
            fortuneCookie_discontinued: App\Doctrine\DiscontinuedFilter

现在它已经在 Doctrine 中注册了...但是正如你在这里看到的,它仍然没有被调用。第二步是在您想要的地方激活它。在某些情况下,您可能希望将此 DiscontinuedFilter 用于网站的一个部分

接下来我们修改一下控制器

public function index(Request $request, CategoryRepository $categoryRepository, EntityManagerInterface $entityManager): Response
    {
        $entityManager->getFilters()
            ->enable('fortuneCookie_discontinued');

刷新,成功加载了ClassMetadata是一个非常大的对象,而且表的别名也返回给我们了,因为过滤器是全局的,所以我们要加强判断:

public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        if ($targetEntity->getReflectionClass()->name !== FortuneCookie::class) {
            return '';
        }
        return sprintf('%s.discontinued = false', $targetTableAlias);
    }

刷新首页,完美的取得了想要的数据,现在的问题是过滤器不是服务,所以不能方便的传参数,比如要把discontinued条件从false改为true,我们稍微修改一下代码

public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        if ($targetEntity->getReflectionClass()->name !== FortuneCookie::class) {
            return '';
        }
        return sprintf('%s.discontinued = %s', $targetTableAlias,$this->getParameter('discontinued'));
    }

同时控制器也需要增加传值

public function index(Request $request, CategoryRepository $categoryRepository, EntityManagerInterface $entityManager): Response
    {
        $entityManager->getFilters()
            ->enable('fortuneCookie_discontinued')
        ->setParameter('discontinued', false);

现在可以很方便的传值给过滤器了,还有一个问题就是:这能叫全局吗?不能!但是我们可以再继续:

1、我们把控制器里的代码删除 2、修改doctrine.yaml

        filters:
            fortuneCookie_discontinued:
                class: App\Doctrine\DiscontinuedFilter
                enabled: true
                parameters:
                    discontinued: false

刷新:真全局了现在

About Me

我是一位精通 Symfony 框架和 API Platform 的开发者,擅长构建高效、可扩展的 Web 应用程序和 API。 此外,我还具备 PrestaShop 模块开发经验,能够为您的电商平台定制功能,满足特定业务需求。