Merge branch 'MDL-64337-master' of git://github.com/jleyva/moodle
This commit is contained in:
@@ -86,6 +86,7 @@ $string['mobilesettings'] = 'Mobile settings';
|
||||
$string['offlineuse'] = 'Offline use';
|
||||
$string['pluginname'] = 'Moodle app tools';
|
||||
$string['pluginnotenabledorconfigured'] = 'Plugin not enabled or configured.';
|
||||
$string['readingthisemailgettheapp'] = 'Reading this in your e-mail? <a href="{$a}">Download the mobile app and receive notifications on your mobile devices</a>.';
|
||||
$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';
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,4 +94,80 @@ class tool_mobile_api_testcase extends externallib_advanced_testcase {
|
||||
$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 = '<p>message body</p>';
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,9 +473,21 @@ class manager {
|
||||
* @param array $processorlist the list of processors for a single user.
|
||||
*/
|
||||
protected static function call_processors(message $eventdata, array $processorlist) {
|
||||
// Allow plugins to change the message/notification data before sending it.
|
||||
$pluginsfunction = get_plugins_with_function('pre_processor_message_send');
|
||||
|
||||
foreach ($processorlist as $procname) {
|
||||
// Let new messaging class add custom content based on the processor.
|
||||
$proceventdata = ($eventdata instanceof message) ? $eventdata->get_eventobject_for_processor($procname) : $eventdata;
|
||||
|
||||
if ($pluginsfunction) {
|
||||
foreach ($pluginsfunction as $plugintype => $plugins) {
|
||||
foreach ($plugins as $pluginfunction) {
|
||||
$pluginfunction($procname, $proceventdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stdproc = new \stdClass();
|
||||
$stdproc->name = $procname;
|
||||
$processor = \core_message\api::get_processed_processor_object($stdproc);
|
||||
|
||||
+4
-2
@@ -24,6 +24,8 @@ attribute on forms to avoid collisions in forms loaded in AJAX requests.
|
||||
and get_reduced_timeout(). These allow for timeouts to be increased by a setting in config.php.
|
||||
* The $draftitemid parameter of file_save_draft_area_files() function now supports the constant IGNORE_FILE_MERGE:
|
||||
When the parameter is set to that constant, the function won't process file merging, keeping the original state of the file area.
|
||||
* Introduced new callback for plugin developers '<component>_pre_processor_message_send($procname, $proceventdata)':
|
||||
This will allow any plugin to manipulate messages or notifications before they are sent by a processor (email, mobile...)
|
||||
|
||||
=== 3.6 ===
|
||||
|
||||
@@ -639,13 +641,13 @@ the groupid field.
|
||||
$OUTPUT->download_dataformat_selector() instead.
|
||||
when building Xpath, or pass the unescaped value when using the named selector.
|
||||
* Add new file_is_executable(), to consistently check for executables even in Windows (PHP bug #41062).
|
||||
* Introduced new hooks for plugin developers.
|
||||
* Introduced new callbacks for plugin developers.
|
||||
- <component>_pre_course_category_delete($category)
|
||||
- <component>_pre_course_delete($course)
|
||||
- <component>_pre_course_module_delete($cm)
|
||||
- <component>_pre_block_delete($instance)
|
||||
- <component>_pre_user_delete($user)
|
||||
These hooks allow developers to use the item in question before it is deleted by core. For example, if your plugin is
|
||||
These callbacks allow developers to use the item in question before it is deleted by core. For example, if your plugin is
|
||||
a module (plugins located in the mod folder) called 'xxx' and you wish to interact with the user object before it is
|
||||
deleted then the function to create would be mod_xxx_pre_user_delete($user) in mod/xxx/lib.php.
|
||||
* pear::Net::GeoIP has been removed.
|
||||
|
||||
Reference in New Issue
Block a user