accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id'])?->getObject(); } public function supportsGenericDoc(GenericDocDTO $genericDocDTO): bool { return $this->supportsKeyAndIdentifiers($genericDocDTO->key, $genericDocDTO->identifiers); } public function supportsKeyAndIdentifiers(string $key, array $identifiers): bool { return self::KEY === $key; } public function buildOneGenericDoc(string $key, array $identifiers): ?GenericDocDTO { if (null === $accompanyingCourseDocument = $this->accompanyingCourseDocumentRepository->find($identifiers['id'])) { return null; } return new GenericDocDTO( self::KEY, $identifiers, \DateTimeImmutable::createFromInterface($accompanyingCourseDocument->getDate()), $accompanyingCourseDocument->getCourse(), ); } public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); $query = new FetchQuery( self::KEY, sprintf('jsonb_build_object(\'id\', acc_course_document.%s)', $classMetadata->getIdentifierColumnNames()[0]), $classMetadata->getColumnName('date'), $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS acc_course_document' ); $query->addWhereClause( sprintf('%s = ?', $classMetadata->getSingleAssociationJoinColumnName('course')), [$accompanyingPeriod->getId()], [Types::INTEGER] ); return $this->addWhereClause($query, $startDate, $endDate, $content); } public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool { return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); } public function buildFetchQueryForPerson(Person $person, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); $query = new FetchQuery( self::KEY, sprintf('jsonb_build_object(\'id\', acc_course_document.%s)', $classMetadata->getIdentifierColumnNames()[0]), $classMetadata->getColumnName('date'), $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS acc_course_document' ); $atLeastOne = false; $or = []; $orParams = []; $orTypes = []; foreach ($person->getAccompanyingPeriodParticipations() as $participation) { if (!$this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $participation->getAccompanyingPeriod())) { continue; } $atLeastOne = true; $or[] = sprintf( "(acc_course_document.%s = ? AND acc_course_document.%s BETWEEN ? AND COALESCE(?, 'infinity'::date))", $classMetadata->getSingleAssociationJoinColumnName('course'), $classMetadata->getColumnName('date') ); $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), $participation->getStartDate(), $participation->getEndDate()]; $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_MUTABLE, Types::DATE_MUTABLE]; } if (!$atLeastOne) { // there aren't any period allowed to be seen. Add an unreachable condition $query->addWhereClause('TRUE = FALSE'); return $query; } $query->addWhereClause('('.implode(' OR ', $or).')', $orParams, $orTypes); return $this->addWhereClause($query, $startDate, $endDate, $content); } public function isAllowedForPerson(Person $person): bool { return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); } private function addWhereClause(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery { $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); if (null !== $startDate) { $query->addWhereClause( sprintf('? <= %s', $classMetadata->getColumnName('date')), [$startDate], [Types::DATE_IMMUTABLE] ); } if (null !== $endDate) { $query->addWhereClause( sprintf('? >= %s', $classMetadata->getColumnName('date')), [$endDate], [Types::DATE_IMMUTABLE] ); } if (null !== $content and '' !== $content) { // add join clause to stored_object table $query->addJoinClause( sprintf( 'JOIN %s AS doc_store ON doc_store.%s = acc_course_document.%s', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), $storedObjectMetadata->getSingleIdentifierColumnName(), $classMetadata->getSingleAssociationJoinColumnName('object') ) ); $query->addWhereClause( sprintf( '(doc_store.%s ilike ? OR acc_course_document.%s ilike ?)', $classMetadata->getColumnName('title'), $classMetadata->getColumnName('description') ), ['%'.$content.'%', '%'.$content.'%'], [Types::STRING, Types::STRING] ); } return $query; } }