Add validation rule identifiers to exceptions and responses
[MAILPOET-4659]
This commit is contained in:
@ -161,11 +161,12 @@ class Exceptions {
|
|||||||
->withMessage(__("Workflow structure modification not supported.", 'mailpoet'));
|
->withMessage(__("Workflow structure modification not supported.", 'mailpoet'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function workflowStructureNotValid(string $detail): UnexpectedValueException {
|
public static function workflowStructureNotValid(string $detail, string $ruleId): UnexpectedValueException {
|
||||||
return UnexpectedValueException::create()
|
return UnexpectedValueException::create()
|
||||||
->withErrorCode(self::WORKFLOW_STRUCTURE_NOT_VALID)
|
->withErrorCode(self::WORKFLOW_STRUCTURE_NOT_VALID)
|
||||||
// translators: %s is a detailed information
|
// translators: %s is a detailed information
|
||||||
->withMessage(sprintf(__("Invalid workflow structure: %s", 'mailpoet'), $detail));
|
->withMessage(sprintf(__("Invalid workflow structure: %s", 'mailpoet'), $detail))
|
||||||
|
->withErrors(['rule_id' => $ruleId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function workflowStepModifiedWhenUnknown(Step $step): UnexpectedValueException {
|
public static function workflowStepModifiedWhenUnknown(Step $step): UnexpectedValueException {
|
||||||
|
@ -15,7 +15,7 @@ class WorkflowWalker {
|
|||||||
$steps = $workflow->getSteps();
|
$steps = $workflow->getSteps();
|
||||||
$root = $steps['root'] ?? null;
|
$root = $steps['root'] ?? null;
|
||||||
if (!$root) {
|
if (!$root) {
|
||||||
throw Exceptions::workflowStructureNotValid(__("Workflow must contain a 'root' step", 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__("Workflow must contain a 'root' step", 'mailpoet'), 'no-root');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($visitors as $visitor) {
|
foreach ($visitors as $visitor) {
|
||||||
@ -75,7 +75,8 @@ class WorkflowWalker {
|
|||||||
__("Step with ID '%1\$s' not found (referenced from '%2\$s')", 'mailpoet'),
|
__("Step with ID '%1\$s' not found (referenced from '%2\$s')", 'mailpoet'),
|
||||||
$stepId,
|
$stepId,
|
||||||
$parentStepId
|
$parentStepId
|
||||||
)
|
),
|
||||||
|
'step-not-found'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,15 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class ConsistentStepMapRule implements WorkflowNodeVisitor {
|
class ConsistentStepMapRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'consistent-step-map';
|
||||||
|
|
||||||
public function initialize(Workflow $workflow): void {
|
public function initialize(Workflow $workflow): void {
|
||||||
foreach ($workflow->getSteps() as $id => $step) {
|
foreach ($workflow->getSteps() as $id => $step) {
|
||||||
if ($id !== $step->getId()) {
|
if ($id !== $step->getId()) {
|
||||||
// translators: %1$s is the ID of the step, %2$s is its index in the steps object.
|
// translators: %1$s is the ID of the step, %2$s is its index in the steps object.
|
||||||
throw Exceptions::workflowStructureNotValid(
|
throw Exceptions::workflowStructureNotValid(
|
||||||
sprintf(__("Step with ID '%1\$s' stored under a mismatched index '%2\$s'.", 'mailpoet'), $step->getId(), $id)
|
sprintf(__("Step with ID '%1\$s' stored under a mismatched index '%2\$s'.", 'mailpoet'), $step->getId(), $id),
|
||||||
|
self::RULE_ID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class NoCycleRule implements WorkflowNodeVisitor {
|
class NoCycleRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'no-cycle';
|
||||||
|
|
||||||
public function initialize(Workflow $workflow): void {
|
public function initialize(Workflow $workflow): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ class NoCycleRule implements WorkflowNodeVisitor {
|
|||||||
foreach ($step->getNextSteps() as $nextStep) {
|
foreach ($step->getNextSteps() as $nextStep) {
|
||||||
$nextStepId = $nextStep->getId();
|
$nextStepId = $nextStep->getId();
|
||||||
if ($nextStepId === $step->getId() || isset($parentIdsMap[$nextStepId])) {
|
if ($nextStepId === $step->getId() || isset($parentIdsMap[$nextStepId])) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Cycle found in workflow graph', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Cycle found in workflow graph', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class NoDuplicateEdgesRule implements WorkflowNodeVisitor {
|
class NoDuplicateEdgesRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'no-duplicate-edges';
|
||||||
|
|
||||||
public function initialize(Workflow $workflow): void {
|
public function initialize(Workflow $workflow): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ class NoDuplicateEdgesRule implements WorkflowNodeVisitor {
|
|||||||
$visitedNextStepIdsMap = [];
|
$visitedNextStepIdsMap = [];
|
||||||
foreach ($node->getStep()->getNextSteps() as $nextStep) {
|
foreach ($node->getStep()->getNextSteps() as $nextStep) {
|
||||||
if (isset($visitedNextStepIdsMap[$nextStep->getId()])) {
|
if (isset($visitedNextStepIdsMap[$nextStep->getId()])) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Duplicate next step definition found', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Duplicate next step definition found', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
$visitedNextStepIdsMap[$nextStep->getId()] = true;
|
$visitedNextStepIdsMap[$nextStep->getId()] = true;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class NoJoinRule implements WorkflowNodeVisitor {
|
class NoJoinRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'no-join';
|
||||||
|
|
||||||
/** @var array<string, Step> */
|
/** @var array<string, Step> */
|
||||||
private $visitedSteps = [];
|
private $visitedSteps = [];
|
||||||
|
|
||||||
@ -22,7 +24,7 @@ class NoJoinRule implements WorkflowNodeVisitor {
|
|||||||
foreach ($step->getNextSteps() as $nextStep) {
|
foreach ($step->getNextSteps() as $nextStep) {
|
||||||
$nextStepId = $nextStep->getId();
|
$nextStepId = $nextStep->getId();
|
||||||
if (isset($this->visitedSteps[$nextStepId])) {
|
if (isset($this->visitedSteps[$nextStepId])) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Path join found in workflow graph', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Path join found in workflow graph', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,15 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class NoSplitRule implements WorkflowNodeVisitor {
|
class NoSplitRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'no-split';
|
||||||
|
|
||||||
public function initialize(Workflow $workflow): void {
|
public function initialize(Workflow $workflow): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function visitNode(Workflow $workflow, WorkflowNode $node): void {
|
public function visitNode(Workflow $workflow, WorkflowNode $node): void {
|
||||||
$step = $node->getStep();
|
$step = $node->getStep();
|
||||||
if (count($step->getNextSteps()) > 1) {
|
if (count($step->getNextSteps()) > 1) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Path split found in workflow graph', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Path split found in workflow graph', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class NoUnreachableStepsRule implements WorkflowNodeVisitor {
|
class NoUnreachableStepsRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'no-unreachable-steps';
|
||||||
|
|
||||||
/** @var WorkflowNode[] */
|
/** @var WorkflowNode[] */
|
||||||
private $visitedNodes = [];
|
private $visitedNodes = [];
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ class NoUnreachableStepsRule implements WorkflowNodeVisitor {
|
|||||||
|
|
||||||
public function complete(Workflow $workflow): void {
|
public function complete(Workflow $workflow): void {
|
||||||
if (count($this->visitedNodes) !== count($workflow->getSteps())) {
|
if (count($this->visitedNodes) !== count($workflow->getSteps())) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Unreachable steps found in workflow graph', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Unreachable steps found in workflow graph', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNode;
|
|||||||
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
use MailPoet\Automation\Engine\Validation\WorkflowGraph\WorkflowNodeVisitor;
|
||||||
|
|
||||||
class TriggersUnderRootRule implements WorkflowNodeVisitor {
|
class TriggersUnderRootRule implements WorkflowNodeVisitor {
|
||||||
|
public const RULE_ID = 'triggers-under-root';
|
||||||
|
|
||||||
/** @var array<string, Step> $triggersMap */
|
/** @var array<string, Step> $triggersMap */
|
||||||
private $triggersMap = [];
|
private $triggersMap = [];
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ class TriggersUnderRootRule implements WorkflowNodeVisitor {
|
|||||||
foreach ($step->getNextSteps() as $nextStep) {
|
foreach ($step->getNextSteps() as $nextStep) {
|
||||||
$nextStepId = $nextStep->getId();
|
$nextStepId = $nextStep->getId();
|
||||||
if (isset($this->triggersMap[$nextStepId])) {
|
if (isset($this->triggersMap[$nextStepId])) {
|
||||||
throw Exceptions::workflowStructureNotValid(__('Trigger must be a direct descendant of workflow root', 'mailpoet'));
|
throw Exceptions::workflowStructureNotValid(__('Trigger must be a direct descendant of workflow root', 'mailpoet'), self::RULE_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user