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  namespace mod_lti\local;
  18  
  19  use core\context\course;
  20  
  21  /**
  22   * Helper class specifically dealing with LTI types (preconfigured tools).
  23   *
  24   * @package    mod_lti
  25   * @copyright  2023 Jake Dallimore <jrhdallimore@gmail.com>
  26   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27   */
  28  class types_helper {
  29  
  30      /**
  31       * Returns all LTI tool types (preconfigured tools) visible in the given course and for the given user.
  32       *
  33       * This list will contain both site level tools and course-level tools.
  34       *
  35       * @param int $courseid the id of the course.
  36       * @param int $userid the id of the user.
  37       * @param array $coursevisible options for 'coursevisible' field, which will default to
  38       *        [LTI_COURSEVISIBLE_PRECONFIGURED, LTI_COURSEVISIBLE_ACTIVITYCHOOSER] if omitted.
  39       * @return \stdClass[] the array of tool type objects.
  40       */
  41      public static function get_lti_types_by_course(int $courseid, int $userid, array $coursevisible = []): array {
  42          global $DB, $SITE;
  43  
  44          if (!has_capability('mod/lti:addpreconfiguredinstance', course::instance($courseid), $userid)) {
  45              return [];
  46          }
  47  
  48          if (empty($coursevisible)) {
  49              $coursevisible = [LTI_COURSEVISIBLE_PRECONFIGURED, LTI_COURSEVISIBLE_ACTIVITYCHOOSER];
  50          }
  51          [$coursevisiblesql, $coursevisparams] = $DB->get_in_or_equal($coursevisible, SQL_PARAMS_NAMED, 'coursevisible');
  52          [$coursevisiblesql1, $coursevisparams1] = $DB->get_in_or_equal($coursevisible, SQL_PARAMS_NAMED, 'coursevisible');
  53          [$coursevisibleoverriddensql, $coursevisoverriddenparams] = $DB->get_in_or_equal(
  54              $coursevisible,
  55              SQL_PARAMS_NAMED,
  56              'coursevisibleoverridden');
  57  
  58          $coursecond = implode(" OR ", ["t.course = :courseid", "t.course = :siteid"]);
  59          $coursecategory = $DB->get_field('course', 'category', ['id' => $courseid]);
  60          $query = "SELECT *
  61                      FROM (SELECT t.*, c.coursevisible as coursevisibleoverridden
  62                              FROM {lti_types} t
  63                         LEFT JOIN {lti_types_categories} tc ON t.id = tc.typeid
  64                         LEFT JOIN {lti_coursevisible} c ON c.typeid = t.id AND c.courseid = $courseid
  65                             WHERE (t.coursevisible $coursevisiblesql
  66                                   OR (c.coursevisible $coursevisiblesql1 AND t.coursevisible NOT IN (:lticoursevisibleno)))
  67                               AND ($coursecond)
  68                               AND t.state = :active
  69                               AND (tc.id IS NULL OR tc.categoryid = :categoryid)) tt
  70                     WHERE tt.coursevisibleoverridden IS NULL
  71                        OR tt.coursevisibleoverridden $coursevisibleoverriddensql";
  72  
  73          return $DB->get_records_sql(
  74              $query,
  75              [
  76                  'siteid' => $SITE->id,
  77                  'courseid' => $courseid,
  78                  'active' => LTI_TOOL_STATE_CONFIGURED,
  79                  'categoryid' => $coursecategory,
  80                  'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
  81                  'lticoursevisibleno' => LTI_COURSEVISIBLE_NO,
  82              ] + $coursevisparams + $coursevisparams1 + $coursevisoverriddenparams
  83          );
  84      }
  85  
  86      /**
  87       * Override coursevisible for a given tool on course level.
  88       *
  89       * @param int $tooltypeid Type ID
  90       * @param int $courseid Course ID
  91       * @param \core\context\course $context Course context
  92       * @param bool $showinactivitychooser Show or not show in activity chooser
  93       * @return bool True if the coursevisible was changed, false otherwise.
  94       */
  95      public static function override_type_showinactivitychooser(int $tooltypeid, int $courseid, \core\context\course $context, bool $showinactivitychooser): bool {
  96          global $DB;
  97  
  98          require_capability('mod/lti:addcoursetool', $context);
  99  
 100          $ltitype = lti_get_type($tooltypeid);
 101          if ($ltitype && ($ltitype->coursevisible != LTI_COURSEVISIBLE_NO)) {
 102              $coursevisible = $showinactivitychooser ? LTI_COURSEVISIBLE_ACTIVITYCHOOSER : LTI_COURSEVISIBLE_PRECONFIGURED;
 103              $ltitype->coursevisible = $coursevisible;
 104  
 105              $config = new \stdClass();
 106              $config->lti_coursevisible = $coursevisible;
 107  
 108              if (intval($ltitype->course) != intval(get_site()->id)) {
 109                  // It is course tool - just update it.
 110                  lti_update_type($ltitype, $config);
 111              } else {
 112                  $coursecategory = $DB->get_field('course', 'category', ['id' => $courseid]);
 113                  $sql = "SELECT COUNT(*) AS count
 114                        FROM {lti_types_categories} tc
 115                       WHERE tc.typeid = :typeid";
 116                  $restrictedtool = $DB->count_records_sql($sql, ['typeid' => $tooltypeid]);
 117                  if ($restrictedtool) {
 118                      $record = $DB->get_record('lti_types_categories', ['typeid' => $tooltypeid, 'categoryid' => $coursecategory]);
 119                      if (!$record) {
 120                          throw new \moodle_exception('You are not allowed to change this setting for this tool.');
 121                      }
 122                  }
 123  
 124                  // This is site tool, but we would like to have course level setting for it.
 125                  $lticoursevisible = $DB->get_record('lti_coursevisible', ['typeid' => $tooltypeid, 'courseid' => $courseid]);
 126                  if (!$lticoursevisible) {
 127                      $lticoursevisible = new \stdClass();
 128                      $lticoursevisible->typeid = $tooltypeid;
 129                      $lticoursevisible->courseid = $courseid;
 130                      $lticoursevisible->coursevisible = $coursevisible;
 131                      $DB->insert_record('lti_coursevisible', $lticoursevisible);
 132                  } else {
 133                      $lticoursevisible->coursevisible = $coursevisible;
 134                      $DB->update_record('lti_coursevisible', $lticoursevisible);
 135                  }
 136              }
 137              return true;
 138          }
 139          return false;
 140      }
 141  
 142  }