Skip to content

Commit

Permalink
MDL-73462 course: Introduce course category tertiary navigation
Browse files Browse the repository at this point in the history
Update the category management page.
  • Loading branch information
Peter Dias committed Mar 1, 2022
1 parent 9cd77c4 commit f1959af
Show file tree
Hide file tree
Showing 20 changed files with 694 additions and 81 deletions.
5 changes: 4 additions & 1 deletion admin/roles/assign.php
Expand Up @@ -183,7 +183,10 @@
break;
}

$PAGE->set_navigation_overflow_state(false);
// In a course category context we leverage overflow for the tertiary navigation
if ($context->contextlevel != CONTEXT_COURSECAT) {
$PAGE->set_navigation_overflow_state(false);
}

// Within a course context we need to explicitly set active tab as there isn't a reference in the nav tree.
if ($context->contextlevel == CONTEXT_COURSE) {
Expand Down
6 changes: 5 additions & 1 deletion admin/roles/check.php
Expand Up @@ -126,7 +126,11 @@
$rolenames = role_get_names($context);
}

$PAGE->set_navigation_overflow_state(false);
// In a course category context we leverage overflow for the tertiary navigation
if ($context->contextlevel != CONTEXT_COURSECAT) {
$PAGE->set_navigation_overflow_state(false);
}

echo $OUTPUT->header();
if ($context->contextlevel == CONTEXT_COURSE || $context->contextlevel == CONTEXT_MODULE) {
echo $OUTPUT->render_participants_tertiary_nav($course);
Expand Down
6 changes: 5 additions & 1 deletion admin/roles/permissions.php
Expand Up @@ -204,7 +204,11 @@
}
}

$PAGE->set_navigation_overflow_state(false);
// When we are within a category context we leave it to the overflow state to display additional nav nodes.
if ($context->contextlevel != CONTEXT_COURSECAT) {
$PAGE->set_navigation_overflow_state(false);
}

