WIP: fix loading of activity document

This commit is contained in:
2023-06-12 17:58:27 +02:00
parent 68c850026b
commit 727e9d0f74
6 changed files with 209 additions and 85 deletions

View File

@@ -23,16 +23,18 @@ use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface;
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
use DateTimeImmutable;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpKernel\HttpCache\Store;
use Symfony\Component\Security\Core\Security;
class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface
final readonly class ActivityDocumentACLAwareRepository implements ActivityDocumentACLAwareRepositoryInterface
{
public function __construct(
private EntityManagerInterface $em,
@@ -42,26 +44,43 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware
{
}
public function buildQueryByPerson(Person $person): QueryBuilder
public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface
{
$qb = $this->em->getRepository(PersonDocument::class)->createQueryBuilder('d');
$qb
->where($qb->expr()->eq('d.person', ':person'))
->setParameter('person', $person);
return $qb;
}
public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface
{
$query = $this->buildBaseFetchQueryForPerson($person, $startDate, $endDate, $content);
$query = $this->buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext($person, $startDate, $endDate, $content);
return $this->addFetchQueryByPersonACL($query, $person);
}
public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery
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(
PersonDocumentGenericDocProvider::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);
@@ -109,11 +128,12 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware
$query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes);
/* $query->addWhereClause(
'activity.person_id = ?',
[$person->getId()],
[Types::INTEGER]
);*/
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(
@@ -131,7 +151,7 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware
);
}
if (null !== $content) {
if (null !== $content or '' !== $content) {
$query->addWhereClause(
'stored_obj.title ilike ?',
['%' . $content . '%'],
@@ -142,55 +162,6 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware
return $query;
}
public function countByPerson(Person $person): int
{
$qb = $this->buildQueryByPerson($person)->select('COUNT(d)');
$this->addACL($qb, $person);
return $qb->getQuery()->getSingleScalarResult();
}
public function findByPerson(Person $person, array $orderBy = [], int $limit = 20, int $offset = 0): array
{
$qb = $this->buildQueryByPerson($person)->select('d');
$this->addACL($qb, $person);
foreach ($orderBy as $field => $order) {
$qb->addOrderBy('d.' . $field, $order);
}
$qb->setFirstResult($offset)->setMaxResults($limit);
return $qb->getQuery()->getResult();
}
private function addACL(QueryBuilder $qb, Person $person): void
{
$reachableScopes = [];
foreach ($this->centerResolverManager->resolveCenters($person) as $center) {
$reachableScopes = [
...$reachableScopes,
...$this->authorizationHelperForCurrentUser
->getReachableScopes(
ActivityVoter::SEE,
$center
)
];
}
if ([] === $reachableScopes) {
$qb->andWhere("'FALSE' = 'TRUE'");
return;
}
$qb->andWhere($qb->expr()->in('d.scope', ':scopes'))
->setParameter('scopes', $reachableScopes);
}
private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery
{
$activityMetadata = $this->em->getClassMetadata(Activity::class);

View File

@@ -0,0 +1,28 @@
<?php
namespace Chill\ActivityBundle\Repository;
use Chill\DocStoreBundle\GenericDoc\FetchQuery;
use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface;
use Chill\PersonBundle\Entity\Person;
use DateTimeImmutable;
/**
* Gives queries usable for fetching documents, with ACL aware
*/
interface ActivityDocumentACLAwareRepositoryInterface
{
/**
* Return a fetch query for querying document's activities for a person
*
* This method must check the rights to see a document: the user must be allowed to see the given activities
*/
public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface;
/**
* Return a fetch query for querying document's activities for an activity in accompanying periods, but for a given person
*
* This method must check the rights to see a document: the user must be allowed to see the given accompanying periods
*/
public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery;
}

View File

@@ -15,7 +15,6 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr;
use Doctrine\Persistence\ManagerRegistry;
/**