Add event subscriber for document restoration on cancel

Implement an event subscriber to restore documents to their last kept version when a workflow transition ends in a non-positive final state. Includes corresponding unit tests and an unreleased feature change log entry.
This commit is contained in:
2025-02-14 15:08:42 +01:00
parent 739e0b1692
commit 0a34f9086f
3 changed files with 233 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
<?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\EventSubscriber;
use Chill\DocStoreBundle\Service\StoredObjectRestoreInterface;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Workflow\Event\TransitionEvent;
use Symfony\Component\Workflow\Registry;
final readonly class OnCancelRestoreDocumentToEditableEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private Registry $registry,
private EntityWorkflowManager $manager,
private StoredObjectRestoreInterface $storedObjectRestore,
) {}
public static function getSubscribedEvents(): array
{
return ['workflow.transition' => ['onCancelRestoreDocumentToEditable', 0]];
}
public function onCancelRestoreDocumentToEditable(TransitionEvent $event): void
{
$entityWorkflow = $event->getSubject();
if (!$entityWorkflow instanceof EntityWorkflow) {
return;
}
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
foreach ($event->getTransition()->getTos() as $place) {
$metadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
if (($metadata['isFinal'] ?? false) && !($metadata['isFinalPositive'] ?? true)) {
$this->restoreDocument($entityWorkflow);
return;
}
}
}
private function restoreDocument(EntityWorkflow $entityWorkflow): void
{
$storedObject = $this->manager->getAssociatedStoredObject($entityWorkflow);
if (null === $storedObject) {
return;
}
$version = $storedObject->getLastKeptBeforeConversionVersion();
if (null === $version) {
return;
}
$this->storedObjectRestore->restore($storedObject->getLastKeptBeforeConversionVersion());
}
}