*/ class AccessCodeRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, AccessCode::class); } /** * The code that opens each door today, for the quick-look list. * * Dated-ahead codes are left in the database and out of the query: a code that does not open * anything yet is not an answer to "what do I type", and showing it beside one that does is * how somebody ends up typing the wrong one. Ordered so that the first row per label is the * one in force -- the caller only has to take it. * * @param list $roles * * @return list */ public function findCurrentReadableBy(array $roles, \DateTimeImmutable $on): array { return $this->createQueryBuilder('c') ->andWhere('c.visibility IN (:visibilities)') ->andWhere('c.validFrom <= :on') ->setParameter('visibilities', CodeVisibility::readableBy($roles)) ->setParameter('on', $on) ->orderBy('c.label', 'ASC') ->addOrderBy('c.validFrom', 'DESC') ->addOrderBy('c.id', 'DESC') ->getQuery() ->getResult(); } /** * Everything the holder of these roles may read, grouped by door and newest code first. * * The restriction is applied here rather than in the template, so a code somebody may not * read is never loaded into a response in the first place -- a hidden table row is still a * published code. * * @param list $roles * * @return list */ public function findReadableBy(array $roles): array { return $this->createQueryBuilder('c') ->andWhere('c.visibility IN (:visibilities)') ->setParameter('visibilities', CodeVisibility::readableBy($roles)) ->orderBy('c.label', 'ASC') ->addOrderBy('c.validFrom', 'DESC') ->addOrderBy('c.id', 'DESC') ->getQuery() ->getResult(); } }