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 311 and 401] [Versions 400 and 401] [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  /**
  18   * File containing the class activity information renderable.
  19   *
  20   * @package    core_course
  21   * @copyright  2021 Jun Pataleta <jun@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace core_course\output;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use cm_info;
  29  use completion_info;
  30  use context;
  31  use core\activity_dates;
  32  use core_availability\info;
  33  use core_completion\cm_completion_details;
  34  use core_user;
  35  use core_user\fields;
  36  use renderable;
  37  use renderer_base;
  38  use stdClass;
  39  use templatable;
  40  
  41  /**
  42   * The activity information renderable class.
  43   *
  44   * @package    core_course
  45   * @copyright  2021 Jun Pataleta <jun@moodle.com>
  46   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  47   */
  48  class activity_information implements renderable, templatable {
  49  
  50      /** @var cm_info The course module information. */
  51      protected $cminfo = null;
  52  
  53      /** @var array The array of relevant dates for this activity. */
  54      protected $activitydates = [];
  55  
  56      /** @var cm_completion_details The user's completion details for this activity. */
  57      protected $cmcompletion = null;
  58  
  59      /**
  60       * Constructor.
  61       *
  62       * @param cm_info $cminfo The course module information.
  63       * @param cm_completion_details $cmcompletion The course module information.
  64       * @param array $activitydates The activity dates.
  65       */
  66      public function __construct(cm_info $cminfo, cm_completion_details $cmcompletion, array $activitydates) {
  67          $this->cminfo = $cminfo;
  68          $this->cmcompletion = $cmcompletion;
  69          $this->activitydates = $activitydates;
  70      }
  71  
  72      /**
  73       * Export this data so it can be used as the context for a mustache template.
  74       *
  75       * @param renderer_base $output Renderer base.
  76       * @return stdClass
  77       */
  78      public function export_for_template(renderer_base $output): stdClass {
  79          $data = $this->build_completion_data();
  80  
  81          $data->cmid = $this->cminfo->id;
  82          $data->activityname = $this->cminfo->get_formatted_name();
  83          $this->build_dates_data($data);
  84          $data->hasdates = !empty($this->activitydates);
  85  
  86          return $data;
  87      }
  88  
  89      /**
  90       * Builds the dates data for export.
  91       *
  92       * @param stdClass $data
  93       */
  94      protected function build_dates_data(stdClass $data): void {
  95          foreach ($this->activitydates as $date) {
  96              if (empty($date['relativeto'])) {
  97                  $date['datestring'] = userdate($date['timestamp'], get_string('strftimedaydatetime', 'core_langconfig'));
  98              } else {
  99                  $diffstr = get_time_interval_string($date['timestamp'], $date['relativeto']);
 100                  if ($date['timestamp'] >= $date['relativeto']) {
 101                      $date['datestring'] = get_string('relativedatessubmissionduedateafter', 'core_course',
 102                          ['datediffstr' => $diffstr]);
 103                  } else {
 104                      $date['datestring'] = get_string('relativedatessubmissionduedatebefore', 'core_course',
 105                          ['datediffstr' => $diffstr]);
 106                  }
 107              }
 108              $data->activitydates[] = $date;
 109          }
 110      }
 111  
 112      /**
 113       * Builds the completion data for export.
 114       *
 115       * @return stdClass
 116       */
 117      protected function build_completion_data(): stdClass {
 118          global $CFG;
 119  
 120          $data = new stdClass();
 121  
 122          $data->hascompletion = $this->cmcompletion->has_completion();
 123          $data->isautomatic = $this->cmcompletion->is_automatic();
 124          $data->showmanualcompletion = $this->cmcompletion->show_manual_completion();
 125  
 126          // Get the name of the user overriding the completion condition, if available.
 127          $data->overrideby = null;
 128          $overrideby = $this->cmcompletion->overridden_by();
 129          $overridebyname = null;
 130          if (!empty($overrideby)) {
 131              $userfields = fields::for_name();
 132              $overridebyrecord = core_user::get_user($overrideby, 'id ' . $userfields->get_sql()->selects, MUST_EXIST);
 133              $data->overrideby = fullname($overridebyrecord);
 134          }
 135  
 136          // We'll show only the completion conditions and not the completion status if we're not tracking completion for this user
 137          // (e.g. a teacher, admin).
 138          $data->istrackeduser = $this->cmcompletion->is_tracked_user();
 139  
 140          // Overall completion states.
 141          $overallcompletion = $this->cmcompletion->get_overall_completion();
 142          $data->overallcomplete = $overallcompletion == COMPLETION_COMPLETE;
 143          $data->overallincomplete = $overallcompletion == COMPLETION_INCOMPLETE;
 144  
 145          // Set an accessible description for manual completions with overridden completion state.
 146          if (!$data->isautomatic && $data->overrideby) {
 147              $setbydata = (object)[
 148                  'activityname' => $this->cminfo->get_formatted_name(),
 149                  'setby' => $data->overrideby,
 150              ];
 151              $setbylangkey = $data->overallcomplete ? 'completion_setby:manual:done' : 'completion_setby:manual:markdone';
 152              $data->accessibledescription = get_string($setbylangkey, 'course', $setbydata);
 153          }
 154  
 155          // Whether the completion of this activity controls the availability of other activities/sections in the course.
 156          $data->withavailability = false;
 157          $course = $this->cminfo->get_course();
 158          // An activity with manual completion tracking which is used to enable access to other activities/sections in
 159          // the course needs to refresh the page after having its completion state toggled. This withavailability flag will enable
 160          // this functionality on the course homepage. Otherwise, the completion toggling will just happen normally via ajax.
 161          if ($this->cmcompletion->has_completion() && !$this->cmcompletion->is_automatic()) {
 162              $data->withavailability = !empty($CFG->enableavailability) && info::completion_value_used($course, $this->cminfo->id);
 163          }
 164  
 165          // Whether this activity is visible to the user. If not, completion information will not be shown.
 166          $data->uservisible = $this->cminfo->uservisible;
 167  
 168          // Build automatic completion details.
 169          $details = [];
 170          foreach ($this->cmcompletion->get_details() as $key => $detail) {
 171              // Set additional attributes for the template.
 172              $detail->key = $key;
 173              $detail->statuscomplete = in_array($detail->status, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]);
 174              $detail->statuscompletefail = $detail->status == COMPLETION_COMPLETE_FAIL;
 175              // This is not used by core themes but may be needed in custom themes.
 176              $detail->statuscompletepass = $detail->status == COMPLETION_COMPLETE_PASS;
 177              $detail->statusincomplete = $detail->status == COMPLETION_INCOMPLETE;
 178  
 179              // Add an accessible description to be used for title and aria-label attributes for overridden completion details.
 180              if ($data->overrideby) {
 181                  $setbydata = (object)[
 182                      'condition' => $detail->description,
 183                      'setby' => $data->overrideby,
 184                  ];
 185                  $overridestatus = $detail->statuscomplete ? 'done' : 'todo';
 186                  $detail->accessibledescription = get_string('completion_setby:auto:' . $overridestatus, 'course', $setbydata);
 187              }
 188  
 189              // We don't need the status in the template.
 190              unset($detail->status);
 191  
 192              $details[] = $detail;
 193          }
 194          $data->completiondetails = $details;
 195  
 196          return $data;
 197      }
 198  }