fix query in timeline in activity and person bundle

This commit is contained in:
Julien Fastré 2021-05-25 09:48:19 +02:00
parent 74541f360b
commit 9b1a66c992
6 changed files with 43 additions and 58 deletions

View File

@ -101,7 +101,7 @@ class TimelineActivityProvider implements TimelineProviderInterface
$metadataActivity = $this->em->getClassMetadata(Activity::class); $metadataActivity = $this->em->getClassMetadata(Activity::class);
[$where, $parameters] = $this->getWhereClauseForPerson($args['person']); [$where, $parameters] = $this->getWhereClauseForPerson($args['person']);
dump($where, $parameters);
return TimelineSingleQuery::fromArray([ return TimelineSingleQuery::fromArray([
'id' => $metadataActivity->getTableName() 'id' => $metadataActivity->getTableName()
.'.'.$metadataActivity->getColumnName('id'), .'.'.$metadataActivity->getColumnName('id'),
@ -119,49 +119,33 @@ class TimelineActivityProvider implements TimelineProviderInterface
$parameters = []; $parameters = [];
$metadataActivity = $this->em->getClassMetadata('ChillActivityBundle:Activity'); $metadataActivity = $this->em->getClassMetadata('ChillActivityBundle:Activity');
$associationMapping = $metadataActivity->getAssociationMapping('person'); $associationMapping = $metadataActivity->getAssociationMapping('person');
$metadataPerson = $this->em->getClassMetadata('ChillPersonBundle:Person');
$role = new Role('CHILL_ACTIVITY_SEE'); $role = new Role('CHILL_ACTIVITY_SEE');
$reachableCenters = $this->helper->getReachableCenters($this->user, $reachableScopes = $this->helper->getReachableScopes($this->user,
$role); $role, $person->getCenter());
$whereClause = sprintf(' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) ');
$scopes_ids = [];
if (count($reachableCenters) === 0) { // first parameter: activity.person_id
return 'FALSE = TRUE';
}
// we start with activities having the person_id linked to person
// (currently only context "person" is supported)
$whereClause = sprintf(' {activity.person_id} = ? ');
$parameters[] = $person->getId(); $parameters[] = $person->getId();
// we add acl (reachable center and scopes) // loop on reachable scopes
$centerAndScopeClauses = []; foreach ($reachableScopes as $scope) {
foreach ($reachableCenters as $center) { if (\in_array($scope->getId(), $scopes_ids)) {
$parameters[] = $center->getId(); continue;
$scopes_ids = [];
$reachableScopes = $this->helper->getReachableScopes($this->user, $role, $person->getCenter());
foreach ($reachableScopes as $scope) {
$scopes_ids[] = '?';
$parameters[] = $scope->getId();
} }
$centerAndScopeClauses[] = \strtr( $scopes_ids[] = '?';
'( {person.center_id} = ? AND {activity.scope_id} IN ({scopes_ids})) ', $parameters[] = $scope->getId();
[
'{scopes_ids}' => \implode(", ", $scopes_ids)
]
);
} }
$whereClause .= ' AND ('.\implode(' OR ', $centerAndScopeClauses).' ) ';
return [ return [
\strtr( \strtr(
$whereClause, $whereClause,
[ [
'{activity.person_id}' => $associationMapping['joinColumns'][0]['name'], '{activity.person_id}' => $associationMapping['joinColumns'][0]['name'],
'{person.center_id}' => $metadataPerson->getTableName().'.'.
$metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'],
'{activity.scope_id}' => $metadataActivity->getTableName().'.'. '{activity.scope_id}' => $metadataActivity->getTableName().'.'.
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'], $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
'{scopes_ids}' => \implode(", ", $scopes_ids)
,
] ]
), ),
$parameters $parameters

View File

@ -28,8 +28,6 @@ use Doctrine\ORM\NativeQuery;
/** /**
* Build timeline * Build timeline
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class TimelineBuilder implements ContainerAwareInterface class TimelineBuilder implements ContainerAwareInterface
{ {

View File

@ -38,12 +38,12 @@ class TimelineSingleQuery
public static function fromArray(array $a) public static function fromArray(array $a)
{ {
return new TimelineSingleQuery( return new TimelineSingleQuery(
$a['id'], $a['id'] ?? null,
$a['date'], $a['date'] ?? null,
$a['type'] ?? $a['key'], $a['type'] ?? $a['key'] ?? null,
$a['FROM'] ?? $a['from'], $a['FROM'] ?? $a['from'] ?? null,
$a['WHERE'] ?? $a['where'], $a['WHERE'] ?? $a['where'] ?? null,
$a['parameters']); $a['parameters'] ?? null);
} }
public function getId(): string public function getId(): string

View File

@ -28,6 +28,7 @@ use Chill\MainBundle\Entity\Center;
use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Timeline\TimelineSingleQuery;
/** /**
* Provide method to build timeline for accompanying periods * Provide method to build timeline for accompanying periods
@ -88,14 +89,16 @@ abstract class AbstractTimelineAccompanyingPeriod implements TimelineProviderInt
} }
$metadata = $this->em $metadata = $this->em
->getClassMetadata(AccompanyingPeriodParticipation::class) ->getClassMetadata(AccompanyingPeriod::class)
; ;
[$where, $parameters] = $this->buildWhereClause($context, $args);
return array( return TimelineSingleQuery::fromArray([
'id' => "{$metadata->getTableName()}.{$metadata->getColumnName('id')}", 'id' => "{$metadata->getTableName()}.{$metadata->getColumnName('id')}",
'FROM' => $this->buildFromClause($context), 'FROM' => $this->buildFromClause($context),
'WHERE' => $this->buildWhereClause($context, $args) 'WHERE' => $where,
); 'parameters' => $parameters
]);
} }
private function buildFromClause($context) private function buildFromClause($context)
@ -130,9 +133,9 @@ abstract class AbstractTimelineAccompanyingPeriod implements TimelineProviderInt
$join = $participation->getAssociationMapping('person')['joinColumns'][0]; $join = $participation->getAssociationMapping('person')['joinColumns'][0];
$person = $this->em->getClassMetadata(Person::class); $person = $this->em->getClassMetadata(Person::class);
$joinCenter = $person->getAssociationMapping('center')['joinColumns'][0]; $joinCenter = $person->getAssociationMapping('center')['joinColumns'][0];
$allowedCenters = $this->authorizationHelper->filterReachableCenters($this->security->getUser(), $args['centers'], PersonVoter::SEE);
if ($context === 'center') { if ($context === 'center') {
$allowedCenters = $this->authorizationHelper->filterReachableCenters($this->security->getUser(), $args['centers'], PersonVoter::SEE);
$params = []; $params = [];
$questionMarks = []; $questionMarks = [];
$query = "{$person->getTableName()}.{$joinCenter['name']} IN ("; $query = "{$person->getTableName()}.{$joinCenter['name']} IN (";

View File

@ -25,8 +25,6 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
/** /**
* Provide information for opening periods to timeline * Provide information for opening periods to timeline
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/ */
class TimelineAccompanyingPeriodClosing extends AbstractTimelineAccompanyingPeriod class TimelineAccompanyingPeriodClosing extends AbstractTimelineAccompanyingPeriod
{ {
@ -49,13 +47,15 @@ class TimelineAccompanyingPeriodClosing extends AbstractTimelineAccompanyingPeri
$metadata = $this->em $metadata = $this->em
->getClassMetadata(AccompanyingPeriod::class); ->getClassMetadata(AccompanyingPeriod::class);
$data = $this->basicFetchQuery($context, $args); $query = $this->basicFetchQuery($context, $args);
[$where, $parameters] = $this->buildWhereClause($context, $args);
$query->setKey('accompanying_period_closing')
->setDate($metadata->getColumnName('closingDate'))
->setWhere($where)
->setParameters($parameters)
;
$data['type'] = 'accompanying_period_closing'; return $query;
$data['date'] = $metadata->getColumnName('closingDate');
$data['WHERE'] = $this->buildWhereClause($context, $args);
return $data;
} }
protected function buildWhereClause($context, array $args): array protected function buildWhereClause($context, array $args): array

View File

@ -47,12 +47,12 @@ class TimelineAccompanyingPeriodOpening extends AbstractTimelineAccompanyingPeri
$metadata = $this->em $metadata = $this->em
->getClassMetadata(AccompanyingPeriod::class); ->getClassMetadata(AccompanyingPeriod::class);
$data = $this->basicFetchQuery($context, $args); $query = $this->basicFetchQuery($context, $args);
$data['type'] = 'accompanying_period_opening'; $query->setKey('accompanying_period_opening')
$data['date'] = $metadata->getColumnName('openingDate'); ->setDate($metadata->getColumnName('openingDate'));
return $data; return $query;
} }
/** /**