Commit beff3806 authored by Marina Glancy's avatar Marina Glancy
Browse files

MDL-10965 courses: capability to browse course list

parent e9cbc454
......@@ -234,10 +234,6 @@ class data_registry_page implements renderable, templatable {
$coursecontext = \context_course::instance($course->id);
if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
continue;
}
$coursenode = [
'text' => shorten_text(format_string($course->shortname, true, ['context' => $coursecontext])),
'contextid' => $coursecontext->id,
......
......@@ -54,6 +54,11 @@ class block_course_list extends block_list {
}
}
$allcourselink =
(has_capability('moodle/course:update', context_system::instance())
|| empty($CFG->block_course_list_hideallcourseslink)) &&
core_course_category::user_top();
if (empty($CFG->disablemycourses) and isloggedin() and !isguestuser() and
!(has_capability('moodle/course:update', context_system::instance()) and $adminseesall)) { // Just print My Courses
if ($courses = enrol_get_my_courses()) {
......@@ -65,7 +70,7 @@ class block_course_list extends block_list {
}
$this->title = get_string('mycourses');
/// If we can update any course of the view all isn't hidden, show the view all courses link
if (has_capability('moodle/course:update', context_system::instance()) || empty($CFG->block_course_list_hideallcourseslink)) {
if ($allcourselink) {
$this->content->footer = "<a href=\"$CFG->wwwroot/course/index.php\">".get_string("fulllistofcourses")."</a> ...";
}
}
......@@ -75,8 +80,9 @@ class block_course_list extends block_list {
}
}
$categories = core_course_category::get(0)->get_children(); // Parent = 0 ie top-level categories only
if ($categories) { //Check we have categories
// User is not enrolled in any courses, show list of available categories or courses (if there is only one category).
$topcategory = core_course_category::top();
if ($topcategory->is_uservisible() && ($categories = $topcategory->get_children())) { // Check we have categories.
if (count($categories) > 1 || (count($categories) == 1 && $DB->count_records('course') > 200)) { // Just print top level category links
foreach ($categories as $category) {
$categoryname = $category->get_formatted_name();
......@@ -84,13 +90,13 @@ class block_course_list extends block_list {
$this->content->items[]="<a $linkcss href=\"$CFG->wwwroot/course/index.php?categoryid=$category->id\">".$icon . $categoryname . "</a>";
}
/// If we can update any course of the view all isn't hidden, show the view all courses link
if (has_capability('moodle/course:update', context_system::instance()) || empty($CFG->block_course_list_hideallcourseslink)) {
if ($allcourselink) {
$this->content->footer .= "<a href=\"$CFG->wwwroot/course/index.php\">".get_string('fulllistofcourses').'</a> ...';
}
$this->title = get_string('categories');
} else { // Just print course names of single category
$category = array_shift($categories);
$courses = get_courses($category->id);
$courses = $category->get_courses();
if ($courses) {
foreach ($courses as $course) {
......@@ -98,12 +104,12 @@ class block_course_list extends block_list {
$linkcss = $course->visible ? "" : " class=\"dimmed\" ";
$this->content->items[]="<a $linkcss title=\""
. format_string($course->shortname, true, array('context' => $coursecontext))."\" ".
. s($course->get_formatted_shortname())."\" ".
"href=\"$CFG->wwwroot/course/view.php?id=$course->id\">"
.$icon. format_string(get_course_display_name_for_list($course), true, array('context' => context_course::instance($course->id))) . "</a>";
.$icon. $course->get_formatted_name() . "</a>";
}
/// If we can update any course of the view all isn't hidden, show the view all courses link
if (has_capability('moodle/course:update', context_system::instance()) || empty($CFG->block_course_list_hideallcourseslink)) {
if ($allcourselink) {
$this->content->footer .= "<a href=\"$CFG->wwwroot/course/index.php\">".get_string('fulllistofcourses').'</a> ...';
}
$this->get_remote_courses();
......
......@@ -48,9 +48,8 @@ function block_html_pluginfile($course, $birecord_or_cm, $context, $filearea, $a
$parentcontext = $context->get_parent_context();
if ($parentcontext->contextlevel === CONTEXT_COURSECAT) {
// Check if category is visible and user can view this category.
$category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST);
if (!$category->visible) {
require_capability('moodle/category:viewhiddencategories', $parentcontext);
if (!core_course_category::get($parentcontext->instanceid, IGNORE_MISSING)) {
send_file_not_found();
}
} else if ($parentcontext->contextlevel === CONTEXT_USER && $parentcontext->instanceid != $USER->id) {
// The block is in the context of a user, it is only visible to the user who it belongs to.
......
......@@ -2352,8 +2352,11 @@ function calendar_get_default_courses($courseid = null, $fields = '*', $canmanag
$fieldlist = explode(',', $fields);
$prefixedfields = array_map(function($value) {
return 'c.' . trim($value);
return 'c.' . trim(strtolower($value));
}, $fieldlist);
if (!in_array('c.visible', $prefixedfields) && !in_array('c.*', $prefixedfields)) {
$prefixedfields[] = 'c.visible';
}
$courses = get_courses('all', 'c.shortname', implode(',', $prefixedfields));
} else {
$courses = enrol_get_users_courses($userid, true, $fields);
......
......@@ -83,6 +83,7 @@ $course = get_course($courseid);
if ($courseid != SITEID && !empty($courseid)) {
navigation_node::override_active_url(new moodle_url('/course/view.php', array('id' => $course->id)));
} else if (!empty($categoryid)) {
core_course_category::get($categoryid); // Check that category exists and can be accessed.
$PAGE->set_category_by_id($categoryid);
navigation_node::override_active_url(new moodle_url('/course/index.php', array('categoryid' => $categoryid)));
} else {
......
This diff is collapsed.
......@@ -415,14 +415,6 @@ class core_course_list_element implements IteratorAggregate {
return context_course::instance($this->__get('id'));
}
/**
* Returns true if this course is visible to the current user.
* @return bool
*/
public function is_uservisible() {
return $this->visible || has_capability('moodle/course:viewhiddencourses', $this->get_context());
}
/**
* Returns true if the current user can review enrolments for this course.
*
......
......@@ -403,12 +403,10 @@ class helper {
$baseurl = new \moodle_url('/course/management.php', $params);
$actions = array();
// View.
if ($course->is_uservisible()) {
$actions['view'] = array(
'url' => new \moodle_url('/course/view.php', array('id' => $course->id)),
'string' => \get_string('view')
);
}
$actions['view'] = array(
'url' => new \moodle_url('/course/view.php', array('id' => $course->id)),
'string' => \get_string('view')
);
// Edit.
if ($course->can_edit()) {
$actions['edit'] = array(
......@@ -802,13 +800,14 @@ class helper {
$searchcriteria = array('modulelist' => $modulelist);
}
$courses = \core_course_category::get(0)->search_courses($searchcriteria, array(
$topcat = \core_course_category::top();
$courses = $topcat->search_courses($searchcriteria, array(
'recursive' => true,
'offset' => $page * $perpage,
'limit' => $perpage,
'sort' => array('fullname' => 1)
));
$totalcount = \core_course_category::get(0)->search_courses_count($searchcriteria, array('recursive' => true));
$totalcount = $topcat->search_courses_count($searchcriteria, array('recursive' => true));
return array($courses, \count($courses), $totalcount);
}
......
......@@ -136,7 +136,7 @@ class core_course_management_renderer extends plugin_renderer_base {
$catatlevel[] = array_shift($selectedparents);
$catatlevel = array_unique($catatlevel);
$listing = core_course_category::get(0)->get_children();
$listing = core_course_category::top()->get_children();
$attributes = array(
'class' => 'ml-1 list-unstyled',
......@@ -200,10 +200,10 @@ class core_course_management_renderer extends plugin_renderer_base {
'aria-expanded' => $isexpanded ? 'true' : 'false'
);
$text = $category->get_formatted_name();
if ($category->parent) {
if (($parent = $category->get_parent_coursecat()) && $parent->id) {
$a = new stdClass;
$a->category = $text;
$a->parentcategory = $category->get_parent_coursecat()->get_formatted_name();
$a->parentcategory = $parent->get_formatted_name();
$textlabel = get_string('categorysubcategoryof', 'moodle', $a);
}
$courseicon = $this->output->pix_icon('i/course', get_string('courses'));
......@@ -327,7 +327,7 @@ class core_course_management_renderer extends plugin_renderer_base {
$cancreatecategory = $category && $category->can_create_subcategory();
$cancreatecategory = $cancreatecategory || core_course_category::can_create_top_level_category();
if ($category === null) {
$category = core_course_category::get(0);
$category = core_course_category::top();
}
if ($cancreatecategory) {
......@@ -459,8 +459,8 @@ class core_course_management_renderer extends plugin_renderer_base {
}
if (core_course_category::can_change_parent_any()) {
$options = array();
if (has_capability('moodle/category:manage', context_system::instance())) {
$options[0] = core_course_category::get(0)->get_formatted_name();
if (core_course_category::top()->has_manage_capability()) {
$options[0] = core_course_category::top()->get_formatted_name();
}
$options += core_course_category::make_categories_list('moodle/category:manage');
$select = html_writer::select(
......
......@@ -113,9 +113,7 @@ class course extends \core_search\base {
return \core_search\manager::ACCESS_DELETED;
}
$coursecontext = \context_course::instance($course->id);
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
if (\core_course_category::can_view_course_info($course)) {
return \core_search\manager::ACCESS_GRANTED;
}
......
......@@ -135,8 +135,7 @@ class customfield extends \core_search\base {
if (!$course) {
return \core_search\manager::ACCESS_DELETED;
}
$coursecontext = \context_course::instance($course->id);
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
if (\core_course_category::can_view_course_info($course)) {
return \core_search\manager::ACCESS_GRANTED;
}
return \core_search\manager::ACCESS_DENIED;
......
......@@ -1870,7 +1870,7 @@ class core_course_external extends external_api {
if (!isset($excludedcats[$category->id])) {
// Final check to see if the category is visible to the user.
if ($category->visible or has_capability('moodle/category:viewhiddencategories', $context)) {
if (core_course_category::can_view_category($category)) {
$categoryinfo = array();
$categoryinfo['id'] = $category->id;
......@@ -3235,14 +3235,18 @@ class core_course_external extends external_api {
}
// Get the public course information, even if we are not enrolled.
$courseinlist = new core_course_list_element($course);
$coursesdata[$course->id] = self::get_course_public_information($courseinlist, $context);
// Now, check if we have access to the course.
try {
self::validate_context($context);
} catch (Exception $e) {
// User can not access the course, check if they can see the public information about the course and return it.
if (core_course_category::can_view_course_info($course)) {
$coursesdata[$course->id] = self::get_course_public_information($courseinlist, $context);
}
continue;
}
$coursesdata[$course->id] = self::get_course_public_information($courseinlist, $context);
// Return information for any user that can access the course.
$coursefields = array('format', 'showgrades', 'newsitems', 'startdate', 'enddate', 'maxbytes', 'showreports', 'visible',
'groupmode', 'groupmodeforce', 'defaultgroupingid', 'enablecompletion', 'completionnotify', 'lang', 'theme',
......
......@@ -29,39 +29,40 @@ require_once($CFG->dirroot. '/course/lib.php');
$categoryid = optional_param('categoryid', 0, PARAM_INT); // Category id
$site = get_site();
if ($CFG->forcelogin) {
require_login();
}
$heading = $site->fullname;
if ($categoryid) {
$category = core_course_category::get($categoryid); // This will validate access.
$PAGE->set_category_by_id($categoryid);
$PAGE->set_url(new moodle_url('/course/index.php', array('categoryid' => $categoryid)));
$PAGE->set_pagetype('course-index-category');
// And the object has been loaded for us no need for another DB call
$category = $PAGE->category;
} else {
// Check if there is only one category, if so use that.
if (core_course_category::count_all() == 1) {
$category = core_course_category::get_default();
$categoryid = $category->id;
$heading = $category->get_formatted_name();
} else if ($category = core_course_category::user_top()) {
// Check if there is only one top-level category, if so use that.
$categoryid = $category->id;
$PAGE->set_url('/course/index.php');
if ($category->is_uservisible() && $categoryid) {
$PAGE->set_category_by_id($categoryid);
$PAGE->set_pagetype('course-index-category');
$PAGE->set_context($category->get_context());
if (!core_course_category::is_simple_site()) {
$PAGE->set_url(new moodle_url('/course/index.php', array('categoryid' => $categoryid)));
$heading = $category->get_formatted_name();
}
} else {
$PAGE->set_context(context_system::instance());
}
$PAGE->set_url('/course/index.php');
$PAGE->set_pagetype('course-index-category');
} else {
throw new moodle_exception('cannotviewcategory');
}
$PAGE->set_pagelayout('coursecategory');
$courserenderer = $PAGE->get_renderer('core', 'course');
if ($CFG->forcelogin) {
require_login();
}
if ($categoryid && !$category->visible && !has_capability('moodle/category:viewhiddencategories', $PAGE->context)) {
throw new moodle_exception('unknowncategory');
}
$PAGE->set_heading($site->fullname);
$PAGE->set_heading($heading);
$content = $courserenderer->course_category($categoryid);
echo $OUTPUT->header();
......
......@@ -48,8 +48,8 @@
}
$context = context_course::instance($course->id);
if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
print_error('coursehidden', '', $CFG->wwwroot .'/');
if (!core_course_category::can_view_course_info($course) && !is_enrolled($context, null, '', true)) {
print_error('cannotviewcategory', '', $CFG->wwwroot .'/');
}
$PAGE->set_course($course);
......
......@@ -762,7 +762,7 @@ function print_course_request_buttons($context) {
echo $OUTPUT->single_button(new moodle_url('/course/request.php'), get_string('requestcourse'), 'get');
}
/// Print a button to manage pending requests
if ($context->contextlevel == CONTEXT_SYSTEM && has_capability('moodle/site:approvecourse', $context)) {
if (has_capability('moodle/site:approvecourse', $context)) {
$disabled = !$DB->record_exists('course_request', array());
echo $OUTPUT->single_button(new moodle_url('/course/pending.php'), get_string('coursespending'), 'get', array('disabled' => $disabled));
}
......
......@@ -68,8 +68,9 @@ if ($courseid) {
} else {
$course = null;
$courseid = null;
$category = core_course_category::get_default();
$categoryid = $category->id;
$topchildren = core_course_category::top()->get_children();
$category = reset($topchildren);
$categoryid = $category ? $category->id : 0;
$context = context_coursecat::instance($category->id);
$url->param('categoryid', $category->id);
}
......@@ -378,9 +379,9 @@ if ($action !== false && confirm_sesskey()) {
}
$categories = core_course_category::get_many($categoryids);
} else if ($for === 'allcategories') {
if ($sortcategoriesby && core_course_category::get(0)->can_resort_subcategories()) {
if ($sortcategoriesby && core_course_category::top()->can_resort_subcategories()) {
\core_course\management\helper::action_category_resort_subcategories(
core_course_category::get(0), $sortcategoriesby);
core_course_category::top(), $sortcategoriesby);
}
$categorieslist = core_course_category::make_categories_list('moodle/category:manage');
$categoryids = array_keys($categorieslist);
......
......@@ -1582,35 +1582,38 @@ class core_course_renderer extends plugin_renderer_base {
*/
public function course_category($category) {
global $CFG;
$coursecat = core_course_category::get(is_object($category) ? $category->id : $category);
$usertop = core_course_category::user_top();
if (empty($category)) {
$coursecat = $usertop;
} else if (is_object($category) && $category instanceof core_course_category) {
$coursecat = $category;
} else {
$coursecat = core_course_category::get(is_object($category) ? $category->id : $category);
}
$site = get_site();
$output = '';
if (can_edit_in_category($coursecat->id)) {
if ($coursecat->can_create_course() || $coursecat->has_manage_capability()) {
// Add 'Manage' button if user has permissions to edit this category.
$managebutton = $this->single_button(new moodle_url('/course/management.php',
array('categoryid' => $coursecat->id)), get_string('managecourses'), 'get');
$this->page->set_button($managebutton);
}
if (!$coursecat->id) {
if (core_course_category::count_all() == 1) {
// There exists only one category in the system, do not display link to it
$coursecat = core_course_category::get_default();
$strfulllistofcourses = get_string('fulllistofcourses');
$this->page->set_title("$site->shortname: $strfulllistofcourses");
} else {
$strcategories = get_string('categories');
$this->page->set_title("$site->shortname: $strcategories");
}
if (core_course_category::is_simple_site()) {
// There is only one category in the system, do not display link to it.
$strfulllistofcourses = get_string('fulllistofcourses');
$this->page->set_title("$site->shortname: $strfulllistofcourses");
} else if (!$coursecat->id || !$coursecat->is_uservisible()) {
$strcategories = get_string('categories');
$this->page->set_title("$site->shortname: $strcategories");
} else {
$title = $site->shortname;
if (core_course_category::count_all() > 1) {
$title .= ": ". $coursecat->get_formatted_name();
}
$this->page->set_title($title);
$strfulllistofcourses = get_string('fulllistofcourses');
$this->page->set_title("$site->shortname: $strfulllistofcourses");
// Print the category selector
if (core_course_category::count_all() > 1) {
$categorieslist = core_course_category::make_categories_list();
if (count($categorieslist) > 1) {
$output .= html_writer::start_tag('div', array('class' => 'categorypicker'));
$select = new single_select(new moodle_url('/course/index.php'), 'categoryid',
core_course_category::make_categories_list(), $coursecat->id, null, 'switchcategory');
......@@ -1644,13 +1647,13 @@ class core_course_renderer extends plugin_renderer_base {
}
$coursedisplayoptions['limit'] = $perpage;
$catdisplayoptions['limit'] = $perpage;
if ($browse === 'courses' || !$coursecat->has_children()) {
if ($browse === 'courses' || !$coursecat->get_children_count()) {
$coursedisplayoptions['offset'] = $page * $perpage;
$coursedisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'courses'));
$catdisplayoptions['nodisplay'] = true;
$catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories'));
$catdisplayoptions['viewmoretext'] = new lang_string('viewallsubcategories');
} else if ($browse === 'categories' || !$coursecat->has_courses()) {
} else if ($browse === 'categories' || !$coursecat->get_courses_count()) {
$coursedisplayoptions['nodisplay'] = true;
$catdisplayoptions['offset'] = $page * $perpage;
$catdisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'categories'));
......@@ -1670,24 +1673,23 @@ class core_course_renderer extends plugin_renderer_base {
// Add action buttons
$output .= $this->container_start('buttons');
$context = get_category_or_system_context($coursecat->id);
if (has_capability('moodle/course:create', $context)) {
// Print link to create a new course, for the 1st available category.
if ($coursecat->id) {
$url = new moodle_url('/course/edit.php', array('category' => $coursecat->id, 'returnto' => 'category'));
} else {
$url = new moodle_url('/course/edit.php', array('category' => $CFG->defaultrequestcategory, 'returnto' => 'topcat'));
if ($coursecat->is_uservisible()) {
$context = get_category_or_system_context($coursecat->id);
if (has_capability('moodle/course:create', $context)) {
// Print link to create a new course, for the 1st available category.
if ($coursecat->id) {
$url = new moodle_url('/course/edit.php', array('category' => $coursecat->id, 'returnto' => 'category'));
} else {
$url = new moodle_url('/course/edit.php',
array('category' => $CFG->defaultrequestcategory, 'returnto' => 'topcat'));
}
$output .= $this->single_button($url, get_string('addnewcourse'), 'get');
}
$output .= $this->single_button($url, get_string('addnewcourse'), 'get');
}
ob_start();
if (core_course_category::count_all() == 1) {
print_course_request_buttons(context_system::instance());
} else {
ob_start();
print_course_request_buttons($context);
$output .= ob_get_contents();
ob_end_clean();
}
$output .= ob_get_contents();
ob_end_clean();
$output .= $this->container_end();
return $output;
......@@ -1828,7 +1830,7 @@ class core_course_renderer extends plugin_renderer_base {
if (empty($displayoptions)) {
$displayoptions = array();
}
$showcategories = core_course_category::count_all() > 1;
$showcategories = !core_course_category::is_simple_site();
$displayoptions += array('limit' => $CFG->coursesperpage, 'offset' => 0);
$chelper = new coursecat_helper();
$searchcriteria = array('tagid' => $tagid, 'ctx' => $ctx, 'rec' => $rec);
......@@ -1950,15 +1952,15 @@ class core_course_renderer extends plugin_renderer_base {
if (!empty($courses) || !empty($rcourses) || !empty($rhosts)) {
$chelper = new coursecat_helper();
$totalcount = count($courses);
if (count($courses) > $CFG->frontpagecourselimit) {
// There are more enrolled courses than we can display, display link to 'My courses'.
$totalcount = count($courses);
$courses = array_slice($courses, 0, $CFG->frontpagecourselimit, true);
$chelper->set_courses_display_options(array(
'viewmoreurl' => new moodle_url('/my/'),
'viewmoretext' => new lang_string('mycourses')
));
} else {
} else if (core_course_category::top()->is_uservisible()) {
// All enrolled courses are displayed, display link to 'All courses' if there are more courses in system.
$chelper->set_courses_display_options(array(
'viewmoreurl' => new moodle_url('/course/index.php'),
......@@ -2007,8 +2009,8 @@ class core_course_renderer extends plugin_renderer_base {
'viewmoretext' => new lang_string('fulllistofcourses')));
$chelper->set_attributes(array('class' => 'frontpage-course-list-all'));
$courses = core_course_category::get(0)->get_courses($chelper->get_courses_display_options());
$totalcount = core_course_category::get(0)->get_courses_count($chelper->get_courses_display_options());
$courses = core_course_category::top()->get_courses($chelper->get_courses_display_options());
$totalcount = core_course_category::top()->get_courses_count($chelper->get_courses_display_options());
if (!$totalcount && !$this->page->user_is_editing() && has_capability('moodle/course:create', context_system::instance())) {
// Print link to create a new course, for the 1st available category.
return $this->add_new_course_button();
......@@ -2038,6 +2040,11 @@ class core_course_renderer extends plugin_renderer_base {
*/
public function frontpage_combo_list() {
global $CFG;
// TODO MDL-10965 improve.
$tree = core_course_category::top();
if (!$tree->get_children_count()) {
return '';
}
$chelper = new coursecat_helper();
$chelper->set_subcat_depth($CFG->maxcategorydepth)->
set_categories_display_options(array(
......@@ -2051,7 +2058,7 @@ class core_course_renderer extends plugin_renderer_base {
array('browse' => 'courses', 'page' => 1))
))->
set_attributes(array('class' => 'frontpage-category-combo'));
return $this->coursecat_tree($chelper, core_course_category::get(0));
return $this->coursecat_tree($chelper, $tree);
}
/**
......@@ -2061,6 +2068,11 @@ class core_course_renderer extends plugin_renderer_base {
*/
public function frontpage_categories_list() {
global $CFG;
// TODO MDL-10965 improve.
$tree = core_course_category::top();
if (!$tree->get_children_count()) {
return '';
}
$chelper = new coursecat_helper();
$chelper->set_subcat_depth($CFG->maxcategorydepth)->
set_show_courses(self::COURSECAT_SHOW_COURSES_COUNT)->
......@@ -2070,7 +2082,7 @@ class core_course_renderer extends plugin_renderer_base {
array('browse' => 'categories', 'page' => 1))
))->
set_attributes(array('class' => 'frontpage-category-names'));
return $this->coursecat_tree($chelper, core_course_category::get(0));
return $this->coursecat_tree($chelper, $tree);
}
/**
......@@ -2379,6 +2391,9 @@ class core_course_renderer extends plugin_renderer_base {
* @return string
*/
protected function frontpage_part($skipdivid, $contentsdivid, $header, $contents) {
if (strval($contents) === '') {
return '';
}
$output = html_writer::link('#' . $skipdivid,
get_string('skipa', 'access', core_text::strtolower(strip_tags($header))),
array('class' => 'skip-block skip'));
......@@ -2438,10 +2453,8 @@ class core_course_renderer extends plugin_renderer_base {
case FRONTPAGEALLCOURSELIST:
$availablecourseshtml = $this->frontpage_available_courses();
if (!empty($availablecourseshtml)) {
$output .= $this->frontpage_part('skipavailablecourses', 'frontpage-available-course-list',
get_string('availablecourses'), $availablecourseshtml);
}
$output .= $this->frontpage_part('skipavailablecourses', 'frontpage-available-course-list',
get_string('availablecourses'), $availablecourseshtml);
break;
case FRONTPAGECATEGORYNAMES:
......@@ -2705,7 +2718,7 @@ class coursecat_helper {
* @return string|null
*/
public function get_category_formatted_description($coursecat, $options = null) {
if ($coursecat->id && !empty($coursecat->description)) {
if ($coursecat->id && $coursecat->is_uservisible() && !empty($coursecat->description)) {
if (!isset($coursecat->descriptionformat)) {
$descriptionformat = FORMAT_MOODLE;
} else {
......
......@@ -71,7 +71,8 @@ $strsearch = new lang_string("search");
$strsearchresults = new lang_string("searchresults");
$strnovalidcourses = new lang_string('novalidcourses');