diff --git a/lang/en/admin.php b/lang/en/admin.php index 1e9ed6bd92d..a83a8af3c50 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -969,11 +969,15 @@ $string['unsuspenduser'] = 'Activate user account'; $string['updateaccounts'] = 'Update existing accounts'; $string['updatecomponent'] = 'Update component'; $string['updateavailable'] = 'There is a newer Moodle version available!'; +$string['updateavailabledetailslink'] = 'See {$a->url} for more details'; +$string['updateavailableforplugin'] = 'There is a newer version for some of your plugins available!'; $string['updateavailable_moreinfo'] = 'More info...'; $string['updateavailable_release'] = 'Moodle {$a}'; $string['updateavailable_version'] = 'Version {$a}'; $string['updateavailablenot'] = 'Your Moodle code seems to be up-to-date'; $string['updatenotifications'] = 'Update notifications'; +$string['updatenotificationfooter'] = 'Your Moodle site {$a->siteurl} is configured to automatically check for available updates. You are receiving this message as the administrator of the site. You can disable automatic checks for available updates in the Site administration section of the Settings block. You can customize the delivery of this message via your personal Messaging setting in the My profile settings section.'; +$string['updatenotificationsubject'] = 'There are available updates for your Moodle site'; $string['updateautocheck'] = 'Automatically check for available updates'; $string['updateautocheck_desc'] = 'If enabled, your site will automatically check for available updates for both Moodle code and all installed extensions. If there is a new update available, a notification will be sent to site admins.'; $string['updateminmaturity'] = 'Required code maturity'; diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 764d5db4fb6..d76e8115b84 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -988,6 +988,7 @@ $string['memberincourse'] = 'People in the course'; $string['messagebody'] = 'Message body'; $string['messagedselectedusers'] = 'Selected users have been messaged and the recipient list has been reset.'; $string['messagedselectedusersfailed'] = 'Something went wrong while messaging selected users. Some may have received the email.'; +$string['messageprovider:availableupdate'] = 'Available update notifications'; $string['messageprovider:backup'] = 'Backup notifications'; $string['messageprovider:courserequestapproved'] = 'Course creation request approval notification'; $string['messageprovider:courserequested'] = 'Course creation request notification'; diff --git a/lib/db/messages.php b/lib/db/messages.php index db087fb5f3d..b736822c862 100644 --- a/lib/db/messages.php +++ b/lib/db/messages.php @@ -38,6 +38,15 @@ $messageproviders = array ( 'capability' => 'moodle/site:config' ), + // cron-based notifications about available moodle and/or additional plugin updates + 'availableupdate' => array( + 'capability' => 'moodle/site:config', + 'defaults' => array( + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF + ), + + ), + 'instantmessage' => array ( 'defaults' => array( 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, diff --git a/lib/pluginlib.php b/lib/pluginlib.php index 8d13c4c8473..401a6de1793 100644 --- a/lib/pluginlib.php +++ b/lib/pluginlib.php @@ -1085,7 +1085,7 @@ class available_update_checker { $changes = $this->compare_responses($previous, $current); $notifications = $this->cron_notifications($changes); $this->cron_notify($notifications); - $this->cron_mtrace('OK'); + $this->cron_mtrace('done'); } catch (available_update_checker_exception $e) { $this->cron_mtrace('FAILED!'); } @@ -1137,6 +1137,124 @@ class available_update_checker { return $notifications; } + + /** + * Sends the given notifications to site admins via messaging API + * + * @param array $notifications array of available_update_info objects to send + */ + protected function cron_notify(array $notifications) { + global $CFG; + + if (empty($notifications)) { + return; + } + + $admins = get_admins(); + + if (empty($admins)) { + return; + } + + $this->cron_mtrace('sending notifications ... ', ''); + + $text = get_string('updatenotifications', 'core_admin') . PHP_EOL; + $html = html_writer::tag('h1', get_string('updatenotifications', 'core_admin')) . PHP_EOL; + + $coreupdates = array(); + $pluginupdates = array(); + + foreach($notifications as $notification) { + if ($notification->component == 'core') { + $coreupdates[] = $notification; + } else { + $pluginupdates[] = $notification; + } + } + + if (!empty($coreupdates)) { + $text .= PHP_EOL . get_string('updateavailable', 'core_admin') . PHP_EOL; + $html .= html_writer::tag('h2', get_string('updateavailable', 'core_admin')) . PHP_EOL; + $html .= html_writer::start_tag('ul') . PHP_EOL; + foreach ($coreupdates as $coreupdate) { + $html .= html_writer::start_tag('li'); + if (isset($coreupdate->release)) { + $text .= get_string('updateavailable_release', 'core_admin', $coreupdate->release); + $html .= html_writer::tag('strong', get_string('updateavailable_release', 'core_admin', $coreupdate->release)); + } + if (isset($coreupdate->version)) { + $text .= ' '.get_string('updateavailable_version', 'core_admin', $coreupdate->version); + $html .= ' '.get_string('updateavailable_version', 'core_admin', $coreupdate->version); + } + if (isset($coreupdate->maturity)) { + $text .= ' ('.get_string('maturity'.$coreupdate->maturity, 'core_admin').')'; + $html .= ' ('.get_string('maturity'.$coreupdate->maturity, 'core_admin').')'; + } + $text .= PHP_EOL; + $html .= html_writer::end_tag('li') . PHP_EOL; + } + $text .= PHP_EOL; + $html .= html_writer::end_tag('ul') . PHP_EOL; + + $a = array('url' => $CFG->wwwroot.'/'.$CFG->admin.'/index.php'); + $text .= get_string('updateavailabledetailslink', 'core_admin', $a) . PHP_EOL; + $a = array('url' => html_writer::link($CFG->wwwroot.'/'.$CFG->admin.'/index.php', $CFG->wwwroot.'/'.$CFG->admin.'/index.php')); + $html .= html_writer::tag('p', get_string('updateavailabledetailslink', 'core_admin', $a)) . PHP_EOL; + } + + if (!empty($pluginupdates)) { + $text .= PHP_EOL . get_string('updateavailableforplugin', 'core_admin') . PHP_EOL; + $html .= html_writer::tag('h2', get_string('updateavailableforplugin', 'core_admin')) . PHP_EOL; + + $html .= html_writer::start_tag('ul') . PHP_EOL; + foreach ($pluginupdates as $pluginupdate) { + $html .= html_writer::start_tag('li'); + $text .= get_string('pluginname', $pluginupdate->component); + $html .= html_writer::tag('strong', get_string('pluginname', $pluginupdate->component)); + + $text .= ' ('.$pluginupdate->component.')'; + $html .= ' ('.$pluginupdate->component.')'; + + $text .= ' '.get_string('updateavailable', 'core_plugin', $pluginupdate->version); + $html .= ' '.get_string('updateavailable', 'core_plugin', $pluginupdate->version); + + $text .= PHP_EOL; + $html .= html_writer::end_tag('li') . PHP_EOL; + } + $text .= PHP_EOL; + $html .= html_writer::end_tag('ul') . PHP_EOL; + + $a = array('url' => $CFG->wwwroot.'/'.$CFG->admin.'/plugins.php'); + $text .= get_string('updateavailabledetailslink', 'core_admin', $a) . PHP_EOL; + $a = array('url' => html_writer::link($CFG->wwwroot.'/'.$CFG->admin.'/plugins.php', $CFG->wwwroot.'/'.$CFG->admin.'/plugins.php')); + $html .= html_writer::tag('p', get_string('updateavailabledetailslink', 'core_admin', $a)) . PHP_EOL; + } + + $a = array('siteurl' => $CFG->wwwroot); + $text .= get_string('updatenotificationfooter', 'core_admin', $a) . PHP_EOL; + $a = array('siteurl' => html_writer::link($CFG->wwwroot, $CFG->wwwroot)); + $html .= html_writer::tag('footer', html_writer::tag('p', get_string('updatenotificationfooter', 'core_admin', $a), + array('style' => 'font-size:smaller; color:#333;'))); + + $mainadmin = reset($admins); + + foreach ($admins as $admin) { + $message = new stdClass(); + $message->component = 'moodle'; + $message->name = 'availableupdate'; + $message->userfrom = $mainadmin; + $message->userto = $admin; + $message->subject = get_string('updatenotifications', 'core_admin'); + $message->fullmessage = $text; + $message->fullmessageformat = FORMAT_PLAIN; + $message->fullmessagehtml = $html; + $message->smallmessage = 'TODO'; + $message->notification = 0; + $message->contexturl = 'http://glum/admin/TODO'; + $message->contexturlname = 'View details TODO'; + message_send($message); + } + } }