|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 require_once(dirname(dirname(__FILE__)) . '/message/lib.php'); 00030 00052 function message_send($eventdata) { 00053 global $CFG, $DB; 00054 00055 //new message ID to return 00056 $messageid = false; 00057 00058 //TODO: we need to solve problems with database transactions here somehow, for now we just prevent transactions - sorry 00059 $DB->transactions_forbidden(); 00060 00061 if (is_int($eventdata->userto)) { 00062 $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto)); 00063 } 00064 if (is_int($eventdata->userfrom)) { 00065 $eventdata->userfrom = $DB->get_record('user', array('id' => $eventdata->userfrom)); 00066 } 00067 if (!isset($eventdata->userto->auth) or !isset($eventdata->userto->suspended) or !isset($eventdata->userto->deleted)) { 00068 $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto->id)); 00069 } 00070 00071 //after how long inactive should the user be considered logged off? 00072 if (isset($CFG->block_online_users_timetosee)) { 00073 $timetoshowusers = $CFG->block_online_users_timetosee * 60; 00074 } else { 00075 $timetoshowusers = 300;//5 minutes 00076 } 00077 00078 // Work out if the user is logged in or not 00079 if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) { 00080 $userstate = 'loggedin'; 00081 } else { 00082 $userstate = 'loggedoff'; 00083 } 00084 00085 // Create the message object 00086 $savemessage = new stdClass(); 00087 $savemessage->useridfrom = $eventdata->userfrom->id; 00088 $savemessage->useridto = $eventdata->userto->id; 00089 $savemessage->subject = $eventdata->subject; 00090 $savemessage->fullmessage = $eventdata->fullmessage; 00091 $savemessage->fullmessageformat = $eventdata->fullmessageformat; 00092 $savemessage->fullmessagehtml = $eventdata->fullmessagehtml; 00093 $savemessage->smallmessage = $eventdata->smallmessage; 00094 00095 if (!empty($eventdata->notification)) { 00096 $savemessage->notification = $eventdata->notification; 00097 } else { 00098 $savemessage->notification = 0; 00099 } 00100 00101 if (!empty($eventdata->contexturl)) { 00102 $savemessage->contexturl = $eventdata->contexturl; 00103 } else { 00104 $savemessage->contexturl = null; 00105 } 00106 00107 if (!empty($eventdata->contexturlname)) { 00108 $savemessage->contexturlname = $eventdata->contexturlname; 00109 } else { 00110 $savemessage->contexturlname = null; 00111 } 00112 00113 $savemessage->timecreated = time(); 00114 00115 // Fetch enabled processors 00116 $processors = get_message_processors(true); 00117 // Fetch default (site) preferences 00118 $defaultpreferences = get_message_output_default_preferences(); 00119 00120 // Preset variables 00121 $processorlist = array(); 00122 $preferencebase = $eventdata->component.'_'.$eventdata->name; 00123 // Fill in the array of processors to be used based on default and user preferences 00124 foreach ($processors as $processor) { 00125 // First find out permissions 00126 $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; 00127 if (isset($defaultpreferences->{$defaultpreference})) { 00128 $permitted = $defaultpreferences->{$defaultpreference}; 00129 } else { 00130 //MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't 00131 //exist in the message_provider table (thus there is no default settings for them) 00132 $preferrormsg = get_string('couldnotfindpreference', 'message', $preferencename); //TODO: undefined $preferencename 00133 throw new coding_exception($preferrormsg,'blah'); 00134 } 00135 00136 // Find out if user has configured this output 00137 // Some processors cannot function without settings from the user 00138 $userisconfigured = $processor->object->is_user_configured($eventdata->userto); 00139 00140 // DEBUG: notify if we are forcing unconfigured output 00141 if ($permitted == 'forced' && !$userisconfigured) { 00142 debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL); 00143 } 00144 00145 // Warn developers that necessary data is missing regardless of how the processors are configured 00146 if (!isset($eventdata->userto->emailstop)) { 00147 debugging('userto->emailstop is not set. Retrieving it from the user table'); 00148 $eventdata->userto->emailstop = $DB->get_field('user', 'emailstop', array('id'=>$eventdata->userto->id)); 00149 } 00150 00151 // Populate the list of processors we will be using 00152 if ($permitted == 'forced' && $userisconfigured) { 00153 // An admin is forcing users to use this message processor. Use this processor unconditionally. 00154 $processorlist[] = $processor->name; 00155 } else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) { 00156 // User has not disabled notifications 00157 // See if user set any notification preferences, otherwise use site default ones 00158 $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; 00159 if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto->id)) { 00160 if (in_array($processor->name, explode(',', $userpreference))) { 00161 $processorlist[] = $processor->name; 00162 } 00163 } else if (isset($defaultpreferences->{$userpreferencename})) { 00164 if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { 00165 $processorlist[] = $processor->name; 00166 } 00167 } 00168 } 00169 } 00170 00171 if (empty($processorlist) && $savemessage->notification) { 00172 //if they have deselected all processors and its a notification mark it read. The user doesnt want to be bothered 00173 $savemessage->timeread = time(); 00174 $messageid = $DB->insert_record('message_read', $savemessage); 00175 } else { // Process the message 00176 // Store unread message just in case we can not send it 00177 $messageid = $savemessage->id = $DB->insert_record('message', $savemessage); 00178 $eventdata->savedmessageid = $savemessage->id; 00179 00180 // Try to deliver the message to each processor 00181 if (!empty($processorlist)) { 00182 foreach ($processorlist as $procname) { 00183 if (!$processors[$procname]->object->send_message($eventdata)) { 00184 debugging('Error calling message processor '.$procname); 00185 $messageid = false; 00186 } 00187 } 00188 00189 //if messaging is disabled and they previously had forum notifications handled by the popup processor 00190 //or any processor that puts a row in message_working then the notification will remain forever 00191 //unread. To prevent this mark the message read if messaging is disabled 00192 if (empty($CFG->messaging)) { 00193 require_once($CFG->dirroot.'/message/lib.php'); 00194 $messageid = message_mark_message_read($savemessage, time()); 00195 } else if ( $DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0){ 00196 //if there is no more processors that want to process this we can move message to message_read 00197 require_once($CFG->dirroot.'/message/lib.php'); 00198 $messageid = message_mark_message_read($savemessage, time(), true); 00199 } 00200 } 00201 } 00202 00203 return $messageid; 00204 } 00205 00206 00213 function message_update_providers($component='moodle') { 00214 global $DB; 00215 00216 // load message providers from files 00217 $fileproviders = message_get_providers_from_file($component); 00218 00219 // load message providers from the database 00220 $dbproviders = message_get_providers_from_db($component); 00221 00222 foreach ($fileproviders as $messagename => $fileprovider) { 00223 00224 if (!empty($dbproviders[$messagename])) { // Already exists in the database 00225 // check if capability has changed 00226 if ($dbproviders[$messagename]->capability == $fileprovider['capability']) { // Same, so ignore 00227 // exact same message provider already present in db, ignore this entry 00228 unset($dbproviders[$messagename]); 00229 continue; 00230 00231 } else { // Update existing one 00232 $provider = new stdClass(); 00233 $provider->id = $dbproviders[$messagename]->id; 00234 $provider->capability = $fileprovider['capability']; 00235 $DB->update_record('message_providers', $provider); 00236 unset($dbproviders[$messagename]); 00237 continue; 00238 } 00239 00240 } else { // New message provider, add it 00241 00242 $provider = new stdClass(); 00243 $provider->name = $messagename; 00244 $provider->component = $component; 00245 $provider->capability = $fileprovider['capability']; 00246 00247 $transaction = $DB->start_delegated_transaction(); 00248 $DB->insert_record('message_providers', $provider); 00249 message_set_default_message_preference($component, $messagename, $fileprovider); 00250 $transaction->allow_commit(); 00251 } 00252 } 00253 00254 foreach ($dbproviders as $dbprovider) { // Delete old ones 00255 $DB->delete_records('message_providers', array('id' => $dbprovider->id)); 00256 $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("%_provider_{$component}_{$dbprovider->name}_%")); 00257 $DB->delete_records_select('user_preferences', $DB->sql_like('name', '?', false), array("message_provider_{$component}_{$dbprovider->name}_%")); 00258 } 00259 00260 return true; 00261 } 00262 00271 function message_update_processors($processorname) { 00272 global $DB; 00273 00274 // validate if our processor exists 00275 $processor = $DB->get_records('message_processors', array('name' => $processorname)); 00276 if (empty($processor)) { 00277 throw new invalid_parameter_exception(); 00278 } 00279 00280 $providers = $DB->get_records_sql('SELECT DISTINCT component FROM {message_providers}'); 00281 00282 $transaction = $DB->start_delegated_transaction(); 00283 foreach ($providers as $provider) { 00284 // load message providers from files 00285 $fileproviders = message_get_providers_from_file($provider->component); 00286 foreach ($fileproviders as $messagename => $fileprovider) { 00287 message_set_default_message_preference($provider->component, $messagename, $fileprovider, $processorname); 00288 } 00289 } 00290 $transaction->allow_commit(); 00291 } 00292 00302 function message_set_default_message_preference($component, $messagename, $fileprovider, $processorname='') { 00303 global $DB; 00304 00305 // Fetch message processors 00306 $condition = null; 00307 // If we need to process a particular processor, set the select condition 00308 if (!empty($processorname)) { 00309 $condition = array('name' => $processorname); 00310 } 00311 $processors = $DB->get_records('message_processors', $condition); 00312 00313 // load default messaging preferences 00314 $defaultpreferences = get_message_output_default_preferences(); 00315 00316 // Setting default preference 00317 $componentproviderbase = $component.'_'.$messagename; 00318 $loggedinpref = array(); 00319 $loggedoffpref = array(); 00320 // set 'permitted' preference first for each messaging processor 00321 foreach ($processors as $processor) { 00322 $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_permitted'; 00323 // if we do not have this setting yet, set it 00324 if (!isset($defaultpreferences->{$preferencename})) { 00325 // determine plugin default settings 00326 $plugindefault = 0; 00327 if (isset($fileprovider['defaults'][$processor->name])) { 00328 $plugindefault = $fileprovider['defaults'][$processor->name]; 00329 } 00330 // get string values of the settings 00331 list($permitted, $loggedin, $loggedoff) = translate_message_default_setting($plugindefault, $processor->name); 00332 // store default preferences for current processor 00333 set_config($preferencename, $permitted, 'message'); 00334 // save loggedin/loggedoff settings 00335 if ($loggedin) { 00336 $loggedinpref[] = $processor->name; 00337 } 00338 if ($loggedoff) { 00339 $loggedoffpref[] = $processor->name; 00340 } 00341 } 00342 } 00343 // now set loggedin/loggedoff preferences 00344 if (!empty($loggedinpref)) { 00345 $preferencename = 'message_provider_'.$componentproviderbase.'_loggedin'; 00346 if (isset($defaultpreferences->{$preferencename})) { 00347 // We have the default preferences for this message provider, which 00348 // likely means that we have been adding a new processor. Add defaults 00349 // to exisitng preferences. 00350 $loggedinpref = array_merge($loggedinpref, explode(',', $defaultpreferences->{$preferencename})); 00351 } 00352 set_config($preferencename, join(',', $loggedinpref), 'message'); 00353 } 00354 if (!empty($loggedoffpref)) { 00355 $preferencename = 'message_provider_'.$componentproviderbase.'_loggedoff'; 00356 if (isset($defaultpreferences->{$preferencename})) { 00357 // We have the default preferences for this message provider, which 00358 // likely means that we have been adding a new processor. Add defaults 00359 // to exisitng preferences. 00360 $loggedoffpref = array_merge($loggedoffpref, explode(',', $defaultpreferences->{$preferencename})); 00361 } 00362 set_config($preferencename, join(',', $loggedoffpref), 'message'); 00363 } 00364 } 00365 00375 function message_get_my_providers() { 00376 global $USER; 00377 return message_get_providers_for_user($USER->id); 00378 } 00379 00386 function message_get_providers_for_user($userid) { 00387 global $DB, $CFG; 00388 00389 $systemcontext = get_context_instance(CONTEXT_SYSTEM); 00390 00391 $providers = $DB->get_records('message_providers', null, 'name'); 00392 00393 // Remove all the providers we aren't allowed to see now 00394 foreach ($providers as $providerid => $provider) { 00395 if (!empty($provider->capability)) { 00396 if (!has_capability($provider->capability, $systemcontext, $userid)) { 00397 unset($providers[$providerid]); // Not allowed to see this 00398 } 00399 } 00400 // Ensure user is not allowed to configure instantmessage if it is globally disabled. 00401 if (!$CFG->messaging && $provider->name == 'instantmessage') { 00402 unset($providers[$providerid]); 00403 } 00404 } 00405 00406 return $providers; 00407 } 00408 00417 function message_get_providers_from_db($component) { 00418 global $DB; 00419 00420 return $DB->get_records('message_providers', array('component'=>$component), '', 'name, id, component, capability'); // Name is unique per component 00421 } 00422 00432 function message_get_providers_from_file($component) { 00433 $defpath = get_component_directory($component).'/db/messages.php'; 00434 00435 $messageproviders = array(); 00436 00437 if (file_exists($defpath)) { 00438 require($defpath); 00439 } 00440 00441 foreach ($messageproviders as $name => $messageprovider) { // Fix up missing values if required 00442 if (empty($messageprovider['capability'])) { 00443 $messageproviders[$name]['capability'] = NULL; 00444 } 00445 if (empty($messageprovider['defaults'])) { 00446 $messageproviders[$name]['defaults'] = array(); 00447 } 00448 } 00449 00450 return $messageproviders; 00451 } 00452 00459 function message_provider_uninstall($component) { 00460 global $DB; 00461 00462 $transaction = $DB->start_delegated_transaction(); 00463 $DB->delete_records('message_providers', array('component' => $component)); 00464 $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("%_provider_{$component}_%")); 00465 $DB->delete_records_select('user_preferences', $DB->sql_like('name', '?', false), array("message_provider_{$component}_%")); 00466 $transaction->allow_commit(); 00467 } 00468 00475 function message_processor_uninstall($name) { 00476 global $DB; 00477 00478 $transaction = $DB->start_delegated_transaction(); 00479 $DB->delete_records('message_processors', array('name' => $name)); 00480 // delete permission preferences only, we do not care about loggedin/loggedoff 00481 // defaults, they will be removed on the next attempt to update the preferences 00482 $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("{$name}_provider_%")); 00483 $transaction->allow_commit(); 00484 }