From efbd37dd7f493316f3632ec393fa873b7257a123 Mon Sep 17 00:00:00 2001 From: Johannes Burk Date: Sat, 11 Jun 2016 01:18:32 +0200 Subject: [PATCH 1/2] Use Messaging API instead of email_to_user() function --- db/messages.php | 40 +++++++++++++++++++++++ lang/en/enrol_apply.php | 10 ++++++ lib.php | 71 ++++++++++++++++++++++++++++++----------- notification.php | 64 +++++++++++++++++++++++++++++++++++++ version.php | 2 +- 5 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 db/messages.php create mode 100644 notification.php diff --git a/db/messages.php b/db/messages.php new file mode 100644 index 0000000..a86fbbb --- /dev/null +++ b/db/messages.php @@ -0,0 +1,40 @@ +. + +/** + * @package enrol_apply + * @copyright 2016 sudile GbR (http://www.sudile.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Johannes Burk + */ + +defined('MOODLE_INTERNAL') || die(); + +$messageproviders = array ( + // Notify teacher/manager that a student has applied for a course enrolment. + 'application' => array ( + 'capability' => 'enrol/apply:manageapplications' + ), + + // Notify student that his application was confirmed. + 'confirmation' => array (), + + // Notify student that his application was canceled. + 'cancelation' => array (), + + // Notify student that his application was deferred (put on a waiting list). + 'waitinglist' => array (), +); diff --git a/lang/en/enrol_apply.php b/lang/en/enrol_apply.php index 9c8e99d..4f6a3aa 100644 --- a/lang/en/enrol_apply.php +++ b/lang/en/enrol_apply.php @@ -53,6 +53,16 @@ $string['notify_desc'] = 'Define who gets notified about new enrolment applicati $string['sendmailtoteacher'] = 'Send email notification to teachers'; $string['sendmailtomanager'] = 'Send email notification to managers'; +$string['messageprovider:application'] = 'Course enrolment application notifications'; +$string['messageprovider:confirmation'] = 'Course enrolment application confirmation notifications'; +$string['messageprovider:cancelation'] = 'Course enrolment application cancelation notifications'; +$string['messageprovider:waitinglist'] = 'Course enrolment application defer notifications'; + +$string['newapplicationnotification'] = 'There is a new course enrolment application awaiting review.'; +$string['applicationconfirmednotification'] = 'Your course enrolment application was confirmed.'; +$string['applicationcancelednotification'] = 'Your course enrolment application was canceled.'; +$string['applicationdeferrednotification'] = 'Your course enrolment application was deferred (you are currently on the waiting list).'; + $string['confirmusers'] = 'Enrol Confirm'; $string['confirmusers_desc'] = 'Users in gray colored rows are on the waiting list.'; diff --git a/lib.php b/lib.php index 5cf85ab..194759b 100644 --- a/lib.php +++ b/lib.php @@ -230,9 +230,12 @@ class enrol_apply_plugin extends enrol_plugin { $this->update_user_enrol($instance, $userenrolment->userid, ENROL_USER_ACTIVE); $DB->delete_records('enrol_apply_applicationinfo', array('userenrolmentid' => $enrol)); - $subject = get_config('enrol_apply', 'confirmmailsubject'); - $body = get_config('enrol_apply', 'confirmmailcontent'); - $this->send_mail_to_applicant($instance, $userenrolment->userid, $subject, $body); + $this->notify_applicant( + $instance, + $userenrolment->userid, + 'confirmation', + get_config('enrol_apply', 'confirmmailsubject'), + get_config('enrol_apply', 'confirmmailcontent')); } } @@ -255,9 +258,12 @@ class enrol_apply_plugin extends enrol_plugin { $this->update_user_enrol($instance, $userenrolment->userid, ENROL_APPLY_USER_WAIT); - $subject = get_config('enrol_apply', 'waitmailsubject'); - $body = get_config('enrol_apply', 'waitmailcontent'); - $this->send_mail_to_applicant($instance, $userenrolment->userid, $subject, $body); + $this->notify_applicant( + $instance, + $userenrolment->userid, + 'waitinglist', + get_config('enrol_apply', 'waitmailsubject'), + get_config('enrol_apply', 'waitmailcontent')); } } } @@ -286,26 +292,41 @@ class enrol_apply_plugin extends enrol_plugin { $this->unenrol_user($instance, $userenrolment->userid); $DB->delete_records('enrol_apply_applicationinfo', array('userenrolmentid' => $enrol)); - $subject = get_config('enrol_apply', 'cancelmailsubject'); - $body = get_config('enrol_apply', 'cancelmailcontent'); - $this->send_mail_to_applicant($instance, $userenrolment->userid, $subject, $body); + $this->notify_applicant( + $instance, + $userenrolment->userid, + 'cancelation', + get_config('enrol_apply', 'cancelmailsubject'), + get_config('enrol_apply', 'cancelmailcontent')); } } - private function send_mail_to_applicant($instance, $userid, $subject, $body) { - global $DB; + private function notify_applicant($instance, $userid, $type, $subject, $content) { global $CFG; + require_once($CFG->dirroot.'/enrol/apply/notification.php'); + // Required for course_get_url() function. + require_once($CFG->dirroot.'/course/lib.php'); $course = get_course($instance->courseid); $user = core_user::get_user($userid); - $body = $this->update_mail_content($body, $course, $user); - $contact = core_user::get_support_user(); - email_to_user($user, $contact, $subject, html_to_text($body), $body); + $content = $this->update_mail_content($content, $course, $user); + + $message = new enrol_apply_notification( + $user, + core_user::get_support_user(), + $type, + $subject, + $content, + course_get_url($course)); + message_send($message); } private function send_application_notification($instance, $userid, $data) { global $CFG, $PAGE; + require_once($CFG->dirroot.'/enrol/apply/notification.php'); + // Required for course_get_url() function. + require_once($CFG->dirroot.'/course/lib.php'); $renderer = $PAGE->get_renderer('enrol_apply'); @@ -336,7 +357,7 @@ class enrol_apply_plugin extends enrol_plugin { $teachers = get_role_users($editingteacherrole->id, $context); $manageurl = new moodle_url("/enrol/apply/manage.php", array('id' => $instance->id)); - $body = $renderer->application_notification_mail_body( + $content = $renderer->application_notification_mail_body( $course, $user, $manageurl, @@ -344,7 +365,14 @@ class enrol_apply_plugin extends enrol_plugin { $standarduserfields, $extrauserfields); foreach ($teachers as $teacher) { - email_to_user($teacher, $contact, get_string('mailtoteacher_suject', 'enrol_apply'), html_to_text($body), $body); + $message = new enrol_apply_notification( + $teacher, + $contact, + 'application', + get_string('mailtoteacher_suject', 'enrol_apply'), + $content, + $manageurl); + message_send($message); } } @@ -356,7 +384,7 @@ class enrol_apply_plugin extends enrol_plugin { $managers = get_role_users($managerrole->id, $context); $manageurl = new moodle_url('/enrol/apply/manage.php'); - $body = $renderer->application_notification_mail_body( + $content = $renderer->application_notification_mail_body( $course, $user, $manageurl, @@ -364,7 +392,14 @@ class enrol_apply_plugin extends enrol_plugin { $standarduserfields, $extrauserfields); foreach ($managers as $manager) { - email_to_user($manager, $contact, get_string('mailtoteacher_suject', 'enrol_apply'), html_to_text($body), $body); + $message = new enrol_apply_notification( + $manager, + $contact, + 'application', + get_string('mailtoteacher_suject', 'enrol_apply'), + $content, + $manageurl); + message_send($message); } } } diff --git a/notification.php b/notification.php new file mode 100644 index 0000000..fce3894 --- /dev/null +++ b/notification.php @@ -0,0 +1,64 @@ +. + +/** + * @package enrol_apply + * @copyright 2016 sudile GbR (http://www.sudile.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Johannes Burk + */ + +defined('MOODLE_INTERNAL') || die(); + +class enrol_apply_notification extends \core\message\message { + public function __construct($to, $from, $type, $subject, $content, $url) { + $this->component = 'enrol_apply'; + + switch ($type) { + case 'application': + $this->name = 'application'; + $this->smallmessage = get_string('newapplicationnotification', 'enrol_apply'); + break; + case 'confirmation': + $this->name = 'confirmation'; + $this->smallmessage = get_string('applicationconfirmednotification', 'enrol_apply'); + break; + case 'cancelation': + $this->name = 'cancelation'; + $this->smallmessage = get_string('applicationcancelednotification', 'enrol_apply'); + break; + case 'waitinglist': + $this->name = 'waitinglist'; + $this->smallmessage = get_string('applicationdeferrednotification', 'enrol_apply'); + break; + default: + throw new invalid_parameter_exception('Invalid enrol_apply notification type.'); + break; + } + + $this->userfrom = $from; + $this->userto = $to; + + $this->subject = $subject; + $this->fullmessage = html_to_text($content); + $this->fullmessageformat = FORMAT_PLAIN; + $this->fullmessagehtml = $content; + + $this->notification = true; + $this->contexturl = $url; + $this->contexturlname = get_string('course'); + } +} diff --git a/version.php b/version.php index f78b896..52ed472 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2016060800; +$plugin->version = 2016060801; $plugin->requires = 2011080100; $plugin->maturity = MATURITY_STABLE; $plugin->release = 'Enrolment upon approval plugin Version 3.1-a'; From 3d278703ab89cf28cd87826160e9d697f73dfb76 Mon Sep 17 00:00:00 2001 From: Johannes Burk Date: Mon, 13 Jun 2016 19:03:39 +0200 Subject: [PATCH 2/2] Change notification settings and behaviour. * Replace global 'sendmailtoteacher' setting (checkbox) by 'notifycoursebased' (checkbox): default for new instances * Replace global 'sendmailtomanager' setting (checkbox) by 'notifyglobal' (multi-select): user based selection (users with 'manageapplications' capability in system context) * Replace instance notification setting (checkbox) by user based selection (multi-select): enrolled users with 'manageapplications' capability in course context * Upgrade process: * if 'sendmailtoteacher' was true, set 'notifycoursebased' true * if 'sendmailtomanager' was true, set 'notifyglobal' to "Everyone who can 'Manage apply enrolment'", "Nobody" otherwise * if instance based notification setting was set to true, set new user based setting to "Everyone who can 'Manage apply enrolment'", "Nobody" otherwise --- db/upgrade.php | 25 +++++++++++++ edit.php | 26 ++++++++++++-- edit_form.php | 12 +++++-- lang/en/enrol_apply.php | 6 ++-- lib.php | 78 ++++++++++++++++++++++++++++++----------- settings.php | 22 ++++++------ version.php | 2 +- 7 files changed, 133 insertions(+), 38 deletions(-) diff --git a/db/upgrade.php b/db/upgrade.php index 8587679..0801784 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -67,6 +67,31 @@ function xmldb_enrol_apply_upgrade($oldversion) { } } + if ($oldversion < 2016060803) { + // Convert old notification settings. + $enrolapply = enrol_get_plugin('apply'); + + $sendmailtoteacher = $enrolapply->get_config('sendmailtoteacher'); + $notifycoursebased = $sendmailtoteacher; + $enrolapply->set_config('notifycoursebased', $notifycoursebased); + $enrolapply->set_config('sendmailtoteacher', null); + + $sendmailtomanager = $enrolapply->get_config('sendmailtomanager'); + $notifyglobal = $sendmailtomanager ? '$@ALL@$' : ''; + $enrolapply->set_config('notifyglobal', $notifyglobal); + $enrolapply->set_config('sendmailtomanager', null); + + $instances = $DB->get_records('enrol', array('enrol' => 'apply')); + foreach ($instances as $instance) { + $sendmailtoteacher = $instance->customint3; + $notify = $sendmailtoteacher ? '$@ALL@$' : ''; + $instance->customtext2 = $notify; + $instance->customint3 = null; + $instance->customint4 = null; + $DB->update_record('enrol', $instance, true); + } + } + return true; } \ No newline at end of file diff --git a/edit.php b/edit.php index 1cf82c2..4bd2917 100644 --- a/edit.php +++ b/edit.php @@ -61,19 +61,39 @@ if ($instanceid) { $instance->courseid = $course->id; } +// Process notify setting for editing... +// Convert to array for use with multi-select element. +$notify = array('$@NONE@$'); +if ($instance->customtext2 != '') { + $notify = explode(',', $instance->customtext2); +} +$instance->notify = $notify; $mform = new enrol_apply_edit_form(null, array($instance, $plugin, $context)); if ($mform->is_cancelled()) { redirect($return); } else if ($data = $mform->get_data()) { + // Process notify setting for storing... + // Note: Mostly copied from admin_setting_users_with_capability::write_setting(). + $notify = $data->notify; + // If all is selected, remove any explicit options. + if (in_array('$@ALL@$', $notify)) { + $notify = array('$@ALL@$'); + } + // None never needs to be written to the DB. + if (in_array('$@NONE@$', $notify)) { + unset($notify[array_search('$@NONE@$', $notify)]); + } + // Convert back to string for storing in enrol table. + $data->customtext2 = implode(',', $notify); if ($instance->id) { $instance->status = $data->status; $instance->name = $data->name; $instance->customtext1 = $data->customtext1; + $instance->customtext2 = $data->customtext2; $instance->customint1 = $data->customint1; $instance->customint2 = $data->customint2; - $instance->customint3 = $data->customint3; $instance->roleid = $data->roleid; $instance->timemodified = time(); $DB->update_record('enrol', $instance); @@ -85,8 +105,8 @@ if ($mform->is_cancelled()) { 'roleid' => $data->roleid, 'customint1' => $data->customint1, 'customint2' => $data->customint2, - 'customint3' => $data->customint3, - 'customtext1' => $data->customtext1); + 'customtext1' => $data->customtext1, + 'customtext2' => $data->customtext2); $plugin->add_instance($course, $fields); } diff --git a/edit_form.php b/edit_form.php index 649a100..68d8b9d 100644 --- a/edit_form.php +++ b/edit_form.php @@ -60,7 +60,15 @@ class enrol_apply_edit_form extends moodleform { $mform->addElement('select', 'customint2', get_string('show_extra_user_profile', 'enrol_apply'), $options); $mform->setDefault('customint2', $plugin->get_config('customint2')); - $mform->addElement('advcheckbox', 'customint3', get_string('sendmailtoteacher', 'enrol_apply')); + $choices = array( + '$@NONE@$' => get_string('nobody'), + '$@ALL@$' => get_string('everyonewhocan', 'admin', get_capability_string('enrol/apply:manageapplications'))); + $users = get_enrolled_users($context, 'enrol/apply:manageapplications'); + foreach ($users as $userid => $user) { + $choices[$userid] = fullname($user); + } + $select = $mform->addElement('select', 'notify', get_string('notify_desc', 'enrol_apply'), $choices); + $select->setMultiple(true); $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); @@ -71,4 +79,4 @@ class enrol_apply_edit_form extends moodleform { $this->set_data($instance); } -} \ No newline at end of file +} diff --git a/lang/en/enrol_apply.php b/lang/en/enrol_apply.php index 4f6a3aa..12249b5 100644 --- a/lang/en/enrol_apply.php +++ b/lang/en/enrol_apply.php @@ -50,8 +50,10 @@ $string['cancelmailcontent_desc'] = 'Please use the following special marks to r $string['notify_heading'] = 'Notification settings'; $string['notify_desc'] = 'Define who gets notified about new enrolment applications.'; -$string['sendmailtoteacher'] = 'Send email notification to teachers'; -$string['sendmailtomanager'] = 'Send email notification to managers'; +$string['notifycoursebased'] = "New enrolment application notification (instance based, eg. course teachers)"; +$string['notifycoursebased_desc'] = "Default for new instances: Notify everyone who have the 'Manage apply enrolment' capability for the corresponding course (eg. teachers and managers)"; +$string['notifyglobal'] = "New enrolment application notification (global, eg. global managers and admins)"; +$string['notifyglobal_desc'] = "Define who gets notified about new enrolment applications for any course."; $string['messageprovider:application'] = 'Course enrolment application notifications'; $string['messageprovider:confirmation'] = 'Course enrolment application confirmation notifications'; diff --git a/lib.php b/lib.php index 194759b..0ea88ad 100644 --- a/lib.php +++ b/lib.php @@ -200,8 +200,7 @@ class enrol_apply_plugin extends enrol_plugin { $fields['roleid'] = $this->get_config('roleid', 0); $fields['customint1'] = $this->get_config('show_standard_user_profile'); $fields['customint2'] = $this->get_config('show_extra_user_profile'); - $fields['customint3'] = $this->get_config('sendmailtoteacher'); - $fields['customint4'] = $this->get_config('sendmailtomanager'); + $fields['customtext2'] = $this->get_config('notifycoursebased') ? '$@ALL@$' : ''; return $fields; } @@ -349,13 +348,9 @@ class enrol_apply_plugin extends enrol_plugin { $extrauserfields = $user->profile; } - // Send notification to Teachers? Instance depending. - if ($instance->customint3 == 1) { - $context = context_course::instance($instance->courseid); - $editingteacherroles = get_archetype_roles('editingteacher'); - $editingteacherrole = reset($editingteacherroles); - $teachers = get_role_users($editingteacherrole->id, $context); - + // Send notification to users with manageapplications in course context (instance depending)? + $courseuserstonotify = $this->get_notifycoursebased_users($instance); + if (!empty($courseuserstonotify)) { $manageurl = new moodle_url("/enrol/apply/manage.php", array('id' => $instance->id)); $content = $renderer->application_notification_mail_body( $course, @@ -364,9 +359,9 @@ class enrol_apply_plugin extends enrol_plugin { $data->applydescription, $standarduserfields, $extrauserfields); - foreach ($teachers as $teacher) { + foreach ($courseuserstonotify as $user) { $message = new enrol_apply_notification( - $teacher, + $user, $contact, 'application', get_string('mailtoteacher_suject', 'enrol_apply'), @@ -376,13 +371,12 @@ class enrol_apply_plugin extends enrol_plugin { } } - // Send notification to managers in system context? - if (get_config('enrol_apply', 'sendmailtomanager') == 1) { - $context = context_system::instance(); - $managerroles = get_archetype_roles('manager'); - $managerrole = reset($editingteacherroles); - $managers = get_role_users($managerrole->id, $context); - + // Send notification to users with manageapplications in system context? + $globaluserstonotify = $this->get_notifyglobal_users(); + $globaluserstonotify = array_udiff($globaluserstonotify, $courseuserstonotify, function($usera, $userb) { + return $usera->id == $userb->id ? 0 : -1; + }); + if (!empty($globaluserstonotify)) { $manageurl = new moodle_url('/enrol/apply/manage.php'); $content = $renderer->application_notification_mail_body( $course, @@ -391,9 +385,9 @@ class enrol_apply_plugin extends enrol_plugin { $data->applydescription, $standarduserfields, $extrauserfields); - foreach ($managers as $manager) { + foreach ($globaluserstonotify as $user) { $message = new enrol_apply_notification( - $manager, + $user, $contact, 'application', get_string('mailtoteacher_suject', 'enrol_apply'), @@ -404,6 +398,50 @@ class enrol_apply_plugin extends enrol_plugin { } } + /** + * Returns enrolled users of a course who should be notified about new course enrolment applications. + * + * Note: mostly copied from get_users_from_config() function in moodlelib.php. + * @param array $instance Enrol apply instance record. + * @return array Array of user IDs. + */ + public function get_notifycoursebased_users($instance) { + $value = $instance->customtext2; + if (empty($value) or $value === '$@NONE@$') { + return array(); + } + + $context = context_course::instance($instance->courseid); + + // We have to make sure that users still have the necessary capability, + // it should be faster to fetch them all first and then test if they are present + // instead of validating them one-by-one. + $users = get_enrolled_users($context, 'enrol/apply:manageapplications'); + + if ($value === '$@ALL@$') { + return $users; + } + + $result = array(); // Result in correct order. + $allowed = explode(',', $value); + foreach ($allowed as $uid) { + if (isset($users[$uid])) { + $user = $users[$uid]; + $result[$user->id] = $user; + } + } + + return $result; + } + + /** + * Returns users who should be notified about new course enrolment applications. + * @return array Array of user IDs. + */ + public function get_notifyglobal_users() { + return get_users_from_config($this->get_config('notifyglobal'), 'enrol/apply:manageapplications'); + } + private function update_mail_content($content, $course, $user) { $replace = array( 'firstname' => $user->firstname, diff --git a/settings.php b/settings.php index f58eb01..7f4601e 100644 --- a/settings.php +++ b/settings.php @@ -90,16 +90,12 @@ if ($ADMIN->fulltree) { 'enrol_apply_notify', get_string('notify_heading', 'enrol_apply'), get_string('notify_desc', 'enrol_apply'))); - $settings->add(new admin_setting_configcheckbox( - 'enrol_apply/sendmailtoteacher', - get_string('sendmailtoteacher', 'enrol_apply'), - '', - 0)); - $settings->add(new admin_setting_configcheckbox( - 'enrol_apply/sendmailtomanager', - get_string('sendmailtomanager', 'enrol_apply'), - '', - 0)); + $settings->add(new admin_setting_users_with_capability( + 'enrol_apply/notifyglobal', + get_string('notifyglobal', 'enrol_apply'), + get_string('notifyglobal_desc', 'enrol_apply'), + array(), + 'enrol/apply:manageapplications')); // Enrol instance defaults... $settings->add(new admin_setting_heading('enrol_manual_defaults', @@ -130,6 +126,12 @@ if ($ADMIN->fulltree) { $settings->add(new admin_setting_configselect('enrol_apply/roleid', get_string('defaultrole', 'role'), '', $student->id, $options)); } + + $settings->add(new admin_setting_configcheckbox( + 'enrol_apply/notifycoursebased', + get_string('notifycoursebased', 'enrol_apply'), + get_string('notifycoursebased_desc', 'enrol_apply'), + 0)); } if ($hassiteconfig) { // Needs this condition or there is error on login page. diff --git a/version.php b/version.php index 52ed472..05a188c 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2016060801; +$plugin->version = 2016060803; $plugin->requires = 2011080100; $plugin->maturity = MATURITY_STABLE; $plugin->release = 'Enrolment upon approval plugin Version 3.1-a';