/** * Reset contents of all database tables to initial values, reset caches, etc. * * Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care! * * @static * @param bool $detectchanges * true - changes in global state and database are reported as errors * false - no errors reported * null - only critical problems are reported as errors * @return void */ public static function reset_all_data($detectchanges = false) { global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION; // Stop any message redirection. phpunit_util::stop_message_redirection(); // Stop any message redirection. phpunit_util::stop_phpmailer_redirection(); // Stop any message redirection. phpunit_util::stop_event_redirection(); // We used to call gc_collect_cycles here to ensure desctructors were called between tests. // This accounted for 25% of the total time running phpunit - so we removed it. // Show any unhandled debugging messages, the runbare() could already reset it. self::display_debugging_messages(); self::reset_debugging(); // reset global $DB in case somebody mocked it $DB = self::get_global_backup('DB'); if ($DB->is_transaction_started()) { // we can not reset inside transaction $DB->force_transaction_rollback(); } $resetdb = self::reset_database(); $warnings = array(); if ($detectchanges === true) { if ($resetdb) { $warnings[] = 'Warning: unexpected database modification, resetting DB state'; } $oldcfg = self::get_global_backup('CFG'); $oldsite = self::get_global_backup('SITE'); foreach ($CFG as $k => $v) { if (!property_exists($oldcfg, $k)) { $warnings[] = 'Warning: unexpected new $CFG->' . $k . ' value'; } else { if ($oldcfg->{$k} !== $CFG->{$k}) { $warnings[] = 'Warning: unexpected change of $CFG->' . $k . ' value'; } } unset($oldcfg->{$k}); } if ($oldcfg) { foreach ($oldcfg as $k => $v) { $warnings[] = 'Warning: unexpected removal of $CFG->' . $k; } } if ($USER->id != 0) { $warnings[] = 'Warning: unexpected change of $USER'; } if ($COURSE->id != $oldsite->id) { $warnings[] = 'Warning: unexpected change of $COURSE'; } } if (ini_get('max_execution_time') != 0) { // This is special warning for all resets because we do not want any // libraries to mess with timeouts unintentionally. // Our PHPUnit integration is not supposed to change it either. if ($detectchanges !== false) { $warnings[] = 'Warning: max_execution_time was changed to ' . ini_get('max_execution_time'); } set_time_limit(0); } // restore original globals $_SERVER = self::get_global_backup('_SERVER'); $CFG = self::get_global_backup('CFG'); $SITE = self::get_global_backup('SITE'); $_GET = array(); $_POST = array(); $_FILES = array(); $_REQUEST = array(); $COURSE = $SITE; // reinitialise following globals $OUTPUT = new bootstrap_renderer(); $PAGE = new moodle_page(); $FULLME = null; $ME = null; $SCRIPT = null; // Empty sessison and set fresh new not-logged-in user. \core\session\manager::init_empty_session(); // reset all static caches \core\event\manager::phpunit_reset(); accesslib_clear_all_caches(true); get_string_manager()->reset_caches(true); reset_text_filters_cache(true); events_get_handlers('reset'); core_text::reset_caches(); get_message_processors(false, true); filter_manager::reset_caches(); // Reset internal users. core_user::reset_internal_users(); //TODO MDL-25290: add more resets here and probably refactor them to new core function // Reset course and module caches. if (class_exists('format_base')) { // If file containing class is not loaded, there is no cache there anyway. format_base::reset_course_cache(0); } get_fast_modinfo(0, 0, true); // Reset other singletons. if (class_exists('core_plugin_manager')) { core_plugin_manager::reset_caches(true); } if (class_exists('\\core\\update\\checker')) { \core\update\checker::reset_caches(true); } if (class_exists('\\core\\update\\deployer')) { \core\update\deployer::reset_caches(true); } // purge dataroot directory self::reset_dataroot(); // restore original config once more in case resetting of caches changed CFG $CFG = self::get_global_backup('CFG'); // inform data generator self::get_data_generator()->reset(); // fix PHP settings error_reporting($CFG->debug); // verify db writes just in case something goes wrong in reset if (self::$lastdbwrites != $DB->perf_get_writes()) { error_log('Unexpected DB writes in phpunit_util::reset_all_data()'); self::$lastdbwrites = $DB->perf_get_writes(); } if ($warnings) { $warnings = implode("\n", $warnings); trigger_error($warnings, E_USER_WARNING); } }
public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them. $ADMIN = $adminroot; // May be used in settings.php. $plugininfo = $this; // Also can be used inside settings.php. if (!$this->is_installed_and_upgraded()) { return; } if (!$hassiteconfig) { return; } $section = $this->get_settings_section_name(); $settings = null; $processors = get_message_processors(); if (isset($processors[$this->name])) { $processor = $processors[$this->name]; if ($processor->available && $processor->hassettings) { $settings = new admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false); include $this->full_path('settings.php'); // This may also set $settings to null. } } if ($settings) { $ADMIN->add($parentnodename, $settings); } }
/** * Test send_instant_messages */ public function test_send_instant_messages() { global $DB, $USER, $CFG; $this->resetAfterTest(true); // Transactions used in tests, tell phpunit use alternative reset method. $this->preventResetByRollback(); // Turn off all message processors (so nothing is really sent) require_once $CFG->dirroot . '/message/lib.php'; $messageprocessors = get_message_processors(); foreach ($messageprocessors as $messageprocessor) { $messageprocessor->enabled = 0; $DB->update_record('message_processors', $messageprocessor); } // Set the required capabilities by the external function $contextid = context_system::instance()->id; $roleid = $this->assignUserCapability('moodle/site:sendmessage', $contextid); $user1 = self::getDataGenerator()->create_user(); // Create test message data. $message1 = array(); $message1['touserid'] = $user1->id; $message1['text'] = 'the message.'; $message1['clientmsgid'] = 4; $messages = array($message1); $sentmessages = core_message_external::send_instant_messages($messages); // We need to execute the return values cleaning process to simulate the web service server. $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); $themessage = $DB->get_record('message', array('id' => $sentmessages[0]['msgid'])); // Confirm that the message was inserted correctly. $this->assertEquals($themessage->useridfrom, $USER->id); $this->assertEquals($themessage->useridto, $message1['touserid']); $this->assertEquals($themessage->smallmessage, $message1['text']); $this->assertEquals($sentmessages[0]['clientmsgid'], $message1['clientmsgid']); }
/** * Test send_instant_messages */ public function test_send_instant_messages() { global $DB, $USER, $CFG; $this->resetAfterTest(true); // Turn off all message processors (so nothing is really sent) require_once($CFG->dirroot . '/message/lib.php'); $messageprocessors = get_message_processors(); foreach($messageprocessors as $messageprocessor) { $messageprocessor->enabled = 0; $DB->update_record('message_processors', $messageprocessor); } // Set the required capabilities by the external function $contextid = context_system::instance()->id; $roleid = $this->assignUserCapability('moodle/site:sendmessage', $contextid); $user1 = self::getDataGenerator()->create_user(); // Create test message data. $message1 = array(); $message1['touserid'] = $user1->id; $message1['text'] = 'the message.'; $message1['clientmsgid'] = 4; $messages = array($message1); $sentmessages = core_message_external::send_instant_messages($messages); $themessage = $DB->get_record('message', array('id' => $sentmessages[0]['msgid'])); // Confirm that the message was inserted correctly. $this->assertEquals($themessage->useridfrom, $USER->id); $this->assertEquals($themessage->useridto, $message1['touserid']); $this->assertEquals($themessage->smallmessage, $message1['text']); $this->assertEquals($sentmessages[0]['clientmsgid'], $message1['clientmsgid']); }
public function test_message_processors_reset() { global $DB; $this->resetAfterTest(true); // Get all processors first. $processors1 = get_message_processors(); // Add a new message processor and get all processors again. $processor = new stdClass(); $processor->name = 'test_processor'; $processor->enabled = 1; $DB->insert_record('message_processors', $processor); $processors2 = get_message_processors(); // Assert that new processor still haven't been added to the list. $this->assertSame($processors1, $processors2); // Reset message processors data. $processors3 = get_message_processors(false, true); // Now, list of processors should not be the same any more, // And we should have one more message processor in the list. $this->assertNotSame($processors1, $processors3); $this->assertEquals(count($processors1) + 1, count($processors3)); }
/** * Called when a message provider wants to send a message. * This functions checks the message recipient's message processor configuration then * sends the message to the configured processors * * Required parameters of the $eventdata object: * component string component name. must exist in message_providers * name string message type name. must exist in message_providers * userfrom object|int the user sending the message * userto object|int the message recipient * subject string the message subject * fullmessage string the full message in a given format * fullmessageformat int the format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..) * fullmessagehtml string the full version (the message processor will choose with one to use) * smallmessage string the small version of the message * * Optional parameters of the $eventdata object: * notification bool should the message be considered as a notification rather than a personal message * contexturl string if this is a notification then you can specify a url to view the event. For example the forum post the user is being notified of. * contexturlname string the display text for contexturl * * Note: processor failure is is not reported as false return value, * earlier versions did not do it consistently either. * * @todo MDL-55449 Drop support for stdClass in Moodle 3.6 * @category message * @param \core\message\message $eventdata information about the message (component, userfrom, userto, ...) * @return mixed the integer ID of the new message or false if there was a problem with submitted data */ function message_send($eventdata) { global $CFG, $DB; // TODO MDL-55449 Drop support for stdClass in Moodle 3.6. if ($eventdata instanceof \stdClass) { if (!isset($eventdata->courseid)) { $eventdata->courseid = null; } debugging('eventdata as \stdClass is deprecated. Please use core\message\message instead.', DEBUG_DEVELOPER); } //new message ID to return $messageid = false; // Fetch default (site) preferences $defaultpreferences = get_message_output_default_preferences(); $preferencebase = $eventdata->component.'_'.$eventdata->name; // If message provider is disabled then don't do any processing. if (!empty($defaultpreferences->{$preferencebase.'_disable'})) { return $messageid; } // By default a message is a notification. Only personal/private messages aren't notifications. if (!isset($eventdata->notification)) { $eventdata->notification = 1; } if (!is_object($eventdata->userto)) { $eventdata->userto = core_user::get_user($eventdata->userto); } if (!is_object($eventdata->userfrom)) { $eventdata->userfrom = core_user::get_user($eventdata->userfrom); } if (!$eventdata->userto) { debugging('Attempt to send msg to unknown user', DEBUG_NORMAL); return false; } if (!$eventdata->userfrom) { debugging('Attempt to send msg from unknown user', DEBUG_NORMAL); return false; } // Verify all necessary data fields are present. if (!isset($eventdata->userto->auth) or !isset($eventdata->userto->suspended) or !isset($eventdata->userto->deleted) or !isset($eventdata->userto->emailstop)) { debugging('Necessary properties missing in userto object, fetching full record', DEBUG_DEVELOPER); $eventdata->userto = core_user::get_user($eventdata->userto->id); } $usertoisrealuser = (core_user::is_real_user($eventdata->userto->id) != false); // If recipient is internal user (noreply user), and emailstop is set then don't send any msg. if (!$usertoisrealuser && !empty($eventdata->userto->emailstop)) { debugging('Attempt to send msg to internal (noreply) user', DEBUG_NORMAL); return false; } //after how long inactive should the user be considered logged off? if (isset($CFG->block_online_users_timetosee)) { $timetoshowusers = $CFG->block_online_users_timetosee * 60; } else { $timetoshowusers = 300;//5 minutes } // Work out if the user is logged in or not if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) { $userstate = 'loggedin'; } else { $userstate = 'loggedoff'; } // Create the message object $savemessage = new stdClass(); $savemessage->courseid = $eventdata->courseid; $savemessage->useridfrom = $eventdata->userfrom->id; $savemessage->useridto = $eventdata->userto->id; $savemessage->subject = $eventdata->subject; $savemessage->fullmessage = $eventdata->fullmessage; $savemessage->fullmessageformat = $eventdata->fullmessageformat; $savemessage->fullmessagehtml = $eventdata->fullmessagehtml; $savemessage->smallmessage = $eventdata->smallmessage; $savemessage->notification = $eventdata->notification; $savemessage->eventtype = $eventdata->name; $savemessage->component = $eventdata->component; if (!empty($eventdata->contexturl)) { $savemessage->contexturl = (string)$eventdata->contexturl; } else { $savemessage->contexturl = null; } if (!empty($eventdata->contexturlname)) { $savemessage->contexturlname = (string)$eventdata->contexturlname; } else { $savemessage->contexturlname = null; } $savemessage->timecreated = time(); if (PHPUNIT_TEST and class_exists('phpunit_util')) { // Add some more tests to make sure the normal code can actually work. $componentdir = core_component::get_component_directory($eventdata->component); if (!$componentdir or !is_dir($componentdir)) { throw new coding_exception('Invalid component specified in message-send(): '.$eventdata->component); } if (!file_exists("$componentdir/db/messages.php")) { throw new coding_exception("$eventdata->component does not contain db/messages.php necessary for message_send()"); } $messageproviders = null; include("$componentdir/db/messages.php"); if (!isset($messageproviders[$eventdata->name])) { throw new coding_exception("Missing messaging defaults for event '$eventdata->name' in '$eventdata->component' messages.php file"); } unset($componentdir); unset($messageproviders); // Now ask phpunit if it wants to catch this message. if (phpunit_util::is_redirecting_messages()) { $savemessage->timeread = time(); $messageid = $DB->insert_record('message_read', $savemessage); $message = $DB->get_record('message_read', array('id'=>$messageid)); phpunit_util::message_sent($message); return $messageid; } } // Fetch enabled processors $processors = get_message_processors(true); // Preset variables $processorlist = array(); // Fill in the array of processors to be used based on default and user preferences foreach ($processors as $processor) { // Skip adding processors for internal user, if processor doesn't support sending message to internal user. if (!$usertoisrealuser && !$processor->object->can_send_to_any_users()) { continue; } // First find out permissions $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; if (isset($defaultpreferences->{$defaultpreference})) { $permitted = $defaultpreferences->{$defaultpreference}; } else { // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't // exist in the message_provider table (thus there is no default settings for them). $preferrormsg = "Could not load preference $defaultpreference. Make sure the component and name you supplied to message_send() are valid."; throw new coding_exception($preferrormsg); } // Find out if user has configured this output // Some processors cannot function without settings from the user $userisconfigured = $processor->object->is_user_configured($eventdata->userto); // DEBUG: notify if we are forcing unconfigured output if ($permitted == 'forced' && !$userisconfigured) { debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL); } // Populate the list of processors we will be using if ($permitted == 'forced' && $userisconfigured) { // An admin is forcing users to use this message processor. Use this processor unconditionally. $processorlist[] = $processor->name; } else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) { // User has not disabled notifications // See if user set any notification preferences, otherwise use site default ones $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto)) { if (in_array($processor->name, explode(',', $userpreference))) { $processorlist[] = $processor->name; } } else if (isset($defaultpreferences->{$userpreferencename})) { if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { $processorlist[] = $processor->name; } } } } // Only cache messages, not notifications. if (empty($savemessage->notification)) { // Cache the timecreated value of the last message between these two users. $cache = cache::make('core', 'message_time_last_message_between_users'); $key = \core_message\helper::get_last_message_time_created_cache_key($savemessage->useridfrom, $savemessage->useridto); $cache->set($key, $savemessage->timecreated); } // Store unread message just in case we get a fatal error any time later. $savemessage->id = $DB->insert_record('message', $savemessage); $eventdata->savedmessageid = $savemessage->id; // Let the manager do the sending or buffering when db transaction in progress. return \core\message\manager::send_message($eventdata, $savemessage, $processorlist); }
/** * Called when a message provider wants to send a message. * This functions checks the message recipient's message processor configuration then * sends the message to the configured processors * * Required parameters of the $eventdata object: * component string component name. must exist in message_providers * name string message type name. must exist in message_providers * userfrom object|int the user sending the message * userto object|int the message recipient * subject string the message subject * fullmessage string the full message in a given format * fullmessageformat int the format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..) * fullmessagehtml string the full version (the message processor will choose with one to use) * smallmessage string the small version of the message * * Optional parameters of the $eventdata object: * notification bool should the message be considered as a notification rather than a personal message * contexturl string if this is a notification then you can specify a url to view the event. For example the forum post the user is being notified of. * contexturlname string the display text for contexturl * * @category message * @param object $eventdata information about the message (component, userfrom, userto, ...) * @return mixed the integer ID of the new message or false if there was a problem with a processor */ function message_send($eventdata) { global $CFG, $DB; //new message ID to return $messageid = false; //TODO: we need to solve problems with database transactions here somehow, for now we just prevent transactions - sorry $DB->transactions_forbidden(); if (is_number($eventdata->userto)) { $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto)); } if (is_int($eventdata->userfrom)) { $eventdata->userfrom = $DB->get_record('user', array('id' => $eventdata->userfrom)); } if (!isset($eventdata->userto->auth) or !isset($eventdata->userto->suspended) or !isset($eventdata->userto->deleted)) { $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto->id)); } //after how long inactive should the user be considered logged off? if (isset($CFG->block_online_users_timetosee)) { $timetoshowusers = $CFG->block_online_users_timetosee * 60; } else { $timetoshowusers = 300;//5 minutes } // Work out if the user is logged in or not if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) { $userstate = 'loggedin'; } else { $userstate = 'loggedoff'; } // Create the message object $savemessage = new stdClass(); $savemessage->useridfrom = $eventdata->userfrom->id; $savemessage->useridto = $eventdata->userto->id; $savemessage->subject = $eventdata->subject; $savemessage->fullmessage = $eventdata->fullmessage; $savemessage->fullmessageformat = $eventdata->fullmessageformat; $savemessage->fullmessagehtml = $eventdata->fullmessagehtml; $savemessage->smallmessage = $eventdata->smallmessage; if (!empty($eventdata->notification)) { $savemessage->notification = $eventdata->notification; } else { $savemessage->notification = 0; } if (!empty($eventdata->contexturl)) { $savemessage->contexturl = $eventdata->contexturl; } else { $savemessage->contexturl = null; } if (!empty($eventdata->contexturlname)) { $savemessage->contexturlname = $eventdata->contexturlname; } else { $savemessage->contexturlname = null; } $savemessage->timecreated = time(); if (PHPUNIT_TEST and class_exists('phpunit_util')) { // Add some more tests to make sure the normal code can actually work. $componentdir = get_component_directory($eventdata->component); if (!$componentdir or !is_dir($componentdir)) { throw new coding_exception('Invalid component specified in message-send(): '.$eventdata->component); } if (!file_exists("$componentdir/db/messages.php")) { throw new coding_exception("$eventdata->component does not contain db/messages.php necessary for message_send()"); } $messageproviders = null; include("$componentdir/db/messages.php"); if (!isset($messageproviders[$eventdata->name])) { throw new coding_exception("Missing messaging defaults for event '$eventdata->name' in '$eventdata->component' messages.php file"); } unset($componentdir); unset($messageproviders); // Now ask phpunit if it wants to catch this message. if (phpunit_util::is_redirecting_messages()) { $savemessage->timeread = time(); $messageid = $DB->insert_record('message_read', $savemessage); $message = $DB->get_record('message_read', array('id'=>$messageid)); phpunit_util::message_sent($message); return $messageid; } } // Fetch enabled processors $processors = get_message_processors(true); // Fetch default (site) preferences $defaultpreferences = get_message_output_default_preferences(); // Preset variables $processorlist = array(); $preferencebase = $eventdata->component.'_'.$eventdata->name; // Fill in the array of processors to be used based on default and user preferences foreach ($processors as $processor) { // First find out permissions $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; if (isset($defaultpreferences->{$defaultpreference})) { $permitted = $defaultpreferences->{$defaultpreference}; } else { //MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't //exist in the message_provider table (thus there is no default settings for them) $preferrormsg = get_string('couldnotfindpreference', 'message', $defaultpreference); throw new coding_exception($preferrormsg,'blah'); } // Find out if user has configured this output // Some processors cannot function without settings from the user $userisconfigured = $processor->object->is_user_configured($eventdata->userto); // DEBUG: notify if we are forcing unconfigured output if ($permitted == 'forced' && !$userisconfigured) { debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL); } // Warn developers that necessary data is missing regardless of how the processors are configured if (!isset($eventdata->userto->emailstop)) { debugging('userto->emailstop is not set. Retrieving it from the user table'); $eventdata->userto->emailstop = $DB->get_field('user', 'emailstop', array('id'=>$eventdata->userto->id)); } // Populate the list of processors we will be using if ($permitted == 'forced' && $userisconfigured) { // An admin is forcing users to use this message processor. Use this processor unconditionally. $processorlist[] = $processor->name; } else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) { // User has not disabled notifications // See if user set any notification preferences, otherwise use site default ones $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto->id)) { if (in_array($processor->name, explode(',', $userpreference))) { $processorlist[] = $processor->name; } } else if (isset($defaultpreferences->{$userpreferencename})) { if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { $processorlist[] = $processor->name; } } } } if (empty($processorlist) && $savemessage->notification) { //if they have deselected all processors and its a notification mark it read. The user doesnt want to be bothered $savemessage->timeread = time(); $messageid = $DB->insert_record('message_read', $savemessage); } else { // Process the message // Store unread message just in case we can not send it $messageid = $savemessage->id = $DB->insert_record('message', $savemessage); $eventdata->savedmessageid = $savemessage->id; // Try to deliver the message to each processor if (!empty($processorlist)) { foreach ($processorlist as $procname) { if (!$processors[$procname]->object->send_message($eventdata)) { debugging('Error calling message processor '.$procname); $messageid = false; } } //if messaging is disabled and they previously had forum notifications handled by the popup processor //or any processor that puts a row in message_working then the notification will remain forever //unread. To prevent this mark the message read if messaging is disabled if (empty($CFG->messaging)) { require_once($CFG->dirroot.'/message/lib.php'); $messageid = message_mark_message_read($savemessage, time()); } else if ( $DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0){ //if there is no more processors that want to process this we can move message to message_read require_once($CFG->dirroot.'/message/lib.php'); $messageid = message_mark_message_read($savemessage, time(), true); } } } return $messageid; }
public function test_send_message() { global $DB, $CFG; $this->preventResetByRollback(); $this->resetAfterTest(); unset_config('noemailever'); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); // Test basic email redirection. $this->assertFileExists("{$CFG->dirroot}/message/output/email/version.php"); $this->assertFileExists("{$CFG->dirroot}/message/output/popup/version.php"); $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email' AND name <> 'popup'"); get_message_processors(true, true); $eventsink = $this->redirectEvents(); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); $message = new stdClass(); $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'; $sink = $this->redirectEmails(); $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $DB->delete_records('message', array()); $events = $eventsink->get_events(); $this->assertCount(1, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $eventsink->clear(); $CFG->messaging = 0; $message = new stdClass(); $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'; $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message_read', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message', array())); $DB->delete_records('message_read', array()); $events = $eventsink->get_events(); $this->assertCount(2, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[1]); $eventsink->clear(); $CFG->messaging = 1; $message = new stdClass(); $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 = '1'; $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message_read', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message', array())); $DB->delete_records('message_read', array()); $events = $eventsink->get_events(); $this->assertCount(2, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[1]); $eventsink->clear(); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); $message = new stdClass(); $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'; $user2->emailstop = '1'; $sink = $this->redirectEmails(); $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $DB->delete_records('message', array()); $events = $eventsink->get_events(); $this->assertCount(1, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $eventsink->clear(); $user2->emailstop = '0'; set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); $message = new stdClass(); $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'; $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(1, $emails); $email = reset($emails); $savedmessage = $DB->get_record('message_read', array('id' => $messageid), '*', MUST_EXIST); $this->assertSame($user1->email, $email->from); $this->assertSame($user2->email, $email->to); $this->assertSame($message->subject, $email->subject); $this->assertNotEmpty($email->header); $this->assertNotEmpty($email->body); $sink->clear(); $this->assertFalse($DB->record_exists('message', array())); $DB->delete_records('message_read', array()); $events = $eventsink->get_events(); $this->assertCount(2, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[1]); $eventsink->clear(); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email,popup', $user2); $message = new stdClass(); $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'; $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(1, $emails); $email = reset($emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $working = $DB->get_record('message_working', array('unreadmessageid' => $messageid), '*', MUST_EXIST); $this->assertSame($user1->email, $email->from); $this->assertSame($user2->email, $email->to); $this->assertSame($message->subject, $email->subject); $this->assertNotEmpty($email->header); $this->assertNotEmpty($email->body); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $DB->delete_records('message', array()); $events = $eventsink->get_events(); $this->assertCount(1, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $eventsink->clear(); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'popup', $user2); $message = new stdClass(); $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'; $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $working = $DB->get_record('message_working', array('unreadmessageid' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $DB->delete_records('message', array()); $events = $eventsink->get_events(); $this->assertCount(1, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $eventsink->clear(); $this->assertFalse($DB->is_transaction_started()); $transaction = $DB->start_delegated_transaction(); if (!$DB->is_transaction_started()) { $this->markTestSkipped('Databases that do not support transactions should not be used at all!'); } $transaction->allow_commit(); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); $message = new stdClass(); $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'; $transaction = $DB->start_delegated_transaction(); $sink = $this->redirectEmails(); $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $DB->delete_records('message', array()); $events = $eventsink->get_events(); $this->assertCount(1, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $eventsink->clear(); $transaction->allow_commit(); $events = $eventsink->get_events(); $this->assertCount(0, $events); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); $message = new stdClass(); $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'; $transaction = $DB->start_delegated_transaction(); $sink = $this->redirectEmails(); $messageid = message_send($message); $emails = $sink->get_messages(); $this->assertCount(0, $emails); $savedmessage = $DB->get_record('message', array('id' => $messageid), '*', MUST_EXIST); $sink->clear(); $this->assertFalse($DB->record_exists('message_read', array())); $events = $eventsink->get_events(); $this->assertCount(0, $events); $transaction->allow_commit(); $events = $eventsink->get_events(); $this->assertCount(2, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[1]); $eventsink->clear(); $transaction = $DB->start_delegated_transaction(); message_send($message); message_send($message); $this->assertCount(2, $DB->get_records('message')); $this->assertCount(1, $DB->get_records('message_read')); $events = $eventsink->get_events(); $this->assertCount(0, $events); $transaction->allow_commit(); $events = $eventsink->get_events(); $this->assertCount(4, $events); $this->assertInstanceOf('\\core\\event\\message_sent', $events[0]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[1]); $this->assertInstanceOf('\\core\\event\\message_sent', $events[2]); $this->assertInstanceOf('\\core\\event\\message_viewed', $events[3]); $eventsink->clear(); $DB->delete_records('message', array()); $DB->delete_records('message_read', array()); $transaction = $DB->start_delegated_transaction(); message_send($message); message_send($message); $this->assertCount(2, $DB->get_records('message')); $this->assertCount(0, $DB->get_records('message_read')); $events = $eventsink->get_events(); $this->assertCount(0, $events); try { $transaction->rollback(new Exception('ignore')); } catch (Exception $e) { $this->assertSame('ignore', $e->getMessage()); } $events = $eventsink->get_events(); $this->assertCount(0, $events); $this->assertCount(0, $DB->get_records('message')); $this->assertCount(0, $DB->get_records('message_read')); message_send($message); $this->assertCount(0, $DB->get_records('message')); $this->assertCount(1, $DB->get_records('message_read')); $events = $eventsink->get_events(); $this->assertCount(2, $events); $sink->clear(); $DB->delete_records('message_read', array()); }
/** * @see plugintype_interface::get_uninstall_url() */ public function get_uninstall_url() { $processors = get_message_processors(); if (isset($processors[$this->name])) { return new moodle_url('/admin/message.php', array('uninstall' => $processors[$this->name]->id, 'sesskey' => sesskey())); } else { return parent::get_uninstall_url(); } }
/** * Test method is_user_enabled. */ public function is_user_enabled() { $processors = get_message_processors(); if (empty($processors)) { $this->markTestSkipped("No message processors found"); } list($name, $testprocessor) = each($processors); // Enable. \core_message\api::update_processor_status($testprocessor, 1); $status = \core_message\api::is_processor_enabled($name); $this->assertEquals(1, $status); // Disable. \core_message\api::update_processor_status($testprocessor, 0); $status = \core_message\api::is_processor_enabled($name); $this->assertEquals(0, $status); // Enable again. \core_message\api::update_processor_status($testprocessor, 1); $status = \core_message\api::is_processor_enabled($name); $this->assertEquals(1, $status); }
/** * Render badges. * @return string */ protected function render_badges() { $mprocs = get_message_processors(true); if (!isset($mprocs['badge'])) { // Badge message processor is not enabled - exit. return null; } $badgerend = $this->get_badge_renderer(); $badges = ''; if ($badgerend && $badgerend instanceof \theme_snap\output\message_badge_renderer) { $badges = '<div class="alert_stream"> ' . $badgerend->messagestitle() . ' <div class="message_badge_container"></div> </div>'; } return $badges; }
/** * Called when a message provider wants to send a message. * This functions checks the user's processor configuration to send the given type of message, * then tries to send it. * * Required parameter $eventdata structure: * component string component name. must exist in message_providers * name string message type name. must exist in message_providers * userfrom object|int the user sending the message * userto object|int the message recipient * subject string the message subject * fullmessage - the full message in a given format * fullmessageformat - the format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..) * fullmessagehtml - the full version (the message processor will choose with one to use) * smallmessage - the small version of the message * contexturl - if this is a notification then you can specify a url to view the event. For example the forum post the user is being notified of. * contexturlname - the display text for contexturl * * @param object $eventdata information about the message (component, userfrom, userto, ...) * @return int|false the ID of the new message or false if there was a problem with a processor */ function message_send($eventdata) { global $CFG, $DB; //new message ID to return $messageid = false; //TODO: we need to solve problems with database transactions here somehow, for now we just prevent transactions - sorry $DB->transactions_forbidden(); if (is_int($eventdata->userto)) { $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto)); } if (is_int($eventdata->userfrom)) { $eventdata->userfrom = $DB->get_record('user', array('id' => $eventdata->userfrom)); } //after how long inactive should the user be considered logged off? if (isset($CFG->block_online_users_timetosee)) { $timetoshowusers = $CFG->block_online_users_timetosee * 60; } else { $timetoshowusers = 300;//5 minutes } // Work out if the user is logged in or not if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) { $userstate = 'loggedin'; } else { $userstate = 'loggedoff'; } // Create the message object $savemessage = new stdClass(); $savemessage->useridfrom = $eventdata->userfrom->id; $savemessage->useridto = $eventdata->userto->id; $savemessage->subject = $eventdata->subject; $savemessage->fullmessage = $eventdata->fullmessage; $savemessage->fullmessageformat = $eventdata->fullmessageformat; $savemessage->fullmessagehtml = $eventdata->fullmessagehtml; $savemessage->smallmessage = $eventdata->smallmessage; if (!empty($eventdata->notification)) { $savemessage->notification = $eventdata->notification; } else { $savemessage->notification = 0; } if (!empty($eventdata->contexturl)) { $savemessage->contexturl = $eventdata->contexturl; } else { $savemessage->contexturl = null; } if (!empty($eventdata->contexturlname)) { $savemessage->contexturlname = $eventdata->contexturlname; } else { $savemessage->contexturlname = null; } $savemessage->timecreated = time(); // Fetch enabled processors $processors = get_message_processors(true); // Fetch default (site) preferences $defaultpreferences = get_message_output_default_preferences(); // Preset variables $processorlist = array(); $preferencebase = $eventdata->component.'_'.$eventdata->name; // Fill in the array of processors to be used based on default and user preferences foreach ($processors as $processor) { // First find out permissions $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; if (isset($defaultpreferences->{$defaultpreference})) { $permitted = $defaultpreferences->{$defaultpreference}; } else { //MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't //exist in the message_provider table (thus there is no default settings for them) $preferrormsg = get_string('couldnotfindpreference', 'message', $preferencename); throw new coding_exception($preferrormsg,'blah'); } // Find out if user has configured this output $userisconfigured = $processor->object->is_user_configured($eventdata->userto); // DEBUG: noify if we are forcing unconfigured output if ($permitted == 'forced' && !$userisconfigured) { debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL); } // Populate the list of processors we will be using if ($permitted == 'forced' && $userisconfigured) { // We force messages for this processor, so use this processor unconditionally if user has configured it $processorlist[] = $processor->name; } else if ($permitted == 'permitted' && $userisconfigured) { // User settings are permitted, see if user set any, otherwise use site default ones $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto->id)) { if (in_array($processor->name, explode(',', $userpreference))) { $processorlist[] = $processor->name; } } else if (isset($defaultpreferences->{$userpreferencename})) { if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { $processorlist[] = $processor->name; } } } } if (empty($processorlist) && $savemessage->notification) { //if they have deselected all processors and its a notification mark it read. The user doesnt want to be bothered $savemessage->timeread = time(); $messageid = $DB->insert_record('message_read', $savemessage); } else { // Process the message // Store unread message just in case we can not send it $messageid = $savemessage->id = $DB->insert_record('message', $savemessage); $eventdata->savedmessageid = $savemessage->id; // Try to deliver the message to each processor if (!empty($processorlist)) { foreach ($processorlist as $procname) { if (!$processors[$procname]->object->send_message($eventdata)) { debugging('Error calling message processor '.$procname); $messageid = false; } } //if messaging is disabled and they previously had forum notifications handled by the popup processor //or any processor that puts a row in message_working then the notification will remain forever //unread. To prevent this mark the message read if messaging is disabled if (empty($CFG->messaging)) { require_once($CFG->dirroot.'/message/lib.php'); $messageid = message_mark_message_read($savemessage, time()); } else if ( $DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0){ //if there is no more processors that want to process this we can move message to message_read require_once($CFG->dirroot.'/message/lib.php'); $messageid = message_mark_message_read($savemessage, time(), true); } } } return $messageid; }
/** * Default message outputs configuration page * * @package core_message * @copyright 2011 Lancaster University Network Services Limited * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once dirname(__FILE__) . '/../config.php'; require_once $CFG->dirroot . '/message/lib.php'; require_once $CFG->libdir . '/adminlib.php'; // This is an admin page admin_externalpage_setup('defaultmessageoutputs'); // Require site configuration capability require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); // Fetch processors $processors = get_message_processors(true); // Fetch message providers $providers = get_message_providers(); if (($form = data_submitted()) && confirm_sesskey()) { $preferences = array(); // Prepare default message outputs settings foreach ($providers as $provider) { $componentproviderbase = $provider->component . '_' . $provider->name; foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) { $value = null; $componentprovidersetting = $componentproviderbase . '_' . $setting; if ($setting == 'permitted') { // if we deal with permitted select element, we need to create individual // setting for each possible processor. Note that this block will // always be processed first after entring parental foreach iteration // so we can change form values on this stage.
/** * Tests deleting a conversation. */ public function test_get_all_message_preferences() { $user = self::getDataGenerator()->create_user(); $this->setUser($user); // Set a couple of preferences to test. set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user); set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user); $processors = get_message_processors(); $providers = message_get_providers_for_user($user->id); $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user); $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']); $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']); }
/** * Get the notification preferences for a given user. * * @param int $userid id of the user, 0 for current user * @return external_description * @throws moodle_exception * @since 3.2 */ public static function get_user_message_preferences($userid = 0) { global $PAGE; $params = self::validate_parameters(self::get_user_message_preferences_parameters(), array('userid' => $userid)); $user = self::validate_preferences_permissions($params['userid']); // Filter out enabled, available system_configured and user_configured processors only. $readyprocessors = array_filter(get_message_processors(), function ($processor) { return $processor->enabled && $processor->configured && $processor->object->is_user_configured() && $processor->object->has_message_preferences(); }); $providers = array_filter(message_get_providers_for_user($user->id), function ($provider) { return $provider->component === 'moodle'; }); $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user); $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors, $providers, $preferences, $user); $renderer = $PAGE->get_renderer('core_message'); $result = array('warnings' => array(), 'preferences' => $notificationlistoutput->export_for_template($renderer), 'blocknoncontacts' => get_user_preferences('message_blocknoncontacts', '', $user->id) ? true : false); return $result; }
/** * @see plugintype_interface::get_uninstall_url() */ public function get_uninstall_url() { $processors = get_message_processors(); return new moodle_url('/admin/message.php', array('uninstall' => $processors[$this->name]->id, 'sesskey' => sesskey())); }
$strblockname = get_string('pluginname', 'block_'.$blockname); if (file_exists($CFG->dirroot.'/blocks/'.$blockname.'/settings.php')) { $settings = new admin_settingpage('blocksetting'.$blockname, $strblockname, 'moodle/site:config', !$block->visible); include($CFG->dirroot.'/blocks/'.$blockname.'/settings.php'); if ($settings) { $ADMIN->add('blocksettings', $settings); } } } // message outputs $ADMIN->add('modules', new admin_category('messageoutputs', get_string('messageoutputs', 'message'))); $ADMIN->add('messageoutputs', new admin_page_managemessageoutputs()); $ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs()); require_once($CFG->dirroot.'/message/lib.php'); $processors = get_message_processors(); foreach ($processors as $processor) { $processorname = $processor->name; if (!$processor->available) { continue; } if ($processor->hassettings) { $strprocessorname = get_string('pluginname', 'message_'.$processorname); $settings = new admin_settingpage('messagesetting'.$processorname, $strprocessorname, 'moodle/site:config', !$processor->enabled); include($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php'); if ($settings) { $ADMIN->add('messageoutputs', $settings); } } }
/** * Send message to message processors. * * @param \stdClass|\core\message\message $eventdata * @param \stdClass $savemessage * @param array $processorlist * @return int $messageid */ protected static function send_message_to_processors($eventdata, \stdClass $savemessage, array $processorlist) { global $CFG, $DB; // We cannot communicate with external systems in DB transactions, // buffer the messages if necessary. if ($DB->is_transaction_started()) { // We need to clone all objects so that devs may not modify it from outside later. $eventdata = clone $eventdata; $eventdata->userto = clone $eventdata->userto; $eventdata->userfrom = clone $eventdata->userfrom; // Conserve some memory the same was as $USER setup does. unset($eventdata->userto->description); unset($eventdata->userfrom->description); self::$buffer[] = array($eventdata, $savemessage, $processorlist); return $savemessage->id; } $processors = get_message_processors(true); $failed = false; 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 (!$processors[$procname]->object->send_message($proceventdata)) { debugging('Error calling message processor ' . $procname); $failed = true; // Previously the $messageid = false here was overridden // by other processors and message_mark_message_read() below. } } // Trigger event for sending a message - must be done before marking as read. \core\event\message_sent::create_from_ids($eventdata->userfrom->id, $eventdata->userto->id, $savemessage->id)->trigger(); if (empty($CFG->messaging)) { // If messaging is disabled and they previously had forum notifications handled by the popup processor // or any processor that puts a row in message_working then the notification will remain forever // unread. To prevent this mark the message read if messaging is disabled. $messageid = message_mark_message_read($savemessage, time()); } else { if ($failed) { // Something failed, better keep it as unread then. $messageid = $savemessage->id; } else { if ($DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0) { // If there is no more processors that want to process this we can move message to message_read. $messageid = message_mark_message_read($savemessage, time(), true); } else { // Some processor is still working on the data, let's keep it unread. $messageid = $savemessage->id; } } } return $messageid; }
/** * Search for a specific message processor * * @param string $query The string to search for * @return array */ public function search($query) { global $CFG, $DB; if ($result = parent::search($query)) { return $result; } $found = false; if ($processors = get_message_processors()) { $textlib = textlib_get_instance(); foreach ($processors as $processor) { if (!$processor->available) { continue; } if (strpos($processor->name, $query) !== false) { $found = true; break; } $strprocessorname = get_string('pluginname', 'message_' . $processor->name); if (strpos($textlib->strtolower($strprocessorname), $query) !== false) { $found = true; break; } } } if ($found) { $result = new stdClass(); $result->page = $this; $result->settings = array(); return array($this->name => $result); } else { return array(); } }
/** * Get the notification preferences for a given user. * * @param int $userid id of the user, 0 for current user * @return external_description * @throws moodle_exception * @since 3.2 */ public static function get_user_notification_preferences($userid = 0) { global $USER, $PAGE; $params = self::validate_parameters(self::get_user_notification_preferences_parameters(), array('userid' => $userid)); if (empty($params['userid'])) { $user = $USER; } else { $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); } $systemcontext = context_system::instance(); self::validate_context($systemcontext); // Check access control. if ($user->id == $USER->id) { // Editing own message profile. require_capability('moodle/user:editownmessageprofile', $systemcontext); } else { // Teachers, parents, etc. $personalcontext = context_user::instance($user->id); require_capability('moodle/user:editmessageprofile', $personalcontext); } $processors = get_message_processors(); $providers = message_get_providers_for_user($user->id); $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user); $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user); $renderer = $PAGE->get_renderer('core_message'); $result = array('warnings' => array(), 'preferences' => $notificationlist->export_for_template($renderer)); return $result; }