mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
Merge branch 'wip-MDL-33017-m24-r2' of git://github.com/samhemelryk/moodle
This commit is contained in:
commit
8f3020558d
51
blocks/navigation/yui/navigation/navigation.js
vendored
51
blocks/navigation/yui/navigation/navigation.js
vendored
@ -74,6 +74,35 @@ var EXPANSIONLIMIT_EVERYTHING = 0,
|
||||
EXPANSIONLIMIT_SECTION = 30,
|
||||
EXPANSIONLIMIT_ACTIVITY = 40;
|
||||
|
||||
/**
|
||||
* Mappings for the different types of nodes coming from the navigation.
|
||||
* Copied from lib/navigationlib.php navigation_node constants.
|
||||
* @type object
|
||||
*/
|
||||
var NODETYPE = {
|
||||
/** @type int Root node = 0 */
|
||||
ROOTNODE : 0,
|
||||
/** @type int System context = 1 */
|
||||
SYSTEM : 1,
|
||||
/** @type int Course category = 10 */
|
||||
CATEGORY : 10,
|
||||
/** @type int Course = 20 */
|
||||
COURSE : 20,
|
||||
/** @type int Course section = 30 */
|
||||
SECTION : 30,
|
||||
/** @type int Activity (course module) = 40 */
|
||||
ACTIVITY : 40,
|
||||
/** @type int Resource (course module = 50 */
|
||||
RESOURCE : 50,
|
||||
/** @type int Custom node (could be anything) = 60 */
|
||||
CUSTOM : 60,
|
||||
/** @type int Setting = 70 */
|
||||
SETTING : 70,
|
||||
/** @type int User context = 80 */
|
||||
USER : 80,
|
||||
/** @type int Container = 90 */
|
||||
CONTAINER : 90
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigation tree class.
|
||||
@ -299,7 +328,7 @@ BRANCH.prototype = {
|
||||
// Prepare the icon, should be an object representing a pix_icon
|
||||
var branchicon = false;
|
||||
var icon = this.get('icon');
|
||||
if (icon && (!isbranch || this.get('type') == 40)) {
|
||||
if (icon && (!isbranch || this.get('type') == NODETYPE.ACTIVITY)) {
|
||||
branchicon = Y.Node.create('<img alt="" />');
|
||||
branchicon.setAttribute('src', M.util.image_url(icon.pix, icon.component));
|
||||
branchli.addClass('item_with_icon');
|
||||
@ -419,13 +448,13 @@ BRANCH.prototype = {
|
||||
var coursecount = 0;
|
||||
for (var i in object.children) {
|
||||
if (typeof(object.children[i])=='object') {
|
||||
if (object.children[i].type == 20) {
|
||||
if (object.children[i].type == NODETYPE.COURSE) {
|
||||
coursecount++;
|
||||
}
|
||||
this.addChild(object.children[i]);
|
||||
}
|
||||
}
|
||||
if (this.get('type') == 10 && coursecount >= M.block_navigation.courselimit) {
|
||||
if ((this.get('type') == NODETYPE.CATEGORY || this.get('type') == NODETYPE.ROOTNODE) && coursecount >= M.block_navigation.courselimit) {
|
||||
this.addViewAllCoursesChild(this);
|
||||
}
|
||||
this.get('tree').toggleExpansion({target:this.node});
|
||||
@ -450,14 +479,14 @@ BRANCH.prototype = {
|
||||
var count = 0, i, children = branch.get('children');
|
||||
for (i in children) {
|
||||
// Add each branch to the tree
|
||||
if (children[i].type == 20) {
|
||||
if (children[i].type == NODETYPE.COURSE) {
|
||||
count++;
|
||||
}
|
||||
if (typeof(children[i])=='object') {
|
||||
branch.addChild(children[i]);
|
||||
}
|
||||
}
|
||||
if (branch.get('type') == 10 && count >= M.block_navigation.courselimit) {
|
||||
if (branch.get('type') == NODETYPE.CATEGORY && count >= M.block_navigation.courselimit) {
|
||||
this.addViewAllCoursesChild(branch);
|
||||
}
|
||||
}
|
||||
@ -468,10 +497,20 @@ BRANCH.prototype = {
|
||||
* Add a link to view all courses in a category
|
||||
*/
|
||||
addViewAllCoursesChild: function(branch) {
|
||||
var url = null;
|
||||
if (branch.get('type') == NODETYPE.ROOTNODE) {
|
||||
if (branch.get('key') === 'mycourses') {
|
||||
url = M.cfg.wwwroot + '/my';
|
||||
} else {
|
||||
url = M.cfg.wwwroot + '/course/index.php';
|
||||
}
|
||||
} else {
|
||||
url = M.cfg.wwwroot+'/course/category.php?id=' + branch.get('key');
|
||||
}
|
||||
branch.addChild({
|
||||
name : M.str.moodle.viewallcourses,
|
||||
title : M.str.moodle.viewallcourses,
|
||||
link : M.cfg.wwwroot+'/course/category.php?id='+branch.get('key'),
|
||||
link : url,
|
||||
haschildren : false,
|
||||
icon : {'pix':"i/navigationitem",'component':'moodle'}
|
||||
});
|
||||
|
253
enrol/tests/enrollib_test.php
Normal file
253
enrol/tests/enrollib_test.php
Normal file
@ -0,0 +1,253 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test non-plugin enrollib parts.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Test non-plugin enrollib parts.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_enrol_testcase extends advanced_testcase {
|
||||
|
||||
public function test_enrol_get_all_users_courses() {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->assertNotEmpty($studentrole);
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->assertNotEmpty($teacherrole);
|
||||
|
||||
$admin = get_admin();
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
$user4 = $this->getDataGenerator()->create_user();
|
||||
$user5 = $this->getDataGenerator()->create_user();
|
||||
|
||||
$category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
|
||||
$category2 = $this->getDataGenerator()->create_category();
|
||||
$course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id));
|
||||
$course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
|
||||
$course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0));
|
||||
$course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
|
||||
|
||||
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
|
||||
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
|
||||
$manual = enrol_get_plugin('manual');
|
||||
$this->assertNotEmpty($manual);
|
||||
|
||||
$manual->enrol_user($maninstance1, $user1->id, $teacherrole->id);
|
||||
$manual->enrol_user($maninstance1, $user2->id, $studentrole->id);
|
||||
$manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
|
||||
$manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
|
||||
|
||||
$manual->enrol_user($maninstance2, $user1->id);
|
||||
$manual->enrol_user($maninstance2, $user2->id);
|
||||
$manual->enrol_user($maninstance2, $user3->id, 0, 1, time()+(60*60));
|
||||
|
||||
$manual->enrol_user($maninstance3, $user1->id);
|
||||
$manual->enrol_user($maninstance3, $user2->id);
|
||||
$manual->enrol_user($maninstance3, $user3->id, 0, 1, time()-(60*60));
|
||||
$manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
|
||||
|
||||
|
||||
$courses = enrol_get_all_users_courses($CFG->siteguest);
|
||||
$this->assertSame(array(), $courses);
|
||||
|
||||
$courses = enrol_get_all_users_courses(0);
|
||||
$this->assertSame(array(), $courses);
|
||||
|
||||
// Results are sorted by visibility, sortorder by default (in our case order of creation)
|
||||
|
||||
$courses = enrol_get_all_users_courses($admin->id);
|
||||
$this->assertCount(1, $courses);
|
||||
$this->assertEquals(array($course1->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($admin->id, true);
|
||||
$this->assertCount(0, $courses);
|
||||
$this->assertEquals(array(), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user1->id);
|
||||
$this->assertCount(3, $courses);
|
||||
$this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user1->id, true);
|
||||
$this->assertCount(2, $courses);
|
||||
$this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user2->id);
|
||||
$this->assertCount(3, $courses);
|
||||
$this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user2->id, true);
|
||||
$this->assertCount(2, $courses);
|
||||
$this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user3->id);
|
||||
$this->assertCount(2, $courses);
|
||||
$this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user3->id, true);
|
||||
$this->assertCount(1, $courses);
|
||||
$this->assertEquals(array($course2->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user4->id);
|
||||
$this->assertCount(2, $courses);
|
||||
$this->assertEquals(array($course1->id, $course3->id), array_keys($courses));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user4->id, true);
|
||||
$this->assertCount(0, $courses);
|
||||
$this->assertEquals(array(), array_keys($courses));
|
||||
|
||||
// Make sure sorting and columns work.
|
||||
|
||||
$basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber',
|
||||
'startdate', 'visible', 'groupmode', 'groupmodeforce');
|
||||
|
||||
$courses = enrol_get_all_users_courses($user2->id, true);
|
||||
$course = reset($courses);
|
||||
context_helper::preload_from_record($course);
|
||||
$course = (array)$course;
|
||||
$this->assertEquals($basefields, array_keys($course), '', 0, 10, true);
|
||||
|
||||
$courses = enrol_get_all_users_courses($user2->id, false, 'modinfo');
|
||||
$course = reset($courses);
|
||||
$this->assertTrue(property_exists($course, 'modinfo'));
|
||||
|
||||
$courses = enrol_get_all_users_courses($user2->id, false, null, 'id DESC');
|
||||
$this->assertEquals(array($course3->id, $course2->id, $course1->id), array_keys($courses));
|
||||
}
|
||||
|
||||
public function test_enrol_user_sees_own_courses() {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->assertNotEmpty($studentrole);
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->assertNotEmpty($teacherrole);
|
||||
|
||||
$admin = get_admin();
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
$user4 = $this->getDataGenerator()->create_user();
|
||||
$user5 = $this->getDataGenerator()->create_user();
|
||||
$user6 = $this->getDataGenerator()->create_user();
|
||||
|
||||
$category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
|
||||
$category2 = $this->getDataGenerator()->create_category();
|
||||
$course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id));
|
||||
$course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
|
||||
$course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0));
|
||||
$course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
|
||||
|
||||
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
|
||||
$maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
$maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
|
||||
|
||||
$manual = enrol_get_plugin('manual');
|
||||
$this->assertNotEmpty($manual);
|
||||
|
||||
$manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
|
||||
|
||||
$manual->enrol_user($maninstance3, $user1->id, $teacherrole->id);
|
||||
|
||||
$manual->enrol_user($maninstance2, $user2->id, $studentrole->id);
|
||||
|
||||
$manual->enrol_user($maninstance1, $user3->id, $studentrole->id, 1, time()+(60*60));
|
||||
$manual->enrol_user($maninstance2, $user3->id, 0, 1, time()-(60*60));
|
||||
$manual->enrol_user($maninstance3, $user2->id, $studentrole->id);
|
||||
$manual->enrol_user($maninstance4, $user2->id, 0, 0, 0, ENROL_USER_SUSPENDED);
|
||||
|
||||
$manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
|
||||
$manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
|
||||
|
||||
|
||||
$this->assertFalse(enrol_user_sees_own_courses($CFG->siteguest));
|
||||
$this->assertFalse(enrol_user_sees_own_courses(0));
|
||||
$this->assertFalse(enrol_user_sees_own_courses($admin));
|
||||
$this->assertFalse(enrol_user_sees_own_courses(-222)); // Nonexistent user.
|
||||
|
||||
$this->assertTrue(enrol_user_sees_own_courses($user1));
|
||||
$this->assertTrue(enrol_user_sees_own_courses($user2->id));
|
||||
$this->assertFalse(enrol_user_sees_own_courses($user3->id));
|
||||
$this->assertFalse(enrol_user_sees_own_courses($user4));
|
||||
$this->assertFalse(enrol_user_sees_own_courses($user5));
|
||||
|
||||
$this->setAdminUser();
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setGuestUser();
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser(0);
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser($user1);
|
||||
$this->assertTrue(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser($user2);
|
||||
$this->assertTrue(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser($user3);
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser($user4);
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$this->setUser($user5);
|
||||
$this->assertFalse(enrol_user_sees_own_courses());
|
||||
|
||||
$user1 = $DB->get_record('user', array('id'=>$user1->id));
|
||||
$this->setUser($user1);
|
||||
$reads = $DB->perf_get_reads();
|
||||
$this->assertTrue(enrol_user_sees_own_courses());
|
||||
$this->assertGreaterThan($reads, $DB->perf_get_reads());
|
||||
|
||||
$user1 = $DB->get_record('user', array('id'=>$user1->id));
|
||||
$this->setUser($user1);
|
||||
require_login($course3);
|
||||
$reads = $DB->perf_get_reads();
|
||||
$this->assertTrue(enrol_user_sees_own_courses());
|
||||
$this->assertEquals($reads, $DB->perf_get_reads());
|
||||
}
|
||||
}
|
@ -392,6 +392,7 @@ $string['creatinguserroles'] = 'Creating user level role assignments and overrid
|
||||
$string['creatingusers'] = 'Creating users';
|
||||
$string['creatingxmlfile'] = 'Creating XML file';
|
||||
$string['currency'] = 'Currency';
|
||||
$string['currentcourse'] = 'Current course';
|
||||
$string['currentcourseadding'] = 'Current course, adding data to it';
|
||||
$string['currentcoursedeleting'] = 'Current course, deleting it first';
|
||||
$string['currentlanguage'] = 'Current language';
|
||||
|
@ -35,8 +35,10 @@ require_once($CFG->dirroot.'/course/lib.php');
|
||||
try {
|
||||
// Start buffer capture so that we can `remove` any errors
|
||||
ob_start();
|
||||
// Require id This is the key for whatever branch we want to get
|
||||
$branchid = required_param('id', PARAM_INT);
|
||||
// Require id This is the key for whatever branch we want to get.
|
||||
// This accepts alphanum because the courses and my courses branches don't have numerical keys.
|
||||
// For those branches we return the alphanum key, courses and mycourses.
|
||||
$branchid = required_param('id', PARAM_ALPHANUM);
|
||||
// This identifies the type of the branch we want to get
|
||||
$branchtype = required_param('type', PARAM_INT);
|
||||
// This identifies the block instance requesting AJAX extension
|
||||
@ -87,8 +89,14 @@ try {
|
||||
}
|
||||
$converter = new navigation_json();
|
||||
|
||||
// Find the actuall branch we are looking for
|
||||
$branch = $navigation->find($branchid, $branchtype);
|
||||
// Find the actual branch we are looking for
|
||||
if ($branchtype != 0) {
|
||||
$branch = $navigation->find($branchid, $branchtype);
|
||||
} else if ($branchid === 'mycourses' || $branchid === 'courses') {
|
||||
$branch = $navigation->find($branchid, navigation_node::TYPE_ROOTNODE);
|
||||
} else {
|
||||
throw new coding_exception('Invalid branch type/id passed to AJAX call to load branches.');
|
||||
}
|
||||
|
||||
// Remove links to categories if required.
|
||||
if (!$linkcategories) {
|
||||
|
@ -710,6 +710,56 @@ function enrol_get_users_courses($userid, $onlyactive = false, $fields = NULL, $
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Can user access at least one enrolled course?
|
||||
*
|
||||
* Cheat if necessary, but find out as fast as possible!
|
||||
*
|
||||
* @param int|stdClass $user null means use current user
|
||||
* @return bool
|
||||
*/
|
||||
function enrol_user_sees_own_courses($user = null) {
|
||||
global $USER;
|
||||
|
||||
if ($user === null) {
|
||||
$user = $USER;
|
||||
}
|
||||
$userid = is_object($user) ? $user->id : $user;
|
||||
|
||||
// Guest account does not have any courses
|
||||
if (isguestuser($userid) or empty($userid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's cheat here if this is the current user,
|
||||
// if user accessed any course recently, then most probably
|
||||
// we do not need to query the database at all.
|
||||
if ($USER->id == $userid) {
|
||||
if (!empty($USER->enrol['enrolled'])) {
|
||||
foreach ($USER->enrol['enrolled'] as $until) {
|
||||
if ($until > time()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now the slow way.
|
||||
$courses = enrol_get_all_users_courses($userid, true);
|
||||
foreach($courses as $course) {
|
||||
if ($course->visible) {
|
||||
return true;
|
||||
}
|
||||
context_helper::preload_from_record($course);
|
||||
$context = context_course::instance($course->id);
|
||||
if (has_capability('moodle/course:viewhiddencourses', $context, $user)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of courses user is enrolled into without any capability checks
|
||||
* - $fields is an array of fieldnames to ADD
|
||||
|
@ -73,6 +73,12 @@ class navigation_node implements renderable {
|
||||
const TYPE_USER = 80;
|
||||
/** @var int Setting node type, used for containers of no importance 90 */
|
||||
const TYPE_CONTAINER = 90;
|
||||
/** var int Course the current user is not enrolled in */
|
||||
const COURSE_OTHER = 0;
|
||||
/** var int Course the current user is enrolled in but not viewing */
|
||||
const COURSE_MY = 1;
|
||||
/** var int Course the current user is currently viewing */
|
||||
const COURSE_CURRENT = 2;
|
||||
|
||||
/** @var int Parameter to aid the coder in tracking [optional] */
|
||||
public $id = null;
|
||||
@ -118,6 +124,8 @@ class navigation_node implements renderable {
|
||||
public $parent = null;
|
||||
/** @var bool Override to not display the icon even if one is provided **/
|
||||
public $hideicon = false;
|
||||
/** @var bool Set to true if we KNOW that this node can be expanded. */
|
||||
public $isexpandable = false;
|
||||
/** @var array */
|
||||
protected $namedtypes = array(0=>'system',10=>'category',20=>'course',30=>'structure',40=>'activity',50=>'resource',60=>'custom',70=>'setting', 80=>'user');
|
||||
/** @var moodle_url */
|
||||
@ -379,7 +387,7 @@ class navigation_node implements renderable {
|
||||
* @return bool Returns true if it has children or could have (by AJAX expansion)
|
||||
*/
|
||||
public function has_children() {
|
||||
return ($this->nodetype === navigation_node::NODETYPE_BRANCH || $this->children->count()>0);
|
||||
return ($this->nodetype === navigation_node::NODETYPE_BRANCH || $this->children->count()>0 || $this->isexpandable);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -580,7 +588,7 @@ class navigation_node implements renderable {
|
||||
*/
|
||||
public function find_expandable(array &$expandable) {
|
||||
foreach ($this->children as &$child) {
|
||||
if ($child->nodetype == self::NODETYPE_BRANCH && $child->children->count() == 0 && $child->display) {
|
||||
if ($child->display && $child->has_children() && $child->children->count() == 0) {
|
||||
$child->id = 'expandable_branch_'.(count($expandable)+1);
|
||||
$this->add_class('canexpand');
|
||||
$expandable[] = array('id' => $child->id, 'key' => $child->key, 'type' => $child->type);
|
||||
@ -935,6 +943,8 @@ class global_navigation extends navigation_node {
|
||||
protected $showemptysections = true;
|
||||
/** @var bool A switch for whether courses should be shown within categories on the navigation. */
|
||||
protected $showcategories = null;
|
||||
/** @var null@var bool A switch for whether or not to show categories in the my courses branch. */
|
||||
protected $showmycategories = null;
|
||||
/** @var array An array of stdClasses for users that the navigation is extended for */
|
||||
protected $extendforuser = array();
|
||||
/** @var navigation_cache */
|
||||
@ -1020,8 +1030,8 @@ class global_navigation extends navigation_node {
|
||||
* @return bool
|
||||
*/
|
||||
public function initialise() {
|
||||
global $CFG, $SITE, $USER, $DB;
|
||||
// Check if it has alread been initialised
|
||||
global $CFG, $SITE, $USER;
|
||||
// Check if it has already been initialised
|
||||
if ($this->initialised || during_initial_install()) {
|
||||
return true;
|
||||
}
|
||||
@ -1029,11 +1039,12 @@ class global_navigation extends navigation_node {
|
||||
|
||||
// Set up the five base root nodes. These are nodes where we will put our
|
||||
// content and are as follows:
|
||||
// site: Navigation for the front page.
|
||||
// myprofile: User profile information goes here.
|
||||
// mycourses: The users courses get added here.
|
||||
// courses: Additional courses are added here.
|
||||
// users: Other users information loaded here.
|
||||
// site: Navigation for the front page.
|
||||
// myprofile: User profile information goes here.
|
||||
// currentcourse: The course being currently viewed.
|
||||
// mycourses: The users courses get added here.
|
||||
// courses: Additional courses are added here.
|
||||
// users: Other users information loaded here.
|
||||
$this->rootnodes = array();
|
||||
if (get_home_page() == HOMEPAGE_SITE) {
|
||||
// The home element should be my moodle because the root element is the site
|
||||
@ -1048,141 +1059,34 @@ class global_navigation extends navigation_node {
|
||||
$this->rootnodes['home']->action->param('redirect', '0');
|
||||
}
|
||||
}
|
||||
$this->rootnodes['site'] = $this->add_course($SITE);
|
||||
$this->rootnodes['site'] = $this->add_course($SITE);
|
||||
$this->rootnodes['myprofile'] = $this->add(get_string('myprofile'), null, self::TYPE_USER, null, 'myprofile');
|
||||
$this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), null, self::TYPE_ROOTNODE, null, 'mycourses');
|
||||
$this->rootnodes['courses'] = $this->add(get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_ROOTNODE, null, 'courses');
|
||||
$this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users');
|
||||
$this->rootnodes['currentcourse'] = $this->add(get_string('currentcourse'), null, self::TYPE_ROOTNODE, null, 'currentcourse');
|
||||
$this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), new moodle_url('/my'), self::TYPE_ROOTNODE, null, 'mycourses');
|
||||
$this->rootnodes['courses'] = $this->add(get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_ROOTNODE, null, 'courses');
|
||||
$this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users');
|
||||
|
||||
// We always load the frontpage course to ensure it is available without
|
||||
// JavaScript enabled.
|
||||
$this->add_front_page_course_essentials($this->rootnodes['site'], $SITE);
|
||||
$this->load_course_sections($SITE, $this->rootnodes['site']);
|
||||
|
||||
// Fetch all of the users courses.
|
||||
$mycourses = enrol_get_my_courses();
|
||||
// We need to show categories if we can show categories and the user isn't enrolled in any courses or we're not showing all courses
|
||||
$showcategories = ($this->show_categories() && (count($mycourses) == 0 || !empty($CFG->navshowallcourses)));
|
||||
$course = $this->page->course;
|
||||
|
||||
// $issite gets set to true if the current pages course is the sites frontpage course
|
||||
$issite = ($this->page->course->id == $SITE->id);
|
||||
// $ismycourse gets set to true if the user is enrolled in the current pages course.
|
||||
$ismycourse = !$issite && (array_key_exists($this->page->course->id, $mycourses));
|
||||
// Determine if the user is enrolled in any course.
|
||||
$enrolledinanycourse = enrol_user_sees_own_courses();
|
||||
|
||||
// Check if any courses were returned.
|
||||
if (count($mycourses) > 0) {
|
||||
|
||||
// Check if categories should be displayed within the my courses branch
|
||||
if (!empty($CFG->navshowmycoursecategories)) {
|
||||
|
||||
// Find the category of each mycourse
|
||||
$categories = array();
|
||||
foreach ($mycourses as $course) {
|
||||
$categories[] = $course->category;
|
||||
}
|
||||
|
||||
// Do a single DB query to get the categories immediately associated with
|
||||
// courses the user is enrolled in.
|
||||
$categories = $DB->get_records_list('course_categories', 'id', array_unique($categories), 'depth ASC, sortorder ASC');
|
||||
// Work out the parent categories that we need to load that we havn't
|
||||
// already got.
|
||||
$categoryids = array();
|
||||
foreach ($categories as $category) {
|
||||
$categoryids = array_merge($categoryids, explode('/', trim($category->path, '/')));
|
||||
}
|
||||
$categoryids = array_unique($categoryids);
|
||||
$categoryids = array_diff($categoryids, array_keys($categories));
|
||||
|
||||
if (count($categoryids)) {
|
||||
// Fetch any other categories we need.
|
||||
$allcategories = $DB->get_records_list('course_categories', 'id', $categoryids, 'depth ASC, sortorder ASC');
|
||||
if (is_array($allcategories) && count($allcategories) > 0) {
|
||||
$categories = array_merge($categories, $allcategories);
|
||||
}
|
||||
}
|
||||
|
||||
// We ONLY want the categories, we need to get rid of the keys
|
||||
$categories = array_values($categories);
|
||||
$addedcategories = array();
|
||||
while (($category = array_shift($categories)) !== null) {
|
||||
if ($category->parent == '0') {
|
||||
$categoryparent = $this->rootnodes['mycourses'];
|
||||
} else if (array_key_exists($category->parent, $addedcategories)) {
|
||||
$categoryparent = $addedcategories[$category->parent];
|
||||
} else {
|
||||
// Prepare to count iterations. We don't want to loop forever
|
||||
// accidentally if for some reason a category can't be placed.
|
||||
if (!isset($category->loopcount)) {
|
||||
$category->loopcount = 0;
|
||||
}
|
||||
$category->loopcount++;
|
||||
if ($category->loopcount > 5) {
|
||||
// This is a pretty serious problem and this should never happen.
|
||||
// If it does then for some reason a category has been loaded but
|
||||
// its parents have now. It could be data corruption.
|
||||
debugging('Category '.$category->id.' could not be placed within the navigation', DEBUG_DEVELOPER);
|
||||
} else {
|
||||
// Add it back to the end of the categories array
|
||||
array_push($categories, $category);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = new moodle_url('/course/category.php', array('id' => $category->id));
|
||||
$addedcategories[$category->id] = $categoryparent->add($category->name, $url, self::TYPE_CATEGORY, $category->name, $category->id);
|
||||
|
||||
if (!$category->visible) {
|
||||
// Let's decide the context where viewhidden cap checks will happen.
|
||||
if ($category->parent == '0') {
|
||||
$contexttocheck = context_system::instance();
|
||||
} else {
|
||||
$contexttocheck = context_coursecat::instance($category->parent);
|
||||
}
|
||||
if (!has_capability('moodle/category:viewhiddencategories', $contexttocheck)) {
|
||||
$addedcategories[$category->id]->display = false;
|
||||
} else {
|
||||
$addedcategories[$category->id]->hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->rootnodes['currentcourse']->mainnavonly = true;
|
||||
if ($enrolledinanycourse) {
|
||||
$this->rootnodes['mycourses']->isexpandable = true;
|
||||
if ($CFG->navshowallcourses) {
|
||||
// When we show all courses we need to show both the my courses and the regular courses branch.
|
||||
$this->rootnodes['courses']->isexpandable = true;
|
||||
}
|
||||
|
||||
// Add all of the users courses to the navigation.
|
||||
// First up we need to add to the mycourses section.
|
||||
foreach ($mycourses as $course) {
|
||||
$course->coursenode = $this->add_course($course, false, true);
|
||||
}
|
||||
|
||||
if (!empty($CFG->navshowallcourses)) {
|
||||
// Load all courses
|
||||
$this->load_all_courses();
|
||||
}
|
||||
|
||||
// Next if nasvshowallcourses is enabled then we need to add courses
|
||||
// to the courses branch as well.
|
||||
if (!empty($CFG->navshowallcourses)) {
|
||||
foreach ($mycourses as $course) {
|
||||
if (!empty($course->category) && !$this->can_add_more_courses_to_category($course->category)) {
|
||||
continue;
|
||||
}
|
||||
$genericcoursenode = $this->add_course($course, true);
|
||||
if ($genericcoursenode->isactive) {
|
||||
// We don't want this node to be active because we want the
|
||||
// node in the mycourses branch to be active.
|
||||
$genericcoursenode->make_inactive();
|
||||
$genericcoursenode->collapse = true;
|
||||
if ($genericcoursenode->parent && $genericcoursenode->parent->type == self::TYPE_CATEGORY) {
|
||||
$parent = $genericcoursenode->parent;
|
||||
while ($parent && $parent->type == self::TYPE_CATEGORY) {
|
||||
$parent->collapse = true;
|
||||
$parent = $parent->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!empty($CFG->navshowallcourses) || !$this->show_categories()) {
|
||||
// Load all courses
|
||||
$this->load_all_courses();
|
||||
} else {
|
||||
$this->rootnodes['courses']->isexpandable = true;
|
||||
}
|
||||
|
||||
$canviewcourseprofile = true;
|
||||
@ -1190,36 +1094,21 @@ class global_navigation extends navigation_node {
|
||||
// Next load context specific content into the navigation
|
||||
switch ($this->page->context->contextlevel) {
|
||||
case CONTEXT_SYSTEM :
|
||||
// This has already been loaded we just need to map the variable
|
||||
if ($showcategories) {
|
||||
$this->load_all_categories(self::LOAD_ROOT_CATEGORIES, true);
|
||||
}
|
||||
// Nothing left to do here I feel.
|
||||
break;
|
||||
case CONTEXT_COURSECAT :
|
||||
// This has already been loaded we just need to map the variable
|
||||
if ($this->show_categories()) {
|
||||
$this->load_all_categories($this->page->context->instanceid, true);
|
||||
}
|
||||
// This is essential, we must load categories.
|
||||
$this->load_all_categories($this->page->context->instanceid, true);
|
||||
break;
|
||||
case CONTEXT_BLOCK :
|
||||
case CONTEXT_COURSE :
|
||||
if ($issite) {
|
||||
// If it is the front page course, or a block on it then
|
||||
// all we need to do is load the root categories if required
|
||||
if ($showcategories) {
|
||||
$this->load_all_categories(self::LOAD_ROOT_CATEGORIES, true);
|
||||
}
|
||||
// Nothing left to do here.
|
||||
break;
|
||||
}
|
||||
// Load the course associated with the page into the navigation
|
||||
$course = $this->page->course;
|
||||
if ($this->show_categories() && !$ismycourse) {
|
||||
// The user isn't enrolled in the course and we need to show categories in which case we need
|
||||
// to load the category relating to the course and depending up $showcategories all of the root categories as well.
|
||||
$this->load_all_categories($course->category, $showcategories);
|
||||
}
|
||||
$coursenode = $this->load_course($course);
|
||||
|
||||
// Load the course associated with the current page into the navigation.
|
||||
$coursenode = $this->add_course($course, false, self::COURSE_CURRENT);
|
||||
// If the course wasn't added then don't try going any further.
|
||||
if (!$coursenode) {
|
||||
$canviewcourseprofile = false;
|
||||
@ -1231,25 +1120,15 @@ class global_navigation extends navigation_node {
|
||||
|
||||
// Not enrolled, can't view, and hasn't switched roles
|
||||
if (!can_access_course($course)) {
|
||||
// TODO: very ugly hack - do not force "parents" to enrol into course their child is enrolled in,
|
||||
// Very ugly hack - do not force "parents" to enrol into course their child is enrolled in,
|
||||
// this hack has been propagated from user/view.php to display the navigation node. (MDL-25805)
|
||||
$isparent = false;
|
||||
if ($this->useridtouseforparentchecks) {
|
||||
if ($this->useridtouseforparentchecks != $USER->id) {
|
||||
$usercontext = context_user::instance($this->useridtouseforparentchecks, MUST_EXIST);
|
||||
if ($DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id))
|
||||
and has_capability('moodle/user:viewdetails', $usercontext)) {
|
||||
$isparent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isparent) {
|
||||
if (!$this->current_user_is_parent_role()) {
|
||||
$coursenode->make_active();
|
||||
$canviewcourseprofile = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the essentials such as reports etc...
|
||||
$this->add_course_essentials($coursenode, $course);
|
||||
// Extend course navigation with it's sections/activities
|
||||
@ -1257,6 +1136,7 @@ class global_navigation extends navigation_node {
|
||||
if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) {
|
||||
$coursenode->make_active();
|
||||
}
|
||||
|
||||
break;
|
||||
case CONTEXT_MODULE :
|
||||
if ($issite) {
|
||||
@ -1274,12 +1154,8 @@ class global_navigation extends navigation_node {
|
||||
$course = $this->page->course;
|
||||
$cm = $this->page->cm;
|
||||
|
||||
if ($this->show_categories() && !$ismycourse) {
|
||||
$this->load_all_categories($course->category, $showcategories);
|
||||
}
|
||||
|
||||
// Load the course associated with the page into the navigation
|
||||
$coursenode = $this->load_course($course);
|
||||
$coursenode = $this->add_course($course, false, self::COURSE_CURRENT);
|
||||
|
||||
// If the course wasn't added then don't try going any further.
|
||||
if (!$coursenode) {
|
||||
@ -1362,11 +1238,8 @@ class global_navigation extends navigation_node {
|
||||
break;
|
||||
}
|
||||
$course = $this->page->course;
|
||||
if ($this->show_categories() && !$ismycourse) {
|
||||
$this->load_all_categories($course->category, $showcategories);
|
||||
}
|
||||
// Load the course associated with the user into the navigation
|
||||
$coursenode = $this->load_course($course);
|
||||
$coursenode = $this->add_course($course, false, self::COURSE_CURRENT);
|
||||
|
||||
// If the course wasn't added then don't try going any further.
|
||||
if (!$coursenode) {
|
||||
@ -1386,34 +1259,6 @@ class global_navigation extends navigation_node {
|
||||
break;
|
||||
}
|
||||
|
||||
// Look for all categories which have been loaded
|
||||
if ($showcategories) {
|
||||
$categories = $this->find_all_of_type(self::TYPE_CATEGORY);
|
||||
if (count($categories) !== 0) {
|
||||
$categoryids = array();
|
||||
foreach ($categories as $category) {
|
||||
$categoryids[] = $category->key;
|
||||
}
|
||||
list($categoriessql, $params) = $DB->get_in_or_equal($categoryids, SQL_PARAMS_NAMED);
|
||||
$params['limit'] = (!empty($CFG->navcourselimit))?$CFG->navcourselimit:20;
|
||||
$sql = "SELECT cc.id, COUNT(c.id) AS coursecount
|
||||
FROM {course_categories} cc
|
||||
JOIN {course} c ON c.category = cc.id
|
||||
WHERE cc.id {$categoriessql}
|
||||
GROUP BY cc.id
|
||||
HAVING COUNT(c.id) > :limit";
|
||||
$excessivecategories = $DB->get_records_sql($sql, $params);
|
||||
foreach ($categories as &$category) {
|
||||
if (array_key_exists($category->key, $excessivecategories) && !$this->can_add_more_courses_to_category($category)) {
|
||||
$url = new moodle_url('/course/category.php', array('id'=>$category->key));
|
||||
$category->add(get_string('viewallcourses'), $url, self::TYPE_SETTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((!empty($CFG->navshowallcourses) || empty($mycourses)) && !$this->can_add_more_courses_to_category($this->rootnodes['courses'])) {
|
||||
$this->rootnodes['courses']->add(get_string('viewallcoursescategories'), new moodle_url('/course/index.php'), self::TYPE_SETTING);
|
||||
}
|
||||
|
||||
// Load for the current user
|
||||
$this->load_for_user();
|
||||
if ($this->page->context->contextlevel >= CONTEXT_COURSE && $this->page->context->instanceid != $SITE->id && $canviewcourseprofile) {
|
||||
@ -1434,7 +1279,7 @@ class global_navigation extends navigation_node {
|
||||
// This is the preferred function name as there is less chance of conflicts
|
||||
$function($this);
|
||||
} else if (function_exists($oldfunction)) {
|
||||
// We continue to support the old function name to ensure backwards compatability
|
||||
// We continue to support the old function name to ensure backwards compatibility
|
||||
debugging("Deprecated local plugin navigation callback: Please rename '{$oldfunction}' to '{$function}'. Support for the old callback will be dropped after the release of 2.4", DEBUG_DEVELOPER);
|
||||
$oldfunction($this);
|
||||
}
|
||||
@ -1470,20 +1315,64 @@ class global_navigation extends navigation_node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if courses should be shown within categories on the navigation.
|
||||
* Returns true if the current user is a parent of the user being currently viewed.
|
||||
*
|
||||
* If the current user is not viewing another user, or if the current user does not hold any parent roles over the
|
||||
* other user being viewed this function returns false.
|
||||
* In order to set the user for whom we are checking against you must call {@link set_userid_for_parent_checks()}
|
||||
*
|
||||
* @since 2.4
|
||||
* @return bool
|
||||
*/
|
||||
protected function show_categories() {
|
||||
protected function current_user_is_parent_role() {
|
||||
global $USER, $DB;
|
||||
if ($this->useridtouseforparentchecks && $this->useridtouseforparentchecks != $USER->id) {
|
||||
$usercontext = context_user::instance($this->useridtouseforparentchecks, MUST_EXIST);
|
||||
if (!has_capability('moodle/user:viewdetails', $usercontext)) {
|
||||
return false;
|
||||
}
|
||||
if ($DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if courses should be shown within categories on the navigation.
|
||||
*
|
||||
* @param bool $ismycourse Set to true if you are calculating this for a course.
|
||||
* @return bool
|
||||
*/
|
||||
protected function show_categories($ismycourse = false) {
|
||||
global $CFG, $DB;
|
||||
if ($ismycourse) {
|
||||
return $this->show_my_categories();
|
||||
}
|
||||
if ($this->showcategories === null) {
|
||||
$show = $this->page->context->contextlevel == CONTEXT_COURSECAT;
|
||||
$show = $show || (!empty($CFG->navshowcategories) && $DB->count_records('course_categories') > 1);
|
||||
$show = false;
|
||||
if ($this->page->context->contextlevel == CONTEXT_COURSECAT) {
|
||||
$show = true;
|
||||
} else if (!empty($CFG->navshowcategories) && $DB->count_records('course_categories') > 1) {
|
||||
$show = true;
|
||||
}
|
||||
$this->showcategories = $show;
|
||||
}
|
||||
return $this->showcategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we should show categories in the My Courses branch.
|
||||
* @return bool
|
||||
*/
|
||||
protected function show_my_categories() {
|
||||
global $CFG, $DB;
|
||||
if ($this->showmycategories === null) {
|
||||
$this->showmycategories = !empty($CFG->navshowmycoursecategories) && $DB->count_records('course_categories') > 1;
|
||||
}
|
||||
return $this->showmycategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the courses in Moodle into the navigation.
|
||||
*
|
||||
@ -1638,6 +1527,10 @@ class global_navigation extends navigation_node {
|
||||
// frotpage is not wanted here
|
||||
continue;
|
||||
}
|
||||
if ($this->page->course && ($this->page->course->id == $course->id)) {
|
||||
// Don't include the currentcourse in this nodelist - it's displayed in the Current course node
|
||||
continue;
|
||||
}
|
||||
context_instance_preload($course);
|
||||
if (!$course->visible && !is_role_switched($course->id) && !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
|
||||
continue;
|
||||
@ -1690,7 +1583,7 @@ class global_navigation extends navigation_node {
|
||||
* @return navigation_node|void returns a navigation node if a category has been loaded.
|
||||
*/
|
||||
protected function load_all_categories($categoryid = self::LOAD_ROOT_CATEGORIES, $showbasecategories = false) {
|
||||
global $DB;
|
||||
global $CFG, $DB;
|
||||
|
||||
// Check if this category has already been loaded
|
||||
if ($this->allcategoriesloaded || ($categoryid < 1 && $this->is_category_fully_loaded($categoryid))) {
|
||||
@ -1808,6 +1701,31 @@ class global_navigation extends navigation_node {
|
||||
$this->load_all_courses($readytoloadcourses);
|
||||
}
|
||||
}
|
||||
|
||||
// Look for all categories which have been loaded
|
||||
if (!empty($this->addedcategories)) {
|
||||
$categoryids = array();
|
||||
foreach ($this->addedcategories as $category) {
|
||||
if ($this->can_add_more_courses_to_category($category)) {
|
||||
$categoryids[] = $category->key;
|
||||
}
|
||||
}
|
||||
list($categoriessql, $params) = $DB->get_in_or_equal($categoryids, SQL_PARAMS_NAMED);
|
||||
$params['limit'] = (!empty($CFG->navcourselimit))?$CFG->navcourselimit:20;
|
||||
$sql = "SELECT cc.id, COUNT(c.id) AS coursecount
|
||||
FROM {course_categories} cc
|
||||
JOIN {course} c ON c.category = cc.id
|
||||
WHERE cc.id {$categoriessql}
|
||||
GROUP BY cc.id
|
||||
HAVING COUNT(c.id) > :limit";
|
||||
$excessivecategories = $DB->get_records_sql($sql, $params);
|
||||
foreach ($categories as &$category) {
|
||||
if (array_key_exists($category->key, $excessivecategories) && !$this->can_add_more_courses_to_category($category)) {
|
||||
$url = new moodle_url('/course/category.php', array('id'=>$category->key));
|
||||
$category->add(get_string('viewallcourses'), $url, self::TYPE_SETTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2178,7 +2096,7 @@ class global_navigation extends navigation_node {
|
||||
$course = $this->page->course;
|
||||
$baseargs = array('id'=>$user->id);
|
||||
if ($course->id != $SITE->id && (!$iscurrentuser || $forceforcontext)) {
|
||||
$coursenode = $this->load_course($course);
|
||||
$coursenode = $this->add_course($course, false, self::COURSE_CURRENT);
|
||||
$baseargs['course'] = $course->id;
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$issitecourse = false;
|
||||
@ -2438,7 +2356,7 @@ class global_navigation extends navigation_node {
|
||||
* @param bool $ismycourse
|
||||
* @return navigation_node
|
||||
*/
|
||||
public function add_course(stdClass $course, $forcegeneric = false, $ismycourse = false) {
|
||||
public function add_course(stdClass $course, $forcegeneric = false, $coursetype = self::COURSE_OTHER) {
|
||||
global $CFG, $SITE;
|
||||
|
||||
// We found the course... we can return it now :)
|
||||
@ -2465,7 +2383,10 @@ class global_navigation extends navigation_node {
|
||||
if (empty($CFG->usesitenameforsitepages)) {
|
||||
$shortname = get_string('sitepages');
|
||||
}
|
||||
} else if ($ismycourse && !$forcegeneric) {
|
||||
} else if ($coursetype == self::COURSE_CURRENT) {
|
||||
$parent = $this->rootnodes['currentcourse'];
|
||||
$url = new moodle_url('/course/view.php', array('id'=>$course->id));
|
||||
} else if ($coursetype == self::COURSE_MY && !$forcegeneric) {
|
||||
if (!empty($CFG->navshowmycoursecategories) && ($parent = $this->rootnodes['mycourses']->find($course->category, self::TYPE_CATEGORY))) {
|
||||
// Nothing to do here the above statement set $parent to the category within mycourses.
|
||||
} else {
|
||||
@ -2475,8 +2396,8 @@ class global_navigation extends navigation_node {
|
||||
} else {
|
||||
$parent = $this->rootnodes['courses'];
|
||||
$url = new moodle_url('/course/view.php', array('id'=>$course->id));
|
||||
if (!empty($course->category) && $this->show_categories()) {
|
||||
if ($this->show_categories() && !$this->is_category_fully_loaded($course->category)) {
|
||||
if (!empty($course->category) && $this->show_categories($coursetype == self::COURSE_MY)) {
|
||||
if (!$this->is_category_fully_loaded($course->category)) {
|
||||
// We need to load the category structure for this course
|
||||
$this->load_all_categories($course->category, false);
|
||||
}
|
||||
@ -2735,6 +2656,9 @@ class global_navigation extends navigation_node {
|
||||
if (!$this->initialised) {
|
||||
$this->initialise();
|
||||
}
|
||||
if ($type == self::TYPE_ROOTNODE && array_key_exists($key, $this->rootnodes)) {
|
||||
return $this->rootnodes[$key];
|
||||
}
|
||||
return parent::find($key, $type);
|
||||
}
|
||||
}
|
||||
@ -2786,7 +2710,7 @@ class global_navigation_for_ajax extends global_navigation {
|
||||
* @return array An array of the expandable nodes
|
||||
*/
|
||||
public function initialise() {
|
||||
global $CFG, $DB, $SITE;
|
||||
global $DB, $SITE;
|
||||
|
||||
if ($this->initialised || during_initial_install()) {
|
||||
return $this->expandable;
|
||||
@ -2795,10 +2719,18 @@ class global_navigation_for_ajax extends global_navigation {
|
||||
|
||||
$this->rootnodes = array();
|
||||
$this->rootnodes['site'] = $this->add_course($SITE);
|
||||
$this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), new moodle_url('/my'), self::TYPE_ROOTNODE, null, 'mycourses');
|
||||
$this->rootnodes['courses'] = $this->add(get_string('courses'), null, self::TYPE_ROOTNODE, null, 'courses');
|
||||
|
||||
// Branchtype will be one of navigation_node::TYPE_*
|
||||
switch ($this->branchtype) {
|
||||
case 0:
|
||||
if ($this->instanceid === 'mycourses') {
|
||||
$this->load_courses_enrolled();
|
||||
} else if ($this->instanceid === 'courses') {
|
||||
$this->load_courses_other();
|
||||
}
|
||||
break;
|
||||
case self::TYPE_CATEGORY :
|
||||
$this->load_category($this->instanceid);
|
||||
break;
|
||||
@ -2858,6 +2790,51 @@ class global_navigation_for_ajax extends global_navigation {
|
||||
return $this->expandable;
|
||||
}
|
||||
|
||||
/**
|
||||
* They've expanded the 'my courses' branch.
|
||||
*/
|
||||
protected function load_courses_enrolled() {
|
||||
global $DB;
|
||||
$courses = enrol_get_my_courses();
|
||||
if ($this->show_my_categories(true)) {
|
||||
// OK Actually we are loading categories. We only want to load categories that have a parent of 0.
|
||||
// In order to make sure we load everything required we must first find the categories that are not
|
||||
// base categories and work out the bottom category in thier path.
|
||||
$categoryids = array();
|
||||
foreach ($courses as $course) {
|
||||
$categoryids[] = $course->category;
|
||||
}
|
||||
$categoryids = array_unique($categoryids);
|
||||
list($sql, $params) = $DB->get_in_or_equal($categoryids);
|
||||
$categories = $DB->get_recordset_select('course_categories', 'id '.$sql.' AND parent <> 0', $params, 'sortorder, id', 'id, path');
|
||||
foreach ($categories as $category) {
|
||||
$bits = explode('/', trim($category->path,'/'));
|
||||
$categoryids[] = array_shift($bits);
|
||||
}
|
||||
$categoryids = array_unique($categoryids);
|
||||
$categories->close();
|
||||
|
||||
// Now we load the base categories.
|
||||
list($sql, $params) = $DB->get_in_or_equal($categoryids);
|
||||
$categories = $DB->get_recordset_select('course_categories', 'id '.$sql.' AND parent = 0', $params, 'sortorder, id');
|
||||
foreach ($categories as $category) {
|
||||
$this->add_category($category, $this->rootnodes['mycourses']);
|
||||
}
|
||||
$categories->close();
|
||||
} else {
|
||||
foreach ($courses as $course) {
|
||||
$this->add_course($course, false, self::COURSE_MY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* They've expanded the general 'courses' branch.
|
||||
*/
|
||||
protected function load_courses_other() {
|
||||
$this->load_all_courses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single category into the AJAX navigation.
|
||||
*
|
||||
@ -2900,7 +2877,6 @@ class global_navigation_for_ajax extends global_navigation {
|
||||
$categories->close();
|
||||
|
||||
if (!is_null($basecategory)) {
|
||||
//echo "<pre>".print_r($subcategories, true).'</pre>';
|
||||
foreach ($subcategories as $category) {
|
||||
$this->add_category($category, $basecategory);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user