diff --git a/course/category.php b/course/category.php index 27f4653e680b1..64ebaaae3689e 100644 --- a/course/category.php +++ b/course/category.php @@ -1,445 +1,458 @@ coursesperpage, PARAM_INT); // how many per page - $categoryedit = optional_param('categoryedit', -1, PARAM_BOOL); - $hide = optional_param('hide', 0, PARAM_INT); - $show = optional_param('show', 0, PARAM_INT); - $moveup = optional_param('moveup', 0, PARAM_INT); - $movedown = optional_param('movedown', 0, PARAM_INT); - $moveto = optional_param('moveto', 0, PARAM_INT); - $resort = optional_param('resort', 0, PARAM_BOOL); - - $site = get_site(); - - if (empty($id)) { - print_error("unknowcategory"); - } - - $PAGE->set_category_by_id($id); - $urlparams = array('id' => $id); - if ($page) { - $urlparams['page'] = $page; - } - if ($perpage) { - $urlparams['perpage'] = $perpage; +// 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 . + +/** + * Displays the top level category or all courses + * In editing mode, allows the admin to edit a category, + * and rearrange courses + * + * @package core + * @subpackage course + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once("../config.php"); +require_once($CFG->dirroot.'/course/lib.php'); + +$id = required_param('id', PARAM_INT); // Category id +$page = optional_param('page', 0, PARAM_INT); // which page to show +$perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page +$categoryedit = optional_param('categoryedit', -1, PARAM_BOOL); +$hide = optional_param('hide', 0, PARAM_INT); +$show = optional_param('show', 0, PARAM_INT); +$moveup = optional_param('moveup', 0, PARAM_INT); +$movedown = optional_param('movedown', 0, PARAM_INT); +$moveto = optional_param('moveto', 0, PARAM_INT); +$resort = optional_param('resort', 0, PARAM_BOOL); +$sesskey = optional_param('sesskey', '', PARAM_RAW); + +if (empty($id)) { + print_error("unknowcategory"); +} + +$PAGE->set_category_by_id($id); +$PAGE->set_url(new moodle_url('/course/category.php', array('id' => $id))); +// This is sure to be the category context +$context = $PAGE->context; +// And the object has been loaded for us no need for another DB call +$category = $PAGE->category; + +$canedit = can_edit_in_category($category->id); +if ($canedit) { + if ($categoryedit !== -1) { + $USER->editing = $categoryedit; } - $PAGE->set_url(new moodle_url('/course/category.php', array('id' => $id))); - navigation_node::override_active_url($PAGE->url); - $context = $PAGE->context; - $category = $PAGE->category; - - $canedit = can_edit_in_category($category->id); - if ($canedit) { - if ($categoryedit !== -1) { - $USER->editing = $categoryedit; - } + require_login(); + $editingon = $PAGE->user_is_editing(); +} else { + if ($CFG->forcelogin) { require_login(); - $editingon = $PAGE->user_is_editing(); - } else { - if ($CFG->forcelogin) { - require_login(); + } + $editingon = false; +} + +if (!$category->visible) { + require_capability('moodle/category:viewhiddencategories', $context); +} + +$canmanage = has_capability('moodle/category:manage', $context); +$sesskeyprovided = !empty($sesskey) && confirm_sesskey($sesskey); + +// Process any category actions. +if ($canmanage && $resort && $sesskeyprovided) { + // Resort the category if requested + if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) { + $i = 1; + foreach ($courses as $course) { + $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id)); + $i++; } - $editingon = false; + fix_course_sortorder(); // should not be needed } +} - if (!$category->visible) { - require_capability('moodle/category:viewhiddencategories', $context); - } +// Process any course actions. +if ($editingon && $sesskeyprovided) { - // Process any category actions. - if (has_capability('moodle/category:manage', $context)) { - /// Resort the category if requested - if ($resort and confirm_sesskey()) { - if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) { - $i = 1; - foreach ($courses as $course) { - $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id)); - $i++; - } - fix_course_sortorder(); // should not be needed - } + // Move a specified course to a new category + if (!empty($moveto) and $data = data_submitted()) { + // Some courses are being moved + // user must have category update in both cats to perform this + require_capability('moodle/category:manage', $context); + require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto)); + + if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) { + print_error('cannotfindcategory', '', '', $data->moveto); } - } - // Process any course actions. - if ($editingon) { - /// Move a specified course to a new category - if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) { // Some courses are being moved - // user must have category update in both cats to perform this - require_capability('moodle/category:manage', $context); - require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto)); - - if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) { - print_error('cannotfindcategory', '', '', $data->moveto); - } + $courses = array(); + foreach ($data as $key => $value) { + if (preg_match('/^c\d+$/', $key)) { + $courseid = substr($key, 1); + array_push($courses, $courseid); - $courses = array(); - foreach ($data as $key => $value) { - if (preg_match('/^c\d+$/', $key)) { - $courseid = substr($key, 1); - array_push($courses, $courseid); - - // check this course's category - if ($movingcourse = $DB->get_record('course', array('id'=>$courseid))) { - if ($movingcourse->category != $id ) { - print_error('coursedoesnotbelongtocategory'); - } - } else { - print_error('cannotfindcourse'); + // check this course's category + if ($movingcourse = $DB->get_record('course', array('id'=>$courseid))) { + if ($movingcourse->category != $id ) { + print_error('coursedoesnotbelongtocategory'); } + } else { + print_error('cannotfindcourse'); } } - move_courses($courses, $data->moveto); } + move_courses($courses, $data->moveto); + } - /// Hide or show a course - if ((!empty($hide) or !empty($show)) and confirm_sesskey()) { - if (!empty($hide)) { - $course = $DB->get_record('course', array('id' => $hide)); - $visible = 0; - } else { - $course = $DB->get_record('course', array('id' => $show)); - $visible = 1; - } + // Hide or show a course + if (!empty($hide) or !empty($show)) { + if (!empty($hide)) { + $course = $DB->get_record('course', array('id' => $hide)); + $visible = 0; + } else { + $course = $DB->get_record('course', array('id' => $show)); + $visible = 1; + } - if ($course) { - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - require_capability('moodle/course:visibility', $coursecontext); - $DB->set_field('course', 'visible', $visible, array('id' => $course->id)); - $DB->set_field('course', 'visibleold', $visible, array('id' => $course->id)); // we set the old flag when user manually changes visibility of course - } + if ($course) { + $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); + require_capability('moodle/course:visibility', $coursecontext); + // Set the visibility of the course + $DB->set_field('course', 'visible', $visible, array('id' => $course->id)); + // we set the old flag when user manually changes visibility of course + $DB->set_field('course', 'visibleold', $visible, array('id' => $course->id)); } + } - /// Move a course up or down - if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) { - require_capability('moodle/category:manage', $context); + // Move a course up or down + if (!empty($moveup) or !empty($movedown)) { + require_capability('moodle/category:manage', $context); - // Ensure the course order has continuous ordering - fix_course_sortorder(); - $swapcourse = NULL; + // Ensure the course order has continuous ordering + fix_course_sortorder(); + $swapcourse = NULL; - if (!empty($moveup)) { - if ($movecourse = $DB->get_record('course', array('id' => $moveup))) { - $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1)); - } - } else { - if ($movecourse = $DB->get_record('course', array('id' => $movedown))) { - $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1)); - } + if (!empty($moveup)) { + if ($movecourse = $DB->get_record('course', array('id' => $moveup))) { + $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1)); } - if ($swapcourse and $movecourse) { - // check course's category - if ($movecourse->category != $id) { - print_error('coursedoesnotbelongtocategory'); - } - $DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id)); - $DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id)); + } else { + if ($movecourse = $DB->get_record('course', array('id' => $movedown))) { + $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1)); } } - - } // End of editing stuff - - // Print headings - $numcategories = $DB->count_records('course_categories'); - - $stradministration = get_string('administration'); - $strcategories = get_string('categories'); - $strcategory = get_string('category'); - $strcourses = get_string('courses'); - - if ($editingon && can_edit_in_category()) { - // Integrate into the admin tree only if the user can edit categories at the top level, - // otherwise the admin block does not appear to this user, and you get an error. - require_once($CFG->libdir . '/adminlib.php'); - admin_externalpage_setup('coursemgmt', '', $urlparams, $CFG->wwwroot . '/course/category.php'); - $PAGE->set_context($context); // Ensure that we are actually showing blocks etc for the cat context - - $settingsnode = $PAGE->settingsnav->find_active_node(); - if ($settingsnode) { - $settingsnode->make_inactive(); - $settingsnode->force_open(); - $PAGE->navbar->add($settingsnode->text, $settingsnode->action); + if ($swapcourse and $movecourse) { + // check course's category + if ($movecourse->category != $id) { + print_error('coursedoesnotbelongtocategory'); + } + $DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id)); + $DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id)); } - echo $OUTPUT->header(); - } else { - $PAGE->set_title("$site->shortname: $category->name"); - $PAGE->set_heading($site->fullname); - $PAGE->set_button(print_course_search('', true, 'navbar')); - $PAGE->set_pagelayout('coursecategory'); - echo $OUTPUT->header(); } +} // End of editing stuff + +// Prepare the standard URL params for this page. We'll need them later. +$urlparams = array('id' => $id); +if ($page) { + $urlparams['page'] = $page; +} +if ($perpage) { + $urlparams['perpage'] = $perpage; +} + +// Begin output +if ($editingon && can_edit_in_category()) { + // Integrate into the admin tree only if the user can edit categories at the top level, + // otherwise the admin block does not appear to this user, and you get an error. + require_once($CFG->libdir . '/adminlib.php'); + admin_externalpage_setup('coursemgmt', '', $urlparams, $CFG->wwwroot . '/course/category.php'); + $PAGE->set_context($context); // Ensure that we are actually showing blocks etc for the cat context + + $settingsnode = $PAGE->settingsnav->find_active_node(); + if ($settingsnode) { + $settingsnode->make_inactive(); + $settingsnode->force_open(); + $PAGE->navbar->add($settingsnode->text, $settingsnode->action); + } + echo $OUTPUT->header(); +} else { + $site = get_site(); + $PAGE->set_title("$site->shortname: $category->name"); + $PAGE->set_heading($site->fullname); + $PAGE->set_button(print_course_search('', true, 'navbar')); + $PAGE->set_pagelayout('coursecategory'); + echo $OUTPUT->header(); +} + /// Print the category selector - $displaylist = array(); - $notused = array(); - make_categories_list($displaylist, $notused); +$displaylist = array(); +$notused = array(); +make_categories_list($displaylist, $notused); - echo '
'; - $select = new single_select(new moodle_url('category.php'), 'id', $displaylist, $category->id, null, 'switchcategory'); - $select->set_label($strcategories.':'); - echo $OUTPUT->render($select); - echo '
'; +echo '
'; +$select = new single_select(new moodle_url('/course/category.php'), 'id', $displaylist, $category->id, null, 'switchcategory'); +$select->set_label(get_string('categories').':'); +echo $OUTPUT->render($select); +echo '
'; /// Print current category description - if (!$editingon && $category->description) { - echo $OUTPUT->box_start(); - $options = new stdClass; - $options->noclean = true; - $options->para = false; - $options->overflowdiv = true; - if (!isset($category->descriptionformat)) { - $category->descriptionformat = FORMAT_MOODLE; - } - $text = file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id, 'coursecat', 'description', null); - echo format_text($text, $category->descriptionformat, $options); - echo $OUTPUT->box_end(); +if (!$editingon && $category->description) { + echo $OUTPUT->box_start(); + $options = new stdClass; + $options->noclean = true; + $options->para = false; + $options->overflowdiv = true; + if (!isset($category->descriptionformat)) { + $category->descriptionformat = FORMAT_MOODLE; } - - if ($editingon && has_capability('moodle/category:manage', $context)) { - echo $OUTPUT->container_start('buttons'); - - // Print button to update this category - $options = array('id' => $category->id); - echo $OUTPUT->single_button(new moodle_url('/course/editcategory.php', $options), get_string('editcategorythis'), 'get'); - - // Print button for creating new categories - $options = array('parent' => $category->id); - echo $OUTPUT->single_button(new moodle_url('/course/editcategory.php', $options), get_string('addsubcategory'), 'get'); - - echo $OUTPUT->container_end(); + $text = file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id, 'coursecat', 'description', null); + echo format_text($text, $category->descriptionformat, $options); + echo $OUTPUT->box_end(); +} + +if ($editingon && $canmanage) { + echo $OUTPUT->container_start('buttons'); + + // Print button to update this category + $url = new moodle_url('/course/editcategory.php', array('id' => $category->id)); + echo $OUTPUT->single_button($url, get_string('editcategorythis'), 'get'); + + // Print button for creating new categories + $url = new moodle_url('/course/editcategory.php', array('parent' => $category->id)); + echo $OUTPUT->single_button($url, get_string('addsubcategory'), 'get'); + + echo $OUTPUT->container_end(); +} + +// Print out all the sub-categories +// In order to view hidden subcategories the user must have the viewhiddencategories +// capability in the current category. +if (has_capability('moodle/category:viewhiddencategories', $context)) { + $categorywhere = ''; +} else { + $categorywhere = 'AND cc.visible = 1'; +} +// We're going to preload the context for the subcategory as we know that we +// need it later on for formatting. + +$ctxselect = context_helper::get_preload_record_columns_sql('ctx'); +$sql = "SELECT cc.*, $ctxselect + FROM {course_categories} cc + JOIN {context} ctx ON cc.id = ctx.instanceid + WHERE cc.parent = :parentid AND + ctx.contextlevel = :contextlevel + $categorywhere + ORDER BY cc.sortorder ASC"; +$subcategories = $DB->get_recordset_sql($sql, array('parentid' => $category->id, 'contextlevel' => CONTEXT_COURSECAT)); +// Prepare a table to display the sub categories. +$table = new html_table; +$table->attributes = array('border' => '0', 'cellspacing' => '2', 'cellpadding' => '4', 'class' => 'generalbox boxaligncenter category_subcategories'); +$table->head = array(new lang_string('subcategories')); +$table->data = array(); +$baseurl = new moodle_url('/course/category.php'); +foreach ($subcategories as $subcategory) { + // Preload the context we will need it to format the category name shortly. + context_helper::preload_from_record($subcategory); + $context = get_context_instance(CONTEXT_COURSECAT, $subcategory->id); + // Prepare the things we need to create a link to the subcategory + $attributes = $subcategory->visible ? array() : array('class' => 'dimmed'); + $text = format_string($subcategory->name, true, array('context' => $context)); + // Add the subcategory to the table + $url->param('id', $subcategory->id); + $table->data[] = array(html_writer::link($url, $text, $attributes)); +} + +$subcategorieswereshown = (count($table->data) > 0); +if ($subcategorieswereshown) { + echo html_writer::table($table); +} + +// Print out all the courses +$courses = get_courses_page($category->id, 'c.sortorder ASC', + 'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible', + $totalcount, $page*$perpage, $perpage); +$numcourses = count($courses); + +if (!$courses) { + if (empty($subcategorieswereshown)) { + echo $OUTPUT->heading(get_string("nocoursesyet")); } -/// Print out all the sub-categories - if ($subcategories = $DB->get_records('course_categories', array('parent' => $category->id), 'sortorder ASC')) { - $firstentry = true; - foreach ($subcategories as $subcategory) { - if ($subcategory->visible || has_capability('moodle/category:viewhiddencategories', $context)) { - $subcategorieswereshown = true; - if ($firstentry) { - echo ''; - echo ''; - echo '
'.get_string('subcategories').'
'; - $firstentry = false; - } - $catlinkcss = $subcategory->visible ? '' : ' class="dimmed" '; - echo ''. - format_string($subcategory->name, true, array('context' => get_context_instance(CONTEXT_COURSECAT, $subcategory->id))).'
'; - } - } - if (!$firstentry) { - echo '
'; - echo '
'; - } - } +} else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) { + echo $OUTPUT->box_start('courseboxes'); + print_courses($category); + echo $OUTPUT->box_end(); -/// Print out all the courses - $courses = get_courses_page($category->id, 'c.sortorder ASC', - 'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible', - $totalcount, $page*$perpage, $perpage); - $numcourses = count($courses); +} else { + echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "/course/category.php?id=$category->id&perpage=$perpage"); - if (!$courses) { - if (empty($subcategorieswereshown)) { - echo $OUTPUT->heading(get_string("nocoursesyet")); - } + echo '
'; + echo ''; + echo ''; + echo ''; + if ($editingon) { + echo ''; + echo ''; + } else { + echo ''; + } + echo ''; - } else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) { - echo $OUTPUT->box_start('courseboxes'); - print_courses($category); - echo $OUTPUT->box_end(); + $count = 0; + $abletomovecourses = false; // for now - } else { - echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "/course/category.php?id=$category->id&perpage=$perpage"); - - $strcourses = get_string('courses'); - $strselect = get_string('select'); - $stredit = get_string('edit'); - $strdelete = get_string('delete'); - $strbackup = get_string('backup'); - $strrestore = get_string('restore'); - $strmoveup = get_string('moveup'); - $strmovedown = get_string('movedown'); - $strupdate = get_string('update'); - $strhide = get_string('hide'); - $strshow = get_string('show'); - $strsummary = get_string('summary'); - $strsettings = get_string('settings'); - - - echo '
'; - echo ''; - echo '
'.get_string('courses').''.get_string('edit').''.get_string('select').' 
'; - echo ''; - if ($editingon) { - echo ''; - echo ''; + // Checking if we are at the first or at the last page, to allow courses to + // be moved up and down beyond the paging border + if ($totalcount > $perpage) { + $atfirstpage = ($page == 0); + if ($perpage > 0) { + $atlastpage = (($page + 1) == ceil($totalcount / $perpage)); } else { - echo ''; + $atlastpage = true; } - echo ''; + } else { + $atfirstpage = true; + $atlastpage = true; + } + $baseurl = new moodle_url('/course/category.php', $urlparams + array('sesskey' => sesskey())); + foreach ($courses as $acourse) { + $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id); - $count = 0; - $abletomovecourses = false; // for now + $count++; + $up = ($count > 1 || !$atfirstpage); + $down = ($count < $numcourses || !$atlastpage); - // Checking if we are at the first or at the last page, to allow courses to - // be moved up and down beyond the paging border - if ($totalcount > $perpage) { - $atfirstpage = ($page == 0); - if ($perpage > 0) { - $atlastpage = (($page + 1) == ceil($totalcount / $perpage)); - } else { - $atlastpage = true; + $linkcss = $acourse->visible ? '' : ' class="dimmed" '; + echo ''; + $coursename = get_course_display_name_for_list($acourse); + echo ''; + if ($editingon) { + echo ''; - $coursename = get_course_display_name_for_list($acourse); - echo ''; - if ($editingon) { - echo ''; - echo ''; - } else { - echo ''; + echo ''; + } else { + echo '"; } - echo ""; - } - - if ($abletomovecourses) { - $movetocategories = array(); - $notused = array(); - make_categories_list($movetocategories, $notused, 'moodle/category:manage'); - $movetocategories[$category->id] = get_string('moveselectedcoursesto'); - echo ''; + if (!empty($acourse->summary)) { + $url = new moodle_url("/course/info.php?id=$acourse->id"); + echo $OUTPUT->action_link($url, ''.get_string('info').'', + new popup_action('click', $url, 'courseinfo'), array('title'=>get_string('summary'))); + } + echo ""; } - - echo '
'.$strcourses.''.$stredit.''.$strselect.' 
'. format_string($coursename) .''; + if (has_capability('moodle/course:update', $coursecontext)) { + $url = new moodle_url('/course/edit.php', array('id' => $acourse->id, 'category' => $id, 'returnto' => 'category')); + echo $OUTPUT->action_icon($url, new pix_icon('t/edit', get_string('settings'))); } - } else { - $atfirstpage = true; - $atlastpage = true; - } - foreach ($courses as $acourse) { - $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id); - - $count++; - $up = ($count > 1 || !$atfirstpage); - $down = ($count < $numcourses || !$atlastpage); - - $linkcss = $acourse->visible ? '' : ' class="dimmed" '; - echo '
'. format_string($coursename) .''; - if (has_capability('moodle/course:update', $coursecontext)) { - echo $OUTPUT->action_icon(new moodle_url('/course/edit.php', - array('id' => $acourse->id, 'category' => $id, 'returnto' => 'category')), - new pix_icon('t/edit', $strsettings)); - } + // role assignment link + if (has_capability('moodle/course:enrolreview', $coursecontext)) { + $url = new moodle_url('/enrol/users.php', array('id' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('i/users', get_string('enrolledusers', 'enrol'))); + } - // role assignment link - if (has_capability('moodle/course:enrolreview', $coursecontext)) { - echo $OUTPUT->action_icon(new moodle_url('/enrol/users.php', array('id' => $acourse->id)), - new pix_icon('i/users', get_string('enrolledusers', 'enrol'))); - } + if (can_delete_course($acourse->id)) { + $url = new moodle_url('/course/delete.php', array('id' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/delete', get_string('delete'))); + } - if (can_delete_course($acourse->id)) { - echo $OUTPUT->action_icon(new moodle_url('/course/delete.php', array('id' => $acourse->id)), - new pix_icon('t/delete', $strdelete)); + // MDL-8885, users with no capability to view hidden courses, should not be able to lock themselves out + if (has_capability('moodle/course:visibility', $coursecontext) && has_capability('moodle/course:viewhiddencourses', $coursecontext)) { + if (!empty($acourse->visible)) { + $url = new moodle_url($baseurl, array('hide' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/hide', get_string('hide'))); + } else { + $url = new moodle_url($baseurl, array('show' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/show', get_string('show'))); } + } - // MDL-8885, users with no capability to view hidden courses, should not be able to lock themselves out - if (has_capability('moodle/course:visibility', $coursecontext) && has_capability('moodle/course:viewhiddencourses', $coursecontext)) { - if (!empty($acourse->visible)) { - echo $OUTPUT->action_icon(new moodle_url('/course/category.php', - array('id' => $category->id, 'page' => $page, 'perpage' => $perpage, - 'hide' => $acourse->id, 'sesskey' => sesskey())), - new pix_icon('t/hide', $strhide)); - } else { - echo $OUTPUT->action_icon(new moodle_url('/course/category.php', - array('id' => $category->id, 'page' => $page, 'perpage' => $perpage, - 'show' => $acourse->id, 'sesskey' => sesskey())), - new pix_icon('t/show', $strshow)); - } - } + if (has_capability('moodle/backup:backupcourse', $coursecontext)) { + $url = new moodle_url('/backup/backup.php', array('id' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/backup', get_string('backup'))); + } - if (has_capability('moodle/backup:backupcourse', $coursecontext)) { - echo $OUTPUT->action_icon(new moodle_url('/backup/backup.php', array('id' => $acourse->id)), - new pix_icon('t/backup', $strbackup)); - } + if (has_capability('moodle/restore:restorecourse', $coursecontext)) { + $url = new moodle_url('/backup/restorefile.php', array('contextid' => $coursecontext->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/restore', get_string('restore'))); + } - if (has_capability('moodle/restore:restorecourse', $coursecontext)) { - echo $OUTPUT->action_icon(new moodle_url('/backup/restorefile.php', array('contextid' => $coursecontext->id)), - new pix_icon('t/restore', $strrestore)); + if ($canmanage) { + if ($up) { + $url = new moodle_url($baseurl, array('moveup' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/up', get_string('moveup'))); } - if (has_capability('moodle/category:manage', $context)) { - if ($up) { - echo $OUTPUT->action_icon(new moodle_url('/course/category.php', - array('id' => $category->id, 'page' => $page, 'perpage' => $perpage, - 'moveup' => $acourse->id, 'sesskey' => sesskey())), - new pix_icon('t/up', $strmoveup)); - } - - if ($down) { - echo $OUTPUT->action_icon(new moodle_url('/course/category.php', - array('id' => $category->id, 'page' => $page, 'perpage' => $perpage, - 'movedown' => $acourse->id, 'sesskey' => sesskey())), - new pix_icon('t/down', $strmovedown)); - } - $abletomovecourses = true; + if ($down) { + $url = new moodle_url($baseurl, array('movedown' => $acourse->id)); + echo $OUTPUT->action_icon($url, new pix_icon('t/down', get_string('movedown'))); } + $abletomovecourses = true; + } - echo ''; - echo ''; - echo ''; - // print enrol info - if ($icons = enrol_get_course_info_icons($acourse)) { - foreach ($icons as $pix_icon) { - echo $OUTPUT->render($pix_icon); - } - } - if (!empty($acourse->summary)) { - $link = new moodle_url("/course/info.php?id=$acourse->id"); - echo $OUTPUT->action_link($link, ''.get_string('info').'', - new popup_action('click', $link, 'courseinfo'), array('title'=>$strsummary)); + echo ''; + echo ''; + echo ''; + // print enrol info + if ($icons = enrol_get_course_info_icons($acourse)) { + foreach ($icons as $pix_icon) { + echo $OUTPUT->render($pix_icon); } - echo "
'; - echo html_writer::select($movetocategories, 'moveto', $category->id, null, array('id'=>'movetoid')); - $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('movecourses', 'movetoid', false)); - echo ''; - echo '
'; - echo '
'; - echo '
'; + echo ""; } - echo '
'; - if (has_capability('moodle/category:manage', $context) and $numcourses > 1) { - /// Print button to re-sort courses by name - unset($options); - $options['id'] = $category->id; - $options['resort'] = 'name'; - $options['sesskey'] = sesskey(); - echo $OUTPUT->single_button(new moodle_url('category.php', $options), get_string('resortcoursesbyname'), 'get'); + if ($abletomovecourses) { + $movetocategories = array(); + $notused = array(); + make_categories_list($movetocategories, $notused, 'moodle/category:manage'); + $movetocategories[$category->id] = get_string('moveselectedcoursesto'); + echo ''; + echo html_writer::select($movetocategories, 'moveto', $category->id, null, array('id'=>'movetoid')); + $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('movecourses', 'movetoid', false)); + echo ''; + echo ''; } - if (has_capability('moodle/course:create', $context)) { - /// Print button to create a new course - unset($options); - $options['category'] = $category->id; - $options['returnto'] = 'category'; - echo $OUTPUT->single_button(new moodle_url('edit.php', $options), get_string('addnewcourse'), 'get'); - } + echo ''; + echo '
'; + echo '
'; +} - if (!empty($CFG->enablecourserequests) && $category->id == $CFG->defaultrequestcategory) { - print_course_request_buttons(get_context_instance(CONTEXT_SYSTEM)); - } - echo ''; +echo '
'; +if ($canmanage and $numcourses > 1) { + // Print button to re-sort courses by name + $url = new moodle_url('/course/category.php', array('id' => $category->id, 'resort' => 'name', 'sesskey' => sesskey())); + echo $OUTPUT->single_button($url, get_string('resortcoursesbyname'), 'get'); +} + +if (has_capability('moodle/course:create', $context)) { + // Print button to create a new course + $url = new moodle_url('/course/edit.php', array('category' => $category->id, 'returnto' => 'category')); + echo $OUTPUT->single_button($url, get_string('addnewcourse'), 'get'); +} - print_course_search(); +if (!empty($CFG->enablecourserequests) && $category->id == $CFG->defaultrequestcategory) { + print_course_request_buttons(get_context_instance(CONTEXT_SYSTEM)); +} +echo '
'; - echo $OUTPUT->footer(); +print_course_search(); +echo $OUTPUT->footer(); \ No newline at end of file diff --git a/course/editcategory.php b/course/editcategory.php index 9752cce1713a5..ff4bad5e0b608 100644 --- a/course/editcategory.php +++ b/course/editcategory.php @@ -1,9 +1,29 @@ . + /** * Page for creating or editing course category name/parent/description. * When called with an id parameter, edits the category with that id. * Otherwise it creates a new category with default parent from the parent * parameter, which may be 0. + * + * @package core + * @subpackage course + * @copyright 2007 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../config.php'); @@ -108,6 +128,21 @@ redirect('category.php?id='.$newcategory->id.'&categoryedit=on'); } +// Unfortunately the navigation never generates correctly for this page because technically +// this page doesn't actually exist on the navigation you get here through the course +// management page. +try { + // First up we'll try to make the course management page active seeing as that is + // where the user thinks they are. + // The big prolem here is that the course management page is a common page + // for both editing users and common users. + $PAGE->settingsnav->get('root')->get('courses')->get('coursemgmt')->make_active(); +} catch (Exception $ex) { + // Failing that we'll override the URL, not as accurate and chances are things + // won't be 100% correct all the time but should work most times. + navigation_node::override_active_url(new moodle_url('/course/index.php', array('categoryedit' => 'on'))); +} + $PAGE->set_title($title); $PAGE->set_heading($fullname); echo $OUTPUT->header(); diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 963f431c86300..45ef60e491a40 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -1057,7 +1057,10 @@ public function initialise() { $mycourses = enrol_get_my_courses(NULL, 'visible DESC,sortorder ASC'); $showallcourses = (count($mycourses) == 0 || !empty($CFG->navshowallcourses)); - $showcategories = ($showallcourses && $this->show_categories()); + // When checking if we are to show categories there is an additional override. + // If the user is viewing a category then we will load it regardless of settings. + // to ensure that the navigation is consistent. + $showcategories = $this->page->context->contextlevel == CONTEXT_COURSECAT || ($showallcourses && $this->show_categories()); $issite = ($this->page->course->id == SITEID); $ismycourse = (array_key_exists($this->page->course->id, $mycourses)); @@ -1152,188 +1155,201 @@ public function initialise() { $canviewcourseprofile = true; - if (!$issite) { - // 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 - $coursenode = $frontpagecourse; - $this->load_all_categories(null, $showcategories); - break; - case CONTEXT_COURSECAT : - // This has already been loaded we just need to map the variable - $coursenode = $frontpagecourse; - $this->load_all_categories($this->page->context->instanceid, $showcategories); + // 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 + $coursenode = $frontpagecourse; + $this->load_all_categories(null, $showcategories); + break; + case CONTEXT_COURSECAT : + // This has already been loaded we just need to map the variable + $coursenode = $frontpagecourse; + $this->load_all_categories($this->page->context->instanceid, $showcategories); + if (array_key_exists($this->page->context->instanceid, $this->addedcategories)) { + $this->addedcategories[$this->page->context->instanceid]->make_active(); + } + break; + case CONTEXT_BLOCK : + case CONTEXT_COURSE : + if ($issite) { + // If it is the front page course, or a block on it then + // everything has already been loaded. break; - case CONTEXT_BLOCK : - case CONTEXT_COURSE : - // Load the course associated with the page into the navigation - $course = $this->page->course; - if ($showcategories && !$ismycourse) { - $this->load_all_categories($course->category, $showcategories); - } - $coursenode = $this->load_course($course); + } + // Load the course associated with the page into the navigation + $course = $this->page->course; + if ($showcategories && !$ismycourse) { + $this->load_all_categories($course->category, $showcategories); + } + $coursenode = $this->load_course($course); - // If the course wasn't added then don't try going any further. - if (!$coursenode) { - $canviewcourseprofile = false; - break; - } + // If the course wasn't added then don't try going any further. + if (!$coursenode) { + $canviewcourseprofile = false; + break; + } - // If the user is not enrolled then we only want to show the - // course node and not populate it. - - // 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, - // 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 = get_context_instance(CONTEXT_USER, $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 the user is not enrolled then we only want to show the + // course node and not populate it. + + // 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, + // 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 = get_context_instance(CONTEXT_USER, $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) { - $coursenode->make_active(); - $canviewcourseprofile = false; - break; - } - } - // Add the essentials such as reports etc... - $this->add_course_essentials($coursenode, $course); - if ($this->format_display_course_content($course->format)) { - // Load the course sections - $sections = $this->load_course_sections($course, $coursenode); } - if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) { + + if (!$isparent) { $coursenode->make_active(); + $canviewcourseprofile = false; + break; + } + } + // Add the essentials such as reports etc... + $this->add_course_essentials($coursenode, $course); + if ($this->format_display_course_content($course->format)) { + // Load the course sections + $sections = $this->load_course_sections($course, $coursenode); + } + if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) { + $coursenode->make_active(); + } + break; + case CONTEXT_MODULE : + if ($issite) { + // If this is the site course then most information will have + // already been loaded. + // However we need to check if there is more content that can + // yet be loaded for the specific module instance. + $activitynode = $this->rootnodes['site']->get($this->page->cm->id, navigation_node::TYPE_ACTIVITY); + if ($activitynode) { + $this->load_activity($this->page->cm, $this->page->course, $activitynode); } break; - case CONTEXT_MODULE : - $course = $this->page->course; - $cm = $this->page->cm; + } - if ($showcategories && !$ismycourse) { - $this->load_all_categories($course->category, $showcategories); - } + $course = $this->page->course; + $cm = $this->page->cm; - // Load the course associated with the page into the navigation - $coursenode = $this->load_course($course); + if ($showcategories && !$ismycourse) { + $this->load_all_categories($course->category, $showcategories); + } - // If the course wasn't added then don't try going any further. - if (!$coursenode) { - $canviewcourseprofile = false; - break; - } + // Load the course associated with the page into the navigation + $coursenode = $this->load_course($course); - // If the user is not enrolled then we only want to show the - // course node and not populate it. - if (!can_access_course($course)) { - $coursenode->make_active(); - $canviewcourseprofile = false; - break; - } + // If the course wasn't added then don't try going any further. + if (!$coursenode) { + $canviewcourseprofile = false; + break; + } - $this->add_course_essentials($coursenode, $course); + // If the user is not enrolled then we only want to show the + // course node and not populate it. + if (!can_access_course($course)) { + $coursenode->make_active(); + $canviewcourseprofile = false; + break; + } - // Get section number from $cm (if provided) - we need this - // before loading sections in order to tell it to load this section - // even if it would not normally display (=> it contains only - // a label, which we are now editing) - $sectionnum = isset($cm->sectionnum) ? $cm->sectionnum : 0; + $this->add_course_essentials($coursenode, $course); + + // Get section number from $cm (if provided) - we need this + // before loading sections in order to tell it to load this section + // even if it would not normally display (=> it contains only + // a label, which we are now editing) + $sectionnum = isset($cm->sectionnum) ? $cm->sectionnum : 0; + if ($sectionnum) { + // This value has to be stored in a member variable because + // otherwise we would have to pass it through a public API + // to course formats and they would need to change their + // functions to pass it along again... + $this->includesectionnum = $sectionnum; + } else { + $this->includesectionnum = false; + } + + // Load the course sections into the page + $sections = $this->load_course_sections($course, $coursenode); + if ($course->id != SITEID) { + // Find the section for the $CM associated with the page and collect + // its section number. if ($sectionnum) { - // This value has to be stored in a member variable because - // otherwise we would have to pass it through a public API - // to course formats and they would need to change their - // functions to pass it along again... - $this->includesectionnum = $sectionnum; + $cm->sectionnumber = $sectionnum; } else { - $this->includesectionnum = false; - } - - // Load the course sections into the page - $sections = $this->load_course_sections($course, $coursenode); - if ($course->id != SITEID) { - // Find the section for the $CM associated with the page and collect - // its section number. - if ($sectionnum) { - $cm->sectionnumber = $sectionnum; - } else { - foreach ($sections as $section) { - if ($section->id == $cm->section) { - $cm->sectionnumber = $section->section; - break; - } + foreach ($sections as $section) { + if ($section->id == $cm->section) { + $cm->sectionnumber = $section->section; + break; } } + } - // Load all of the section activities for the section the cm belongs to. - if (isset($cm->sectionnumber) and !empty($sections[$cm->sectionnumber])) { - list($sectionarray, $activityarray) = $this->generate_sections_and_activities($course); - $activities = $this->load_section_activities($sections[$cm->sectionnumber]->sectionnode, $cm->sectionnumber, $activityarray); - } else { - $activities = array(); - if ($activity = $this->load_stealth_activity($coursenode, get_fast_modinfo($course))) { - // "stealth" activity from unavailable section - $activities[$cm->id] = $activity; - } - } + // Load all of the section activities for the section the cm belongs to. + if (isset($cm->sectionnumber) and !empty($sections[$cm->sectionnumber])) { + list($sectionarray, $activityarray) = $this->generate_sections_and_activities($course); + $activities = $this->load_section_activities($sections[$cm->sectionnumber]->sectionnode, $cm->sectionnumber, $activityarray); } else { $activities = array(); - $activities[$cm->id] = $coursenode->get($cm->id, navigation_node::TYPE_ACTIVITY); - } - if (!empty($activities[$cm->id])) { - // Finally load the cm specific navigaton information - $this->load_activity($cm, $course, $activities[$cm->id]); - // Check if we have an active ndoe - if (!$activities[$cm->id]->contains_active_node() && !$activities[$cm->id]->search_for_active_node()) { - // And make the activity node active. - $activities[$cm->id]->make_active(); + if ($activity = $this->load_stealth_activity($coursenode, get_fast_modinfo($course))) { + // "stealth" activity from unavailable section + $activities[$cm->id] = $activity; } - } else { - //TODO: something is wrong, what to do? (Skodak) } - break; - case CONTEXT_USER : - $course = $this->page->course; - if ($showcategories && !$ismycourse) { - $this->load_all_categories($course->category, $showcategories); + } else { + $activities = array(); + $activities[$cm->id] = $coursenode->get($cm->id, navigation_node::TYPE_ACTIVITY); + } + if (!empty($activities[$cm->id])) { + // Finally load the cm specific navigaton information + $this->load_activity($cm, $course, $activities[$cm->id]); + // Check if we have an active ndoe + if (!$activities[$cm->id]->contains_active_node() && !$activities[$cm->id]->search_for_active_node()) { + // And make the activity node active. + $activities[$cm->id]->make_active(); } - // Load the course associated with the user into the navigation - $coursenode = $this->load_course($course); + } else { + //TODO: something is wrong, what to do? (Skodak) + } + break; + case CONTEXT_USER : + if ($issite) { + // The users profile information etc is already loaded + // for the front page. + break; + } + $course = $this->page->course; + if ($showcategories && !$ismycourse) { + $this->load_all_categories($course->category, $showcategories); + } + // Load the course associated with the user into the navigation + $coursenode = $this->load_course($course); - // If the course wasn't added then don't try going any further. - if (!$coursenode) { - $canviewcourseprofile = false; - break; - } + // If the course wasn't added then don't try going any further. + if (!$coursenode) { + $canviewcourseprofile = false; + break; + } - // If the user is not enrolled then we only want to show the - // course node and not populate it. - if (!can_access_course($course)) { - $coursenode->make_active(); - $canviewcourseprofile = false; - break; - } - $this->add_course_essentials($coursenode, $course); - $sections = $this->load_course_sections($course, $coursenode); + // If the user is not enrolled then we only want to show the + // course node and not populate it. + if (!can_access_course($course)) { + $coursenode->make_active(); + $canviewcourseprofile = false; break; - } - } else { - // We need to check if the user is viewing a front page module. - // If so then there is potentially more content to load yet for that - // module. - if ($this->page->context->contextlevel == CONTEXT_MODULE) { - $activitynode = $this->rootnodes['site']->get($this->page->cm->id, navigation_node::TYPE_ACTIVITY); - if ($activitynode) { - $this->load_activity($this->page->cm, $this->page->course, $activitynode); } - } + $this->add_course_essentials($coursenode, $course); + $sections = $this->load_course_sections($course, $coursenode); + break; } $limit = 20; @@ -1413,7 +1429,9 @@ public function initialise() { protected function show_categories() { global $CFG, $DB; if ($this->showcategories === null) { - $this->showcategories = !empty($CFG->navshowcategories) && $DB->count_records('course_categories') > 1; + $show = $this->page->context->contextlevel == CONTEXT_COURSECAT; + $show = $show || (!empty($CFG->navshowcategories) && $DB->count_records('course_categories') > 1); + $this->showcategories = $show; } return $this->showcategories; } @@ -1467,13 +1485,16 @@ protected function load_all_courses($categoryids=null) { $categoryselect = ''; } - list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); + $ccselect = context_helper::get_preload_record_columns_sql('ctx'); + $params['contextlevel'] = CONTEXT_COURSE; list($courseids, $courseparams) = $DB->get_in_or_equal(array_keys($this->addedcourses) + array(SITEID), SQL_PARAMS_NAMED, 'lcourse', false); - $sql = "SELECT c.id, c.sortorder, c.visible, c.fullname, c.shortname, c.category, cat.path AS categorypath $ccselect + $sql = "SELECT c.id, c.sortorder, c.visible, c.fullname, c.shortname, c.category, cat.path AS categorypath, $ccselect FROM {course} c - $ccjoin + JOIN {context} ctx ON c.id = ctx.instanceid LEFT JOIN {course_categories} cat ON cat.id=c.category - WHERE c.id {$courseids} {$categoryselect} + WHERE c.id {$courseids} AND + ctx.contextlevel = :contextlevel + {$categoryselect} ORDER BY c.sortorder ASC"; $limit = 20; if (!empty($CFG->navcourselimit)) { @@ -1483,7 +1504,7 @@ protected function load_all_courses($categoryids=null) { $coursenodes = array(); foreach ($courses as $course) { - context_instance_preload($course); + context_helper::preload_from_record($course); $coursenodes[$course->id] = $this->add_course($course); } return $coursenodes; @@ -1963,10 +1984,14 @@ protected function load_for_user($user=null, $forceforcontext=false) { $user = $USER; } else if (!is_object($user)) { // If the user is not an object then get them from the database - list($select, $join) = context_instance_preload_sql('u.id', CONTEXT_USER, 'ctx'); - $sql = "SELECT u.* $select FROM {user} u $join WHERE u.id = :userid"; - $user = $DB->get_record_sql($sql, array('userid' => (int)$user), MUST_EXIST); - context_instance_preload($user); + $select = context_helper::get_preload_record_columns_sql('ctx'); + $sql = "SELECT u.*, $select + FROM {user} u + JOIN {context} ctx ON u.id = ctx.instanceid + WHERE u.id = :userid AND + ctx.contextlevel = :contextlevel"; + $user = $DB->get_record_sql($sql, array('userid' => (int)$user, 'contextlevel' => CONTEXT_USER), MUST_EXIST); + context_helper::preload_from_record($user); } $iscurrentuser = ($user->id == $USER->id); @@ -3682,10 +3707,14 @@ protected function generate_user_settings($courseid, $userid, $gstitle='usercurr if (!empty($this->page->course->id) && $this->page->course->id == $courseid) { $course = $this->page->course; } else { - list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); - $sql = "SELECT c.* $select FROM {course} c $join WHERE c.id = :courseid"; - $course = $DB->get_record_sql($sql, array('courseid' => $courseid), MUST_EXIST); - context_instance_preload($course); + $select = context_helper::get_preload_record_columns_sql('ctx'); + $sql = "SELECT c.*, $select + FROM {course} c + JOIN {context} ctx ON c.id = ctx.instanceid + WHERE c.id = :courseid AND ctx.contextlevel = :contextlevel"; + $params = array('courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE); + $course = $DB->get_record_sql($sql, $params, MUST_EXIST); + context_helper::preload_from_record($course); } } else { $course = $SITE; @@ -3699,14 +3728,17 @@ protected function generate_user_settings($courseid, $userid, $gstitle='usercurr $user = $USER; $usercontext = get_context_instance(CONTEXT_USER, $user->id); // User context } else { - - list($select, $join) = context_instance_preload_sql('u.id', CONTEXT_USER, 'ctx'); - $sql = "SELECT u.* $select FROM {user} u $join WHERE u.id = :userid"; - $user = $DB->get_record_sql($sql, array('userid' => $userid), IGNORE_MISSING); + $select = context_helper::get_preload_record_columns_sql('ctx'); + $sql = "SELECT u.*, $select + FROM {user} u + JOIN {context} ctx ON u.id = ctx.instanceid + WHERE u.id = :userid AND ctx.contextlevel = :contextlevel"; + $params = array('userid' => $userid, 'contextlevel' => CONTEXT_USER); + $user = $DB->get_record_sql($sql, $params, IGNORE_MISSING); if (!$user) { return false; } - context_instance_preload($user); + context_helper::preload_from_record($user); // Check that the user can view the profile $usercontext = get_context_instance(CONTEXT_USER, $user->id); // User context diff --git a/theme/base/style/course.css b/theme/base/style/course.css index 3062ac629a0b5..7a457a4a89b12 100644 --- a/theme/base/style/course.css +++ b/theme/base/style/course.css @@ -123,3 +123,6 @@ #page-course-index.dir-rtl .category .image {padding-left: 5px; padding-right: 0px;} #page-course-index.dir-rtl .indentation {padding-left: 0px;padding-right: 30px;} + +table.category_subcategories {margin-bottom:1em;} +table.category_subcategories td {white-space: nowrap;} \ No newline at end of file