From 3a8cf5e67d98a203f72b43454f45405d0b4d1d42 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 8 Jun 2018 11:37:43 +0800 Subject: [PATCH] MDL-53566 core: Add UI for context locking --- admin/lock.php | 96 ++++++++++++++++++++++++++++ admin/settings/development.php | 3 + course/classes/management/helper.php | 24 +++++++ lang/en/admin.php | 8 +++ lib/blocklib.php | 24 +++++++ lib/navigationlib.php | 50 +++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 admin/lock.php diff --git a/admin/lock.php b/admin/lock.php new file mode 100644 index 0000000000000..3041ded67ae49 --- /dev/null +++ b/admin/lock.php @@ -0,0 +1,96 @@ +. + +/** + * This file is used to display a categories sub categories, external pages, and settings. + * + * @package admin + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../config.php'); +require_once("{$CFG->libdir}/adminlib.php"); + +$contextid = required_param('id', PARAM_INT); +$confirm = optional_param('confirm', null, PARAM_INT); +$returnurl = optional_param('returnurl', null, PARAM_LOCALURL); + +$PAGE->set_url('/admin/lock.php', ['id' => $contextid]); + +list($context, $course, $cm) = get_context_info_array($contextid); + +$parentcontext = $context->get_parent_context(); +if ($parentcontext && !empty($parentcontext->locked)) { + // Can't make changes to a context whose parent is locked. + throw new \coding_exception('Not sure how you got here'); +} + +if ($course) { + $isfrontpage = ($course->id == SITEID); +} else { + $isfrontpage = false; + $course = $SITE; +} + +require_login($course, false, $cm); +require_capability('moodle/site:managecontextlocks', $context); + +$PAGE->set_pagelayout('admin'); +$PAGE->navigation->clear_cache(); + +$a = (object) [ + 'contextname' => $context->get_context_name(), +]; + +if (null !== $confirm && confirm_sesskey()) { + $context->set_locked(!empty($confirm)); + + if ($context->locked) { + $lockmessage = get_string('managecontextlocklocked', 'admin', $a); + } else { + $lockmessage = get_string('managecontextlockunlocked', 'admin', $a); + } + + if (empty($returnurl)) { + $returnurl = $context->get_url(); + } else { + $returnurl = new moodle_url($returnurl); + } + redirect($returnurl, $lockmessage); +} + +$heading = get_string('managecontextlock', 'admin'); +$PAGE->set_title($heading); +$PAGE->set_heading($heading); + +echo $OUTPUT->header(); + +if ($context->locked) { + $confirmstring = get_string('confirmcontextunlock', 'admin', $a); + $target = 0; +} else { + $confirmstring = get_string('confirmcontextlock', 'admin', $a); + $target = 1; +} + +$confirmurl = new \moodle_url($PAGE->url, ['confirm' => $target]); +if (!empty($returnurl)) { + $confirmurl->param('returnurl', $returnurl); +} + +echo $OUTPUT->confirm($confirmstring, $confirmurl, $context->get_url()); +echo $OUTPUT->footer(); diff --git a/admin/settings/development.php b/admin/settings/development.php index cc2a6203905d7..54fe94b3318b9 100644 --- a/admin/settings/development.php +++ b/admin/settings/development.php @@ -16,6 +16,9 @@ $temp->add(new admin_setting_configexecutable('pathtosassc', new lang_string('pathtosassc', 'admin'), new lang_string('pathtosassc_help', 'admin'), '')); + $temp->add(new admin_setting_configcheckbox('contextlocking', new lang_string('contextlocking', 'core_admin'), + new lang_string('contextlocking_desc', 'core_admin'), 0)); + $temp->add(new admin_setting_configcheckbox('forceclean', new lang_string('forceclean', 'core_admin'), new lang_string('forceclean_desc', 'core_admin'), 0)); diff --git a/course/classes/management/helper.php b/course/classes/management/helper.php index 2374883cadd27..0befd6433dfa7 100644 --- a/course/classes/management/helper.php +++ b/course/classes/management/helper.php @@ -168,6 +168,8 @@ public static function get_course_detail_array(\core_course_list_element $course * @return array */ public static function get_category_listitem_actions(\core_course_category $category) { + global $CFG; + $manageurl = new \moodle_url('/course/management.php', array('categoryid' => $category->id)); $baseurl = new \moodle_url($manageurl, array('sesskey' => \sesskey())); $actions = array(); @@ -280,6 +282,28 @@ public static function get_category_listitem_actions(\core_course_category $cate ); } + // Context locking. + if (!empty($CFG->contextlocking) && has_capability('moodle/site:managecontextlocks', $category->get_context())) { + $parentcontext = $category->get_context()->get_parent_context(); + if (empty($parentcontext) || !$parentcontext->locked) { + if ($category->get_context()->locked) { + $lockicon = 'i/unlock'; + $lockstring = get_string('managecontextunlock', 'admin'); + } else { + $lockicon = 'i/lock'; + $lockstring = get_string('managecontextlock', 'admin'); + } + $actions['managecontextlock'] = [ + 'url' => new \moodle_url('/admin/lock.php', [ + 'id' => $category->get_context()->id, + 'returnurl' => $manageurl->out_as_local_url(false), + ]), + 'icon' => new \pix_icon($lockicon, $lockstring), + 'string' => $lockstring, + ]; + } + } + // Cohorts. if ($category->can_review_cohorts()) { $actions['cohorts'] = array( diff --git a/lang/en/admin.php b/lang/en/admin.php index 11d79f3c7eaf6..41608542d3350 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -379,8 +379,12 @@ $string['configwarning'] = 'Be careful modifying these settings - strange values could cause problems.'; $string['configyuicomboloading'] = 'This options enables combined file loading optimisation for YUI libraries. This setting should be enabled on production sites for performance reasons.'; $string['confirmation'] = 'Confirmation'; +$string['confirmcontextlock'] = '{$a->contextname} is currently unlocked. Locking it will prevent any further changes. Are you sure you wish to continue?'; +$string['confirmcontextunlock'] = '{$a->contextname} is currently locked. Unlocking it will allow users to make changes. Are you sure you wish to continue?'; $string['confirmdeletecomments'] = 'You are about to delete comments, are you sure?'; $string['confirmed'] = 'Confirmed'; +$string['contextlocking'] = 'Context locking'; +$string['contextlocking_desc'] = 'This setting allows you to lock categories, courses, activites, and blocks within the site by removing all write-access to those locations.'; $string['cookiehttponly'] = 'Only http cookies'; $string['cookiesecure'] = 'Secure cookies only'; $string['country'] = 'Default country'; @@ -718,6 +722,10 @@ $string['maintenancemodeisscheduledlong'] = 'This site will be switched to maintenance mode in {$a->hour} hours {$a->min} mins {$a->sec} secs'; $string['maintfileopenerror'] = 'Error opening maintenance files!'; $string['maintinprogress'] = 'Maintenance is in progress...'; +$string['managecontextlock'] = 'Lock this context'; +$string['managecontextlocklocked'] = '{$a->contextname}, and all of its children are now locked.'; +$string['managecontextlockunlocked'] = '{$a->contextname}, and all of its children are now unlocked.'; +$string['managecontextunlock'] = 'Unlock this context'; $string['manageformats'] = 'Manage course formats'; $string['manageformatsgotosettings'] = 'Default format can be changed in {$a}'; $string['managelang'] = 'Manage'; diff --git a/lib/blocklib.php b/lib/blocklib.php index feaefb39e1924..18172c2bc17aa 100644 --- a/lib/blocklib.php +++ b/lib/blocklib.php @@ -1378,6 +1378,30 @@ public function edit_controls($block) { ); } + if (!empty($CFG->contextlocking) && has_capability('moodle/site:managecontextlocks', $block->context)) { + $parentcontext = $block->context->get_parent_context(); + if (empty($parentcontext) || empty($parentcontext->locked)) { + if ($block->context->locked) { + $lockicon = 'i/unlock'; + $lockstring = get_string('managecontextunlock', 'admin'); + } else { + $lockicon = 'i/lock'; + $lockstring = get_string('managecontextlock', 'admin'); + } + $controls[] = new action_menu_link_secondary( + new moodle_url( + '/admin/lock.php', + [ + 'id' => $block->context->id, + ] + ), + new pix_icon($lockicon, $lockstring, 'moodle', array('class' => 'iconsmall', 'title' => '')), + $lockstring, + ['class' => 'editing_lock'] + ); + } + } + return $controls; } diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 94f995d26fe25..93d32b5d2bdbf 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -834,6 +834,43 @@ public function action() { } return $this->action; } + + /** + * Add the menu item to handle locking and unlocking of a conext. + * + * @param \navigation_node $node Node to add + * @param \context $context The context to be locked + */ + protected function add_context_locking_node(\navigation_node $node, \context $context) { + global $CFG; + // Manage context locking. + if (!empty($CFG->contextlocking) && has_capability('moodle/site:managecontextlocks', $context)) { + $parentcontext = $context->get_parent_context(); + if (empty($parentcontext) || !$parentcontext->locked) { + if ($context->locked) { + $lockicon = 'i/unlock'; + $lockstring = get_string('managecontextunlock', 'admin'); + } else { + $lockicon = 'i/lock'; + $lockstring = get_string('managecontextlock', 'admin'); + } + $node->add( + $lockstring, + new moodle_url( + '/admin/lock.php', + [ + 'id' => $context->id, + ] + ), + self::TYPE_SETTING, + null, + 'contextlocking', + new pix_icon($lockicon, '') + ); + } + } + + } } /** @@ -4371,6 +4408,9 @@ protected function load_course_settings($forceopen = false) { null, 'gradebooksetup', new pix_icon('i/settings', '')); } + // Add the context locking node. + $this->add_context_locking_node($coursenode, $coursecontext); + // Add outcome if permitted if ($adminoptions->outcomes) { $url = new moodle_url('/grade/edit/outcome/course.php', array('id'=>$course->id)); @@ -4507,6 +4547,10 @@ protected function load_module_settings() { $url = new moodle_url('/'.$CFG->admin.'/roles/check.php', array('contextid'=>$this->page->cm->context->id)); $modulenode->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING, null, 'rolecheck'); } + + // Add the context locking node. + $this->add_context_locking_node($modulenode, $this->page->cm->context); + // Manage filters if (has_capability('moodle/filter:manage', $this->page->cm->context) && count(filter_get_available_in_context($this->page->cm->context))>0) { $url = new moodle_url('/filter/manage.php', array('contextid'=>$this->page->cm->context->id)); @@ -5087,6 +5131,9 @@ protected function load_block_settings() { 'checkpermissions', new pix_icon('i/checkpermissions', '')); } + // Add the context locking node. + $this->add_context_locking_node($blocknode, $this->context); + return $blocknode; } @@ -5149,6 +5196,9 @@ protected function load_category_settings() { $categorynode->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING, null, 'checkpermissions', new pix_icon('i/checkpermissions', '')); } + // Add the context locking node. + $this->add_context_locking_node($categorynode, $catcontext); + // Cohorts if (has_any_capability(array('moodle/cohort:view', 'moodle/cohort:manage'), $catcontext)) { $categorynode->add(get_string('cohorts', 'cohort'), new moodle_url('/cohort/index.php',