Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.
   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   * Contains class mod_h5pactivity\output\reportlink
  19   *
  20   * @package   mod_h5pactivity
  21   * @copyright 2020 Ferran Recio
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_h5pactivity\output;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  use mod_h5pactivity\local\attempt as activity_attempt;
  30  use renderable;
  31  use templatable;
  32  use renderer_base;
  33  use moodle_url;
  34  use user_picture;
  35  use stdClass;
  36  
  37  /**
  38   * Class to help display report link in mod_h5pactivity.
  39   *
  40   * @copyright 2020 Ferran Recio
  41   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   */
  43  class attempt implements renderable, templatable {
  44  
  45      /** @var activity_attempt attempt */
  46      public $attempt;
  47  
  48      /** @var stdClass user record */
  49      public $user;
  50  
  51      /** @var int courseid necesary to present user picture */
  52      public $courseid;
  53  
  54      /**
  55       * Constructor.
  56       *
  57       * @param activity_attempt $attempt the attempt object
  58       * @param stdClass $user a user record (default null).
  59       * @param int $courseid optional course id (default null).
  60       */
  61      public function __construct(activity_attempt $attempt, stdClass $user = null, int $courseid = null) {
  62          $this->attempt = $attempt;
  63          $this->user = $user;
  64          $this->courseid = $courseid;
  65      }
  66  
  67      /**
  68       * Export this data so it can be used as the context for a mustache template.
  69       *
  70       * @param renderer_base $output
  71       * @return stdClass
  72       */
  73      public function export_for_template(renderer_base $output) {
  74          $attempt = $this->attempt;
  75  
  76          $data = (object)[
  77              'id' => $attempt->get_id(),
  78              'h5pactivityid' => $attempt->get_h5pactivityid(),
  79              'userid' => $attempt->get_userid(),
  80              'timecreated' => $attempt->get_timecreated(),
  81              'timemodified' => $attempt->get_timemodified(),
  82              'attempt' => $attempt->get_attempt(),
  83              'rawscore' => $attempt->get_rawscore(),
  84              'maxscore' => $attempt->get_maxscore(),
  85              'duration' => '-',
  86              'durationcompact' => '-',
  87              'completion' => $attempt->get_completion(),
  88              'completionicon' => $this->completion_icon($output, $attempt->get_completion()),
  89              'completiontext' => $this->completion_icon($output, $attempt->get_completion(), true),
  90              'success' => $attempt->get_success(),
  91              'successicon' => $this->success_icon($output, $attempt->get_success()),
  92              'successtext' => $this->success_icon($output, $attempt->get_success(), true),
  93              'scaled' => $attempt->get_scaled(),
  94              'reporturl' => new moodle_url('/mod/h5pactivity/report.php', [
  95                  'a' => $attempt->get_h5pactivityid(), 'attemptid' => $attempt->get_id()
  96              ]),
  97          ];
  98          if ($attempt->get_duration() !== null) {
  99              $data->durationvalue = $attempt->get_duration();
 100              $duration = $this->extract_duration($data->durationvalue);
 101              $data->duration = $this->format_duration($duration);
 102              $data->durationcompact = $this->format_duration_short($duration);
 103          }
 104  
 105          if (!empty($data->maxscore)) {
 106              $data->score = get_string('score_out_of', 'mod_h5pactivity', $data);
 107          }
 108          if ($this->user) {
 109              $data->user = $this->user;
 110              $userpicture = new user_picture($this->user);
 111              $userpicture->courseid = $this->courseid;
 112              $data->user->picture = $output->render($userpicture);
 113              $data->user->fullname = fullname($this->user);
 114          }
 115          return $data;
 116      }
 117  
 118      /**
 119       * Return a completion icon HTML.
 120       *
 121       * @param renderer_base $output the renderer base object
 122       * @param int|null $completion the current completion value
 123       * @param bool $showtext if the icon must have a text or only icon
 124       * @return string icon HTML
 125       */
 126      private function completion_icon(renderer_base $output, int $completion = null, bool $showtext = false): string {
 127          if ($completion === null) {
 128              return '';
 129          }
 130          if ($completion) {
 131              $alt = get_string('attempt_completion_yes', 'mod_h5pactivity');
 132              $icon = 'i/completion-auto-y';
 133          } else {
 134              $alt = get_string('attempt_completion_no', 'mod_h5pactivity');
 135              $icon = 'i/completion-auto-n';
 136          }
 137          $text = '';
 138          if ($showtext) {
 139              $text = $alt;
 140              $alt = '';
 141          }
 142          return $output->pix_icon($icon, $alt).$text;
 143      }
 144  
 145      /**
 146       * Return a success icon
 147       * @param renderer_base $output the renderer base object
 148       * @param int|null $success the current success value
 149       * @param bool $showtext if the icon must have a text or only icon
 150       * @return string icon HTML
 151       */
 152      private function success_icon(renderer_base $output, int $success = null, bool $showtext = false): string {
 153          if ($success === null) {
 154              $alt = get_string('attempt_success_unknown', 'mod_h5pactivity');
 155              if ($showtext) {
 156                  return $alt;
 157              }
 158              $icon = 'i/empty';
 159          } else if ($success) {
 160              $alt = get_string('attempt_success_pass', 'mod_h5pactivity');
 161              $icon = 'i/checkedcircle';
 162          } else {
 163              $alt = get_string('attempt_success_fail', 'mod_h5pactivity');
 164              $icon = 'i/uncheckedcircle';
 165          }
 166          $text = '';
 167          if ($showtext) {
 168              $text = $alt;
 169              $alt = '';
 170          }
 171          return $output->pix_icon($icon, $alt).$text;
 172      }
 173  
 174      /**
 175       * Return the duration in long format (localized)
 176       *
 177       * @param stdClass $duration object with (h)hours, (m)minutes and (s)seconds
 178       * @return string the long format duration
 179       */
 180      private function format_duration (stdClass $duration): string {
 181          $result = [];
 182          if ($duration->h) {
 183              $result[] = get_string('numhours', 'moodle', $duration->h);
 184          }
 185          if ($duration->m) {
 186              $result[] = get_string('numminutes', 'moodle', $duration->m);
 187          }
 188          if ($duration->s) {
 189              $result[] = get_string('numseconds', 'moodle', $duration->s);
 190          }
 191          return implode(' ', $result);
 192      }
 193  
 194      /**
 195       * Return the duration en short format (for example: 145' 43'')
 196       *
 197       * Note: this method is used to make duration responsive.
 198       *
 199       * @param stdClass $duration object with (h)hours, (m)minutes and (s)seconds
 200       * @return string the short format duration
 201       */
 202      private function format_duration_short (stdClass $duration): string {
 203          $result = [];
 204          if ($duration->h || $duration->m) {
 205              $result[] = ($duration->h * 60 + $duration->m)."'";
 206          }
 207          if ($duration->s) {
 208              $result[] = $duration->s."''";
 209          }
 210          return implode(' ', $result);
 211      }
 212  
 213      /**
 214       * Extract hours and minutes from second duration.
 215       *
 216       * Note: this function is used to generate the param for format_duration
 217       * and format_duration_short
 218       *
 219       * @param int $seconds number of second
 220       * @return stdClass with (h)hours, (m)minutes and (s)seconds
 221       */
 222      private function extract_duration (int $seconds): stdClass {
 223          $h = floor($seconds / 3600);
 224          $m = floor(($seconds - $h * 3600) / 60);
 225          $s = $seconds - ($h * 3600 + $m * 60);
 226          return (object)['h' => $h, 'm' => $m, 's' => $s];
 227      }
 228  }