Location: PHPKode > projects > Ps and Qs: Processing QTI using PHP > qti-eb/functionsfiles/gradeanswers.inc.php
<?php

$functionsmemory = array(); // Will store key->value pairs for things which want some persistence

//$functionsmemory['askconfidence'] = true;

$questiondisplaycount=0;
$sectiondisplaycount=0;


// print_r($_POST);

function shallWeSkip()
{
  global $functionsmemory;
  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(strlen($functionsmemory['choose']['assessment'])>0 && $functionsmemory['current']['assessment']!=$functionsmemory['choose']['assessment'])
    return true;
  if(strlen($functionsmemory['choose']['section'])>0 && $functionsmemory['current']['section']!=$functionsmemory['choose']['section'])
    return true;
  if(strlen($functionsmemory['choose']['item'])>0 && $functionsmemory['current']['item']!=$functionsmemory['choose']['item'])
    return true;
  if(strlen($functionsmemory['choose']['objectbank'])>0 && $functionsmemory['current']['objectbank']!=$functionsmemory['choose']['objectbank'])
    return true;
  return false;
}


// The following two functions are called before the start, and after the end, respectively,
//  of the QTI XML processing. Use them to wrap HTML around the whole output, for example.
function qtiEbVeryStart()
{
  global $submitted, $functionsmemory, $qtifilename; // In most cases $submitted will come from the webserver $_REQUEST data
  $functionsmemory['choose'] = $submitted['choose'];
  $functionsmemory['submitted'] = $submitted;
  $functionsmemory['itemfeedbacktodisplay'] = array(); // Response processing will add to this
  echo "\n<form method=\"post\" action=\"./\">\n";
/*
  if(is_array($functionsmemory['choose']))
    foreach($functionsmemory['choose'] as $k=>$v)
      echo "\n<input type=\"hidden\" name=\"choose[" . htmlspecialchars($k) 
	         . "]\" value=\"" . htmlspecialchars($v) . "\" />";
  ?>
  <input type="hidden" name="action" value="process" />
  <input type="hidden" name="processorfile" value="gradeanswers.inc.php" />
  <input type="hidden" name="filetoload" value="<?php echo $qtifilename ?>" />
  <?php
  */
}
function qtiEbVeryEnd()
{
  global $questiondisplaycount, $sectiondisplaycount;
//  echo "<p align=\"center\"><input type=\"submit\" value=\"Submit your answer" 
//       . (($questiondisplaycount>1 || $sectiondisplaycount>1)?'s':'') . "\" /></p>";
  echo "</form>";
}


