]> git.mjollnir.org Git - moodle.git/commitdiff
filters: MDL-7336 redo global settings page to use the new libs
authortjhunt <tjhunt>
Mon, 13 Apr 2009 07:03:32 +0000 (07:03 +0000)
committertjhunt <tjhunt>
Mon, 13 Apr 2009 07:03:32 +0000 (07:03 +0000)
Note: ->stringfilters update not done yet.

admin/filters.php
lang/en_utf8/admin.php
lang/en_utf8/filters.php
lib/adminlib.php
lib/filterlib.php
lib/simpletest/testfilterconfig.php

index 411751fd69dd288a5d465ce955d7296bfa656e6a..71e324e11cf09ea24e3bbe25e730ebe55a2e7dfd 100644 (file)
@@ -1,12 +1,44 @@
 <?php // $Id$
 
-    require_once('../config.php');
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.org                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
 
-    $action     = optional_param('action', '', PARAM_ACTION);
+/**
+ * Processes actions from the admin_setting_managefilters object (defined in
+ * adminlib.php).
+ *
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package administration
+ *//** */
+
+    require_once(dirname(__FILE__) . '/../config.php');
+
+    $action = optional_param('action', '', PARAM_ACTION);
     $filterpath = optional_param('filterpath', '', PARAM_PATH);
 
     require_login();
-    require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+    $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+    require_capability('moodle/site:config', $systemcontext);
 
     $returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=managefilters";
 
         redirect($returnurl);
     }
 
-    // get a list of installed filters
-    $installedfilters = array();
-    $filterlocations = array('mod','filter');
-    foreach ($filterlocations as $filterlocation) {
-        $plugins = get_list_of_plugins($filterlocation);
-        foreach ($plugins as $plugin) {
-            $pluginpath = "$CFG->dirroot/$filterlocation/$plugin/filter.php";
-            if (is_readable($pluginpath)) {
-                $installedfilters["$filterlocation/$plugin"] = "$filterlocation/$plugin";
-            }
-        }
-    }
+    $filters = filter_get_global_states();
 
