validateSynchronisationData($data); /** @var ResponseGenerator $responseGenerator */ $responseGenerator = $this->getServiceLocator()->get(ResponseGenerator::class); // extract the actions and build usable instances $actions = $responseGenerator->prepareActions($data, $this->getAvailableActions()); $timeNow = microtime(true); $lastActionTimestamp = $responseGenerator->getLastActionTimestamp($actions, $serviceContext, $timeNow); $response = []; foreach ($actions as $action) { if ($action instanceof TestRunnerAction) { $response[] = $responseGenerator->getActionResponse( $action, $timeNow, $lastActionTimestamp, $serviceContext ); } else { $response[] = $action; // if error happened } // no need to break on the first error as all actions expected to be with a response by the fe part } $this->persistContext($serviceContext); return $response; } /** * Get available actions from config * * @return array */ public function getAvailableActions(): array { return is_array($this->getOption(self::ACTIONS_OPTION)) ? $this->getOption(self::ACTIONS_OPTION) : []; } /** * Set available actions to config * * @param array $actions */ public function setAvailableActions(array $actions = []): void { $this->setOption(self::ACTIONS_OPTION, $actions); } /** * @param $data * @throws common_exception_InconsistentData */ protected function validateSynchronisationData($data): void { if (empty($data)) { throw new common_exception_InconsistentData('No action to check. Processing action requires data.'); } } /** * @param QtiRunnerServiceContext $serviceContext */ protected function persistContext(QtiRunnerServiceContext $serviceContext): void { try { /** @var QtiRunnerService $runnerService */ $runnerService = $this->getServiceLocator()->get(QtiRunnerService::SERVICE_ID); $runnerService->persist($serviceContext); } catch (common_Exception $e) { // log the error message but return the data common_Logger::e($e->getMessage()); } } }