protected function buildResponseDeclaration($responseIdentifier, $validation) { $responseDeclaration = new ResponseDeclaration($responseIdentifier); $responseDeclaration->setCardinality(Cardinality::MULTIPLE); $responseDeclaration->setBaseType(BaseType::DIRECTED_PAIR); /** @var clozeassociation_validation $validation */ $validationValues = $validation->get_valid_response()->get_value(); $validationScore = $validation->get_valid_response()->get_score(); // Build correct response // Try to handle `null` values in `valid_response` `value`s $values = new ValueCollection(); foreach ($validationValues as $index => $validResponse) { if (!isset($this->possibleResponsesMap[$validResponse])) { throw new MappingException('Invalid or missing missing valid response `' . $validResponse . '``'); } if (!empty($validResponse)) { $first = ClozeassociationMapper::GAP_IDENTIFIER_PREFIX . $index; $second = ClozeassociationMapper::GAPCHOICE_IDENTIFIER_PREFIX . $this->possibleResponsesMap[$validResponse]; $values->attach(new Value(new QtiDirectedPair($first, $second))); } } if ($values->count() > 0) { $correctResponse = new CorrectResponse($values); $responseDeclaration->setCorrectResponse($correctResponse); } return $responseDeclaration; }
/** * Unmarshall a DOMElement object corresponding to a QTI responseDeclaration element. * * @param DOMElement $element A DOMElement object. * @return QtiComponent A ResponseDeclaration object. * @throws UnmarshallingException */ protected function unmarshall(DOMElement $element) { try { $baseComponent = parent::unmarshall($element); $object = new ResponseDeclaration($baseComponent->getIdentifier()); $object->setBaseType($baseComponent->getBaseType()); $object->setCardinality($baseComponent->getCardinality()); $object->setDefaultValue($baseComponent->getDefaultValue()); $correctResponseElts = self::getChildElementsByTagName($element, 'correctResponse'); if (count($correctResponseElts) === 1) { $correctResponseElt = $correctResponseElts[0]; $marshaller = $this->getMarshallerFactory()->createMarshaller($correctResponseElt, array($baseComponent->getBaseType())); $object->setCorrectResponse($marshaller->unmarshall($correctResponseElt)); } $mappingElts = self::getChildElementsByTagName($element, 'mapping'); if (count($mappingElts) === 1) { $mappingElt = $mappingElts[0]; $marshaller = $this->getMarshallerFactory()->createMarshaller($mappingElt, array($baseComponent->getBaseType())); $object->setMapping($marshaller->unmarshall($mappingElt)); } $areaMappingElts = self::getChildElementsByTagName($element, 'areaMapping'); if (count($areaMappingElts) === 1) { $areaMappingElt = $areaMappingElts[0]; $marshaller = $this->getMarshallerFactory()->createMarshaller($areaMappingElt); $object->setAreaMapping($marshaller->unmarshall($areaMappingElt)); } return $object; } catch (InvalidArgumentException $e) { $msg = "An unexpected error occured while unmarshalling the responseDeclaration."; throw new UnmarshallingException($msg, $element, $e); } }
public function testMarshallMapping() { $identifier = 'response3'; $cardinality = Cardinality::SINGLE; $baseType = BaseType::FLOAT; $component = new ResponseDeclaration($identifier, $baseType, $cardinality); $entries = new MapEntryCollection(); $entries[] = new MapEntry(1.0, 1.1, true); $entries[] = new MapEntry(1.1, 1.2, false); $mapping = new Mapping($entries, 0.0); $component->setMapping($mapping); $marshaller = $this->getMarshallerFactory('2.1.0')->createMarshaller($component); $element = $marshaller->marshall($component); $this->assertInstanceOf('\\DOMElement', $element); $this->assertEquals('responseDeclaration', $element->nodeName); $this->assertEquals($identifier, $element->getAttribute('identifier')); $this->assertEquals('float', $element->getAttribute('baseType')); $this->assertEquals('single', $element->getAttribute('cardinality')); $correctResponses = $element->getElementsByTagName('defaultValue'); $this->assertEquals(0, $correctResponses->length); $mapping = $element->getElementsByTagName('mapping'); $this->assertEquals(1, $mapping->length); $entries = $mapping->item(0)->getElementsByTagName('mapEntry'); $this->assertEquals(2, $entries->length); $entry = $entries->item(0); $this->assertEquals('mapEntry', $entry->nodeName); $this->assertEquals('1.0', $entry->getAttribute('mapKey')); $this->assertEquals('1.1', $entry->getAttribute('mappedValue')); $entry = $entries->item(1); $this->assertEquals('mapEntry', $entry->nodeName); $this->assertEquals('1.1', $entry->getAttribute('mapKey')); $this->assertEquals('1.2', $entry->getAttribute('mappedValue')); }
protected function buildResponseDeclaration($responseIdentifier, $validation) { /** @var tokenhighlight_validation $validation */ $responseDeclaration = new ResponseDeclaration($responseIdentifier, BaseType::IDENTIFIER); $answersCount = count($validation->get_valid_response()->get_value()); $responseDeclaration->setCardinality($answersCount <= 1 ? Cardinality::SINGLE : Cardinality::MULTIPLE); $correctResponseBuilder = new QtiCorrectResponseBuilder(); $responseDeclaration->setCorrectResponse($correctResponseBuilder->buildWithBaseTypeIdentifier($validation, $this->indexIdentifierMap)); return $responseDeclaration; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { /** @var mcq_validation $validation */ $responseDeclaration = new ResponseDeclaration($responseIdentifier); $responseDeclaration->setCardinality($this->isMultipleResponse ? Cardinality::MULTIPLE : Cardinality::SINGLE); $responseDeclaration->setBaseType(BaseType::IDENTIFIER); $correctResponseBuilder = new QtiCorrectResponseBuilder(); $responseDeclaration->setCorrectResponse($correctResponseBuilder->buildWithBaseTypeIdentifier($validation, $this->valueIdentifierMap)); return $responseDeclaration; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { /** @var orderlist_validation $validation */ $responseDeclaration = new ResponseDeclaration($responseIdentifier); $responseDeclaration->setCardinality(Cardinality::ORDERED); $responseDeclaration->setBaseType(BaseType::IDENTIFIER); $correctResponseBuilder = new QtiCorrectResponseBuilder(); $responseDeclaration->setCorrectResponse($correctResponseBuilder->buildWithBaseTypeIdentifier($validation, $this->indexIdentifiersMap)); return $responseDeclaration; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { $responseDeclaration = new ResponseDeclaration($responseIdentifier); $responseDeclaration->setCardinality(Cardinality::MULTIPLE); $responseDeclaration->setBaseType(BaseType::DIRECTED_PAIR); $score = floatval($validation->get_valid_response()->get_score()); $value = $validation->get_valid_response()->get_value(); // The validation in `choicematrix` has to be an array if (!is_array($value)) { throw new MappingException('Broken validation object. Response declaration mapping failed'); } $responseDeclaration->setCorrectResponse(new CorrectResponse($this->buildValueCollection($value))); return $responseDeclaration; }
/** * @param string $identifier * @param array $mapping Mapping of `mapKey` to [`mappedValue`, `caseSensitive`] * ie. { * "York" => [1, false] * "york" => [1, false] * "Manhattan" => [1, true] * } * * @return \qtism\data\state\ResponseDeclaration */ public static function buildWithMapping($identifier, array $mapping, $mapEntryKeyType = null) { $responseDeclaration = new ResponseDeclaration($identifier); $mapEntryCollection = new MapEntryCollection(); foreach ($mapping as $mapKey => $values) { $mappedValue = $values[0]; $caseSensitive = isset($values[1]) ? $values[1] : false; if ($mapEntryKeyType) { $keyParts = explode(' ', $mapKey); $mapKey = new QtiDirectedPair($keyParts[0], $keyParts[1]); } $mapEntryCollection->attach(new MapEntry($mapKey, floatval($mappedValue), $caseSensitive)); } $responseDeclaration->setMapping(new Mapping($mapEntryCollection)); return $responseDeclaration; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { /** @var clozedropdown_validation $validation */ // Since we split {{response}} to multiple interactions, so we would have multiple <responseDeclaration> as needed as well $responseDeclarationCollection = new ResponseDeclarationCollection(); foreach ($validation->get_valid_response()->get_value() as $index => $value) { $valueIdentifierMap = $this->valueIdentifierMapPerInlineChoices[$index]; $valueCollection = new ValueCollection(); $valueCollection->attach(new Value($valueIdentifierMap[$value])); // We make assumption about interaction identifier shall always be the appended with index, ie. `_0` $responseDeclaration = new ResponseDeclaration($responseIdentifier . '_' . $index); $responseDeclaration->setBaseType(BaseType::IDENTIFIER); $responseDeclaration->setCardinality(Cardinality::SINGLE); $responseDeclaration->setCorrectResponse(new CorrectResponse($valueCollection)); $responseDeclarationCollection->attach($responseDeclaration); } return $responseDeclarationCollection; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { /** @var clozetext_validation $validation */ // Since we split {{response}} to multiple interactions, so we would have multiple <responseDeclaration> as needed as well $responseDeclarationCollection = new ResponseDeclarationCollection(); // Process `valid_response` foreach ($validation->get_valid_response()->get_value() as $index => $value) { // We make assumption about interaction identifier shall always be the appended with index, ie. `_0` $responseDeclaration = new ResponseDeclaration($responseIdentifier . '_' . $index); $responseDeclaration->setCardinality(Cardinality::SINGLE); $responseDeclaration->setBaseType(BaseType::STRING); $valueCollection = new ValueCollection(); $valueCollection->attach(new Value($value)); $validResponseScore = floatval($validation->get_valid_response()->get_score()); $mapEntriesCollection = new MapEntryCollection(); $mapEntriesCollection->attach(new MapEntry($value, $validResponseScore, $this->isCaseSensitive)); if (count($validation->get_alt_responses()) > 0) { /** @var clozetext_validation_alt_responses_item $alt */ foreach ($validation->get_alt_responses() as $alt) { // Assuming if (!is_null($alt->get_value()) && isset($alt->get_value()[$index])) { $alternativeValue = $alt->get_value()[$index]; $alternativeScore = floatval($alt->get_score()); $valueCollection->attach(new Value($alternativeValue)); $mapEntriesCollection->attach(new MapEntry($alternativeValue, $alternativeScore, $this->isCaseSensitive)); } } } $responseDeclaration->setCorrectResponse(new CorrectResponse($valueCollection)); $responseDeclaration->setMapping(new Mapping($mapEntriesCollection)); $responseDeclarationCollection->attach($responseDeclaration); } return $responseDeclarationCollection; }
protected function buildResponseDeclaration($responseIdentifier, $validation) { $responseDeclaration = new ResponseDeclaration($responseIdentifier); $responseDeclaration->setCardinality(Cardinality::SINGLE); $responseDeclaration->setBaseType(BaseType::STRING); $correctResponseBuilder = new QtiCorrectResponseBuilder(); $responseDeclaration->setCorrectResponse($correctResponseBuilder->build($validation)); $mappingResponseBuilder = new QtiMappingBuilder(); $mapping = $mappingResponseBuilder->build($validation); $responseDeclaration->setMapping($mapping); foreach ($mapping->getMapEntries() as $mapEntry) { /** @var MapEntry $mapEntry */ $mapEntry->setCaseSensitive($this->isCaseSensitive); } return $responseDeclaration; }
private function assertInteractionTwo(ChoiceInteraction $interaction, ResponseDeclaration $responseDeclaration) { // And its prompt is mapped correctly $promptString = QtiMarshallerUtil::marshallCollection($interaction->getPrompt()->getComponents()); $this->assertEquals('Pick the odd one out', $promptString); // All the choices also mapped properly /** @var SimpleChoice[] $simpleChoices */ $simpleChoices = $interaction->getSimpleChoices()->getArrayCopy(true); $this->assertEquals($simpleChoices[0]->getIdentifier(), 'CHOICE_0'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[0]->getContent()), 'Tomato'); $this->assertEquals($simpleChoices[1]->getIdentifier(), 'CHOICE_1'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[1]->getContent()), 'Orange'); $this->assertEquals($simpleChoices[2]->getIdentifier(), 'CHOICE_2'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[2]->getContent()), 'Celery'); $this->assertEquals($simpleChoices[3]->getIdentifier(), 'CHOICE_3'); $this->assertEquals(QtiMarshallerUtil::marshallCollection($simpleChoices[3]->getContent()), 'Pear'); // Check usual stuff $this->assertEquals(1, $interaction->getMinChoices()); $this->assertEquals(1, $interaction->getMaxChoices()); $this->assertFalse($interaction->mustShuffle()); $this->assertEquals(Orientation::HORIZONTAL, $interaction->getOrientation()); // Check the response declaration fine for mcq with multiple responses $this->assertEquals(BaseType::IDENTIFIER, $responseDeclaration->getBaseType()); $this->assertEquals(Cardinality::SINGLE, $responseDeclaration->getCardinality()); $correctResponse = $responseDeclaration->getCorrectResponse(); $this->assertTrue($correctResponse instanceof CorrectResponse); /** @var Value[] $values */ $values = $correctResponse->getValues()->getArrayCopy(true); $this->assertEquals($values[0]->getValue(), 'CHOICE_2'); $this->assertNull($responseDeclaration->getMapping()); }