mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Add duplicate workflow prevention in MetadataExtractor
Integrate DuplicateEntityWorkflowFinder to prevent creating workflows for entities with existing opened or positive final workflows. Updated EntityWorkflowVoter to implement the same check before allowing creation. Removed unnecessary blank workflow parameter from Twig template.
This commit is contained in:
parent
758a14366e
commit
5a5d259d18
@ -13,6 +13,7 @@ namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\MainBundle\Workflow\Helper\DuplicateEntityWorkflowFinder;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@ -27,7 +28,11 @@ class EntityWorkflowVoter extends Voter
|
||||
|
||||
final public const SHOW_ENTITY_LINK = 'CHILL_MAIN_WORKFLOW_LINK_SHOW';
|
||||
|
||||
public function __construct(private readonly EntityWorkflowManager $manager, private readonly Security $security) {}
|
||||
public function __construct(
|
||||
private readonly EntityWorkflowManager $manager,
|
||||
private readonly Security $security,
|
||||
private readonly DuplicateEntityWorkflowFinder $duplicateEntityWorkflowFinder,
|
||||
) {}
|
||||
|
||||
protected function supports($attribute, $subject)
|
||||
{
|
||||
@ -41,6 +46,15 @@ class EntityWorkflowVoter extends Voter
|
||||
{
|
||||
switch ($attribute) {
|
||||
case self::CREATE:
|
||||
if (false === $this->voteOnAttribute(self::SEE, $subject, $token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->duplicateEntityWorkflowFinder->hasDuplicateOpenedOrFinalPositiveEntityWorkflow($subject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
case self::SEE:
|
||||
$handler = $this->manager->getHandler($subject);
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?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\Helper;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
|
||||
/**
|
||||
* Class DuplicateEntityWorkflowFinder.
|
||||
*
|
||||
* Finds duplicate entity workflows based on their status.
|
||||
*/
|
||||
class DuplicateEntityWorkflowFinder
|
||||
{
|
||||
public function __construct(private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly OpenedEntityWorkflowHelper $openedEntityWorkflowHelper) {}
|
||||
|
||||
/**
|
||||
* Return true if the related entity has opened workflow with same name, or workflow with a positive final step.
|
||||
*
|
||||
* This will return false if the other workflow is final **and** negative (because it has been canceled, for instance).
|
||||
*
|
||||
* If there isn't any other workflow related to the same entity, this will return false.
|
||||
*/
|
||||
public function hasDuplicateOpenedOrFinalPositiveEntityWorkflow(EntityWorkflow $entityWorkflow): bool
|
||||
{
|
||||
$otherWorkflows = $this->entityWorkflowRepository->findByRelatedEntity($entityWorkflow->getRelatedEntityClass(), $entityWorkflow->getRelatedEntityId());
|
||||
|
||||
foreach ($otherWorkflows as $otherWorkflow) {
|
||||
if ($entityWorkflow === $otherWorkflow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($otherWorkflow->getWorkflowName() !== $entityWorkflow->getWorkflowName()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->openedEntityWorkflowHelper->isFinal($otherWorkflow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->openedEntityWorkflowHelper->isFinalPositive($otherWorkflow)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -19,20 +19,33 @@ use Symfony\Component\Workflow\WorkflowInterface;
|
||||
|
||||
class MetadataExtractor
|
||||
{
|
||||
public function __construct(private readonly Registry $registry, private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
|
||||
public function __construct(
|
||||
private readonly Registry $registry,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly DuplicateEntityWorkflowFinder $duplicateEntityWorkflowFinder,
|
||||
) {}
|
||||
|
||||
public function availableWorkflowFor(string $relatedEntityClass, ?int $relatedEntityId = 0): array
|
||||
{
|
||||
$blankEntityWorkflow = new EntityWorkflow();
|
||||
$blankEntityWorkflow
|
||||
->setRelatedEntityId($relatedEntityId)
|
||||
->setRelatedEntityClass($relatedEntityClass);
|
||||
->setRelatedEntityClass($relatedEntityClass)
|
||||
;
|
||||
|
||||
// build the list of available workflows, and extract their names from metadata
|
||||
$workflows = $this->registry->all($blankEntityWorkflow);
|
||||
$workflowsList = [];
|
||||
|
||||
foreach ($workflows as $workflow) {
|
||||
// shortcut: we must not be able to create a new workflow if there are already created workflows,
|
||||
// so, we find if there are workflows opened or final positive for the same entity
|
||||
$blankEntityWorkflow->setWorkflowName($workflow->getName());
|
||||
if ($this->duplicateEntityWorkflowFinder->hasDuplicateOpenedOrFinalPositiveEntityWorkflow($blankEntityWorkflow)) {
|
||||
// if yes, we skip suggesting workflow
|
||||
continue;
|
||||
}
|
||||
|
||||
$metadata = $workflow->getMetadataStore()->getWorkflowMetadata();
|
||||
$text = \array_key_exists('label', $metadata) ?
|
||||
$this->translatableStringHelper->localize($metadata['label']) : $workflow->getName();
|
||||
|
@ -59,7 +59,6 @@ class WorkflowTwigExtensionRuntime implements RuntimeExtensionInterface
|
||||
|
||||
return $environment->render('@ChillMain/Workflow/_extension_list_workflow_for.html.twig', [
|
||||
'entity_workflows_json' => $this->normalizer->normalize($entityWorkflows, 'json', ['groups' => 'read']),
|
||||
'blank_workflow' => $blankEntityWorkflow,
|
||||
'workflows_available' => $workflowsAvailable,
|
||||
'relatedEntityClass' => $relatedEntityClass,
|
||||
'relatedEntityId' => $relatedEntityId,
|
||||
|
Loading…
x
Reference in New Issue
Block a user