Source of file TICRepository.php

Size: 4,813 Bytes - Last Modified: 2023-11-16T22:56:02+01:00

/home/websites/teicee/packagist/site/phpdoc/conf/../vendor/teicee/dorm-bundle/src/Base/TICRepository.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
<?php
namespace TIC\DormBundle\Base;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;

/**
 * Repository de base disposant de nombreuses méthodes utiles.
 * @see https://symfony.com/doc/current/doctrine.html#doctrine-queries
 * 
 * @TODO ajouter des méthodes saveEntity et deleteEntity
 *       à défaut de charger l'ensemble du ManagerTrait
 *       (problématique car _em déjà présent et getRepo/getItem spécifiques)
 */
abstract class TICRepository extends ServiceEntityRepository
{

	// Initialisation automatique des propriétés à partir du nom de la classe du controlleur
#	use \TIC\CoreBundle\Traits\ContextProperties;
#	use \TIC\DormBundle\Traits\ManagerTrait;
	use \TIC\DormBundle\Traits\RepositoryFilterable;

	/**
	 * Construction du Repository en renseignant automatiquement l'entité associée.
	 */
	public function __construct(ManagerRegistry $registry)
	{
		$entityClass = \str_replace("\\Repository\\", "\\Entity\\", static::class);
		$entityClass = \preg_replace('/Repository$/', '', $entityClass);
		parent::__construct($registry, $entityClass);
	}

	/**
	 * Retourne une instance d'un autre Repository du projet.
	 *
	 * @param   string  $entity
	 * @return  EntityRepository
	 */
	protected function getRepo(string $entity): EntityRepository
	{
		$entitySpace = \preg_match('/^(.+\\\\Entity\\\\)/', $this->_entityName, $m) ? $m[1] : '';
		return $this->_em->getRepository($entitySpace . \ucfirst($entity));
	}

	/**
	 * Retourne une entité en fonction de sa clé primaire.
	 * Note: utilisé par la méthode getItem() des controlleurs (utile pour surcharge)
	 *
	 * @param   mixed   $id         Valeur de la clé primaire pour l'entité recherchée
	 * @return  Entity              Retourne l'entité correspondante (ou NULL sinon)
	 */
	public function getItem($id): ?object
	{
		return $this->find($id);
	}

	/**
	 * Recherche des valeurs existantes d'un champs (avec motif de filtrage cf typeahead).
	 *
	 * @param   string  $field      Nom du champs pour la récupération des valeurs
	 * @param   string  $term       Terme de recherche pour filtrage des résultats
	 * @param   integer $minOccurs  Nombre minimum d'occurence d'une valeur pour être proposée
	 * @return  array               Liste des différentes valeurs correspondantes
	 */
	public function getFieldValues(string $field, string $term = '', int $minOccurs = 0): array
	{
		$field = 'a.' . $field;
		if (! $minOccurs) $qb = $this->createQueryBuilder('a')
			->select('DISTINCT(' . $field . ')')
			->where($field . ' IS NOT NULL')->andWhere($field . ' != \'\'')
			->orderBy($field, 'ASC')
		;
		else $qb = $this->createQueryBuilder('a')
			->select($field)->groupBy($field)
			->where($field . ' IS NOT NULL')->andWhere($field . ' != \'\'')
			->having('COUNT(' . $field . ') >= :min')->setParameter('min', $minOccurs)
			->orderBy($field, 'ASC')
		;
		if ($term !== '') $qb
			->andWhere($field . ' LIKE :term')
			->setParameter('term', '%' . $term . '%')
		;
		return $qb->getQuery()->getResult('column');
	}

	/**
	 * Génération d'une chaine aléatoire et unique pour une colonne indiquée.
	 *
	 * @param   string  $field      Nom du champs à tester pour l'unicité
	 * @param   integer $length     Nombre de caractères à générer (longueur de la chaine)
	 * @param   string  $format     Motif sprintf (avec un %s) pour créer une valeur contenant la partie aléatoire
	 * @param   mixed   $sigils     Alphabet à utiliser (caractères autorisés dans la chaine)
	 *                              si Null  : ensemble alpha-numérique [a-zA-Z0-9]
	 *                              si True  : ASCII de base imprimable, sauf & < > $ ^ " ' ` \ |
	 *                              si False : alpha-numérique non ambigus [A-Z0-9], sauf 0 O 1 I
	 * @return  string              Chaine constituée de $length caractères aléatoires parmis $sigils
	 */
	public function genUniqueRandom(string $field, int $length = 8, string $format = null, mixed $sigils = null): string
	{
		// limite au nombre de valeurs générées et testées par sécurité
		$max_try = 1000;
		while (true) {
			// génération d'une chaine aléatoire formattée
			$str = \TIC\CoreBundle\Util\StringHelper::genrandom($length, $sigils);
			if (\is_string($format) && (\strpos($format, '%s') !== false)) $str = \sprintf($format, $str);
			
			// vérification de l'unicité dans la table
			$res = $this->createQueryBuilder('a')->select('COUNT(a)')
				->where('a.' . $field . ' = :str')->setParameter('str', $str)
				->getQuery()->getSingleScalarResult();
			if (! $res) break;
			if (--$max_try < 1) throw new \Exception("Can't generate unique random value for " . $field);
		}
		return $str;
	}

}