authorizationHelper = $authorizationHelper; $this->centerResolverDispatcher = $centerResolverDispatcher; $this->tokenStorage = $tokenStorage; $this->repository = $repository; $this->em = $em; $this->security = $security; } public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array { $user = $this->security->getUser(); $center = $this->centerResolverDispatcher->resolveCenter($period); if (0 === count($orderBy)) { $orderBy = ['date' => 'DESC']; } $scopes = $this->authorizationHelper ->getReachableCircles($user, $role, $center); return $this->em->getRepository(Activity::class) ->findByAccompanyingPeriod($period, $scopes, true, $limit, $start, $orderBy); } /** * @param array $orderBy * * @return Activity[]|array */ public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array { $user = $this->security->getUser(); $center = $this->centerResolverDispatcher->resolveCenter($person); if (0 === count($orderBy)) { $orderBy = ['date' => 'DESC']; } $reachableScopes = $this->authorizationHelper ->getReachableCircles($user, $role, $center); return $this->em->getRepository(Activity::class) ->findByPersonImplied($person, $reachableScopes, $orderBy, $limit, $start); } public function queryTimelineIndexer(string $context, array $args = []): array { $metadataActivity = $this->em->getClassMetadata(Activity::class); $from = $this->getFromClauseCenter($args); [$where, $parameters] = $this->getWhereClause($context, $args); return [ 'id' => $metadataActivity->getTableName() . '.' . $metadataActivity->getColumnName('id'), 'type' => 'activity', 'date' => $metadataActivity->getTableName() . '.' . $metadataActivity->getColumnName('date'), 'FROM' => $from, 'WHERE' => $where, 'parameters' => $parameters, ]; } private function getFromClauseCenter(array $args): string { $metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataPerson = $this->em->getClassMetadata(Person::class); $associationMapping = $metadataActivity->getAssociationMapping('person'); return $metadataActivity->getTableName() . ' JOIN ' . $metadataPerson->getTableName() . ' ON ' . $metadataPerson->getTableName() . '.' . $associationMapping['joinColumns'][0]['referencedColumnName'] . ' = ' . $associationMapping['joinColumns'][0]['name']; } private function getWhereClause(string $context, array $args): array { $where = ''; $parameters = []; $metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataPerson = $this->em->getClassMetadata(Person::class); $activityToPerson = $metadataActivity->getAssociationMapping('person')['joinColumns'][0]['name']; $activityToScope = $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name']; $personToCenter = $metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name']; // acls: $role = new Role(ActivityVoter::SEE); $reachableCenters = $this->authorizationHelper->getReachableCenters( $this->tokenStorage->getToken()->getUser(), $role ); if (count($reachableCenters) === 0) { // insert a dummy condition return 'FALSE = TRUE'; } if ('person' === $context) { // we start with activities having the person_id linked to person $where .= sprintf('%s = ? AND ', $activityToPerson); $parameters[] = $person->getId(); } // we add acl (reachable center and scopes) $where .= '('; // first loop for the for centers $centersI = 0; // like centers#i foreach ($reachableCenters as $center) { // we pass if not in centers if (!in_array($center, $args['centers'], true)) { continue; } // we get all the reachable scopes for this center $reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), $role, $center); // we get the ids for those scopes $reachablesScopesId = array_map( static function (Scope $scope) { return $scope->getId(); }, $reachableScopes ); // if not the first center if (0 < $centersI) { $where .= ') OR ('; } // condition for the center $where .= sprintf(' %s.%s = ? ', $metadataPerson->getTableName(), $personToCenter); $parameters[] = $center->getId(); // begin loop for scopes $where .= ' AND ('; $scopesI = 0; //like scope#i foreach ($reachablesScopesId as $scopeId) { if (0 < $scopesI) { $where .= ' OR '; } $where .= sprintf(' %s.%s = ? ', $metadataActivity->getTableName(), $activityToScope); $parameters[] = $scopeId; ++$scopesI; } // close loop for scopes $where .= ') '; ++$centersI; } // close loop for centers $where .= ')'; return [$where, $parameters]; } }