2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * This page contains navigation hooks for learning plans.
21 * @copyright 2015 Damyon Wiese
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die();
26 require_once($CFG->libdir . '/externallib.php');
29 * This function extends the course navigation
31 * @param navigation_node $navigation The navigation node to extend
32 * @param stdClass $course The course to object for the tool
33 * @param context $coursecontext The context of the course
35 function tool_lp_extend_navigation_course($navigation, $course, $coursecontext) {
36 if (!\tool_lp\api::is_enabled()) {
40 // Just a link to course report.
41 $title = get_string('coursecompetencies', 'tool_lp');
42 $path = new moodle_url("/admin/tool/lp/coursecompetencies.php", array('courseid' => $course->id));
43 $settingsnode = navigation_node::create($title,
45 navigation_node::TYPE_SETTING,
48 new pix_icon('competency', '', 'tool_lp'));
49 if (isset($settingsnode)) {
50 $navigation->add_node($settingsnode);
56 * This function extends the user navigation.
58 * @param navigation_node $navigation The navigation node to extend
59 * @param stdClass $user The user object
60 * @param context_user $usercontext The user context
61 * @param stdClass $course The course object
62 * @param context_course $coursecontext The context of the course
64 function tool_lp_extend_navigation_user($navigation, $user, $usercontext, $course, $coursecontext) {
65 if (!\tool_lp\api::is_enabled()) {
69 if (\tool_lp\plan::can_read_user($user->id)) {
70 $node = $navigation->add(get_string('learningplans', 'tool_lp'),
71 new moodle_url('/admin/tool/lp/plans.php', array('userid' => $user->id)));
73 if (\tool_lp\user_evidence::can_read_user($user->id)) {
74 $node->add(get_string('userevidence', 'tool_lp'),
75 new moodle_url('/admin/tool/lp/user_evidence_list.php', array('userid' => $user->id)));
82 * Add nodes to myprofile page.
84 * @param \core_user\output\myprofile\tree $tree Tree object
85 * @param stdClass $user user object
86 * @param bool $iscurrentuser
87 * @param stdClass $course Course object
91 function tool_lp_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
92 if (!\tool_lp\api::is_enabled()) {
94 } else if (!\tool_lp\plan::can_read_user($user->id)) {
98 $url = new moodle_url('/admin/tool/lp/plans.php', array('userid' => $user->id));
99 $node = new core_user\output\myprofile\node('miscellaneous', 'learningplans',
100 get_string('learningplans', 'tool_lp'), null, $url);
101 $tree->add_node($node);
107 * This function extends the category navigation to add learning plan links.
109 * @param navigation_node $navigation The navigation node to extend
110 * @param context $coursecategorycontext The context of the course category
112 function tool_lp_extend_navigation_category_settings($navigation, $coursecategorycontext) {
113 if (!\tool_lp\api::is_enabled()) {
117 // We check permissions before renderring the links.
118 $templatereadcapability = \tool_lp\template::can_read_context($coursecategorycontext);
119 $competencyreadcapability = \tool_lp\competency_framework::can_read_context($coursecategorycontext);
120 if (!$templatereadcapability && !$competencyreadcapability) {
124 // The link to the learning plan page.
125 if ($templatereadcapability) {
126 $title = get_string('templates', 'tool_lp');
127 $path = new moodle_url("/admin/tool/lp/learningplans.php", array('pagecontextid' => $coursecategorycontext->id));
128 $settingsnode = navigation_node::create($title,
130 navigation_node::TYPE_SETTING,
133 new pix_icon('competency', '', 'tool_lp'));
134 if (isset($settingsnode)) {
135 $navigation->add_node($settingsnode);
139 // The link to the competency frameworks page.
140 if ($competencyreadcapability) {
141 $title = get_string('competencyframeworks', 'tool_lp');
142 $path = new moodle_url("/admin/tool/lp/competencyframeworks.php", array('pagecontextid' => $coursecategorycontext->id));
143 $settingsnode = navigation_node::create($title,
145 navigation_node::TYPE_SETTING,
148 new pix_icon('competency', '', 'tool_lp'));
149 if (isset($settingsnode)) {
150 $navigation->add_node($settingsnode);
159 * @param stdClass $course The course object.
160 * @param stdClass $cm The cm object.
161 * @param context $context The context object.
162 * @param string $filearea The file area.
163 * @param array $args List of arguments.
164 * @param bool $forcedownload Whether or not to force the download of the file.
165 * @param array $options Array of options.
168 function tool_lp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
171 if (!\tool_lp\api::is_enabled()) {
175 $fs = get_file_storage();
178 $itemid = array_shift($args);
179 $filename = array_shift($args);
180 $filepath = $args ? '/' .implode('/', $args) . '/' : '/';
182 if ($filearea == 'userevidence' && $context->contextlevel == CONTEXT_USER) {
183 if (\tool_lp\user_evidence::can_read_user($context->instanceid)) {
184 $file = $fs->get_file($context->id, 'tool_lp', $filearea, $itemid, $filepath, $filename);
192 send_stored_file($file, null, 0, $forcedownload);
196 * Hook when a comment is added.
198 * @param stdClass $comment The comment.
199 * @param stdClass $params The parameters.
202 function tool_lp_comment_add($comment, $params) {
205 if (!\tool_lp\api::is_enabled()) {
209 if ($params->commentarea == 'user_competency') {
210 $uc = new \tool_lp\user_competency($params->itemid);
212 // Message both the user and the reviewer, except when they are the author of the message.
213 $recipients = array($uc->get_userid());
214 if ($uc->get_reviewerid()) {
215 $recipients[] = $uc->get_reviewerid();
217 $recipients = array_diff($recipients, array($comment->userid));
218 if (empty($recipients)) {
224 if ($USER->id != $comment->userid) {
225 $user = core_user::get_user($comment->userid);
227 $fullname = fullname($user);
229 // Get the competency.
230 $competency = $uc->get_competency();
231 $competencyname = format_string($competency->get_shortname(), true, array('context' => $competency->get_context()));
233 // We want to send a message for one plan, trying to find an active one first, or the last modified one.
235 $plans = $uc->get_plans();
236 foreach ($plans as $candidate) {
237 if ($candidate->get_status() == \tool_lp\plan::STATUS_ACTIVE) {
241 } else if (!empty($plan) && $plan->get_timemodified() < $candidate->get_timemodified()) {
244 } else if (empty($plan)) {
250 // TODO MDL-52749 Replace the link to the plan with the user competency page.
252 $urlname = get_string('userplans', 'tool_lp');
253 $url = new moodle_url('/admin/tool/lp/plans.php', array('userid' => $uc->get_userid()));
255 $urlname = $competencyname;
256 $url = new moodle_url('/admin/tool/lp/user_competency_in_plan.php', array(
257 'userid' => $uc->get_userid(),
258 'competencyid' => $uc->get_competencyid(),
259 'planid' => $plan->get_id()
263 // Construct the message content.
264 $fullmessagehtml = get_string('usercommentedonacompetencyhtml', 'tool_lp', array(
265 'fullname' => $fullname,
266 'competency' => $competencyname,
267 'comment' => format_text($comment->content, $comment->format, array('context' => $params->context->id)),
268 'url' => $url->out(true),
269 'urlname' => $urlname,
271 if ($comment->format == FORMAT_PLAIN || $comment->format == FORMAT_MOODLE) {
272 $format = FORMAT_MOODLE;
273 $fullmessage = get_string('usercommentedonacompetency', 'tool_lp', array(
274 'fullname' => $fullname,
275 'competency' => $competencyname,
276 'comment' => $comment->content,
277 'url' => $url->out(false),
280 $format = FORMAT_HTML;
281 $fullmessage = $fullmessagehtml;
284 $message = new \core\message\message();
285 $message->component = 'tool_lp';
286 $message->name = 'user_competency_comment';
287 $message->notification = 1;
288 $message->userfrom = core_user::get_noreply_user();
289 $message->subject = get_string('usercommentedonacompetencysubject', 'tool_lp', $fullname);
290 $message->fullmessage = $fullmessage;
291 $message->fullmessageformat = $format;
292 $message->fullmessagehtml = $fullmessagehtml;
293 $message->smallmessage = get_string('usercommentedonacompetencysmall', 'tool_lp', array(
294 'fullname' => $fullname,
295 'competency' => $competencyname,
297 $message->contexturl = $url->out(false);
298 $message->contexturlname = $urlname;
300 // Message each recipient.
301 foreach ($recipients as $recipient) {
302 $msgcopy = clone($message);
303 $msgcopy->userto = $recipient;
304 message_send($msgcopy);
307 } else if ($params->commentarea == 'plan') {
308 $plan = new \tool_lp\plan($params->itemid);
310 // Message both the user and the reviewer, except when they are the author of the message.
311 $recipients = array($plan->get_userid());
312 if ($plan->get_reviewerid()) {
313 $recipients[] = $plan->get_reviewerid();
315 $recipients = array_diff($recipients, array($comment->userid));
316 if (empty($recipients)) {
322 if ($USER->id != $comment->userid) {
323 $user = core_user::get_user($comment->userid);
326 $fullname = fullname($user);
327 $planname = format_string($plan->get_name(), true, array('context' => $plan->get_context()));
328 $urlname = $planname;
329 $url = new moodle_url('/admin/tool/lp/plan.php', array(
330 'id' => $plan->get_id()
333 // Construct the message content.
334 $fullmessagehtml = get_string('usercommentedonaplanhtml', 'tool_lp', array(
335 'fullname' => $fullname,
337 'comment' => format_text($comment->content, $comment->format, array('context' => $params->context->id)),
338 'url' => $url->out(true),
339 'urlname' => $urlname,
341 if ($comment->format == FORMAT_PLAIN || $comment->format == FORMAT_MOODLE) {
342 $format = FORMAT_MOODLE;
343 $fullmessage = get_string('usercommentedonaplan', 'tool_lp', array(
344 'fullname' => $fullname,
346 'comment' => $comment->content,
347 'url' => $url->out(false),
350 $format = FORMAT_HTML;
351 $fullmessage = $fullmessagehtml;
354 $message = new \core\message\message();
355 $message->component = 'tool_lp';
356 $message->name = 'plan_comment';
357 $message->notification = 1;
358 $message->userfrom = core_user::get_noreply_user();
359 $message->subject = get_string('usercommentedonaplansubject', 'tool_lp', $fullname);
360 $message->fullmessage = $fullmessage;
361 $message->fullmessageformat = $format;
362 $message->fullmessagehtml = $fullmessagehtml;
363 $message->smallmessage = get_string('usercommentedonaplansmall', 'tool_lp', array(
364 'fullname' => $fullname,
367 $message->contexturl = $url->out(false);
368 $message->contexturlname = $urlname;
370 // Message each recipient.
371 foreach ($recipients as $recipient) {
372 $msgcopy = clone($message);
373 $msgcopy->userto = $recipient;
374 message_send($msgcopy);
380 * Return the permissions of for the comments.
382 * @param stdClass $params The parameters.
385 function tool_lp_comment_permissions($params) {
386 if (!\tool_lp\api::is_enabled()) {
387 return array('post' => false, 'view' => false);
390 if ($params->commentarea == 'user_competency') {
391 $uc = new \tool_lp\user_competency($params->itemid);
392 if ($uc->can_read()) {
393 return array('post' => $uc->can_comment(), 'view' => $uc->can_read_comments());
395 } else if ($params->commentarea == 'plan') {
396 $plan = new \tool_lp\plan($params->itemid);
397 if ($plan->can_read()) {
398 return array('post' => $plan->can_comment(), 'view' => $plan->can_read_comments());
402 return array('post' => false, 'view' => false);
406 * Validates comments.
408 * @param stdClass $params The parameters.
411 function tool_lp_comment_validate($params) {
412 if (!\tool_lp\api::is_enabled()) {
416 if ($params->commentarea == 'user_competency') {
417 if (!\tool_lp\user_competency::record_exists($params->itemid)) {
421 } else if ($params->commentarea == 'plan') {
422 if (!\tool_lp\plan::record_exists($params->itemid)) {
431 * Inject the competencies elements into all moodle module settings forms.
433 * @param moodleform $formwrapper The moodle quickforms wrapper object.
434 * @param MoodleQuickForm $mform The actual form object (required to modify the form).
436 function tool_lp_coursemodule_standard_elements($formwrapper, $mform) {
437 global $CFG, $COURSE;
439 if (!\tool_lp\api::is_enabled()) {
441 } else if (!has_capability('moodle/competency:coursecompetencymanage', $formwrapper->get_context())) {
445 $mform->addElement('header', 'competenciessection', get_string('competencies', 'tool_lp'));
447 MoodleQuickForm::registerElementType('course_competencies',
448 "$CFG->dirroot/admin/tool/lp/classes/course_competencies_form_element.php",
449 'tool_lp_course_competencies_form_element');
451 if ($cm = $formwrapper->get_coursemodule()) {
455 'courseid' => $COURSE->id,
458 $mform->addElement('course_competencies', 'competencies', get_string('modcompetencies', 'tool_lp'), $options);
459 $mform->addHelpButton('competencies', 'modcompetencies', 'tool_lp');
460 MoodleQuickForm::registerElementType('course_competency_rule',
461 "$CFG->dirroot/admin/tool/lp/classes/course_competency_rule_form_element.php",
462 'tool_lp_course_competency_rule_form_element');
463 // Reuse the same options.
464 $mform->addElement('course_competency_rule', 'competency_rule', get_string('uponcoursemodulecompletion', 'tool_lp'), $options);
468 * Hook the add/edit of the course module.
470 * @param stdClass $data Data from the form submission.
471 * @param stdClass $course The course.
473 function tool_lp_coursemodule_edit_post_actions($data, $course) {
474 if (!\tool_lp\api::is_enabled()) {
478 // It seems like the form did not contain any of the form fields, we can return.
479 if (!isset($data->competency_rule) && !isset($data->competencies)) {
483 // We bypass the API here and go direct to the persistent layer - because we don't want to do permission
484 // checks here - we need to load the real list of existing course module competencies.
485 $existing = \tool_lp\course_module_competency::list_course_module_competencies($data->coursemodule);
487 $existingids = array();
488 foreach ($existing as $cmc) {
489 array_push($existingids, $cmc->get_competencyid());
492 $newids = isset($data->competencies) ? $data->competencies : array();
494 $removed = array_diff($existingids, $newids);
495 $added = array_diff($newids, $existingids);
497 foreach ($removed as $removedid) {
498 \tool_lp\api::remove_competency_from_course_module($data->coursemodule, $removedid);
500 foreach ($added as $addedid) {
501 \tool_lp\api::add_competency_to_course_module($data->coursemodule, $addedid);
504 if (isset($data->competency_rule)) {
505 // Now update the rules for each course_module_competency.
506 $current = \tool_lp\api::list_course_module_competencies_in_course_module($data->coursemodule);
507 foreach ($current as $coursemodulecompetency) {
508 \tool_lp\api::set_course_module_competency_ruleoutcome($coursemodulecompetency, $data->competency_rule);
516 * Reports whether a scale is being used in the plugin.
518 * @param int $scaleid The scale ID.
521 function tool_lp_scale_used_anywhere($scaleid) {
522 return \tool_lp\api::is_scale_used_anywhere($scaleid);