Require subjects by class name to have them type checked and autocompleted
[MAILPOET-4465]
This commit is contained in:
@ -95,6 +95,12 @@ class Exceptions {
|
||||
->withMessage(__(sprintf("Subject with key '%s' not found.", $key), 'mailpoet'));
|
||||
}
|
||||
|
||||
public static function subjectClassNotFound(string $key): NotFoundException {
|
||||
return NotFoundException::create()
|
||||
->withErrorCode(self::SUBJECT_NOT_FOUND)
|
||||
->withMessage(__(sprintf("Subject of class '%s' not found.", $key), 'mailpoet'));
|
||||
}
|
||||
|
||||
public static function subjectLoadFailed(string $key, array $args): InvalidStateException {
|
||||
return InvalidStateException::create()
|
||||
->withErrorCode(self::SUBJECT_LOAD_FAILED)
|
||||
|
@ -4,6 +4,7 @@ namespace MailPoet\Automation\Engine\Workflows;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use MailPoet\Automation\Engine\Exceptions;
|
||||
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
|
||||
use MailPoet\Automation\Engine\Utils\Json;
|
||||
|
||||
class WorkflowRun {
|
||||
@ -33,6 +34,12 @@ class WorkflowRun {
|
||||
/** @var Subject[] */
|
||||
private $subjects;
|
||||
|
||||
/** @var array<class-string, string> */
|
||||
private $subjectKeyClassMap = [];
|
||||
|
||||
/**
|
||||
* @param Subject[] $subjects
|
||||
*/
|
||||
public function __construct(
|
||||
int $workflowId,
|
||||
string $triggerKey,
|
||||
@ -43,6 +50,10 @@ class WorkflowRun {
|
||||
$this->triggerKey = $triggerKey;
|
||||
$this->subjects = $subjects;
|
||||
|
||||
foreach ($subjects as $subject) {
|
||||
$this->subjectKeyClassMap[get_class($subject)] = $subject->getKey();
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
@ -88,7 +99,17 @@ class WorkflowRun {
|
||||
return $this->subjects;
|
||||
}
|
||||
|
||||
public function requireSubject(string $key): Subject {
|
||||
/**
|
||||
* @template T of Subject
|
||||
* @param class-string<T> $class
|
||||
* @return T
|
||||
*/
|
||||
public function requireSubject(string $class): Subject {
|
||||
$key = $this->subjectKeyClassMap[$class] ?? null;
|
||||
if (!$key) {
|
||||
throw Exceptions::subjectClassNotFound($class);
|
||||
}
|
||||
|
||||
$subjects = $this->getSubjects($key);
|
||||
if (count($subjects) === 0) {
|
||||
throw Exceptions::subjectNotFound($key);
|
||||
@ -96,7 +117,13 @@ class WorkflowRun {
|
||||
if (count($subjects) > 1) {
|
||||
throw Exceptions::multipleSubjectsFound($key);
|
||||
}
|
||||
return $subjects[0];
|
||||
|
||||
// ensure PHPStan we're indeed returning an instance of $class
|
||||
$subject = $subjects[0];
|
||||
if (!$subject instanceof $class) {
|
||||
throw new InvalidStateException();
|
||||
}
|
||||
return $subject;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
|
@ -76,7 +76,7 @@ class SendWelcomeEmailAction implements Action {
|
||||
public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void {
|
||||
$newsletter = $this->getWelcomeEmailForStep($step);
|
||||
|
||||
$subscriberSubject = $workflowRun->requireSubject(SubscriberSubject::KEY);
|
||||
$subscriberSubject = $workflowRun->requireSubject(SubscriberSubject::class);
|
||||
$subscriberId = $subscriberSubject->getFields()['id']->getValue();
|
||||
$subscriber = $this->subscribersRepository->findOneById($subscriberId);
|
||||
|
||||
@ -88,7 +88,7 @@ class SendWelcomeEmailAction implements Action {
|
||||
throw InvalidStateException::create()->withMessage(sprintf("Cannot schedule a newsletter for subscriber ID '%s' because their status is '%s'.", $subscriber->getId(), $subscriber->getStatus()));
|
||||
}
|
||||
|
||||
$segmentSubject = $workflowRun->requireSubject(SegmentSubject::KEY);
|
||||
$segmentSubject = $workflowRun->requireSubject(SegmentSubject::class);
|
||||
$segmentId = $segmentSubject->getFields()['id']->getValue();
|
||||
$subscriberSegment = $this->subscriberSegmentRepository->findOneBy([
|
||||
'subscriber' => $subscriber,
|
||||
|
Reference in New Issue
Block a user