Ejemplo n.º 1
0
/**
 * Given text in a variety of format codings, this function returns the text as safe HTML.
 *
 * This function should mainly be used for long strings like posts,
 * answers, glossary items etc. For short strings {@link format_string()}.
 *
 * <pre>
 * Options:
 *      trusted     :   If true the string won't be cleaned. Default false required noclean=true.
 *      noclean     :   If true the string won't be cleaned. Default false required trusted=true.
 *      nocache     :   If true the strign will not be cached and will be formatted every call. Default false.
 *      filter      :   If true the string will be run through applicable filters as well. Default true.
 *      para        :   If true then the returned string will be wrapped in div tags. Default true.
 *      newlines    :   If true then lines newline breaks will be converted to HTML newline breaks. Default true.
 *      context     :   The context that will be used for filtering.
 *      overflowdiv :   If set to true the formatted text will be encased in a div
 *                      with the class no-overflow before being returned. Default false.
 *      allowid     :   If true then id attributes will not be removed, even when
 *                      using htmlpurifier. Default false.
 * </pre>
 *
 * @staticvar array $croncache
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            [FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_MARKDOWN]
 * @param object/array $options text formatting options
 * @param int $courseiddonotuse deprecated course id, use context option instead
 * @return string
 */
function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseiddonotuse = null)
{
    global $CFG, $DB, $PAGE;
    if ($text === '' || is_null($text)) {
        // No need to do any filters and cleaning.
        return '';
    }
    // Detach object, we can not modify it.
    $options = (array) $options;
    if (!isset($options['trusted'])) {
        $options['trusted'] = false;
    }
    if (!isset($options['noclean'])) {
        if ($options['trusted'] and trusttext_active()) {
            // No cleaning if text trusted and noclean not specified.
            $options['noclean'] = true;
        } else {
            $options['noclean'] = false;
        }
    }
    if (!isset($options['nocache'])) {
        $options['nocache'] = false;
    }
    if (!isset($options['filter'])) {
        $options['filter'] = true;
    }
    if (!isset($options['para'])) {
        $options['para'] = true;
    }
    if (!isset($options['newlines'])) {
        $options['newlines'] = true;
    }
    if (!isset($options['overflowdiv'])) {
        $options['overflowdiv'] = false;
    }
    // Calculate best context.
    if (empty($CFG->version) or $CFG->version < 2013051400 or during_initial_install()) {
        // Do not filter anything during installation or before upgrade completes.
        $context = null;
    } else {
        if (isset($options['context'])) {
            // First by explicit passed context option.
            if (is_object($options['context'])) {
                $context = $options['context'];
            } else {
                $context = context::instance_by_id($options['context']);
            }
        } else {
            if ($courseiddonotuse) {
                // Legacy courseid.
                $context = context_course::instance($courseiddonotuse);
            } else {
                // Fallback to $PAGE->context this may be problematic in CLI and other non-standard pages :-(.
                $context = $PAGE->context;
            }
        }
    }
    if (!$context) {
        // Either install/upgrade or something has gone really wrong because context does not exist (yet?).
        $options['nocache'] = true;
        $options['filter'] = false;
    }
    if ($options['filter']) {
        $filtermanager = filter_manager::instance();
        $filtermanager->setup_page_for_filters($PAGE, $context);
        // Setup global stuff filters may have.
    } else {
        $filtermanager = new null_filter_manager();
    }
    switch ($format) {
        case FORMAT_HTML:
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => FORMAT_HTML, 'noclean' => $options['noclean']));
            break;
        case FORMAT_PLAIN:
            $text = s($text);
            // Cleans dangerous JS.
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;
        case FORMAT_WIKI:
            // This format is deprecated.
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>' . s($text);
            break;
        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => FORMAT_MARKDOWN, 'noclean' => $options['noclean']));
            break;
        default:
            // FORMAT_MOODLE or anything else.
            $text = text_to_html($text, null, $options['para'], $options['newlines']);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => $format, 'noclean' => $options['noclean']));
            break;
    }
    if ($options['filter']) {
        // At this point there should not be any draftfile links any more,
        // this happens when developers forget to post process the text.
        // The only potential problem is that somebody might try to format
        // the text before storing into database which would be itself big bug..
        $text = str_replace("\"{$CFG->httpswwwroot}/draftfile.php", "\"{$CFG->httpswwwroot}/brokenfile.php#", $text);
        if ($CFG->debugdeveloper) {
            if (strpos($text, '@@PLUGINFILE@@/') !== false) {
                debugging('Before calling format_text(), the content must be processed with file_rewrite_pluginfile_urls()', DEBUG_DEVELOPER);
            }
        }
    }
    if (!empty($options['overflowdiv'])) {
        $text = html_writer::tag('div', $text, array('class' => 'no-overflow'));
    }
    return $text;
}
Ejemplo n.º 2
0
/**
 * Given text in a variety of format codings, this function returns
 * the text as safe HTML.
 *
 * This function should mainly be used for long strings like posts,
 * answers, glossary items etc. For short strings @see format_string().
 *
 * <pre>
 * Options:
 *      trusted     :   If true the string won't be cleaned. Default false required noclean=true.
 *      noclean     :   If true the string won't be cleaned. Default false required trusted=true.
 *      nocache     :   If true the strign will not be cached and will be formatted every call. Default false.
 *      filter      :   If true the string will be run through applicable filters as well. Default true.
 *      para        :   If true then the returned string will be wrapped in div tags. Default true.
 *      newlines    :   If true then lines newline breaks will be converted to HTML newline breaks. Default true.
 *      context     :   The context that will be used for filtering.
 *      overflowdiv :   If set to true the formatted text will be encased in a div
 *                      with the class no-overflow before being returned. Default false.
 *      allowid     :   If true then id attributes will not be removed, even when
 *                      using htmlpurifier. Default false.
 * </pre>
 *
 * @todo Finish documenting this function
 *
 * @staticvar array $croncache
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            [FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_MARKDOWN]
 * @param object/array $options text formatting options
 * @param int $courseid_do_not_use deprecated course id, use context option instead
 * @return string
 */
