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 400 and 401]

   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 having a single grade item of GRADE_TYPE_VALUE are eligible for declarative binding.
 100                              if (plugin_supports('mod', $mod->modname, FEATURE_GRADE_HAS_GRADE)) {
 101                                  $gradinginfo = grade_get_grades($resource->courseid, 'mod', $mod->modname, $mod->instance);
 102                                  if (count($gradinginfo->items) == 1) {
 103                                      $gradeitem = \grade_item::fetch([
 104                                          'courseid' => $resource->courseid,
 105                                          'itemtype' => 'mod',
 106                                          'itemmodule' => $mod->modname,
 107                                          'iteminstance' => $mod->instance
 108                                      ]);
 109                                      if ($gradeitem && $gradeitem->gradetype == GRADE_TYPE_VALUE) {
 110                                          $resource->supportsgrades = true;
 111                                          $resource->grademax = (int)$gradinginfo->items[0]->grademax;
 112                                      }
 113                                  }
 114                              }
 115                              $availableresources[] = $resource;
 116                          }
 117                      }
 118                  }
 119              }
 120          }
 121          return $availableresources;
 122      }
 123  
 124      /**
 125       * Find all published resources which are visible to the given user.
 126       *
 127       * @param int $userid the id of the user to check.
 128       * @return published_resource[] an array of published_resource view objects instances.
 129       */
 130      public function find_all_for_user(int $userid): array {
 131          global $DB, $CFG;
 132          require_once($CFG->libdir . '/accesslib.php');
 133          require_once($CFG->libdir . '/enrollib.php');
 134          require_once($CFG->libdir . '/moodlelib.php');
 135          require_once($CFG->libdir . '/modinfolib.php');
 136          require_once($CFG->libdir . '/weblib.php');
 137  
 138          [$insql, $inparams] = $DB->get_in_or_equal(['LTI-1p3'], SQL_PARAMS_NAMED);
 139          $sql = "SELECT elt.id, elt.uuid, elt.enrolid, elt.contextid, elt.institution, elt.lang, elt.timezone,
 140                         elt.maxenrolled, elt.maildisplay, elt.city, elt.country, elt.gradesync, elt.gradesynccompletion,
 141                         elt.membersync, elt.membersyncmode, elt.roleinstructor, elt.rolelearner, e.name AS enrolname,
 142                         e.courseid, ctx.contextlevel, c.fullname AS coursefullname
 143                    FROM {enrol} e
 144                    JOIN {enrol_lti_tools} elt
 145                      ON (e.id = elt.enrolid and e.status = :enrolstatusenabled)
 146                    JOIN {course} c
 147                      ON (c.id = e.courseid)
 148                    JOIN {context} ctx
 149                      ON (ctx.id = elt.contextid)
 150                   WHERE elt.ltiversion $insql
 151                ORDER BY courseid";
 152          $params = array_merge($inparams, ['enrolstatusenabled' => ENROL_INSTANCE_ENABLED]);
 153          $resources = $DB->get_records_sql($sql, $params);
 154  
 155          // Only users who have the ability to publish content should see published content.
 156          $resources = array_filter($resources, function($resource) use ($userid) {
 157              return has_capability('enrol/lti:config', \context_course::instance($resource->courseid), $userid);
 158          });
 159  
 160          // Make sure the user can access each course or module, excluding those which are inaccessible from the return.
 161          $availableresources = $this->get_available_resources_from_records($resources, $userid);
 162  
 163          return $this->published_resources_from_records($availableresources);
 164      }
 165  
 166      /**
 167       * Find all published_resource instances matching the supplied ids for the current user.
 168       *
 169       * @param array $ids the array containing object ids to lookup
 170       * @param int $userid the id of the user to check
 171       * @return array an array of published_resource instances which are available to the user.
 172       */
 173      public function find_all_by_ids_for_user(array $ids, int $userid): array {
 174          global $DB, $CFG;
 175  
 176          if (empty($ids)) {
 177              return [];
 178          }
 179  
 180          require_once($CFG->libdir . '/accesslib.php');
 181          require_once($CFG->libdir . '/enrollib.php');
 182          require_once($CFG->libdir . '/moodlelib.php');
 183          require_once($CFG->libdir . '/modinfolib.php');
 184          require_once($CFG->libdir . '/weblib.php');
 185  
 186          [$insql, $inparams] = $DB->get_in_or_equal(['LTI-1p3'], SQL_PARAMS_NAMED);
 187          [$idsinsql, $idsinparams] = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED);
 188          $sql = "SELECT elt.id, elt.uuid, elt.enrolid, elt.contextid, elt.institution, elt.lang, elt.timezone,
 189                         elt.maxenrolled, elt.maildisplay, elt.city, elt.country, elt.gradesync, elt.gradesynccompletion,
 190                         elt.membersync, elt.membersyncmode, elt.roleinstructor, elt.rolelearner, e.name AS enrolname,
 191                         e.courseid, ctx.contextlevel, c.fullname AS coursefullname
 192                    FROM {enrol} e
 193                    JOIN {enrol_lti_tools} elt
 194                      ON (e.id = elt.enrolid and e.status = :enrolstatusenabled)
 195                    JOIN {course} c
 196                      ON (c.id = e.courseid)
 197                    JOIN {context} ctx
 198                      ON (ctx.id = elt.contextid)
 199                   WHERE elt.ltiversion $insql
 200                     AND elt.id $idsinsql
 201                ORDER BY courseid";
 202          $params = array_merge($inparams, $idsinparams, ['enrolstatusenabled' => ENROL_INSTANCE_ENABLED]);
 203          $resources = $DB->get_records_sql($sql, $params);
 204  
 205          // Make sure the user can access each course or module, excluding those which are inaccessible from the return.
 206          $availableresources = $this->get_available_resources_from_records($resources, $userid);
 207  
 208          return $this->published_resources_from_records($availableresources);
 209      }
 210  }