You are here

class hotpot_xml_tree in Quiz 6.5

Same name and namespace in other branches
  1. 6.6 includes/moodle/question/format/hotpot/format.php \hotpot_xml_tree

Hierarchy

Expanded class hierarchy of hotpot_xml_tree

File

includes/moodle/question/format/hotpot/format.php, line 535

View source
class hotpot_xml_tree {
  function hotpot_xml_tree($str, $xml_root = '') {
    if (empty($str)) {
      $this->xml = array();
    }
    else {

      // encode htmlentities in JCloze
      $this
        ->encode_cdata($str, 'gap-fill');

      // xmlize (=convert xml to tree)
      $this->xml = xmlize($str, 0);
    }
    $this->xml_root = $xml_root;
  }
  function xml_value($tags, $more_tags = "[0]['#']") {
    $tags = empty($tags) ? '' : "['" . str_replace(",", "'][0]['#']['", $tags) . "']";
    eval('$value = &$this->xml' . $this->xml_root . $tags . $more_tags . ';');
    if (is_string($value)) {

      // decode angle brackets and ampersands
      $value = strtr($value, array(
        '&#x003C;' => '<',
        '&#x003E;' => '>',
        '&#x0026;' => '&',
      ));

      // remove white space between <table>, <ul|OL|DL> and <OBJECT|EMBED> parts
      // (so it doesn't get converted to <br />)
      $htmltags = '(' . 'TABLE|/?CAPTION|/?COL|/?COLGROUP|/?TBODY|/?TFOOT|/?THEAD|/?TD|/?TH|/?TR' . '|OL|UL|/?LI' . '|DL|/?DT|/?DD' . '|EMBED|OBJECT|APPLET|/?PARAM' . ')';
      $search = '#(<' . $htmltags . '[^>]*' . '>)\\s+' . '(?=' . '<' . ')#is';
      $value = preg_replace($search, '\\1', $value);

      // replace remaining newlines with <br />
      $value = str_replace("\n", '<br />', $value);

      // encode unicode characters as HTML entities
      // (in particular, accented charaters that have not been encoded by HP)
      // multibyte unicode characters can be detected by checking the hex value of the first character
      //    00 - 7F : ascii char (roman alphabet + punctuation)
      //    80 - BF : byte 2, 3 or 4 of a unicode char
      //    C0 - DF : 1st byte of 2-byte char
      //    E0 - EF : 1st byte of 3-byte char
      //    F0 - FF : 1st byte of 4-byte char
      // if the string doesn't match the above, it might be
      //    80 - FF : single-byte, non-ascii char
      $search = '#(' . '[\\xc0-\\xdf][\\x80-\\xbf]' . '|' . '[\\xe0-\\xef][\\x80-\\xbf]{2}' . '|' . '[\\xf0-\\xff][\\x80-\\xbf]{3}' . '|' . '[\\x80-\\xff]' . ')#se';
      $value = preg_replace($search, "hotpot_utf8_to_html_entity('\\1')", $value);
    }
    return $value;
  }
  function encode_cdata(&$str, $tag) {

    // conversion tables
    static $HTML_ENTITIES = array(
      '&apos;' => "'",
      '&quot;' => '"',
      '&lt;' => '<',
      '&gt;' => '>',
      '&amp;' => '&',
    );
    static $ILLEGAL_STRINGS = array(
      "\r" => '',
      "\n" => '&lt;br /&gt;',
      ']]>' => '&#93;&#93;&#62;',
    );

    // extract the $tag from the $str(ing), if possible
    $pattern = '|(^.*<' . $tag . '[^>]*)(>.*<)(/' . $tag . '>.*$)|is';
    if (preg_match($pattern, $str, $matches)) {

      // encode problematic CDATA chars and strings
      $matches[2] = strtr($matches[2], $ILLEGAL_STRINGS);

      // if there are any ampersands in "open text"
      // surround them by CDATA start and end markers
      // (and convert HTML entities to plain text)
      $search = '/>([^<]*&[^<]*)</e';
      $replace = '"><![CDATA[".strtr("$1", $HTML_ENTITIES)."]]><"';
      $matches[2] = preg_replace($search, $replace, $matches[2]);
      $str = $matches[1] . $matches[2] . $matches[3];
    }
  }

}

Members