Add message handling for public view creation

Introduce `PostPublicViewMessage` and `PostPublicViewMessageHandler` to handle external user views on public links by applying workflow transitions. Integrate with `WorkflowViewSendPublicController` and add relevant tests.
This commit is contained in:
2024-10-09 21:33:09 +02:00
parent 40b8fae8ba
commit 82e2b9a0f6
6 changed files with 334 additions and 4 deletions

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Workflow\Messenger;
/**
* Message sent after a EntityWorkflowSendView was created, which means that
* an external user has seen a link for a public view.
*/
class PostPublicViewMessage
{
public function __construct(
public int $entityWorkflowSendViewId,
) {}
}

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Workflow\Messenger;
use Chill\MainBundle\Repository\EntityWorkflowSendViewRepository;
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Workflow\Registry;
/**
* Handle the behaviour after a EntityWorkflowSentView was created.
*
* This handler apply a transition if the workflow's configuration defines one.
*/
final readonly class PostPublicViewMessageHandler implements MessageHandlerInterface
{
private const LOG_PREFIX = '[PostPublicViewMessageHandler] ';
private const TRANSITION_ON_VIEW = 'onExternalView';
public function __construct(
private EntityWorkflowSendViewRepository $sendViewRepository,
private Registry $registry,
private LoggerInterface $logger,
) {}
public function __invoke(PostPublicViewMessage $message): void
{
$view = $this->sendViewRepository->find($message->entityWorkflowSendViewId);
if (null === $view) {
throw new \RuntimeException("EntityworkflowSendViewId {$message->entityWorkflowSendViewId} not found");
}
$step = $view->getSend()->getEntityWorkflowStep();
$entityWorkflow = $step->getEntityWorkflow();
if ($step !== $entityWorkflow->getCurrentStep()) {
$this->logger->info(self::LOG_PREFIX."Do not handle view, as the current's step for the associated EntityWorkflow has already moved", [
'id' => $message->entityWorkflowSendViewId,
'entityWorkflow' => $entityWorkflow->getId(),
]);
return;
}
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$metadata = $workflow->getMetadataStore();
foreach ($workflow->getMarking($entityWorkflow)->getPlaces() as $place => $key) {
$placeMetadata = $metadata->getPlaceMetadata($place);
if (array_key_exists(self::TRANSITION_ON_VIEW, $placeMetadata)) {
if ($workflow->can($entityWorkflow, $placeMetadata[self::TRANSITION_ON_VIEW])) {
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
$dto->transition = $workflow->getEnabledTransition($entityWorkflow, $placeMetadata[self::TRANSITION_ON_VIEW]);
$workflow->apply($entityWorkflow, $placeMetadata[self::TRANSITION_ON_VIEW], [
'context' => $dto,
'transitionAt' => $view->getViewAt(),
'transition' => $placeMetadata[self::TRANSITION_ON_VIEW],
]);
return;
}
$this->logger->info(self::LOG_PREFIX.'Not able to apply this transition', ['transition' => $placeMetadata[self::TRANSITION_ON_VIEW],
'entityWorkflowId' => $entityWorkflow->getId(), 'viewId' => $view->getId()]);
}
}
}
}