function format_text($text, $format = FORMAT_MOODLE, $options = NULL, $courseid_do_not_use = NULL)
{
    global $CFG, $COURSE, $DB, $PAGE;
    static $croncache = array();
    if ($text === '' || is_null($text)) {
        return '';
        // no need to do any filters and cleaning
    }
    $options = (array) $options;
    // detach object, we can not modify it
    if (!isset($options['trusted'])) {
        $options['trusted'] = false;
    }
    if (!isset($options['noclean'])) {
        if ($options['trusted'] and trusttext_active()) {
            // no cleaning if text trusted and noclean not specified
            $options['noclean'] = true;
        } else {
            $options['noclean'] = false;
        }
    }
    if (!isset($options['nocache'])) {
        $options['nocache'] = false;
    }
    if (!isset($options['filter'])) {
        $options['filter'] = true;
    }
    if (!isset($options['para'])) {
        $options['para'] = true;
    }
    if (!isset($options['newlines'])) {
        $options['newlines'] = true;
    }
    if (!isset($options['overflowdiv'])) {
        $options['overflowdiv'] = false;
    }
    // Calculate best context
    if (empty($CFG->version) or $CFG->version < 2010072800 or during_initial_install()) {
        // do not filter anything during installation or before upgrade completes
        $context = null;
    } else {
        if (isset($options['context'])) {
            // first by explicit passed context option
            if (is_object($options['context'])) {
                $context = $options['context'];
            } else {
                $context = get_context_instance_by_id($options['context']);
            }
        } else {
            if ($courseid_do_not_use) {
                // legacy courseid
                $context = get_context_instance(CONTEXT_COURSE, $courseid_do_not_use);
            } else {
                // fallback to $PAGE->context this may be problematic in CLI and other non-standard pages :-(
                $context = $PAGE->context;
            }
        }
    }
    if (!$context) {
        // either install/upgrade or something has gone really wrong because context does not exist (yet?)
        $options['nocache'] = true;
        $options['filter'] = false;
    }
    if ($options['filter']) {
        $filtermanager = filter_manager::instance();
    } else {
        $filtermanager = new null_filter_manager();
    }
    if (!empty($CFG->cachetext) and empty($options['nocache'])) {
        $hashstr = $text . '-' . $filtermanager->text_filtering_hash($context) . '-' . $context->id . '-' . current_language() . '-' . (int) $format . (int) $options['trusted'] . (int) $options['noclean'] . (int) $options['para'] . (int) $options['newlines'];
        $time = time() - $CFG->cachetext;
        $md5key = md5($hashstr);
        if (CLI_SCRIPT) {
            if (isset($croncache[$md5key])) {
                return $croncache[$md5key];
            }
        }
        if ($oldcacheitem = $DB->get_record('cache_text', array('md5key' => $md5key), '*', IGNORE_MULTIPLE)) {
            if ($oldcacheitem->timemodified >= $time) {
                if (CLI_SCRIPT) {
                    if (count($croncache) > 150) {
                        reset($croncache);
                        $key = key($croncache);
                        unset($croncache[$key]);
                    }
                    $croncache[$md5key] = $oldcacheitem->formattedtext;
                }
                return $oldcacheitem->formattedtext;
            }
        }
    }
    switch ($format) {
        case FORMAT_HTML:
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => FORMAT_HTML, 'noclean' => $options['noclean']));
            break;
        case FORMAT_PLAIN:
            $text = s($text);
            // cleans dangerous JS
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;
        case FORMAT_WIKI:
            // this format is deprecated
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>' . s($text);
            break;
        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => FORMAT_MARKDOWN, 'noclean' => $options['noclean']));
            break;
        default:
            // FORMAT_MOODLE or anything else
            $text = text_to_html($text, null, $options['para'], $options['newlines']);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, array('originalformat' => $format, 'noclean' => $options['noclean']));
            break;
    }
    if ($options['filter']) {
        // at this point there should not be any draftfile links any more,
        // this happens when developers forget to post process the text.
        // The only potential problem is that somebody might try to format
        // the text before storing into database which would be itself big bug.
        $text = str_replace("\"{$CFG->httpswwwroot}/draftfile.php", "\"{$CFG->httpswwwroot}/brokenfile.php#", $text);
    }
    // Warn people that we have removed this old mechanism, just in case they
    // were stupid enough to rely on it.
    if (isset($CFG->currenttextiscacheable)) {
        debugging('Once upon a time, Moodle had a truly evil use of global variables ' . 'called $CFG->currenttextiscacheable. The good news is that this no ' . 'longer exists. The bad news is that you seem to be using a filter that ' . 'relies on it. Please seek out and destroy that filter code.', DEBUG_DEVELOPER);
    }
    if (!empty($options['overflowdiv'])) {
        $text = html_writer::tag('div', $text, array('class' => 'no-overflow'));
    }
    if (empty($options['nocache']) and !empty($CFG->cachetext)) {
        if (CLI_SCRIPT) {
            // special static cron cache - no need to store it in db if its not already there
            if (count($croncache) > 150) {
                reset($croncache);
                $key = key($croncache);
                unset($croncache[$key]);
            }
            $croncache[$md5key] = $text;
            return $text;
        }
        $newcacheitem = new stdClass();
        $newcacheitem->md5key = $md5key;
        $newcacheitem->formattedtext = $text;
        $newcacheitem->timemodified = time();
        if ($oldcacheitem) {
            // See bug 4677 for discussion
            $newcacheitem->id = $oldcacheitem->id;
            try {
                $DB->update_record('cache_text', $newcacheitem);
                // Update existing record in the cache table
            } catch (dml_exception $e) {
                // It's unlikely that the cron cache cleaner could have
                // deleted this entry in the meantime, as it allows
                // some extra time to cover these cases.
            }
        } else {
            try {
                $DB->insert_record('cache_text', $newcacheitem);
                // Insert a new record in the cache table
            } catch (dml_exception $e) {
                // Again, it's possible that another user has caused this
                // record to be created already in the time that it took
                // to traverse this function.  That's OK too, as the
                // call above handles duplicate entries, and eventually
                // the cron cleaner will delete them.
            }
        }
    }
    return $text;
}
Ejemplo n.º 3
0
/**
 * Given text in a variety of format codings, this function returns
 * the text as safe HTML.
 *
 * This function should mainly be used for long strings like posts,
 * answers, glossary items etc. For short strings @see format_string().
 *
 * @uses $CFG
 * @uses FORMAT_MOODLE
 * @uses FORMAT_HTML
 * @uses FORMAT_PLAIN
 * @uses FORMAT_WIKI
 * @uses FORMAT_MARKDOWN
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            (FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_WIKI, FORMAT_MARKDOWN)
 * @param  array $options ?
 * @param int $courseid ?
 * @return string
 * @todo Finish documenting this function
 */
