From: tjhunt Date: Mon, 13 Apr 2009 07:03:32 +0000 (+0000) Subject: filters: MDL-7336 redo global settings page to use the new libs X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=456c8cc738dc8d244355701cb35ad23d856e9cad;p=moodle.git filters: MDL-7336 redo global settings page to use the new libs Note: ->stringfilters update not done yet. --- diff --git a/admin/filters.php b/admin/filters.php index 411751fd69..71e324e11c 100644 --- a/admin/filters.php +++ b/admin/filters.php @@ -1,12 +1,44 @@ wwwroot/$CFG->admin/settings.php?section=managefilters"; @@ -14,89 +46,90 @@ 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&filterpath=' . $delete . '&confirm=1&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); - -?> diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php index da31d7e386..243a69c6a2 100644 --- a/lang/en_utf8/admin.php +++ b/lang/en_utf8/admin.php @@ -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 $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 MDL-11061.'; @@ -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'; diff --git a/lang/en_utf8/filters.php b/lang/en_utf8/filters.php index 3608dd6742..7758886f2b 100644 --- a/lang/en_utf8/filters.php +++ b/lang/en_utf8/filters.php @@ -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'; diff --git a/lib/adminlib.php b/lib/adminlib.php index f771db5af2..524c727bf8 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -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() . + '&filterpath=' . urlencode($filterpath) . '&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 '' . + '' . $straction . ' '; + } - // 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') . '&newstate=', $this->activechoices, + 'active' . basename($filter), $filterinfo->active, '', '', '', true, 'self', '', NULL, get_string('save')); + + $updown = ''; + $spacer = ' '; + 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 = '' . $this->strsettings . ''; } - 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 = ""; - $hideshow .= "pixpath}/i/hide.gif\" class=\"icon\" alt=\"$strhide\" />"; - $hidden = false; - $displayname = "$name"; - } - else { - $hideshow = ""; - $hideshow .= "pixpath}/i/show.gif\" class=\"icon\" alt=\"$strshow\" />"; - $hidden = true; - $displayname = "$name"; - } - - // get up/down link (only if not hidden) - $updown = ''; - if (!$hidden) { - if ($updowncount>1) { - $updown .= ""; - $updown .= "\"$strup\" "; - } - else { - $updown .= "pixpath/spacer.gif\" class=\"icon\" alt=\"\" /> "; - } - if ($updowncount<$activefilterscount) { - $updown .= ""; - $updown .= "\"$strdown\""; - } - else { - $updown .= "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 = "$strsettings"; + // 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); diff --git a/lib/filterlib.php b/lib/filterlib.php index e953c850a4..129bfec20b 100644 --- a/lib/filterlib.php +++ b/lib/filterlib.php @@ -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) * diff --git a/lib/simpletest/testfilterconfig.php b/lib/simpletest/testfilterconfig.php index 5f16665a66..e1ee4a9bc4 100644 --- a/lib/simpletest/testfilterconfig.php +++ b/lib/simpletest/testfilterconfig.php @@ -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')); + } +} ?>