Example #1
3
 /**
  * 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);
     }
 }
Example #2
0
 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']);
 }
Example #4
0
    /**
     * 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']);
    }
Example #5
0
 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));
 }
Example #6
0
/**
 * 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);
}
Example #7
0
/**
 * 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());
 }
Example #9
0
 /**
  * @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();
     }
 }
Example #10
0
 /**
  * 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;
 }
Example #12
0
/**
 * 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.
Example #14
0
 /**
  * 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']);
 }
Example #15
0
 /**
  * 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;
 }
Example #16
0
 /**
  * @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()));
 }
Example #17
0
        $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);
            }
        }
    }
Example #18
0
 /**
  * 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;
 }
Example #19
0
 /**
  * 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();
     }
 }
Example #20
0
 /**
  * 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;
 }