buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext($person, $startDate, $endDate, $content); return $this->addFetchQueryByPersonACL($query, $person); } public function buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( PersonActivityGenericDocProvider::KEY, sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) ); $query->addJoinClause( 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = stored_obj.id' ); $query->addJoinClause( 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' ); $query->addWhereClause( sprintf('activity.%s = ?', $activityMetadata->getSingleAssociationJoinColumnName('person')), [$person->getId()], [Types::INTEGER] ); return $this->addWhereClauses($query, $startDate, $endDate, $content); } public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( AccompanyingPeriodActivityGenericDocProvider::KEY, sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) ); $query->addJoinClause( 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = stored_obj.id' ); $query->addJoinClause( 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' ); // add documents of activities from parcours context $or = []; $orParams = []; $orTypes = []; foreach ($person->getAccompanyingPeriodParticipations() as $participation) { if (!$this->security->isGranted(ActivityVoter::SEE, $participation->getAccompanyingPeriod())) { continue; } $or[] = sprintf( '(activity.%s = ? AND stored_obj.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', $activityMetadata->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->addWhereClauses($query, $startDate, $endDate, $content); } private function addWhereClauses(FetchQuery $query, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); if (null !== $startDate) { $query->addWhereClause( sprintf('stored_obj.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), [$startDate], [Types::DATE_IMMUTABLE] ); } if (null !== $endDate) { $query->addWhereClause( sprintf('stored_obj.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), [$endDate], [Types::DATE_IMMUTABLE] ); } if (null !== $content and '' !== $content) { $query->addWhereClause( 'stored_obj.title ilike ?', ['%'.$content.'%'], [Types::STRING] ); } return $query; } private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery { $activityMetadata = $this->em->getClassMetadata(Activity::class); $reachableScopes = []; foreach ($this->centerResolverManager->resolveCenters($person) as $center) { $reachableScopes = [ ...$reachableScopes, ...$this->authorizationHelperForCurrentUser->getReachableScopes(ActivityVoter::SEE, $center), ]; } if ([] === $reachableScopes) { $fetchQuery->addWhereClause('FALSE = TRUE'); return $fetchQuery; } $fetchQuery->addWhereClause( sprintf( 'activity.%s IN (%s)', $activityMetadata->getSingleAssociationJoinColumnName('scope'), implode(', ', array_fill(0, count($reachableScopes), '?')) ), array_map(static fn (Scope $s) => $s->getId(), $reachableScopes), array_fill(0, count($reachableScopes), Types::INTEGER) ); return $fetchQuery; } }