-    // get all the currently selected filters
-    if (!empty($CFG->textfilters)) {
-        $activefilters = explode(',', $CFG->textfilters);
-    } else {
-        $activefilters = array();
+    // In case any new filters have been installed, but not put in the table yet.
+    $fitlernames = filter_get_all_installed();
+    $newfilters = $fitlernames;
+    foreach ($filters as $filter => $notused) {
+        unset($newfilters[$filter]);
     }
 
-    //======================
-    // Process Actions
-    //======================
+    if (!isset($filters[$filterpath]) && !isset($newfilters[$filterpath])) {
+        throw new moodle_exception('filternotinstalled', 'error', $returnurl, $filterpath);
+    }
 
     switch ($action) {
 
-    case 'hide':
-        $key=array_search($filterpath, $activefilters);
-        // check filterpath is valid
-        if ($key===false) {
-            break;
-        }
-        // just delete it
-        unset($activefilters[$key]);
-        break;
-
-    case 'show':
-        // check filterpath is valid
-        if (!array_key_exists($filterpath, $installedfilters)) {
-            print_error('filternotinstalled', 'error', $url, $filterpath);
-        } elseif (array_search($filterpath,$activefilters)) {
-            // filterpath is already active - doubleclick??
-        } else {
-            // add it to installed filters
-            $activefilters[] = $filterpath;
-            $activefilters = array_unique($activefilters);
+    case 'setstate':
+        if ($newstate = optional_param('newstate', '', PARAM_INTEGER)) {
+            filter_set_global_state($filterpath, $newstate);
+            unset($newfilters[$filterpath]);
         }
         break;
 
     case 'down':
-        $key=array_search($filterpath, $activefilters);
-        // check filterpath is valid
-        if ($key===false) {
-            print_error("filternotactive", 'error', $url, $filterpath );
-        } elseif ($key>=(count($activefilters)-1)) {
-            // cannot be moved any further down - doubleclick??
-        } else {
-            // swap with $key+1
-            $fsave = $activefilters[$key];
-            $activefilters[$key] = $activefilters[$key+1];
-            $activefilters[$key+1] = $fsave;
+        if (isset($filters[$filterpath])) {
+            $oldpos = $filters[$filterpath]->sortorder;
+            if ($oldpos <= count($filters)) {
+                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos + 1);
+            }
         }
         break;
 
     case 'up':
-        $key=array_search($filterpath, $activefilters);
-        // check filterpath is valid
-        if ($key===false) {
-            print_error("filternotactive", 'error', $url, $filterpath );
-        } elseif ($key<1) {
-            //cannot be moved any further up - doubleclick??
-        } else {
-            // swap with $key-1
-            $fsave = $activefilters[$key];
-            $activefilters[$key] = $activefilters[$key-1];
-            $activefilters[$key-1] = $fsave;
+        if (isset($filters[$filterpath])) {
+            $oldpos = $filters[$filterpath]->sortorder;
+            if ($oldpos >= 1) {
+                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos - 1);
+            }
         }
         break;
+
+    case 'delete':
+        $filtername = $fitlernames[$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', admin_url('qtypes.php'), $a);
+        }
+
+        // If not yet confirmed, display a confirmation message.
+        if (!optional_param('confirm', '', PARAM_BOOL)) {
+            $title = get_string('deletefilterareyousure', 'admin', $filtername);
+            print_header($title, $title);
+            print_heading($title);
+            notice_yesno(get_string('deletefilterareyousuremessage', 'admin', $filtername),
+                    admin_url('filters.php?action=delete&amp;filterpath=' . $delete . '&amp;confirm=1&amp;sesskey=' . sesskey()),
+                    $returnurl, NULL, NULL, 'post', 'get');
+            print_footer('empty');
+            exit;
+        }
+
+        // Do the deletion.
+        $title = get_string('deletingfilter', 'admin', $filtername);
+        print_header($title, $title);
+        print_heading($title);
+
+        // Delete all data for this plugin.
+        filter_delete_all_data($filterpath);
+
+        $a = new stdClass;
+        $a->fitler = $filtername;
+        $a->directory = $filterparth;
+        print_box(get_string('deletefilterfiles', 'admin', $a), 'generalbox', 'notice');
+        print_continue($returnurl);
+        admin_externalpage_print_footer();
+        exit;
     }
 
-    // save, reset cache and return
-    set_config('textfilters', implode(',', $activefilters));
+    // Add any missing filters to the DB table.
+    foreach ($newfilters as $filter => $notused) {
+        filter_set_global_state($filter, TEXTFILTER_DISABLED);
+    }
+
+    // Reset caches and return
     reset_text_filters_cache();
     redirect($returnurl);
-
-?>
index da31d7e3863c34252b6fca3980243b1363c8f83e..243a69c6a258d1ef2488aed17b27232b8c1e2a03 100644 (file)
@@ -46,6 +46,7 @@ $string['calendar_weekend'] = 'Weekend Days';
 $string['calendarexportsalt'] = 'Calendar export salt';
 $string['calendarsettings'] = 'Calendar';
 $string['cannotdeletemissingqtype'] = 'You cannot delete the missing question type. It is needed by the system.';
+$string['cannotdeletemodfilter'] = 'You cannot uninstall the \'$a->filter\' because it is part of the \'$a->module\' module.';
 $string['cannotdeleteqtypeinuse'] = 'You cannot delete the question type \'$a\'. There are questions of this type in the question bank.';
 $string['cannotdeleteqtypeneeded'] = 'You cannot delete the question type \'$a\'. There are other question types installed that rely on it.';
 $string['cfgwwwrootwarning'] = 'You have defined &#36;CFG->wwwroot incorrectly in your config.php file. It does not match the URL you are using to access this page. Please correct it, or you will experience strange bugs like <a href=\'http://tracker.moodle.org/browse/MDL-11061\'>MDL-11061</a>.';
@@ -334,11 +335,15 @@ $string['defaultsettinginfo'] = 'Default: $a';
 $string['defaultuserroleid'] = 'Default role for all users';
 $string['defaultvalues'] = 'Default values';
 $string['deleteerrors'] = 'Delete errors';
+$string['deletefilterareyousure'] = 'Are you sure you want to delete the filter \'$a\'';
+$string['deletefilterareyousuremessage'] = 'You are about to completely delete the filter \'$a\'. Are you sure you want to uninstall it?';
+$string['deletefilterfiles'] = 'All data associated with the filter \'$a->filter\' has been deleted from the database. To complete the deletion (and to prevent the filter from re-installing itself), you should now delete this directory from your server: $a->directory';
 $string['deleteincompleteusers'] = 'Delete incomplete users after';
 $string['deleteqtypeareyousure'] = 'Are you sure you want to delete the question type \'$a\'';
 $string['deleteqtypeareyousuremessage'] = 'You are about to completely delete the question type \'$a\'. Are you sure you want to uninstall it?';
 $string['deleteunconfirmed'] = 'Delete not fully setup users after';
 $string['deleteuser'] = 'Delete user';
+$string['deletingfilter'] = 'Deleting filter \'$a\'';
 $string['deletingqtype'] = 'Deleting question type \'$a\'';
 $string['density'] = 'Density';
 $string['denyemailaddresses'] = 'Denied email domains';
index 3608dd6742ecaa51a76bb6eaed85e9472b3c4f5e..7758886f2b177924058f32cf3a727af5a921ca1e 100644 (file)
@@ -6,8 +6,11 @@ $string['anycourse'] = 'any course';
 $string['anyfield'] = 'any field';
 $string['anyrole'] = 'any role';
 $string['anyvalue'] = 'any value';
+$string['applyto'] = 'Apply to';
 $string['categoryrole'] = 'Category role';
 $string['tablenosave'] = 'Changes in table above are saved automatically.';
+$string['content'] = 'Content';
+$string['contentandheadings'] = 'Content and headings';
 $string['contains'] = 'contains';
 $string['courserole'] = 'Course role';
 $string['courserolelabel'] = '$a->label is $a->rolename in $a->coursename from $a->categoryname';
@@ -15,10 +18,12 @@ $string['courserolelabelerror'] = '$a->label error: course $a->coursename does n
 $string['datelabelisafter'] = '$a->label is after $a->after';
 $string['datelabelisbefore'] = '$a->label is before $a->before';
 $string['datelabelisbetween'] = '$a->label is between $a->after and $a->before';
+$string['disabled'] = 'Disabled';
 $string['doesnotcontain'] = 'doesn\'t contain';
 $string['endswith'] = 'ends with';
 $string['firstaccess'] = 'First access';
 $string['globalrolelabel'] = '$a->label is $a->value';
+$string['isactive'] = 'Active?';
 $string['isanyvalue'] = 'is any value';
 $string['isafter'] = 'is after';
 $string['isbefore'] = 'is before';
@@ -28,6 +33,8 @@ $string['isequalto'] = 'is equal to';
 $string['isnotequalto'] = 'isn\'t equal to';
 $string['isnotdefined'] = 'isn\'t defined';
 $string['newfilter'] = 'New filter';
+$string['offbutavailable'] = 'Off, but available';
+$string['on'] = 'On';
 $string['profilelabel'] = '$a->label: $a->profile $a->operator $a->value';
 $string['profilelabelnovalue'] = '$a->label: $a->profile $a->operator';
 $string['removeall'] = 'Remove all filters';
index f771db5af2a34b2b6fb3b5fe7110a372b8e570af..524c727bf8ead2bf9a202ff20acf9bb3aede0dc8 100644 (file)
@@ -3711,7 +3711,8 @@ class admin_setting_managefilters extends admin_setting {
     }
 
     public function write_setting($data) {
-        // do not write any setting
+        // do not write any settings. Instead all our UI submits to admin/filters.php
+        // which makes and changes, then redirects back.
         return '';
     }
 
@@ -3734,119 +3735,120 @@ class admin_setting_managefilters extends admin_setting {
         return false;
     }
 
-    public function output_html($data, $query='') {
+    protected function action_url($filterpath, $action) {
         global $CFG;
+        return $CFG->wwwroot . '/' . $CFG->admin . '/filters.php?sesskey=' . sesskey() .
+                '&amp;filterpath=' . urlencode($filterpath) . '&amp;action=' . $action;
+    }
 
-        $strname     = get_string('name');
-        $strhide     = get_string('disable');
-        $strshow     = get_string('enable');
-        $strhideshow = "$strhide/$strshow";
-        $strsettings = get_string('settings');
-        $strup       = get_string('up');
-        $strdown     = get_string('down');
-        $strupdown   = "$strup/$strdown";
-
-        // get a list of possible filters (and translate name if possible)
-        // note filters can be in the dedicated filters area OR in their
-        // associated modules
-        $installedfilters = filter_get_all_installed();
-        $filtersettings_new = array();
-        foreach ($installedfilters as $path => $strfiltername) {
-            $settingspath_new = $CFG->dirroot . '/' . $path . '/filtersettings.php';
-            if (is_readable($settingspath_new)) {
-                $filtersettings_new[] = $path;
-            }
-        }
+    protected function action_icon($url, $icon, $straction) {
+        global $CFG;
+        return '<a href="' . $url . '" title="' . $straction . '">' .
+                '<img src="' . $CFG->pixpath . '/t/' . $icon . '.gif" alt="' . $straction . '" /></a> ';
+    }
 
-        // get all the currently selected filters
-        if (!empty($CFG->textfilters)) {
-            $oldactivefilters = explode(',', $CFG->textfilters);
-            $oldactivefilters = array_unique($oldactivefilters);
-        } else {
-            $oldactivefilters = array();
-        }
+    protected function get_table_row($filterinfo, $isfirstrow, $islastactive) {
+        global $CFG;
+        $row = array();
+        $filter = $filterinfo->filter;
 
-        // take this opportunity to clean up filters
-        $activefilters = array();
-        foreach ($oldactivefilters as $oldactivefilter) {
-            if (!empty($oldactivefilter) and array_key_exists($oldactivefilter, $installedfilters)) {
-                $activefilters[] = $oldactivefilter;
+        $row[] = $this->filternames[$filter];
+
+        $row[] = popup_form($this->action_url($filter, 'setstate') . '&amp;newstate=', $this->activechoices,
+                'active' . basename($filter), $filterinfo->active, '', '', '', true, 'self', '', NULL, get_string('save'));
+
+        $updown = '';
+        $spacer = '<img src="' . $CFG->pixpath . '/spacer.gif" class="iconsmall" alt="" /> ';
+        if ($filterinfo->active != TEXTFILTER_DISABLED) {
+            if (!$isfirstrow) {
+                $updown .= $this->action_icon($this->action_url($filter, 'up'), 'up', $this->strup);
+            } else {
+                $updown .= $spacer;
+            }
+            if (!$islastactive) {
+                $updown .= $this->action_icon($this->action_url($filter, 'down'), 'down', $this->strdown);
+            } else {
+                $updown .= $spacer;
             }
         }
+        $row[] = $updown;
 
-        // Get the list of all filters, and pull the active filters
-        // to the top.
-        $displayfilters = array();
-        foreach ($activefilters as $activefilter) {
-            $name = $installedfilters[$activefilter];
-            $displayfilters[$activefilter] = $name;
+        $row[] = 'TODO Apply to col';
+
+        // settings link (if defined)
+        $settings = '';
+        if (filter_has_global_settings($filter)) {
+            $settings = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' .
+                    str_replace('/', '',$filter) . '">' . $this->strsettings . '</a>';
         }
-        foreach ($installedfilters as $key => $filter) {
-            if (!array_key_exists($key, $displayfilters)) {
-                $displayfilters[$key] = $filter;
-            }
+        $row[] = $settings;
+
+        return $row;
+    }
+
+    public function output_html($data, $query='') {
+        global $CFG;
+
+        $this->activechoices = array(
+            TEXTFILTER_DISABLED => get_string('disabled', 'filters'),
+            TEXTFILTER_OFF => get_string('offbutavailable', 'filters'),
+            TEXTFILTER_ON => get_string('on', 'filters'),
+        );
+        $this->applytochoices = array(
+            1 => get_string('content', 'filters'),
+            3 => get_string('contentandheadings', 'filters'),
+        );
+        $this->strup = get_string('up');
+        $this->strdown = get_string('down');
+        $this->strsettings = get_string('settings');
+
+        $filters = filter_get_global_states();
+
+        // In case any new filters have been installed, but not put in the table yet.
+        $this->filternames = filter_get_all_installed();
+        $newfilters = $this->filternames;
+        foreach ($filters as $filter => $notused) {
+            unset($newfilters[$filter]);
         }
 
         $return = print_heading(get_string('actfilterhdr', 'filters'), '', 3, 'main', true);
         $return .= print_box_start('generalbox filtersui', '', true);
 
         $table = new object();
-        $table->head  = array($strname, $strhideshow, $strupdown, $strsettings);
-        $table->align = array('left', 'center', 'center', 'center');
+        $table->head  = array(get_string('filter'), get_string('isactive', 'filters'),
+                get_string('order'), get_string('applyto', 'filters'), $this->strsettings);
+        $table->align = array('left', 'left', 'center', 'left', 'left');
         $table->width = '90%';
         $table->data  = array();
 
-        $filtersurl = "$CFG->wwwroot/$CFG->admin/filters.php?sesskey=".sesskey();
-        $imgurl     = "$CFG->pixpath/t";
-
-        // iterate through filters adding to display table
-        $updowncount = 1;
-        $activefilterscount = count($activefilters);
-        foreach ($displayfilters as $path => $name) {
-            $upath = urlencode($path);
-            // get hide/show link
-            if (in_array($path, $activefilters)) {
-                $hideshow = "<a href=\"$filtersurl&amp;action=hide&amp;filterpath=$upath\">";
-                $hideshow .= "<img src=\"{$CFG->pixpath}/i/hide.gif\" class=\"icon\" alt=\"$strhide\" /></a>";
-                $hidden = false;
-                $displayname = "<span>$name</span>";
-            }
-            else {
-                $hideshow = "<a href=\"$filtersurl&amp;action=show&amp;filterpath=$upath\">";
-                $hideshow .= "<img src=\"{$CFG->pixpath}/i/show.gif\" class=\"icon\" alt=\"$strshow\" /></a>";
-                $hidden = true;
-                $displayname = "<span class=\"dimmed_text\">$name</span>";
-            }
-
-            // get up/down link (only if not hidden)
-            $updown = '';
-            if (!$hidden) {
-                if ($updowncount>1) {
-                    $updown .= "<a href=\"$filtersurl&amp;action=up&amp;filterpath=$upath\">";
-                    $updown .= "<img src=\"$imgurl/up.gif\" alt=\"$strup\" /></a>&nbsp;";
-                }
-                else {
-                    $updown .= "<img src=\"$CFG->pixpath/spacer.gif\" class=\"icon\" alt=\"\" />&nbsp;";
-                }
-                if ($updowncount<$activefilterscount) {
-                    $updown .= "<a href=\"$filtersurl&amp;action=down&amp;filterpath=$upath\">";
-                    $updown .= "<img src=\"$imgurl/down.gif\" alt=\"$strdown\" /></a>";
-                }
-                else {
-                    $updown .= "<img src=\"$CFG->pixpath/spacer.gif\" class=\"icon\" alt=\"\" />";
-                }
-                ++$updowncount;
+        $lastactive = null;
+        foreach ($filters as $filter => $filterinfo) {
+            if ($filterinfo->active != TEXTFILTER_DISABLED) {
+                $lastactive = $filter;
             }
+        }
 
-            // settings link (if defined)
-            $settings = '';
-            if (in_array($path, $filtersettings_new)) {
-                $settings = "<a href=\"settings.php?section=filtersetting".str_replace('/', '',$path)."\">$strsettings</a>";
+        // iterate through filters adding to display table
+        $firstrow = true;
+        foreach ($filters as $filter => $filterinfo) {
+            $row = $this->get_table_row($filterinfo, $firstrow, $filter == $lastactive);
+            $table->data[] = $row;
+            if ($filterinfo->active == TEXTFILTER_DISABLED) {
+                $table->rowclass[] = 'dimmed_text';
+            } else {
+                $table->rowclass[] = '';
             }
-
-            // write data into the table object
-            $table->data[] = array($displayname, $hideshow, $updown, $settings);
+            $firstrow = false;
+        }
+        foreach ($newfilters as $filter => $filtername) {
+            $filterinfo = new stdClass;
+            $filterinfo->filter = $filter;
+            $filterinfo->active = TEXTFILTER_DISABLED;
+            $row = $this->get_table_row($filterinfo, $firstrow, $filter == $lastactive);
+            $table->data[] = $row;
+            $table->rowclass[] = 'dimmed_text';
         }
+
         $return .= print_table($table, true);
         $return .= get_string('tablenosave', 'filters');
         $return .= print_box_end(true);
index e953c850a48a76a16acac87c13772b21e4aa9fed..129bfec20b4203c4dd5ac8b7b78dba5988bee9fe 100644 (file)
@@ -573,6 +573,43 @@ function filter_get_active_in_context($context) {
     return $filters;
 }
 
+/**
+ * This function is for use by the filter administration page.
+ * @return array 'filtername' => object with fields 'filter' (=filtername), 'active' and 'sortorder'
+ */
+function filter_get_global_states() {
+    global $DB;
+    $context = get_context_instance(CONTEXT_SYSTEM);
+    return $DB->get_records('filter_active', array('contextid' => $context->id), 'sortorder', 'filter,active,sortorder');
+}
+
+/**
+ * Delete all the data in the database relating to a filter, prior to deleting it.
+ * @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
+ */
+function filter_delete_all_data($filter) {
+    global $DB;
+    if (substr($filter, 0, 7) == 'filter/') {
+        unset_all_config_for_plugin('filter_' . basename($filter));
+    }
+    $DB->delete_records('filter_active', array('filter' => $filter));
+    $DB->delete_records('filter_config', array('filter' => $filter));
+}
+
+/**
+ * Does this filter have a global settings page in the admin tree?
+ * (The settings page for a filter must be called, for example,
+ * filtersettingfiltertex or filtersettingmodglossay.)
+ *
+ * @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'.
+ * @return boolean Whether there should be a 'Settings' link on the config page.
+ */
+function filter_has_global_settings($filter) {
+    global $CFG;
+    $settingspath = $CFG->dirroot . '/' . $filter . '/filtersettings.php';
+    return is_readable($settingspath);
+}
+
 /**
  * Process phrases intelligently found within a HTML text (such as adding links)
  *
index 5f16665a66cbbd5a5b2c028eb62dc7832270df0e..e1ee4a9bc4640d9879e479097f033054c44a733e 100644 (file)
@@ -217,6 +217,21 @@ class filter_active_global_test extends UnitTestCaseUsingDatabase {
         // Validate.
         $this->assert_global_sort_order(array('filter/2', 'filter/1', 'filter/3'));
     }
+
+    public function test_filter_get_global_states() {
+        // Setup fixture.
+        filter_set_global_state('filter/1', TEXTFILTER_ON);
+        filter_set_global_state('filter/2', TEXTFILTER_OFF);
+        filter_set_global_state('filter/3', TEXTFILTER_DISABLED);
+        // Exercise SUT.
+        $filters = filter_get_global_states();
+        // Validate.
+        $this->assertEqual(array(
+            'filter/1' => (object) array('filter' => 'filter/1', 'active' => TEXTFILTER_ON, 'sortorder' => 1),
+            'filter/2' => (object) array('filter' => 'filter/2', 'active' => TEXTFILTER_OFF, 'sortorder' => 2),
+            'filter/3' => (object) array('filter' => 'filter/3', 'active' => TEXTFILTER_DISABLED, 'sortorder' => 3)
+        ), $filters);
+    }
 }
 
 /**
@@ -477,4 +492,34 @@ class filter_get_active_in_context_test extends UnitTestCaseUsingDatabase {
     }
 }
 
+class filter_delete_all_data_test extends UnitTestCaseUsingDatabase {
+    private $syscontext;
+    private $childcontext;
+    private $childcontext2;
+
+    public function setUp() {
+        // Create the table we need and switch to test DB.
+        $this->create_test_tables(array('filter_active', 'filter_config', 'config', 'config_plugins'), 'lib');
+        $this->switch_to_test_db();
+    }
+
+    public function test_filter_delete_all_data_filter() {
+        $syscontext = get_context_instance(CONTEXT_SYSTEM);
+        filter_set_global_state('filter/name', TEXTFILTER_ON);
+        filter_set_global_state('filter/other', TEXTFILTER_ON);
+        filter_set_local_config('filter/name', $syscontext->id, 'settingname', 'A value');
+        filter_set_local_config('filter/other', $syscontext->id, 'settingname', 'Other value');
+        set_config('configname', 'A config value', 'filter_name');
+        set_config('configname', 'Other config value', 'filter_other');
+        filter_delete_all_data('filter/name');
+        $this->assertEqual(1, $this->testdb->count_records('filter_active'));
+        $this->assertTrue($this->testdb->record_exists('filter_active', array('filter' => 'filter/other')));
+        $this->assertEqual(1, $this->testdb->count_records('filter_config'));
+        $this->assertTrue($this->testdb->record_exists('filter_config', array('filter' => 'filter/other')));
+        $expectedconfig = new stdClass;
+        $expectedconfig->configname = 'Other config value';
+        $this->assertEqual($expectedconfig, get_config('filter_other'));
+        $this->assertFalse(get_config('filter_name'));
+    }
+}
 ?>