Prevent infinite loop when a subject from the trigger is missing
Given the trigger provides two subjects but only one subject was given via parameter and no transformer was able to generate the second from the first, this method runs into an infinite loop. This commit prevents this infinite loop. [MAILPOET-4935]
This commit is contained in:
@@ -96,12 +96,17 @@ class SubjectTransformerHandler {
|
||||
*/
|
||||
public function provideAllSubjects(Trigger $trigger, Subject ...$subjects): array {
|
||||
$allSubjectsKeys = $this->subjectKeysForTrigger($trigger);
|
||||
$allSubjectKeyTargets = array_diff($allSubjectsKeys, array_map(
|
||||
$allSubjectKeyTargets = array_filter(
|
||||
array_diff($allSubjectsKeys, array_map(
|
||||
function(Subject $subject): string {
|
||||
return $subject->getKey();
|
||||
},
|
||||
$subjects
|
||||
));
|
||||
)),
|
||||
function(string $target) use ($subjects): bool {
|
||||
return $this->canSubjectsTransformTo($target, ...$subjects);
|
||||
}
|
||||
);
|
||||
|
||||
$allSubjects = [];
|
||||
foreach ($subjects as $existingSubject) {
|
||||
@@ -118,9 +123,17 @@ class SubjectTransformerHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
while (count($allSubjects) < count($allSubjectsKeys)) {
|
||||
$allSubjects = $this->provideAllSubjects($trigger, ...array_values($allSubjects));
|
||||
}
|
||||
|
||||
$allSubjectsTransformed = true;
|
||||
do {
|
||||
foreach ($allSubjectKeyTargets as $key) {
|
||||
if (!isset($allSubjects[$key])) {
|
||||
$allSubjectsTransformed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$allSubjects = $allSubjectsTransformed ? $allSubjects : $this->provideAllSubjects($trigger, ...array_values($allSubjects));
|
||||
} while (!$allSubjectsTransformed);
|
||||
return array_values($allSubjects);
|
||||
}
|
||||
|
||||
@@ -164,4 +177,25 @@ class SubjectTransformerHandler {
|
||||
|
||||
return $transformerChain;
|
||||
}
|
||||
|
||||
private function canSubjectsTransformTo(string $target, Subject ...$subjects): bool {
|
||||
if (
|
||||
in_array($target, array_map(
|
||||
function(Subject $subject): string {
|
||||
return $subject->getKey();
|
||||
},
|
||||
$subjects
|
||||
))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($subjects as $subject) {
|
||||
$possibleTransformations = $this->getPossibleTransformations($subject->getKey());
|
||||
if (in_array($target, $possibleTransformations)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user