Select Git revision
-
Dennis Ahrens authoredDennis Ahrens authored
lib.php 9.98 KiB
<?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/>.
/**
* @package local_sembasednav
* @copyright 2020 Julian Wendling, Hochschule Hannover <julian.wendling@stud.hs-hannover.de>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function local_sembasednav_extend_navigation(global_navigation $navigation)
{
global $PAGE, $CFG;
$myCoursesNode = $navigation->find('mycourses', global_navigation::TYPE_ROOTNODE);
$myCoursesChildNodes = $myCoursesNode->get_children_key_list();
$maxSemesterNodes = get_config('sembasednav', 'setting_nodescount');
$openFirstSemester = get_config('sembasednav', 'setting_openfirstnode');
$semesterDescending = get_config('sembasednav', 'setting_semesterorder');
$specialNodesFirst = get_config('sembasednav', 'setting_specialNodes');
// Register JS to close all child nodes from root node (mycourse)
$PAGE->requires->js_call_amd('local_sembasednav/sembasednav', 'closeAllChildNodes', [$myCoursesNode->key]);
try {
$courses = enrol_get_my_courses();
} catch (Exception $e) {
echo $e->getMessage();
$courses = [];
}
// Removes courses that are shown by default
foreach ($myCoursesChildNodes as $cn) {
$myCoursesNode->find($cn, null)->showinflatnavigation = false;
}
// Nodes that are excluded from max semester count - will always be shown
$noSemesterAssignedName = get_config('sembasednav', 'setting_nosemestername');
$specialNodes = ["Semesterunabhängig", $noSemesterAssignedName];
$specialNodesList = [];
$mySemesters = [];
// Sort semester depending on setting
if ($semesterDescending == 0) {
// Descending
usort($courses, function ($a, $b) {
$aId = get_semester_id($a->id);
$bId = get_semester_id($b->id);
return strcasecmp($bId, $aId);
});
} else {
// Ascending
usort($courses, function ($a, $b) {
$aId = get_semester_id($a->id);
$bId = get_semester_id($b->id);
return strcasecmp($aId, $bId);
});
}
// Assign all modules and semesters
foreach ($courses as $c) {
$semesterName = get_semester_name($c->id);
$courseName = empty($CFG->navshowfullcoursenames) ? $c->shortname : $c->fullname;
if (in_array($semesterName, $specialNodes, true)) {
$specialNodesList[$semesterName][] = $courseName;
} else {
if (count($mySemesters) >= $maxSemesterNodes) {
continue;
}
$mySemesters[$semesterName][] = $courseName;
}
}
if ($specialNodesFirst == 0)
add_semester_nodes($specialNodesList, $myCoursesNode);
// Add all semester nodes
add_semester_nodes($mySemesters, $myCoursesNode);
if ($openFirstSemester)
open_semester_node(array_keys($mySemesters)[0] , $myCoursesNode);
// Add all special nodes
if ($specialNodesFirst == 1)
add_semester_nodes($specialNodesList, $myCoursesNode);
// Sorts course node alphabetically
usort($courses, function ($a, $b) {
$aId = $a->shortname;
$bId = $b->shortname;
return strcasecmp($aId, $bId);
});
// Creates all course nodes and assigns them to their semester node
foreach ($courses as $c) {
$semesterName = get_semester_name($c->id);
$semesterKey = create_node_key($semesterName);
$semesterNode = $navigation->find($semesterKey, null);
// Can't find semester of current course
if (!$semesterNode) {
continue;
}
$courseName = empty($CFG->navshowfullcoursenames) ? $c->shortname : $c->fullname;
$courseKey = create_node_key($courseName);
$courseNode = navigation_node::create($courseName, new moodle_url('/course/view.php', array('id' => $c->id)), global_navigation::TYPE_COURSE, $courseName, $courseKey, new pix_icon('i/course', 'grades'));
$courseNode->showinflatnavigation = true;
$courseNode->add_class('p-l-3');
if (!$semesterNode->forceopen)
$courseNode->add_class('localboostnavigationcollapsedchild');
$semesterNode->add_node($courseNode);
// Open semester node of active course
if ($courseNode->isactive) {
open_semester_node($semesterNode->text , $myCoursesNode);
}
}
}
/**
* Adds all semester nodes to given parent node and registers
* them for collapse navigation js
* @param array $semesterList
* @param $parentNode
* @throws coding_exception
* @throws dml_exception
*/
function add_semester_nodes(array $semesterList, $parentNode)
{
global $PAGE;
$collapsenodesforjs = [];
foreach ($semesterList as $key => $value) {
$semesterNode = create_semester_node($key);
if (!in_array($semesterNode->key, $collapsenodesforjs)) {
$collapsenodesforjs[] = $semesterNode->key;
}
$parentNode->add_node($semesterNode);
}
// Apply collapse navigation js to every semester
if (!empty($collapsenodesforjs)) {
$PAGE->requires->js_call_amd('local_boostnavigation/collapsenavdrawernodes', 'init',
[$collapsenodesforjs, []]);
foreach ($collapsenodesforjs as $node) {
user_preference_allow_ajax_update('local_boostnavigation-collapse_' . $node . 'node', PARAM_BOOL);
}
}
}
/**
* @param $semesterKey
* @param $myCourseNode
*/
function open_semester_node($semesterKey, $myCourseNode)
{
if (empty($semesterKey))
return;
$key = create_node_key($semesterKey);
$semesterNode = $myCourseNode->find($key, global_navigation::NODETYPE_BRANCH);
$semesterNode->forceopen = true;
$semesterNode->remove_class('localboostnavigationcollapsedparent');
foreach ($semesterNode->get_children_key_list() as $c) {
$node = $myCourseNode->find($c, null);
$node->remove_class('localboostnavigationcollapsedchild');
}
}
/**
* Creates a semester node with needed css classes for collapse navigation js
* @param string $semesterName
* @return navigation_node
* @throws coding_exception
* @throws dml_exception
*/
function create_semester_node(string $semesterName)
{
$localBoostnavigationConfig = get_config('local_boostnavigation');
$userprefmycoursesnode = get_user_preferences('local_boostnavigation-collapse_mycoursesnode',
$localBoostnavigationConfig->collapsemycoursesnodedefault);
$semesterKey = create_node_key($semesterName);
$semesterNode = navigation_node::create($semesterName, new moodle_url('/course/view.php', null), global_navigation::NODETYPE_BRANCH, null, $semesterKey, null);
$semesterNode->showinflatnavigation = true;
$semesterNode->add_class('localboostnavigationcollapsibleparent');
$semesterNode->add_class('localboostnavigationcollapsedparent');
if ($userprefmycoursesnode == 1) {
$semesterNode->add_class('localboostnavigationcollapsedchild');
}
return $semesterNode;
}
/**
* Creates a whitespace and slash free semester key
* @param string $semesterName
* @return string
*/
function create_node_key(string $semesterName)
{
return "node-" . str_replace([" ", "/"], "-", $semesterName);
}
/**
* Returns semester name of given course id.
* If no semester is found, return no semester assigned name.
* @param int $id
* @return string
*/
function get_semester_name(int $id)
{
global $DB;
$noSemesterAssigned = get_config('sembasednav', 'setting_nosemestername');
$semesterName = '';
try {
$semFieldName = $DB->get_record('customfield_field', array('type' => 'semester'), '*', MUST_EXIST);
} catch (Exception $e) {
return $noSemesterAssigned;
}
try {
$allCustomFields = get_course_metadata($id);
$semesterField = $allCustomFields[$semFieldName->shortname];
$semesterValue = preg_replace('/[^0-9]/', '', $semesterField); // extract semester int from string
$semesterName = \customfield_semester\data_controller::get_name_for_semester((int)$semesterValue);
} catch (Exception $e) {
}
return empty($semesterName) || $semesterName === '' ? $noSemesterAssigned : $semesterName;
}
/**
* @param int $id
* @return string
*/
function get_semester_id(int $id)
{
global $DB;
$semesterValue = '';
try {
$semFieldName = $DB->get_record('customfield_field', array('type' => 'semester'), '*', MUST_EXIST);
} catch (Exception $e) {
return 0;
}
try {
$allCustomFields = get_course_metadata($id);
$semesterField = $allCustomFields[$semFieldName->shortname];
$semesterValue = preg_replace('/[^0-9]/', '', $semesterField); // extract semester int from string
} catch (Exception $e) {
}
return empty($semesterValue) || $semesterValue === '' ? 0 : $semesterValue;
}
// https://docs.moodle.org/dev/Custom_fields_API#Example_code_for_course_custom_fields
/**
* Used to access course semester field
* @param $courseid
* @return array
* @throws moodle_exception
*/
function get_course_metadata($courseid)
{
$handler = \core_customfield\handler::get_handler('core_course', 'course');
$data = $handler->get_instance_data($courseid);
$metadata = [];
foreach ($data as $d) {
if (empty($d->get_value())) {
continue;
}
$cat = $d->get_field()->get_category()->get('name');
$metadata[$d->get_field()->get('shortname')] = $cat . ': ' . $d->get_value();
}
return $metadata;
}