function format_text($text, $format = FORMAT_MOODLE, $options = NULL, $courseid = NULL)
{
    global $CFG, $COURSE, $DB, $PAGE;
    static $croncache = array();
    $hashstr = '';
    if ($text === '') {
        return '';
        // no need to do any filters and cleaning
    }
    if (!isset($options->trusted)) {
        $options->trusted = false;
    }
    if (!isset($options->noclean)) {
        if ($options->trusted and trusttext_active()) {
            // no cleaning if text trusted and noclean not specified
            $options->noclean = true;
        } else {
            $options->noclean = false;
        }
    }
    if (!isset($options->nocache)) {
        $options->nocache = false;
    }
    if (!isset($options->smiley)) {
        $options->smiley = true;
    }
    if (!isset($options->filter)) {
        $options->filter = true;
    }
    if (!isset($options->para)) {
        $options->para = true;
    }
    if (!isset($options->newlines)) {
        $options->newlines = true;
    }
    if (empty($courseid)) {
        $courseid = $COURSE->id;
    }
    if ($options->filter) {
        $filtermanager = filter_manager::instance();
    } else {
        $filtermanager = new null_filter_manager();
    }
    $context = $PAGE->context;
    if (!empty($CFG->cachetext) and empty($options->nocache)) {
        $hashstr .= $text . '-' . $filtermanager->text_filtering_hash($context, $courseid) . '-' . (int) $courseid . '-' . current_language() . '-' . (int) $format . (int) $options->trusted . (int) $options->noclean . (int) $options->smiley . (int) $options->filter . (int) $options->para . (int) $options->newlines;
        $time = time() - $CFG->cachetext;
        $md5key = md5($hashstr);
        if (CLI_SCRIPT) {
            if (isset($croncache[$md5key])) {
                return $croncache[$md5key];
            }
        }
        if ($oldcacheitem = $DB->get_record('cache_text', array('md5key' => $md5key), '*', true)) {
            if ($oldcacheitem->timemodified >= $time) {
                if (CLI_SCRIPT) {
                    if (count($croncache) > 150) {
                        reset($croncache);
                        $key = key($croncache);
                        unset($croncache[$key]);
                    }
                    $croncache[$md5key] = $oldcacheitem->formattedtext;
                }
                return $oldcacheitem->formattedtext;
            }
        }
    }
    switch ($format) {
        case FORMAT_HTML:
            if ($options->smiley) {
                replace_smilies($text);
            }
            if (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            $text = $filtermanager->filter_text($text, $context, $courseid);
            break;
        case FORMAT_PLAIN:
            $text = s($text);
            // cleans dangerous JS
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;
        case FORMAT_WIKI:
            // this format is deprecated
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>' . s($text);
            break;
        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if ($options->smiley) {
                replace_smilies($text);
            }
            if (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            $text = $filtermanager->filter_text($text, $context, $courseid);
            break;
        default:
            // FORMAT_MOODLE or anything else
            $text = text_to_html($text, $options->smiley, $options->para, $options->newlines);
            if (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            $text = $filtermanager->filter_text($text, $context, $courseid);
            break;
    }
    // Warn people that we have removed this old mechanism, just in case they
    // were stupid enough to rely on it.
    if (isset($CFG->currenttextiscacheable)) {
        debugging('Once upon a time, Moodle had a truly evil use of global variables ' . 'called $CFG->currenttextiscacheable. The good news is that this no ' . 'longer exists. The bad news is that you seem to be using a filter that ' . 'relies on it. Please seek out and destroy that filter code.', DEBUG_DEVELOPER);
    }
    if (empty($options->nocache) and !empty($CFG->cachetext)) {
        if (CLI_SCRIPT) {
            // special static cron cache - no need to store it in db if its not already there
            if (count($croncache) > 150) {
                reset($croncache);
                $key = key($croncache);
                unset($croncache[$key]);
            }
            $croncache[$md5key] = $text;
            return $text;
        }
        $newcacheitem = new object();
        $newcacheitem->md5key = $md5key;
        $newcacheitem->formattedtext = $text;
        $newcacheitem->timemodified = time();
        if ($oldcacheitem) {
            // See bug 4677 for discussion
            $newcacheitem->id = $oldcacheitem->id;
            try {
                $DB->update_record('cache_text', $newcacheitem);
                // Update existing record in the cache table
            } catch (dml_exception $e) {
                // It's unlikely that the cron cache cleaner could have
                // deleted this entry in the meantime, as it allows
                // some extra time to cover these cases.
            }
        } else {
            try {
                $DB->insert_record('cache_text', $newcacheitem);
                // Insert a new record in the cache table
            } catch (dml_exception $e) {
                // Again, it's possible that another user has caused this
                // record to be created already in the time that it took
                // to traverse this function.  That's OK too, as the
                // call above handles duplicate entries, and eventually
                // the cron cleaner will delete them.
            }
        }
    }
    return $text;
}
Ejemplo n.º 4
0
/**
 * Given text in a variety of format codings, this function returns the text as safe HTML.
 *
 * This function should mainly be used for long strings like posts,
 * answers, glossary items etc. For short strings {@link format_string()}.
 *
 * <pre>
 * Options:
 *      trusted     :   If true the string won't be cleaned. Default false required noclean=true.
 *      noclean     :   If true the string won't be cleaned. Default false required trusted=true.
 *      nocache     :   If true the strign will not be cached and will be formatted every call. Default false.
 *      filter      :   If true the string will be run through applicable filters as well. Default true.
 *      para        :   If true then the returned string will be wrapped in div tags. Default true.
 *      newlines    :   If true then lines newline breaks will be converted to HTML newline breaks. Default true.
 *      context     :   The context that will be used for filtering.
 *      overflowdiv :   If set to true the formatted text will be encased in a div
 *                      with the class no-overflow before being returned. Default false.
 *      allowid     :   If true then id attributes will not be removed, even when
 *                      using htmlpurifier. Default false.
 *      blanktarget :   If true all <a> tags will have target="_blank" added unless target is explicitly specified.
 * </pre>
 *
 * @staticvar array $croncache
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            [FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_MARKDOWN]
 * @param object/array $options text formatting options
 * @param int $courseiddonotuse deprecated course id, use context option instead
 * @return string
 */
function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseiddonotuse = null) {
    global $CFG, $DB, $PAGE;

    if ($text === '' || is_null($text)) {
        // No need to do any filters and cleaning.
        return '';
    }

    // Detach object, we can not modify it.
    $options = (array)$options;

    if (!isset($options['trusted'])) {
        $options['trusted'] = false;
    }
    if (!isset($options['noclean'])) {
        if ($options['trusted'] and trusttext_active()) {
            // No cleaning if text trusted and noclean not specified.
            $options['noclean'] = true;
        } else {
            $options['noclean'] = false;
        }
    }
    if (!isset($options['nocache'])) {
        $options['nocache'] = false;
    }
    if (!isset($options['filter'])) {
        $options['filter'] = true;
    }
    if (!isset($options['para'])) {
        $options['para'] = true;
    }
    if (!isset($options['newlines'])) {
        $options['newlines'] = true;
    }
    if (!isset($options['overflowdiv'])) {
        $options['overflowdiv'] = false;
    }
    $options['blanktarget'] = !empty($options['blanktarget']);

    // Calculate best context.
    if (empty($CFG->version) or $CFG->version < 2013051400 or during_initial_install()) {
        // Do not filter anything during installation or before upgrade completes.
        $context = null;

    } else if (isset($options['context'])) { // First by explicit passed context option.
        if (is_object($options['context'])) {
            $context = $options['context'];
        } else {
            $context = context::instance_by_id($options['context']);
        }
    } else if ($courseiddonotuse) {
        // Legacy courseid.
        $context = context_course::instance($courseiddonotuse);
    } else {
        // Fallback to $PAGE->context this may be problematic in CLI and other non-standard pages :-(.
        $context = $PAGE->context;
    }

    if (!$context) {
        // Either install/upgrade or something has gone really wrong because context does not exist (yet?).
        $options['nocache'] = true;
        $options['filter']  = false;
    }

    if ($options['filter']) {
        $filtermanager = filter_manager::instance();
        $filtermanager->setup_page_for_filters($PAGE, $context); // Setup global stuff filters may have.
        $filteroptions = array(
            'originalformat' => $format,
            'noclean' => $options['noclean'],
        );
    } else {
        $filtermanager = new null_filter_manager();
        $filteroptions = array();
    }

    switch ($format) {
        case FORMAT_HTML:
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, $filteroptions);
            break;

        case FORMAT_PLAIN:
            $text = s($text); // Cleans dangerous JS.
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;

        case FORMAT_WIKI:
            // This format is deprecated.
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>'.s($text);
            break;

        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, $filteroptions);
            break;

        default:  // FORMAT_MOODLE or anything else.
            $text = text_to_html($text, null, $options['para'], $options['newlines']);
            if (!$options['noclean']) {
                $text = clean_text($text, FORMAT_HTML, $options);
            }
            $text = $filtermanager->filter_text($text, $context, $filteroptions);
            break;
    }
    if ($options['filter']) {
        // At this point there should not be any draftfile links any more,
        // this happens when developers forget to post process the text.
        // The only potential problem is that somebody might try to format
        // the text before storing into database which would be itself big bug..
        $text = str_replace("\"$CFG->httpswwwroot/draftfile.php", "\"$CFG->httpswwwroot/brokenfile.php#", $text);

        if ($CFG->debugdeveloper) {
            if (strpos($text, '@@PLUGINFILE@@/') !== false) {
                debugging('Before calling format_text(), the content must be processed with file_rewrite_pluginfile_urls()',
                    DEBUG_DEVELOPER);
            }
        }
    }

    if (!empty($options['overflowdiv'])) {
        $text = html_writer::tag('div', $text, array('class' => 'no-overflow'));
    }

    if ($options['blanktarget']) {
        $domdoc = new DOMDocument();
        $domdoc->loadHTML($text);
        foreach ($domdoc->getElementsByTagName('a') as $link) {
            if ($link->hasAttribute('target') && strpos($link->getAttribute('target'), '_blank') === false) {
                continue;
            }
            $link->setAttribute('target', '_blank');
            if (strpos($link->getAttribute('rel'), 'noreferrer') === false) {
                $link->setAttribute('rel', trim($link->getAttribute('rel') . ' noreferrer'));
            }
        }

        // This regex is nasty and I don't like it. The correct way to solve this is by loading the HTML like so:
        // $domdoc->loadHTML($text, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); however it seems like the libxml
        // version that travis uses doesn't work properly and ends up leaving <html><body>, so I'm forced to use
        // this regex to remove those tags.
        $text = trim(preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $domdoc->saveHTML()));
    }

    return $text;
}
Ejemplo n.º 5
0
/**
 * Given text in a variety of format codings, this function returns
 * the text as safe HTML.
 *
 * This function should mainly be used for long strings like posts,
 * answers, glossary items etc. For short strings @see format_string().
 *
 * @uses $CFG
 * @uses FORMAT_MOODLE
 * @uses FORMAT_HTML
 * @uses FORMAT_PLAIN
 * @uses FORMAT_WIKI
 * @uses FORMAT_MARKDOWN
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            (FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_WIKI, FORMAT_MARKDOWN)
 * @param  array $options ?
 * @param int $courseid ?
 * @return string
 * @todo Finish documenting this function
 */
