Updated text conversion to read and store safe xml strings.
This commit is contained in:
committed by
Eloy Lafuente (stronk7)
parent
726a770949
commit
584f92962d
@@ -257,9 +257,9 @@ class cc2moodle {
|
||||
'[#date_now#]',
|
||||
'[#section_count#]');
|
||||
|
||||
$replace_values = array(htmlentities($course_title),
|
||||
htmlentities($course_short_name),
|
||||
htmlentities($course_description),
|
||||
$replace_values = array(entities::safexml($course_title),
|
||||
entities::safexml($course_short_name),
|
||||
entities::safexml($course_description),
|
||||
time(),
|
||||
$section_count);
|
||||
|
||||
@@ -565,7 +565,7 @@ class cc2moodle {
|
||||
}
|
||||
|
||||
$replace_values = array($instances[$i - 1]['instance'],
|
||||
htmlentities($instances[$i - 1]['title']),
|
||||
entities::safexml($instances[$i - 1]['title']),
|
||||
$user_info);
|
||||
|
||||
$instance .= str_replace($find_tags, $replace_values, $sheet);
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
|
||||
|
||||
class entities {
|
||||
/**
|
||||
*
|
||||
* Prepares convert for inclusion into XML
|
||||
* @param string $value
|
||||
*/
|
||||
public static function safexml($value) {
|
||||
$result = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'),
|
||||
ENT_NOQUOTES,
|
||||
'UTF-8',
|
||||
false);
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function prepare_content($content) {
|
||||
$result = $content;
|
||||
@@ -31,13 +43,12 @@ class entities {
|
||||
return '';
|
||||
}
|
||||
$encoding = null;
|
||||
$xml_error = new libxml_errors_mgr();
|
||||
$dom = new DOMDocument();
|
||||
try {
|
||||
if ($dom->loadHTML($content)) {
|
||||
$encoding = $dom->xmlEncoding;
|
||||
}
|
||||
} catch(DOMException $e) {
|
||||
//silence the exception if any
|
||||
$dom->validateOnParse = false;
|
||||
$dom->strictErrorChecking = false;
|
||||
if ($dom->loadHTML($content)) {
|
||||
$encoding = $dom->xmlEncoding;
|
||||
}
|
||||
if (empty($encoding)) {
|
||||
$encoding = mb_detect_encoding($content, 'auto', true);
|
||||
@@ -223,6 +234,7 @@ class entities {
|
||||
}
|
||||
|
||||
protected function get_all_files () {
|
||||
global $CFG;
|
||||
|
||||
$all_files = array();
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@ class cc_forum extends entities {
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
//To be more true to the actual forum name we use only forum title
|
||||
htmlentities($topic_data['title']),
|
||||
htmlentities($topic_data['description']),
|
||||
self::safexml($topic_data['title']),
|
||||
self::safexml($topic_data['description']),
|
||||
time());
|
||||
|
||||
$result = str_replace($find_tags, $replace_values, $sheet_mod_forum);
|
||||
|
||||
@@ -54,8 +54,8 @@ class cc_label extends entities {
|
||||
$title = isset($instance['title']) && !empty($instance['title']) ? $instance['title'] : 'Untitled';
|
||||
$content = "<img src=\"$@FILEPHP@$$@SLASH@$"."folder.gif\" alt=\"Folder\" title=\"{$title}\" /> {$title}";
|
||||
$replace_values = array($instance['instance'],
|
||||
$title,
|
||||
htmlentities($content),
|
||||
self::safexml($title),
|
||||
self::safexml($content),
|
||||
time());
|
||||
|
||||
return str_replace($find_tags, $replace_values, $sheet_mod_label);
|
||||
|
||||
@@ -140,10 +140,10 @@ class cc_quiz extends entities {
|
||||
'[#node_questions_feedback#]');
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
htmlentities($instance['title']),
|
||||
htmlentities($instance['title']),
|
||||
htmlentities($quiz_stamp),
|
||||
htmlentities($questions_strings),
|
||||
self::safexml($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
self::safexml($quiz_stamp),
|
||||
self::safexml($questions_strings),
|
||||
time(),
|
||||
$instance['options']['max_attempts'],
|
||||
$instance['options']['timelimit'],
|
||||
@@ -256,7 +256,7 @@ class cc_quiz extends entities {
|
||||
$quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
htmlentities($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
$quiz_stamp,
|
||||
$node_course_question_categories_questions);
|
||||
|
||||
@@ -304,10 +304,10 @@ class cc_quiz extends entities {
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node;
|
||||
|
||||
$replace_values = array($question['id'],
|
||||
htmlentities($this->truncate_text($question['title'], 255, true)),
|
||||
htmlentities($question['title']),
|
||||
self::safexml($this->truncate_text($question['title'], 255, true)),
|
||||
self::safexml($question['title']),
|
||||
$question_moodle_type,
|
||||
htmlentities($question['feedback']),
|
||||
self::safexml($question['feedback']),
|
||||
time(),
|
||||
$question_type_node,
|
||||
$quiz_stamp,
|
||||
@@ -764,7 +764,7 @@ class cc_quiz extends entities {
|
||||
'[#is_single#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
htmlentities($answer_string),
|
||||
self::safexml($answer_string),
|
||||
$is_single);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
@@ -819,8 +819,8 @@ class cc_quiz extends entities {
|
||||
'[#use_case#]',
|
||||
'[#node_course_question_categories_question_category_question_answer#]');
|
||||
|
||||
$replace_values = array(htmlentities($answers_string),
|
||||
htmlentities($use_case),
|
||||
$replace_values = array(self::safexml($answers_string),
|
||||
self::safexml($use_case),
|
||||
$node_course_question_categories_question_answer);
|
||||
|
||||
|
||||
@@ -866,7 +866,7 @@ class cc_quiz extends entities {
|
||||
'[#false_answer_id#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
htmlentities($true_answer_id),
|
||||
$true_answer_id,
|
||||
$false_answer_id);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
@@ -900,9 +900,9 @@ class cc_quiz extends entities {
|
||||
'[#answer_feedback#]');
|
||||
|
||||
$replace_values = array($answer['id'],
|
||||
htmlentities($answer['title']),
|
||||
self::safexml($answer['title']),
|
||||
$answer['score'],
|
||||
$answer['feedback']);
|
||||
self::safexml($answer['feedback']));
|
||||
|
||||
$node_question_categories_question_answer = str_replace($find_tags, $replace_values, $sheet_question_categories_question_answer);
|
||||
|
||||
|
||||
@@ -149,13 +149,13 @@ class cc_resource extends entities {
|
||||
//silence the complaints
|
||||
}
|
||||
chdir($cdir);
|
||||
$mod_alltext = htmlspecialchars($mod_alltext, ENT_COMPAT, 'UTF-8', false);
|
||||
$mod_alltext = self::safexml($mod_alltext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
htmlspecialchars($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
$mod_type,
|
||||
$mod_reference,
|
||||
'',
|
||||
|
||||
@@ -80,7 +80,7 @@ class cc11_basiclti extends entities11 {
|
||||
protected function getValue($node, $default = '') {
|
||||
$result = $default;
|
||||
if (is_object($node) && ($node->length > 0) && !empty($node->item(0)->nodeValue)) {
|
||||
$result = htmlentities(trim($node->item(0)->nodeValue));
|
||||
$result = htmlspecialchars(trim($node->item(0)->nodeValue), ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ class cc11_forum extends entities11 {
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
//To be more true to the actual forum name we use only forum title
|
||||
htmlentities($topic_data['title']),
|
||||
htmlentities($topic_data['description']),
|
||||
self::safexml($topic_data['title']),
|
||||
self::safexml($topic_data['description']),
|
||||
time());
|
||||
|
||||
$result = str_replace($find_tags, $replace_values, $sheet_mod_forum);
|
||||
|
||||
@@ -75,7 +75,7 @@ class cc11_lti extends entities11 {
|
||||
protected function getValue($node, $default = '') {
|
||||
$result = $default;
|
||||
if (is_object($node) && ($node->length > 0) && !empty($node->item(0)->nodeValue)) {
|
||||
$result = htmlentities(trim($node->item(0)->nodeValue));
|
||||
$result = htmlspecialchars(trim($node->item(0)->nodeValue), ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -140,10 +140,10 @@ class cc11_quiz extends entities11 {
|
||||
'[#node_questions_feedback#]');
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
htmlentities($instance['title']),
|
||||
htmlentities($instance['title']),
|
||||
htmlentities($quiz_stamp),
|
||||
htmlentities($questions_strings),
|
||||
self::safexml($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
self::safexml($quiz_stamp),
|
||||
self::safexml($questions_strings),
|
||||
time(),
|
||||
$instance['options']['max_attempts'],
|
||||
$instance['options']['timelimit'],
|
||||
@@ -256,7 +256,7 @@ class cc11_quiz extends entities11 {
|
||||
$quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
|
||||
|
||||
$replace_values = array($instance['id'],
|
||||
htmlentities($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
$quiz_stamp,
|
||||
$node_course_question_categories_questions);
|
||||
|
||||
@@ -304,10 +304,10 @@ class cc11_quiz extends entities11 {
|
||||
$question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node;
|
||||
|
||||
$replace_values = array($question['id'],
|
||||
htmlentities($this->truncate_text($question['title'], 255, true)),
|
||||
htmlentities($question['title']),
|
||||
self::safexml($this->truncate_text($question['title'], 255, true)),
|
||||
self::safexml($question['title']),
|
||||
$question_moodle_type,
|
||||
htmlentities($question['feedback']),
|
||||
self::safexml($question['feedback']),
|
||||
time(),
|
||||
$question_type_node,
|
||||
$quiz_stamp,
|
||||
@@ -764,7 +764,7 @@ class cc11_quiz extends entities11 {
|
||||
'[#is_single#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
htmlentities($answer_string),
|
||||
self::safexml($answer_string),
|
||||
$is_single);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
@@ -819,8 +819,8 @@ class cc11_quiz extends entities11 {
|
||||
'[#use_case#]',
|
||||
'[#node_course_question_categories_question_category_question_answer#]');
|
||||
|
||||
$replace_values = array(htmlentities($answers_string),
|
||||
htmlentities($use_case),
|
||||
$replace_values = array(self::safexml($answers_string),
|
||||
self::safexml($use_case),
|
||||
$node_course_question_categories_question_answer);
|
||||
|
||||
|
||||
@@ -866,7 +866,7 @@ class cc11_quiz extends entities11 {
|
||||
'[#false_answer_id#]');
|
||||
|
||||
$replace_values = array($node_course_question_categories_question_answer,
|
||||
htmlentities($true_answer_id),
|
||||
$true_answer_id,
|
||||
$false_answer_id);
|
||||
|
||||
$node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question);
|
||||
@@ -900,9 +900,9 @@ class cc11_quiz extends entities11 {
|
||||
'[#answer_feedback#]');
|
||||
|
||||
$replace_values = array($answer['id'],
|
||||
htmlentities($answer['title']),
|
||||
self::safexml($answer['title']),
|
||||
$answer['score'],
|
||||
$answer['feedback']);
|
||||
self::safexml($answer['feedback']));
|
||||
|
||||
$node_question_categories_question_answer = str_replace($find_tags, $replace_values, $sheet_question_categories_question_answer);
|
||||
|
||||
|
||||
@@ -157,13 +157,13 @@ class cc11_resource extends entities11 {
|
||||
//silence the complaints
|
||||
}
|
||||
chdir($cdir);
|
||||
$mod_alltext = htmlspecialchars($mod_alltext, ENT_COMPAT, 'UTF-8', false);
|
||||
$mod_alltext = self::safexml($mod_alltext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$replace_values = array($instance['instance'],
|
||||
htmlspecialchars($instance['title']),
|
||||
self::safexml($instance['title']),
|
||||
$mod_type,
|
||||
$mod_reference,
|
||||
'',
|
||||
|
||||
+12
-1
@@ -109,7 +109,14 @@ final class libxml_errors_mgr {
|
||||
* @var boolean
|
||||
*/
|
||||
private $previous = false;
|
||||
public function __construct(){
|
||||
|
||||
/**
|
||||
* @param boolean $reset
|
||||
*/
|
||||
public function __construct($reset=false){
|
||||
if ($reset) {
|
||||
error_messages::instance()->reset();
|
||||
}
|
||||
$this->previous = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
}
|
||||
@@ -146,6 +153,10 @@ final class libxml_errors_mgr {
|
||||
libxml_use_internal_errors($this->previous);
|
||||
}
|
||||
}
|
||||
|
||||
public function collect() {
|
||||
$this->collect_errors();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -103,12 +103,18 @@ class imscc1_converter extends base_converter {
|
||||
}
|
||||
$status = $cc2moodle->generate_moodle_xml();
|
||||
//Final cleanup
|
||||
$xml_error = new libxml_errors_mgr(true);
|
||||
$mdoc = new DOMDocument();
|
||||
$mdoc->preserveWhiteSpace = false;
|
||||
$mdoc->formatOutput = true;
|
||||
$mdoc->validateOnParse = false;
|
||||
$mdoc->strictErrorChecking = false;
|
||||
if ($mdoc->load($manifestdir.'/moodle.xml', LIBXML_NONET)) {
|
||||
$mdoc->save($this->get_workdir_path().'/moodle.xml', LIBXML_NOEMPTYTAG);
|
||||
} else {
|
||||
$xml_error->collect();
|
||||
$this->log('validation error(s): '.PHP_EOL.error_messages::instance(), backup::LOG_DEBUG, null, 2);
|
||||
throw new imscc1_convert_exception(error_messages::instance()->to_string(true));
|
||||
}
|
||||
//Move the files to the workdir
|
||||
rename($manifestdir.'/course_files', $this->get_workdir_path().'/course_files');
|
||||
|
||||
@@ -103,12 +103,18 @@ class imscc11_converter extends base_converter {
|
||||
}
|
||||
$status = $cc112moodle->generate_moodle_xml();
|
||||
//Final cleanup
|
||||
$xml_error = new libxml_errors_mgr(true);
|
||||
$mdoc = new DOMDocument();
|
||||
$mdoc->preserveWhiteSpace = false;
|
||||
$mdoc->formatOutput = true;
|
||||
$mdoc->validateOnParse = false;
|
||||
$mdoc->strictErrorChecking = false;
|
||||
if ($mdoc->load($manifestdir.'/moodle.xml', LIBXML_NONET)) {
|
||||
$mdoc->save($this->get_workdir_path().'/moodle.xml', LIBXML_NOEMPTYTAG);
|
||||
} else {
|
||||
$xml_error->collect();
|
||||
$this->log('validation error(s): '.PHP_EOL.error_messages::instance(), backup::LOG_DEBUG, null, 2);
|
||||
throw new imscc11_convert_exception(error_messages::instance()->to_string(true));
|
||||
}
|
||||
//Move the files to the workdir
|
||||
rename($manifestdir.'/course_files', $this->get_workdir_path().'/course_files');
|
||||
|
||||
Reference in New Issue
Block a user