Merge branch '323-related-entity-permission-give-from-workflow' into signature-app-master

This commit is contained in:
2024-11-13 22:44:29 +01:00
86 changed files with 1444 additions and 446 deletions

View File

@@ -0,0 +1,115 @@
<?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\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Workflow\Registry;
/**
* Check if an object, associated with a workflow, is blocked, or not, by this workflow.
*/
class WorkflowRelatedEntityPermissionHelper
{
public function __construct(
private readonly Security $security,
private readonly EntityWorkflowManager $entityWorkflowManager,
private readonly Registry $registry,
) {}
public function isAllowedByWorkflow(object $entity): bool
{
$entityWorkflows = $this->entityWorkflowManager->findByRelatedEntity($entity);
$currentUser = $this->security->getUser();
foreach ($entityWorkflows as $entityWorkflow) {
// if the user is finalized, we have to check if the workflow is finalPositive, or not
if ($entityWorkflow->isFinal()) {
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$marking = $workflow->getMarkingStore()->getMarking($entityWorkflow);
foreach ($marking->getPlaces() as $place => $int) {
$placeMetadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
if (true === ($placeMetadata['isFinalPositive'] ?? false)) {
// the workflow is final, and final positive, so we stop here.
return false;
}
}
}
}
foreach ($entityWorkflows as $entityWorkflow) {
// so, the workflow is running... We return true if the current user is involved
foreach ($entityWorkflow->getSteps() as $step) {
if ($step->getAllDestUser()->contains($currentUser)) {
return true;
}
}
}
return false;
}
/**
* Return true if the user is allowed to update the given object.
*
* Return false if some workflow block the edition of the object.
*/
public function notBlockedByWorkflow(object $entity): bool
{
$entityWorkflows = $this->entityWorkflowManager->findByRelatedEntity($entity);
$currentUser = $this->security->getUser();
$usersInvolved = [];
$entityWorkflowsNotFinalizedPositive = [];
foreach ($entityWorkflows as $entityWorkflow) {
// as soon as there is one signatured applyied, we are not able to
// edit the document any more
foreach ($entityWorkflow->getSteps() as $step) {
foreach ($step->getSignatures() as $signature) {
if (EntityWorkflowSignatureStateEnum::SIGNED === $signature->getState()) {
return false;
}
}
}
if ($entityWorkflow->isFinal()) {
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$marking = $workflow->getMarkingStore()->getMarking($entityWorkflow);
foreach ($marking->getPlaces() as $place => $active) {
$metadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
if ($metadata['isFinalPositive'] ?? true) {
return false;
}
}
} else {
$entityWorkflowsNotFinalizedPositive[] = $entityWorkflow;
foreach ($entityWorkflow->getSteps() as $step) {
foreach ($step->getAllDestUser()->toArray() as $user) {
$usersInvolved[] = $user;
}
}
}
}
// if there isn't any user, but a workflow, blocked
if ([] !== $entityWorkflowsNotFinalizedPositive) {
if ([] === $usersInvolved) {
return false;
}
return in_array($currentUser, $usersInvolved, true);
}
return true;
}
}