> */ private $whereBuilderMap = []; public function __construct( EntityManager $entityManager, SelectBuilderFactory $selectBuilderFactory, WhereBuilderFactory $whereBuilderFactory ) { $this->entityManager = $entityManager; $this->selectBuilderFactory = $selectBuilderFactory; $this->whereBuilderFactory = $whereBuilderFactory; } /** * Check whether an entity has a duplicate. */ public function check(Entity $entity): bool { $where = $this->getWhere($entity); if (!$where) { return false; } return $this->checkByWhere($entity, $where); } /** * Find entity duplicates. * * @return ?Collection */ public function find(Entity $entity): ?Collection { $where = $this->getWhere($entity); if (!$where) { return null; } return $this->findByWhere($entity, $where); } /** * The method is public for backward compatibility. */ public function checkByWhere(Entity $entity, WhereItem $where): bool { $entityType = $entity->getEntityType(); if ($entity->hasId()) { $where = Cond::and( $where, Cond::notEqual( Cond::column('id'), $entity->getId() ) ); } $duplicate = $this->entityManager ->getRDBRepository($entityType) ->where($where) ->select('id') ->findOne(); return (bool) $duplicate; } /** * The method is public for backward compatibility. * * @return ?Collection */ public function findByWhere(Entity $entity, WhereItem $where): ?Collection { $entityType = $entity->getEntityType(); if ($entity->hasId()) { $where = Cond::and( $where, Cond::notEqual( Cond::column('id'), $entity->getId() ) ); } $query = $this->selectBuilderFactory ->create() ->from($entityType) ->withStrictAccessControl() ->buildQueryBuilder() ->where($where) ->select($this->getSelect($entity)) ->limit(0, self::LIMIT) ->build(); $builder = $this->entityManager ->getRDBRepository($entityType) ->clone($query); if (!$builder->findOne()) { return null; } return $builder->find(); } /** * @return string[] */ private function getSelect(Entity $entity): array { $select = $this->selectAttributeList; foreach ($select as $item) { if (!$entity->hasAttribute($item)) { unset($select[$item]); } } return array_values($select); } private function getWhere(Entity $entity): ?WhereItem { $entityType = $entity->getEntityType(); if (!array_key_exists($entityType, $this->whereBuilderMap)) { $this->whereBuilderMap[$entityType] = $this->loadWhereBuilder($entityType); } $builder = $this->whereBuilderMap[$entityType]; if (!$builder) { return null; } return $builder->build($entity); } /** * @return ?WhereBuilder */ private function loadWhereBuilder(string $entityType): ?WhereBuilder { if (!$this->whereBuilderFactory->has($entityType)) { return null; } return $this->whereBuilderFactory->create($entityType); } }