教义覆盖所有实体的默认查找器方法

问题描述 投票:0回答:3

有一种方法可以覆盖所有实体存储库的默认查找器方法例如,这是Doctrine \ ORM \ EntityRepository中的默认方法findBy

 public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
    }    

但是我需要这样的东西

 public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
        $criteria['foo'] = 'bar';
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
    }   

我想通过修改条件数组并在需要时添加一些自定义条件属性来创建服务以覆盖此方法。我知道我可以覆盖每个实体的存储库,但是我的项目已经扩大了,现在我想要一个实用的解决方案以避免在所有实体存储库中进行更改。

symfony doctrine-orm doctrine
3个回答
1
投票

您可以创建一个扩展ServiceEntityRepository的类,并在该类中定义您要覆盖的所有类。最后,您将需要更新所有存储库以扩展此新类,而不是ServiceEntityRepository。


1
投票

您不应该这样。拥抱Doctrine Filters。使用一个,您可以在所有查询中全局引入任何一种逻辑。


0
投票

请参阅@emix的答案,这是更详细的解决方案

现在让我们创建注释。这将添加到该类中,该类将指示将由该准则过滤的字段。

/**
 * @Annotation
 * @Target("CLASS")
 */
final class CenterSelector
{
    public $centerFieldName;
}

并在课堂上使用它

 /**
 * @CenterSelector(centerFieldName="you-name-field")
 */
class CommercialPiece{
   protected $you-name-field;
}

创建从SQLFilter扩展的Filter类

class CenterFilter extends SQLFilter
{
    protected $reader;

    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {

        if (empty($this->reader)) {
            return '';
        }

        // The Doctrine filter is called for any query on any entity
        // Check if the current entity is (marked with an annotation)
        $centerSelector = $this->reader->getClassAnnotation(
            $targetEntity->getReflectionClass(),
            CenterSelector::class
        );

        if (!$centerSelector) {
            return '';
        }

        // FieldName parameter in annotation
        $fieldName = $centerSelector->centerFieldName;

        try {
            $mySelector= $this->getParameter('my-selector');
        } catch (\InvalidArgumentException $e) {
            // No my-selector has been defined
            return '';
        }

        if (empty($fieldName) || empty($mySelector)) {
            return '';
        } else{
            var_dump($mySelector);
            // Add the Where clause in the request
            $query = sprintf('%s.%s = %s', $targetTableAlias, $fieldName, $mySelector);
        }

        return $query;
    }

    public function setAnnotationReader(Reader $reader)
    {
        $this->reader = $reader;
    }
}

并且我在onKernelRequest上创建了一个侦听器

  public function __construct(
        ObjectManager $em, 
        SessionInterface $session, 
        Reader $reader)
    {
        $this->em = $em;
        $this->session = $session;
        $this->reader = $reader;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $globalSelector = $this->session->get('my-global-selector');           
        $filter = $this->em->getFilters()->enable('center_filter');
        $filter->setParameter('my-selector', $globalSelector );
        $filter->setAnnotationReader($this->reader);
    }

最后不要忘了在config.yml中添加它

orm:
    entity_managers:
        default:
            auto_mapping: true
            filters:
                center_filter:
                    class: your-name-space\Filter\CenterFilter
                    enabled: true
© www.soinside.com 2019 - 2024. All rights reserved.