diff --git a/README.md b/README.md index 8d7413e..ce055b1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ This plugin requires Moodle 3.1+ Changes ------- +* 2016-11-03 - Add global plugin settings and instance settings for role list customization other than course contact setting * 2016-07-19 - Check compatibility for Moodle 3.1, no functionality change * 2016-03-07 - Workaround: Add non-breaking space to block title because otherwise the Moodle CLI installer fails due to a duplicate title with block_partipants. The space should not have a big visual impact. * 2016-02-10 - Change plugin version and release scheme to the scheme promoted by moodle.org, no functionality change @@ -71,13 +72,29 @@ block_people should work with all Bootstrap based Moodle themes. Settings -------- -block_people has neither a settings page nor settings in config.php. Nevertheless, there are some Moodle settings it responds to: +block_people has a plugin settings page and also has instance settings. -### 1. List of teachers +### 1. List of roles to be shown -block_people gets the list of teacher roles from $CFG->coursecontact. With this Moodle core setting, you can define which roles are displayed in block_people's list of teachers. +block_people gets the list of roles to be shown in three different way, depending on settings. -### 2. Quicklink for teachers +##### Course contact ($CFG->coursecontact) +With this Moodle core setting (Site administration -> Appearance -> Courses), you can define which roles are displayed in block_people's list of people. +If plugin settings are not enabled, this is the default visualization mode. + +##### Plugin settings +Within the plugin settings the core setting $CFG->coursecontact can be overridden, selecting a new list of roles to be shown in block instances. +In the plugin settings can also be allowed the instance override of plugin settings, selecting which roles can be overridden and which ones not. + +##### Instance settings +If allowed by plugin settings, you can also decide to select a specific list of roles to be shown for a single instance, from the available ones. + +Other settings +-------- + +Other than specific settings, block_people responds to other Moodle settings: + +### 1. Quicklink for teachers block_people only shows a quicklink to the teacher's profile if the user has the capability moodle/user:viewdetails See http://docs.moodle.org/en/Capabilities/moodle/user:viewdetails for details on this capability @@ -85,12 +102,12 @@ See http://docs.moodle.org/en/Capabilities/moodle/user:viewdetails for details o block_people only shows a quicklink to the message system if the user has the capability moodle/site:sendmessage and if the Moodle message system is turnes on ($CFG->messaging) See http://docs.moodle.org/en/Capabilities/moodle/site:sendmessage for details on this capability and http://docs.moodle.org/en/Messaging for details on the messaging system -### 3. Participants List +### 2. Participants List block_people only shows the link to the participants list if the user has the capability moodle/course:viewparticipants. See http://docs.moodle.org/en/Capabilities/moodle/course:viewparticipants for details on this capability -### 4. Roles sort order +### 3. Roles sort order block_people shows teacher role groups in the order defined in /admin/roles/manage.php. Please visit this settings page if you want to modify the sort order diff --git a/block_people.php b/block_people.php index 8b893c0..560e6d3 100644 --- a/block_people.php +++ b/block_people.php @@ -25,27 +25,35 @@ defined('MOODLE_INTERNAL') || die(); class block_people extends block_base { - function init() { - $this->title = get_string('pluginname', 'block_people').' '; // Non-breaking space is added because otherwise the Moodle CLI installer fails due to a duplicate block title with block_partipants. The space should not have a big visual impact. + + public function init() { + /* Non-breaking space is added because otherwise the Moodle CLI installer fails due + to a duplicate block title with block_partipants. + The space should not have a big visual impact. */ + $this->title = get_string('pluginname', 'block_people') . ' '; } - function applicable_formats() { + public function applicable_formats() { return array('course-view' => true, 'site' => true); } - function has_config() { - return false; + public function has_config() { + return true; } - function instance_allow_multiple() { + public function instance_allow_config() { + return true; + } + + public function instance_allow_multiple() { return false; } - function instance_can_be_hidden() { + public function instance_can_be_hidden() { return true; } - function get_content() { + public function get_content() { global $COURSE, $CFG, $DB, $OUTPUT, $USER; if ($this->content !== null) { @@ -57,42 +65,63 @@ function get_content() { return $this->content; } - // Prepare output + // Prepare output. $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; - // Get context + // Get context. $currentcontext = $this->page->context; - // Get teachers separated by roles - $CFG->coursecontact = trim($CFG->coursecontact); - if (!empty($CFG->coursecontact)) { - $teacherroles = explode(',', $CFG->coursecontact); - foreach($teacherroles as $tr) { - $teachers[$tr] = get_role_users($tr, $currentcontext, true, 'u.id, u.lastname, u.firstname, u.firstnamephonetic, u. lastnamephonetic, u.middlename, u.alternatename, u.picture, u.imagealt, u.email', 'u.lastname ASC, u.firstname ASC'); + require_once($CFG->dirroot . '/blocks/people/lib.php'); + + // Get roles from instance settings or default settings. + $rolesvisualization = block_people_get_roles_visualization($this); + $roles = block_people_get_roles_to_be_shown($this, $rolesvisualization); + // Get teachers separated by roles. + $teachers = array(); + $fields = array( + 'u.id', + 'u.lastname', + 'u.firstname', + 'u.firstnamephonetic', + 'u.lastnamephonetic', + 'u.middlename', + 'u.alternatename', + 'u.picture', + 'u.imagealt', + 'u.email' + ); + $sort = array( + 'u.lastname ASC', + 'u.firstname ASC' + ); + + if (!empty($roles)) { + foreach ($roles as $tr) { + $teachers[$tr] = get_role_users($tr, $currentcontext, true, implode(',', $fields), implode(',', $sort)); } } - // Get role names / aliases in course context + // Get role names / aliases in course context. $rolenames = role_get_names($currentcontext, ROLENAME_ALIAS, true); - // Start teachers list + // Start teachers list. $this->content->text .= html_writer::start_tag('div', array('class' => 'teachers')); - // Check every teacherrole + // Check every teacherrole. foreach ($teachers as $id => $tr) { if (count($tr) > 0) { - // Write heading and open new list + // Write heading and open new list. $this->content->text .= html_writer::tag('h3', $rolenames[$id]); $this->content->text .= html_writer::start_tag('ul'); - // Do for every teacher with this role + // Do for every teacher with this role. foreach ($tr as $t) { - // Output teacher + // Output teacher. $this->content->text .= html_writer::start_tag('li'); - // create user object for picture output + // Create user object for picture output. $user = new stdClass(); $user->id = $t->id; $user->lastname = $t->lastname; @@ -106,55 +135,90 @@ function get_content() { $user->email = $t->email; $this->content->text .= html_writer::start_tag('div', array('class' => 'image')); - if (has_capability('moodle/user:viewdetails', $currentcontext)) { - $this->content->text .= $OUTPUT->user_picture($user, array('size' => 30, 'link' => true, 'courseid' => $COURSE->id)); - } - else { - $this->content->text .= $OUTPUT->user_picture($user, array('size' => 30, 'link' => false, 'courseid' => $COURSE->id)); - } + if (has_capability('moodle/user:viewdetails', $currentcontext)) { + $this->content->text .= $OUTPUT->user_picture($user, + array('size' => 30, 'link' => true, 'courseid' => $COURSE->id) + ); + } else { + $this->content->text .= $OUTPUT->user_picture($user, + array('size' => 30, 'link' => false, 'courseid' => $COURSE->id) + ); + } $this->content->text .= html_writer::end_tag('div'); $this->content->text .= html_writer::start_tag('div', array('class' => 'name')); - $this->content->text .= fullname($t); + $this->content->text .= fullname($t); $this->content->text .= html_writer::end_tag('div'); $this->content->text .= html_writer::start_tag('div', array('class' => 'icons')); - if (has_capability('moodle/user:viewdetails', $currentcontext)) { - $this->content->text .= html_writer::start_tag('a', array('href' => new moodle_url('/user/view.php', array('id' => $t->id, 'course' => $COURSE->id)), 'title' => get_string('viewprofile', 'core'))); - $this->content->text .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/user'), 'class' => 'icon', 'alt' => get_string('viewprofile', 'core'))); - $this->content->text .= html_writer::end_tag('a'); - } - - if ($CFG->messaging && has_capability('moodle/site:sendmessage', $currentcontext) && $t->id != $USER->id) { - $this->content->text .= html_writer::start_tag('a', array('href' => new moodle_url('/message/index.php', array('id' => $t->id)), 'title' => get_string('sendmessageto', 'core_message', fullname($t)))); - $this->content->text .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/email'), 'class' => 'icon', 'alt' => get_string('sendmessageto', 'core_message', fullname($t)))); - $this->content->text .= html_writer::end_tag('a'); - } + if (has_capability('moodle/user:viewdetails', $currentcontext)) { + $this->content->text .= html_writer::start_tag('a', + array( + 'href' => new moodle_url('/user/view.php', array('id' => $t->id, 'course' => $COURSE->id)), + 'title' => get_string('viewprofile', 'core') + ) + ); + $this->content->text .= html_writer::empty_tag('img', + array( + 'src' => $OUTPUT->pix_url('i/user'), + 'class' => 'icon', + 'alt' => get_string('viewprofile', 'core') + ) + ); + $this->content->text .= html_writer::end_tag('a'); + } + + if ($CFG->messaging && has_capability('moodle/site:sendmessage', $currentcontext) && $t->id != $USER->id) { + $this->content->text .= html_writer::start_tag('a', + array( + 'href' => new moodle_url('/message/index.php', array('id' => $t->id)), + 'title' => get_string('sendmessageto', 'core_message', fullname($t)) + ) + ); + $this->content->text .= html_writer::empty_tag('img', + array( + 'src' => $OUTPUT->pix_url('t/email'), + 'class' => 'icon', + 'alt' => get_string('sendmessageto', 'core_message', fullname($t)) + ) + ); + $this->content->text .= html_writer::end_tag('a'); + } $this->content->text .= html_writer::end_tag('div'); $this->content->text .= html_writer::end_tag('li'); } - // End list + // End list. $this->content->text .= html_writer::end_tag('ul'); } } - // End teachers list + // End teachers list. $this->content->text .= html_writer::end_tag('div'); - // Output participant list + // Output participant list. $this->content->text .= html_writer::start_tag('div', array('class' => 'participants')); $this->content->text .= html_writer::tag('h3', get_string('participants')); - // Only if user is allow to see participants list + // Only if user is allow to see participants list. if (has_capability('moodle/course:viewparticipants', $currentcontext)) { - $this->content->text .= html_writer::start_tag('a', array('href' => new moodle_url('/user/index.php', array('contextid' => $currentcontext->id)), 'title' => get_string('participants'))); - $this->content->text .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/users'), 'class' => 'icon', 'alt' => get_string('participants'))); + $this->content->text .= html_writer::start_tag('a', + array( + 'href' => new moodle_url('/user/index.php', array('contextid' => $currentcontext->id)), + 'title' => get_string('participants') + ) + ); + $this->content->text .= html_writer::empty_tag('img', + array( + 'src' => $OUTPUT->pix_url('i/users'), + 'class' => 'icon', + 'alt' => get_string('participants') + ) + ); $this->content->text .= get_string('participantslist', 'block_people'); $this->content->text .= html_writer::end_tag('a'); - } - else { + } else { $this->content->text .= html_writer::start_tag('span', array('class' => 'hint')); $this->content->text .= get_string('noparticipantslist', 'block_people'); $this->content->text .= html_writer::end_tag('span'); diff --git a/db/access.php b/db/access.php index c9498d7..e797fc6 100644 --- a/db/access.php +++ b/db/access.php @@ -39,4 +39,13 @@ ), 'clonepermissionsfrom' => 'moodle/site:manageblocks' ), + 'block/people:overrideglobalsettings' => array( + 'riskbitmask' => RISK_SPAM, + 'captype' => 'write', + 'contextlevel' => CONTEXT_BLOCK, + 'archetypes' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW + ) + ), ); diff --git a/edit_form.php b/edit_form.php new file mode 100644 index 0000000..7913d94 --- /dev/null +++ b/edit_form.php @@ -0,0 +1,55 @@ +. + +/** + * People block edit form. + * + * @package block_people + * @copyright 2016 Giorgio Riva, University of Milano-Bicocca + * @copyright 2013 Alexander Bias, University of Ulm + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +require_once($CFG->dirroot.'/blocks/people/lib.php'); + +class block_people_edit_form extends block_edit_form { + + protected function specific_definition($mform) { + $context = context_course::instance($this->page->course->id); + + $mform->addElement('header', 'configheader', get_string('blocksettings', 'block')); + // Show instance settings only if override is allowed. + if (can_override_roles($context)) { + // Override default roles. + $mform->addElement('advcheckbox', 'config_overridedefaultroles', '', + get_string('overridedefaultroles', 'block_people')); + $mform->setDefault('config_overridedefaultroles', false); + $mform->addHelpButton('config_overridedefaultroles', 'overridedefaultroles', 'block_people'); + // Overridable roles. + $availableroles = block_people_get_instance_overridable_roles($context); + $select = $mform->addElement('select', 'config_instanceroles', + get_string('instanceroles', 'block_people'), $availableroles); + $select->setMultiple(true); + $mform->setDefault('config_instanceroles', explode(',', get_config('block_people', 'defaultroles'))); + $mform->addHelpButton('config_instanceroles', 'instanceroles', 'block_people'); + $mform->disabledIf('config_instanceroles', 'config_overridedefaultroles'); + } else { + $mform->addElement('static', 'overridenotallowed', '', get_string('overridenotallowed', 'block_people')); + } + } +} \ No newline at end of file diff --git a/lang/en/block_people.php b/lang/en/block_people.php index 8681eef..310f70e 100644 --- a/lang/en/block_people.php +++ b/lang/en/block_people.php @@ -28,4 +28,22 @@ $string['participantslist'] = 'Show participants list'; $string['people:addinstance'] = 'Add a new people block'; $string['people:myaddinstance'] = 'Add a new people block to Dashboard'; +$string['people:overrideglobalsettings'] = 'Override global plugin settings'; $string['noparticipantslist'] = 'Viewing the participants list is prohibited in this course'; + +// Settings. +$string['overridecoursecontact'] = 'Override course contacts'; +$string['overridecoursecontact_help'] = 'Override global core setting coursecontact with a different roles list.'; +$string['defaultroles'] = 'Default listed roles'; +$string['defaultroles_help'] = 'List of roles to be shown by default in the block when course contact override is enabled.'; +$string['allowinstanceoverride'] = 'Allow instance override'; +$string['allowinstanceoverride_help'] = 'Allow override of default settings in block instances'; +$string['overridableroles'] = 'Available roles for instance override'; +$string['overridableroles_help'] = 'List of available roles in block instance\'s settings when local override is allowed.'; + +$string['overridedefaultroles'] = 'Override default roles'; +$string['overridedefaultroles_help'] = 'List of available roles in block instance\'s settings when local override is allowed.'; +$string['instanceroles'] = 'Overridedefaultroles'; +$string['instanceroles_help'] = 'List of available roles in block instance\'s settings when local override is allowed.'; + +$string['overridenotallowed'] = 'Instance override of default settings is not allowed'; diff --git a/lib.php b/lib.php new file mode 100644 index 0000000..f0b96b0 --- /dev/null +++ b/lib.php @@ -0,0 +1,158 @@ +. + +/** + * People block lib. + * + * @package block_people + * @copyright 2016 Giorgio Riva, University of Milano-Bicocca + * @copyright 2013 Alexander Bias, University of Ulm + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +define('BLOCK_PEOPLE_SHOW_NOTHING', 0); +define('BLOCK_PEOPLE_SHOW_COURSE_CONTACT', 1); +define('BLOCK_PEOPLE_SHOW_DEFAULT_ROLES', 2); +define('BLOCK_PEOPLE_SHOW_INSTANCE_ROLES', 3); + +/** + * Get the list of assignable roles in course context + * + * @param null $context + * @return array + */ +function block_people_get_course_assignable_roles($context = null) { + global $DB; + // Get roles assignables in course context. + $courseroles = get_roles_for_contextlevels(CONTEXT_COURSE); + $courseroles = $DB->get_records_list('role', 'id', $courseroles, 'sortorder ASC'); + // Get localized role names. + $assignableroles = role_fix_names($courseroles, $context, ROLENAME_ALIAS, true); + + return $assignableroles; +} + +/** + * Get the list of available roles for instance override + * + * @param null $context + * @return array + */ +function block_people_get_instance_overridable_roles($context = null) { + // Get the available roles from global config. + $availableroles = array_flip(explode(',', get_config('block_people', 'overridableroles'))); + // Get the assignable roles. + $roles = block_people_get_course_assignable_roles($context); + + $availableroles = array_intersect_key($roles, $availableroles); + + return $availableroles; +} + +/** + * Check if current user can override roles + * + * @param $context + * @return bool + */ +function can_override_roles($context) { + // Override core setting is disables, so noone can override roles. + if (!get_config('block_people', 'overridecoursecontact')) { + return false; + } + // Override core setting is enabled but instance override is not allowed, so noone can override roles. + if (get_config('block_people', 'overridecoursecontact') && + !get_config('block_people', 'allowinstanceoverride')) { + return false; + } + // Override core setting is enabled and instance override is allowed, + // so only users with overrideglobalsettings capability can override global settings. + if (get_config('block_people', 'overridecoursecontact') && + get_config('block_people', 'allowinstanceoverride') && + has_capability('block/people:overrideglobalsettings', $context)) { + return true; + } + // Default return. + return false; +} + +/** + * According to settings, get the type of visualization to use + * + * @param block_people $instance Current block instance + * @return int Type of visualization + */ +function block_people_get_roles_visualization(block_people $instance) { + // Get settings. + $overridecoursecontact = get_config('block_people', 'overridecoursecontact'); + $allowinstanceoverride = get_config('block_people', 'allowinstanceoverride'); + $instanceoverride = isset($instance->config->overridedefaultroles) ? $instance->config->overridedefaultroles : false; + // If overridecoursecontact is false then we use course contact as roles. + if (!$overridecoursecontact) { + return BLOCK_PEOPLE_SHOW_COURSE_CONTACT; + } + // If overridecoursecontact and instance override is not allowed, we use default. + if ($overridecoursecontact && !$allowinstanceoverride) { + return BLOCK_PEOPLE_SHOW_DEFAULT_ROLES; + } + // If overridecoursecontact and instance override is not allowed, we use default. + if ($overridecoursecontact && $allowinstanceoverride && !$instanceoverride) { + return BLOCK_PEOPLE_SHOW_DEFAULT_ROLES; + } + // If all is active, we use instance roles. + if ($overridecoursecontact && $allowinstanceoverride && $instanceoverride) { + return BLOCK_PEOPLE_SHOW_INSTANCE_ROLES; + } + // If code reach this line, something is wrong and then nothing is shown. + return BLOCK_PEOPLE_SHOW_NOTHING; +} + +/** + * Get roles to be shown in che current instance, according to type of visualization + * + * @param block_people $instance + * @param $visualization + * @return array + */ +function block_people_get_roles_to_be_shown(block_people $instance, $visualization) { + global $CFG; + $roles = array(); + + switch ($visualization) { + case BLOCK_PEOPLE_SHOW_COURSE_CONTACT: { + $roles = explode(',', $CFG->coursecontact); + break; + } + case BLOCK_PEOPLE_SHOW_DEFAULT_ROLES: { + $roles = explode(',', get_config('block_people', 'defaultroles')); + break; + } + case BLOCK_PEOPLE_SHOW_INSTANCE_ROLES: { + // Get default roles that can't be overridden. + $defaultroles = explode(',', get_config('block_people', 'defaultroles')); + $overridableroles = explode(',', get_config('block_people', 'instanceavailableroles')); + $defaultrolenotoverridable = array_diff($defaultroles, $overridableroles); + // Merge not ovverridable default roles with instance defined roles. + $roles = array_merge($defaultrolenotoverridable, $instance->config->instanceroles); + break; + } + } + + return $roles; +} + diff --git a/settings.php b/settings.php new file mode 100644 index 0000000..272f33e --- /dev/null +++ b/settings.php @@ -0,0 +1,67 @@ +. + +/** + * People block settings. + * + * @package block_people + * @copyright 2016 Giorgio Riva, University of Milano-Bicocca + * @copyright 2013 Alexander Bias, University of Ulm + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +require_once($CFG->dirroot.'/blocks/people/lib.php'); + +if ($ADMIN->fulltree) { + + // Override global course contact setting (Site Administration -> Appearance -> Courses -> coursecontact). + $name = 'block_people/overridecoursecontact'; + $title = get_string('overridecoursecontact', 'block_people'); + $description = get_string('overridecoursecontact_help', 'block_people'); + $default = false; + $setting = new admin_setting_configcheckbox($name, $title, $description, $default); + $settings->add($setting); + + // Default selected roles. + $name = 'block_people/defaultroles'; + $title = get_string('defaultroles', 'block_people'); + $description = get_string('defaultroles_help', 'block_people'); + $roles = block_people_get_course_assignable_roles(); + $default = explode(',', $CFG->coursecontact); + $setting = new admin_setting_configmultiselect($name, $title, $description, $default, $roles); + $settings->add($setting); + + // Allow instance override of default selected roles. + $name = 'block_people/allowinstanceoverride'; + $title = get_string('allowinstanceoverride', 'block_people'); + $description = get_string('allowinstanceoverride_help', 'block_people'); + $default = false; + $setting = new admin_setting_configcheckbox($name, $title, $description, $default); + $settings->add($setting); + + // Overridable roles. + $name = 'block_people/overridableroles'; + $title = get_string('overridableroles', 'block_people'); + $description = get_string('overridableroles_help', 'block_people'); + $roles = block_people_get_course_assignable_roles(); + $default = explode(',', $CFG->coursecontact); + $setting = new admin_setting_configmultiselect($name, $title, $description, $default, $roles); + $settings->add($setting); + +} + diff --git a/version.php b/version.php index bd73f48..8e25d8f 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'block_people'; -$plugin->version = 2016071900; -$plugin->release = 'v3.1-r1'; +$plugin->version = 2016110300; +$plugin->release = 'v3.1-r3'; $plugin->requires = 2016052300; $plugin->maturity = MATURITY_STABLE;