$permissions['allowobjectembed'] = new configvar (get_string('configallowobjectembed', 'admin'),
choose_from_menu ($noyesoptions, 'allowobjectembed', $config->allowobjectembed, '', '', '', true) );
+/// enabletrusttext
+ $permissions['enabletrusttext'] = new configvar (get_string('configenabletrusttext', 'admin'),
+ choose_from_menu ($noyesoptions, 'enabletrusttext', $config->enabletrusttext, '', '', '', true) );
unset($options);
$options['none'] = 'No courses';
$temp->add(new admin_setting_configtext('maxbytes', get_string('maxbytes', 'admin'), get_string('configmaxbytes', 'admin'), PARAM_INT));
$temp->add(new admin_setting_configcheckbox('messaging', get_string('messaging', 'admin'), get_string('configmessaging','admin')));
$temp->add(new admin_setting_configcheckbox('allowobjectembed', get_string('allowobjectembed', 'admin'), get_string('configallowobjectembed', 'admin')));
+$temp->add(new admin_setting_configcheckbox('enabletrusttext', get_string('enabletrusttext', 'admin'), get_string('configenabletrusttext', 'admin')));
$temp->add(new admin_setting_configselect('maxeditingtime', get_string('maxeditingtime','admin'), get_string('configmaxeditingtime','admin'), array(60 => get_string('numminutes', '', 1),
300 => get_string('numminutes', '', 5),
900 => get_string('numminutes', '', 15),
)
),
+ 'moodle/site:trustcontent' => array(
+
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'legacy' => array(
+ 'guest' => CAP_PREVENT,
+ 'student' => CAP_PREVENT,
+ 'teacher' => CAP_PREVENT,
+ 'editingteacher' => CAP_ALLOW,
+ 'coursecreator' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ )
+ ),
+
'moodle/user:create' => array(
'captype' => 'write',
'enablecourserequests' => 0,
'enablerssfeeds' => 0,
'enablestats' => 0,
+ 'enabletrusttext' => 0,
'enrol' => 'internal',
'extendedusernamechars' => false,
'editorbackgroundcolor' => '#ffffff',
*/
define('FORMAT_MARKDOWN', '4'); // Markdown-formatted text http://daringfireball.net/projects/markdown/
+/**
+ * TRUSTTEXT marker - if present in text, text cleaning should be bypassed
+ */
+define('TRUSTTEXT', '#####TRUSTTEXT#####');
+
/**
* Allowed tags - string of html tags that can be tested against for safe html tags
* @return string
* @todo Finish documenting this function
*/
-function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL ) {
+function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
global $CFG, $course;
+ if (!isset($options->trusttext)) {
+ $options->trusttext = false;
+ }
+
if (!isset($options->noclean)) {
$options->noclean=false;
}
if (!empty($CFG->cachetext)) {
$time = time() - $CFG->cachetext;
- $md5key = md5($text.'-'.$courseid.$options->noclean.$options->smiley.$options->filter.$options->para.$options->newlines.$format.current_language().$courseid);
+ $md5key = md5($text.'-'.$courseid.$options->noclean.$options->smiley.$options->filter.$options->para.$options->newlines.$format.current_language().$courseid.$options->trusttext);
if ($oldcacheitem = get_record_sql('SELECT * FROM '.$CFG->prefix.'cache_text WHERE md5key = \''.$md5key.'\'', true)) {
if ($oldcacheitem->timemodified >= $time) {
return $oldcacheitem->formattedtext;
}
}
+ // trusttext overrides the noclean option!
+ if ($options->trusttext) {
+ if (trusttext_present($text)) {
+ $text = trusttext_strip($text);
+ if (!empty($CFG->enabletrusttext)) {
+ $options->noclean = true;
+ } else {
+ $options->noclean = false;
+ }
+ } else {
+ $options->noclean = false;
+ }
+ }
+
$CFG->currenttextiscacheable = true; // Default status - can be changed by any filter
switch ($format) {
case FORMAT_HTML:
- if (!empty($options->smiley)) {
+ if ($options->smiley) {
replace_smilies($text);
}
- if (empty($options->noclean)) {
+ if (!$options->noclean) {
$text = clean_text($text, $format);
}
- if (!empty($options->filter)) {
+ if ($options->filter) {
$text = filter_text($text, $courseid);
}
break;
case FORMAT_MARKDOWN:
$text = markdown_to_html($text);
- if (!empty($options->smiley)) {
+ if ($options->smiley) {
replace_smilies($text);
}
- if (empty($options->noclean)) {
+ if (!$options->noclean) {
$text = clean_text($text, $format);
}
- if (!empty($options->filter)) {
+ if ($options->filter) {
$text = filter_text($text, $courseid);
}
break;
default: // FORMAT_MOODLE or anything else
$text = text_to_html($text, $options->smiley, $options->para, $options->newlines);
- if (empty($options->noclean)) {
+ if (!$options->noclean) {
$text = clean_text($text, $format);
}
- if (!empty($options->filter)) {
+ if ($options->filter) {
$text = filter_text($text, $courseid);
}
break;
* @todo Finish documenting this function
*/
function filter_text($text, $courseid=NULL) {
-
global $CFG;
require_once($CFG->libdir.'/filterlib.php');
return $text;
}
+/**
+ * Is the text marked as trusted?
+ *
+ * @param string $text text to be searched for TRUSTTEXT marker
+ * @return boolean
+ */
+function trusttext_present($text) {
+ if (strpos($text, TRUSTTEXT) !== FALSE) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * This funtion MUST be called before the cleaning or any other
+ * function that modifies the data! We do not know the origin of trusttext
+ * in database, if it gets there in tweaked form we must not convert it
+ * to supported form!!!
+ *
+ * Please be carefull not to use stripslashes on data from database
+ * or twice stripslashes when processing data recieved from user.
+ *
+ * @param string $text text that may contain TRUSTTEXT marker
+ * @return text without any TRUSTTEXT marker
+ */
+function trusttext_strip($text) {
+ global $CFG;
+
+ while (true) { //removing nested TRUSTTEXT
+ $orig = $text;
+ $text = str_replace(TRUSTTEXT, '', $text);
+ if (strcmp($orig, $text) === 0) {
+ return $text;
+ }
+ }
+}
+
+/**
+ * Mark text as trusted, such text may contain any HTML tags because the
+ * normal text cleaning will be bypassed.
+ * Please make sure that the text comes from trusted user before storing
+ * it into database!
+ */
+function trusttext_mark($text) {
+ global $CFG;
+ if (!empty($CFG->enabletrusttext) and (strpos($text, TRUSTTEXT) === FALSE)) {
+ return TRUSTTEXT.$text;
+ } else {
+ return $text;
+ }
+}
+function trusttext_after_edit(&$text, $context) {
+ if (has_capability('moodle/site:trustcontent', $context)) {
+ $text = trusttext_mark($text);
+ } else {
+ $text = trusttext_strip($text);
+ }
+}
+
+function trusttext_prepare_edit(&$text, &$format, $usehtmleditor, $context) {
+ global $CFG;
+
+ $options = new object();
+ $options->smiley = false;
+ $options->filter = false;
+ if (!empty($CFG->enabletrusttext)
+ and has_capability('moodle/site:trustcontent', $context)
+ and trusttext_present($text)) {
+ $options->noclean = true;
+ } else {
+ $options->noclean = false;
+ }
+ $text = trusttext_strip($text);
+ if ($usehtmleditor) {
+ $text = format_text($text, $format, $options);
+ $format = FORMAT_HTML;
+ } else if (!$options->noclean){
+ $text = clean_text($text, $format);
+ }
+}
+
/**
* Given raw text (eg typed in by a user), this function cleans it up
* and removes any nasty tags that could mess up Moodle pages.
if (!isset($form->format)) {
$form->format = $defaultformat;
}
- if ($usehtmleditor) { //clean and convert before editing
- $options = new object();
- $options->smiley = false;
- $options->filter = false;
- $form->text = format_text($form->text, $form->format, $options);
- $form->format = FORMAT_HTML;
- }
+
+ trusttext_prepare_edit($form->text, $form->format, $usehtmleditor, $context)
+
?>
<form name="form" method="post" action="comment.php">
<table class="generalbox">
}
if ( $confirm and $form = data_submitted() ) {
- //$form->text = clean_text($form->text, $form->format);
+ trusttext_after_edit($form->text, $context);
$newentry->entryid = $entry->id;
$newentry->comment = $form->text;
if (!isset($newentry->format)) {
$newentry->format = $defaultformat;
}
- if ($usehtmleditor) { //clean and convert before editing
- $options = new object();
- $options->smiley = false;
- $options->filter = false;
- $newentry->definition = format_text($newentry->definition, $newentry->format, $options);
- $newentry->format = FORMAT_HTML;
- }
+
+ trusttext_prepare_edit($newentry->definition, $newentry->format, $usehtmleditor, $context)
+
?>
<form name="form" method="post" action="edit.php" enctype="multipart/form-data">
<table border="0" cellpadding="5">
}
if ( $confirm ) {
$form = data_submitted();
+ trusttext_after_edit($form->text, $context);
+
if ( !isset($form->usedynalink) ) {
$form->usedynalink = 0;
}
$newentry->userid = $form->userid;
$newentry->timecreated = $form->timecreated;
+
if ( $aliases = get_records("glossary_alias","entryid",$e) ) {
foreach ($aliases as $alias) {
$newentry->aliases .= $alias->alias . "\n";
include("tabs.html");
if (!$e) {
- require_capability('glossary_write', $context);
+ require_capability('mod/glossary:write', $context);
}
include("edit.html");
$xmlentry = $xmlentries[$i];
unset($newentry);
$newentry->concept = trim(addslashes($xmlentry['#']['CONCEPT'][0]['#']));
- $newentry->definition = addslashes($xmlentry['#']['DEFINITION'][0]['#']);
+ $newentry->definition = trusttext_strip(addslashes($xmlentry['#']['DEFINITION'][0]['#']));
if ( isset($xmlentry['#']['CASESENSITIVE'][0]['#']) ) {
$newentry->casesensitive = addslashes($xmlentry['#']['CASESENSITIVE'][0]['#']);
} else {
//Default (old) print format used if custom function doesn't exist in format
function glossary_print_entry_default ($entry) {
echo '<b>'. strip_tags($entry->concept) . ': </b>';
+
+ $definition = $entry->definition;
+
+ // always detect and strip TRUSTTEXT marker before processing and add+strip it afterwards!
+ if (trusttext_present($definition)) {
+ $ttpresent = true;
+ $definition = trusttext_strip($definition);
+ } else {
+ $ttpresent = false;
+ }
+
+ $definition = '<span class="nolink">' . strip_tags($definition) . '</span>';
+
+ // reconstruct the TRUSTTEXT properly after processing
+ if ($ttpresent) {
+ $definition = trusttext_mark($definition);
+ } else {
+ $definition = trusttext_strip($definition); //make 100% sure TRUSTTEXT marker was not created
+ }
+
+ $options = new object();
$options->para = false;
- $definition = format_text('<span class="nolink">' . strip_tags($entry->definition) . '</span>', $entry->format,$options);
+ $options->trusttext = true;
+ $definition = format_text($definition, $entry->format, $options);
echo ($definition);
echo '<br /><br />';
}
function glossary_print_entry_concept($entry) {
+ $options = new object();
$options->para = false;
$text = format_text('<span class="nolink">' . $entry->concept . '</span>', FORMAT_MOODLE, $options);
if (!empty($entry->highlight)) {
$definition = $entry->definition;
+ // always detect and strip TRUSTTEXT marker before processing and add+strip it afterwards!
+ if (trusttext_present($definition)) {
+ $ttpresent = true;
+ $definition = trusttext_strip($definition);
+ } else {
+ $ttpresent = false;
+ }
+
$links = array();
$tags = array();
$urls = array();
$definition = str_replace(array_keys($links),$links,$definition);
}
+ $options = new object();
$options->para = false;
+ $options->trusttext = true;
+
+ // reconstruct the TRUSTTEXT properly after processing
+ if ($ttpresent) {
+ $definition = trusttext_mark($definition);
+ } else {
+ $definition = trusttext_strip($definition); //make 100% sure TRUSTTEXT marker was not created
+ }
- $text = format_text($definition, $entry->format,$options);
+ $text = format_text($definition, $entry->format, $options);
if (!empty($entry->highlight)) {
$text = highlight($entry->highlight, $text);
}
echo ' ';
echo '</td><td class="entry">';
- echo format_text($comment->comment, $comment->format);
+ $options = new object();
+ $options->trusttext = true;
+ echo format_text($comment->comment, $comment->format, $options);
echo '<div class="icons commands">';
if ( $entry->approved and $permissiongranted ) {
$co .= glossary_start_tag("ENTRY",3,true);
$co .= glossary_full_tag("CONCEPT",4,false,trim($entry->concept));
- $co .= glossary_full_tag("DEFINITION",4,false,$entry->definition);
+ $co .= glossary_full_tag("DEFINITION",4,false,trusttext_strip($entry->definition));
$co .= glossary_full_tag("FORMAT",4,false,$entry->format);
$co .= glossary_full_tag("USEDYNALINK",4,false,$entry->usedynalink);
$co .= glossary_full_tag("CASESENSITIVE",4,false,$entry->casesensitive);
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
- $version = 2006082300; // YYYYMMDD = date
+ $version = 2006082600; // YYYYMMDD = date
// XY = increments within a single day
$release = '1.7 dev'; // Human-friendly version name