2021-03-18 13:37:13 +01:00

146 lines
4.5 KiB
PHP

<?php
namespace Chill\ThirdPartyBundle\Repository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Query;
/**
* ThirdPartyRepository
*
*/
class ThirdPartyRepository extends \Doctrine\ORM\EntityRepository
{
/**
* count amongst parties associated to $centers, with $terms parameters
*
* @param array $centers
* @param type $terms
* @return int
*/
public function countByMemberOfCenters(array $centers, $terms = []): int
{
$qb = $this->buildQuery($centers, $terms);
$qb->select('COUNT(tp)');
return $qb->getQuery()->getSingleScalarResult();
}
/**
* Search amongst parties associated to $centers, with $terms parameters
*
* Different format for return:
* - ['entity']: return the entity hydrated as objects
* - ['array', [ DQL ]: return objects hydrated as entity, with
* an array describing the fields as DQL.
*
* supported terms:
*
* - name or _default: containing the name (name LIKE %string%)
* - is_active: is active = true / false
* - types: an array of types
*
* @param array $centers
* @param int $firstResult
* @param int $maxResults
* @param array $terms
* @param string[] $returnFormat a format for returning
* @return array
*/
public function findByMemberOfCenters(array $centers, $firstResult = 0, $maxResults = 20, $terms = [], $returnFormat = ['entity']): array
{
$qb = $this->buildQuery($centers, $terms);
switch($returnFormat[0]) {
case 'entity':
$qb->select('tp');
$hydrate = Query::HYDRATE_OBJECT;
break;
case 'array':
$hydrate = Query::HYDRATE_ARRAY;
$first = true;
foreach ($returnFormat[1] as $dql) {
if ($first) {
$qb->select($dql);
$first = false;
} else {
$qb->addSelect($dql);
}
}
break;
default:
throw new \DomainException("This return format is invalid");
}
$qb->setFirstResult($firstResult)
->setMaxResults($maxResults);
return $qb->getQuery()->getResult();
}
protected function createMemberOfCentersQuery($centers): QueryBuilder
{
$qb = $this->createQueryBuilder('tp');
$or = $qb->expr()->orX();
foreach ($centers as $center) {
$or->add($qb->expr()->isMemberOf(':center_'.$center->getId(), 'tp.centers'));
$qb->setParameter('center_'.$center->getId(), $center);
}
$qb->where($or);
return $qb;
}
protected function buildQuery($centers, $terms): QueryBuilder
{
$qb = $this->createMemberOfCentersQuery($centers);
$this->setNameCondition($qb, $terms);
$this->setTypesCondition($qb, $terms);
$this->setIsActiveCondition($qb, $terms);
return $qb;
}
/**
* Add parameters to filter by containing $terms["name"] or
* $terms["_default"]
*
* @param QueryBuilder $qb
* @param array $terms
*/
protected function setNameCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('name', $terms) || \array_key_exists('_default', $terms)) {
$term = $terms['name'] ?? $terms['_default'];
if (empty($term)) {
return;
}
$qb->andWhere($qb->expr()->like('UNACCENT(LOWER(tp.name))', 'UNACCENT(LOWER(:name))'));
$qb->setParameter('name', '%'.$term.'%');
}
}
protected function setTypesCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('types', $terms)) {
$orx = $qb->expr()->orX();
foreach ($terms['types'] as $type) {
$orx->add('JSONB_EXISTS_IN_ARRAY(tp.type, :type_'.$type.') = \'TRUE\'');
$qb->setParameter('type_'.$type, $type);
}
$qb->andWhere($orx);
}
}
protected function setIsActiveCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('is_active', $terms)) {
$qb->andWhere(
$terms['is_active'] ? $qb->expr()->eq('tp.active', "'TRUE'") :
$qb->expr()->eq('tp.active', "'FALSE'")
);
}
}
}