2009-05-26 02:46:09 +00:00
< ? php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2008-07-24 08:38:03 +00:00
/**
2012-01-05 12:05:02 +07:00
* Functions for interacting with the message system
2008-07-24 08:38:03 +00:00
*
2012-01-05 12:05:02 +07:00
* @ package core_message
* @ copyright 2008 Luis Rodrigues and Martin Dougiamas
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2008-07-24 08:38:03 +00:00
*/
2010-07-25 13:35:05 +00:00
defined ( 'MOODLE_INTERNAL' ) || die ();
2016-02-26 17:47:58 +11:00
require_once ( __DIR__ . '/../message/lib.php' );
2011-05-19 17:25:39 +01:00
2008-07-24 08:38:03 +00:00
/**
2009-11-07 10:27:57 +00:00
* Called when a message provider wants to send a message .
2012-02-22 11:15:42 +13:00
* This functions checks the message recipient ' s message processor configuration then
2012-01-05 12:05:02 +07:00
* sends the message to the configured processors
2009-11-07 10:27:57 +00:00
*
2012-03-22 17:20:59 +01:00
* Required parameters of the $eventdata object :
2010-11-09 06:47:53 +00:00
* component string component name . must exist in message_providers
* name string message type name . must exist in message_providers
2011-05-27 10:07:26 +01:00
* userfrom object | int the user sending the message
* userto object | int the message recipient
2010-10-27 08:47:33 +00:00
* subject string the message subject
2012-03-22 17:20:59 +01:00
* 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
2009-11-07 10:27:57 +00:00
*
2014-06-10 17:21:40 +12:00
* Note : processor failure is is not reported as false return value ,
* earlier versions did not do it consistently either .
*
2016-10-28 00:06:31 +02:00
* @ todo MDL - 55449 Drop support for stdClass in Moodle 3.6
2012-01-05 12:05:02 +07:00
* @ category message
2016-07-20 12:40:34 +01:00
* @ param \core\message\message $eventdata information about the message ( component , userfrom , userto , ... )
2014-06-10 17:21:40 +12:00
* @ return mixed the integer ID of the new message or false if there was a problem with submitted data
2008-07-24 08:38:03 +00:00
*/
2009-11-07 10:27:57 +00:00
function message_send ( $eventdata ) {
2008-07-24 08:38:03 +00:00
global $CFG , $DB ;
2016-10-28 00:06:31 +02:00
// TODO MDL-55449 Drop support for stdClass in Moodle 3.6.
2016-07-20 12:40:34 +01:00
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 );
}
2011-02-10 13:25:38 +08:00
//new message ID to return
$messageid = false ;
2013-11-20 15:25:17 +08:00
// 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 ;
}
2014-04-04 17:53:25 +02:00
// By default a message is a notification. Only personal/private messages aren't notifications.
if ( ! isset ( $eventdata -> notification )) {
$eventdata -> notification = 1 ;
}
2014-06-10 17:21:40 +12:00
if ( ! is_object ( $eventdata -> userto )) {
2013-08-30 14:28:17 +08:00
$eventdata -> userto = core_user :: get_user ( $eventdata -> userto );
2010-10-27 08:47:33 +00:00
}
2014-06-10 17:21:40 +12:00
if ( ! is_object ( $eventdata -> userfrom )) {
2013-08-30 14:28:17 +08:00
$eventdata -> userfrom = core_user :: get_user ( $eventdata -> userfrom );
2010-10-27 08:47:33 +00:00
}
2014-06-10 17:21:40 +12:00
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 );
}
2013-08-30 14:28:17 +08:00
$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 ;
}
2010-07-06 01:52:32 +00:00
//after how long inactive should the user be considered logged off?
2008-07-24 08:38:03 +00:00
if ( isset ( $CFG -> block_online_users_timetosee )) {
$timetoshowusers = $CFG -> block_online_users_timetosee * 60 ;
} else {
2010-07-06 01:52:32 +00:00
$timetoshowusers = 300 ; //5 minutes
2008-07-24 08:38:03 +00:00
}
2010-07-06 01:52:32 +00:00
// Work out if the user is logged in or not
2010-11-19 05:18:34 +00:00
if ( ! empty ( $eventdata -> userto -> lastaccess ) && ( time () - $timetoshowusers ) < $eventdata -> userto -> lastaccess ) {
2008-07-24 08:38:03 +00:00
$userstate = 'loggedin' ;
2010-07-06 01:52:32 +00:00
} else {
$userstate = 'loggedoff' ;
2008-07-24 08:38:03 +00:00
}
2009-11-01 11:31:16 +00:00
2010-07-06 01:52:32 +00:00
// Create the message object
2010-09-21 08:07:44 +00:00
$savemessage = new stdClass ();
2016-07-20 12:40:34 +01:00
$savemessage -> courseid = $eventdata -> courseid ;
2008-07-24 08:38:03 +00:00
$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 ;
2014-04-04 17:53:25 +02:00
$savemessage -> notification = $eventdata -> notification ;
2016-06-16 07:41:02 +00:00
$savemessage -> eventtype = $eventdata -> name ;
$savemessage -> component = $eventdata -> component ;
2010-10-08 02:49:53 +00:00
2010-10-26 08:00:29 +00:00
if ( ! empty ( $eventdata -> contexturl )) {
2014-06-10 17:21:40 +12:00
$savemessage -> contexturl = ( string ) $eventdata -> contexturl ;
2010-10-26 08:00:29 +00:00
} else {
$savemessage -> contexturl = null ;
}
if ( ! empty ( $eventdata -> contexturlname )) {
2014-06-10 17:21:40 +12:00
$savemessage -> contexturlname = ( string ) $eventdata -> contexturlname ;
2010-10-26 08:00:29 +00:00
} else {
$savemessage -> contexturlname = null ;
}
2010-10-08 02:49:53 +00:00
$savemessage -> timecreated = time ();
2008-07-24 08:38:03 +00:00
2012-10-13 17:48:06 +02:00
if ( PHPUNIT_TEST and class_exists ( 'phpunit_util' )) {
// Add some more tests to make sure the normal code can actually work.
2013-07-16 22:42:37 +02:00
$componentdir = core_component :: get_component_directory ( $eventdata -> component );
2012-10-13 17:48:06 +02:00
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 ;
}
}
2011-05-19 17:25:39 +01:00
// 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 ) {
2013-08-30 14:28:17 +08:00
// 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 ;
}
2011-05-19 17:25:39 +01:00
// First find out permissions
$defaultpreference = $processor -> name . '_provider_' . $preferencebase . '_permitted' ;
2011-05-31 09:46:22 +01:00
if ( isset ( $defaultpreferences -> { $defaultpreference })) {
2011-05-19 17:25:39 +01:00
$permitted = $defaultpreferences -> { $defaultpreference };
} else {
2012-10-30 11:03:12 +08:00
// 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 );
2010-11-09 06:01:20 +00:00
}
2011-05-19 17:25:39 +01:00
// Find out if user has configured this output
2011-08-16 14:06:11 +08:00
// Some processors cannot function without settings from the user
2011-05-31 09:07:38 +01:00
$userisconfigured = $processor -> object -> is_user_configured ( $eventdata -> userto );
2011-05-19 17:25:39 +01:00
2011-06-24 14:19:40 +08:00
// DEBUG: notify if we are forcing unconfigured output
2011-05-31 09:07:38 +01:00
if ( $permitted == 'forced' && ! $userisconfigured ) {
2011-05-19 17:25:39 +01:00
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
2011-05-31 09:07:38 +01:00
if ( $permitted == 'forced' && $userisconfigured ) {
2011-11-16 13:01:55 +08:00
// An admin is forcing users to use this message processor. Use this processor unconditionally.
2011-05-19 17:25:39 +01:00
$processorlist [] = $processor -> name ;
2011-08-16 14:06:11 +08:00
} else if ( $permitted == 'permitted' && $userisconfigured && ! $eventdata -> userto -> emailstop ) {
2011-11-16 13:01:55 +08:00
// User has not disabled notifications
// See if user set any notification preferences, otherwise use site default ones
2011-05-19 17:25:39 +01:00
$userpreferencename = 'message_provider_' . $preferencebase . '_' . $userstate ;
2014-06-10 17:21:40 +12:00
if ( $userpreference = get_user_preferences ( $userpreferencename , null , $eventdata -> userto )) {
2011-05-19 17:25:39 +01:00
if ( in_array ( $processor -> name , explode ( ',' , $userpreference ))) {
$processorlist [] = $processor -> name ;
}
2011-05-31 09:46:22 +01:00
} else if ( isset ( $defaultpreferences -> { $userpreferencename })) {
2011-05-19 17:25:39 +01:00
if ( in_array ( $processor -> name , explode ( ',' , $defaultpreferences -> { $userpreferencename }))) {
$processorlist [] = $processor -> name ;
}
}
}
2008-08-02 00:04:29 +00:00
}
2008-07-24 08:38:03 +00:00
2016-10-20 06:01:57 +00:00
// Only cache messages, not notifications.
if ( empty ( $savemessage -> notification )) {
// Cache the timecreated value of the last message between these two users.
2016-11-10 12:47:20 +08:00
$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 );
2016-10-20 06:01:57 +00:00
$cache -> set ( $key , $savemessage -> timecreated );
}
2014-06-10 17:21:40 +12:00
// 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 ;
2014-02-19 21:25:51 -08:00
2014-06-10 17:21:40 +12:00
// Let the manager do the sending or buffering when db transaction in progress.
return \core\message\manager :: send_message ( $eventdata , $savemessage , $processorlist );
2008-07-24 08:38:03 +00:00
}
2008-07-31 08:01:46 +00:00
/**
2012-01-05 12:05:02 +07:00
* Updates the message_providers table with the current set of message providers
2011-05-27 09:28:09 +01:00
*
2012-01-05 12:05:02 +07:00
* @ param string $component For example 'moodle' , 'mod_forum' or 'block_quiz_results'
* @ return boolean True on success
2008-07-31 08:01:46 +00:00
*/
function message_update_providers ( $component = 'moodle' ) {
global $DB ;
// load message providers from files
$fileproviders = message_get_providers_from_file ( $component );
// load message providers from the database
$dbproviders = message_get_providers_from_db ( $component );
foreach ( $fileproviders as $messagename => $fileprovider ) {
if ( ! empty ( $dbproviders [ $messagename ])) { // Already exists in the database
2011-05-31 10:55:30 +01:00
// check if capability has changed
2008-07-31 08:01:46 +00:00
if ( $dbproviders [ $messagename ] -> capability == $fileprovider [ 'capability' ]) { // Same, so ignore
// exact same message provider already present in db, ignore this entry
unset ( $dbproviders [ $messagename ]);
continue ;
} else { // Update existing one
2010-09-21 08:07:44 +00:00
$provider = new stdClass ();
2009-11-07 10:27:57 +00:00
$provider -> id = $dbproviders [ $messagename ] -> id ;
$provider -> capability = $fileprovider [ 'capability' ];
2008-07-31 08:01:46 +00:00
$DB -> update_record ( 'message_providers' , $provider );
unset ( $dbproviders [ $messagename ]);
continue ;
}
} else { // New message provider, add it
2010-09-21 08:07:44 +00:00
$provider = new stdClass ();
2008-07-31 08:01:46 +00:00
$provider -> name = $messagename ;
$provider -> component = $component ;
$provider -> capability = $fileprovider [ 'capability' ];
2011-05-20 15:10:27 +01:00
$transaction = $DB -> start_delegated_transaction ();
2008-07-31 08:01:46 +00:00
$DB -> insert_record ( 'message_providers' , $provider );
2011-05-20 15:10:27 +01:00
message_set_default_message_preference ( $component , $messagename , $fileprovider );
$transaction -> allow_commit ();
2008-07-31 08:01:46 +00:00
}
}
foreach ( $dbproviders as $dbprovider ) { // Delete old ones
$DB -> delete_records ( 'message_providers' , array ( 'id' => $dbprovider -> id ));
2011-05-31 10:55:30 +01:00
$DB -> delete_records_select ( 'config_plugins' , " plugin = 'message' AND " . $DB -> sql_like ( 'name' , '?' , false ), array ( " %_provider_ { $component } _ { $dbprovider -> name } _% " ));
$DB -> delete_records_select ( 'user_preferences' , $DB -> sql_like ( 'name' , '?' , false ), array ( " message_provider_ { $component } _ { $dbprovider -> name } _% " ));
2012-08-14 11:40:28 +12:00
cache_helper :: invalidate_by_definition ( 'core' , 'config' , array (), 'message' );
2008-07-31 08:01:46 +00:00
}
2011-05-31 10:05:39 +01:00
return true ;
2008-07-31 08:01:46 +00:00
}
2011-06-01 11:44:36 +01:00
/**
* This function populates default message preferences for all existing providers
* when the new message processor is added .
*
* @ param string $processorname The name of message processor plugin ( e . g . 'email' , 'jabber' )
2012-01-05 12:05:02 +07:00
* @ throws invalid_parameter_exception if $processorname does not exist in the database
2011-06-01 11:44:36 +01:00
*/
function message_update_processors ( $processorname ) {
global $DB ;
// validate if our processor exists
$processor = $DB -> get_records ( 'message_processors' , array ( 'name' => $processorname ));
if ( empty ( $processor )) {
throw new invalid_parameter_exception ();
}
$providers = $DB -> get_records_sql ( 'SELECT DISTINCT component FROM {message_providers}' );
$transaction = $DB -> start_delegated_transaction ();
foreach ( $providers as $provider ) {
// load message providers from files
$fileproviders = message_get_providers_from_file ( $provider -> component );
foreach ( $fileproviders as $messagename => $fileprovider ) {
message_set_default_message_preference ( $provider -> component , $messagename , $fileprovider , $processorname );
}
}
$transaction -> allow_commit ();
}
2011-05-20 15:10:27 +01:00
/**
2012-01-05 12:05:02 +07:00
* Setting default messaging preferences for particular message provider
2011-05-27 09:28:09 +01:00
*
2011-05-20 15:10:27 +01:00
* @ param string $component The name of component ( e . g . moodle , mod_forum , etc . )
* @ param string $messagename The name of message provider
* @ param array $fileprovider The value of $messagename key in the array defined in plugin messages . php
2012-01-05 12:05:02 +07:00
* @ param string $processorname The optional name of message processor
2011-05-20 15:10:27 +01:00
*/
2011-06-01 11:44:36 +01:00
function message_set_default_message_preference ( $component , $messagename , $fileprovider , $processorname = '' ) {
2011-05-20 15:10:27 +01:00
global $DB ;
// Fetch message processors
2011-06-01 11:44:36 +01:00
$condition = null ;
// If we need to process a particular processor, set the select condition
if ( ! empty ( $processorname )) {
$condition = array ( 'name' => $processorname );
}
$processors = $DB -> get_records ( 'message_processors' , $condition );
2011-05-20 15:10:27 +01:00
// load default messaging preferences
$defaultpreferences = get_message_output_default_preferences ();
2011-05-27 09:28:09 +01:00
// Setting default preference
2011-05-20 15:10:27 +01:00
$componentproviderbase = $component . '_' . $messagename ;
$loggedinpref = array ();
$loggedoffpref = array ();
2011-05-27 09:28:09 +01:00
// set 'permitted' preference first for each messaging processor
2011-05-20 15:10:27 +01:00
foreach ( $processors as $processor ) {
$preferencename = $processor -> name . '_provider_' . $componentproviderbase . '_permitted' ;
2011-05-27 09:28:09 +01:00
// if we do not have this setting yet, set it
2011-05-31 09:46:22 +01:00
if ( ! isset ( $defaultpreferences -> { $preferencename })) {
2011-05-20 15:10:27 +01:00
// determine plugin default settings
$plugindefault = 0 ;
if ( isset ( $fileprovider [ 'defaults' ][ $processor -> name ])) {
$plugindefault = $fileprovider [ 'defaults' ][ $processor -> name ];
}
// get string values of the settings
list ( $permitted , $loggedin , $loggedoff ) = translate_message_default_setting ( $plugindefault , $processor -> name );
// store default preferences for current processor
set_config ( $preferencename , $permitted , 'message' );
// save loggedin/loggedoff settings
if ( $loggedin ) {
$loggedinpref [] = $processor -> name ;
}
if ( $loggedoff ) {
$loggedoffpref [] = $processor -> name ;
}
}
}
2011-05-27 09:28:09 +01:00
// now set loggedin/loggedoff preferences
2011-05-20 15:10:27 +01:00
if ( ! empty ( $loggedinpref )) {
$preferencename = 'message_provider_' . $componentproviderbase . '_loggedin' ;
2011-06-01 11:44:36 +01:00
if ( isset ( $defaultpreferences -> { $preferencename })) {
// We have the default preferences for this message provider, which
// likely means that we have been adding a new processor. Add defaults
// to exisitng preferences.
$loggedinpref = array_merge ( $loggedinpref , explode ( ',' , $defaultpreferences -> { $preferencename }));
}
2011-05-20 15:10:27 +01:00
set_config ( $preferencename , join ( ',' , $loggedinpref ), 'message' );
}
if ( ! empty ( $loggedoffpref )) {
$preferencename = 'message_provider_' . $componentproviderbase . '_loggedoff' ;
2011-06-01 11:44:36 +01:00
if ( isset ( $defaultpreferences -> { $preferencename })) {
// We have the default preferences for this message provider, which
// likely means that we have been adding a new processor. Add defaults
// to exisitng preferences.
$loggedoffpref = array_merge ( $loggedoffpref , explode ( ',' , $defaultpreferences -> { $preferencename }));
}
2011-05-20 15:10:27 +01:00
set_config ( $preferencename , join ( ',' , $loggedoffpref ), 'message' );
}
}
2008-07-31 08:01:46 +00:00
/**
2011-05-28 08:46:47 +01:00
* Returns the active providers for the user specified , based on capability
2011-05-27 09:28:09 +01:00
*
2011-05-28 08:46:47 +01:00
* @ param int $userid id of user
2012-01-05 12:05:02 +07:00
* @ return array An array of message providers
2008-07-31 08:01:46 +00:00
*/
2011-05-28 08:46:47 +01:00
function message_get_providers_for_user ( $userid ) {
2011-07-05 15:23:37 +01:00
global $DB , $CFG ;
2008-07-31 08:01:46 +00:00
2012-05-15 16:55:21 +01:00
$providers = get_message_providers ();
2008-07-31 08:01:46 +00:00
2012-10-23 10:26:33 +08:00
// Ensure user is not allowed to configure instantmessage if it is globally disabled.
if ( ! $CFG -> messaging ) {
foreach ( $providers as $providerid => $provider ) {
if ( $provider -> name == 'instantmessage' ) {
unset ( $providers [ $providerid ]);
break ;
2008-07-31 08:01:46 +00:00
}
}
2012-10-23 10:26:33 +08:00
}
2012-04-19 18:03:18 +07:00
2012-10-23 10:26:33 +08:00
// If the component is an enrolment plugin, check it is enabled
foreach ( $providers as $providerid => $provider ) {
2013-07-16 22:41:00 +02:00
list ( $type , $name ) = core_component :: normalize_component ( $provider -> component );
2012-10-23 10:26:33 +08:00
if ( $type == 'enrol' && ! enrol_is_enabled ( $name )) {
2011-07-05 15:23:37 +01:00
unset ( $providers [ $providerid ]);
2012-10-23 10:26:33 +08:00
}
}
// Now we need to check capabilities. We need to eliminate the providers
// where the user does not have the corresponding capability anywhere.
// Here we deal with the common simple case of the user having the
// capability in the system context. That handles $CFG->defaultuserroleid.
// For the remaining providers/capabilities, we need to do a more complex
// query involving all overrides everywhere.
$unsureproviders = array ();
$unsurecapabilities = array ();
$systemcontext = context_system :: instance ();
foreach ( $providers as $providerid => $provider ) {
if ( empty ( $provider -> capability ) || has_capability ( $provider -> capability , $systemcontext , $userid )) {
// The provider is relevant to this user.
2012-04-19 18:03:18 +07:00
continue ;
}
2012-10-23 10:26:33 +08:00
$unsureproviders [ $providerid ] = $provider ;
$unsurecapabilities [ $provider -> capability ] = 1 ;
unset ( $providers [ $providerid ]);
}
if ( empty ( $unsureproviders )) {
// More complex checks are not required.
return $providers ;
}
// Now check the unsure capabilities.
list ( $capcondition , $params ) = $DB -> get_in_or_equal (
array_keys ( $unsurecapabilities ), SQL_PARAMS_NAMED );
$params [ 'userid' ] = $userid ;
$sql = " SELECT DISTINCT rc.capability, 1
FROM { role_assignments } ra
JOIN { context } actx ON actx . id = ra . contextid
JOIN { role_capabilities } rc ON rc . roleid = ra . roleid
JOIN { context } cctx ON cctx . id = rc . contextid
WHERE ra . userid = : userid
AND rc . capability $capcondition
AND rc . permission > 0
2012-11-13 15:09:14 +08:00
AND ( " . $DB->sql_concat ('actx.path', " '/' " ). " LIKE " . $DB->sql_concat ('cctx.path', " '/%' " ).
" OR " . $DB -> sql_concat ( 'cctx.path' , " '/' " ) . " LIKE " . $DB -> sql_concat ( 'actx.path' , " '/%' " ) . " ) " ;
2012-10-23 10:26:33 +08:00
if ( ! empty ( $CFG -> defaultfrontpageroleid )) {
$frontpagecontext = context_course :: instance ( SITEID );
list ( $capcondition2 , $params2 ) = $DB -> get_in_or_equal (
array_keys ( $unsurecapabilities ), SQL_PARAMS_NAMED );
$params = array_merge ( $params , $params2 );
$params [ 'frontpageroleid' ] = $CFG -> defaultfrontpageroleid ;
$params [ 'frontpagepathpattern' ] = $frontpagecontext -> path . '/' ;
$sql .= "
2012-11-13 22:34:36 +08:00
UNION
2012-10-23 10:26:33 +08:00
SELECT DISTINCT rc . capability , 1
FROM { role_capabilities } rc
JOIN { context } cctx ON cctx . id = rc . contextid
WHERE rc . roleid = : frontpageroleid
AND rc . capability $capcondition2
AND rc . permission > 0
2012-11-13 15:09:14 +08:00
AND " . $DB->sql_concat ('cctx.path', " '/' " ). " LIKE : frontpagepathpattern " ;
2012-10-23 10:26:33 +08:00
}
$relevantcapabilities = $DB -> get_records_sql_menu ( $sql , $params );
// Add back any providers based on the detailed capability check.
foreach ( $unsureproviders as $providerid => $provider ) {
if ( array_key_exists ( $provider -> capability , $relevantcapabilities )) {
$providers [ $providerid ] = $provider ;
2011-07-05 15:23:37 +01:00
}
2008-07-31 08:01:46 +00:00
}
return $providers ;
}
/**
* Gets the message providers that are in the database for this component .
2011-05-27 09:28:09 +01:00
*
2012-01-05 12:05:02 +07:00
* This is an internal function used within messagelib . php
2008-07-31 08:01:46 +00:00
*
2012-02-22 11:15:42 +13:00
* @ see message_update_providers ()
2012-01-05 12:05:02 +07:00
* @ param string $component A moodle component like 'moodle' , 'mod_forum' , 'block_quiz_results'
* @ return array An array of message providers
2008-07-31 08:01:46 +00:00
*/
function message_get_providers_from_db ( $component ) {
global $DB ;
2009-11-07 10:27:57 +00:00
return $DB -> get_records ( 'message_providers' , array ( 'component' => $component ), '' , 'name, id, component, capability' ); // Name is unique per component
2008-07-31 08:01:46 +00:00
}
/**
2012-01-05 12:05:02 +07:00
* Loads the messages definitions for a component from file
2011-05-27 09:28:09 +01:00
*
2012-01-05 12:05:02 +07:00
* If no messages are defined for the component , return an empty array .
* This is an internal function used within messagelib . php
2008-07-31 08:01:46 +00:00
*
2012-01-05 12:05:02 +07:00
* @ see message_update_providers ()
* @ see message_update_processors ()
* @ param string $component A moodle component like 'moodle' , 'mod_forum' , 'block_quiz_results'
* @ return array An array of message providers or empty array if not exists
2008-07-31 08:01:46 +00:00
*/
function message_get_providers_from_file ( $component ) {
2013-07-16 22:42:37 +02:00
$defpath = core_component :: get_component_directory ( $component ) . '/db/messages.php' ;
2008-07-31 08:01:46 +00:00
$messageproviders = array ();
if ( file_exists ( $defpath )) {
require ( $defpath );
}
foreach ( $messageproviders as $name => $messageprovider ) { // Fix up missing values if required
if ( empty ( $messageprovider [ 'capability' ])) {
$messageproviders [ $name ][ 'capability' ] = NULL ;
}
2011-05-20 15:10:27 +01:00
if ( empty ( $messageprovider [ 'defaults' ])) {
$messageproviders [ $name ][ 'defaults' ] = array ();
}
2008-07-31 08:01:46 +00:00
}
return $messageproviders ;
}
/**
2012-01-05 12:05:02 +07:00
* Remove all message providers for particular component and corresponding settings
2011-05-27 09:28:09 +01:00
*
2012-01-05 12:05:02 +07:00
* @ param string $component A moodle component like 'moodle' , 'mod_forum' , 'block_quiz_results'
2011-05-27 09:28:09 +01:00
* @ return void
2008-07-31 08:01:46 +00:00
*/
2011-06-02 09:27:05 +01:00
function message_provider_uninstall ( $component ) {
2010-09-17 07:58:04 +00:00
global $DB ;
2010-10-25 09:29:34 +00:00
2011-05-20 15:10:27 +01:00
$transaction = $DB -> start_delegated_transaction ();
$DB -> delete_records ( 'message_providers' , array ( 'component' => $component ));
$DB -> delete_records_select ( 'config_plugins' , " plugin = 'message' AND " . $DB -> sql_like ( 'name' , '?' , false ), array ( " %_provider_ { $component } _% " ));
$DB -> delete_records_select ( 'user_preferences' , $DB -> sql_like ( 'name' , '?' , false ), array ( " message_provider_ { $component } _% " ));
$transaction -> allow_commit ();
2012-08-14 11:40:28 +12:00
// Purge all messaging settings from the caches. They are stored by plugin so we have to clear all message settings.
cache_helper :: invalidate_by_definition ( 'core' , 'config' , array (), 'message' );
2008-08-02 00:04:29 +00:00
}
2011-06-02 09:27:05 +01:00
/**
2012-01-05 12:05:02 +07:00
* Uninstall a message processor
2011-06-02 09:27:05 +01:00
*
2012-01-05 12:05:02 +07:00
* @ param string $name A message processor name like 'email' , 'jabber'
2011-06-02 09:27:05 +01:00
*/
function message_processor_uninstall ( $name ) {
global $DB ;
$transaction = $DB -> start_delegated_transaction ();
$DB -> delete_records ( 'message_processors' , array ( 'name' => $name ));
2012-04-03 14:48:54 +01:00
$DB -> delete_records_select ( 'config_plugins' , " plugin = ? " , array ( " message_ { $name } " ));
2011-06-02 09:27:05 +01:00
// delete permission preferences only, we do not care about loggedin/loggedoff
// defaults, they will be removed on the next attempt to update the preferences
$DB -> delete_records_select ( 'config_plugins' , " plugin = 'message' AND " . $DB -> sql_like ( 'name' , '?' , false ), array ( " { $name } _provider_% " ));
$transaction -> allow_commit ();
2012-08-14 11:40:28 +12:00
// Purge all messaging settings from the caches. They are stored by plugin so we have to clear all message settings.
cache_helper :: invalidate_by_definition ( 'core' , 'config' , array (), array ( 'message' , " message_ { $name } " ));
2011-06-02 09:27:05 +01:00
}