Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 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 enrol_lti\local\ltiadvantage\repository;
  18  use core_availability\info_module;
  19  use enrol_lti\local\ltiadvantage\viewobject\published_resource;
  20  
  21  /**
  22   * Class published_resource_repository for fetching the published_resource instances from the store.
  23   *
  24   * @package enrol_lti
  25   * @copyright 2021 Jake Dallimore <jrhdallimore@gmail.com>
  26   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27   */
  28  class published_resource_repository {
  29  
  30      /**
  31       * Convert a list of stdClasses to a list of published_resource instances.
  32       *
  33       * @param array $records the records.
  34       * @return array the array of published_resource instances.
  35       */
  36      private function published_resources_from_records(array $records): array {
  37          $publishedresources = [];
  38          foreach ($records as $record) {
  39              $publishedresource = new published_resource(
  40                  $record->name,
  41                  $record->coursefullname,
  42                  $record->courseid,
  43                  $record->contextid,
  44                  $record->id,
  45                  $record->uuid,
  46                  $record->supportsgrades,
  47                  $record->grademax ?? null,
  48                  $record->iscourse,
  49              );
  50              $publishedresources[] = $publishedresource;
  51          }
  52          return $publishedresources;
  53      }
  54  
  55      /**
  56       * Given a list of published resources, return a list of those which are available to the provided user.
  57       *
  58       * @param array $resources the array of records representing published resources.
  59       * @param int $userid the Moodle user id to check.
  60       * @return array an array of stdClasses containing data about resources which are available to the current user.
  61       */
  62      private function get_available_resources_from_records(array $resources, int $userid): array {
  63          global $CFG;
  64          require_once($CFG->libdir . '/gradelib.php');
  65          require_once($CFG->libdir . '/moodlelib.php');
  66  
  67          $availableresources = [];
  68  
  69          foreach ($resources as $resource) {
  70              if ($resource->contextlevel == CONTEXT_COURSE) {
  71                  // Shared item is a course.
  72                  if (!can_access_course(get_course($resource->courseid), $userid)) {
  73                      continue;
  74                  }
  75                  $resource->name = format_string($resource->coursefullname, true, ['context' => $resource->contextid]);
  76                  $resource->coursefullname = $resource->name;
  77                  $resource->iscourse = true;
  78                  $resource->supportsgrades = true;
  79  
  80                  $coursegradeitem = \grade_item::fetch_course_item($resource->courseid);
  81                  $resource->grademax = $coursegradeitem->grademax;
  82  
  83                  $availableresources[] = $resource;
  84              } else if ($resource->contextlevel = CONTEXT_MODULE) {
  85                  // Shared item is a module.
  86                  $resource->coursefullname = format_string($resource->coursefullname, true,
  87                      ['context' => $resource->contextid]);
  88  
  89                  $mods = get_fast_modinfo($resource->courseid, $userid)->get_cms();
  90                  foreach ($mods as $mod) {
  91                      if ($mod->context->id == $resource->contextid) {
  92                          if (info_module::is_user_visible($mod->id, $userid, true)) {
  93  
  94                              $resource->iscourse = false;
  95                              $resource->name = $mod->name;
  96                              $resource->supportsgrades = false;
  97                              $resource->grademax = null;
  98  
  99                              // Only activities with GRADE_TYPE_VALUE are valid.
 100                              if (plugin_supports('mod', $mod->modname, FEATURE_GRADE_HAS_GRADE)) {
 101                                  $gradeitem = \grade_item::fetch([
 102                                      'courseid' => $resource->courseid,
 103                                      'itemtype' => 'mod',
 104                                      'itemmodule' => $mod->modname,
 105                                      'iteminstance' => $mod->instance
 106                                  ]);
 107                                  if ($gradeitem && $gradeitem->gradetype == GRADE_TYPE_VALUE) {
 108                                      $gradinginfo = grade_get_grades($resource->courseid, 'mod', $mod->modname,
 109                                          $mod->instance);
 110                                      $resource->supportsgrades = true;
 111                                      $resource->grademax = (int) $gradinginfo->items[0]->grademax;
 112                                  }
 113                              }
 114                              $availableresources[] = $resource;
 115                          }
 116                      }
 117                  }
 118              }
 119          }
 120          return $availableresources;
 121      }
 122  
 123      /**
 124       * Find all published resources which are visible to the given user.
 125       *
 126       * @param int $userid the id of the user to check.
 127       * @return published_resource[] an array of published_resource view objects instances.
 128       */
 129      public function find_all_for_user(int $userid): array {
 130          global $DB, $CFG;
 131          require_once($CFG->libdir . '/accesslib.php');
 132          require_once($CFG->libdir . '/enrollib.php');
 133          require_once($CFG->libdir . '/moodlelib.php');
 134          require_once($CFG->libdir . '/modinfolib.php');
 135          require_once($CFG->libdir . '/weblib.php');
 136  
 137          [$insql, $inparams] = $DB->get_in_or_equal(['LTI-1p3'], SQL_PARAMS_NAMED);
 138          $sql = "SELECT elt.id, elt.uuid, elt.enrolid, elt.contextid, elt.institution, elt.lang, elt.timezone,
 139                         elt.maxenrolled, elt.maildisplay, elt.city, elt.country, elt.gradesync, elt.gradesynccompletion,
 140                         elt.membersync, elt.membersyncmode, elt.roleinstructor, elt.rolelearner, e.name AS enrolname,
 141                         e.courseid, ctx.contextlevel, c.fullname AS coursefullname
 142                    FROM {enrol} e
 143                    JOIN {enrol_lti_tools} elt
 144                      ON (e.id = elt.enrolid and e.status = :enrolstatusenabled)
 145                    JOIN {course} c
 146                      ON (c.id = e.courseid)
 147                    JOIN {context} ctx
 148                      ON (ctx.id = elt.contextid)
 149                   WHERE elt.ltiversion $insql
 150                ORDER BY courseid";
 151          $params = array_merge($inparams, ['enrolstatusenabled' => ENROL_INSTANCE_ENABLED]);
 152          $resources = $DB->get_records_sql($sql, $params);
 153  
 154          // Only users who have the ability to publish content should see published content.
 155          $resources = array_filter($resources, function($resource) use ($userid) {
 156              return has_capability('enrol/lti:config', \context_course::instance($resource->courseid), $userid);
 157          });
 158  
 159          // Make sure the user can access each course or module, excluding those which are inaccessible from the return.
 160          $availableresources = $this->get_available_resources_from_records($resources, $userid);
 161  
 162          return $this->published_resources_from_records($availableresources);
 163      }
 164  
 165      /**
 166       * Find all published_resource instances matching the supplied ids for the current user.
 167       *
 168       * @param array $ids the array containing object ids to lookup
 169       * @param int $userid the id of the user to check
 170       * @return array an array of published_resource instances which are available to the user.
 171       */
 172      public function find_all_by_ids_for_user(array $ids, int $userid): array {
 173          global $DB, $CFG;
 174  
 175          if (empty($ids)) {
 176              return [];
 177          }
 178  
 179          require_once($CFG->libdir . '/accesslib.php');
 180          require_once($CFG->libdir . '/enrollib.php');
 181          require_once($CFG->libdir . '/moodlelib.php');
 182          require_once($CFG->libdir . '/modinfolib.php');
 183          require_once($CFG->libdir . '/weblib.php');
 184  
 185          [$insql, $inparams] = $DB->get_in_or_equal(['LTI-1p3'], SQL_PARAMS_NAMED);
 186          [$idsinsql, $idsinparams] = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED);
 187          $sql = "SELECT elt.id, elt.uuid, elt.enrolid, elt.contextid, elt.institution, elt.lang, elt.timezone,
 188                         elt.maxenrolled, elt.maildisplay, elt.city, elt.country, elt.gradesync, elt.gradesynccompletion,
 189                         elt.membersync, elt.membersyncmode, elt.roleinstructor, elt.rolelearner, e.name AS enrolname,
 190                         e.courseid, ctx.contextlevel, c.fullname AS coursefullname
 191                    FROM {enrol} e
 192                    JOIN {enrol_lti_tools} elt
 193                      ON (e.id = elt.enrolid and e.status = :enrolstatusenabled)
 194                    JOIN {course} c
 195                      ON (c.id = e.courseid)
 196                    JOIN {context} ctx
 197                      ON (ctx.id = elt.contextid)
 198                   WHERE elt.ltiversion $insql
 199                     AND elt.id $idsinsql
 200                ORDER BY courseid";
 201          $params = array_merge($inparams, $idsinparams, ['enrolstatusenabled' => ENROL_INSTANCE_ENABLED]);
 202          $resources = $DB->get_records_sql($sql, $params);
 203  
 204          // Make sure the user can access each course or module, excluding those which are inaccessible from the return.
 205          $availableresources = $this->get_available_resources_from_records($resources, $userid);
 206  
 207          return $this->published_resources_from_records($availableresources);
 208      }
 209  }