diff --git a/src/Entity/Domain.php b/src/Entity/Domain.php index deb34af..192cfd9 100644 --- a/src/Entity/Domain.php +++ b/src/Entity/Domain.php @@ -44,7 +44,14 @@ use Symfony\Component\Serializer\Attribute\SerializedName; ], provider: FindDomainCollectionFromEntityProvider::class, parameters: [ - 'registrant' => new QueryParameter(description: 'The exact name of the registrant (case insensitive)', required: true), + 'registrant' => new QueryParameter( + description: 'The exact name of the registrant contact (case insensitive)', + required: false + ), + 'administrative' => new QueryParameter( + description: 'The exact name of the administrative contact (case insensitive)', + required: false + ), ] ), new Get( diff --git a/src/State/FindDomainCollectionFromEntityProvider.php b/src/State/FindDomainCollectionFromEntityProvider.php index ee53fd1..2a55342 100644 --- a/src/State/FindDomainCollectionFromEntityProvider.php +++ b/src/State/FindDomainCollectionFromEntityProvider.php @@ -22,6 +22,11 @@ readonly class FindDomainCollectionFromEntityProvider implements ProviderInterfa { $request = $this->requestStack->getCurrentRequest(); $registrant = trim((string) $request->get('registrant')); + $administrative = trim((string) $request->get('administrative')); + + if ('' === $registrant && '' === $administrative) { + throw new BadRequestHttpException('Either "registrant" or "administrative" must be provided'); + } $forbidden = [ 'redacted', @@ -34,23 +39,59 @@ readonly class FindDomainCollectionFromEntityProvider implements ProviderInterfa ]; foreach ($forbidden as $word) { - if (str_contains(strtolower($registrant), $word)) { + if (str_contains(strtolower($registrant.' '.$administrative), $word)) { throw new BadRequestHttpException('Forbidden search term'); } } - return $this->domainRepository->createQueryBuilder('d') + $qb = $this->domainRepository->createQueryBuilder('d') ->select('DISTINCT d') - ->join('d.domainEntities', 'de', Join::WITH, 'de.deletedAt IS NULL AND JSONB_CONTAINS(de.roles, :role) = true') - ->join( - 'de.entity', - 'e', - Join::WITH, - 'e.tld IS NOT NULL AND e.handle NOT IN (:blacklist) AND (e.jCardOrg = UPPER(:registrant) OR e.jCardFn = UPPER(:registrant))' - ) - ->setParameter('registrant', $registrant) - ->setParameter('blacklist', RDAPService::ENTITY_HANDLE_BLACKLIST) - ->setParameter('role', '"registrant"') - ->getQuery()->getResult(); + ->setParameter('blacklist', RDAPService::ENTITY_HANDLE_BLACKLIST); + + $orX = $qb->expr()->orX(); + + if ($registrant) { + $qb + ->leftJoin( + 'd.domainEntities', + 'der', + Join::WITH, + 'der.deletedAt IS NULL AND JSONB_CONTAINS(der.roles, \'"registrant"\') = true' + ) + ->leftJoin( + 'der.entity', + 'er', + Join::WITH, + 'er.handle NOT IN (:blacklist) AND (er.jCardOrg = UPPER(:registrant) OR er.jCardFn = UPPER(:registrant))' + ) + ->setParameter('registrant', $registrant); + + $orX->add('er.id IS NOT NULL'); + } + + if ($administrative) { + $qb + ->leftJoin( + 'd.domainEntities', + 'dea', + Join::WITH, + 'dea.deletedAt IS NULL AND JSONB_CONTAINS(dea.roles, \'"administrative"\') = true' + ) + ->leftJoin( + 'dea.entity', + 'ea', + Join::WITH, + 'ea.handle NOT IN (:blacklist) AND (ea.jCardOrg = UPPER(:administrative) OR ea.jCardFn = UPPER(:administrative))' + ) + ->setParameter('administrative', $administrative); + + $orX->add('ea.id IS NOT NULL'); + } + + if ($orX->count() > 0) { + $qb->andWhere($orX); + } + + return $qb->getQuery()->getResult(); } }