Merge branch 'w51_MDL-29996_m25_oldfilters' of git://github.com/skodak/moodle

This commit is contained in:
Sam Hemelryk 2013-01-07 15:22:37 +13:00
commit dd89f61e68
24 changed files with 474 additions and 548 deletions

View file

@ -35,7 +35,7 @@
require_once($CFG->libdir . '/adminlib.php'); require_once($CFG->libdir . '/adminlib.php');
$action = optional_param('action', '', PARAM_ALPHANUMEXT); $action = optional_param('action', '', PARAM_ALPHANUMEXT);
$filterpath = optional_param('filterpath', '', PARAM_PATH); $filterpath = optional_param('filterpath', '', PARAM_SAFEDIR);
require_login(); require_login();
$systemcontext = context_system::instance(); $systemcontext = context_system::instance();
@ -84,39 +84,22 @@
case 'down': case 'down':
if (isset($filters[$filterpath])) { if (isset($filters[$filterpath])) {
$oldpos = $filters[$filterpath]->sortorder; filter_set_global_state($filterpath, $filters[$filterpath]->active, 1);
if ($oldpos <= count($filters)) {
filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos + 1);
}
} }
break; break;
case 'up': case 'up':
if (isset($filters[$filterpath])) { if (isset($filters[$filterpath])) {
$oldpos = $filters[$filterpath]->sortorder; $oldpos = $filters[$filterpath]->sortorder;
if ($oldpos >= 1) { filter_set_global_state($filterpath, $filters[$filterpath]->active, -1);
filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos - 1);
}
} }
break; break;
case 'delete': case 'delete':
if (!empty($filternames[$filterpath])) {
$filtername = $filternames[$filterpath];
} else {
$filtername = $filterpath;
}
if (substr($filterpath, 0, 4) == 'mod/') {
$mod = basename($filterpath);
$a = new stdClass;
$a->filter = $filtername;
$a->module = get_string('modulename', $mod);
print_error('cannotdeletemodfilter', 'admin', $returnurl, $a);
}
// If not yet confirmed, display a confirmation message. // If not yet confirmed, display a confirmation message.
if (!optional_param('confirm', '', PARAM_BOOL)) { if (!optional_param('confirm', '', PARAM_BOOL)) {
$filtername = filter_get_name($filterpath);
$title = get_string('deletefilterareyousure', 'admin', $filtername); $title = get_string('deletefilterareyousure', 'admin', $filtername);
echo $OUTPUT->header(); echo $OUTPUT->header();
echo $OUTPUT->heading($title); echo $OUTPUT->heading($title);
@ -129,7 +112,7 @@
} }
// Do the deletion. // Do the deletion.
$title = get_string('deletingfilter', 'admin', $filtername); $title = get_string('deletingfilter', 'admin', $filterpath);
echo $OUTPUT->header(); echo $OUTPUT->header();
echo $OUTPUT->heading($title); echo $OUTPUT->heading($title);
@ -137,8 +120,8 @@
filter_delete_all_for_filter($filterpath); filter_delete_all_for_filter($filterpath);
$a = new stdClass; $a = new stdClass;
$a->filter = $filtername; $a->filter = $filterpath;
$a->directory = $filterpath; $a->directory = "$CFG->dirroot/filter/$filterpath";
echo $OUTPUT->box(get_string('deletefilterfiles', 'admin', $a), 'generalbox', 'notice'); echo $OUTPUT->box(get_string('deletefilterfiles', 'admin', $a), 'generalbox', 'notice');
echo $OUTPUT->continue_button($returnurl); echo $OUTPUT->continue_button($returnurl);
echo $OUTPUT->footer(); echo $OUTPUT->footer();
@ -241,7 +224,7 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
} }
// Disable/off/on // Disable/off/on
$select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . basename($filter)); $select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . $filter);
$select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide')); $select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide'));
$row[] = $OUTPUT->render($select); $row[] = $OUTPUT->render($select);
@ -263,25 +246,20 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
$row[] = $updown; $row[] = $updown;
// Apply to strings. // Apply to strings.
$select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . basename($filter)); $select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . $filter);
$select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide')); $select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide'));
$select->disabled = $filterinfo->active == TEXTFILTER_DISABLED; $select->disabled = $filterinfo->active == TEXTFILTER_DISABLED;
$row[] = $OUTPUT->render($select); $row[] = $OUTPUT->render($select);
// Settings link, if required // Settings link, if required
if (filter_has_global_settings($filter)) { if (filter_has_global_settings($filter)) {
$row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' . $row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' . $filter . '">' . get_string('settings') . '</a>';
str_replace('/', '',$filter) . '">' . get_string('settings') . '</a>';
} else { } else {
$row[] = ''; $row[] = '';
} }
// Delete // Delete
if (substr($filter, 0, 4) != 'mod/') { $row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
$row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
} else {
$row[] = '';
}
return $row; return $row;
} }

View file

@ -1822,6 +1822,14 @@ class restore_filters_structure_step extends restore_structure_step {
$data = (object)$data; $data = (object)$data;
if (strpos($data->filter, 'filter/') === 0) {
$data->filter = substr($data->filter, 7);
} else if (strpos($data->filter, '/') !== false) {
// Unsupported old filter.
return;
}
if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
return; return;
} }
@ -1832,6 +1840,14 @@ class restore_filters_structure_step extends restore_structure_step {
$data = (object)$data; $data = (object)$data;
if (strpos($data->filter, 'filter/') === 0) {
$data->filter = substr($data->filter, 7);
} else if (strpos($data->filter, '/') !== false) {
// Unsupported old filter.
return;
}
if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
return; return;
} }

View file

@ -26,6 +26,6 @@ function xmldb_filter_activitynames_install() {
global $CFG; global $CFG;
require_once("$CFG->libdir/filterlib.php"); require_once("$CFG->libdir/filterlib.php");
filter_set_global_state('filter/activitynames', TEXTFILTER_ON); filter_set_global_state('activitynames', TEXTFILTER_ON);
} }

View file

@ -7,7 +7,7 @@
require_once("../../config.php"); require_once("../../config.php");
if (!filter_is_enabled('filter/algebra')) { if (!filter_is_enabled('algebra')) {
print_error('filternotenabled'); print_error('filternotenabled');
} }

View file

@ -9,7 +9,7 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
require_once('../../config.php'); require_once('../../config.php');
if (!filter_is_enabled('filter/algebra')) { if (!filter_is_enabled('algebra')) {
print_error('filternotenabled'); print_error('filternotenabled');
} }

View file

@ -27,7 +27,7 @@ require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/adminlib.php'); require_once($CFG->libdir . '/adminlib.php');
$contextid = required_param('contextid',PARAM_INT); $contextid = required_param('contextid',PARAM_INT);
$forfilter = optional_param('filter', '', PARAM_SAFEPATH); $forfilter = optional_param('filter', '', PARAM_SAFEDIR);
list($context, $course, $cm) = get_context_info_array($contextid); list($context, $course, $cm) = get_context_info_array($contextid);
@ -82,8 +82,8 @@ if ($forfilter) {
print_error('filterdoesnothavelocalconfig', 'error', $forfilter); print_error('filterdoesnothavelocalconfig', 'error', $forfilter);
} }
require_once($CFG->dirroot . '/filter/local_settings_form.php'); require_once($CFG->dirroot . '/filter/local_settings_form.php');
require_once($CFG->dirroot . '/' . $forfilter . '/filterlocalsettings.php'); require_once($CFG->dirroot . '/filter/' . $forfilter . '/filterlocalsettings.php');
$formname = basename($forfilter) . '_filter_local_settings_form'; $formname = $forfilter . '_filter_local_settings_form';
$settingsform = new $formname($CFG->wwwroot . '/filter/manage.php', $forfilter, $context); $settingsform = new $formname($CFG->wwwroot . '/filter/manage.php', $forfilter, $context);
if ($settingsform->is_cancelled()) { if ($settingsform->is_cancelled()) {
redirect($baseurl); redirect($baseurl);
@ -96,7 +96,7 @@ if ($forfilter) {
/// Process any form submission. /// Process any form submission.
if ($forfilter == '' && optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { if ($forfilter == '' && optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
foreach ($availablefilters as $filter => $filterinfo) { foreach ($availablefilters as $filter => $filterinfo) {
$newstate = optional_param(str_replace('/', '_', $filter), false, PARAM_INT); $newstate = optional_param($filter, false, PARAM_INT);
if ($newstate !== false && $newstate != $filterinfo->localstate) { if ($newstate !== false && $newstate != $filterinfo->localstate) {
filter_set_local_state($filter, $context->id, $newstate); filter_set_local_state($filter, $context->id, $newstate);
} }
@ -181,9 +181,8 @@ if (empty($availablefilters)) {
} else { } else {
$activechoices[TEXTFILTER_INHERIT] = $strdefaultoff; $activechoices[TEXTFILTER_INHERIT] = $strdefaultoff;
} }
$filtername = str_replace('/', '_', $filter); $select = html_writer::label($filterinfo->localstate, 'menu'. $filter, false, array('class' => 'accesshide'));
$select = html_writer::label($filterinfo->localstate, 'menu'. $filtername, false, array('class' => 'accesshide')); $select .= html_writer::select($activechoices, $filter, $filterinfo->localstate, false);
$select .= html_writer::select($activechoices, $filtername, $filterinfo->localstate, false);
$row[] = $select; $row[] = $select;
// Settings link, if required // Settings link, if required

View file

@ -27,6 +27,6 @@ function xmldb_filter_mediaplugin_install() {
global $CFG; global $CFG;
require_once("$CFG->libdir/filterlib.php"); require_once("$CFG->libdir/filterlib.php");
filter_set_global_state('filter/mediaplugin', TEXTFILTER_ON); filter_set_global_state('mediaplugin', TEXTFILTER_ON);
} }

View file

@ -29,7 +29,7 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
require('../../config.php'); require('../../config.php');
if (!filter_is_enabled('filter/tex') and !filter_is_enabled('filter/algebra')) { if (!filter_is_enabled('tex') and !filter_is_enabled('algebra')) {
print_error('filternotenabled'); print_error('filternotenabled');
} }

View file

@ -9,7 +9,7 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
require_once('../../config.php'); require_once('../../config.php');
if (!filter_is_enabled('filter/tex')) { if (!filter_is_enabled('tex')) {
print_error('filternotenabled'); print_error('filternotenabled');
} }

View file

@ -28,7 +28,7 @@
require_once("../../config.php"); require_once("../../config.php");
if (!filter_is_enabled('filter/tex')) { if (!filter_is_enabled('tex')) {
print_error('filternotenabled'); print_error('filternotenabled');
} }

View file

@ -1,6 +1,13 @@
This file describes API changes in core filter API and plugins, This file describes API changes in core filter API and plugins,
information provided here is intended especially for developers. information provided here is intended especially for developers.
=== 2.5 ===
* legacy_filter emulation was removed
* support for 'mod/*' filters was removed
* use short filter name instead of old path, ex.: 'filter/tex' ---> 'tex'
in all filter API functions and methods
=== 2.3 === === 2.3 ===
* new setup() method added to moodle_text_filter, invoked before * new setup() method added to moodle_text_filter, invoked before

View file

@ -6092,8 +6092,7 @@ class admin_page_managefilters extends admin_externalpage {
$found = true; $found = true;
break; break;
} }
list($type, $filter) = explode('/', $path); if (strpos($path, $query) !== false) {
if (strpos($filter, $query) !== false) {
$found = true; $found = true;
break; break;
} }

View file

@ -456,7 +456,7 @@
<TABLE NAME="filter_active" COMMENT="Stores information about which filters are active in which contexts. Also the filter sort order. See get_active_filters in lib/filterlib.php for how this data is used." PREVIOUS="course_format_options" NEXT="filter_config"> <TABLE NAME="filter_active" COMMENT="Stores information about which filters are active in which contexts. Also the filter sort order. See get_active_filters in lib/filterlib.php for how this data is used." PREVIOUS="course_format_options" NEXT="filter_config">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="filter"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="filter"/>
<FIELD NAME="filter" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The filter internal name, like 'filter/tex' or 'mod/glossary'." PREVIOUS="id" NEXT="contextid"/> <FIELD NAME="filter" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The filter internal name, like 'tex'." PREVIOUS="id" NEXT="contextid"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="References context.id." PREVIOUS="filter" NEXT="active"/> <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="References context.id." PREVIOUS="filter" NEXT="active"/>
<FIELD NAME="active" TYPE="int" LENGTH="4" NOTNULL="true" SEQUENCE="false" COMMENT="Whether this filter is active in this context. +1 = On, -1 = Off, no row with this contextid = inherit. As a special case, when contextid points to the system context, -9999 means this filter is completely disabled." PREVIOUS="contextid" NEXT="sortorder"/> <FIELD NAME="active" TYPE="int" LENGTH="4" NOTNULL="true" SEQUENCE="false" COMMENT="Whether this filter is active in this context. +1 = On, -1 = Off, no row with this contextid = inherit. As a special case, when contextid points to the system context, -9999 means this filter is completely disabled." PREVIOUS="contextid" NEXT="sortorder"/>
<FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Only relevant if contextid points to the system context. In other cases this field should contain 0. The order in which the filters should be applied." PREVIOUS="active"/> <FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Only relevant if contextid points to the system context. In other cases this field should contain 0. The order in which the filters should be applied." PREVIOUS="active"/>
@ -472,7 +472,7 @@
<TABLE NAME="filter_config" COMMENT="Stores per-context configuration settings for filters which have them." PREVIOUS="filter_active" NEXT="event"> <TABLE NAME="filter_config" COMMENT="Stores per-context configuration settings for filters which have them." PREVIOUS="filter_active" NEXT="event">
<FIELDS> <FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="filter"/> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="filter"/>
<FIELD NAME="filter" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The filter internal name, like 'filter/tex' or 'mod/glossary'." PREVIOUS="id" NEXT="contextid"/> <FIELD NAME="filter" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The filter internal name, like 'tex'." PREVIOUS="id" NEXT="contextid"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="References context.id." PREVIOUS="filter" NEXT="name"/> <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="References context.id." PREVIOUS="filter" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The config variable name." PREVIOUS="contextid" NEXT="value"/> <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The config variable name." PREVIOUS="contextid" NEXT="value"/>
<FIELD NAME="value" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The correspoding config variable value." PREVIOUS="name"/> <FIELD NAME="value" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The correspoding config variable value." PREVIOUS="name"/>

View file

@ -1524,5 +1524,46 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2012120300.04); upgrade_main_savepoint(true, 2012120300.04);
} }
if ($oldversion < 2012120300.07) {
// Purge removed module filters and all their settings.
$tables = array('filter_active', 'filter_config');
foreach ($tables as $table) {
$DB->delete_records_select($table, "filter LIKE 'mod/%'");
$filters = $DB->get_records_sql("SELECT DISTINCT filter FROM {{$table}} WHERE filter LIKE 'filter/%'");
foreach ($filters as $filter) {
$DB->set_field($table, 'filter', substr($filter->filter, 7), array('filter'=>$filter->filter));
}
}
$configs = array('stringfilters', 'filterall');
foreach ($configs as $config) {
if ($filters = get_config(null, $config)) {
$filters = explode(',', $filters);
$newfilters = array();
foreach($filters as $filter) {
if (strpos($filter, '/') === false) {
$newfilters[] = $filter;
} else if (strpos($filter, 'filter/') === 0) {
$newfilters[] = substr($filter, 7);
}
}
$filters = implode(',', $newfilters);
set_config($config, $filters);
}
}
unset($tables);
unset($table);
unset($configs);
unset($newfilters);
unset($filters);
unset($filter);
// Main savepoint reached.
upgrade_main_savepoint(true, 2012120300.07);
}
return true; return true;
} }

