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
刷新:真全局了现在