From d1bdf41c4c011d197d1c2190fa6eaf3093611845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 15 Mar 2023 13:36:41 +0100 Subject: [PATCH 01/11] Feature: Force language when converting documents --- src/Bundle/ChillWopiBundle/src/Controller/Convert.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Bundle/ChillWopiBundle/src/Controller/Convert.php b/src/Bundle/ChillWopiBundle/src/Controller/Convert.php index 0a4dc8762..aced2d0c5 100644 --- a/src/Bundle/ChillWopiBundle/src/Controller/Convert.php +++ b/src/Bundle/ChillWopiBundle/src/Controller/Convert.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Entity\User; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Mime\Part\DataPart; @@ -40,6 +41,8 @@ class Convert private LoggerInterface $logger; + private RequestStack $requestStack; + private Security $security; private StoredObjectManagerInterface $storedObjectManager; @@ -49,12 +52,14 @@ class Convert */ public function __construct( HttpClientInterface $httpClient, + RequestStack $requestStack, Security $security, StoredObjectManagerInterface $storedObjectManager, LoggerInterface $logger, ParameterBagInterface $parameters ) { $this->httpClient = $httpClient; + $this->requestStack = $requestStack; $this->security = $security; $this->storedObjectManager = $storedObjectManager; $this->logger = $logger; @@ -68,6 +73,10 @@ class Convert } $content = $this->storedObjectManager->read($storedObject); + $query = []; + if (null !== $request = $this->requestStack->getCurrentRequest()) { + $query['lang'] = $request->getLocale(); + } try { $url = sprintf('%s/cool/convert-to/pdf', $this->collaboraDomain); @@ -76,6 +85,7 @@ class Convert ]); $response = $this->httpClient->request('POST', $url, [ 'headers' => $form->getPreparedHeaders()->toArray(), + 'query' => $query, 'body' => $form->bodyToString(), 'timeout' => 10, ]); From 44ecad2bca2d755f832d939cc61ac01e24cc127f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 15 Mar 2023 13:38:19 +0100 Subject: [PATCH 02/11] Fixed: re-introduce creator in async doc generation --- .../Service/DocGenerator/ActivityContext.php | 2 +- .../Service/DocGenerator/CalendarContext.php | 2 +- .../DocGenerator/CalendarContextTest.php | 2 +- .../Service/Context/BaseContextData.php | 8 ++---- .../Service/Generator/Generator.php | 5 +++- .../Service/Generator/GeneratorInterface.php | 4 ++- .../Messenger/RequestGenerationHandler.php | 27 +++++++++++++++++-- .../Messenger/RequestGenerationMessage.php | 8 ++++++ .../AccompanyingPeriodContext.php | 2 +- .../Service/DocGenerator/PersonContext.php | 2 +- 10 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php index ac832b34b..3df0d886d 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php @@ -152,7 +152,7 @@ class ActivityContext implements $options = $template->getOptions(); $data = []; - $data = array_merge($data, $this->baseContextData->getData()); + $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null)); $data['activity'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => Activity::class, 'groups' => 'docgen:read']); $data['course'] = $this->normalizer->normalize($entity->getAccompanyingPeriod(), 'docgen', ['docgen:expects' => AccompanyingPeriod::class, 'groups' => 'docgen:read']); diff --git a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php index 6eadaf997..cba7fc661 100644 --- a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php +++ b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php @@ -156,7 +156,7 @@ final class CalendarContext implements CalendarContextInterface $options = $this->getOptions($template); $data = array_merge( - $this->baseContextData->getData(), + $this->baseContextData->getData($contextGenerationData['creator'] ?? null), [ 'calendar' => $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => Calendar::class, 'groups' => ['docgen:read']]), ] diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php index be31485d4..cbb4ea3af 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php @@ -205,7 +205,7 @@ final class CalendarContextTest extends TestCase ?NormalizerInterface $normalizer = null ): CalendarContext { $baseContext = $this->prophesize(BaseContextData::class); - $baseContext->getData()->willReturn(['base_context' => 'data']); + $baseContext->getData(null)->willReturn(['base_context' => 'data']); $personRender = $this->prophesize(PersonRender::class); $personRender->renderString(Argument::type(Person::class), [])->willReturn('person name'); diff --git a/src/Bundle/ChillDocGeneratorBundle/Service/Context/BaseContextData.php b/src/Bundle/ChillDocGeneratorBundle/Service/Context/BaseContextData.php index e7b56ed88..5aed8554b 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Service/Context/BaseContextData.php +++ b/src/Bundle/ChillDocGeneratorBundle/Service/Context/BaseContextData.php @@ -21,18 +21,14 @@ class BaseContextData { private NormalizerInterface $normalizer; - private Security $security; - - public function __construct(Security $security, NormalizerInterface $normalizer) + public function __construct(NormalizerInterface $normalizer) { - $this->security = $security; $this->normalizer = $normalizer; } - public function getData(): array + public function getData(?User $user = null): array { $data = []; - $user = $this->security->getUser(); $data['creator'] = $this->normalizer->normalize( $user instanceof User ? $user : null, diff --git a/src/Bundle/ChillDocGeneratorBundle/Service/Generator/Generator.php b/src/Bundle/ChillDocGeneratorBundle/Service/Generator/Generator.php index 0775cfb49..4ddcb461c 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Service/Generator/Generator.php +++ b/src/Bundle/ChillDocGeneratorBundle/Service/Generator/Generator.php @@ -9,6 +9,7 @@ use Chill\DocGeneratorBundle\GeneratorDriver\DriverInterface; use Chill\DocGeneratorBundle\GeneratorDriver\Exception\TemplateException; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Service\StoredObjectManagerInterface; +use Chill\MainBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\File\File; @@ -55,7 +56,8 @@ class Generator implements GeneratorInterface array $contextGenerationDataNormalized, ?StoredObject $destinationStoredObject = null, bool $isTest = false, - ?File $testFile = null + ?File $testFile = null, + ?User $creator = null ): ?string { if ($destinationStoredObject instanceof StoredObject && StoredObject::STATUS_PENDING !== $destinationStoredObject->getStatus()) { $this->logger->info(self::LOG_PREFIX.'Aborting generation of an already generated document'); @@ -80,6 +82,7 @@ class Generator implements GeneratorInterface $contextGenerationDataNormalized = array_merge( $contextGenerationDataNormalized, + ['creator' => $creator], $context instanceof DocGeneratorContextWithPublicFormInterface ? $context->contextGenerationDataDenormalize($template, $entity, $contextGenerationDataNormalized) : [] diff --git a/src/Bundle/ChillDocGeneratorBundle/Service/Generator/GeneratorInterface.php b/src/Bundle/ChillDocGeneratorBundle/Service/Generator/GeneratorInterface.php index 385e1d010..a8f01b97c 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Service/Generator/GeneratorInterface.php +++ b/src/Bundle/ChillDocGeneratorBundle/Service/Generator/GeneratorInterface.php @@ -4,6 +4,7 @@ namespace Chill\DocGeneratorBundle\Service\Generator; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\DocStoreBundle\Entity\StoredObject; +use Chill\MainBundle\Entity\User; use Symfony\Component\HttpFoundation\File\File; interface GeneratorInterface @@ -22,6 +23,7 @@ interface GeneratorInterface array $contextGenerationDataNormalized, ?StoredObject $destinationStoredObject = null, bool $isTest = false, - ?File $testFile = null + ?File $testFile = null, + ?User $creator = null ): ?string; } diff --git a/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationHandler.php b/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationHandler.php index 0cfdecd0a..8fef8cf41 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationHandler.php +++ b/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationHandler.php @@ -6,7 +6,9 @@ use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository; use Chill\DocGeneratorBundle\Service\Generator\Generator; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Repository\StoredObjectRepository; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; @@ -23,18 +25,28 @@ class RequestGenerationHandler implements MessageHandlerInterface private Generator $generator; + private LoggerInterface $logger; + + private UserRepositoryInterface $userRepository; + public const AUTHORIZED_TRIALS = 5; + private const LOG_PREFIX = '[docgen message handler] '; + public function __construct( DocGeneratorTemplateRepository $docGeneratorTemplateRepository, EntityManagerInterface $entityManager, Generator $generator, - StoredObjectRepository $storedObjectRepository + LoggerInterface $logger, + StoredObjectRepository $storedObjectRepository, + UserRepositoryInterface $userRepository ) { $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; $this->entityManager = $entityManager; $this->generator = $generator; + $this->logger = $logger; $this->storedObjectRepository = $storedObjectRepository; + $this->userRepository = $userRepository; } public function __invoke(RequestGenerationMessage $message) @@ -51,6 +63,8 @@ class RequestGenerationHandler implements MessageHandlerInterface throw new UnrecoverableMessageHandlingException('maximum number of retry reached'); } + $creator = $this->userRepository->find($message->getCreatorId()); + $destinationStoredObject->addGenerationTrial(); $this->entityManager->createQuery('UPDATE '.StoredObject::class.' s SET s.generationTrialsCounter = s.generationTrialsCounter + 1 WHERE s.id = :id') ->setParameter('id', $destinationStoredObject->getId()) @@ -60,7 +74,16 @@ class RequestGenerationHandler implements MessageHandlerInterface $template, $message->getEntityId(), $message->getContextGenerationData(), - $destinationStoredObject + $destinationStoredObject, + false, + null, + $creator ); + + $this->logger->info(self::LOG_PREFIX.'Request generation finished', [ + 'template_id' => $message->getTemplateId(), + 'destination_stored_object' => $message->getDestinationStoredObjectId(), + 'duration_int' => (new \DateTimeImmutable('now'))->getTimestamp() - $message->getCreatedAt()->getTimestamp(), + ]); } } diff --git a/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationMessage.php b/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationMessage.php index edba90ce4..8362e4ecc 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationMessage.php +++ b/src/Bundle/ChillDocGeneratorBundle/Service/Messenger/RequestGenerationMessage.php @@ -18,6 +18,8 @@ class RequestGenerationMessage private array $contextGenerationData; + private \DateTimeImmutable $createdAt; + public function __construct( User $creator, DocGeneratorTemplate $template, @@ -30,6 +32,7 @@ class RequestGenerationMessage $this->entityId = $entityId; $this->destinationStoredObjectId = $destinationStoredObject->getId(); $this->contextGenerationData = $contextGenerationData; + $this->createdAt = new \DateTimeImmutable('now'); } public function getCreatorId(): int @@ -56,4 +59,9 @@ class RequestGenerationMessage { return $this->contextGenerationData; } + + public function getCreatedAt(): \DateTimeImmutable + { + return $this->createdAt; + } } diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php index 9ab733d87..bbfb67b43 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php @@ -204,7 +204,7 @@ class AccompanyingPeriodContext implements $options = $template->getOptions(); $data = []; - $data = array_merge($data, $this->baseContextData->getData()); + $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null)); $data['course'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => AccompanyingPeriod::class, 'groups' => 'docgen:read']); foreach (['mainPerson', 'person1', 'person2'] as $k) { diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php index 988c50829..ff3c4ef49 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php @@ -165,7 +165,7 @@ final class PersonContext implements PersonContextInterface } $data = []; - $data = array_merge($data, $this->baseContextData->getData()); + $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null)); $data['person'] = $this->normalizer->normalize($entity, 'docgen', [ 'docgen:expects' => Person::class, 'groups' => ['docgen:read'], From c3558beee145a9328e0108ad428beb2ee8d500b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Mar 2023 00:12:09 +0100 Subject: [PATCH 03/11] Fixed: add a social issue on an activity to an accompanying period --- src/Bundle/ChillActivityBundle/Entity/Activity.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 8fcae3e0b..2a5ae6acb 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -257,12 +257,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * Add a social issue. * - * Note: the social issue consistency (the fact that only yougest social issues + * Note: the social issue consistency (the fact that only youngest social issues * are kept) is processed by an entity listener: * * @see{\Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodSocialIssueConsistencyEntityListener} - * - * @return $this */ public function addSocialIssue(SocialIssue $socialIssue): self { @@ -270,6 +268,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac $this->socialIssues[] = $socialIssue; } + if ($this->getAccompanyingPeriod() !== null) { + $this->getAccompanyingPeriod()->addSocialIssue($socialIssue); + } + return $this; } @@ -550,6 +552,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $this->accompanyingPeriod = $accompanyingPeriod; + foreach ($this->getSocialIssues() as $issue) { + $this->accompanyingPeriod->addSocialIssue($issue); + } + return $this; } From 1cc80c8e6af7149f9c7942612d1f6e18d56cbaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Mar 2023 00:12:41 +0100 Subject: [PATCH 04/11] Fixed: takes all activity into account to check social issue consistency --- .../AccompanyingPeriodValidityValidator.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php index 51462c56e..9454d31d0 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php @@ -54,7 +54,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator $activities = $this->activityRepository->findBy(['accompanyingPeriod' => $period]); foreach ($activities as $activity) { - $socialIssues = $activity->getSocialIssues()->toArray(); + $socialIssues = array_merge($socialIssues, $activity->getSocialIssues()->toArray()); } foreach ($period->getWorks() as $work) { @@ -64,7 +64,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator $socialIssuesByKey = []; foreach ($socialIssues as $si) { - $socialIssuesByKey[$si->getId()] = $si; + $socialIssuesByKey[spl_object_hash($si)] = $si; } $periodIssuesWithAncestors = []; @@ -75,7 +75,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator $periodIssuesWithAncestors, array_map( static function (SocialIssue $si) { - return $si->getId(); + return spl_object_hash($si); }, $si->getAncestors(true) ) From 06b7e8427003c6875c08b45a4e20c64a751fb571 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 16 Mar 2023 13:48:01 +0100 Subject: [PATCH 05/11] FIX [thirdparty][profession] set default value for profession in symfony form --- src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php index 384c743c2..b1446a543 100644 --- a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php +++ b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php @@ -110,6 +110,7 @@ class ThirdPartyType extends AbstractType ->add('profession', TextType::class, [ 'label' => 'thirdparty.Profession', 'required' => false, + 'empty_data' => '', ]) ->add('contactDataAnonymous', CheckboxType::class, [ 'required' => false, From c729a1430473b7d3d9e889a5e0bd35c5f7596e82 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 20 Mar 2023 07:54:16 +0100 Subject: [PATCH 06/11] FIX [minor] remove dump, use statement, ... --- src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php b/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php index 6555f7835..c2caf13bb 100644 --- a/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php +++ b/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php @@ -117,7 +117,6 @@ class SimilarPersonMatcher $qb->setParameter('fullName', $this->personRender->renderString($person, [])); } - dump($qb->getQuery()); return $qb->getQuery()->getResult(); } } From df2480c47c3bbe72be73396736b01445b9689383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 20 Mar 2023 21:36:46 +0100 Subject: [PATCH 07/11] Fixed: transform null value into emtpy string into ThirdParty::setProfession --- src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php index b13118168..29565e86a 100644 --- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php +++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php @@ -807,10 +807,10 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface /** * @return $this - */ - public function setProfession(string $profession): self + */"" + public function setProfession(?string $profession): self { - $this->profession = $profession; + $this->profession = (string) $profession; return $this; } From ecac40958696e0ad588b8b3a434e95a0c0961397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 20 Mar 2023 21:38:42 +0100 Subject: [PATCH 08/11] fixed: fix 3party syntax --- src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php index 29565e86a..966e40bd1 100644 --- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php +++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php @@ -805,9 +805,6 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface return $this; } - /** - * @return $this - */"" public function setProfession(?string $profession): self { $this->profession = (string) $profession; From a8977729fea74410de53df3939ab1cce9d73f88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 21 Mar 2023 16:39:31 +0100 Subject: [PATCH 09/11] Fixed: [similar person matcher] properly takes person center into account Center comes from the table person_center_history, not person.center_id --- .../ChillPersonBundle/Search/SimilarPersonMatcher.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php b/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php index 6555f7835..b7e2c12b0 100644 --- a/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php +++ b/src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php @@ -76,8 +76,17 @@ class SimilarPersonMatcher $qb->select('p') ->from(Person::class, 'p') + ->join('p.centerHistory', 'center_history') ->where('SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= :precision') - ->andWhere($qb->expr()->in('p.center', ':centers')); + ->andWhere($qb->expr()->in('center_history.center', ':centers')) + ->andWhere($qb->expr()->andX( + $qb->expr()->lte('center_history.startDate', 'CURRENT_DATE()'), + $qb->expr()->orX( + $qb->expr()->isNull('center_history.endDate'), + $qb->expr()->gt('center_history.endDate', 'CURRENT_DATE()') + ) + )) + ; $qb ->setParameter('fullName', $this->personRender->renderString($person, [])) From 4eb7d10e459b4dd5b99d288f08132a63c5a716e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 23 Mar 2023 11:23:14 +0100 Subject: [PATCH 10/11] Fixed: [calendar ms synchro] do not throw an error if we are not allowed to get the default calendar --- .../Connector/MSGraph/MapCalendarToUser.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php index 504d48ffc..563bd3a38 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php @@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\User; use DateTimeImmutable; use LogicException; use Psr\Log\LoggerInterface; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use function array_key_exists; @@ -74,9 +75,18 @@ class MapCalendarToUser public function getDefaultUserCalendar(string $idOrUserPrincipalName): ?array { - $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [ - 'query' => ['$filter' => 'isDefaultCalendar eq true'], - ])->toArray()['value']; + try { + $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [ + 'query' => ['$filter' => 'isDefaultCalendar eq true'], + ])->toArray()['value']; + } catch (ClientExceptionInterface $e) { + $this->logger->error('[MapCalendarToUser] Error while listing calendars for a user', [ + 'http_status_code' => $e->getResponse()->getStatusCode(), + 'id_user' => $idOrUserPrincipalName, + ]); + + return null; + } return $value[0] ?? null; } From 96ddc73e45c406cf49ee2762417f3c171683a402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 23 Mar 2023 12:48:37 +0100 Subject: [PATCH 11/11] Feature: [calendar sync msgraph] Allow to show the calendar details if the user does not have msgraph mapping We first check that there are "msgraph" attributes before forcing redirection to MSGraph authorization. If not, we let's the user see the calendar edit/create page. --- .../MSGraphRemoteCalendarConnector.php | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php index c376f9680..d409e6f03 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php @@ -34,6 +34,7 @@ use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -64,6 +65,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface private OnBehalfOfUserHttpClient $userHttpClient; + private Security $security; + public function __construct( CalendarRepository $calendarRepository, CalendarRangeRepository $calendarRangeRepository, @@ -74,7 +77,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface OnBehalfOfUserHttpClient $userHttpClient, RemoteEventConverter $remoteEventConverter, TranslatorInterface $translator, - UrlGeneratorInterface $urlGenerator + UrlGeneratorInterface $urlGenerator, + Security $security ) { $this->calendarRepository = $calendarRepository; $this->calendarRangeRepository = $calendarRangeRepository; @@ -86,6 +90,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $this->translator = $translator; $this->urlGenerator = $urlGenerator; $this->userHttpClient = $userHttpClient; + $this->security = $security; } public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int @@ -133,6 +138,24 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface public function isReady(): bool { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + // this is not a user from chill. This is not the role of this class to + // restrict access, so we will just say that we do not have to do anything more + // here... + return true; + } + + if (null === $this->mapCalendarToUser->getUserId($user)) { + // this user is not mapped with remote calendar. The user will have to wait for + // the next calendar subscription iteration + $this->logger->debug('mark user ready for msgraph calendar as he does not have any mapping', [ + 'userId' => $user->getId(), + ]); + return true; + } + return $this->tokenStorage->hasToken(); }