View file

@ -33,7 +33,7 @@ class tinymce_dragmath extends editor_tinymce_plugin {
if ($this->get_config('requiretex', 1)) { if ($this->get_config('requiretex', 1)) {
// If TeX filter is disabled, do not add button. // If TeX filter is disabled, do not add button.
$filters = filter_get_active_in_context($context); $filters = filter_get_active_in_context($context);
if (!array_key_exists('filter/tex', $filters)) { if (!array_key_exists('tex', $filters)) {
return; return;
} }
} }

View file

@ -34,7 +34,7 @@ class tinymce_moodleemoticon extends editor_tinymce_plugin {
if ($this->get_config('requireemoticon', 1)) { if ($this->get_config('requireemoticon', 1)) {
// If emoticon filter is disabled, do not add button. // If emoticon filter is disabled, do not add button.
$filters = filter_get_active_in_context($context); $filters = filter_get_active_in_context($context);
if (!array_key_exists('filter/emoticon', $filters)) { if (!array_key_exists('emoticon', $filters)) {
return; return;
} }
} }

View file

@ -2,6 +2,11 @@ This files describes API changes in /lib/editor/tinymce/* - TinyMCE editor,
information provided here is intended especially for developers. information provided here is intended especially for developers.
=== 2.5 ===
* update filter related code to use short filter names instead
of original paths, ex.: 'filter/tex' ---> 'tex'
=== 2.4 === === 2.4 ===
new features: new features:

View file

@ -2715,7 +2715,7 @@ function file_modify_html_header($text) {
}*/ }*/
$ufo = ''; $ufo = '';
if (filter_is_enabled('filter/mediaplugin')) { if (filter_is_enabled('mediaplugin')) {
// this script is needed by most media filter plugins. // this script is needed by most media filter plugins.
$attributes = array('type'=>'text/javascript', 'src'=>$CFG->httpswwwroot . '/lib/ufo.js'); $attributes = array('type'=>'text/javascript', 'src'=>$CFG->httpswwwroot . '/lib/ufo.js');
$ufo = html_writer::tag('script', '', $attributes) . "\n"; $ufo = html_writer::tag('script', '', $attributes) . "\n";

View file

@ -1,5 +1,4 @@
<?php <?php
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
@ -18,8 +17,7 @@
/** /**
* Library functions for managing text filter plugins. * Library functions for managing text filter plugins.
* *
* @package core * @package core_filter
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
@ -50,8 +48,7 @@ define('TEXTFILTER_EXCL_SEPARATOR', '-%-');
* *
* This class is a singleton. * This class is a singleton.
* *
* @package core * @package core_filter
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
@ -115,33 +112,27 @@ class filter_manager {
} }
/** /**
* Factory method for creating a filter * Factory method for creating a filter.
* *
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param string $filtername The filter name, for example 'tex'.
* @param object $context context object. * @param context $context context object.
* @param array $localconfig array of local configuration variables for this filter. * @param array $localconfig array of local configuration variables for this filter.
* @return object moodle_text_filter The filter, or null, if this type of filter is * @return moodle_text_filter The filter, or null, if this type of filter is
* not recognised or could not be created. * not recognised or could not be created.
*/ */
protected function make_filter_object($filtername, $context, $localconfig) { protected function make_filter_object($filtername, $context, $localconfig) {
global $CFG; global $CFG;
$path = $CFG->dirroot .'/'. $filtername .'/filter.php'; $path = $CFG->dirroot .'/filter/'. $filtername .'/filter.php';
if (!is_readable($path)) { if (!is_readable($path)) {
return null; return null;
} }
include_once($path); include_once($path);
$filterclassname = 'filter_' . basename($filtername); $filterclassname = 'filter_' . $filtername;
if (class_exists($filterclassname)) { if (class_exists($filterclassname)) {
return new $filterclassname($context, $localconfig); return new $filterclassname($context, $localconfig);
} }
// TODO: deprecated since 2.2, will be out in 2.3, see MDL-29996
$legacyfunctionname = basename($filtername) . '_filter';
if (function_exists($legacyfunctionname)) {
return new legacy_filter($legacyfunctionname, $context, $localconfig);
}
return null; return null;
} }
@ -193,7 +184,7 @@ class filter_manager {
*/ */
public function filter_text($text, $context, array $options = array()) { public function filter_text($text, $context, array $options = array()) {
$text = $this->apply_filter_chain($text, $this->get_text_filters($context), $options); $text = $this->apply_filter_chain($text, $this->get_text_filters($context), $options);
/// <nolink> tags removed for XHTML compatibility // <nolink> tags removed for XHTML compatibility
$text = str_replace(array('<nolink>', '</nolink>'), '', $text); $text = str_replace(array('<nolink>', '</nolink>'), '', $text);
return $text; return $text;
} }
@ -202,7 +193,7 @@ class filter_manager {
* Filter a piece of string * Filter a piece of string
* *
* @param string $string The text to filter * @param string $string The text to filter
* @param object $context * @param context $context
* @return string resulting string * @return string resulting string
*/ */
public function filter_string($string, $context) { public function filter_string($string, $context) {
@ -211,7 +202,7 @@ class filter_manager {
/** /**
* @todo Document this function * @todo Document this function
* @param object $context * @param context $context
* @return object A string filter * @return object A string filter
*/ */
public function text_filtering_hash($context) { public function text_filtering_hash($context) {
@ -253,8 +244,7 @@ class filter_manager {
* *
* @todo Document this class * @todo Document this class
* *
* @package core * @package core_filter
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
@ -286,8 +276,7 @@ class null_filter_manager {
* *
* @todo Document this class * @todo Document this class
* *
* @package core * @package core_filter
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
@ -351,8 +340,7 @@ class performance_measuring_filter_manager extends filter_manager {
* Base class for text filters. You just need to override this class and * Base class for text filters. You just need to override this class and
* implement the filter method. * implement the filter method.
* *
* @package core * @package core_filter
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
@ -364,9 +352,9 @@ abstract class moodle_text_filter {
/** /**
* Set any context-specific configuration for this filter. * Set any context-specific configuration for this filter.
* @param object $context The current course id. *
* @param object $context The current context. * @param context $context The current context.
* @param array $config Any context-specific configuration for this filter. * @param array $localconfig Any context-specific configuration for this filter.
*/ */
public function __construct($context, array $localconfig) { public function __construct($context, array $localconfig) {
$this->context = $context; $this->context = $context;
@ -408,50 +396,6 @@ abstract class moodle_text_filter {
public abstract function filter($text, array $options = array()); public abstract function filter($text, array $options = array());
} }
/**
* moodle_text_filter implementation that encapsulates an old-style filter that
* only defines a function, not a class.
*
* @deprecated since 2.2, see MDL-29995
* @todo will be out in 2.3, see MDL-29996
* @package core
* @subpackage filter
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class legacy_filter extends moodle_text_filter {
/** @var string */
protected $filterfunction;
protected $courseid;
/**
* Set any context-specific configuration for this filter.
*
* @param string $filterfunction
* @param object $context The current context.
* @param array $config Any context-specific configuration for this filter.
*/
public function __construct($filterfunction, $context, array $localconfig) {
parent::__construct($context, $localconfig);
$this->filterfunction = $filterfunction;
$this->courseid = get_courseid_from_context($this->context);
}
/**
* @param string $text
* @param array $options options - not supported for legacy filters
* @return mixed
*/
public function filter($text, array $options = array()) {
if ($this->courseid) {
// old filters are called only when inside courses
return call_user_func($this->filterfunction, $this->courseid, $text);
} else {
return $text;
}
}
}
/** /**
* This is just a little object to define a phrase and some instructions * This is just a little object to define a phrase and some instructions
* for how to process it. Filters can create an array of these to pass * for how to process it. Filters can create an array of these to pass
@ -509,66 +453,40 @@ class filterobject {
} }
/** /**
* Look up the name of this filter in the most appropriate location. * Look up the name of this filter
* If $filterlocation = 'mod' then does get_string('filtername', $filter);
* else if $filterlocation = 'filter' then does get_string('filtername', 'filter_' . $filter);
* with a fallback to get_string('filtername', $filter) for backwards compatibility.
* These are the only two options supported at the moment.
* *
* @param string $filter the folder name where the filter lives. * @param string $filter the filter name
* @return string the human-readable name for this filter. * @return string the human-readable name for this filter.
*/ */
function filter_get_name($filter) { function filter_get_name($filter) {
// TODO: should we be using pluginname here instead? , see MDL-29998 if (strpos($filter, 'filter/') === 0) {
list($type, $filter) = explode('/', $filter); debugging("Old '$filter'' parameter used in filter_get_name()");
switch ($type) { $filter = substr($filter, 7);
case 'filter': } else if (strpos($filter, '/') !== false) {
$strfiltername = get_string('filtername', 'filter_' . $filter); throw new coding_exception('Unknown filter type ' . $filter);
if (substr($strfiltername, 0, 2) != '[[') { }
// found a valid string.
return $strfiltername;
}
// Fall through to try the legacy location.
// TODO: deprecated since 2.2, will be out in 2.3, see MDL-29996 if (get_string_manager()->string_exists('filtername', 'filter_' . $filter)) {
case 'mod': return get_string('filtername', 'filter_' . $filter);
$strfiltername = get_string('filtername', $filter); } else {
if (substr($strfiltername, 0, 2) == '[[') { return $filter;
$strfiltername .= ' (' . $type . '/' . $filter . ')';
}
return $strfiltername;
default:
throw new coding_exception('Unknown filter type ' . $type);
} }
} }
/** /**
* Get the names of all the filters installed in this Moodle. * Get the names of all the filters installed in this Moodle.
* *
* @global object
* @return array path => filter name from the appropriate lang file. e.g. * @return array path => filter name from the appropriate lang file. e.g.
* array('mod/glossary' => 'Glossary Auto-linking', 'filter/tex' => 'TeX Notation'); * array('tex' => 'TeX Notation');
* sorted in alphabetical order of name. * sorted in alphabetical order of name.
*/ */
function filter_get_all_installed() { function filter_get_all_installed() {
global $CFG; global $CFG;
$filternames = array(); $filternames = array();
// TODO: deprecated since 2.2, will be out in 2.3, see MDL-29996 foreach (get_list_of_plugins('filter') as $filter) {
$filterlocations = array('mod', 'filter'); if (is_readable("$CFG->dirroot/filter/$filter/filter.php")) {
foreach ($filterlocations as $filterlocation) { $filternames[$filter] = filter_get_name($filter);
// TODO: move get_list_of_plugins() to get_plugin_list()
$filters = get_list_of_plugins($filterlocation);
foreach ($filters as $filter) {
// MDL-29994 - Ignore mod/data and mod/glossary filters forever, this will be out in 2.3
if ($filterlocation == 'mod' && ($filter == 'data' || $filter == 'glossary')) {
continue;
}
$path = $filterlocation . '/' . $filter;
if (is_readable($CFG->dirroot . '/' . $path . '/filter.php')) {
$strfiltername = filter_get_name($path);
$filternames[$path] = $strfiltername;
}
} }
} }
collatorlib::asort($filternames); collatorlib::asort($filternames);
@ -578,17 +496,11 @@ function filter_get_all_installed() {
/** /**
* Set the global activated state for a text filter. * Set the global activated state for a text filter.
* *
* @global object * @param string $filtername The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param int $state One of the values TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED.
* @param integer $state One of the values TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED. * @param int $move 1 means up, 0 means the same, -1 means down
* @param integer $sortorder (optional) a position in the sortorder to place this filter.
* If not given defaults to:
* No change in order if we are updating an existing record, and not changing to or from TEXTFILTER_DISABLED.
* Just after the last currently active filter when adding an unknown filter
* in state TEXTFILTER_ON or TEXTFILTER_OFF, or enabling/disabling an existing filter.
* Just after the very last filter when adding an unknown filter in state TEXTFILTER_DISABLED
*/ */
function filter_set_global_state($filter, $state, $sortorder = false) { function filter_set_global_state($filtername, $state, $move = 0) {
global $DB; global $DB;
// Check requested state is valid. // Check requested state is valid.
@ -597,84 +509,141 @@ function filter_set_global_state($filter, $state, $sortorder = false) {
"Must be one of TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED."); "Must be one of TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED.");
} }
// Check sortorder is valid. if ($move > 0) {
if ($sortorder !== false) { $move = 1;
if ($sortorder < 1 || $sortorder > $DB->get_field('filter_active', 'MAX(sortorder)', array()) + 1) { } else if ($move < 0) {
throw new coding_exception("Invalid sort order passed to filter_set_global_state."); $move = -1;
}
} }
// See if there is an existing record. if (strpos($filtername, 'filter/') === 0) {
//debugging("Old filtername '$filtername' parameter used in filter_set_global_state()", DEBUG_DEVELOPER);
$filtername = substr($filtername, 7);
} else if (strpos($filtername, '/') !== false) {
throw new coding_exception("Invalid filter name '$filtername' used in filter_set_global_state()");
}
$transaction = $DB->start_delegated_transaction();
$syscontext = context_system::instance(); $syscontext = context_system::instance();
$rec = $DB->get_record('filter_active', array('filter' => $filter, 'contextid' => $syscontext->id)); $filters = $DB->get_records('filter_active', array('contextid' => $syscontext->id), 'sortorder ASC');
if (empty($rec)) {
$insert = true; $on = array();
$rec = new stdClass; $off = array();
$rec->filter = $filter;
$rec->contextid = $syscontext->id; foreach($filters as $f) {
} else { if ($f->active == TEXTFILTER_DISABLED) {
$insert = false; $off[$f->filter] = $f;
if ($sortorder === false && !($rec->active == TEXTFILTER_DISABLED xor $state == TEXTFILTER_DISABLED)) { } else {
$sortorder = $rec->sortorder; $on[$f->filter] = $f;
} }
} }
// Automatic sort order. // Update the state or add new record.
if ($sortorder === false) { if (isset($on[$filtername])) {
if ($state == TEXTFILTER_DISABLED && $insert) { $filter = $on[$filtername];
$prevmaxsortorder = $DB->get_field('filter_active', 'MAX(sortorder)', array()); if ($filter->active != $state) {
} else { $filter->active = $state;
$prevmaxsortorder = $DB->get_field_select('filter_active', 'MAX(sortorder)', 'active <> ?', array(TEXTFILTER_DISABLED)); $DB->update_record('filter_active', $filter);
} if ($filter->active == TEXTFILTER_DISABLED) {
if (empty($prevmaxsortorder)) { unset($on[$filtername]);
$sortorder = 1; $off = array($filter->filter => $filter) + $off;
} else {
$sortorder = $prevmaxsortorder + 1;
if (!$insert && $state == TEXTFILTER_DISABLED) {
$sortorder = $prevmaxsortorder;
} }
} }
}
// Move any existing records out of the way of the sortorder. } else if (isset($off[$filtername])) {
if ($insert) { $filter = $off[$filtername];
$DB->execute('UPDATE {filter_active} SET sortorder = sortorder + 1 WHERE sortorder >= ?', array($sortorder)); if ($filter->active != $state) {
} else if ($sortorder != $rec->sortorder) { $filter->active = $state;
$sparesortorder = $DB->get_field('filter_active', 'MIN(sortorder)', array()) - 1; $DB->update_record('filter_active', $filter);
$DB->set_field('filter_active', 'sortorder', $sparesortorder, array('filter' => $filter, 'contextid' => $syscontext->id)); if ($filter->active != TEXTFILTER_DISABLED) {
if ($sortorder < $rec->sortorder) { unset($off[$filtername]);
$DB->execute('UPDATE {filter_active} SET sortorder = sortorder + 1 WHERE sortorder >= ? AND sortorder < ?', $on[$filter->filter] = $filter;
array($sortorder, $rec->sortorder)); }
} else if ($sortorder > $rec->sortorder) { }
$DB->execute('UPDATE {filter_active} SET sortorder = sortorder - 1 WHERE sortorder <= ? AND sortorder > ?',
array($sortorder, $rec->sortorder)); } else {
$filter = new stdClass();
$filter->filter = $filtername;
$filter->contextid = $syscontext->id;
$filter->active = $state;
$filter->sortorder = 99999;
$filter->id = $DB->insert_record('filter_active', $filter);
$filters[$filter->id] = $filter;
if ($state == TEXTFILTER_DISABLED) {
$off[$filter->filter] = $filter;
} else {
$on[$filter->filter] = $filter;
} }
} }
// Insert/update the new record. // Move only active.
$rec->active = $state; if ($move != 0 and isset($on[$filter->filter])) {
$rec->sortorder = $sortorder; $i = 1;
if ($insert) { foreach ($on as $f) {
$DB->insert_record('filter_active', $rec); $f->newsortorder = $i;
} else { $i++;
$DB->update_record('filter_active', $rec); }
$filter->newsortorder = $filter->newsortorder + $move;
foreach ($on as $f) {
if ($f->id == $filter->id) {
continue;
}
if ($f->newsortorder == $filter->newsortorder) {
if ($move == 1) {
$f->newsortorder = $f->newsortorder - 1;
} else {
$f->newsortorder = $f->newsortorder + 1;
}
}
}
collatorlib::asort_objects_by_property($on, 'newsortorder', collatorlib::SORT_NUMERIC);
} }
// Inactive are sorted by filter name.
collatorlib::asort_objects_by_property($off, 'filter', collatorlib::SORT_NATURAL);
// Update records if necessary.
$i = 1;
foreach ($on as $f) {
if ($f->sortorder != $i) {
$DB->set_field('filter_active', 'sortorder', $i, array('id'=>$f->id));
}
$i++;
}
foreach ($off as $f) {
if ($f->sortorder != $i) {
$DB->set_field('filter_active', 'sortorder', $i, array('id'=>$f->id));
}
$i++;
}
$transaction->allow_commit();
} }
/** /**
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param string $filtername The filter name, for example 'tex'.
* @return boolean is this filter allowed to be used on this site. That is, the * @return boolean is this filter allowed to be used on this site. That is, the
* admin has set the global 'active' setting to On, or Off, but available. * admin has set the global 'active' setting to On, or Off, but available.
*/ */
function filter_is_enabled($filter) { function filter_is_enabled($filtername) {
return array_key_exists($filter, filter_get_globally_enabled()); if (strpos($filtername, 'filter/') === 0) {
//debugging("Old filtername '$filtername' parameter used in filter_is_enabled()", DEBUG_DEVELOPER);
$filtername = substr($filtername, 7);
} else if (strpos($filtername, '/') !== false) {
throw new coding_exception("Invalid filter name '$filtername' used in filter_is_enabled()");
}
return array_key_exists($filtername, filter_get_globally_enabled());
} }
/** /**
* Return a list of all the filters that may be in use somewhere. * Return a list of all the filters that may be in use somewhere.
* *
* @staticvar array $enabledfilters * @staticvar array $enabledfilters
* @return array where the keys and values are both the filter name, like 'filter/tex'. * @return array where the keys and values are both the filter name, like 'tex'.
*/ */
function filter_get_globally_enabled() { function filter_get_globally_enabled() {
static $enabledfilters = null; static $enabledfilters = null;
@ -694,8 +663,7 @@ function filter_get_globally_enabled() {
* Return the names of the filters that should also be applied to strings * Return the names of the filters that should also be applied to strings
* (when they are enabled). * (when they are enabled).
* *
* @global object * @return array where the keys and values are both the filter name, like 'tex'.
* @return array where the keys and values are both the filter name, like 'filter/tex'.
*/ */
function filter_get_string_filters() { function filter_get_string_filters() {
global $CFG; global $CFG;
@ -711,7 +679,7 @@ function filter_get_string_filters() {
* Sets whether a particular active filter should be applied to all strings by * Sets whether a particular active filter should be applied to all strings by
* format_string, or just used by format_text. * format_string, or just used by format_text.
* *
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param string $filter The filter name, for example 'tex'.
* @param boolean $applytostrings if true, this filter will apply to format_string * @param boolean $applytostrings if true, this filter will apply to format_string
* and format_text, when it is enabled. * and format_text, when it is enabled.
*/ */
@ -732,8 +700,7 @@ function filter_set_applies_to_strings($filter, $applytostrings) {
/** /**
* Set the local activated state for a text filter. * Set the local activated state for a text filter.
* *
* @global object * @param string $filter The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
* @param integer $contextid The id of the context to get the local config for. * @param integer $contextid The id of the context to get the local config for.
* @param integer $state One of the values TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_INHERIT. * @param integer $state One of the values TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_INHERIT.
* @return void * @return void
@ -778,8 +745,7 @@ function filter_set_local_state($filter, $contextid, $state) {
/** /**
* Set a particular local config variable for a filter in a context. * Set a particular local config variable for a filter in a context.
* *
* @global object * @param string $filter The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
* @param integer $contextid The id of the context to get the local config for. * @param integer $contextid The id of the context to get the local config for.
* @param string $name the setting name. * @param string $name the setting name.
* @param string $value the corresponding value. * @param string $value the corresponding value.
@ -808,8 +774,7 @@ function filter_set_local_config($filter, $contextid, $name, $value) {
/** /**
* Remove a particular local config variable for a filter in a context. * Remove a particular local config variable for a filter in a context.
* *
* @global object * @param string $filter The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
* @param integer $contextid The id of the context to get the local config for. * @param integer $contextid The id of the context to get the local config for.
* @param string $name the setting name. * @param string $name the setting name.
*/ */
@ -824,8 +789,7 @@ function filter_unset_local_config($filter, $contextid, $name) {
* for you automatically. You only need this, for example, when you are getting * for you automatically. You only need this, for example, when you are getting
* the config so you can show the user an editing from. * the config so you can show the user an editing from.
* *
* @global object * @param string $filter The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
* @param integer $contextid The ID of the context to get the local config for. * @param integer $contextid The ID of the context to get the local config for.
* @return array of name => value pairs. * @return array of name => value pairs.
*/ */
@ -838,7 +802,6 @@ function filter_get_local_config($filter, $contextid) {
* This function is for use by backup. Gets all the filter information specific * This function is for use by backup. Gets all the filter information specific
* to one context. * to one context.
* *
* @global object
* @param int $contextid * @param int $contextid
* @return array Array with two elements. The first element is an array of objects with * @return array Array with two elements. The first element is an array of objects with
* fields filter and active. These come from the filter_active table. The * fields filter and active. These come from the filter_active table. The
@ -847,7 +810,6 @@ function filter_get_local_config($filter, $contextid) {
*/ */
function filter_get_all_local_settings($contextid) { function filter_get_all_local_settings($contextid) {
global $DB; global $DB;
$context = context_system::instance();
return array( return array(
$DB->get_records('filter_active', array('contextid' => $contextid), 'filter', 'filter,active'), $DB->get_records('filter_active', array('contextid' => $contextid), 'filter', 'filter,active'),
$DB->get_records('filter_config', array('contextid' => $contextid), 'filter,name', 'filter,name,value'), $DB->get_records('filter_config', array('contextid' => $contextid), 'filter,name', 'filter,name,value'),
@ -858,14 +820,13 @@ function filter_get_all_local_settings($contextid) {
* Get the list of active filters, in the order that they should be used * Get the list of active filters, in the order that they should be used
* for a particular context, along with any local configuration variables. * for a particular context, along with any local configuration variables.
* *
* @global object * @param context $context a context
* @param object $context a context
* @return array an array where the keys are the filter names, for example * @return array an array where the keys are the filter names, for example
* 'filter/tex' or 'mod/glossary' and the values are any local * 'tex' and the values are any local
* configuration for that filter, as an array of name => value pairs * configuration for that filter, as an array of name => value pairs
* from the filter_config table. In a lot of cases, this will be an * from the filter_config table. In a lot of cases, this will be an
* empty array. So, an example return value for this function might be * empty array. So, an example return value for this function might be
* array('filter/tex' => array(), 'mod/glossary' => array('glossaryid', 123)) * array(tex' => array())
*/ */
function filter_get_active_in_context($context) { function filter_get_active_in_context($context) {
global $DB, $FILTERLIB_PRIVATE; global $DB, $FILTERLIB_PRIVATE;
@ -891,15 +852,13 @@ function filter_get_active_in_context($context) {
JOIN {context} ctx ON f.contextid = ctx.id JOIN {context} ctx ON f.contextid = ctx.id
WHERE ctx.id IN ($contextids) WHERE ctx.id IN ($contextids)
GROUP BY filter GROUP BY filter
HAVING MAX(f.active * " . $DB->sql_cast_2signed('ctx.depth') . HAVING MAX(f.active * ctx.depth) > -MIN(f.active * ctx.depth)
") > -MIN(f.active * " . $DB->sql_cast_2signed('ctx.depth') . ")
) active ) active
LEFT JOIN {filter_config} fc ON fc.filter = active.filter AND fc.contextid = $context->id LEFT JOIN {filter_config} fc ON fc.filter = active.filter AND fc.contextid = $context->id
ORDER BY active.sortorder"; ORDER BY active.sortorder";
//TODO: remove sql_cast_2signed() once we do not support upgrade from Moodle 2.2
$rs = $DB->get_recordset_sql($sql); $rs = $DB->get_recordset_sql($sql);
// Masssage the data into the specified format to return. // Massage the data into the specified format to return.
$filters = array(); $filters = array();
foreach ($rs as $row) { foreach ($rs as $row) {
if (!isset($filters[$row->filter])) { if (!isset($filters[$row->filter])) {
@ -918,6 +877,7 @@ function filter_get_active_in_context($context) {
/** /**
* Preloads the list of active filters for all activities (modules) on the course * Preloads the list of active filters for all activities (modules) on the course
* using two database queries. * using two database queries.
*
* @param course_modinfo $modinfo Course object from get_fast_modinfo * @param course_modinfo $modinfo Course object from get_fast_modinfo
*/ */
function filter_preload_activities(course_modinfo $modinfo) { function filter_preload_activities(course_modinfo $modinfo) {
@ -1000,7 +960,7 @@ function filter_preload_activities(course_modinfo $modinfo) {
} }
} }
// Chuck away the ones that aren't active // Chuck away the ones that aren't active.
foreach ($courseactive as $filter=>$score) { foreach ($courseactive as $filter=>$score) {
if ($score <= 0) { if ($score <= 0) {
unset($courseactive[$filter]); unset($courseactive[$filter]);
@ -1010,7 +970,7 @@ function filter_preload_activities(course_modinfo $modinfo) {
} }
// Loop through the contexts to reconstruct filter_active lists for each // Loop through the contexts to reconstruct filter_active lists for each
// cm on the course // cm on the course.
if (!isset($FILTERLIB_PRIVATE->active)) { if (!isset($FILTERLIB_PRIVATE->active)) {
$FILTERLIB_PRIVATE->active = array(); $FILTERLIB_PRIVATE->active = array();
} }
@ -1023,18 +983,18 @@ function filter_preload_activities(course_modinfo $modinfo) {
foreach ($remainingactives[$contextid] as $row) { foreach ($remainingactives[$contextid] as $row) {
if ($row->active > 0 && empty($banned[$row->filter])) { if ($row->active > 0 && empty($banned[$row->filter])) {
// If it's marked active for specific context, add entry // If it's marked active for specific context, add entry
// (doesn't matter if one exists already) // (doesn't matter if one exists already).
$FILTERLIB_PRIVATE->active[$contextid][$row->filter] = array(); $FILTERLIB_PRIVATE->active[$contextid][$row->filter] = array();
} else { } else {
// If it's marked inactive, remove entry (doesn't matter // If it's marked inactive, remove entry (doesn't matter
// if it doesn't exist) // if it doesn't exist).
unset($FILTERLIB_PRIVATE->active[$contextid][$row->filter]); unset($FILTERLIB_PRIVATE->active[$contextid][$row->filter]);
} }
} }
} }
} }
// Process all config rows to add config data to these entries // Process all config rows to add config data to these entries.
foreach ($filterconfigs as $row) { foreach ($filterconfigs as $row) {
if (isset($FILTERLIB_PRIVATE->active[$row->contextid][$row->filter])) { if (isset($FILTERLIB_PRIVATE->active[$row->contextid][$row->filter])) {
$FILTERLIB_PRIVATE->active[$row->contextid][$row->filter][$row->name] = $row->value; $FILTERLIB_PRIVATE->active[$row->contextid][$row->filter][$row->name] = $row->value;
@ -1046,10 +1006,9 @@ function filter_preload_activities(course_modinfo $modinfo) {
* List all of the filters that are available in this context, and what the * List all of the filters that are available in this context, and what the
* local and inherited states of that filter are. * local and inherited states of that filter are.
* *
* @global object * @param context $context a context that is not the system context.
* @param object $context a context that is not the system context. * @return array an array with filter names, for example 'tex'
* @return array an array with filter names, for example 'filter/tex' or * as keys. and and the values are objects with fields:
* 'mod/glossary' as keys. and and the values are objects with fields:
* ->filter filter name, same as the key. * ->filter filter name, same as the key.
* ->localstate TEXTFILTER_ON/OFF/INHERIT * ->localstate TEXTFILTER_ON/OFF/INHERIT
* ->inheritedstate TEXTFILTER_ON/OFF - the state that will be used if localstate is set to TEXTFILTER_INHERIT. * ->inheritedstate TEXTFILTER_ON/OFF - the state that will be used if localstate is set to TEXTFILTER_INHERIT.
@ -1072,8 +1031,7 @@ function filter_get_available_in_context($context) {
ELSE fa.active END AS localstate, ELSE fa.active END AS localstate,
parent_states.inheritedstate parent_states.inheritedstate
FROM (SELECT f.filter, MAX(f.sortorder) AS sortorder, FROM (SELECT f.filter, MAX(f.sortorder) AS sortorder,
CASE WHEN MAX(f.active * " . $DB->sql_cast_2signed('ctx.depth') . CASE WHEN MAX(f.active * ctx.depth) > -MIN(f.active * ctx.depth) THEN " . TEXTFILTER_ON . "
") > -MIN(f.active * " . $DB->sql_cast_2signed('ctx.depth') . ") THEN " . TEXTFILTER_ON . "
ELSE " . TEXTFILTER_OFF . " END AS inheritedstate ELSE " . TEXTFILTER_OFF . " END AS inheritedstate
FROM {filter_active} f FROM {filter_active} f
JOIN {context} ctx ON f.contextid = ctx.id JOIN {context} ctx ON f.contextid = ctx.id
@ -1089,7 +1047,6 @@ function filter_get_available_in_context($context) {
/** /**
* This function is for use by the filter administration page. * This function is for use by the filter administration page.
* *
* @global object
* @return array 'filtername' => object with fields 'filter' (=filtername), 'active' and 'sortorder' * @return array 'filtername' => object with fields 'filter' (=filtername), 'active' and 'sortorder'
*/ */
function filter_get_global_states() { function filter_get_global_states() {
@ -1101,14 +1058,12 @@ function filter_get_global_states() {
/** /**
* Delete all the data in the database relating to a filter, prior to deleting it. * Delete all the data in the database relating to a filter, prior to deleting it.
* *
* @global object * @param string $filter The filter name, for example 'tex'.
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
*/ */
function filter_delete_all_for_filter($filter) { function filter_delete_all_for_filter($filter) {
global $DB; global $DB;
if (substr($filter, 0, 7) == 'filter/') {
unset_all_config_for_plugin('filter_' . basename($filter)); unset_all_config_for_plugin('filter_' . $filter);
}
$DB->delete_records('filter_active', array('filter' => $filter)); $DB->delete_records('filter_active', array('filter' => $filter));
$DB->delete_records('filter_config', array('filter' => $filter)); $DB->delete_records('filter_config', array('filter' => $filter));
} }
@ -1126,27 +1081,26 @@ function filter_delete_all_for_context($contextid) {
/** /**
* Does this filter have a global settings page in the admin tree? * Does this filter have a global settings page in the admin tree?
* (The settings page for a filter must be called, for example, * (The settings page for a filter must be called, for example, filtersettingfiltertex.)
* filtersettingfiltertex or filtersettingmodglossay.)
* *
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param string $filter The filter name, for example 'tex'.
* @return boolean Whether there should be a 'Settings' link on the config page. * @return boolean Whether there should be a 'Settings' link on the config page.
*/ */
function filter_has_global_settings($filter) { function filter_has_global_settings($filter) {
global $CFG; global $CFG;
$settingspath = $CFG->dirroot . '/' . $filter . '/filtersettings.php'; $settingspath = $CFG->dirroot . '/filter/' . $filter . '/filtersettings.php';
return is_readable($settingspath); return is_readable($settingspath);
} }
/** /**
* Does this filter have local (per-context) settings? * Does this filter have local (per-context) settings?
* *
* @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. * @param string $filter The filter name, for example 'tex'.
* @return boolean Whether there should be a 'Settings' link on the manage filters in context page. * @return boolean Whether there should be a 'Settings' link on the manage filters in context page.
*/ */
function filter_has_local_settings($filter) { function filter_has_local_settings($filter) {
global $CFG; global $CFG;
$settingspath = $CFG->dirroot . '/' . $filter . '/filterlocalsettings.php'; $settingspath = $CFG->dirroot . '/filter/' . $filter . '/filterlocalsettings.php';
return is_readable($settingspath); return is_readable($settingspath);
} }
@ -1162,7 +1116,7 @@ function filter_context_may_have_filter_settings($context) {
} }
/** /**
* Process phrases intelligently found within a HTML text (such as adding links) * Process phrases intelligently found within a HTML text (such as adding links).
* *
* @staticvar array $usedpharses * @staticvar array $usedpharses
* @param string $text the text that we are filtering * @param string $text the text that we are filtering
@ -1179,8 +1133,8 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
static $usedphrases; static $usedphrases;
$ignoretags = array(); //To store all the enclosig tags to be completely ignored $ignoretags = array(); // To store all the enclosig tags to be completely ignored.
$tags = array(); //To store all the simple tags to be ignored $tags = array(); // To store all the simple tags to be ignored.
if (!$overridedefaultignore) { if (!$overridedefaultignore) {
// A list of open/close tags that we should not replace within // A list of open/close tags that we should not replace within
@ -1192,12 +1146,12 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
$filterignoretagsclose = array('</head>', '</nolink>', '</span>', $filterignoretagsclose = array('</head>', '</nolink>', '</span>',
'</script>', '</textarea>', '</select>','</a>'); '</script>', '</textarea>', '</select>','</a>');
} else { } else {
// Set an empty default list // Set an empty default list.
$filterignoretagsopen = array(); $filterignoretagsopen = array();
$filterignoretagsclose = array(); $filterignoretagsclose = array();
} }
// Add the user defined ignore tags to the default list // Add the user defined ignore tags to the default list.
if ( is_array($ignoretagsopen) ) { if ( is_array($ignoretagsopen) ) {
foreach ($ignoretagsopen as $open) { foreach ($ignoretagsopen as $open) {
$filterignoretagsopen[] = $open; $filterignoretagsopen[] = $open;
@ -1207,41 +1161,41 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
} }
} }
/// Invalid prefixes and suffixes for the fullmatch searches // Invalid prefixes and suffixes for the fullmatch searches
/// Every "word" character, but the underscore, is a invalid suffix or prefix. // Every "word" character, but the underscore, is a invalid suffix or prefix.
/// (nice to use this because it includes national characters (accents...) as word characters. // (nice to use this because it includes national characters (accents...) as word characters.
$filterinvalidprefixes = '([^\W_])'; $filterinvalidprefixes = '([^\W_])';
$filterinvalidsuffixes = '([^\W_])'; $filterinvalidsuffixes = '([^\W_])';
//// Double up some magic chars to avoid "accidental matches" // Double up some magic chars to avoid "accidental matches"
$text = preg_replace('/([#*%])/','\1\1',$text); $text = preg_replace('/([#*%])/','\1\1',$text);
////Remove everything enclosed by the ignore tags from $text //Remove everything enclosed by the ignore tags from $text
filter_save_ignore_tags($text,$filterignoretagsopen,$filterignoretagsclose,$ignoretags); filter_save_ignore_tags($text,$filterignoretagsopen,$filterignoretagsclose,$ignoretags);
/// Remove tags from $text // Remove tags from $text
filter_save_tags($text,$tags); filter_save_tags($text,$tags);
/// Time to cycle through each phrase to be linked // Time to cycle through each phrase to be linked
$size = sizeof($link_array); $size = sizeof($link_array);
for ($n=0; $n < $size; $n++) { for ($n=0; $n < $size; $n++) {
$linkobject =& $link_array[$n]; $linkobject =& $link_array[$n];
/// Set some defaults if certain properties are missing // Set some defaults if certain properties are missing
/// Properties may be missing if the filterobject class has not been used to construct the object // Properties may be missing if the filterobject class has not been used to construct the object
if (empty($linkobject->phrase)) { if (empty($linkobject->phrase)) {
continue; continue;
} }
/// Avoid integers < 1000 to be linked. See bug 1446. // Avoid integers < 1000 to be linked. See bug 1446.
$intcurrent = intval($linkobject->phrase); $intcurrent = intval($linkobject->phrase);
if (!empty($intcurrent) && strval($intcurrent) == $linkobject->phrase && $intcurrent < 1000) { if (!empty($intcurrent) && strval($intcurrent) == $linkobject->phrase && $intcurrent < 1000) {
continue; continue;
} }
/// All this work has to be done ONLY it it hasn't been done before // All this work has to be done ONLY it it hasn't been done before
if (!$linkobject->work_calculated) { if (!$linkobject->work_calculated) {
if (!isset($linkobject->hreftagbegin) or !isset($linkobject->hreftagend)) { if (!isset($linkobject->hreftagbegin) or !isset($linkobject->hreftagend)) {
$linkobject->work_hreftagbegin = '<span class="highlight"'; $linkobject->work_hreftagbegin = '<span class="highlight"';
$linkobject->work_hreftagend = '</span>'; $linkobject->work_hreftagend = '</span>';
@ -1250,8 +1204,8 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
$linkobject->work_hreftagend = $linkobject->hreftagend; $linkobject->work_hreftagend = $linkobject->hreftagend;
} }
/// Double up chars to protect true duplicates // Double up chars to protect true duplicates
/// be cleared up before returning to the user. // be cleared up before returning to the user.
$linkobject->work_hreftagbegin = preg_replace('/([#*%])/','\1\1',$linkobject->work_hreftagbegin); $linkobject->work_hreftagbegin = preg_replace('/([#*%])/','\1\1',$linkobject->work_hreftagbegin);
if (empty($linkobject->casesensitive)) { if (empty($linkobject->casesensitive)) {
@ -1265,41 +1219,41 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
$linkobject->work_fullmatch = true; $linkobject->work_fullmatch = true;
} }
/// Strip tags out of the phrase // Strip tags out of the phrase
$linkobject->work_phrase = strip_tags($linkobject->phrase); $linkobject->work_phrase = strip_tags($linkobject->phrase);
/// Double up chars that might cause a false match -- the duplicates will // Double up chars that might cause a false match -- the duplicates will
/// be cleared up before returning to the user. // be cleared up before returning to the user.
$linkobject->work_phrase = preg_replace('/([#*%])/','\1\1',$linkobject->work_phrase); $linkobject->work_phrase = preg_replace('/([#*%])/','\1\1',$linkobject->work_phrase);
/// Set the replacement phrase properly // Set the replacement phrase properly
if ($linkobject->replacementphrase) { //We have specified a replacement phrase if ($linkobject->replacementphrase) { //We have specified a replacement phrase
/// Strip tags // Strip tags
$linkobject->work_replacementphrase = strip_tags($linkobject->replacementphrase); $linkobject->work_replacementphrase = strip_tags($linkobject->replacementphrase);
} else { //The replacement is the original phrase as matched below } else { //The replacement is the original phrase as matched below
$linkobject->work_replacementphrase = '$1'; $linkobject->work_replacementphrase = '$1';
} }
/// Quote any regular expression characters and the delimiter in the work phrase to be searched // Quote any regular expression characters and the delimiter in the work phrase to be searched
$linkobject->work_phrase = preg_quote($linkobject->work_phrase, '/'); $linkobject->work_phrase = preg_quote($linkobject->work_phrase, '/');
/// Work calculated // Work calculated
$linkobject->work_calculated = true; $linkobject->work_calculated = true;
} }
/// If $CFG->filtermatchoneperpage, avoid previously (request) linked phrases // If $CFG->filtermatchoneperpage, avoid previously (request) linked phrases
if (!empty($CFG->filtermatchoneperpage)) { if (!empty($CFG->filtermatchoneperpage)) {
if (!empty($usedphrases) && in_array($linkobject->work_phrase,$usedphrases)) { if (!empty($usedphrases) && in_array($linkobject->work_phrase,$usedphrases)) {
continue; continue;
} }
} }
/// Regular expression modifiers // Regular expression modifiers
$modifiers = ($linkobject->work_casesensitive) ? 's' : 'isu'; // works in unicode mode! $modifiers = ($linkobject->work_casesensitive) ? 's' : 'isu'; // works in unicode mode!
/// Do we need to do a fullmatch? // Do we need to do a fullmatch?
/// If yes then go through and remove any non full matching entries // If yes then go through and remove any non full matching entries
if ($linkobject->work_fullmatch) { if ($linkobject->work_fullmatch) {
$notfullmatches = array(); $notfullmatches = array();
$regexp = '/'.$filterinvalidprefixes.'('.$linkobject->work_phrase.')|('.$linkobject->work_phrase.')'.$filterinvalidsuffixes.'/'.$modifiers; $regexp = '/'.$filterinvalidprefixes.'('.$linkobject->work_phrase.')|('.$linkobject->work_phrase.')'.$filterinvalidsuffixes.'/'.$modifiers;
@ -1316,7 +1270,7 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
} }
} }
/// Finally we do our highlighting // Finally we do our highlighting
if (!empty($CFG->filtermatchonepertext) || !empty($CFG->filtermatchoneperpage)) { if (!empty($CFG->filtermatchonepertext) || !empty($CFG->filtermatchoneperpage)) {
$resulttext = preg_replace('/('.$linkobject->work_phrase.')/'.$modifiers, $resulttext = preg_replace('/('.$linkobject->work_phrase.')/'.$modifiers,
$linkobject->work_hreftagbegin. $linkobject->work_hreftagbegin.
@ -1330,43 +1284,43 @@ function filter_phrases($text, &$link_array, $ignoretagsopen=NULL, $ignoretagscl
} }
/// If the text has changed we have to look for links again // If the text has changed we have to look for links again
if ($resulttext != $text) { if ($resulttext != $text) {
/// Set $text to $resulttext // Set $text to $resulttext
$text = $resulttext; $text = $resulttext;
/// Remove everything enclosed by the ignore tags from $text // Remove everything enclosed by the ignore tags from $text
filter_save_ignore_tags($text,$filterignoretagsopen,$filterignoretagsclose,$ignoretags); filter_save_ignore_tags($text,$filterignoretagsopen,$filterignoretagsclose,$ignoretags);
/// Remove tags from $text // Remove tags from $text
filter_save_tags($text,$tags); filter_save_tags($text,$tags);
/// If $CFG->filtermatchoneperpage, save linked phrases to request // If $CFG->filtermatchoneperpage, save linked phrases to request
if (!empty($CFG->filtermatchoneperpage)) { if (!empty($CFG->filtermatchoneperpage)) {
$usedphrases[] = $linkobject->work_phrase; $usedphrases[] = $linkobject->work_phrase;
} }
} }
/// Replace the not full matches before cycling to next link object // Replace the not full matches before cycling to next link object
if (!empty($notfullmatches)) { if (!empty($notfullmatches)) {
$text = str_replace(array_keys($notfullmatches),$notfullmatches,$text); $text = str_replace(array_keys($notfullmatches),$notfullmatches,$text);
unset($notfullmatches); unset($notfullmatches);
} }
} }
/// Rebuild the text with all the excluded areas // Rebuild the text with all the excluded areas
if (!empty($tags)) { if (!empty($tags)) {
$text = str_replace(array_keys($tags), $tags, $text); $text = str_replace(array_keys($tags), $tags, $text);
} }
if (!empty($ignoretags)) { if (!empty($ignoretags)) {
$ignoretags = array_reverse($ignoretags); /// Reversed so "progressive" str_replace() will solve some nesting problems. $ignoretags = array_reverse($ignoretags); // Reversed so "progressive" str_replace() will solve some nesting problems.
$text = str_replace(array_keys($ignoretags),$ignoretags,$text); $text = str_replace(array_keys($ignoretags),$ignoretags,$text);
} }
//// Remove the protective doubleups // Remove the protective doubleups
$text = preg_replace('/([#*%])(\1)/','\1',$text); $text = preg_replace('/([#*%])(\1)/','\1',$text);
/// Add missing javascript for popus // Add missing javascript for popus
$text = filter_add_javascript($text); $text = filter_add_javascript($text);
@ -1415,10 +1369,10 @@ function filter_remove_duplicates($linkarray) {
**/ **/
function filter_save_ignore_tags(&$text, $filterignoretagsopen, $filterignoretagsclose, &$ignoretags) { function filter_save_ignore_tags(&$text, $filterignoretagsopen, $filterignoretagsclose, &$ignoretags) {
/// Remove everything enclosed by the ignore tags from $text // Remove everything enclosed by the ignore tags from $text
foreach ($filterignoretagsopen as $ikey=>$opentag) { foreach ($filterignoretagsopen as $ikey=>$opentag) {
$closetag = $filterignoretagsclose[$ikey]; $closetag = $filterignoretagsclose[$ikey];
/// form regular expression // form regular expression
$opentag = str_replace('/','\/',$opentag); // delimit forward slashes $opentag = str_replace('/','\/',$opentag); // delimit forward slashes
$closetag = str_replace('/','\/',$closetag); // delimit forward slashes $closetag = str_replace('/','\/',$closetag); // delimit forward slashes
$pregexp = '/'.$opentag.'(.*?)'.$closetag.'/is'; $pregexp = '/'.$opentag.'(.*?)'.$closetag.'/is';
@ -1464,10 +1418,10 @@ function filter_add_javascript($text) {
global $CFG; global $CFG;
if (stripos($text, '</html>') === FALSE) { if (stripos($text, '</html>') === FALSE) {
return $text; // this is not a html file return $text; // This is not a html file.
} }
if (strpos($text, 'onclick="return openpopup') === FALSE) { if (strpos($text, 'onclick="return openpopup') === FALSE) {
return $text; // no popup - no need to add javascript return $text; // No popup - no need to add javascript.
} }
$js =" $js ="
<script type=\"text/javascript\"> <script type=\"text/javascript\">
@ -1485,11 +1439,11 @@ function filter_add_javascript($text) {
// --> // -->
</script>"; </script>";
if (stripos($text, '</head>') !== FALSE) { if (stripos($text, '</head>') !== FALSE) {
//try to add it into the head element // Try to add it into the head element.
$text = str_ireplace('</head>', $js.'</head>', $text); $text = str_ireplace('</head>', $js.'</head>', $text);
return $text; return $text;
} }
//last chance - try adding head element // Last chance - try adding head element.
return preg_replace("/<html.*?>/is", "\\0<head>".$js.'</head>', $text); return preg_replace("/<html.*?>/is", "\\0<head>".$js.'</head>', $text);
} }

View file

@ -2654,12 +2654,12 @@ class plugininfo_filter extends plugininfo_base {
// get the list of filters from both /filter and /mod location // get the list of filters from both /filter and /mod location
$installed = filter_get_all_installed(); $installed = filter_get_all_installed();
foreach ($installed as $filterlegacyname => $displayname) { foreach ($installed as $name => $displayname) {
$plugin = new $typeclass(); $plugin = new $typeclass();
$plugin->type = $type; $plugin->type = $type;
$plugin->typerootdir = $typerootdir; $plugin->typerootdir = $typerootdir;
$plugin->name = self::normalize_legacy_name($filterlegacyname); $plugin->name = $name;
$plugin->rootdir = $CFG->dirroot . '/' . $filterlegacyname; $plugin->rootdir = "$CFG->dirroot/filter/$name";
$plugin->displayname = $displayname; $plugin->displayname = $displayname;
$plugin->load_disk_version(); $plugin->load_disk_version();
@ -2676,9 +2676,9 @@ class plugininfo_filter extends plugininfo_base {
// if we're upgrading from 1.9, the table does not exist yet // if we're upgrading from 1.9, the table does not exist yet
// if it does, make sure that all installed filters are registered // if it does, make sure that all installed filters are registered
$needsreload = false; $needsreload = false;
foreach (array_keys($installed) as $filterlegacyname) { foreach (array_keys($installed) as $name) {
if (!isset($globalstates[self::normalize_legacy_name($filterlegacyname)])) { if (!isset($globalstates[$name])) {
filter_set_global_state($filterlegacyname, TEXTFILTER_DISABLED); filter_set_global_state($name, TEXTFILTER_DISABLED);
$needsreload = true; $needsreload = true;
} }
} }
@ -2695,8 +2695,8 @@ class plugininfo_filter extends plugininfo_base {
$plugin->type = $type; $plugin->type = $type;
$plugin->typerootdir = $typerootdir; $plugin->typerootdir = $typerootdir;
$plugin->name = $name; $plugin->name = $name;
$plugin->rootdir = $CFG->dirroot . '/' . $info->legacyname; $plugin->rootdir = "$CFG->dirroot/filter/$name";
$plugin->displayname = $info->legacyname; $plugin->displayname = $name;
$plugin->load_db_version(); $plugin->load_db_version();
@ -2721,11 +2721,6 @@ class plugininfo_filter extends plugininfo_base {
* @see load_version_php() * @see load_version_php()
*/ */
protected function load_version_php() { protected function load_version_php() {
if (strpos($this->name, 'mod_') === 0) {
// filters bundled with modules do not have a version.php and so
// do not provide their own versioning information.
return new stdClass();
}
return parent::load_version_php(); return parent::load_version_php();
} }
@ -2733,8 +2728,7 @@ class plugininfo_filter extends plugininfo_base {
$globalstates = self::get_global_states(); $globalstates = self::get_global_states();
foreach ($globalstates as $filterlegacyname => $info) { foreach ($globalstates as $name => $info) {
$name = self::normalize_legacy_name($filterlegacyname);
if ($name === $this->name) { if ($name === $this->name) {
if ($info->active == TEXTFILTER_DISABLED) { if ($info->active == TEXTFILTER_DISABLED) {
return false; return false;
@ -2753,8 +2747,7 @@ class plugininfo_filter extends plugininfo_base {
if (!isset($globalstates[$this->name])) { if (!isset($globalstates[$this->name])) {
return parent::get_settings_section_name(); return parent::get_settings_section_name();
} }
$legacyname = $globalstates[$this->name]->legacyname; return 'filtersetting' . $this->name;
return 'filtersetting' . str_replace('/', '', $legacyname);
} }
public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
@ -2776,33 +2769,7 @@ class plugininfo_filter extends plugininfo_base {
} }
public function get_uninstall_url() { public function get_uninstall_url() {
return new moodle_url('/admin/filters.php', array('sesskey' => sesskey(), 'filterpath' => $this->name, 'action' => 'delete'));
if (strpos($this->name, 'mod_') === 0) {
return null;
} else {
$globalstates = self::get_global_states();
$legacyname = $globalstates[$this->name]->legacyname;
return new moodle_url('/admin/filters.php', array('sesskey' => sesskey(), 'filterpath' => $legacyname, 'action' => 'delete'));
}
}
/**
* Convert legacy filter names like 'filter/foo' or 'mod/bar' into frankenstyle
*
* @param string $legacyfiltername legacy filter name
* @return string frankenstyle-like name
*/
protected static function normalize_legacy_name($legacyfiltername) {
$name = str_replace('/', '_', $legacyfiltername);
if (strpos($name, 'filter_') === 0) {
$name = substr($name, 7);
if (empty($name)) {
throw new coding_exception('Unable to determine filter name: ' . $legacyfiltername);
}
}
return $name;
} }
/** /**
@ -2826,10 +2793,8 @@ class plugininfo_filter extends plugininfo_base {
$globalstatescache = array(); $globalstatescache = array();
} else { } else {
foreach (filter_get_global_states() as $legacyname => $info) { foreach (filter_get_global_states() as $name => $info) {
$name = self::normalize_legacy_name($legacyname);
$filterinfo = new stdClass(); $filterinfo = new stdClass();
$filterinfo->legacyname = $legacyname;
$filterinfo->active = $info->active; $filterinfo->active = $info->active;
$filterinfo->sortorder = $info->sortorder; $filterinfo->sortorder = $info->sortorder;
$globalstatescache[$name] = $filterinfo; $globalstatescache[$name] = $filterinfo;

View file

@ -44,7 +44,7 @@ class filter_active_global_testcase extends advanced_testcase {
private function assert_only_one_filter_globally($filter, $state) { private function assert_only_one_filter_globally($filter, $state) {
global $DB; global $DB;
$recs = $DB->get_records('filter_active'); $recs = $DB->get_records('filter_active');
$this->assertEquals(1, count($recs), 'More than one record returned %s.'); $this->assertCount(1, $recs);
$rec = reset($recs); $rec = reset($recs);
unset($rec->id); unset($rec->id);
$expectedrec = new stdClass(); $expectedrec = new stdClass();
@ -71,25 +71,25 @@ class filter_active_global_testcase extends advanced_testcase {
public function test_set_filter_globally_on() { public function test_set_filter_globally_on() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/name', TEXTFILTER_ON, 1); filter_set_global_state('name', TEXTFILTER_ON);
// Validate. // Validate.
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_ON); $this->assert_only_one_filter_globally('name', TEXTFILTER_ON);
} }
public function test_set_filter_globally_off() { public function test_set_filter_globally_off() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/name', TEXTFILTER_OFF, 1); filter_set_global_state('name', TEXTFILTER_OFF);
// Validate. // Validate.
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_OFF); $this->assert_only_one_filter_globally('name', TEXTFILTER_OFF);
} }
public function test_set_filter_globally_disabled() { public function test_set_filter_globally_disabled() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/name', TEXTFILTER_DISABLED, 1); filter_set_global_state('name', TEXTFILTER_DISABLED);
// Validate. // Validate.
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_DISABLED); $this->assert_only_one_filter_globally('name', TEXTFILTER_DISABLED);
} }
/** /**
@ -97,135 +97,93 @@ class filter_active_global_testcase extends advanced_testcase {
* @return void * @return void
*/ */
public function test_global_config_exception_on_invalid_state() { public function test_global_config_exception_on_invalid_state() {
filter_set_global_state('filter/name', 0, 1); filter_set_global_state('name', 0);
} }
public function test_set_no_sortorder_clash() { public function test_auto_sort_order() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/one', TEXTFILTER_DISABLED, 1); filter_set_global_state('one', TEXTFILTER_DISABLED);
filter_set_global_state('filter/two', TEXTFILTER_DISABLED, 1); filter_set_global_state('two', TEXTFILTER_DISABLED);
// Validate - should have pushed other filters down.
$this->assert_global_sort_order(array('filter/two', 'filter/one'));
}
public function test_auto_sort_order_disabled() {
// Setup fixture.
// Exercise SUT.
filter_set_global_state('filter/one', TEXTFILTER_DISABLED);
filter_set_global_state('filter/two', TEXTFILTER_DISABLED);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/one', 'filter/two')); $this->assert_global_sort_order(array('one', 'two'));
} }
public function test_auto_sort_order_enabled() { public function test_auto_sort_order_enabled() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/one', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/two', TEXTFILTER_OFF); filter_set_global_state('two', TEXTFILTER_OFF);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/one', 'filter/two')); $this->assert_global_sort_order(array('one', 'two'));
}
public function test_auto_sort_order_mixed() {
// Setup fixture.
// Exercise SUT.
filter_set_global_state('filter/0', TEXTFILTER_DISABLED);
filter_set_global_state('filter/1', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_DISABLED);
filter_set_global_state('filter/3', TEXTFILTER_OFF);
// Validate.
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/0', 'filter/2'));
} }
public function test_update_existing_dont_duplicate() { public function test_update_existing_dont_duplicate() {
// Setup fixture. // Setup fixture.
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_global_state('filter/name', TEXTFILTER_OFF); filter_set_global_state('name', TEXTFILTER_OFF);
// Validate. // Validate.
$this->assert_only_one_filter_globally('filter/name', TEXTFILTER_OFF); $this->assert_only_one_filter_globally('name', TEXTFILTER_OFF);
}
/**
* @expectedException coding_exception
* @return void
*/
public function test_sort_order_not_too_low() {
// Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON);
// Exercise SUT.
filter_set_global_state('filter/2', TEXTFILTER_ON, 0);
}
/**
* @expectedException coding_exception
* @return void
*/
public function test_sort_order_not_too_high() {
// Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON);
// Exercise SUT.
filter_set_global_state('filter/2', TEXTFILTER_ON, 3);
} }
public function test_update_reorder_down() { public function test_update_reorder_down() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_ON); filter_set_global_state('two', TEXTFILTER_ON);
filter_set_global_state('filter/3', TEXTFILTER_ON); filter_set_global_state('three', TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/2', TEXTFILTER_ON, 1); filter_set_global_state('two', TEXTFILTER_ON, -1);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/2', 'filter/1', 'filter/3')); $this->assert_global_sort_order(array('two', 'one', 'three'));
} }
public function test_update_reorder_up() { public function test_update_reorder_up() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_ON); filter_set_global_state('two', TEXTFILTER_ON);
filter_set_global_state('filter/3', TEXTFILTER_ON); filter_set_global_state('three', TEXTFILTER_ON);
filter_set_global_state('filter/4', TEXTFILTER_ON); filter_set_global_state('four', TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/2', TEXTFILTER_ON, 3); filter_set_global_state('two', TEXTFILTER_ON, 1);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/2', 'filter/4')); $this->assert_global_sort_order(array('one', 'three', 'two', 'four'));
} }
public function test_auto_sort_order_change_to_enabled() { public function test_auto_sort_order_change_to_enabled() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_DISABLED); filter_set_global_state('two', TEXTFILTER_DISABLED);
filter_set_global_state('filter/3', TEXTFILTER_DISABLED); filter_set_global_state('three', TEXTFILTER_DISABLED);
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/3', TEXTFILTER_ON); filter_set_global_state('three', TEXTFILTER_ON);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/1', 'filter/3', 'filter/2')); $this->assert_global_sort_order(array('one', 'three', 'two'));
} }
public function test_auto_sort_order_change_to_disabled() { public function test_auto_sort_order_change_to_disabled() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_ON); filter_set_global_state('two', TEXTFILTER_ON);
filter_set_global_state('filter/3', TEXTFILTER_DISABLED); filter_set_global_state('three', TEXTFILTER_DISABLED);
// Exercise SUT. // Exercise SUT.
filter_set_global_state('filter/1', TEXTFILTER_DISABLED); filter_set_global_state('one', TEXTFILTER_DISABLED);
// Validate. // Validate.
$this->assert_global_sort_order(array('filter/2', 'filter/1', 'filter/3')); $this->assert_global_sort_order(array('two', 'one', 'three'));
} }
public function test_filter_get_global_states() { public function test_filter_get_global_states() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/1', TEXTFILTER_ON); filter_set_global_state('one', TEXTFILTER_ON);
filter_set_global_state('filter/2', TEXTFILTER_OFF); filter_set_global_state('two', TEXTFILTER_OFF);
filter_set_global_state('filter/3', TEXTFILTER_DISABLED); filter_set_global_state('three', TEXTFILTER_DISABLED);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_global_states(); $filters = filter_get_global_states();
// Validate. // Validate.
$this->assertEquals(array( $this->assertEquals(array(
'filter/1' => (object) array('filter' => 'filter/1', 'active' => TEXTFILTER_ON, 'sortorder' => 1), 'one' => (object) array('filter' => 'one', 'active' => TEXTFILTER_ON, 'sortorder' => 1),
'filter/2' => (object) array('filter' => 'filter/2', 'active' => TEXTFILTER_OFF, 'sortorder' => 2), 'two' => (object) array('filter' => 'two', 'active' => TEXTFILTER_OFF, 'sortorder' => 2),
'filter/3' => (object) array('filter' => 'filter/3', 'active' => TEXTFILTER_DISABLED, 'sortorder' => 3) 'three' => (object) array('filter' => 'three', 'active' => TEXTFILTER_DISABLED, 'sortorder' => 3)
), $filters); ), $filters);
} }
} }
@ -264,21 +222,21 @@ class filter_active_local_testcase extends advanced_testcase {
public function test_local_on() { public function test_local_on() {
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', 123, TEXTFILTER_ON); filter_set_local_state('name', 123, TEXTFILTER_ON);
// Validate. // Validate.
$this->assert_only_one_local_setting('filter/name', 123, TEXTFILTER_ON); $this->assert_only_one_local_setting('name', 123, TEXTFILTER_ON);
} }
public function test_local_off() { public function test_local_off() {
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', 123, TEXTFILTER_OFF); filter_set_local_state('name', 123, TEXTFILTER_OFF);
// Validate. // Validate.
$this->assert_only_one_local_setting('filter/name', 123, TEXTFILTER_OFF); $this->assert_only_one_local_setting('name', 123, TEXTFILTER_OFF);
} }
public function test_local_inherit() { public function test_local_inherit() {
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT); filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
// Validate. // Validate.
$this->assert_no_local_setting(); $this->assert_no_local_setting();
} }
@ -289,7 +247,7 @@ class filter_active_local_testcase extends advanced_testcase {
*/ */
public function test_local_invalid_state_throws_exception() { public function test_local_invalid_state_throws_exception() {
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', 123, -9999); filter_set_local_state('name', 123, -9999);
} }
/** /**
@ -298,14 +256,14 @@ class filter_active_local_testcase extends advanced_testcase {
*/ */
public function test_throws_exception_when_setting_global() { public function test_throws_exception_when_setting_global() {
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', context_system::instance()->id, TEXTFILTER_INHERIT); filter_set_local_state('name', context_system::instance()->id, TEXTFILTER_INHERIT);
} }
public function test_local_inherit_deletes_existing() { public function test_local_inherit_deletes_existing() {
// Setup fixture. // Setup fixture.
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT); filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
// Exercise SUT. // Exercise SUT.
filter_set_local_state('filter/name', 123, TEXTFILTER_INHERIT); filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
// Validate. // Validate.
$this->assert_no_local_setting(); $this->assert_no_local_setting();
} }
@ -340,28 +298,28 @@ class filter_config_testcase extends advanced_testcase {
public function test_set_new_config() { public function test_set_new_config() {
// Exercise SUT. // Exercise SUT.
filter_set_local_config('filter/name', 123, 'settingname', 'An arbitrary value'); filter_set_local_config('name', 123, 'settingname', 'An arbitrary value');
// Validate. // Validate.
$this->assert_only_one_config('filter/name', 123, 'settingname', 'An arbitrary value'); $this->assert_only_one_config('name', 123, 'settingname', 'An arbitrary value');
} }
public function test_update_existing_config() { public function test_update_existing_config() {
// Setup fixture. // Setup fixture.
filter_set_local_config('filter/name', 123, 'settingname', 'An arbitrary value'); filter_set_local_config('name', 123, 'settingname', 'An arbitrary value');
// Exercise SUT. // Exercise SUT.
filter_set_local_config('filter/name', 123, 'settingname', 'A changed value'); filter_set_local_config('name', 123, 'settingname', 'A changed value');
// Validate. // Validate.
$this->assert_only_one_config('filter/name', 123, 'settingname', 'A changed value'); $this->assert_only_one_config('name', 123, 'settingname', 'A changed value');
} }
public function test_filter_get_local_config() { public function test_filter_get_local_config() {
// Setup fixture. // Setup fixture.
filter_set_local_config('filter/name', 123, 'setting1', 'An arbitrary value'); filter_set_local_config('name', 123, 'setting1', 'An arbitrary value');
filter_set_local_config('filter/name', 123, 'setting2', 'Another arbitrary value'); filter_set_local_config('name', 123, 'setting2', 'Another arbitrary value');
filter_set_local_config('filter/name', 122, 'settingname', 'Value from another context'); filter_set_local_config('name', 122, 'settingname', 'Value from another context');
filter_set_local_config('filter/other', 123, 'settingname', 'Someone else\'s value'); filter_set_local_config('other', 123, 'settingname', 'Someone else\'s value');
// Exercise SUT. // Exercise SUT.
$config = filter_get_local_config('filter/name', 123); $config = filter_get_local_config('name', 123);
// Validate. // Validate.
$this->assertEquals(array('setting1' => 'An arbitrary value', 'setting2' => 'Another arbitrary value'), $config); $this->assertEquals(array('setting1' => 'An arbitrary value', 'setting2' => 'Another arbitrary value'), $config);
} }
@ -398,18 +356,18 @@ class filter_get_active_available_in_context_testcase extends advanced_testcase
public function test_globally_on_is_returned() { public function test_globally_on_is_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$syscontext); $filters = filter_get_active_in_context(self::$syscontext);
// Validate. // Validate.
$this->assert_filter_list(array('filter/name'), $filters); $this->assert_filter_list(array('name'), $filters);
// Check no config returned correctly. // Check no config returned correctly.
$this->assertEquals(array(), $filters['filter/name']); $this->assertEquals(array(), $filters['name']);
} }
public function test_globally_off_not_returned() { public function test_globally_off_not_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_OFF); filter_set_global_state('name', TEXTFILTER_OFF);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext2); $filters = filter_get_active_in_context(self::$childcontext2);
// Validate. // Validate.
@ -418,18 +376,18 @@ class filter_get_active_available_in_context_testcase extends advanced_testcase
public function test_globally_off_overridden() { public function test_globally_off_overridden() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_OFF); filter_set_global_state('name', TEXTFILTER_OFF);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext2); $filters = filter_get_active_in_context(self::$childcontext2);
// Validate. // Validate.
$this->assert_filter_list(array('filter/name'), $filters); $this->assert_filter_list(array('name'), $filters);
} }
public function test_globally_on_overridden() { public function test_globally_on_overridden() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_OFF);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext2); $filters = filter_get_active_in_context(self::$childcontext2);
// Validate. // Validate.
@ -438,8 +396,8 @@ class filter_get_active_available_in_context_testcase extends advanced_testcase
public function test_globally_disabled_not_overridden() { public function test_globally_disabled_not_overridden() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_DISABLED); filter_set_global_state('name', TEXTFILTER_DISABLED);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$syscontext); $filters = filter_get_active_in_context(self::$syscontext);
// Validate. // Validate.
@ -448,45 +406,45 @@ class filter_get_active_available_in_context_testcase extends advanced_testcase
public function test_single_config_returned() { public function test_single_config_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value'); filter_set_local_config('name', self::$childcontext->id, 'settingname', 'A value');
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext); $filters = filter_get_active_in_context(self::$childcontext);
// Validate. // Validate.
$this->assertEquals(array('settingname' => 'A value'), $filters['filter/name']); $this->assertEquals(array('settingname' => 'A value'), $filters['name']);
} }
public function test_multi_config_returned() { public function test_multi_config_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value'); filter_set_local_config('name', self::$childcontext->id, 'settingname', 'A value');
filter_set_local_config('filter/name', self::$childcontext->id, 'anothersettingname', 'Another value'); filter_set_local_config('name', self::$childcontext->id, 'anothersettingname', 'Another value');
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext); $filters = filter_get_active_in_context(self::$childcontext);
// Validate. // Validate.
$this->assertEquals(array('settingname' => 'A value', 'anothersettingname' => 'Another value'), $filters['filter/name']); $this->assertEquals(array('settingname' => 'A value', 'anothersettingname' => 'Another value'), $filters['name']);
} }
public function test_config_from_other_context_not_returned() { public function test_config_from_other_context_not_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value'); filter_set_local_config('name', self::$childcontext->id, 'settingname', 'A value');
filter_set_local_config('filter/name', self::$childcontext2->id, 'anothersettingname', 'Another value'); filter_set_local_config('name', self::$childcontext2->id, 'anothersettingname', 'Another value');
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext2); $filters = filter_get_active_in_context(self::$childcontext2);
// Validate. // Validate.
$this->assertEquals(array('anothersettingname' => 'Another value'), $filters['filter/name']); $this->assertEquals(array('anothersettingname' => 'Another value'), $filters['name']);
} }
public function test_config_from_other_filter_not_returned() { public function test_config_from_other_filter_not_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_config('filter/name', self::$childcontext->id, 'settingname', 'A value'); filter_set_local_config('name', self::$childcontext->id, 'settingname', 'A value');
filter_set_local_config('filter/other', self::$childcontext->id, 'anothersettingname', 'Another value'); filter_set_local_config('other', self::$childcontext->id, 'anothersettingname', 'Another value');
// Exercise SUT. // Exercise SUT.
$filters = filter_get_active_in_context(self::$childcontext); $filters = filter_get_active_in_context(self::$childcontext);
// Validate. // Validate.
$this->assertEquals(array('settingname' => 'A value'), $filters['filter/name']); $this->assertEquals(array('settingname' => 'A value'), $filters['name']);
} }
protected function assert_one_available_filter($filter, $localstate, $inheritedstate, $filters) { protected function assert_one_available_filter($filter, $localstate, $inheritedstate, $filters) {
@ -502,28 +460,28 @@ class filter_get_active_available_in_context_testcase extends advanced_testcase
public function test_available_in_context_localoverride() { public function test_available_in_context_localoverride() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_OFF);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_available_in_context(self::$childcontext); $filters = filter_get_available_in_context(self::$childcontext);
// Validate. // Validate.
$this->assert_one_available_filter('filter/name', TEXTFILTER_OFF, TEXTFILTER_ON, $filters); $this->assert_one_available_filter('name', TEXTFILTER_OFF, TEXTFILTER_ON, $filters);
} }
public function test_available_in_context_nolocaloverride() { public function test_available_in_context_nolocaloverride() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_OFF); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_OFF);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_available_in_context(self::$childcontext2); $filters = filter_get_available_in_context(self::$childcontext2);
// Validate. // Validate.
$this->assert_one_available_filter('filter/name', TEXTFILTER_INHERIT, TEXTFILTER_OFF, $filters); $this->assert_one_available_filter('name', TEXTFILTER_INHERIT, TEXTFILTER_OFF, $filters);
} }
public function test_available_in_context_disabled_not_returned() { public function test_available_in_context_disabled_not_returned() {
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_DISABLED); filter_set_global_state('name', TEXTFILTER_DISABLED);
filter_set_local_state('filter/name', self::$childcontext->id, TEXTFILTER_ON); filter_set_local_state('name', self::$childcontext->id, TEXTFILTER_ON);
// Exercise SUT. // Exercise SUT.
$filters = filter_get_available_in_context(self::$childcontext); $filters = filter_get_available_in_context(self::$childcontext);
// Validate. // Validate.
@ -610,43 +568,43 @@ class filter_preload_activities_testcase extends advanced_testcase {
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Enable filter globally, check // Enable filter globally, check
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Disable for activity 2 // Disable for activity 2
filter_set_local_state('filter/name', self::$activity2context->id, TEXTFILTER_OFF); filter_set_local_state('name', self::$activity2context->id, TEXTFILTER_OFF);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Disable at category // Disable at category
filter_set_local_state('filter/name', self::$catcontext->id, TEXTFILTER_OFF); filter_set_local_state('name', self::$catcontext->id, TEXTFILTER_OFF);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Enable for activity 1 // Enable for activity 1
filter_set_local_state('filter/name', self::$activity1context->id, TEXTFILTER_ON); filter_set_local_state('name', self::$activity1context->id, TEXTFILTER_ON);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Disable globally // Disable globally
filter_set_global_state('filter/name', TEXTFILTER_DISABLED); filter_set_global_state('name', TEXTFILTER_DISABLED);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Add another 2 filters // Add another 2 filters
filter_set_global_state('filter/frog', TEXTFILTER_ON); filter_set_global_state('frog', TEXTFILTER_ON);
filter_set_global_state('filter/zombie', TEXTFILTER_ON); filter_set_global_state('zombie', TEXTFILTER_ON);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Disable random one of these in each context // Disable random one of these in each context
filter_set_local_state('filter/zombie', self::$activity1context->id, TEXTFILTER_OFF); filter_set_local_state('zombie', self::$activity1context->id, TEXTFILTER_OFF);
filter_set_local_state('filter/frog', self::$activity2context->id, TEXTFILTER_OFF); filter_set_local_state('frog', self::$activity2context->id, TEXTFILTER_OFF);
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
// Now do some filter options // Now do some filter options
filter_set_local_config('filter/name', self::$activity1context->id, 'a', 'x'); filter_set_local_config('name', self::$activity1context->id, 'a', 'x');
filter_set_local_config('filter/zombie', self::$activity1context->id, 'a', 'y'); filter_set_local_config('zombie', self::$activity1context->id, 'a', 'y');
filter_set_local_config('filter/frog', self::$activity1context->id, 'a', 'z'); filter_set_local_config('frog', self::$activity1context->id, 'a', 'z');
// These last two don't do anything as they are not at final level but I // These last two don't do anything as they are not at final level but I
// thought it would be good to have that verified in test // thought it would be good to have that verified in test
filter_set_local_config('filter/frog', self::$coursecontext->id, 'q', 'x'); filter_set_local_config('frog', self::$coursecontext->id, 'q', 'x');
filter_set_local_config('filter/frog', self::$catcontext->id, 'q', 'z'); filter_set_local_config('frog', self::$catcontext->id, 'q', 'z');
$this->assert_matches($modinfo); $this->assert_matches($modinfo);
} }
} }
@ -666,19 +624,19 @@ class filter_delete_config_testcase extends advanced_testcase {
global $DB; global $DB;
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_global_state('filter/other', TEXTFILTER_ON); filter_set_global_state('other', TEXTFILTER_ON);
filter_set_local_config('filter/name', context_system::instance()->id, 'settingname', 'A value'); filter_set_local_config('name', context_system::instance()->id, 'settingname', 'A value');
filter_set_local_config('filter/other', context_system::instance()->id, 'settingname', 'Other value'); filter_set_local_config('other', context_system::instance()->id, 'settingname', 'Other value');
set_config('configname', 'A config value', 'filter_name'); set_config('configname', 'A config value', 'filter_name');
set_config('configname', 'Other config value', 'filter_other'); set_config('configname', 'Other config value', 'filter_other');
// Exercise SUT. // Exercise SUT.
filter_delete_all_for_filter('filter/name'); filter_delete_all_for_filter('name');
// Validate. // Validate.
$this->assertEquals(1, $DB->count_records('filter_active')); $this->assertEquals(1, $DB->count_records('filter_active'));
$this->assertTrue($DB->record_exists('filter_active', array('filter' => 'filter/other'))); $this->assertTrue($DB->record_exists('filter_active', array('filter' => 'other')));
$this->assertEquals(1, $DB->count_records('filter_config')); $this->assertEquals(1, $DB->count_records('filter_config'));
$this->assertTrue($DB->record_exists('filter_config', array('filter' => 'filter/other'))); $this->assertTrue($DB->record_exists('filter_config', array('filter' => 'other')));
$expectedconfig = new stdClass; $expectedconfig = new stdClass;
$expectedconfig->configname = 'Other config value'; $expectedconfig->configname = 'Other config value';
$this->assertEquals($expectedconfig, get_config('filter_other')); $this->assertEquals($expectedconfig, get_config('filter_other'));
@ -689,18 +647,18 @@ class filter_delete_config_testcase extends advanced_testcase {
global $DB; global $DB;
// Setup fixture. // Setup fixture.
filter_set_global_state('filter/name', TEXTFILTER_ON); filter_set_global_state('name', TEXTFILTER_ON);
filter_set_local_state('filter/name', 123, TEXTFILTER_OFF); filter_set_local_state('name', 123, TEXTFILTER_OFF);
filter_set_local_config('filter/name', 123, 'settingname', 'A value'); filter_set_local_config('name', 123, 'settingname', 'A value');
filter_set_local_config('filter/other', 123, 'settingname', 'Other value'); filter_set_local_config('other', 123, 'settingname', 'Other value');
filter_set_local_config('filter/other', 122, 'settingname', 'Other value'); filter_set_local_config('other', 122, 'settingname', 'Other value');
// Exercise SUT. // Exercise SUT.
filter_delete_all_for_context(123); filter_delete_all_for_context(123);
// Validate. // Validate.
$this->assertEquals(1, $DB->count_records('filter_active')); $this->assertEquals(1, $DB->count_records('filter_active'));
$this->assertTrue($DB->record_exists('filter_active', array('contextid' => context_system::instance()->id))); $this->assertTrue($DB->record_exists('filter_active', array('contextid' => context_system::instance()->id)));
$this->assertEquals(1, $DB->count_records('filter_config')); $this->assertEquals(1, $DB->count_records('filter_config'));
$this->assertTrue($DB->record_exists('filter_config', array('filter' => 'filter/other'))); $this->assertTrue($DB->record_exists('filter_config', array('filter' => 'other')));
} }
} }
@ -735,9 +693,9 @@ class filter_filter_set_applies_to_strings extends advanced_testcase {
$CFG->filterall = 0; $CFG->filterall = 0;
$CFG->stringfilters = ''; $CFG->stringfilters = '';
// Exercise SUT. // Exercise SUT.
filter_set_applies_to_strings('filter/name', true); filter_set_applies_to_strings('name', true);
// Validate. // Validate.
$this->assertEquals('filter/name', $CFG->stringfilters); $this->assertEquals('name', $CFG->stringfilters);
$this->assertEquals(1, $CFG->filterall); $this->assertEquals(1, $CFG->filterall);
} }
@ -745,9 +703,9 @@ class filter_filter_set_applies_to_strings extends advanced_testcase {
global $CFG; global $CFG;
// Setup fixture. // Setup fixture.
$CFG->filterall = 1; $CFG->filterall = 1;
$CFG->stringfilters = 'filter/name'; $CFG->stringfilters = 'name';
// Exercise SUT. // Exercise SUT.
filter_set_applies_to_strings('filter/name', false); filter_set_applies_to_strings('name', false);
// Validate. // Validate.
$this->assertEquals('', $CFG->stringfilters); $this->assertEquals('', $CFG->stringfilters);
$this->assertEquals('', $CFG->filterall); $this->assertEquals('', $CFG->filterall);
@ -757,11 +715,11 @@ class filter_filter_set_applies_to_strings extends advanced_testcase {
global $CFG; global $CFG;
// Setup fixture. // Setup fixture.
$CFG->filterall = 1; $CFG->filterall = 1;
$CFG->stringfilters = 'filter/name,filter/other'; $CFG->stringfilters = 'name,other';
// Exercise SUT. // Exercise SUT.
filter_set_applies_to_strings('filter/name', false); filter_set_applies_to_strings('name', false);
// Validate. // Validate.
$this->assertEquals('filter/other', $CFG->stringfilters); $this->assertEquals('other', $CFG->stringfilters);
$this->assertEquals(1, $CFG->filterall); $this->assertEquals(1, $CFG->filterall);
} }
} }

View file

@ -2,6 +2,10 @@ This files describes API changes in /mod/* - activity modules,
information provided here is intended especially for developers. information provided here is intended especially for developers.
=== 2.5 ===
* support for 'mod/*' filters was removed
=== 2.4 === === 2.4 ===
new features: new features:

View file

@ -218,7 +218,7 @@ function report_security_check_mediafilterswf($detailed=false) {
$activefilters = filter_get_globally_enabled(); $activefilters = filter_get_globally_enabled();
if (array_search('filter/mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) { if (array_search('mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) {
$result->status = REPORT_SECURITY_CRITICAL; $result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_mediafilterswf_error', 'report_security'); $result->info = get_string('check_mediafilterswf_error', 'report_security');
} else { } else {

View file

@ -30,7 +30,7 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$version = 2012120300.06; // YYYYMMDD = weekly release date of this DEV branch $version = 2012120300.07; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches // RR = release increments - 00 in DEV branches
// .XX = incremental changes // .XX = incremental changes