File "WorkflowWalker.php"
Full Path: /home/warrior1/public_html/languages/wp-content-20241001222009/plugins/mailpoet/lib/Automation/Engine/Validation/WorkflowGraph/WorkflowWalker.php
File size: 2.65 KB
MIME-type: text/x-php
Charset: utf-8
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Engine\Validation\WorkflowGraph;
if (!defined('ABSPATH')) exit;
use Generator;
use MailPoet\Automation\Engine\Data\Step;
use MailPoet\Automation\Engine\Data\Workflow;
use MailPoet\Automation\Engine\Exceptions;
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException;
class WorkflowWalker {
/** @param WorkflowNodeVisitor[] $visitors */
public function walk(Workflow $workflow, array $visitors = []): void {
$steps = $workflow->getSteps();
$root = $steps['root'] ?? null;
if (!$root) {
throw Exceptions::workflowStructureNotValid(__("Workflow must contain a 'root' step", 'mailpoet'), 'no-root');
}
foreach ($visitors as $visitor) {
$visitor->initialize($workflow);
}
foreach ($this->walkStepsDepthFirstPreOrder($steps, $root) as $record) {
[$step, $parents] = $record;
foreach ($visitors as $visitor) {
$visitor->visitNode($workflow, new WorkflowNode($step, array_values($parents)));
}
}
foreach ($visitors as $visitor) {
$visitor->complete($workflow);
}
}
/**
* @param array<string, Step> $steps
* @return Generator<array{0: Step, 1: array<string, Step>}>
*/
private function walkStepsDepthFirstPreOrder(array $steps, Step $root): Generator {
/** @var array{0: Step, 1: array<string, Step>}[] $stack */
$stack = [
[$root, []],
];
do {
$record = array_pop($stack);
if (!$record) {
throw new InvalidStateException();
}
yield $record;
[$step, $parents] = $record;
foreach (array_reverse($step->getNextSteps()) as $nextStepData) {
$nextStepId = $nextStepData->getId();
$nextStep = $steps[$nextStepId] ?? null;
if (!$nextStep) {
throw $this->createStepNotFoundException($nextStepId, $step->getId());
}
$nextStepParents = array_merge($parents, [$step->getId() => $step]);
if (isset($nextStepParents[$nextStepId])) {
continue; // cycle detected, do not enter the path again
}
array_push($stack, [$nextStep, $nextStepParents]);
}
} while (count($stack) > 0);
}
private function createStepNotFoundException(string $stepId, string $parentStepId): UnexpectedValueException {
return Exceptions::workflowStructureNotValid(
// translators: %1$s is ID of the step not found, %2$s is ID of the step that references it
sprintf(
__("Step with ID '%1\$s' not found (referenced from '%2\$s')", 'mailpoet'),
$stepId,
$parentStepId
),
'step-not-found'
);
}
}