<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ResourceBundle\Doctrine\ORM;
use Doctrine\ORM\EntityRepository as BaseEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Doctrine\ORM\QueryAdapter;
use Pagerfanta\Pagerfanta;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
/** @psalm-suppress DeprecatedInterface */
class EntityRepository extends BaseEntityRepository implements RepositoryInterface
{
public function add(ResourceInterface $resource): void
{
$this->_em->persist($resource);
$this->_em->flush();
}
public function remove(ResourceInterface $resource): void
{
if (null !== $this->find($resource->getId())) {
$this->_em->remove($resource);
$this->_em->flush();
}
}
public function createPaginator(array $criteria = [], array $sorting = []): iterable
{
$queryBuilder = $this->createQueryBuilder('o');
$this->applyCriteria($queryBuilder, $criteria);
$this->applySorting($queryBuilder, $sorting);
return $this->getPaginator($queryBuilder);
}
protected function getPaginator(QueryBuilder $queryBuilder): Pagerfanta
{
// Use output walkers option in the query adapter should be false as it affects performance greatly (see sylius/sylius#3775)
return new Pagerfanta(new QueryAdapter($queryBuilder, false, false));
}
/**
* @param array $objects
*/
protected function getArrayPaginator($objects): Pagerfanta
{
return new Pagerfanta(new ArrayAdapter($objects));
}
protected function applyCriteria(QueryBuilder $queryBuilder, array $criteria = []): void
{
foreach ($criteria as $property => $value) {
if (!in_array($property, array_merge($this->_class->getAssociationNames(), $this->_class->getFieldNames()), true)) {
continue;
}
$name = $this->getPropertyName($property);
if (null === $value) {
$queryBuilder->andWhere($queryBuilder->expr()->isNull($name));
} elseif (is_array($value)) {
$queryBuilder->andWhere($queryBuilder->expr()->in($name, $value));
} elseif ('' !== $value) {
$parameter = str_replace('.', '_', $property);
$queryBuilder
->andWhere($queryBuilder->expr()->eq($name, ':' . $parameter))
->setParameter($parameter, $value)
;
}
}
}
protected function applySorting(QueryBuilder $queryBuilder, array $sorting = []): void
{
foreach ($sorting as $property => $order) {
if (!in_array($property, array_merge($this->_class->getAssociationNames(), $this->_class->getFieldNames()), true)) {
continue;
}
if (!empty($order)) {
$queryBuilder->addOrderBy($this->getPropertyName($property), $order);
}
}
}
protected function getPropertyName(string $name): string
{
if (false === strpos($name, '.')) {
return 'o' . '.' . $name;
}
return $name;
}
}