function format_text($text, $format = FORMAT_MOODLE, $options = NULL, $courseid = NULL)
{
    global $CFG, $COURSE;
    static $croncache = array();
    if ($text === '') {
        return '';
        // no need to do any filters and cleaning
    }
    if (!isset($options->trusttext)) {
        $options->trusttext = false;
    }
    if (!isset($options->noclean)) {
        $options->noclean = false;
    }
    if (!isset($options->nocache)) {
        $options->nocache = false;
    }
    if (!isset($options->smiley)) {
        $options->smiley = true;
    }
    if (!isset($options->filter)) {
        $options->filter = true;
    }
    if (!isset($options->para)) {
        $options->para = true;
    }
    if (!isset($options->newlines)) {
        $options->newlines = true;
    }
    if (empty($courseid)) {
        $courseid = $COURSE->id;
    }
    if (!empty($CFG->cachetext) and empty($options->nocache)) {
        $time = time() - $CFG->cachetext;
        $md5key = md5($text . '-' . (int) $courseid . '-' . current_language() . '-' . (int) $format . (int) $options->trusttext . (int) $options->noclean . (int) $options->smiley . (int) $options->filter . (int) $options->para . (int) $options->newlines);
        if (defined('FULLME') and FULLME == 'cron') {
            if (isset($croncache[$md5key])) {
                return $croncache[$md5key];
            }
        }
        if ($oldcacheitem = get_record_sql('SELECT * FROM ' . $CFG->prefix . 'cache_text WHERE md5key = \'' . $md5key . '\'', true)) {
            if ($oldcacheitem->timemodified >= $time) {
                if (defined('FULLME') and FULLME == 'cron') {
                    if (count($croncache) > 150) {
                        reset($croncache);
                        $key = key($croncache);
                        unset($croncache[$key]);
                    }
                    $croncache[$md5key] = $oldcacheitem->formattedtext;
                }
                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;
        }
    } else {
        if (!debugging('', DEBUG_DEVELOPER)) {
            // strip any forgotten trusttext in non-developer mode
            // do not forget to disable text cache when debugging trusttext!!
            $text = trusttext_strip($text);
        }
    }
    $CFG->currenttextiscacheable = true;
    // Default status - can be changed by any filter
    switch ($format) {
        case FORMAT_HTML:
            if ($options->smiley) {
                replace_smilies($text);
            }
            if (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            if ($options->filter) {
                $text = filter_text($text, $courseid);
            }
            break;
        case FORMAT_PLAIN:
            $text = s($text);
            // cleans dangerous JS
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;
        case FORMAT_WIKI:
            // this format is deprecated
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>' . s($text);
            break;
        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if ($options->smiley) {
                replace_smilies($text);
            }
            if (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            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 (!$options->noclean) {
                $text = clean_text($text, FORMAT_HTML);
            }
            if ($options->filter) {
                $text = filter_text($text, $courseid);
            }
            break;
    }
    if (empty($options->nocache) and !empty($CFG->cachetext) and $CFG->currenttextiscacheable) {
        if (defined('FULLME') and FULLME == 'cron') {
            // special static cron cache - no need to store it in db if its not already there
            if (count($croncache) > 150) {
                reset($croncache);
                $key = key($croncache);
                unset($croncache[$key]);
            }
            $croncache[$md5key] = $text;
            return $text;
        }
        $newcacheitem = new object();
        $newcacheitem->md5key = $md5key;
        $newcacheitem->formattedtext = addslashes($text);
        $newcacheitem->timemodified = time();
        if ($oldcacheitem) {
            // See bug 4677 for discussion
            $newcacheitem->id = $oldcacheitem->id;
            @update_record('cache_text', $newcacheitem);
            // Update existing record in the cache table
            // It's unlikely that the cron cache cleaner could have
            // deleted this entry in the meantime, as it allows
            // some extra time to cover these cases.
        } else {
            @insert_record('cache_text', $newcacheitem);
            // Insert a new record in the cache table
            // Again, it's possible that another user has caused this
            // record to be created already in the time that it took
            // to traverse this function.  That's OK too, as the
            // call above handles duplicate entries, and eventually
            // the cron cleaner will delete them.
        }
    }
    return $text;
}
Ejemplo n.º 6
0
function format_text($text, $format = FORMAT_MOODLE, $options = NULL, $courseid = NULL)
{
    global $CFG, $course;
    if (!isset($options->noclean)) {
        $options->noclean = false;
    }
    if (!isset($options->smiley)) {
        $options->smiley = true;
    }
    if (!isset($options->filter)) {
        $options->filter = true;
    }
    if (!isset($options->para)) {
        $options->para = true;
    }
    if (!isset($options->newlines)) {
        $options->newlines = true;
    }
    if (empty($courseid)) {
        if (!empty($course->id)) {
            // An ugly hack for better compatibility
            $courseid = $course->id;
        }
    }
    /*
    if (!empty($CFG->cachetext)) {
        $time = time() - $CFG->cachetext;
        $md5key = md5($text.'-'.$courseid.$options->noclean.$options->smiley.$options->filter.$options->para.$options->newlines);
        if ($cacheitem = get_record_select('cache_text', "md5key = '$md5key' AND timemodified > '$time'")) {
            return $cacheitem->formattedtext;
        }
    }
    */
    // DISABLED - there is no cache_text - Penny
    $CFG->currenttextiscacheable = true;
    // Default status - can be changed by any filter
    switch ($format) {
        case FORMAT_HTML:
            if (!empty($options->smiley)) {
                replace_smilies($text);
            }
            if (!isset($options->noclean)) {
                $text = clean_text($text, $format, !empty($options->cleanuserfile));
            }
            if (!empty($options->filter)) {
                $text = filter_text($text, $courseid);
            }
            break;
        case FORMAT_PLAIN:
            $text = s($text);
            $text = rebuildnolinktag($text);
            $text = str_replace('  ', '&nbsp; ', $text);
            $text = nl2br($text);
            break;
        case FORMAT_WIKI:
            // this format is deprecated
            $text = '<p>NOTICE: Wiki-like formatting has been removed from Moodle.  You should not be seeing
                     this message as all texts should have been converted to Markdown format instead.
                     Please post a bug report to http://moodle.org/bugs with information about where you
                     saw this message.</p>' . s($text);
            break;
        case FORMAT_MARKDOWN:
            $text = markdown_to_html($text);
            if (!empty($options->smiley)) {
                replace_smilies($text);
            }
            if (empty($options->noclean)) {
                $text = clean_text($text, $format);
            }
            if (!empty($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)) {
                $text = clean_text($text, $format);
            }
            if (!empty($options->filter)) {
                $text = filter_text($text, $courseid);
            }
            break;
    }
    if (!empty($CFG->cachetext) and $CFG->currenttextiscacheable) {
        $newrecord->md5key = $md5key;
        $newrecord->formattedtext = $text;
        $newrecord->timemodified = time();
        @insert_record('cache_text', $newrecord);
    }
    return $text;
}
Ejemplo n.º 7
0
 if ($forum->type != 'single') {
     $fullsubject .= " -> <a href=\"discuss.php?d={$discussion->id}\">" . format_string($discussion->name, true) . "</a>";
     if ($post->parent != 0) {
         $fullsubject .= " -> <a href=\"discuss.php?d={$post->discussion}&amp;parent={$post->id}\">" . format_string($post->subject, true) . "</a>";
     }
 }
 $post->subject = $fullsubject;
 //Indicate search terms only found in HTML markup
 //Use highlight() with nonsense tags to spot search terms in the
 //actual text content first.          fiedorow - 9/2/2005
 $missing_terms = "";
 // Hack for posts of format FORMAT_PLAIN. Otherwise html tags added by
 // the highlight() call bellow get stripped out by forum_print_post().
 if ($post->format == FORMAT_PLAIN) {
     $post->message = stripslashes_safe($post->message);
     $post->message = rebuildnolinktag($post->message);
     $post->message = str_replace(' ', '&nbsp; ', $post->message);
     $post->message = nl2br($post->message);
     $post->format = FORMAT_HTML;
 }
 $options = new object();
 $options->trusttext = true;
 // detect TRUSTTEXT marker before first call to format_text
 if (trusttext_present($post->message)) {
     $ttpresent = true;
 } else {
     $ttpresent = false;
 }
 $message = highlight($strippedsearch, format_text($post->message, $post->format, $options, $course->id), 0, '<fgw9sdpq4>', '</fgw9sdpq4>');
 foreach ($searchterms as $searchterm) {
     if (preg_match("/{$searchterm}/i", $message) && !preg_match('/<fgw9sdpq4>' . $searchterm . '<\\/fgw9sdpq4>/i', $message)) {