echo $OUTPUT->header();
if ($context->contextlevel == CONTEXT_COURSE || $context->contextlevel == CONTEXT_MODULE) {
echo $OUTPUT->render_participants_tertiary_nav($course);
Expand Down
11 changes: 11 additions & 0 deletions course/classes/category.php
Expand Up @@ -2777,6 +2777,17 @@ public function has_manage_capability() {
return has_capability('moodle/category:manage', $this->get_context());
}

/**
* Checks whether the category has access to content bank
*
* @return bool
*/
public function has_contentbank() {
$cb = new \core_contentbank\contentbank();
return ($cb->is_context_allowed($this->get_context()) &&
has_capability('moodle/contentbank:access', $this->get_context()));
}

/**
* Returns true if the user has the manage capability on the parent category.
* @return bool
Expand Down
41 changes: 19 additions & 22 deletions course/classes/management/helper.php
Expand Up @@ -173,6 +173,14 @@ public static function get_category_listitem_actions(\core_course_category $cate
$manageurl = new \moodle_url('/course/management.php', array('categoryid' => $category->id));
$baseurl = new \moodle_url($manageurl, array('sesskey' => \sesskey()));
$actions = array();

// View link.
$actions['view'] = [
'url' => new \moodle_url('/course/index.php', ['categoryid' => $category->id]),
'icon' => null,
'string' => get_string('view')
];

// Edit.
if ($category->can_edit()) {
$actions['edit'] = array(
Expand Down Expand Up @@ -252,36 +260,15 @@ public static function get_category_listitem_actions(\core_course_category $cate
);
}

// Assign roles.
if ($category->can_review_roles()) {
$actions['assignroles'] = array(
'url' => new \moodle_url('/admin/roles/assign.php', array('contextid' => $category->get_context()->id,
'returnurl' => $manageurl->out_as_local_url(false))),
'icon' => new \pix_icon('t/assignroles', new \lang_string('assignroles', 'role')),
'string' => new \lang_string('assignroles', 'role')
);
}

// Permissions.
if ($category->can_review_permissions()) {
$actions['permissions'] = array(
'url' => new \moodle_url('/admin/roles/permissions.php', array('contextid' => $category->get_context()->id,
'returnurl' => $manageurl->out_as_local_url(false))),
'url' => new \moodle_url('/admin/roles/permissions.php', ['contextid' => $category->get_context()->id]),
'icon' => new \pix_icon('i/permissions', new \lang_string('permissions', 'role')),
'string' => new \lang_string('permissions', 'role')
);
}

// Check permissions.
if ($category->can_review_permissions()) {
$actions['checkroles'] = array(
'url' => new \moodle_url('/admin/roles/check.php', array('contextid' => $category->get_context()->id,
'returnurl' => $manageurl->out_as_local_url(false))),
'icon' => new \pix_icon('i/checkpermissions', new \lang_string('checkpermissions', 'role')),
'string' => new \lang_string('checkpermissions', 'role')
);
}

// Context locking.
if (!empty($CFG->contextlocking) && has_capability('moodle/site:managecontextlocks', $category->get_context())) {
$parentcontext = $category->get_context()->get_parent_context();
Expand Down Expand Up @@ -351,6 +338,16 @@ public static function get_category_listitem_actions(\core_course_category $cate
}
}

// Content bank.
if ($category->has_contentbank()) {
$url = new \moodle_url('/contentbank/index.php', ['contextid' => $category->get_context()->id]);
$actions['contentbank'] = [
'url' => $url,
'icon' => new \pix_icon('i/contentbank', ''),
'string' => get_string('contentbank')
];
}

return $actions;
}

Expand Down
17 changes: 16 additions & 1 deletion course/classes/management_renderer.php
Expand Up @@ -64,12 +64,16 @@ public function enhance_management_interface() {
/**
* Displays a heading for the management pages.
*
* @deprecated since Moodle 4.0. This is now handled/replaced with the tertiary navigation
* @todo Final deprecation MDL-73975
* @param string $heading The heading to display
* @param string|null $viewmode The current view mode if there are options.
* @param int|null $categoryid The currently selected category if there is one.
* @return string
*/
public function management_heading($heading, $viewmode = null, $categoryid = null) {
debugging('management_heading() is deprecated. Use the class manage_categories_action_bar instead.', DEBUG_DEVELOPER);

$html = html_writer::start_div('coursecat-management-header clearfix');
if (!empty($heading)) {
$html .= $this->heading($heading);
Expand Down Expand Up @@ -1294,11 +1298,13 @@ public function search_listitem_actions(core_course_list_element $course) {
/**
* Renders html to display a course search form
*
* @deprecated since Moodle 4.0. This is now handled within manage_categories_action_bar
* @todo Final deprecation MDL-73975
* @param string $value default value to populate the search field
* @return string
*/
public function course_search_form($value = '') {

debugging('course_search_form() is deprecated. Use the class manage_categories_action_bar instead.', DEBUG_DEVELOPER);
$data = [
'action' => new moodle_url('/course/management.php'),
'btnclass' => 'btn-primary',
Expand Down Expand Up @@ -1337,4 +1343,13 @@ public function accessible_skipto_links($displaycategorylisting, $displaycoursel
return $html;
}

/**
* Render the tertiary nav for the manage categories page.
*
* @param \core_course\output\manage_categories_action_bar $actionbar
* @return string The renderered template
*/
public function render_action_bar(\core_course\output\manage_categories_action_bar $actionbar): string {
return $this->render_from_template('core_course/manage_category_actionbar', $actionbar->export_for_template($this));
}
}
171 changes: 171 additions & 0 deletions course/classes/output/category_action_bar.php
@@ -0,0 +1,171 @@
<?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/>.

namespace core_course\output;

use context_coursecat;
use core_course_category;
use course_request;
use moodle_page;
use moodle_url;

/**
* Class responsible for generating the action bar (tertiary nav) elements in an individual category page
*
* @package core
* @copyright 2021 Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class category_action_bar extends manage_categories_action_bar {
/**
* @var object The current category we are referring to.
*/
protected $category;
/**
* Constructor category_action_bar
*
* @param moodle_page $page The page object
* @param object $category
* @param object|null $course The course that we are generating the nav for
* @param string|null $searchvalue
*/
public function __construct(moodle_page $page, object $category, ?object $course = null, ?string $searchvalue = null) {
$this->category = $category;
parent::__construct($page, 'courses', $course, $searchvalue);
}

/**
* Gets the url_select to be displayed in the participants page if available.
*
* @param \renderer_base $output
* @return object|null The content required to render the url_select
*/
protected function get_category_select(\renderer_base $output): ?object {
if (!$this->searchvalue && !core_course_category::is_simple_site()) {
$categories = core_course_category::make_categories_list();
if (count($categories) > 1) {
foreach ($categories as $id => $cat) {
$url = new moodle_url($this->page->url, ['categoryid' => $id]);
$options[$url->out()] = $cat;
}
$currenturl = new moodle_url($this->page->url, ['categoryid' => $this->category->id]);
$select = new \url_select($options, $currenturl, null);
$select->set_label(get_string('categories'), ['class' => 'sr-only']);
$select->class .= ' text-truncate w-100';
return $select->export_for_template($output);
}
}

return null;
}

/**
* Gets the additional options to be displayed within a 'More' dropdown in the tertiary navigation.
* The predefined order defined by UX is:
* - Add a course
* - Add a sub cat
* - Manage course
* - Request a course
* - Course pending approval
*
* @return array
*/
protected function get_additional_category_options(): array {
global $CFG, $DB;
if ($this->category->is_uservisible()) {
$context = get_category_or_system_context($this->category->id);
if (has_capability('moodle/course:create', $context)) {
$params = [
'category' => $this->category->id ?: $CFG->defaultrequestcategory,
'returnto' => $this->category->id ? 'category' : 'topcat'
];

$options[0] = [
'url' => new moodle_url('/course/edit.php', $params),
'string' => get_string('addnewcourse')
];
}

if (!empty($CFG->enablecourserequests)) {
// Display an option to request a new course.
if (course_request::can_request($context)) {
$params = [];
if ($context instanceof context_coursecat) {
$params['category'] = $context->instanceid;
}

$options[3] = [
'url' => new moodle_url('/course/request.php', $params),
'string' => get_string('requestcourse')
];
}

// Display the manage pending requests option.
if (has_capability('moodle/site:approvecourse', $context)) {
$disabled = !$DB->record_exists('course_request', array());
if (!$disabled) {
$options[4] = [
'url' => new moodle_url('/course/pending.php'),
'string' => get_string('coursespending')
];
}
}
}
}

if ($this->category->can_create_course() || $this->category->has_manage_capability()) {
// Add 'Manage' button if user has permissions to edit this category.
$options[2] = [
'url' => new moodle_url('/course/management.php', ['categoryid' => $this->category->id]),
'string' => get_string('managecourses')
];

if ($this->category->has_manage_capability()) {
$addsubcaturl = new moodle_url('/course/editcategory.php', array('parent' => $this->category->id));
$options[1] = [
'url' => $addsubcaturl,
'string' => get_string('addsubcategory')
];
}
}

// We have stored the options in a predefined order. Sort it based on index and return.
if (isset($options)) {
sort($options);
return ['options' => $options];
}

return [];
}

/**
* Export the content to be displayed on the category page.
*
* @param \renderer_base $output
* @return array Consists of the following:
* - categoryselect A list of available categories to be fed into a urlselect
* - search The course search form
* - additionaloptions Additional actions that can be performed in a category
*/
public function export_for_template(\renderer_base $output): array {
return [
'categoryselect' => $this->get_category_select($output),
'search' => $this->get_search_form(),
'additionaloptions' => $this->get_additional_category_options()
];
}

}

0 comments on commit f1959af

Please sign in to comment.