protected function buildResponseProcessing($validation, $isCaseSensitive = true) { // Guess question type $validationClazz = new \ReflectionClass($validation); $questionType = str_replace('_validation', '', $validationClazz->getShortName()); if (in_array($questionType, Constants::$questionTypesWithMappingSupport)) { $responseProcessing = new ResponseProcessing(); $responseProcessing->setTemplate(Constants::RESPONSE_PROCESSING_TEMPLATE_MAP_RESPONSE); return $responseProcessing; } if ($validation->get_valid_response()->get_score() != 1) { $validation->get_valid_response()->set_score(1); LogService::log('Only support mapping to `matchCorrect` template, thus validation score is changed to 1 and since mapped to QTI pre-defined `match_correct.xml` template'); } // Warn and remove `alt_responses` because couldn't support responseDeclaration with multiple valid answers if (!empty($validation->get_alt_responses())) { $validation->set_alt_responses([]); LogService::log('Does not support multiple validation responses for `responseDeclaration`, only use `valid_response`, ignoring `alt_responses`'); } // Warn since we only support match_correct, can't support `$isCaseSensitive` if ($isCaseSensitive == false) { LogService::log('Only support mapping to `matchCorrect` template, thus case sensitivity is ignored'); } $responseProcessing = new ResponseProcessing(); $responseProcessing->setTemplate(Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT); return $responseProcessing; }
public function build($itemIdentifier, $itemLabel, array $questions, $content = '') { // Initialise our <assessmentItem> $assessmentItem = new AssessmentItem($itemIdentifier, $itemIdentifier, false); $assessmentItem->setLabel($itemLabel); $assessmentItem->setOutcomeDeclarations($this->buildOutcomeDeclarations()); $assessmentItem->setToolName('Learnosity'); // Store interactions on this array to later be placed on <itemBody> $interactions = []; $responseDeclarationCollection = new ResponseDeclarationCollection(); $responseProcessingTemplates = []; foreach ($questions as $question) { /** @var Question $question */ // Map the `questions` and its validation objects to be placed at <itemBody> // The extraContent usually comes from `stimulus` of item that mapped to inline interaction and has no `prompt` list($interaction, $responseDeclaration, $responseProcessing, $extraContent) = $this->map($question); if (!empty($responseDeclaration)) { // TODO: Need to tidy this up // Well sometimes we can have multiple response declarations, ie. clozetext if ($responseDeclaration instanceof ResponseDeclarationCollection) { $responseDeclarationCollection->merge($responseDeclaration); } else { $responseDeclarationCollection->attach($responseDeclaration); } } if (!empty($responseProcessing)) { /** @var ResponseProcessing $responseProcessing */ $responseProcessingTemplates[] = $responseProcessing->getTemplate(); } $interactions[$question->get_reference()]['interaction'] = $interaction; if (!empty($extraContent)) { $interactions[$question->get_reference()]['extraContent'] = $extraContent; } } // Build <itemBody> $assessmentItem->setItemBody($this->itemBodyBuilder->buildItemBody($interactions, $content)); // Map <responseDeclaration> if (!empty($responseDeclarationCollection)) { $assessmentItem->setResponseDeclarations($responseDeclarationCollection); } // Map <responseProcessing> - combine response processing from questions // TODO: Tidy up this stuff if (!empty($responseProcessingTemplates)) { $templates = array_unique($responseProcessingTemplates); $isOnlyMatchCorrect = count($templates) === 1 && $templates[0] === Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT; $responseProcessing = new ResponseProcessing(); $responseProcessing->setTemplate($isOnlyMatchCorrect ? Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT : Constants::RESPONSE_PROCESSING_TEMPLATE_MAP_RESPONSE); $assessmentItem->setResponseProcessing($responseProcessing); } return $assessmentItem; }
protected function buildAssessmentItem(array $interactions, $responseProcessingTemplate = '') { $assessmentItem = new AssessmentItem('testItemID', 'testItemTitle', false); $responseProcessing = new ResponseProcessing(); $responseProcessing->setTemplate($responseProcessingTemplate); $assessmentItem->setResponseProcessing($responseProcessing); $itemBody = new ItemBody(); $p = new P(); $pCollection = new InlineCollection(); $pCollection->attach(new TextRun('The Matrix movie is starring ')); $pCollection->attach(new TextRun('.')); foreach ($interactions as $interaction) { $pCollection->attach($interaction); } $p->setContent($pCollection); $collection = new BlockCollection(); $collection->attach($p); $itemBody->setContent($collection); $assessmentItem->setItemBody($itemBody); return $assessmentItem; }
private function getResponseProcessingTemplate(ResponseProcessing $responseProcessing = null) { if ($responseProcessing === null) { return ResponseProcessingTemplate::none(); } if ($responseProcessing->getResponseRules()->count()) { LogService::log('Does not support custom response processing on <responseProcessing>. Ignoring <responseProcessing>'); return ResponseProcessingTemplate::unsupported(); } if (!empty($responseProcessing->getTemplateLocation())) { LogService::log('Does not support \'templateLocation\' on <responseProcessing>. Ignoring <responseProcessing>'); return ResponseProcessingTemplate::unsupported(); } if (!empty($responseProcessing->getTemplate())) { return ResponseProcessingTemplate::getFromTemplateUrl($responseProcessing->getTemplate()); } return ResponseProcessingTemplate::none(); }