getToken()->getUser() instanceof User) { throw new RuntimeException('A user should be authenticated !'); } $this->user = $storage->getToken()->getUser(); } public function fetchQuery($context, array $args) { if ('center' === $context) { return TimelineSingleQuery::fromArray($this->aclAwareRepository ->queryTimelineIndexer($context, $args)); } $metadataActivity = $this->em->getClassMetadata(Activity::class); [$where, $parameters] = $this->getWhereClauseForPerson($args['person']); return TimelineSingleQuery::fromArray([ 'id' => $metadataActivity->getTableName() . '.' . $metadataActivity->getColumnName('id'), 'type' => 'activity', 'date' => $metadataActivity->getTableName() . '.' . $metadataActivity->getColumnName('date'), 'FROM' => $this->getFromClausePerson(), 'WHERE' => $where, 'parameters' => $parameters, ]); } public function getEntities(array $ids): array { $activities = $this->em->getRepository(Activity::class) ->findBy(['id' => $ids]); $result = []; foreach ($activities as $activity) { $result[$activity->getId()] = $activity; } return $result; } public function getEntityTemplate($entity, $context, array $args): array { $this->checkContext($context); return [ 'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig', 'template_data' => [ 'activity' => $entity, 'context' => $context, ], ]; } public function supportsType($type): bool { return 'activity' === $type; } /** * Check if the context is supported. * * @throws LogicException if the context is not supported */ private function checkContext(string $context) { if (false === in_array($context, self::SUPPORTED_CONTEXTS, true)) { throw new LogicException( sprintf( "The context '%s' is not supported. Currently only 'person' is supported", $context ) ); } } private function getFromClausePerson(): string { $metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataPerson = $this->em->getClassMetadata(Person::class); $associationMapping = $metadataActivity->getAssociationMapping('person'); return sprintf( '%s JOIN %s ON %s.%s = %s', $metadataActivity->getTableName(), $metadataPerson->getTableName(), $metadataPerson->getTableName(), $associationMapping['joinColumns'][0]['referencedColumnName'], $associationMapping['joinColumns'][0]['name'] ); } private function getWhereClauseForPerson(Person $person) { $parameters = []; $metadataActivity = $this->em->getClassMetadata(Activity::class); $associationMapping = $metadataActivity->getAssociationMapping('person'); $role = new Role('CHILL_ACTIVITY_SEE'); $reachableScopes = $this->helper->getReachableScopes($this->user, $role->getRole(), $person->getCenter()); $whereClause = ' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) '; $scopes_ids = []; // first parameter: activity.person_id $parameters[] = $person->getId(); // loop on reachable scopes foreach ($reachableScopes as $scope) { /** @phpstan-ignore-next-line */ if (in_array($scope->getId(), $scopes_ids, true)) { continue; } $scopes_ids[] = '?'; $parameters[] = $scope->getId(); } return [ strtr( $whereClause, [ '{activity.person_id}' => $associationMapping['joinColumns'][0]['name'], '{activity.scope_id}' => $metadataActivity->getTableName() . '.' . $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'], '{scopes_ids}' => implode(', ', $scopes_ids), ] ), $parameters, ]; } }