MDL-27171 messages: add default message outputs management interface

This introduces the new page where admin may change the permissions and
defaults for particular combination of message processors and providers.

Signed-off-by: Ruslan Kabalin <ruslan.kabalin@luns.net.uk>
This commit is contained in:
Ruslan Kabalin 2011-05-13 11:13:13 +01:00
parent e710658d89
commit 1d72e9d441
8 changed files with 326 additions and 23 deletions

View File

@ -49,6 +49,7 @@ if ($hassiteconfig) {
// message outputs
$ADMIN->add('modules', new admin_category('messageoutputs', get_string('messageoutputs', 'message')));
$ADMIN->add('messageoutputs', new admin_page_managemessageoutputs());
$ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs());
require_once($CFG->dirroot.'/message/lib.php');
$processors = get_message_processors();
foreach ($processors as $processor) {
@ -56,8 +57,8 @@ if ($hassiteconfig) {
if (!$processor->available) {
continue;
}
$strprocessorname = get_string('pluginname', 'message_'.$processorname);
if (file_exists($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php')) {
if ($processor->hassettings) {
$strprocessorname = get_string('pluginname', 'message_'.$processorname);
$settings = new admin_settingpage('messagesetting'.$processorname, $strprocessorname, 'moodle/site:config', !$processor->enabled);
include($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php');
if ($settings) {

View File

@ -42,14 +42,18 @@ $string['contactlistempty'] = 'Your contact list is empty';
$string['contacts'] = 'Contacts';
$string['context'] = 'context';
$string['couldnotfindpreference'] = 'Could not load preference {$a}. Does the component and name you supplied to message_send() match a row in message_providers? Message providers must appear in the database so users can configure how they will be notified when they receive messages.';
$string['defaultmessageoutputs'] = 'Default message outputs';
$string['defaults'] = 'Defaults';
$string['deletemessagesdays'] = 'Number of days before old messages are automatically deleted';
$string['disabled'] = 'Messaging is disabled on this site';
$string['disallowed'] = 'Disallowed';
$string['discussion'] = 'Discussion';
$string['editmymessage'] = 'Messaging';
$string['emailmessages'] = 'Email messages when I am offline';
$string['emailtagline'] = 'This is a copy of a message sent to you at "{$a->sitename}". Go to {$a->url} to reply.';
$string['emptysearchstring'] = 'You must search for something';
$string['errorcallingprocessor'] = 'Error calling defined processor';
$string['forced'] = 'Forced';
$string['formorethan'] = 'For more than';
$string['guestnoeditmessage'] = 'Guest user can not edit messaging options';
$string['guestnoeditmessageother'] = 'Guest user can not edit other user messaging options';
@ -98,6 +102,7 @@ $string['outputenabled'] = 'Output enabled';
$string['outputnotavailable'] = 'Not available';
$string['outputnotconfigured'] = 'Not configured';
$string['pagerefreshes'] = 'This page refreshes automatically every {$a} seconds';
$string['permitted'] = 'Permitted';
$string['private_config'] = 'Popup message window';
$string['processortag'] = 'Destination';
$string['providers_config'] = 'Configure notification methods for incoming messages';
@ -110,6 +115,8 @@ $string['search'] = 'Search';
$string['searchforperson'] = 'Search for a person';
$string['searchmessages'] = 'Search messages';
$string['searchcombined'] = 'Search people and messages';
$string['sendingvia'] = 'Sending {$a->provider} via {$a->processor}';
$string['sendingviawhen'] = 'Sending {$a->provider} via {$a->processor} when {$a->state}';
$string['sendmessage'] = 'Send message';
$string['sendmessageto'] = 'Send message to {$a}';
$string['sendmessagetopopup'] = 'Send message to {$a} - new window';

View File

@ -4965,6 +4965,21 @@ class admin_page_managemessageoutputs extends admin_externalpage {
}
}
/**
* Default message outputs configuration
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_page_defaultmessageoutputs extends admin_page_managemessageoutputs {
/**
* Calls parent::__construct with specific arguments
*/
public function __construct() {
global $CFG;
admin_externalpage::__construct('defaultmessageoutputs', get_string('defaultmessageoutputs', 'message'), "$CFG->wwwroot/message/defaultoutputs.php");
}
}
/**
* Question type manage page
*

View File

@ -445,6 +445,7 @@ class page_requirements_manager {
break;
case 'core_message':
$module = array('name' => 'core_message',
'requires' => array('base', 'node', 'event', 'node-event-simulate'),
'fullpath' => '/message/module.js');
break;
case 'core_flashdetect':

115
message/defaultoutputs.php Normal file
View File

@ -0,0 +1,115 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Default message outputs configuration page
*
* @package message
* @copyright 2011 Lancaster University Network Services Limited
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once(dirname(dirname(__FILE__)) . '/message/lib.php');
require_once($CFG->libdir.'/adminlib.php');
// This is an admin page
admin_externalpage_setup('defaultmessageoutputs');
// Require site configuration capability
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
// Fetch processors
$processors = get_message_processors(true);
// Fetch message providers
$providers = $DB->get_records('message_providers', null, 'name');
if (($form = data_submitted()) && confirm_sesskey()) {
$preferences = array();
// Prepare default message outputs settings
foreach ( $providers as $provider) {
$componentproviderbase = $provider->component.'_'.$provider->name;
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting){
$value = null;
$componentprovidersetting = $componentproviderbase.'_'.$setting;
if ($setting == 'permitted') {
// if we deal with permitted select element, we need to create individual
// setting for each possible processor. Note that this block will
// always be processed first after entring parental foreach iteration
// so we can change form values on this stage.
foreach($processors as $processor) {
$value = '';
if (isset($form->{$componentprovidersetting}[$processor->name])) {
$value = $form->{$componentprovidersetting}[$processor->name];
}
// Ensure that loggedin loggedoff options are set correctly
// for this permission
if ($value == 'forced') {
$form->{$componentproviderbase.'_loggedin'}[$processor->name] = 1;
$form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 1;
} else if ($value == 'disallowed') {
// It might be better to unset them, but I can't figure out why that cause error
$form->{$componentproviderbase.'_loggedin'}[$processor->name] = 0;
$form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 0;
}
// record the site preference
$preferences[$processor->name.'_provider_'.$componentprovidersetting] = $value;
}
} else if (array_key_exists($componentprovidersetting, $form)) {
// we must be processing loggedin or loggedoff checkboxes. Store
// defained comma-separated processors as setting value.
// Using array_filter eliminates elements set to 0 above
$value = join(',', array_keys(array_filter($form->{$componentprovidersetting})));
if (empty($value)) {
$value = null;
}
}
if ($setting != 'permitted') {
// we have already recoded site preferences for 'permitted' type
$preferences['message_provider_'.$componentprovidersetting] = $value;
}
}
}
// Update database
$transaction = $DB->start_delegated_transaction();
foreach ($preferences as $name => $value) {
set_config($name, $value, 'message');
}
$transaction->allow_commit();
// Redirect
$url = new moodle_url('defaultoutputs.php');
redirect($url);
}
// Page settings
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->requires->js_init_call('M.core_message.init_defaultoutputs');
// Grab the renderer
$renderer = $PAGE->get_renderer('core', 'message');
// Display the manage message outputs interface
$preferences = get_config('message');
$messageoutputs = $renderer->manage_defaultmessageoutputs($processors, $providers, $preferences);
// Display the page
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('defaultmessageoutputs', 'message'));
echo $messageoutputs;
echo $OUTPUT->footer();

View File

@ -53,6 +53,11 @@ define('MESSAGE_SEARCH_MAX_RESULTS', 200);
define('MESSAGE_CONTACTS_PER_PAGE',10);
define('MESSAGE_MAX_COURSE_NAME_LENGTH', 30);
/**
* Set default value for default outputs permitted setting
*/
define('MESSAGE_DEFAULT_PERMITTED_VALUE', 'disallowed');
if (!isset($CFG->message_contacts_refresh)) { // Refresh the contacts list every 60 seconds
$CFG->message_contacts_refresh = 60;
}
@ -2171,30 +2176,45 @@ function message_print_heading($title, $colspan=3) {
/**
* Get all message processors and validate corresponding plugin existance and
* configuration
* @param bool $enabled only return enabled processors
* @return array $processors array of objects containing information on message processors
*/
function get_message_processors() {
function get_message_processors($enabled = false) {
global $DB, $CFG;
$processors = $DB->get_records('message_processors', null, 'name');
foreach ($processors as &$processor){
$processorfile = $CFG->dirroot. '/message/output/'.$processor->name.'/message_output_'.$processor->name.'.php';
if (is_readable($processorfile)) {
include_once($processorfile);
$processclass = 'message_output_' . $processor->name;
if (class_exists($processclass)) {
$pclass = new $processclass();
$processor->configured = 0;
if ($pclass->is_system_configured()) {
$processor->configured = 1;
static $processors;
if (empty($processors)) {
$processors = $DB->get_records('message_processors', null, 'name');
foreach ($processors as &$processor){
$processorfile = $CFG->dirroot. '/message/output/'.$processor->name.'/message_output_'.$processor->name.'.php';
if (is_readable($processorfile)) {
include_once($processorfile);
$processclass = 'message_output_' . $processor->name;
if (class_exists($processclass)) {
$pclass = new $processclass();
$processor->configured = 0;
if ($pclass->is_system_configured()) {
$processor->configured = 1;
}
$processor->hassettings = 0;
if (is_readable($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php')) {
$processor->hassettings = 1;
}
$processor->available = 1;
} else {
print_error('errorcallingprocessor', 'message');
}
$processor->available = 1;
} else {
print_error('errorcallingprocessor', 'message');
$processor->available = 0;
}
} else {
$processor->available = 0;
}
}
if ($enabled) {
// Filter out enabled processors only, the reason of not doing this in
// database request is caching the result.
$processors = array_filter($processors, create_function('$a', 'return $a->enabled;'));
}
return $processors;
}

View File

@ -42,4 +42,49 @@ M.core_message.init_notification = function(Y, title, content, url) {
return false;
}, o);
});
};
};
M.core_message.init_defaultoutputs = function(Y) {
var defaultoutputs = {
init : function() {
Y.all('#defaultmessageoutputs select').each(function(node) {
// attach event listener
node.on('change', defaultoutputs.changeState);
// set initial layout
node.simulate("change");
}, this);
},
changeState : function(e) {
var value = e.target._node.options[e.target.get('selectedIndex')].value;
var parentnode = e.target.ancestor('td');
switch (value) {
case 'forced':
defaultoutputs.updateCheckboxes(parentnode, 1, 1);
break;
case 'disallowed':
defaultoutputs.updateCheckboxes(parentnode, 1, 0);
break;
case 'permitted':
defaultoutputs.updateCheckboxes(parentnode, 0, 0);
break;
}
},
updateCheckboxes : function(blocknode, disabled, checked) {
blocknode.all('input[type=checkbox]').each(function(node) {
node.removeAttribute('disabled');
if (disabled) {
node.setAttribute('disabled', 1)
node.removeAttribute('checked');
}
if (checked) {
node.setAttribute('checked', 1)
}
}, this);
}
}
defaultoutputs.init();
}

View File

@ -46,8 +46,6 @@ class core_message_renderer extends plugin_renderer_base {
// Display the current workflows
$table = new html_table();
$table->attributes['class'] = 'generaltable';
$table->head = array();
$table->colclasses = array();
$table->data = array();
$table->head = array(
get_string('name'),
@ -58,7 +56,7 @@ class core_message_renderer extends plugin_renderer_base {
'displayname', 'availability', 'settings',
);
foreach ( $processors as $processor ){
foreach ($processors as $processor) {
$row = new html_table_row();
$row->attributes['class'] = 'messageoutputs';
@ -94,7 +92,7 @@ class core_message_renderer extends plugin_renderer_base {
}
// Settings
$settings = new html_table_cell();
if ($processor->available && file_exists($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php')) {
if ($processor->available && $processor->hassettings) {
$settingsurl = new moodle_url('settings.php', array('section' => 'messagesetting'.$processor->name));
$settings->text = html_writer::link($settingsurl, get_string('settings', 'message'));
}
@ -104,4 +102,105 @@ class core_message_renderer extends plugin_renderer_base {
}
return html_writer::table($table);
}
/**
* Display the interface to manage default message outputs
*
* @param array $processors The list of message processors
* @param array $providers The list of message providers
* @param array $preferences The list of current preferences
* @return string The text to render
*/
public function manage_defaultmessageoutputs($processors, $providers, $preferences) {
global $CFG;
// Prepare list of options for dropdown menu
$options = array();
foreach (array('disallowed', 'permitted', 'forced') as $setting) {
$options[$setting] = get_string($setting, 'message');
}
$output = html_writer::start_tag('form', array('id'=>'defaultmessageoutputs', 'method'=>'post'));
$output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
// Display users outputs table
$table = new html_table();
$table->attributes['class'] = 'generaltable';
$table->data = array();
$table->head = array('');
// Populate the header row
foreach ($processors as $processor) {
$table->head[] = get_string('pluginname', 'message_'.$processor->name);
}
// Generate the matrix of settings for each provider and processor
foreach ($providers as $provider) {
$row = new html_table_row();
$row->attributes['class'] = 'defaultmessageoutputs';
$row->cells = array();
// Provider Name
$providername = get_string('messageprovider:'.$provider->name, $provider->component);
$row->cells[] = new html_table_cell($providername);
// Settings for each processor
foreach ($processors as $processor) {
$cellcontent = '';
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) {
// pepare element and preference names
$elementname = $provider->component.'_'.$provider->name.'_'.$setting.'['.$processor->name.']';
$preferencebase = $provider->component.'_'.$provider->name.'_'.$setting;
// prepare language bits
$processorname = get_string('pluginname', 'message_'.$processor->name);
$statename = get_string($setting, 'message');
$labelparams = array(
'provider' => $providername,
'processor' => $processorname,
'state' => $statename
);
if ($setting == 'permitted') {
$label = get_string('sendingvia', 'message', $labelparams);
// determine the current setting or use default
$select = MESSAGE_DEFAULT_PERMITTED_VALUE;
$preference = $processor->name.'_provider_'.$preferencebase;
if (array_key_exists($preference, $preferences)) {
$select = $preferences->{$preference};
}
// dropdown menu
$cellcontent = html_writer::select($options, $elementname, $select, false, array('id' => $elementname));
$cellcontent .= html_writer::label($label, $elementname, true, array('class' => 'accesshide'));
$cellcontent .= html_writer::tag('div', get_string('defaults', 'message'));
} else {
$label = get_string('sendingviawhen', 'message', $labelparams);
// determine the current setting based on the 'permitted' setting above
$checked = false;
if ($select == 'forced') {
$checked = true;
} else if ($select == 'permitted') {
$preference = 'message_provider_'.$preferencebase;
if (array_key_exists($preference, $preferences)) {
$checked = (int)in_array($processor->name, explode(',', $preferences->{$preference}));
}
}
// generate content
$cellcontent .= html_writer::start_tag('div');
$cellcontent .= html_writer::checkbox($elementname, 1, $checked, '', array('id' => $elementname));
$cellcontent .= html_writer::label($label, $elementname, true, array('class' => 'accesshide'));
$cellcontent .= $statename;
$cellcontent .= html_writer::end_tag('div');
}
}
$row->cells[] = new html_table_cell($cellcontent);
}
$table->data[] = $row;
}
$output .= html_writer::table($table);
$output .= html_writer::start_tag('div', array('class' => 'form-buttons'));
$output .= html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('savechanges','admin'), 'class' => 'form-submit'));
$output .= html_writer::end_tag('div');
$output .= html_writer::end_tag('form');
return $output;
}
}