21 private const EVENT_STEP =
'onExecuteStep';
36 private $onStepChangeCallback;
41 private $onSaveCallback;
46 private $onFinishCallback;
52 $this->scenario = $scenario;
53 $this->generation = $generation;
55 $this->stepId = $this->generation->getStep();
60 private function initSteps(): void
62 foreach ($this->scenario->getMap() as $stepId => $step)
69 $this->steps[$stepId] = $scenarioStep;
72 $query = StepsTable::query()
73 ->setSelect([
'ID',
'STEP_ID',
'STATUS'])
74 ->where(
'GENERATION_ID', $this->generation->getId())
77 while ($step =
$query->fetch())
80 isset($this->steps[(
int)$step[
'STEP_ID']])
81 && StepStatuses::tryFrom((
int)$step[
'STATUS'])
84 $this->steps[(int)$step[
'STEP_ID']]->status =
85 StepStatuses::from((
int)$step[
'STATUS']);
86 $this->steps[(int)$step[
'STEP_ID']]->entityId = (
int)$step[
'ID'];
102 foreach ($this->steps as $step)
119 foreach ($this->steps as $step)
134 foreach ($this->steps as $step)
136 if ($step->status === StepStatuses::Error)
151 foreach ($this->steps as $step)
154 $step->status->value > StepStatuses::New->value
158 $step->step->init($this->generation, $step->stepId);
159 $step->step->clearErrors();
160 $this->saveStepStatus($step, StepStatuses::New);
167 $this->onStepChangeCallback = $callback;
172 private function callOnStepChange(): void
174 if (isset($this->onStepChangeCallback) && is_int($this->stepId))
176 call_user_func($this->onStepChangeCallback, $this->stepId);
180 public function onSave(callable $callback): self
182 $this->onSaveCallback = $callback;
187 private function callOnSave(): void
189 if (isset($this->onSaveCallback))
191 call_user_func($this->onSaveCallback);
197 $this->onFinishCallback = $callback;
202 private function callOnFinish(): void
204 if (isset($this->onFinishCallback))
206 call_user_func($this->onFinishCallback);
217 if (!$this->scenario->checkStep($this->stepId))
222 $this->stepId = $this->stepId ?? $this->scenario->getFirstStepId();
228 foreach ($this->steps as $stepId => $step)
230 if ($stepId > $this->stepId)
237 || $step->status === StepStatuses::Error
245 $this->executeStep($step);
249 $this->saveStepStatus($step, StepStatuses::Error);
254 $this->stepId === $stepId
256 $step->step->isFinished()
257 || $step->step->isAsync()
261 $this->stepId = $this->scenario->getNextStepId($this->stepId);
267 $this->callOnStepChange();
274 $this->scenario->onFinish($this->generation);
275 $this->callOnFinish();
287 $step->step->init($this->generation, $step->stepId);
290 !$step->step->isStarted()
291 && $step->stepId === $this->scenario->getQuotaCalculateStep()
294 $this->checkRequestQuotas();
297 $step->step->execute();
299 if ($step->step->isStarted())
301 $this->saveStepStatus($step, StepStatuses::Started);
304 if ($step->step->isFinished())
309 if ($step->step->isChanged() || $step->step->isFinished())
314 $this->generation->getEvent()->send(self::EVENT_STEP);
317 private function saveStepStatus(ScenarioStepDto $step, StepStatuses
$status): void
321 if (!isset($step->entityId))
323 $resAdd = StepsTable::add([
324 'GENERATION_ID' => $this->generation->getId(),
325 'STEP_ID' => $step->stepId,
326 'CLASS' => $step->step::class,
330 if ($resAdd->isSuccess())
332 $step->entityId = $resAdd->getId();
338 StepsTable::update($step->entityId, [
347 private function checkRequestQuotas(): void
349 $quotaLimitText = $this->getQuotaLimitText();
350 if (is_string($quotaLimitText))
352 throw new GenerationException(
353 GenerationErrors::requestQuotaExceeded,
356 'errorText' => $quotaLimitText,
362 !$this->generation->getChatId()
363 || $this->generation->getChatId() <= 0
369 $this->generation->getScenario()?->getChatbot()?->onRequestQuotaOk(
370 new ChatBotMessageDto(
371 $this->generation->getChatId(),
372 $this->generation->getId(),
377 private function getQuotaLimitText(): ?string
379 if (!Loader::includeModule(
'ai'))
384 $requestCount = $this->getRequestQuotasSum();
385 if ($requestCount <= 0)
390 return $this->getRequestLimiter()->getTextFromCheckLimit($requestCount);
398 private function getRequestQuotas():
array
404 foreach ($this->scenario->getMap() as $step)
406 $stepQuota = $step::getRequestQuota($this->generation->getSiteData());
412 if (isset($quotas[$stepQuota->connectorClass]))
414 $quotas[$stepQuota->connectorClass]->requestCount += $stepQuota->requestCount;
418 $quotas[$stepQuota->connectorClass] = $stepQuota;
429 private function getRequestQuotasSum(): int
432 foreach ($this->getRequestQuotas() as $quota)
434 $requestCount += $quota->requestCount;
437 return $requestCount;
445 private function getRequestLimiter(): RequestLimiter
447 if (empty($this->requestLimiter))
449 $this->requestLimiter =
new RequestLimiter();
452 return $this->requestLimiter;