From c6ebb024f28794f6aba406a9496597923635e6fb Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Fri, 1 Feb 2019 12:39:00 +0100 Subject: [PATCH] MDL-64337 tool_mobile: Add app promotion text in email notifications --- admin/tool/mobile/lang/en/tool_mobile.php | 1 + admin/tool/mobile/lib.php | 68 +++++++++++++++++--- admin/tool/mobile/tests/api_test.php | 76 +++++++++++++++++++++++ 3 files changed, 137 insertions(+), 8 deletions(-) diff --git a/admin/tool/mobile/lang/en/tool_mobile.php b/admin/tool/mobile/lang/en/tool_mobile.php index f2d08accf68f3..a373878529610 100644 --- a/admin/tool/mobile/lang/en/tool_mobile.php +++ b/admin/tool/mobile/lang/en/tool_mobile.php @@ -86,6 +86,7 @@ $string['offlineuse'] = 'Offline use'; $string['pluginname'] = 'Moodle app tools'; $string['pluginnotenabledorconfigured'] = 'Plugin not enabled or configured.'; +$string['readingthisemailgettheapp'] = 'Reading this in your e-mail? Download the mobile app and receive notifications on your mobile devices.'; $string['remoteaddons'] = 'Remote add-ons'; $string['selfsignedoruntrustedcertificatewarning'] = 'It seems that the HTTPS certificate is self-signed or not trusted. The mobile app will only work with trusted sites.'; $string['setuplink'] = 'App download page'; diff --git a/admin/tool/mobile/lib.php b/admin/tool/mobile/lib.php index 56465103dd1f5..74b3c0b367176 100644 --- a/admin/tool/mobile/lib.php +++ b/admin/tool/mobile/lib.php @@ -86,6 +86,25 @@ function tool_mobile_create_app_download_url() { return $downloadurl; } +/** + * Checks if the given user has a mobile token (has used recently the app). + * + * @param int $userid the user to check + * @return bool true if the user has a token, false otherwise. + */ +function tool_mobile_user_has_token($userid) { + global $DB; + + $sql = "SELECT 1 + FROM {external_tokens} t, {external_services} s + WHERE t.externalserviceid = s.id + AND s.enabled = 1 + AND s.shortname IN ('moodle_mobile_app', 'local_mobile') + AND t.userid = ?"; + + return $DB->record_exists_sql($sql, [$userid]); +} + /** * User profile page callback. * @@ -97,7 +116,7 @@ function tool_mobile_create_app_download_url() { * @return void Return if the mobile web services setting is disabled or if not the current user. */ function tool_mobile_myprofile_navigation(\core_user\output\myprofile\tree $tree, $user, $iscurrentuser) { - global $CFG, $DB; + global $CFG; if (empty($CFG->enablemobilewebservice)) { return; @@ -111,13 +130,7 @@ function tool_mobile_myprofile_navigation(\core_user\output\myprofile\tree $tree return; } - $sql = "SELECT 1 - FROM {external_tokens} t, {external_services} s - WHERE t.externalserviceid = s.id - AND s.enabled = 1 - AND s.shortname IN ('moodle_mobile_app', 'local_mobile') - AND t.userid = ?"; - $userhastoken = $DB->record_exists_sql($sql, [$user->id]); + $userhastoken = tool_mobile_user_has_token($user->id); $mobilecategory = new core_user\output\myprofile\category('mobile', get_string('mobileapp', 'tool_mobile'), 'loginactivity'); @@ -147,3 +160,42 @@ function tool_mobile_standard_footer_html() { } return $output; } + +/** + * Callback to be able to change a message/notification data per processor. + * + * @param str $procname processor name + * @param stdClass $data message or notification data + */ +function tool_mobile_pre_processor_message_send($procname, $data) { + global $CFG; + + if (empty($CFG->enablemobilewebservice)) { + return; + } + + if (empty($data->userto)) { + return; + } + + // Only hack email. + if ($procname == 'email') { + + // Send a message only when there is an HTML version of the email, mobile services are enabled, + // the user receiving the message has not used the app and there is an app download URL set. + if (empty($data->fullmessagehtml)) { + return; + } + + if (!$url = tool_mobile_create_app_download_url()) { + return; + } + + $userto = is_object($data->userto) ? $data->userto->id : $data->userto; + if (tool_mobile_user_has_token($userto)) { + return; + } + + $data->fullmessagehtml .= html_writer::tag('p', get_string('readingthisemailgettheapp', 'tool_mobile', $url->out())); + } +} diff --git a/admin/tool/mobile/tests/api_test.php b/admin/tool/mobile/tests/api_test.php index f5ee43474f4d1..4d9a07dabe0f8 100644 --- a/admin/tool/mobile/tests/api_test.php +++ b/admin/tool/mobile/tests/api_test.php @@ -94,4 +94,80 @@ public function test_get_potential_config_issues() { $this->assertTrue(in_array($issue[0], $expectedissues)); } } + + /** + * Test pre_processor_message_send callback. + */ + public function test_pre_processor_message_send_callback() { + global $DB, $CFG; + require_once($CFG->libdir . '/externallib.php'); + $this->preventResetByRollback(); + $this->resetAfterTest(); + + // Enable mobile services and required configuration. + $CFG->enablewebservices = 1; + $CFG->enablemobilewebservice = 1; + $mobileappdownloadpage = 'htt://mobileappdownloadpage'; + set_config('setuplink', $mobileappdownloadpage, 'tool_mobile'); + + $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); + $user2 = $this->getDataGenerator()->create_user(); + set_config('allowedemaildomains', 'example.com'); + + $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); + set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + + // Extra content for all types of messages. + $message = new \core\message\message(); + $message->courseid = 1; + $message->component = 'moodle'; + $message->name = 'instantmessage'; + $message->userfrom = $user1; + $message->userto = $user2; + $message->subject = 'message subject 1'; + $message->fullmessage = 'message body'; + $message->fullmessageformat = FORMAT_MARKDOWN; + $message->fullmessagehtml = '

message body

'; + $message->smallmessage = 'small message'; + $message->notification = '0'; + $content = array('*' => array('header' => ' test ', 'footer' => ' test ')); + $message->set_additional_content('email', $content); + + $sink = $this->redirectEmails(); + $messageid = message_send($message); + $emails = $sink->get_messages(); + $this->assertCount(1, $emails); + $email = reset($emails); + + // Check we got the promotion text. + $this->assertContains($mobileappdownloadpage, quoted_printable_decode($email->body)); + $sink->clear(); + + // Disable mobile so we don't get mobile promotions. + $CFG->enablemobilewebservice = 0; + $messageid = message_send($message); + $emails = $sink->get_messages(); + $this->assertCount(1, $emails); + $email = reset($emails); + // Check we don't get the promotion text. + $this->assertNotContains($mobileappdownloadpage, quoted_printable_decode($email->body)); + $sink->clear(); + + // Enable mobile again and set current user mobile token so we don't get mobile promotions. + $CFG->enablemobilewebservice = 1; + $user3 = $this->getDataGenerator()->create_user(); + $this->setUser($user3); + $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE)); + $token = external_generate_token_for_current_user($service); + + $message->userto = $user3; + $messageid = message_send($message); + $emails = $sink->get_messages(); + $this->assertCount(1, $emails); + $email = reset($emails); + // Check we don't get the promotion text. + $this->assertNotContains($mobileappdownloadpage, quoted_printable_decode($email->body)); + $sink->clear(); + $sink->close(); + } }