em->getClassMetadata(StoredObject::class); if (null !== $startDate) { $query->addWhereClause( sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), [$startDate], [Types::DATE_IMMUTABLE] ); } if (null !== $endDate) { $query->addWhereClause( sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), [$endDate], [Types::DATE_IMMUTABLE] ); } if (null !== $content) { $query->addWhereClause( sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), ['%' . $content . '%'], [Types::STRING] ); } return $query; } /** * @throws MappingException */ public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $calendarMetadata = $this->em->getClassMetadata(Calendar::class); $query = new FetchQuery( self::KEY, sprintf("jsonb_build_object('id', cd.%s)", $classMetadata->getColumnName('id')), 'cd.'.$storedObjectMetadata->getColumnName('createdAt'), $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' ); $query->addJoinClause( sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), $storedObjectMetadata->getColumnName('id'), $classMetadata->getSingleAssociationJoinColumnName('storedObject') )); $query->addJoinClause( sprintf('JOIN %s calendar ON calendar.%s = cd.%s', $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), $calendarMetadata->getColumnName('id'), $classMetadata->getSingleAssociationJoinColumnName('calendar') ) ); // get the documents associated with accompanying periods in which person participates $or = []; $orParams = []; $orTypes = []; foreach ($person->getAccompanyingPeriodParticipations() as $participation) { if (!$this->security->isGranted(CalendarVoter::SEE, $participation->getAccompanyingPeriod())) { continue; } $or[] = sprintf( '(calendar.%s = ? AND cd.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', $calendarMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), $storedObjectMetadata->getColumnName('createdAt') ); $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), DateTimeImmutable::createFromInterface($participation->getStartDate()), null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; } if ([] === $or) { $query->addWhereClause('TRUE = FALSE'); return $query; } // $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); } /** * @param Person $person * @return bool */ public function isAllowedForPerson(Person $person): bool { return $this->security->isGranted(CalendarVoter::SEE, $person); } }