function readCommon($xml) { $depth = $xml->depth; $text = ""; while ($xml->levelRead($depth)) { if ($xml->nodeType == XMLReader::ELEMENT) { $text .= "<property name=\"{$xml->name}\" value=\"" . xmlspecialchars($xml->readString()) . "\"/>\n"; } } return $text; }
/** Select the given value. @param $sValue The value to select. */ protected function selectItem($sValue) { $sEscapedValue = xmlspecialchars($sValue); $aOption = $this->oXML->options->xpath('.//item[(not(@value) and @label="' . $sEscapedValue . '" or @value="' . $sEscapedValue . '") and not(@disabled)]'); $iSize = count($aOption); $iSize > 1 and burn('BadXMLException', _WT('The value was found more than once in the options.')); if ($iSize == 1) { $aOption[0]['selected'] = 'selected'; } }
<?php $this->isEqual('Time to say 'night.', xmlspecialchars("Time to say 'night."), _WT("Encoding of ' failed.")); $this->isEqual('">_>" & "<_<"', xmlspecialchars('">_>" & "<_<"'), _WT('Encoding of ">_>" & "<_<" failed.')); $this->isEqual('東方妖々夢', xmlspecialchars('東方妖々夢'), _WT('xmlspecialchars should not encode unicode characters.'));
public function buildQTI($data = null) { if (!is_null($data)) { $this->data = $data; } if (empty($this->data)) { return false; } // container element and other metadata $ai = $this->initialXML(); // response declarations for ($g = 0; array_key_exists("gap_{$g}_response_0", $this->data); $g++) { $rd = $ai->addChild("responseDeclaration"); $rd->addAttribute("identifier", "RESPONSE_gap_{$g}"); $rd->addAttribute("cardinality", "single"); $rd->addAttribute("baseType", "string"); $m = $rd->addChild("mapping"); $m->addAttribute("defaultValue", "0"); for ($r = 0; array_key_exists("gap_{$g}_response_{$r}", $this->data); $r++) { $me = $m->addChild("mapEntry"); $me->addAttribute("mapKey", $this->data["gap_{$g}_response_{$r}"]); $me->addAttribute("mappedValue", $this->data["gap_{$g}_response_{$r}_score"]); } } // outcome declaration $od = $ai->addChild("outcomeDeclaration"); $od->addAttribute("identifier", "SCORE"); $od->addAttribute("cardinality", "single"); $od->addAttribute("baseType", "float"); $od->addChild("defaultValue"); $od->defaultValue->addChild("value", "0"); // item body $ib = $ai->addChild("itemBody"); // get stimulus and add to the XML tree if (isset($this->data["stimulus"]) && !empty($this->data["stimulus"])) { $this->data["stimulus"] = wrapindiv($this->data["stimulus"]); // parse it as XML $stimulus = stringtoxml($this->data["stimulus"], "stimulus"); if (is_array($stimulus)) { // errors $this->errors[] = "Stimulus is not valid XML. It must not only be valid XML but valid QTI, which accepts a subset of XHTML. Details on specific issues follow:"; $this->errors = array_merge($this->errors, $stimulus); } else { simplexml_append($ib, $stimulus); } } // div with class eqiat-te $d = $ib->addChild("div"); $d->addAttribute("class", "eqiat-te"); // body text $bt = $d->addChild("div"); $bt->addAttribute("class", "textentrytextbody"); $text = xmlspecialchars($this->data["textbody"]); $text = preg_replace('%\\n\\n+%', "</p><p>", $text); $text = preg_replace('%\\n%', "<br/>", $text); $text = "<p>" . $text . "</p>"; $g = 0; $start = 0; while (($start = strpos($text, "[", $start)) !== false) { $start = strpos($text, "["); $end = strpos($text, "]", $start); // base expected length on the longest answer plus 10% $el = 0; for ($r = 0; array_key_exists("gap_{$g}_response_{$r}", $this->data); $r++) { $el = max($el, strlen($this->data["gap_{$g}_response_{$r}"])); } $el = ceil($el * 1.1); $text = substr($text, 0, $start) . '<textEntryInteraction responseIdentifier="RESPONSE_gap_' . $g++ . '" expectedLength="' . $el . '"/>' . substr($text, $end + 1); } // parse it as XML libxml_use_internal_errors(true); $textxml = simplexml_load_string($text); if ($textxml === false) { $this->errors[] = "Text body did not convert to valid XML"; foreach (libxml_get_errors() as $error) { $this->errors[] = "Text body line " . $error->line . ", column " . $error->column . ": " . $error->message; } libxml_clear_errors(); } else { simplexml_append($bt, $textxml); } libxml_use_internal_errors(false); // response processing $rp = $ai->addChild("responseProcessing"); // set score = 0 $sov = $rp->addChild("setOutcomeValue"); $sov->addAttribute("identifier", "SCORE"); $sov->addChild("baseValue", "0.0")->addAttribute("baseType", "float"); for ($g = 0; array_key_exists("gap_{$g}_response_0", $this->data); $g++) { $rc = $rp->addChild("responseCondition"); // if $ri = $rc->addChild("responseIf"); // not null $ri->addChild("not")->addChild("isNull")->addChild("variable")->addAttribute("identifier", "RESPONSE_gap_{$g}"); // increment score $sov = $ri->addChild("setOutcomeValue"); $sov->addAttribute("identifier", "SCORE"); $s = $sov->addChild("sum"); $s->addChild("variable")->addAttribute("identifier", "SCORE"); $s->addChild("mapResponse")->addAttribute("identifier", "RESPONSE_gap_{$g}"); } if (!empty($this->errors)) { return false; } // validate the QTI validateQTI($ai, $this->errors, $this->warnings, $this->messages); if (!empty($this->errors)) { return false; } $this->qti = $ai; return $this->qti; }
/** Output the form to string. @return string The resulting XHTML form. */ public function toString() { $oDoc = new DOMDocument(); $oXSL = new XSLTProcessor(); $oDoc->loadXML($this->buildXSLStylesheet()); $oXSL->importStyleSheet($oDoc); // time consuming $oWidgetsNode = $this->xpathOne('//widgets'); $oWidgetsNode = dom_import_simplexml($oWidgetsNode); // If some fields are required we put a label on top to inform the user if (count($this->oXML->xpath('//widget[@required]')) > 0) { $oOwnerDoc = $oWidgetsNode->ownerDocument; $oNode = $oOwnerDoc->createElement('ol'); $oNode->setAttribute('class', 'notice required'); $oWidgetsNode->insertBefore($oNode, $oWidgetsNode->firstChild); $o = $oOwnerDoc->createElement('li'); $oNode->appendChild($o); $aNotice = explode('*', _WT('The fields marked with * are required.')); $o->appendChild($oOwnerDoc->createTextNode($aNotice[0])); $o->appendChild($oOwnerDoc->createElement('em', '*')); $o->appendChild($oOwnerDoc->createTextNode($aNotice[1])); } // If we have any error we put a friendly message on top // $oErrorOl created here is also used to display global error messages if (!empty($this->aErrors)) { $oErrorOl = $oWidgetsNode->ownerDocument->createElement('ol'); $oErrorOl->setAttribute('class', 'error'); $oWidgetsNode->insertBefore($oErrorOl, $oWidgetsNode->firstChild); $oErrorOl = simplexml_import_dom($oErrorOl); $o = $oErrorOl->addChild('li'); $o->addChild('strong', _WT('One or more errors have been detected.')); } // Fill in the values and errors if any $aKeys = array_keys(array_merge($this->aData, $this->aErrors)); foreach ($aKeys as $sName) { // For global errors (namely errors with an empty string as widget name), we create // an ordered list at the beginning of the form and put the errors inside it. if (empty($sName)) { if (is_array($this->aErrors[$sName])) { foreach ($this->aErrors[$sName] as $sMsg) { $oErrorOl->addChild('li', $sMsg); } } else { $oErrorOl->addChild('li', $this->aErrors[$sName]); } continue; } // If it isn't a global error we fill values and errors normally ctype_print($sName) or burn('InvalidArgumentException', _WT('The widget name must be printable.')); $a = $this->oXML->xpath('//widget[name="' . xmlspecialchars($sName) . '"]'); if (!empty($a)) { $oWidget = $a[0]; if (isset($this->aData[$sName])) { if (empty($oWidget->options)) { $oWidget->value = $this->aData[$sName]; } else { $oOptionHelper = $this->helper('weeFormOptionsHelper', $sName); if (empty($oWidget->options['multiple'])) { if ($oOptionHelper->isInOptions($this->aData[$sName])) { $oOptionHelper->select($this->aData[$sName]); } } else { foreach ($this->aData[$sName] as $mValue) { if ($oOptionHelper->isInOptions($mValue)) { $oOptionHelper->select($mValue); } } } } } if (!empty($this->aErrors[$sName])) { if (!empty($oWidget->errors)) { $oNode = dom_import_simplexml($oWidget->errors); $oNode->parentNode->removeChild($oNode); } $oWidget->addChild('errors'); if (is_array($this->aErrors[$sName])) { foreach ($this->aErrors[$sName] as $sMsg) { $oWidget->errors->addChild('error', $sMsg); } } else { $oWidget->errors->addChild('error', $this->aErrors[$sName]); } } } } return $oXSL->transformToXML(dom_import_simplexml($this->oXML)->ownerDocument); }
creationtool="OmegaT" creationtoolversion="1.7.3_1" segtype="sentence" o-tmf="OmegaT TMX" adminlang="EN-US" srclang="EN" datatype="plaintext" > </header> <body> EOT; fwrite($f_out, $str); reset($src_list); while (list($k, $v) = each($src_list)) { $k = xmlspecialchars($k); $v = xmlspecialchars($v); $str = <<<EOT <tu> <tuv lang="EN"> <seg>{$k}</seg> </tuv> <tuv lang="{$dest_lang}"> <seg>{$v}</seg> </tuv> </tu> EOT; fwrite($f_out, $str); } $str = "</body>\n</tmx>"; fwrite($f_out, $str); fclose($f_out);
function makeTag($name, $attributes = null, $textContent = null, $close = true, $encodeContent = true) { $tag = "<{$name}"; if (is_array($attributes)) { foreach ($attributes as $attr => $value) { $tag .= ' ' . xmlspecialchars($attr) . '="' . xmlspecialchars($value) . '"'; } } if ($close && !$textContent) { $tag .= '/>'; } else { $tag .= '>'; } if ($textContent) { if ($encodeContent) { $tag .= xmlspecialchars($textContent); } else { $tag .= $textContent; } $tag .= "</{$name}>"; } output($tag . "\n"); }
function renderVastOutput($aOut, $pluginType, $vastAdDescription) { $adName = $aOut['name']; $player = ""; $player .= " <Ad id=\"{player_allocated_ad_id}\" >"; $player .= " <InLine>"; $player .= " <AdSystem>OpenX</AdSystem>\n"; $player .= " <AdTitle><![CDATA[{$adName}]]></AdTitle>\n"; $player .= " <Description><![CDATA[{$vastAdDescription}]]></Description>\n"; $player .= " <Impression>\n"; $player .= " <URL id=\"primaryAdServer\"><![CDATA[{$aOut['impressionUrl']}]]></URL>\n"; if (!empty($aOut['thirdPartyImpressionUrl'])) { $player .= " <URL id=\"secondaryAdServer\"><![CDATA[{$aOut['thirdPartyImpressionUrl']}]]></URL>\n"; } $player .= " </Impression>\n"; if (isset($aOut['companionMarkup'])) { if (!empty($aOut['companionClickUrl'])) { $CompanionClickThrough = " <CompanionClickThrough>\n"; $CompanionClickThrough .= " <URL><![CDATA[{$aOut['companionClickUrl']}]]></URL>\n"; $CompanionClickThrough .= " </CompanionClickThrough>\n"; } //debugdump( '$companionOutput', $companionOutput ); $player .= " <CompanionAds>\n"; $player .= " <Companion id=\"companion\" width=\"{$aOut['companionWidth']}\" height=\"{$aOut['companionHeight']}\" resourceType=\"HTML\">\n"; $player .= " <Code><![CDATA[{$aOut['companionMarkup']}]]></Code>\n"; $player .= "\t\t\t\t\t{$CompanionClickThrough}"; $player .= " </Companion>\n"; $player .= " </CompanionAds>\n"; } if ($pluginType == 'vastOverlay') { $code = $resourceType = $creativeType = $elementName = ''; switch ($aOut['overlayFormat']) { case VAST_OVERLAY_FORMAT_HTML: $code = "<![CDATA[" . $aOut['overlayMarkupTemplate'] . "]]>"; $resourceType = 'HTML'; $elementName = 'Code'; break; case VAST_OVERLAY_FORMAT_IMAGE: $creativeType = strtoupper($aOut['overlayContentType']); // BC when the overlay_creative_type field is not set in the DB if (empty($creativeType)) { $creativeType = strtoupper(substr($aOut['overlayFilename'], -3)); // case of .jpeg files OXPL-493 if ($creativeType == 'PEG') { $creativeType = 'JPEG'; } } if ($creativeType == 'JPEG') { $creativeType = 'JPG'; } $creativeType = 'image/' . $creativeType; $code = getImageUrlFromFilename($aOut['overlayFilename']); $resourceType = 'static'; $elementName = 'URL'; break; case VAST_OVERLAY_FORMAT_SWF: $creativeType = 'application/x-shockwave-flash'; $code = getImageUrlFromFilename($aOut['overlayFilename']); $resourceType = 'static'; $elementName = 'URL'; break; case VAST_OVERLAY_FORMAT_TEXT: $resourceType = 'TEXT'; $code = "<![CDATA[\n \t<Title>" . xmlspecialchars($aOut['overlayTextTitle']) . "</Title>\n \t\t<Description>" . xmlspecialchars($aOut['overlayTextDescription']) . "</Description>\n \t\t<CallToAction>" . xmlspecialchars($aOut['overlayTextCall']) . "</CallToAction>\n \t\t]]>\n "; $elementName = 'Code'; break; } if (!empty($aOut['clickUrl'])) { $nonLinearClickThrough = "<NonLinearClickThrough>\n <URL><![CDATA[{$aOut['clickUrl']}]]></URL>\n </NonLinearClickThrough>\n"; } $creativeTypeAttribute = ''; if (!empty($creativeType)) { $creativeType = strtolower($creativeType); $creativeTypeAttribute = 'creativeType="' . $creativeType . '"'; } $player .= " <NonLinearAds>\n"; $player .= " <NonLinear id=\"overlay\" width=\"{$aOut['overlayWidth']}\" height=\"{$aOut['overlayHeight']}\" resourceType=\"{$resourceType}\" {$creativeTypeAttribute}>\n"; $player .= " <{$elementName}>\n \t\t\t\t\t\t\t\t\t{$code}\n \t\t\t\t\t\t\t\t</{$elementName}>\n"; $player .= " {$nonLinearClickThrough}"; $player .= " </NonLinear>\n"; $player .= " </NonLinearAds>\n"; } if (isset($aOut['fullPathToVideo'])) { $player .= getVastVideoAdOutput($aOut); } $player .= " </InLine>\n"; $player .= " </Ad>\n"; return $player; }
function begin_document($path) { global $PHP_SELF, $base_url, $id_pool, $assessments, $basepath, $collection, $document, $phpext; // print "$basepath"; $id = get_full_path($basepath, $path); if ($document[$id]) { $a =& $document[$id]; if ($a[1]) { print "<span style=\"padding: 2px; border: 1px dashed blue\" title=\"in pool\">"; } else { print "<span>"; } switch ($a[0]) { case "0": print "<img style=\"vertical-align: center;\" src=\"{$base_url}/img/mode_highlight\" title=\"highlighting mode\" alt=\"[highlighting]\"/>"; break; case "1": print "<img style=\"vertical-align: center;\" src=\"{$base_url}/img/nok\" title=\"assessing mode (not validated)\" alt=\"[assessing]\"/>"; break; case "2": print "<img style=\"vertical-align: center;\" src=\"{$base_url}/img/ok\" title=\"assessing mode (validated)\" alt=\"[validated]\"/>"; break; } print "</span> "; } print "<a id='" . xmlspecialchars($id) . "'" . ($a[1] ? " name='toAssess'" : "") . " href=\"{$base_url}/article{$phpext}?collection={$collection}&id_pool={$id_pool}&file={$id}\">"; }
/** Create the form from a set metadata. Called by the class' constructor. @param $oSet The set to build the form for. */ protected function loadFromSet($oSet) { $aMeta = $oSet->getMeta(); $aRefSets = $this->loadRefSets($oSet); $this->oXML = simplexml_load_string('<form><method>' . xmlspecialchars(array_value($this->aOptions, 'method', 'post')) . '</method><widgets><widget type="fieldset"/></widgets></form>'); foreach ($aMeta['colsobj'] as $oCol) { $sColumn = $oCol->name(); // Ignore given columns if (in_array($sColumn, $this->aOptions['ignorecolumns'])) { continue; } if (!empty($aRefSets[$sColumn])) { $this->addWidget('choice', $oCol); $sLabelColumn = $aRefSets[$sColumn]['key']; foreach ($aRefSets[$sColumn]['meta']['columns'] as $sRefColumn) { if (strpos($sRefColumn, 'label') !== false) { $sLabelColumn = $sRefColumn; break; } } $oHelper = $this->helper('weeFormOptionsHelper', $sColumn); $oHelper->addOption(array('label' => 'NULL', 'value' => '')); foreach ($aRefSets[$sColumn]['set']->fetchAll() as $aRow) { $oHelper->addOption(array('label' => $aRow[$sLabelColumn], 'value' => $aRow[$aRefSets[$sColumn]['key']])); } } else { $sWidget = 'textbox'; if (in_array($sColumn, $aMeta['primary']) && empty($this->aOptions['show-pkey'])) { if ($this->aOptions['action'] != 'update') { continue; } $sWidget = 'hidden'; } elseif (strpos($sColumn, '_is_')) { $sWidget = 'checkbox'; } elseif (strpos($sColumn, 'password')) { $sWidget = 'password'; } $this->addWidget($sWidget, $oCol); } } $oFieldset = $this->oXML->widgets->widget->addChild('widget'); $oFieldset->addAttribute('type', 'fieldset'); $oFieldset->addChild('class', 'buttonsfieldset'); if ($this->aOptions['action'] == 'update') { $oButton = $oFieldset->addChild('widget'); $oButton->addAttribute('type', 'resetbutton'); } $oButton = $oFieldset->addChild('widget'); $oButton->addAttribute('type', 'submitbutton'); }
/** Encode a given value. @param $mValue The value to encode. @return string The encoded value. */ public function encode($mValue) { return xmlspecialchars($mValue); }
/** Select elements in the XML document. @param $sSelect The selector. @param $oDocument The XML document. @param $oXPath The XPATH object for this document. @return DOMNodeList The selected elements. */ protected function select($sSelect, DOMDocument $oDocument, DOMXPath $oXPath) { if ($sSelect[0] == '#') { return $oXPath->query('//*[@id="' . xmlspecialchars(substr($sSelect, 1)) . '"]'); } if (strpos($sSelect, '/') !== false) { return $oXPath->query($sSelect); } return $oDocument->getElementsByTagName($sSelect); }
public static function xml_pretty_printer($xml, $html_output = FALSE) { $xml_obj = new SimpleXMLElement($xml); $xml_lines = explode("\n", str_replace("><", ">\n<", $xml_obj->asXML())); $indent_level = 0; $new_xml_lines = array(); foreach ($xml_lines as $xml_line) { if (preg_match('#^(<[a-z0-9_:-]+((\\s+[a-z0-9_:-]+="[^"]+")*)?>.*<\\s*/\\s*[^>]+>)|(<[a-z0-9_:-]+((\\s+[a-z0-9_:-]+="[^"]+")*)?\\s*/\\s*>)#i', ltrim($xml_line))) { $new_line = str_pad('', $indent_level * 4) . ltrim($xml_line); $new_xml_lines[] = $new_line; # $new_xml_lines[] = "Didn't increment 1."; } elseif (preg_match('#^<[a-z0-9_:-]+((\\s+[a-z0-9_:-]+="[^"]+")*)?>#i', ltrim($xml_line))) { $new_line = str_pad('', $indent_level * 4) . ltrim($xml_line); $indent_level++; $new_xml_lines[] = $new_line; # $new_xml_lines[] = "Increment."; } elseif (preg_match('#<\\s*/\\s*[^>/]+>#i', $xml_line)) { $indent_level--; if (trim($new_xml_lines[sizeof($new_xml_lines) - 1]) == trim(str_replace("/", "", $xml_line))) { $new_xml_lines[sizeof($new_xml_lines) - 1] .= $xml_line; # $new_xml_lines[] = "Decrement 1."; } else { $new_line = str_pad('', $indent_level * 4) . $xml_line; $new_xml_lines[] = $new_line; # $new_xml_lines[] = "Decrement 2."; } } else { $new_line = str_pad('', $indent_level * 4) . $xml_line; $new_xml_lines[] = $new_line; # $new_xml_lines[] = "Didn't increment 2."; } } $xml = join("\n", $new_xml_lines); return $html_output ? '<pre>' . xmlspecialchars($xml) . '</pre>' : $xml; }
/** * Input: the data (in string form) from the polling locations file. * Returns the feed contents for polling locations */ function addLocations($datastr) { addLogMessage("Start Locations"); $locArray = parseCSV($datastr); $str = ""; $savedID = -1; $savedName = ""; foreach ($locArray as $loc) { $curID = $loc[0]; $curName = $loc[2]; if (strlen($curID) > 0 && strcmp($curID, "ID") != 0 && strcmp(trim($curName), "MAIL BALLOT PRECINCT") != 0) { if ($savedID != $curID) { $str .= "<polling_location id=\"" . $curID . "\">"; $str .= "<address>"; $str .= " <location_name>" . xmlspecialchars($loc[2]) . "</location_name>"; $str .= " <line1>" . xmlspecialchars($loc[3]) . "</line1>"; $str .= " <city>" . xmlspecialchars($loc[4]) . "</city>"; $str .= " <state>NM</state>"; $str .= " <zip>" . xmlspecialchars($loc[5]) . "</zip>"; $str .= "</address>"; $str .= "<directions>" . xmlspecialchars(trim($loc[6])) . "</directions>"; $str .= "</polling_location>\n"; } } $savedID = $curID; $savedName = $curName; } addLogMessage("End Locations"); return $str; }
public function buildQTI($data = null) { if (!is_null($data)) { $this->data = $data; } if (empty($this->data)) { return false; } // container element and other metadata $ai = $this->initialXML(); // response declarations for ($q = 0; array_key_exists("question_{$q}_prompt", $this->data); $q++) { $rd = $ai->addChild("responseDeclaration"); $rd->addAttribute("identifier", "RESPONSE_question_{$q}"); $rd->addAttribute("cardinality", "multiple"); $rd->addAttribute("baseType", "identifier"); // build array of correct responses $correct = array(); for ($o = 0; array_key_exists("option_{$o}_optiontext", $this->data); $o++) { if (isset($this->data["question_{$q}_option_{$o}_correct"])) { $correct[] = $o; } } // add correctResponse node only if any options are correct if (!empty($correct)) { $rd->addChild("correctResponse"); foreach ($correct as $o) { $rd->correctResponse->addChild("value", "question_{$q}_option_{$o}"); } } } // outcome declaration $od = $ai->addChild("outcomeDeclaration"); $od->addAttribute("identifier", "SCORE"); $od->addAttribute("cardinality", "single"); $od->addAttribute("baseType", "integer"); $od->addChild("defaultValue"); $od->defaultValue->addChild("value", "0"); // item body $ib = $ai->addChild("itemBody"); // get stimulus and add to the XML tree if (isset($this->data["stimulus"]) && !empty($this->data["stimulus"])) { $this->data["stimulus"] = wrapindiv($this->data["stimulus"]); // parse it as XML $stimulus = stringtoxml($this->data["stimulus"], "stimulus"); if (is_array($stimulus)) { // errors $this->errors[] = "Stimulus is not valid XML. It must not only be valid XML but valid QTI, which accepts a subset of XHTML. Details on specific issues follow:"; $this->errors = array_merge($this->errors, $stimulus); } else { simplexml_append($ib, $stimulus); } } // div with class eqiat-emi $d = $ib->addChild("div"); $d->addAttribute("class", "eqiat-emi"); // list the options $options = ""; for ($o = 0; array_key_exists("option_{$o}_optiontext", $this->data); $o++) { $options .= "<li>" . xmlspecialchars($this->data["option_{$o}_optiontext"]) . "</li>"; } simplexml_append($d, simplexml_load_string('<ol class="emioptions">' . $options . '</ol>')); // questions for ($q = 0; array_key_exists("question_{$q}_prompt", $this->data); $q++) { $ci = $d->addChild("choiceInteraction"); $ci->addAttribute("maxChoices", "0"); $ci->addAttribute("minChoices", "0"); $ci->addAttribute("shuffle", "false"); $ci->addAttribute("responseIdentifier", "RESPONSE_question_{$q}"); $ci->addChild("prompt", $this->data["question_{$q}_prompt"]); for ($o = 0; array_key_exists("option_{$o}_optiontext", $this->data); $o++) { $sc = $ci->addChild("simpleChoice", chr(ord("A") + $o)); $sc->addAttribute("identifier", "question_{$q}_option_{$o}"); } } // response processing $rp = $ai->addChild("responseProcessing"); // set score = 0 $sov = $rp->addChild("setOutcomeValue"); $sov->addAttribute("identifier", "SCORE"); $sov->addChild("baseValue", "0")->addAttribute("baseType", "integer"); for ($q = 0; array_key_exists("question_{$q}_prompt", $this->data); $q++) { $rc = $rp->addChild("responseCondition"); // if $ri = $rc->addChild("responseIf"); // build array of correct responses $correct = array(); for ($o = 0; array_key_exists("option_{$o}_optiontext", $this->data); $o++) { if (isset($this->data["question_{$q}_option_{$o}_correct"])) { $correct[] = $o; } } // criteria for a correct answer if (empty($correct)) { // multiple response in which the correct response is to tick no // boxes -- check number of responses is equal to zero $e = $ri->addChild("equal"); $e->addAttribute("toleranceMode", "exact"); $e->addChild("containerSize")->addChild("variable")->addAttribute("identifier", "RESPONSE_question_{$q}"); $e->addChild("baseValue", "0")->addAttribute("baseType", "integer"); } else { // otherwise, we match responses to the correctResponse above $m = $ri->addChild("match"); $m->addChild("variable")->addAttribute("identifier", "RESPONSE_question_{$q}"); $m->addChild("correct")->addAttribute("identifier", "RESPONSE_question_{$q}"); } // increment score $sov = $ri->addChild("setOutcomeValue"); $sov->addAttribute("identifier", "SCORE"); $s = $sov->addChild("sum"); $s->addChild("variable")->addAttribute("identifier", "SCORE"); $s->addChild("baseValue", "1")->addAttribute("baseType", "integer"); } if (!empty($this->errors)) { return false; } // validate the QTI validateQTI($ai, $this->errors, $this->warnings, $this->messages); if (!empty($this->errors)) { return false; } $this->qti = $ai; return $this->qti; }