Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace core_course\task;
  18  
  19  use core\task\adhoc_task;
  20  
  21  /**
  22   * Class handling course content updates notifications.
  23   *
  24   * @package core_course
  25   * @copyright 2021 Juan Leyva <juan@moodle.com>
  26   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27   */
  28  class content_notification_task extends adhoc_task {
  29  
  30      // Use the logging trait for better logging.
  31      use \core\task\logging_trait;
  32  
  33      /**
  34       * Run the main task.
  35       */
  36      public function execute() {
  37          global $CFG, $OUTPUT;
  38          require_once($CFG->libdir . '/enrollib.php');
  39  
  40          $data = $this->get_custom_data();
  41  
  42          $course = get_course($data->courseid);
  43          $modinfo = get_fast_modinfo($course);
  44          $cm = $modinfo->cms[$data->cmid];
  45          $isupdate = !empty($data->update);
  46  
  47          if (!$course->visible || !$cm->visible) {
  48              // The course or module is hidden. We don't check if the user can see hidden courses, does not make sense here.
  49              // Permissions may have changed since it was queued.
  50              return;
  51          }
  52  
  53          // Get only active users.
  54          $coursecontext = \context_course::instance($course->id);
  55          $modcontext = \context_module::instance($cm->id);
  56          $users = get_enrolled_users($coursecontext, '', 0, 'u.*', null, 0, 0, true);
  57  
  58          if (empty($users)) {
  59              return;
  60          }
  61  
  62          $userfrom = \core_user::get_user($data->userfrom);
  63  
  64          // Now send the messages
  65          $countusers = count($users);
  66          $sentcount = $errorcount = 0;
  67          $this->log_start("Sending course content update notifications to {$countusers} potential users
  68              from user with id {$userfrom->id}.");
  69          foreach ($users as $user) {
  70  
  71              cron_setup_user($user, $course);
  72  
  73              $cm = get_fast_modinfo($course)->cms[$cm->id];
  74  
  75              if (!$cm->uservisible && !$cm->is_visible_on_course_page()) {
  76                  // User can't access or see the activity in the course page.
  77                  $this->log("Ignoring user {$user->id} (no permissions to see the module)", 1);
  78                  continue;
  79              }
  80  
  81              // Get module names in the user's language.
  82              $modnames = get_module_types_names();
  83              $a = [
  84                  'coursename' => format_string(get_course_display_name_for_list($course), true, ['context' => $modcontext]),
  85                  'courselink' => (new \moodle_url('/course/view.php', ['id' => $course->id]))->out(false),
  86                  'modulename' => format_string($cm->name, $modcontext->id),
  87                  'moduletypename' => $modnames[$cm->modname],
  88                  'link' => (new \moodle_url('/mod/' . $cm->modname . '/view.php', ['id' => $cm->id]))->out(false),
  89                  'notificationpreferenceslink' =>
  90                      (new \moodle_url('/message/notificationpreferences.php', ['userid' => $user->id]))->out(false),
  91              ];
  92  
  93              if ($isupdate) {
  94                  $messagesubject = get_string('coursecontentnotifupdate', 'course', $a);
  95                  $messagebody = get_string('coursecontentnotifupdatebody', 'course', $a);
  96              } else {
  97                  $messagesubject = get_string('coursecontentnotifnew', 'course', $a);
  98                  $messagebody = get_string('coursecontentnotifnewbody', 'course', $a);
  99              }
 100  
 101              // Send notification.
 102              $eventdata = new \core\message\message();
 103              $eventdata->courseid = $course->id;
 104              $eventdata->component = 'moodle';
 105              $eventdata->name = 'coursecontentupdated';
 106              $eventdata->userfrom = $userfrom;
 107              $eventdata->userto = $user;
 108              $eventdata->subject = $messagesubject;
 109              $eventdata->fullmessageformat = FORMAT_HTML;
 110              $eventdata->fullmessagehtml = $messagebody;
 111              $eventdata->smallmessage = strip_tags($eventdata->fullmessagehtml);
 112              $eventdata->contexturl = (new \moodle_url('/mod/' . $cm->modname . '/view.php', ['id' => $cm->id]))->out(false);
 113              $eventdata->contexturlname = $cm->name;
 114              $eventdata->notification = 1;
 115  
 116              // Add notification custom data.
 117              $eventcustomdata = ['notificationiconurl' => $cm->get_icon_url()->out(false)];
 118              if ($courseimage = \core_course\external\course_summary_exporter::get_course_image($course)) {
 119                  $eventcustomdata['notificationpictureurl'] = $courseimage;
 120              }
 121              $eventdata->customdata = $eventcustomdata;
 122  
 123              $completion = \core_completion\cm_completion_details::get_instance($cm, $user->id);
 124              $activitydates = \core\activity_dates::get_dates_for_module($cm, $user->id);
 125              if (!empty($activitydates)) {
 126                  $activityinfo = new \core_course\output\activity_information($cm, $completion, $activitydates);
 127                  $data = $activityinfo->export_for_template($OUTPUT);
 128                  foreach ($data->activitydates as $date) {
 129                      $eventdata->fullmessagehtml .= \html_writer::div($date['label'] . ' ' . $date['datestring']);
 130                  }
 131              }
 132              $eventdata->fullmessage = html_to_text($eventdata->fullmessagehtml);
 133  
 134              if (message_send($eventdata)) {
 135                  $this->log("Notification sent to user with id {$user->id}", 1);
 136                  $sentcount++;
 137              } else {
 138                  $this->log("Failed to send notification to user with id {$user->id}", 1);
 139                  $errorcount++;
 140              }
 141          }
 142  
 143          $this->log_finish("Sent {$sentcount} notifications with {$errorcount} failures");
 144      }
 145  }