From 274dc06881635804a03066c8c0de83e519332cfb Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Tue, 22 Jul 2014 17:05:06 +0800 Subject: [PATCH] MDL-34189 cohorts: Allow admin/manager to see all cohorts on one page --- cohort/assign.php | 8 +- cohort/edit.php | 29 +++- cohort/edit_form.php | 5 + cohort/index.php | 70 +++++++--- cohort/lib.php | 177 +++++++++++++++++++++--- cohort/tests/behat/add_cohort.feature | 2 +- cohort/tests/behat/view_cohorts.feature | 67 +++++++++ cohort/tests/cohortlib_test.php | 69 +++++++++ lang/en/cohort.php | 2 + lib/accesslib.php | 2 +- 10 files changed, 383 insertions(+), 48 deletions(-) create mode 100644 cohort/tests/behat/view_cohorts.feature diff --git a/cohort/assign.php b/cohort/assign.php index c50e3a06672..88731179679 100644 --- a/cohort/assign.php +++ b/cohort/assign.php @@ -26,6 +26,7 @@ require('../config.php'); require_once($CFG->dirroot.'/cohort/locallib.php'); $id = required_param('id', PARAM_INT); +$returnurl = optional_param('returnurl', '', PARAM_LOCALURL); require_login(); @@ -38,7 +39,11 @@ $PAGE->set_context($context); $PAGE->set_url('/cohort/assign.php', array('id'=>$id)); $PAGE->set_pagelayout('admin'); -$returnurl = new moodle_url('/cohort/index.php', array('contextid'=>$cohort->contextid)); +if ($returnurl) { + $returnurl = new moodle_url($returnurl); +} else { + $returnurl = new moodle_url('/cohort/index.php', array('contextid' => $cohort->contextid)); +} if (!empty($cohort->component)) { // We can not manually edit cohorts that were created by external systems, sorry. @@ -100,6 +105,7 @@ if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) { ?>
+ diff --git a/cohort/edit.php b/cohort/edit.php index a585f35cda1..dbee96f9949 100644 --- a/cohort/edit.php +++ b/cohort/edit.php @@ -31,6 +31,7 @@ $id = optional_param('id', 0, PARAM_INT); $contextid = optional_param('contextid', 0, PARAM_INT); $delete = optional_param('delete', 0, PARAM_BOOL); $confirm = optional_param('confirm', 0, PARAM_BOOL); +$returnurl = optional_param('returnurl', '', PARAM_LOCALURL); require_login(); @@ -52,7 +53,11 @@ if ($id) { require_capability('moodle/cohort:manage', $context); -$returnurl = new moodle_url('/cohort/index.php', array('contextid'=>$context->id)); +if ($returnurl) { + $returnurl = new moodle_url($returnurl); +} else { + $returnurl = new moodle_url('/cohort/index.php', array('contextid'=>$context->id)); +} if (!empty($cohort->component)) { // We can not manually edit cohorts that were created by external systems, sorry. @@ -60,7 +65,8 @@ if (!empty($cohort->component)) { } $PAGE->set_context($context); -$PAGE->set_url('/cohort/edit.php', array('contextid'=>$context->id, 'id'=>$cohort->id)); +$baseurl = new moodle_url('/cohort/edit.php', array('contextid' => $context->id, 'id' => $cohort->id)); +$PAGE->set_url($baseurl); $PAGE->set_context($context); $PAGE->set_pagelayout('admin'); @@ -84,7 +90,8 @@ if ($delete and $cohort->id) { $PAGE->set_heading($COURSE->fullname); echo $OUTPUT->header(); echo $OUTPUT->heading($strheading); - $yesurl = new moodle_url('/cohort/edit.php', array('id'=>$cohort->id, 'delete'=>1, 'confirm'=>1,'sesskey'=>sesskey())); + $yesurl = new moodle_url('/cohort/edit.php', array('id' => $cohort->id, 'delete' => 1, + 'confirm' => 1, 'sesskey' => sesskey(), 'returnurl' => $returnurl->out_as_local_url())); $message = get_string('delconfirm', 'cohort', format_string($cohort->name)); echo $OUTPUT->confirm($message, $yesurl, $returnurl); echo $OUTPUT->footer(); @@ -107,7 +114,7 @@ $PAGE->set_title($strheading); $PAGE->set_heading($COURSE->fullname); $PAGE->navbar->add($strheading); -$editform = new cohort_edit_form(null, array('editoroptions'=>$editoroptions, 'data'=>$cohort)); +$editform = new cohort_edit_form(null, array('editoroptions'=>$editoroptions, 'data'=>$cohort, 'returnurl'=>$returnurl)); if ($editform->is_cancelled()) { redirect($returnurl); @@ -121,12 +128,22 @@ if ($editform->is_cancelled()) { cohort_add_cohort($data); } - // Use new context id, it could have been changed. - redirect(new moodle_url('/cohort/index.php', array('contextid'=>$data->contextid))); + if ($returnurl->get_param('showall') || $returnurl->get_param('contextid') == $data->contextid) { + // Redirect to where we were before. + redirect($returnurl); + } else { + // Use new context id, it has been changed. + redirect(new moodle_url('/cohort/index.php', array('contextid' => $data->contextid))); + } } echo $OUTPUT->header(); echo $OUTPUT->heading($strheading); + +if (!$id && ($editcontrols = cohort_edit_controls($context, $baseurl))) { + echo $OUTPUT->render($editcontrols); +} + echo $editform->display(); echo $OUTPUT->footer(); diff --git a/cohort/edit_form.php b/cohort/edit_form.php index fb7409e901e..72a5db7d0ee 100644 --- a/cohort/edit_form.php +++ b/cohort/edit_form.php @@ -53,6 +53,11 @@ class cohort_edit_form extends moodleform { $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); + if (isset($this->_customdata['returnurl'])) { + $mform->addElement('hidden', 'returnurl', $this->_customdata['returnurl']->out_as_local_url()); + $mform->setType('returnurl', PARAM_LOCALURL); + } + $this->add_action_buttons(); $this->set_data($cohort); diff --git a/cohort/index.php b/cohort/index.php index b0c30bd8080..796dd03d165 100644 --- a/cohort/index.php +++ b/cohort/index.php @@ -25,10 +25,12 @@ require('../config.php'); require($CFG->dirroot.'/cohort/lib.php'); require_once($CFG->libdir.'/adminlib.php'); +require_once($CFG->libdir.'/coursecatlib.php'); $contextid = optional_param('contextid', 0, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); $searchquery = optional_param('search', '', PARAM_RAW); +$showall = optional_param('showall', false, PARAM_BOOL); require_login(); @@ -61,13 +63,18 @@ if ($category) { $PAGE->set_url('/cohort/index.php', array('contextid'=>$context->id)); $PAGE->set_title($strcohorts); $PAGE->set_heading($COURSE->fullname); + $showall = false; } else { admin_externalpage_setup('cohorts', '', null, '', array('pagelayout'=>'report')); } echo $OUTPUT->header(); -$cohorts = cohort_get_cohorts($context->id, $page, 25, $searchquery); +if ($showall) { + $cohorts = cohort_get_all_cohorts($page, 25, $searchquery); +} else { + $cohorts = cohort_get_cohorts($context->id, $page, 25, $searchquery); +} $count = ''; if ($cohorts['allcohorts'] > 0) { @@ -80,6 +87,22 @@ if ($cohorts['allcohorts'] > 0) { echo $OUTPUT->heading(get_string('cohortsin', 'cohort', $context->get_context_name()).$count); +$params = array('page' => $page); +if ($contextid) { + $params['contextid'] = $contextid; +} +if ($searchquery) { + $params['search'] = $searchquery; +} +if ($showall) { + $params['showall'] = true; +} +$baseurl = new moodle_url('/cohort/index.php', $params); + +if ($editcontrols = cohort_edit_controls($context, $baseurl)) { + echo $OUTPUT->render($editcontrols); +} + // Add search form. $search = html_writer::start_tag('form', array('id'=>'searchcohortquery', 'method'=>'get')); $search .= html_writer::start_tag('div'); @@ -87,25 +110,26 @@ $search .= html_writer::label(get_string('searchcohort', 'cohort'), 'cohort_sear $search .= html_writer::empty_tag('input', array('id'=>'cohort_search_q', 'type'=>'text', 'name'=>'search', 'value'=>$searchquery)); $search .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('search', 'cohort'))); $search .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'contextid', 'value'=>$contextid)); +$search .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'showall', 'value'=>$showall)); $search .= html_writer::end_tag('div'); $search .= html_writer::end_tag('form'); echo $search; - // Output pagination bar. -$params = array('page' => $page); -if ($contextid) { - $params['contextid'] = $contextid; -} -if ($search) { - $params['search'] = $searchquery; -} -$baseurl = new moodle_url('/cohort/index.php', $params); echo $OUTPUT->paging_bar($cohorts['totalcohorts'], $page, 25, $baseurl); $data = array(); foreach($cohorts['cohorts'] as $cohort) { $line = array(); + $cohortcontext = context::instance_by_id($cohort->contextid); + if ($showall) { + if ($cohortcontext->contextlevel == CONTEXT_COURSECAT) { + $cat = coursecat::get($cohortcontext->instanceid); + $line[] = html_writer::link(new moodle_url('/cohort/index.php' , array('contextid' => $cohort->contextid)), $cat->get_formatted_name()); + } else { + $line[] = get_string('coresystem'); + } + } $line[] = format_string($cohort->name); $line[] = s($cohort->idnumber); // All idnumbers are plain text. $line[] = format_text($cohort->description, $cohort->descriptionformat); @@ -120,12 +144,19 @@ foreach($cohorts['cohorts'] as $cohort) { $buttons = array(); if (empty($cohort->component)) { - if ($manager) { - $buttons[] = html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id, 'delete'=>1)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/delete'), 'alt'=>get_string('delete'), 'class'=>'iconsmall'))); - $buttons[] = html_writer::link(new moodle_url('/cohort/edit.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/edit'), 'alt'=>get_string('edit'), 'class'=>'iconsmall'))); + $cohortmanager = has_capability('moodle/cohort:manage', $cohortcontext); + $cohortcanassign = has_capability('moodle/cohort:assign', $cohortcontext); + + $urlparams = array('id' => $cohort->id, 'returnurl' => $baseurl->out_as_local_url()); + if ($cohortmanager) { + $buttons[] = html_writer::link(new moodle_url('/cohort/edit.php', $urlparams + array('delete' => 1)), + html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/delete'), 'alt' => get_string('delete'), 'class' => 'iconsmall'))); + $buttons[] = html_writer::link(new moodle_url('/cohort/edit.php', $urlparams), + html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/edit'), 'alt' => get_string('edit'), 'class' => 'iconsmall'))); } - if ($manager or $canassign) { - $buttons[] = html_writer::link(new moodle_url('/cohort/assign.php', array('id'=>$cohort->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('i/users'), 'alt'=>get_string('assign', 'core_cohort'), 'class'=>'iconsmall'))); + if ($cohortcanassign) { + $buttons[] = html_writer::link(new moodle_url('/cohort/assign.php', $urlparams), + html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/users'), 'alt' => get_string('assign', 'core_cohort'), 'class' => 'iconsmall'))); } } $line[] = implode(' ', $buttons); @@ -136,14 +167,13 @@ $table = new html_table(); $table->head = array(get_string('name', 'cohort'), get_string('idnumber', 'cohort'), get_string('description', 'cohort'), get_string('memberscount', 'cohort'), get_string('component', 'cohort'), get_string('edit')); $table->colclasses = array('leftalign name', 'leftalign id', 'leftalign description', 'leftalign size','centeralign source', 'centeralign action'); +if ($showall) { + array_unshift($table->head, get_string('category')); + array_unshift($table->colclasses, 'leftalign category'); +} $table->id = 'cohorts'; $table->attributes['class'] = 'admintable generaltable'; $table->data = $data; echo html_writer::table($table); echo $OUTPUT->paging_bar($cohorts['totalcohorts'], $page, 25, $baseurl); - -if ($manager) { - echo $OUTPUT->single_button(new moodle_url('/cohort/edit.php', array('contextid'=>$context->id)), get_string('add')); -} - echo $OUTPUT->footer(); diff --git a/cohort/lib.php b/cohort/lib.php index 66396393168..0110e9a9a82 100644 --- a/cohort/lib.php +++ b/cohort/lib.php @@ -247,9 +247,40 @@ function cohort_get_visible_list($course, $onlyenrolled=true) { return $cohorts; } +/** + * Produces a part of SQL query to filter cohorts by the search string + * + * Called from {@link cohort_get_cohorts()} and {@link cohort_get_all_cohorts()} + * + * @access private + * + * @param string $search + * @return array of two elements - SQL condition and array of unnamed parameters + */ +function cohort_get_search_query($search) { + global $DB; + $params = array(); + if (empty($search)) { + // This function should not be called if there is no search string, just in case return dummy query. + return array('1=1', $params); + } + $searchparam = '%' . $DB->sql_like_escape($search) . '%'; + $conditions = array(); + $fields = array('name', 'idnumber', 'description'); + foreach ($fields as $field) { + $conditions[] = $DB->sql_like($field, "?", false); + $params[] = $searchparam; + } + $sql = '(' . implode(' OR ', $conditions) . ')'; + return array($sql, $params); +} + /** * Get all the cohorts defined in given context. * + * The function does not check user capability to view/manage cohorts in the given context + * assuming that it has been already verified. + * * @param int $contextid * @param int $page number of the current page * @param int $perpage items per page @@ -259,29 +290,137 @@ function cohort_get_visible_list($course, $onlyenrolled=true) { function cohort_get_cohorts($contextid, $page = 0, $perpage = 25, $search = '') { global $DB; - // Add some additional sensible conditions - $tests = array('contextid = ?'); - $params = array($contextid); - - if (!empty($search)) { - $conditions = array('name', 'idnumber', 'description'); - $searchparam = '%' . $DB->sql_like_escape($search) . '%'; - foreach ($conditions as $key=>$condition) { - $conditions[$key] = $DB->sql_like($condition, "?", false); - $params[] = $searchparam; - } - $tests[] = '(' . implode(' OR ', $conditions) . ')'; - } - $wherecondition = implode(' AND ', $tests); - $fields = "SELECT *"; $countfields = "SELECT COUNT(1)"; $sql = " FROM {cohort} - WHERE $wherecondition"; + WHERE contextid = ?"; + $params = array($contextid); $order = " ORDER BY name ASC, idnumber ASC"; - $allcohorts = $DB->count_records('cohort', array('contextid'=>$contextid)); - $totalcohorts = $DB->count_records_sql($countfields . $sql, $params); + + if (!empty($search)) { + list($searchcondition, $searchparams) = cohort_get_search_query($search); + $sql .= ' AND ' . $searchcondition; + $params = array_merge($params, $searchparams); + } + + $totalcohorts = $allcohorts = $DB->count_records('cohort', array('contextid' => $contextid)); + if (!empty($search)) { + $totalcohorts = $DB->count_records_sql($countfields . $sql, $params); + } $cohorts = $DB->get_records_sql($fields . $sql . $order, $params, $page*$perpage, $perpage); - return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts, 'allcohorts'=>$allcohorts); + return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts, 'allcohorts' => $allcohorts); } + +/** + * Get all the cohorts defined anywhere in system. + * + * The function assumes that user capability to view/manage cohorts on system level + * has already been verified. This function only checks if such capabilities have been + * revoked in child (categories) contexts. + * + * @param int $page number of the current page + * @param int $perpage items per page + * @param string $search search string + * @return array Array(totalcohorts => int, cohorts => array, allcohorts => int) + */ +function cohort_get_all_cohorts($page = 0, $perpage = 25, $search = '') { + global $DB; + + $fields = "SELECT c.*, ".context_helper::get_preload_record_columns_sql('ctx'); + $countfields = "SELECT COUNT(*)"; + $sql = " FROM {cohort} c + JOIN {context} ctx ON ctx.id = c.contextid "; + $params = array(); + $wheresql = ''; + + if ($excludedcontexts = cohort_get_invisible_contexts()) { + list($excludedsql, $excludedparams) = $DB->get_in_or_equal($excludedcontexts, SQL_PARAMS_QM, null, false); + $wheresql = ' WHERE c.contextid '.$excludedsql; + $params = array_merge($params, $excludedparams); + } + + $totalcohorts = $allcohorts = $DB->count_records_sql($countfields . $sql . $wheresql, $params); + + if (!empty($search)) { + list($searchcondition, $searchparams) = cohort_get_search_query($search); + $wheresql .= ($wheresql ? ' AND ' : ' WHERE ') . $searchcondition; + $params = array_merge($params, $searchparams); + $totalcohorts = $DB->count_records_sql($countfields . $sql . $wheresql, $params); + } + + $order = " ORDER BY c.name ASC, c.idnumber ASC"; + $cohorts = $DB->get_records_sql($fields . $sql . $wheresql . $order, $params, $page*$perpage, $perpage); + + // Preload used contexts, they will be used to check view/manage/assign capabilities and display categories names. + foreach (array_keys($cohorts) as $key) { + context_helper::preload_from_record($cohorts[$key]); + } + + return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts, 'allcohorts' => $allcohorts); +} + +/** + * Returns list of contexts where cohorts are present but current user does not have capability to view/manage them. + * + * This function is called from {@link cohort_get_all_cohorts()} to ensure correct pagination in rare cases when user + * is revoked capability in child contexts. It assumes that user's capability to view/manage cohorts on system + * level has already been verified. + * + * @access private + * + * @return array array of context ids + */ +function cohort_get_invisible_contexts() { + global $DB; + if (is_siteadmin()) { + // Shortcut, admin can do anything and can not be prohibited from any context. + return array(); + } + $records = $DB->get_recordset_sql("SELECT DISTINCT ctx.id, ".context_helper::get_preload_record_columns_sql('ctx')." ". + "FROM {context} ctx JOIN {cohort} c ON ctx.id = c.contextid "); + $excludedcontexts = array(); + foreach ($records as $ctx) { + context_helper::preload_from_record($ctx); + if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), context::instance_by_id($ctx->id))) { + $excludedcontexts[] = $ctx->id; + } + } + return $excludedcontexts; +} + +/** + * Returns navigation controls (tabtree) to be displayed on cohort management pages + * + * @param context $context system or category context where cohorts controls are about to be displayed + * @param moodle_url $currenturl + * @return null|renderable + */ +function cohort_edit_controls(context $context, moodle_url $currenturl) { + $tabs = array(); + $currenttab = 'view'; + $viewurl = new moodle_url('/cohort/index.php', array('contextid' => $context->id)); + if (($searchquery = $currenturl->get_param('search'))) { + $viewurl->param('search', $searchquery); + } + if ($context->contextlevel == CONTEXT_SYSTEM) { + $tabs[] = new tabobject('view', new moodle_url($viewurl, array('showall' => 0)), get_string('systemcohorts', 'cohort')); + $tabs[] = new tabobject('viewall', new moodle_url($viewurl, array('showall' => 1)), get_string('allcohorts', 'cohort')); + if ($currenturl->get_param('showall')) { + $currenttab = 'viewall'; + } + } else { + $tabs[] = new tabobject('view', $viewurl, get_string('cohorts', 'cohort')); + } + if (has_capability('moodle/cohort:manage', $context)) { + $addurl = new moodle_url('/cohort/edit.php', array('contextid' => $context->id)); + $tabs[] = new tabobject('addcohort', $addurl, get_string('addcohort', 'cohort')); + if ($currenturl->get_path() === $addurl->get_path() && !$currenturl->param('id')) { + $currenttab = 'addcohort'; + } + } + if (count($tabs) > 1) { + return new tabtree($tabs, $currenttab); + } + return null; +} \ No newline at end of file diff --git a/cohort/tests/behat/add_cohort.feature b/cohort/tests/behat/add_cohort.feature index bb6db425795..faac511b7e6 100644 --- a/cohort/tests/behat/add_cohort.feature +++ b/cohort/tests/behat/add_cohort.feature @@ -13,7 +13,7 @@ Feature: Add cohorts of users | user4 | Forth | User | forth@user.com | And I log in as "admin" And I navigate to "Cohorts" node in "Site administration > Users > Accounts" - And I press "Add" + And I follow "Add new cohort" And I set the following fields to these values: | Name | Test cohort name | | Context | System | diff --git a/cohort/tests/behat/view_cohorts.feature b/cohort/tests/behat/view_cohorts.feature new file mode 100644 index 00000000000..be8e08862d5 --- /dev/null +++ b/cohort/tests/behat/view_cohorts.feature @@ -0,0 +1,67 @@ +@core @core_cohort +Feature: View cohort list + In order to operate with cohorts + As an admin or manager + I need to be able to view the list of cohorts in the system + + Background: + Given the following "categories" exist: + | name | category | idnumber | + | Cat 1 | 0 | CAT1 | + | Cat 2 | 0 | CAT2 | + | Cat 3 | CAT1 | CAT3 | + And the following "cohorts" exist: + | name | idnumber | + | System cohort | CH0 | + And the following "cohorts" exist: + | name | idnumber | contextlevel | reference | + | Cohort in category 1 | CH1 | Category | CAT1 | + | Cohort in category 2 | CH2 | Category | CAT2 | + | Cohort in category 3 | CH3 | Category | CAT3 | + Given the following "users" exist: + | username | firstname | lastname | email | + | user1 | First | User | first@user.com | + | user2 | Second | User | second@user.com | + And the following "role assigns" exist: + | user | role | contextlevel | reference | + | user1 | manager | System | | + | user2 | manager | Category | CAT1 | + + @javascript + Scenario: Admin can see system cohorts and all cohorts + When I log in as "admin" + And I navigate to "Cohorts" node in "Site administration > Users > Accounts" + Then I should see "System cohort" + And I should not see "Cohort in category" + And I follow "All cohorts" + And I should see "System cohort" + And I should see "Cohort in category 1" + And I should see "Cohort in category 2" + And I should see "Cohort in category 3" + And I log out + + @javascript + Scenario: Manager can see system cohorts and all cohorts + When I log in as "user1" + And I navigate to "Cohorts" node in "Site administration > Users > Accounts" + Then I should see "System cohort" + And I should not see "Cohort in category" + And I follow "All cohorts" + And I should see "System cohort" + And I should see "Cohort in category 1" + And I should see "Cohort in category 2" + And I should see "Cohort in category 3" + And I log out + + @javascript + Scenario: Manager in category can see cohorts in the category + When I log in as "user2" + And I follow "Courses" + And I follow "Cat 1" + And I follow "Cohorts" + And I should not see "All cohorts" + And I should not see "System cohort" + And I should see "Cohort in category 1" + And I should not see "Cohort in category 2" + And I should not see "Cohort in category 3" + And I log out diff --git a/cohort/tests/cohortlib_test.php b/cohort/tests/cohortlib_test.php index eadcc561ca2..ee441079a35 100644 --- a/cohort/tests/cohortlib_test.php +++ b/cohort/tests/cohortlib_test.php @@ -473,5 +473,74 @@ class core_cohort_cohortlib_testcase extends advanced_testcase { $this->assertEquals(0, $result['totalcohorts']); $this->assertEquals(array(), $result['cohorts']); $this->assertEquals(3, $result['allcohorts']); + + $result = cohort_get_cohorts(context_system::instance()->id); + $this->assertEquals(1, $result['totalcohorts']); + $this->assertEquals(array($cohort4->id=>$cohort4), $result['cohorts']); + $this->assertEquals(1, $result['allcohorts']); + } + + public function test_cohort_get_all_cohorts() { + global $DB; + + $this->resetAfterTest(); + + $category1 = $this->getDataGenerator()->create_category(); + $category2 = $this->getDataGenerator()->create_category(); + + $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>context_coursecat::instance($category1->id)->id, 'name'=>'aaagrrryyy', 'idnumber'=>'','description'=>'')); + $cohort2 = $this->getDataGenerator()->create_cohort(array('contextid'=>context_coursecat::instance($category1->id)->id, 'name'=>'bbb', 'idnumber'=>'', 'description'=>'yyybrrr')); + $cohort3 = $this->getDataGenerator()->create_cohort(array('contextid'=>context_coursecat::instance($category2->id)->id, 'name'=>'ccc', 'idnumber'=>'xxarrrghyyy', 'description'=>'po_us')); + $cohort4 = $this->getDataGenerator()->create_cohort(array('contextid'=>context_system::instance()->id)); + + // Get list of all cohorts as admin. + $this->setAdminUser(); + + $result = cohort_get_all_cohorts(0, 100, ''); + $this->assertEquals(4, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1, $cohort2->id=>$cohort2, $cohort3->id=>$cohort3, $cohort4->id=>$cohort4), $result['cohorts']); + $this->assertEquals(4, $result['allcohorts']); + + $result = cohort_get_all_cohorts(0, 100, 'grrr'); + $this->assertEquals(1, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1), $result['cohorts']); + $this->assertEquals(4, $result['allcohorts']); + + // Get list of all cohorts as manager who has capability everywhere. + $user = $this->getDataGenerator()->create_user(); + $managerrole = $DB->get_record('role', array('shortname' => 'manager')); + role_assign($managerrole->id, $user->id, context_system::instance()->id); + $this->setUser($user); + + $result = cohort_get_all_cohorts(0, 100, ''); + $this->assertEquals(4, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1, $cohort2->id=>$cohort2, $cohort3->id=>$cohort3, $cohort4->id=>$cohort4), $result['cohorts']); + $this->assertEquals(4, $result['allcohorts']); + + $result = cohort_get_all_cohorts(0, 100, 'grrr'); + $this->assertEquals(1, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1), $result['cohorts']); + $this->assertEquals(4, $result['allcohorts']); + + // Get list of all cohorts as manager who has capability everywhere except category2. + $context2 = context_coursecat::instance($category2->id); + role_change_permission($managerrole->id, $context2, 'moodle/cohort:view', CAP_PROHIBIT); + role_change_permission($managerrole->id, $context2, 'moodle/cohort:manage', CAP_PROHIBIT); + $this->assertFalse(has_any_capability(array('moodle/cohort:view', 'moodle/cohort:manage'), $context2)); + + $result = cohort_get_all_cohorts(0, 100, ''); + $this->assertEquals(3, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1, $cohort2->id=>$cohort2, $cohort4->id=>$cohort4), $result['cohorts']); + $this->assertEquals(3, $result['allcohorts']); + + $result = cohort_get_all_cohorts(0, 100, 'grrr'); + $this->assertEquals(1, $result['totalcohorts']); + $this->assertEquals(array($cohort1->id=>$cohort1), $result['cohorts']); + $this->assertEquals(3, $result['allcohorts']); + + $result = cohort_get_cohorts(context_coursecat::instance($category1->id)->id, 1, 1, 'yyy'); + $this->assertEquals(2, $result['totalcohorts']); + $this->assertEquals(array($cohort2->id=>$cohort2), $result['cohorts']); + $this->assertEquals(2, $result['allcohorts']); } } diff --git a/lang/en/cohort.php b/lang/en/cohort.php index b7d94e65186..e76b5281285 100644 --- a/lang/en/cohort.php +++ b/lang/en/cohort.php @@ -25,6 +25,7 @@ */ $string['addcohort'] = 'Add new cohort'; +$string['allcohorts'] = 'All cohorts'; $string['anycohort'] = 'Any'; $string['assign'] = 'Assign'; $string['assignto'] = 'Cohort \'{$a}\' members'; @@ -59,6 +60,7 @@ $string['potusers'] = 'Potential users'; $string['potusersmatching'] = 'Potential matching users'; $string['removeuserwarning'] = 'Removing users from a cohort may result in unenrolling of users from multiple courses which includes deleting of user settings, grades, group membership and other user information from affected courses.'; $string['selectfromcohort'] = 'Select members from cohort'; +$string['systemcohorts'] = 'System cohorts'; $string['unknowncohort'] = 'Unknown cohort ({$a})!'; $string['useradded'] = 'User added to cohort "{$a}"'; $string['search'] = 'Search'; diff --git a/lib/accesslib.php b/lib/accesslib.php index bd58f9a962b..b3ed02ac690 100644 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -5156,7 +5156,7 @@ abstract class context extends stdClass implements IteratorAggregate { * @return void (modifies $rec) */ protected static function preload_from_record(stdClass $rec) { - if (empty($rec->ctxid) or empty($rec->ctxlevel) or empty($rec->ctxinstance) or empty($rec->ctxpath) or empty($rec->ctxdepth)) { + if (empty($rec->ctxid) or empty($rec->ctxlevel) or !isset($rec->ctxinstance) or empty($rec->ctxpath) or empty($rec->ctxdepth)) { // $rec does not have enough data, passed here repeatedly or context does not exist yet return; }