// "and":
function qtiEbStartand($attrs, $context)
{
  global $functionsmemory;

  // We need to store an "and-context" which tells us the starting index of its range
  // in the $functionsmemory['current']['respcondition']['satisfied'][] array
  $functionsmemory['and-context'][] = array('startindex'=>sizeof($functionsmemory['current']['respcondition']['satisfied']));
}
function qtiEbDataand($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopand($context)
{
  global $functionsmemory;

  // The context tells us where in the 'satisfied' array we should start
  $andcontext = array_pop($functionsmemory['and-context']);
  
  // Work through the 'satisfied' array from the end back to the startindex, merging data in 'AND' fashion and removing the values
  $satisfied = true;
  while(sizeof($functionsmemory['current']['respcondition']['satisfied']) >= $andcontext['startindex'])
  {
    $last = array_pop($functionsmemory['current']['respcondition']['satisfied']);
	if($last === null) break;
    $satisfied = $satisfied && $last;
  }

  $functionsmemory['current']['respcondition']['satisfied'][$andcontext['startindex']] = $satisfied;
}
// ...end "and"


// "altmaterial":
function qtiEbStartaltmaterial($attrs, $context)
{
  global $functionsmemory;
  if($functionsmemory['displayaltmaterial']!=true)
    $functionsmemory['hidematerial'] = true;
}
function qtiEbDataaltmaterial($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopaltmaterial($context)
{
  global $functionsmemory;
  unset($functionsmemory['hidematerial']);
}
// ...end "altmaterial"


// "assessfeedback":
function qtiEbStartassessfeedback($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataassessfeedback($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopassessfeedback($context)
{
  global $functionsmemory;
}
// ...end "assessfeedback"


// "assessment":
function qtiEbStartassessment($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['assessment'] = $attrs['ident'];

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "<h1>Assessment $attrs[ident]</h1>";
}
function qtiEbDataassessment($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopassessment($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  unset($functionsmemory['current']['assessment']);
  echo "<hr noshade=\"noshade\" />";
}
// ...end "assessment"


// "assessmentcontrol":
function qtiEbStartassessmentcontrol($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataassessmentcontrol($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopassessmentcontrol($context)
{
  global $functionsmemory;
}
// ...end "assessmentcontrol"


// "assessproc_extension":
function qtiEbStartassessproc_extension($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataassessproc_extension($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopassessproc_extension($context)
{
  global $functionsmemory;
}
// ...end "assessproc_extension"


// "conditionvar":
function qtiEbStartconditionvar($attrs, $context)
{
  global $functionsmemory;
  // "conditionvar" is essentially just a container - the "respcondition" handler decides whether the condition is met
}
function qtiEbDataconditionvar($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopconditionvar($context)
{
  global $functionsmemory;

//  print_r($functionsmemory['current']['respcondition']['satisfied']);

  // One thing we need to do here is, if multiple conditions, conflate them using AND
  if(is_array($functionsmemory['current']['respcondition']['satisfied']))
  {
    if(sizeof($functionsmemory['current']['respcondition']['satisfied'])==0)
	  $satisfied = false;
	else
	{
      $satisfied = true;
      foreach($functionsmemory['current']['respcondition']['satisfied'] as $v)
        if(!$v)
	      $satisfied = false;
      $functionsmemory['current']['respcondition']['satisfied'] = $satisfied;
    }
//	echo "<p>Setting ['current']['respcondition']['satisfied'] to $satisfied</p>";
  }
}
// ...end "conditionvar"


// "decvar":
function qtiEbStartdecvar($attrs, $context)
{
  global $functionsmemory;
  // Take the variable's name (default SCORE)
  $varname = (strlen($attrs['varname'])>0) ? $attrs['varname'] : 'SCORE';
  // Take the variable's initial value (default 0)
  $functionsmemory['resprocessing'][$varname]['value'] = (isset($attrs['defaultval'])) ? $attrs['defaultval'] : 0;
  $functionsmemory['resprocessing'][$varname]['vartype'] = $attrs['vartype'];
  // Store other optional attributes if given
  if(isset($attrs['cutvalue'])) $functionsmemory['resprocessing'][$varname]['cutvalue'] = $attrs['cutvalue'];
  if(isset($attrs['minvalue'])) $functionsmemory['resprocessing'][$varname]['minvalue'] = $attrs['minvalue'];
  if(isset($attrs['maxvalue'])) $functionsmemory['resprocessing'][$varname]['maxvalue'] = $attrs['maxvalue'];
  if(isset($attrs['members'])) $functionsmemory['resprocessing'][$varname]['members'] = $attrs['members'];
}
function qtiEbDatadecvar($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopdecvar($context)
{
  global $functionsmemory;
}
// ...end "decvar"


// "displayfeedback":
function qtiEbStartdisplayfeedback($attrs, $context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

//  echo "<p>if(" . (($functionsmemory['current']['respcondition']['satisfied']===true)?'TRUE':'not true') . " == true)"
//    . " \$functionsmemory['itemfeedbacktodisplay'][$attrs[linkrefid]] = true</p>";
  if($functionsmemory['current']['respcondition']['satisfied'] == true)
    $functionsmemory['itemfeedbacktodisplay'][$attrs['linkrefid']] = true;
  else
    $functionsmemory['itemfeedbackNOTtodisplay'][$attrs['linkrefid']] = true;
	// This "else" is used simply because some feedback NEVER gets a "displayfeedback" specification
	//  - in this case it would NEVER get displayed, but actually we want to display it

}
function qtiEbDatadisplayfeedback($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopdisplayfeedback($context)
{
  global $functionsmemory;
}
// ...end "displayfeedback"


// "duration":
function qtiEbStartduration($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataduration($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopduration($context)
{
  global $functionsmemory;
}
// ...end "duration"


// "fieldentry":
function qtiEbStartfieldentry($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatafieldentry($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopfieldentry($context)
{
  global $functionsmemory;
}
// ...end "fieldentry"


// "fieldlabel":
function qtiEbStartfieldlabel($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatafieldlabel($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopfieldlabel($context)
{
  global $functionsmemory;
}
// ...end "fieldlabel"


// "flow":
function qtiEbStartflow($attrs, $context)
{
  global $functionsmemory;
  echo "\n<div class=\"flow\">";
}
function qtiEbDataflow($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopflow($context)
{
  global $functionsmemory;
  echo "\n</div>";
}
// ...end "flow"


// "flow_label":
function qtiEbStartflow_label($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataflow_label($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopflow_label($context)
{
  global $functionsmemory;
}
// ...end "flow_label"


// "flow_mat":
function qtiEbStartflow_mat($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataflow_mat($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopflow_mat($context)
{
  global $functionsmemory;
}
// ...end "flow_mat"


// "hint":
function qtiEbStarthint($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['materialcontext'] = 'hint';
}
function qtiEbDatahint($context, $data)
{
  global $functionsmemory;
}
function qtiEbStophint($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
}
// ...end "hint"


// "hintmaterial":
function qtiEbStarthintmaterial($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['materialcontext'] = 'hint';
}
function qtiEbDatahintmaterial($context, $data)
{
  global $functionsmemory;
}
function qtiEbStophintmaterial($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
}
// ...end "hintmaterial"


// "interpretvar":
function qtiEbStartinterpretvar($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['materialcontext'] = 'itemfeedback';
}
function qtiEbDatainterpretvar($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopinterpretvar($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
}
// ...end "interpretvar"


// "item":
function qtiEbStartitem($attrs, $context)
{
  global $functionsmemory, $questiondisplaycount;
  $functionsmemory['current']['item'] = $attrs['ident'];

  $questiondisplaycount++;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;
  echo "\n<fieldset style=\"margin: 10px; background:white;\"><legend style=\"background:white; border: 1px solid black;\"><strong>Item $questiondisplaycount</strong>"
             . (strlen($attrs['title'])>0 ? ': '.htmlspecialchars($attrs['title']):'')
			 . "<!-- ident: $attrs[ident] --></legend>";
}
function qtiEbDataitem($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitem($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "<div class=\"itemscore\" align=\"center\" style=\"font-weight: bold;\">Score for this item: " 
        . $functionsmemory['resprocessing']['SCORE']['value'] . "</div>";

  $functionsmemory['current']['section']['itemscores'][] = $functionsmemory['resprocessing']['SCORE']['value'];

  // The confidence-based-assessment element
  if($functionsmemory['askconfidence']==true)
  {
    $confidencesubmitted = $functionsmemory['submitted']['confidence'][$functionsmemory['current']['item']];
    echo "\n\n<div class=\"confidenceoptions\" style=\"border:1px solid gray; margin: 2px; text-align:right;\">"
	  . "<span style=\"color: rgb(51,51,51)\">Confidence level chosen:</span> ";
    if($confidencesubmitted==3)
	  echo "High";
    elseif($confidencesubmitted==2)
	  echo "Medium";
    else
	  echo "Low";
	echo "\n</div>";
  }

  echo "\n</fieldset>\n";

  unset($functionsmemory['current']['item']);
  unset($functionsmemory['resprocessing']);
  unset($functionsmemory['itemfeedback']);
  unset($functionsmemory['itemfeedbacktodisplay']);
}
// ...end "item"


// "itemcontrol":
function qtiEbStartitemcontrol($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitemcontrol($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemcontrol($context)
{
  global $functionsmemory;
}
// ...end "itemcontrol"


// "itemfeedback":
function qtiEbStartitemfeedback($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['materialcontext'] = 'itemfeedback';
  $functionsmemory['itemfeedback'] = $attrs;
  $functionsmemory['itemfeedback']['display'] 
             = ($functionsmemory['itemfeedbacktodisplay'][$attrs['linkrefid']]==true);
}
function qtiEbDataitemfeedback($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemfeedback($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
  unset($functionsmemory['itemfeedback']);
}
// ...end "itemfeedback"


// "itemmetadata":
function qtiEbStartitemmetadata($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitemmetadata($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemmetadata($context)
{
  global $functionsmemory;
}
// ...end "itemmetadata"


// "itempostcondition":
function qtiEbStartitempostcondition($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitempostcondition($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitempostcondition($context)
{
  global $functionsmemory;
}
// ...end "itempostcondition"


// "itemprecondition":
function qtiEbStartitemprecondition($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitemprecondition($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemprecondition($context)
{
  global $functionsmemory;
}
// ...end "itemprecondition"


// "itemproc_extension":
function qtiEbStartitemproc_extension($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitemproc_extension($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemproc_extension($context)
{
  global $functionsmemory;
}
// ...end "itemproc_extension"


// "itemref":
function qtiEbStartitemref($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataitemref($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemref($context)
{
  global $functionsmemory;
}
// ...end "itemref"


// "itemrubric":
function qtiEbStartitemrubric($attrs, $context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  $functionsmemory['materialcontext']='itemrubric';
  // echo "<div class=\"itemrubric\" style=\"background: silver; border: 1px solid black; padding: 10px; margin: 10px; \" >";
}
function qtiEbDataitemrubric($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopitemrubric($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  unset($functionsmemory['materialcontext']);
  // echo "</div>";
}
// ...end "itemrubric"


// "mat_extension":
function qtiEbStartmat_extension($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = true; // Can't handle, so we want ALT stuff
}
function qtiEbDatamat_extension($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmat_extension($context)
{
  global $functionsmemory;
}
// ...end "mat_extension"


// "matapplet":
function qtiEbStartmatapplet($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = true; // Can't handle, so we want ALT stuff
}
function qtiEbDatamatapplet($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatapplet($context)
{
  global $functionsmemory;
}
// ...end "matapplet"


// "matapplication":
function qtiEbStartmatapplication($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = true; // Can't handle, so we want ALT stuff
}
function qtiEbDatamatapplication($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatapplication($context)
{
  global $functionsmemory;
}
// ...end "matapplication"


// "mataudio":
function qtiEbStartmataudio($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = true; // Can't handle, so we want ALT stuff
}
function qtiEbDatamataudio($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmataudio($context)
{
  global $functionsmemory;
}
// ...end "mataudio"


// "matbreak":
function qtiEbStartmatbreak($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = false;
  echo "<p class=\"matbreak\" />&nbsp;</p>";
}
function qtiEbDatamatbreak($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatbreak($context)
{
  global $functionsmemory;
}
// ...end "matbreak"



// "matemtext":
function qtiEbStartmatemtext($attrs, $context)
{
  global $functionsmemory;
  qtiEbStartmatemtext($attrs, $context);
}
function qtiEbDatamatemtext($context, $data)
{
  global $functionsmemory;
  if($functionsmemory['materialcontext'] == 'interpretvar')
    return; // We're not interested in displaying interpretvar stuff 
//  if($functionsmemory['materialcontext'] == 'itemfeedback')
//    return;

  echo "\n\n<em>" . 
        ($functionsmemory['current']['mattexttype']=='text/html' ? $data : htmlspecialchars($data))
		. '</em>';
}
function qtiEbStopmatemtext($context)
{
  global $functionsmemory;
  qtiEbStopmatemtext($context);
}
// ...end "matemtext"


// "material":
function qtiEbStartmaterial($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatamaterial($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmaterial($context)
{
  global $functionsmemory;
}
// ...end "material"


// "material_ref":
function qtiEbStartmaterial_ref($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatamaterial_ref($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmaterial_ref($context)
{
  global $functionsmemory;
}
// ...end "material_ref"


// "matimage":
function qtiEbStartmatimage($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = false;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

//  if($functionsmemory['materialcontext'] == 'itemfeedback')
//    return;
  echo "<img src=\"$attrs[uri]\" width=\"$attrs[width]\" height=\"$attrs[height]\" border=\"1\" />";
}
function qtiEbDatamatimage($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatimage($context)
{
  global $functionsmemory;
}
// ...end "matimage"


// "matref":
function qtiEbStartmatref($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatamatref($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatref($context)
{
  global $functionsmemory;
}
// ...end "matref"


// "mattext":
function qtiEbStartmattext($attrs, $context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  $functionsmemory['displayaltmaterial'] = false;
  $functionsmemory['current']['mattexttype'] = $attrs['texttype'];

  if($functionsmemory['itemfeedbacktodisplay'][$functionsmemory['itemfeedback']['ident']])
    echo "<div style=\"background: yellow; margin: 1px; \">";
}
function qtiEbDatamattext($context, $data)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  // Ignore hinty stuff
  if($functionsmemory['materialcontext'] == 'hint' || 
     $functionsmemory['materialcontext'] == 'objectives' )
    return;

  // echo "<strong>MATTEXT</strong>";
  if(strlen($functionsmemory['itemfeedback']['ident'])>0 
              && !($functionsmemory['itemfeedbacktodisplay'][$functionsmemory['itemfeedback']['ident']])
              && ($functionsmemory['itemfeedbackNOTtodisplay'][$functionsmemory['itemfeedback']['ident']])
			  )
    return; 
 // elseif(strlen($functionsmemory['itemfeedback']['ident'])>0)
 // print_r($functionsmemory['itemfeedbacktodisplay']);

  echo "\n\n" . 
        ($functionsmemory['current']['mattexttype']=='text/html' ? $data : htmlspecialchars($data))
//        $context[sizeof($context)-1]->content[sizeof($context[sizeof($context)-1]->content)-1]
		. '';
}
function qtiEbStopmattext($context)
{
  global $functionsmemory;
 
  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

 if($functionsmemory['itemfeedbacktodisplay'][$functionsmemory['itemfeedback']['ident']])
    echo "</div>";
  unset($functionsmemory['current']['mattexttype']);
}
// ...end "mattext"


// "matvideo":
function qtiEbStartmatvideo($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['displayaltmaterial'] = true; // Can't handle, so we want ALT stuff
//  echo "<fieldset class=\"render_hotspot\" style=\"background:rgb(250,250,250); border: 2px solid black; margin: 5px;\" ><legend style=\"border: 1px solid black; background: rgb(255,204,204)\">QTI rendering warning: video material not supported!</legend>";
}
function qtiEbDatamatvideo($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopmatvideo($context)
{
  global $functionsmemory;
//  echo "</fieldset>";
}
// ...end "matvideo"


// "not":
function qtiEbStartnot($attrs, $context)
{
  global $functionsmemory;

  // We need to store an "and-context" which tells us the starting index of its range
  // in the $functionsmemory['current']['respcondition']['satisfied'][] array
  $functionsmemory['not-context'][] = array('startindex'=>sizeof($functionsmemory['current']['respcondition']['satisfied']));
}
function qtiEbDatanot($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopnot($context)
{
  global $functionsmemory;

  // The context tells us where in the 'satisfied' array we should start
  $notcontext = array_pop($functionsmemory['not-context']);
  
  // Work through the 'satisfied' array from the end back to the startindex, merging data in 'AND' fashion and removing the values
  $satisfied = true;
  while(sizeof($functionsmemory['current']['respcondition']['satisfied']) >= $notcontext['startindex'])
  {
    $last = array_pop($functionsmemory['current']['respcondition']['satisfied']);
	if($last === null) break;
    $satisfied = $satisfied && $last;
  }

  $functionsmemory['current']['respcondition']['satisfied'][$notcontext['startindex']] = !$satisfied;
}
// ...end "not"


// "objectbank":
function qtiEbStartobjectbank($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['objectbank'] = $attrs['ident'];
}
function qtiEbDataobjectbank($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopobjectbank($context)
{
  global $functionsmemory;
  unset($functionsmemory['current']['objectbank']);
}
// ...end "objectbank"


// "objectives":
function qtiEbStartobjectives($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['materialcontext'] = 'objectives';
}
function qtiEbDataobjectives($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopobjectives($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
}
// ...end "objectives"

// "or":
function qtiEbStartor($attrs, $context)
{
  global $functionsmemory;

  // We need to store an "or-context" which tells us the starting index of its range
  // in the $functionsmemory['current']['respcondition']['satisfied'][] array
  $functionsmemory['or-context'][] = array('startindex'=>sizeof($functionsmemory['current']['respcondition']['satisfied']));
}
function qtiEbDataor($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopor($context)
{
  global $functionsmemory;

  // The context tells us where in the 'satisfied' array we should start
  $orcontext = array_pop($functionsmemory['or-context']);
  
  // Work through the 'satisfied' array from the end back to the startindex, merging data in 'OR' fashion and removing the values
  $satisfied = false;
  while(sizeof($functionsmemory['current']['respcondition']['satisfied']) >= $orcontext['startindex'])
  {
    $last = array_pop($functionsmemory['current']['respcondition']['satisfied']);
	if($last === null) break;
    $satisfied = $satisfied || $last;
  }

  $functionsmemory['current']['respcondition']['satisfied'][$orcontext['startindex']] = $satisfied;
}
// ...end "or"


// "order":
function qtiEbStartorder($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataorder($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoporder($context)
{
  global $functionsmemory;
}
// ...end "order"


// "other":
function qtiEbStartother($attrs, $context)
{
  global $functionsmemory;
  
  if($functionsmemory['resprocessing']['anythingsatisfied']===false)
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
	$functionsmemory['resprocessing']['anythingsatisfied'] = true;
  }
}
function qtiEbDataother($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopother($context)
{
  global $functionsmemory;
}
// ...end "other"


// "outcomes":
function qtiEbStartoutcomes($attrs, $context)
{
  global $functionsmemory;
  
  // Initialise the default SCORE variable for the resprocessing block - i.e. for the item
  $functionsmemory['resprocessing']['SCORE']['value'] = 0;
}
function qtiEbDataoutcomes($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopoutcomes($context)
{
  global $functionsmemory;
}
// ...end "outcomes"


// "outcomes_processing":
function qtiEbStartoutcomes_processing($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataoutcomes_processing($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopoutcomes_processing($context)
{
  global $functionsmemory;
}
// ...end "outcomes_processing"


// "presentation":
function qtiEbStartpresentation($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatapresentation($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoppresentation($context)
{
  global $functionsmemory;
}
// ...end "presentation"


// "presentation_material":
function qtiEbStartpresentation_material($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatapresentation_material($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoppresentation_material($context)
{
  global $functionsmemory;
}
// ...end "presentation_material"

// "qmd_itemtype":
function qtiEbStartqmd_itemtype($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_itemtype($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_itemtype($context)
{
  global $functionsmemory;
}
// ...end "qmd_itemtype"


// "qmd_levelofdifficulty":
function qtiEbStartqmd_levelofdifficulty($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_levelofdifficulty($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_levelofdifficulty($context)
{
  global $functionsmemory;
}
// ...end "qmd_levelofdifficulty"


// "qmd_maximumscore":
function qtiEbStartqmd_maximumscore($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_maximumscore($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_maximumscore($context)
{
  global $functionsmemory;
}
// ...end "qmd_maximumscore"


// "qmd_minimumscore":
function qtiEbStartqmd_minimumscore($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_minimumscore($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_minimumscore($context)
{
  global $functionsmemory;
}
// ...end "qmd_minimumscore"


// "qmd_status":
function qtiEbStartqmd_status($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_status($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_status($context)
{
  global $functionsmemory;
}
// ...end "qmd_status"


// "qmd_weighting":
function qtiEbStartqmd_weighting($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_weighting($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_weighting($context)
{
  global $functionsmemory;
}
// ...end "qmd_weighting"


// "qmd_toolvendor":
function qtiEbStartqmd_toolvendor($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_toolvendor($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_toolvendor($context)
{
  global $functionsmemory;
}
// ...end "qmd_toolvendor"


// "qmd_topic":
function qtiEbStartqmd_topic($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqmd_topic($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqmd_topic($context)
{
  global $functionsmemory;
}
// ...end "qmd_topic"


// "qticomment":
function qtiEbStartqticomment($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqticomment($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopqticomment($context)
{
  global $functionsmemory;
}
// ...end "qticomment"


// "qtimetadata":
function qtiEbStartqtimetadata($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqtimetadata($context, $data)
{
  global $functionsmemory;
}

function qtiEbStopqtimetadata($context)
{
  global $functionsmemory;
}
// ...end "qtimetadata"


// "qtimetadatafield":
function qtiEbStartqtimetadatafield($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataqtimetadatafield($context, $data)
{
  global $functionsmemory;
}

function qtiEbStopqtimetadatafield($context)
{
  global $functionsmemory;
}
// ...end "qtimetadatafield"


// "questestinterop":
function qtiEbStartquestestinterop($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataquestestinterop($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopquestestinterop($context)
{
  global $functionsmemory;
}
// ...end "questestinterop"


// "reference":
function qtiEbStartreference($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatareference($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopreference($context)
{
  global $functionsmemory;
}
// ...end "reference"


// "render_choice":
function qtiEbStartrender_choice($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['render'] = 'choice';
  $functionsmemory['renderchoicemultiple'] = $attrs['maxnumber']>1;
}
function qtiEbDatarender_choice($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprender_choice($context)
{
  global $functionsmemory;
  unset($functionsmemory['render']);
  unset($functionsmemory['renderchoicemultiple']);
}
// ...end "render_choice"


// "render_fib":
function qtiEbStartrender_fib($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['render_fib'] = $attrs;
  $functionsmemory['render'] = 'fib';
  // Bizarrely, it seems the best way to render this stuff seems to be at the STOP rather than at the START
}
function qtiEbDatarender_fib($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprender_fib($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

//  print_r($functionsmemory['submitted']);

  if(!($functionsmemory['current']['render_fib']['rows']>1))
    echo "<input type=\"text\" name=\"" . $context[sizeof($context, $data)-1]->attributes['ident'] 
	           . "\" size=\"" . $functionsmemory['current']['render_fib']['columns'] 
			   . "\" maxlength=\"" . $functionsmemory['current']['render_fib']['maxchars'] 
			   . "\" disabled=\"true"
			   . "\" value=\"" . htmlspecialchars(stripslashes($functionsmemory['submitted'][str_replace('.','_',$context[sizeof($context)-1]->attributes['ident'])]))
			   . "\" />";
  else
    echo "<textarea name=\"" . $context[sizeof($context)-1]->attributes['ident'] 
	           . "\" cols=\"" . $functionsmemory['current']['render_fib']['columns'] 
			   . "\" rows=\"" . $functionsmemory['current']['render_fib']['rows'] 
			   . "\" disabled=\"true"
			   . "\" style=\"margin: 10px; \" />"
			   . htmlspecialchars(stripslashes($functionsmemory['submitted'][str_replace('.','_',$context[sizeof($context)-1]->attributes['ident'])]))
		       .  "</textarea>";
  unset($functionsmemory['current']['render_fib']);
  unset($functionsmemory['render']);
}
// ...end "render_fib"


// "render_hotspot":
function qtiEbStartrender_hotspot($attrs, $context)
{
  global $functionsmemory;
  if(shallWeSkip()) return;
  echo "<fieldset class=\"render_hotspot\" style=\"background:rgb(250,250,250); border: 2px solid black; margin: 5px;\" ><legend style=\"border: 1px solid black; background: rgb(255,204,204)\">QTI rendering warning: HOTSPOT response type not supported!</legend>";

}
function qtiEbDatarender_hotspot($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprender_hotspot($context)
{
  global $functionsmemory;
  if(shallWeSkip()) return;
  echo "</fieldset>";
}
// ...end "render_hotspot"


// "render_slider":
function qtiEbStartrender_slider($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['render'] = 'slider';
}
function qtiEbDatarender_slider($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprender_slider($context)
{
  global $functionsmemory;
  unset($functionsmemory['render']);
}
// ...end "render_slider"


// "respcondition":
function qtiEbStartrespcondition($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['respcondition'] = $attrs;
//  $functionsmemory['current']['respcondition']['satisfied'] = false;
  // This "satisfied" starts as an array so it can hold multiple values -
  //   but importantly, it gets conflated down to a single boolean using AND and OR
  $functionsmemory['current']['respcondition']['satisfied'] = array();
}
function qtiEbDatarespcondition($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprespcondition($context)
{
  global $functionsmemory;
  
  if($functionsmemory['current']['respcondition']['satisfied']===true)
    $functionsmemory['resprocessing']['anythingsatisfied'] = true; // So that <other/> doesn't kick in!
  
  unset($functionsmemory['current']['respcondition']);
}
// ...end "respcondition"

// "response_extension":
function qtiEbStartresponse_extension($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataresponse_extension($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_extension($context)
{
  global $functionsmemory;
}
// ...end "response_extension"


// "response_grp":
function qtiEbStartresponse_grp($attrs, $context)
{
  global $functionsmemory;
  echo "<div class=\"response_grp\" id=\"$attrs[ident]\" style=\"padding: 5px;\">";
  $functionsmemory['response']=$attrs; // This should work for _lid, _num, _xy, etc.
}
function qtiEbDataresponse_grp($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_grp($context)
{
  global $functionsmemory;
  unset($functionsmemory['response']);
  echo "</div>";
}
// ...end "response_grp"


// "response_label":
function qtiEbStartresponse_label($attrs, $context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

//  echo "<p>" . $functionsmemory['submitted'][$context[sizeof($context)-3]->attributes['ident']] . "==" . $attrs['ident'] . "</p>";
//  print_r($context[sizeof($context)-3]);
  echo "<label style=\"padding: 5px 15px;\">";
  if($functionsmemory['render']=='choice' && $functionsmemory['response_lid_rcardinality']=='Multiple')
  {
//   echo '<pre>';
//   print_r(str_replace('.','_',$attrs['ident']));
//   print_r($functionsmemory['submitted'][$functionsmemory['response_lid']]);
//   print_r(array_search(str_replace('.','_',$attrs['ident']), $functionsmemory['submitted'][$functionsmemory['response_lid']]) !== false);
//   echo '</pre>';
    echo "\n<input type=\"checkbox\" name=\"$functionsmemory[response_lid][]\" value=\"$attrs[ident]\" disabled=\"true\""
	         . (is_array($functionsmemory['submitted'][$functionsmemory['response_lid']]) && (array_search(str_replace('.','_',$attrs['ident']), $functionsmemory['submitted'][$functionsmemory['response_lid']]) !== false) ? ' checked="checked"': '')
			 . ">\n";
  }
  elseif($functionsmemory['render']=='choice')
    echo "\n<input type=\"radio\" name=\"$functionsmemory[response_lid]\" value=\"$attrs[ident]\" disabled=\"true\""
	         . ($functionsmemory['submitted'][str_replace('.','_',$context[sizeof($context)-3]->attributes['ident'])]==$attrs['ident'] ? ' checked="checked"': '')
	         . ">\n";
  elseif($functionsmemory['render']=='slider')
    echo "\n<select disabled=\"true\"><option>" 
	        . $functionsmemory['submitted'][str_replace('.','_',$context[sizeof($context)-3]->attributes['ident'])]
			. "</option></select>\n";
  elseif($functionsmemory['render']=='fib')
    ; // echo "<p>The response_label rendering device wants to render a FIB here....</p>";
	// DO WE NEED TO DO ANYTHING AT ALL? NOT SURE!
  else
  {
    echo "<p>ERROR - Unrecognised &quot;response_label&quot; type in file.</p><pre>";
	print_r($functionsmemory);
  }
}
function qtiEbDataresponse_label($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_label($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "\n</label>";
}
// ...end "response_label"


// "response_lid":
function qtiEbStartresponse_lid($attrs, $context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "<div class=\"response_lid\" id=\"$attrs[ident]\" style=\"padding: 5px;\">";
  $functionsmemory['response']=$attrs; // This should work for _lid, _num, _xy, etc.
  $functionsmemory['response_lid']=$attrs['ident'];
  $functionsmemory['response_lid_rcardinality']=$attrs['rcardinality'];
}
function qtiEbDataresponse_lid($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_lid($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  unset($functionsmemory['response']);
  unset($functionsmemory['response_lid']);
  echo "</div>";
}
// ...end "response_lid"


// "response_num":
function qtiEbStartresponse_num($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['response']=$attrs; // This should work for _lid, _num, _xy, etc.
}
function qtiEbDataresponse_num($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_num($context)
{
  global $functionsmemory;
  unset($functionsmemory['response']);
}
// ...end "response_num"


// "response_str":
function qtiEbStartresponse_str($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['response']=$attrs; // This should work for _lid, _num, _xy, etc.
}
function qtiEbDataresponse_str($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_str($context)
{
  global $functionsmemory;
  unset($functionsmemory['response']);
}
// ...end "response_str"


// "response_xy":
function qtiEbStartresponse_xy($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['response']=$attrs; // This should work for _lid, _num, _xy, etc.
  echo "\n<fieldset class=\"render_hotspot\" style=\"background:rgb(250,250,250); border: 2px solid black; margin: 5px;\" ><legend style=\"border: 1px solid black; background: rgb(255,204,204)\">QTI rendering warning: X-Y response type not supported!</legend>";
}
function qtiEbDataresponse_xy($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresponse_xy($context)
{
  global $functionsmemory;
  unset($functionsmemory['response']);
  echo "\n</fieldset>";
}
// ...end "response_xy"


// "resprocessing":
function qtiEbStartresprocessing($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['resprocessing'] = array(); // Holds, eg. 'SCORE'
  $functionsmemory['resprocessing']['showfeedback'] = array(); // Holds IDs of things we want shown
  $functionsmemory['resprocessing']['anythingsatisfied'] = false; // For use by the <other/> thingy
  $functionsmemory['resprocessing']['SCORE']['value'] = 0; // Initialised in <outcomes> too but let's make sure
}
function qtiEbDataresprocessing($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopresprocessing($context)
{
  global $functionsmemory;
  // unset($functionsmemory['resprocessing']); // DO NOT UNSET - the <item> will unset it once it's finished with it
}
// ...end "resprocessing"


// "rubric":
function qtiEbStartrubric($attrs, $context)
{
  global $functionsmemory;

  $functionsmemory['materialcontext']='rubric';
  echo "<div class=\"rubric\" style=\"background: silver; border: 1px solid black; padding: 10px;\" >";
}
function qtiEbDatarubric($context, $data)
{
  global $functionsmemory;
}
function qtiEbStoprubric($context)
{
  global $functionsmemory;
  unset($functionsmemory['materialcontext']);
  echo "</div>";
}
// ...end "rubric"


// "section":
function qtiEbStartsection($attrs, $context)
{
  global $functionsmemory, $sectiondisplaycount, $questiondisplaycount;
  $functionsmemory['current']['section'] = $attrs['ident'];

  $functionsmemory['current']['section']['itemscores'] = array();

  $questiondisplaycount = 0;
  $sectiondisplaycount++;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "<fieldset style=\"background:rgb(153,153,204)\"><legend style=\"background:white; border: 1px solid black;\"><strong>Section $sectiondisplaycount</strong>"
             . (strlen($attrs['title'])>0 ? ': '.htmlspecialchars($attrs['title']):'')
			 . "<!-- ident: $attrs[ident] --></legend>";
}
function qtiEbDatasection($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsection($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  echo "<div class=\"itemscore\" align=\"center\" style=\"font-weight: bold;\">Scores for this section: ";
  print_r($functionsmemory['current']['section']['itemscores']);
  echo "</div>";

  echo "</fieldset>";

  unset($functionsmemory['current']['section']);
}
// ...end "section"


// "sectioncontrol":
function qtiEbStartsectioncontrol($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectioncontrol($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectioncontrol($context)
{
  global $functionsmemory;
}
// ...end "sectioncontrol"


// "sectionfeedback":
function qtiEbStartsectionfeedback($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectionfeedback($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectionfeedback($context)
{
  global $functionsmemory;
}
// ...end "sectionfeedback"


// "sectionpostcondition":
function qtiEbStartsectionpostcondition($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectionpostcondition($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectionpostcondition($context)
{
  global $functionsmemory;
}
// ...end "sectionpostcondition"


// "sectionprecondition":
function qtiEbStartsectionprecondition($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectionprecondition($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectionprecondition($context)
{
  global $functionsmemory;
}
// ...end "sectionprecondition"


// "sectionproc_extension":
function qtiEbStartsectionproc_extension($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectionproc_extension($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectionproc_extension($context)
{
  global $functionsmemory;
}
// ...end "sectionproc_extension"


// "sectionref":
function qtiEbStartsectionref($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasectionref($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsectionref($context)
{
  global $functionsmemory;
}
// ...end "sectionref"


// "selection":
function qtiEbStartselection($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataselection($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopselection($context)
{
  global $functionsmemory;
}
// ...end "selection"


// "selection_ordering":
function qtiEbStartselection_ordering($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDataselection_ordering($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopselection_ordering($context)
{
  global $functionsmemory;
}
// ...end "selection_ordering"


// "sequence_parameter":
function qtiEbStartsequence_parameter($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasequence_parameter($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsequence_parameter($context)
{
  global $functionsmemory;
}
// ...end "sequence_parameter"


// "setvar":
function qtiEbStartsetvar($attrs, $context)
{
  global $functionsmemory;
  // Take the variable's name (default SCORE)
  $functionsmemory['setvar']['varname'] = (strlen($attrs['varname'])>0) ? $attrs['varname'] : 'SCORE';
  $functionsmemory['setvar']['action'] = (strlen($attrs['action'])>0) ? $attrs['action'] : 'Set';
  $functionsmemory['setvar']['data'] = '';
}
function qtiEbDatasetvar($context, $data)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  $functionsmemory['setvar']['data'] .= $data;
}
function qtiEbStopsetvar($context)
{
  global $functionsmemory;

  // If we only want one WHATEVER and it's not the current WHATEVER, skip
  if(shallWeSkip()) return;

  $varname = $functionsmemory['setvar']['varname'];

  // IMPORTANT! THIS SETVAR ACTION SHOULD ONLY BE TAKEN WHEN THE conditionvar CRITERIA ARE MET!
  if(!($functionsmemory['current']['respcondition']['satisfied'] == true))
  {
 //   echo "<p>respcondition not satisfied.</p>";
    return;
  }

//  echo "<p>&lt;setvar&gt; changed $varname from " . $functionsmemory['resprocessing'][$varname]['value'];

  if($functionsmemory['resprocessing'][$varname]['vartype']=='String'
       || $functionsmemory['resprocessing'][$varname]['vartype']=='Enumerated')
  {
    settype($functionsmemory['setvar']['data'], 'string');
    switch($functionsmemory['setvar']['action'])
    {
      case 'Add':
        $functionsmemory['resprocessing'][$varname]['value'] .= $functionsmemory['setvar']['data'];
	    break;
      case 'Subtract': // Makes no sense - just use "set" instead
      case 'Multiply': // Makes no sense - just use "set" instead
      case 'Divide': // Makes no sense - just use "set" instead
      default:
        $functionsmemory['resprocessing'][$varname]['value'] = $functionsmemory['setvar']['data'];
	    break;
    }
  }
  else
  {
    settype($functionsmemory['setvar']['data'], 'double');
    switch($functionsmemory['setvar']['action'])
    {
      case 'Add':
        $functionsmemory['resprocessing'][$varname]['value'] += $functionsmemory['setvar']['data'];
	    break;
      case 'Subtract':
        $functionsmemory['resprocessing'][$varname]['value'] -= $functionsmemory['setvar']['data'];
	    break;
      case 'Multiply':
        $functionsmemory['resprocessing'][$varname]['value'] *= $functionsmemory['setvar']['data'];
	    break;
      case 'Divide':
        $functionsmemory['resprocessing'][$varname]['value'] /= $functionsmemory['setvar']['data'];
	    break;
      default:
        $functionsmemory['resprocessing'][$varname]['value'] = $functionsmemory['setvar']['data'];
	    break;
    }
  }
//  echo " to " . $functionsmemory['resprocessing'][$varname]['value'] . "</p>";
  unset($functionsmemory['setvar']);
}
// ...end "setvar"


// "solution":
function qtiEbStartsolution($attrs, $context)
{
  global $functionsmemory;
  echo "\n<fieldset class=\"solution\" style=\"border: 1px solid rgb(0,102,0);\"><legend>Solution:</legend>";
}
function qtiEbDatasolution($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsolution($context)
{
  global $functionsmemory;
  echo "\n</fieldset>";
}
// ...end "solution"


// "solutionmaterial":
function qtiEbStartsolutionmaterial($attrs, $context)
{
  global $functionsmemory;
}
function qtiEbDatasolutionmaterial($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopsolutionmaterial($context)
{
  global $functionsmemory;
}
// ...end "solutionmaterial"

// "unanswered":
function qtiEbStartunanswered($attrs, $context)
{
  global $functionsmemory;
  
  if(!isset($functionsmemory['submitted'][$me->attributes['respident']])
     || ($functionsmemory['submitted'][$me->attributes['respident']] === '')
        )
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
}
function qtiEbDataunanswered($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopunanswered($context)
{
  global $functionsmemory;
}
// ...end "unanswered"


// "varequal":
function qtiEbStartvarequal($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['varequal'] = $context[sizeof($context)-1];
}
function qtiEbDatavarequal($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['varequal']->content[] = $data;
}
function qtiEbStopvarequal($context)
{
  global $functionsmemory;

  $me = $functionsmemory['current']['varequal'];

//  print_r($me);
//  echo "<p>if(" . $functionsmemory['submitted'][$me->attributes['respident']] . " == " . $me->content[0] . ")</p>";
  if(is_array($functionsmemory['submitted'][$me->attributes['respident']])
    && array_search($me->content[0], $functionsmemory['submitted'][$me->attributes['respident']])!==false)
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  elseif($functionsmemory['submitted'][$me->attributes['respident']] == $me->content[0])
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['varequal']);
}
// ...end "varequal"

// "varinside":
function qtiEbStartvarinside($attrs, $context)
{
  global $functionsmemory;
  echo "<p>QTI processor warning: \"varinside\" processing instruction not supported!</p>";
}
function qtiEbDatavarinside($context, $data)
{
  global $functionsmemory;
}
function qtiEbStopvarinside($context)
{
  global $functionsmemory;
}
// ...end "varinside"




// "varlt":
function qtiEbStartvarlt($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['varlt'] = $context[sizeof($context)-1];
}
function qtiEbDatavarlt($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['varlt']->content[] = $data;
}
function qtiEbStopvarlt($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['varlt'];
  if( ((float)($functionsmemory['submitted'][$me->attributes['respident']])) < ((float)($me->content[0])) )
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['varlt']);
}
// ...end "varlt"


// "varlte":
function qtiEbStartvarlte($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['varlte'] = $context[sizeof($context)-1];
}
function qtiEbDatavarlte($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['varlte']->content[] = $data;
}
function qtiEbStopvarlte($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['varlte'];
  if( ((float)($functionsmemory['submitted'][$me->attributes['respident']])) <= ((float)($me->content[0])) )
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['varlte']);
}
// ...end "varlte"


// "vargt":
function qtiEbStartvargt($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['vargt'] = $context[sizeof($context)-1];
}
function qtiEbDatavargt($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['vargt']->content[] = $data;
}
function qtiEbStopvargt($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['vargt'];
  if( ((float)($functionsmemory['submitted'][$me->attributes['respident']])) > ((float)($me->content[0])) )
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['vargt']);
}
// ...end "vargt"


// "vargte":
function qtiEbStartvargte($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['vargte'] = $context[sizeof($context)-1];
}
function qtiEbDatavargte($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['vargte']->content[] = $data;
}
function qtiEbStopvargte($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['vargte'];
  if( ((float)($functionsmemory['submitted'][$me->attributes['respident']])) >= ((float)($me->content[0])) )
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['vargte']);
}
// ...end "vargte"


// "varsubset":
function qtiEbStartvarsubset($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['varsubset'] = $context[sizeof($context)-1];
}
function qtiEbDatavarsubset($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['varsubset']->content[] = $data;
}
function qtiEbStopvarsubset($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['varsubset'];
  
  $set = explode(',', (string)($me->content[0]) );
  
  if(array_search((string)($functionsmemory['submitted'][$me->attributes['respident']]) , (string)($me->content[0]) ) !==false)
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['varsubset']);
}
// ...end "varsubset"


// "varsubstring":
function qtiEbStartvarsubstring($attrs, $context)
{
  global $functionsmemory;
  $functionsmemory['current']['varsubstring'] = $context[sizeof($context)-1];
}
function qtiEbDatavarsubstring($context, $data)
{
  global $functionsmemory;
  $functionsmemory['current']['varsubstring']->content[] = $data;
}
function qtiEbStopvarsubstring($context)
{
  global $functionsmemory;
  $me = $functionsmemory['current']['varsubstring'];
  
  if($me->attributes['case']=='Yes')
    $test = ((string)($functionsmemory['submitted'][$me->attributes['respident']])) == ((string)($me->content[0]));
  else
    $test = strtolower($functionsmemory['submitted'][$me->attributes['respident']]) == strtolower($me->content[0]);
  
  if($test)
  {
    $functionsmemory['current']['respcondition']['satisfied'][] = true;
  }
  else
    $functionsmemory['current']['respcondition']['satisfied'][] = false;
  unset($functionsmemory['current']['varsubstring']);
}
// ...end "varsubstring"
?>
Return current item: Ps and Qs: Processing QTI using PHP