/**
  * Remove unused response declaration from the items and rp template misuse
  *
  * @param oat\taoQtiItem\modal\Item $item
  * @param string $itemFile
  * @return boolean
  */
 protected function updateItem(\oat\taoQtiItem\model\qti\Item $item, $itemFile)
 {
     $changed = false;
     $responses = $item->getResponses();
     $interactions = $item->getInteractions();
     $usedResponses = [];
     foreach ($interactions as $interaction) {
         $usedResponses[] = $interaction->attr('responseIdentifier');
     }
     foreach ($responses as $response) {
         $responseIdentifier = $response->attr('identifier');
         if (!in_array($responseIdentifier, $usedResponses)) {
             $changed = true;
             $item->removeResponse($response);
         }
     }
     $xml = simplexml_load_file($itemFile);
     $rpTemplate = (string) $xml->responseProcessing['template'];
     //detect wrong usage for standard standard response declaration
     $rp = $item->getResponseProcessing();
     if ($rp instanceof \oat\taoQtiItem\model\qti\response\TemplatesDriven && $rpTemplate) {
         if (count($interactions) > 1) {
             $changed = true;
         } else {
             $interaction = reset($interactions);
             if ($interaction && $interaction->attr('responseIdentifier') != 'RESPONSE') {
                 $changed = true;
             }
         }
     }
     return $changed;
 }
 /**
  * Remove unused response declaration from the items and rp template misuse
  *
  * @param oat\taoQtiItem\modal\Item $item
  * @param string $itemFile
  * @return boolean
  */
 protected function updateItem(Item $item, $itemFile)
 {
     $changed = false;
     $requireFix = false;
     $interactions = $item->getInteractions();
     foreach ($interactions as $interaction) {
         if ($interaction instanceof PortableCustomInteraction && $interaction->getTypeIdentifier() === 'textReaderInteraction') {
             $response = $interaction->getResponse();
             $currentDefaultVal = $response->getDefaultValue();
             if (!is_array($currentDefaultVal) || empty($currentDefaultVal) || count($currentDefaultVal) !== 1) {
                 $requireFix = true;
             } else {
                 $val = $currentDefaultVal[0];
                 $requireFix = !($val instanceof Value && $val->getValue() === 'true');
             }
             if ($requireFix) {
                 $defaultValue = new Value();
                 $defaultValue->setValue('true');
                 $response->setDefaultValue([$defaultValue]);
                 $changed = true;
             }
         }
     }
     return $changed;
 }
 /**
  * Short description of method takeOverFrom
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  ResponseProcessing responseProcessing
  * @param  Item item
  * @return oat\taoQtiItem\model\qti\response\Composite
  */
 public static function takeOverFrom(ResponseProcessing $responseProcessing, Item $item)
 {
     $returnValue = null;
     if ($responseProcessing instanceof static) {
         // already good
         $returnValue = $responseProcessing;
     } elseif ($responseProcessing instanceof Template) {
         // IMS Template
         $rp = new Summation($item, 'SCORE');
         foreach ($item->getInteractions() as $interaction) {
             $response = $interaction->getResponse();
             try {
                 $irp = IrpTemplate::createByTemplate($responseProcessing->getUri(), $response, $item);
             } catch (Exception $e) {
                 throw new TakeoverFailedException();
             }
             $rp->add($irp, $item);
         }
         $returnValue = $rp;
     } elseif ($responseProcessing instanceof TemplatesDriven) {
         // TemplateDriven
         $rp = new Summation($item, 'SCORE');
         foreach ($item->getInteractions() as $interaction) {
             $response = $interaction->getResponse();
             try {
                 $irp = IrpTemplate::createByTemplate($responseProcessing->getTemplate($response), $response, $item);
             } catch (Exception $e) {
                 throw new TakeoverFailedException();
             }
             $rp->add($irp, $item);
         }
         $returnValue = $rp;
     } else {
         common_Logger::d('Composite ResponseProcessing can not takeover from ' . get_class($responseProcessing) . ' yet');
         throw new TakeoverFailedException();
     }
     common_Logger::i('Converted to Composite', array('TAOITEMS', 'QTI'));
     return $returnValue;
 }
 /**
  * Short description of method buildRule
  *
  * @deprecated
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Item item
  * @return string
  */
 public function buildRule(Item $item)
 {
     $returnValue = (string) '';
     foreach ($item->getInteractions() as $interaction) {
         $response = $interaction->getResponse();
         $uri = $response->getHowMatch();
         $templateName = substr($uri, strrpos($uri, '/') + 1);
         $matchingTemplate = dirname(__FILE__) . '/rpTemplate/rule.' . $templateName . '.tpl.php';
         $tplRenderer = new taoItems_models_classes_TemplateRenderer($matchingTemplate, array('responseIdentifier' => $response->getIdentifier(), 'outcomeIdentifier' => 'SCORE'));
         $returnValue .= $tplRenderer->render();
     }
     return (string) $returnValue;
 }
 /**
  * Short description of method buildCompositeResponseProcessing
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  DOMElement data
  * @param  Item item
  * @return oat\taoQtiItem\model\qti\response\ResponseProcessing
  */
 protected function buildCompositeResponseProcessing(DOMElement $data, Item $item)
 {
     $returnValue = null;
     // STRONGLY simplified summation detection
     $patternCorrectTAO = '/responseCondition [count(./*) = 1 ] [name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "match" ] [name(./responseIf/match/*[1]) = "variable" ] [name(./responseIf/match/*[2]) = "correct" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [count(./responseIf/setOutcomeValue/*) = 1 ] [name(./responseIf/setOutcomeValue/*[1]) = "baseValue"]';
     $patternMapTAO = '/responseCondition [count(./*) = 1 ] [name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "not" ] [count(./responseIf/not/*) = 1 ] [name(./responseIf/not/*[1]) = "isNull" ] [count(./responseIf/not/isNull/*) = 1 ] [name(./responseIf/not/isNull/*[1]) = "variable" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [count(./responseIf/setOutcomeValue/*) = 1 ] [name(./responseIf/setOutcomeValue/*[1]) = "mapResponse"]';
     $patternMapPointTAO = '/responseCondition [count(./*) = 1 ] [name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "not" ] [count(./responseIf/not/*) = 1 ] [name(./responseIf/not/*[1]) = "isNull" ] [count(./responseIf/not/isNull/*) = 1 ] [name(./responseIf/not/isNull/*[1]) = "variable" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [count(./responseIf/setOutcomeValue/*) = 1 ] [name(./responseIf/setOutcomeValue/*[1]) = "mapResponsePoint"]';
     $patternNoneTAO = '/responseCondition [count(./*) = 1 ] [name(./*[1]) = "responseIf" ] [count(./responseIf/*) = 2 ] [name(./responseIf/*[1]) = "isNull" ] [count(./responseIf/isNull/*) = 1 ] [name(./responseIf/isNull/*[1]) = "variable" ] [name(./responseIf/*[2]) = "setOutcomeValue" ] [count(./responseIf/setOutcomeValue/*) = 1 ] [name(./responseIf/setOutcomeValue/*[1]) = "baseValue"]';
     $possibleSummation = '/setOutcomeValue [count(./*) = 1 ] [name(./*[1]) = "sum" ]';
     $irps = array();
     $composition = null;
     $data = simplexml_import_dom($data);
     foreach ($data as $responseRule) {
         if (!is_null($composition)) {
             throw new UnexpectedResponseProcessing('Not composite, rules after composition');
         }
         $subtree = new SimpleXMLElement($responseRule->asXML());
         if (count($subtree->xpath($patternCorrectTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->match->variable[0]['identifier'];
             $irps[$responseIdentifier] = array('class' => 'MatchCorrectTemplate', 'outcome' => (string) $subtree->responseIf->setOutcomeValue[0]['identifier']);
         } elseif (count($subtree->xpath($patternMapTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->not->isNull->variable[0]['identifier'];
             $irps[$responseIdentifier] = array('class' => 'MapResponseTemplate', 'outcome' => (string) $subtree->responseIf->setOutcomeValue[0]['identifier']);
         } elseif (count($subtree->xpath($patternMapPointTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->not->isNull->variable[0]['identifier'];
             $irps[$responseIdentifier] = array('class' => 'MapResponsePointTemplate', 'outcome' => (string) $subtree->responseIf->setOutcomeValue[0]['identifier']);
         } elseif (count($subtree->xpath($patternNoneTAO)) > 0) {
             $responseIdentifier = (string) $subtree->responseIf->isNull->variable[0]['identifier'];
             $irps[$responseIdentifier] = array('class' => 'None', 'outcome' => (string) $subtree->responseIf->setOutcomeValue[0]['identifier'], 'default' => (string) $subtree->responseIf->setOutcomeValue[0]->baseValue[0]);
         } elseif (count($subtree->xpath($possibleSummation)) > 0) {
             $composition = 'Summation';
             $outcomesUsed = array();
             foreach ($subtree->xpath('/setOutcomeValue/sum/variable') as $var) {
                 $outcomesUsed[] = (string) $var[0]['identifier'];
             }
         } else {
             throw new UnexpectedResponseProcessing('Not composite, unknown rule');
         }
     }
     if (is_null($composition)) {
         throw new UnexpectedResponseProcessing('Not composit, Composition rule missing');
     }
     $responses = array();
     foreach ($item->getInteractions() as $interaction) {
         $responses[$interaction->getResponse()->getIdentifier()] = $interaction->getResponse();
     }
     if (count(array_diff(array_keys($irps), array_keys($responses))) > 0) {
         throw new UnexpectedResponseProcessing('Not composit, no responses for rules: ' . implode(',', array_diff(array_keys($irps), array_keys($responses))));
     }
     if (count(array_diff(array_keys($responses), array_keys($irps))) > 0) {
         common_Logger::w('Some responses have no processing');
         throw new UnexpectedResponseProcessing('Not composit, no support for unmatched variables yet');
     }
     //assuming sum is correct
     $compositonRP = new Summation($item);
     foreach ($responses as $id => $response) {
         $outcome = null;
         foreach ($item->getOutcomes() as $possibleOutcome) {
             if ($possibleOutcome->getIdentifier() == $irps[$id]['outcome']) {
                 $outcome = $possibleOutcome;
                 break;
             }
         }
         if (is_null($outcome)) {
             throw new ParsingException('Undeclared Outcome in ResponseProcessing');
         }
         $classname = '\\oat\\taoQtiItem\\model\\qti\\response\\interactionResponseProcessing\\' . $irps[$id]['class'];
         $irp = new $classname($response, $outcome);
         if ($irp instanceof \oat\taoQtiItem\model\qti\response\interactionResponseProcessing\None && isset($irps[$id]['default'])) {
             $irp->setDefaultValue($irps[$id]['default']);
         }
         $compositonRP->add($irp);
     }
     $returnValue = $compositonRP;
     return $returnValue;
 }