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 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [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   * External tool module external API
  19   *
  20   * @package    mod_lti
  21   * @category   external
  22   * @copyright  2015 Juan Leyva <juan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since      Moodle 3.0
  25   */
  26  
  27  use core_course\external\helper_for_get_mods_by_courses;
  28  
  29  defined('MOODLE_INTERNAL') || die;
  30  
  31  require_once($CFG->libdir . '/externallib.php');
  32  require_once($CFG->dirroot . '/mod/lti/lib.php');
  33  require_once($CFG->dirroot . '/mod/lti/locallib.php');
  34  
  35  /**
  36   * External tool module external functions
  37   *
  38   * @package    mod_lti
  39   * @category   external
  40   * @copyright  2015 Juan Leyva <juan@moodle.com>
  41   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   * @since      Moodle 3.0
  43   */
  44  class mod_lti_external extends external_api {
  45  
  46      /**
  47       * Returns structure be used for returning a tool type from a web service.
  48       *
  49       * @return external_function_parameters
  50       * @since Moodle 3.1
  51       */
  52      private static function tool_type_return_structure() {
  53          return new external_single_structure(
  54              array(
  55                  'id' => new external_value(PARAM_INT, 'Tool type id'),
  56                  'name' => new external_value(PARAM_NOTAGS, 'Tool type name'),
  57                  'description' => new external_value(PARAM_NOTAGS, 'Tool type description'),
  58                  'platformid' => new external_value(PARAM_TEXT, 'Platform ID'),
  59                  'clientid' => new external_value(PARAM_TEXT, 'Client ID'),
  60                  'deploymentid' => new external_value(PARAM_INT, 'Deployment ID'),
  61                  'urls' => new external_single_structure(
  62                      array(
  63                          'icon' => new external_value(PARAM_URL, 'Tool type icon URL'),
  64                          'edit' => new external_value(PARAM_URL, 'Tool type edit URL'),
  65                          'course' => new external_value(PARAM_URL, 'Tool type edit URL', VALUE_OPTIONAL),
  66                          'publickeyset' => new external_value(PARAM_URL, 'Public Keyset URL'),
  67                          'accesstoken' => new external_value(PARAM_URL, 'Access Token URL'),
  68                          'authrequest' => new external_value(PARAM_URL, 'Authorisation Request URL'),
  69                      )
  70                  ),
  71                  'state' => new external_single_structure(
  72                      array(
  73                          'text' => new external_value(PARAM_TEXT, 'Tool type state name string'),
  74                          'pending' => new external_value(PARAM_BOOL, 'Is the state pending'),
  75                          'configured' => new external_value(PARAM_BOOL, 'Is the state configured'),
  76                          'rejected' => new external_value(PARAM_BOOL, 'Is the state rejected'),
  77                          'unknown' => new external_value(PARAM_BOOL, 'Is the state unknown'),
  78                      )
  79                  ),
  80                  'hascapabilitygroups' => new external_value(PARAM_BOOL, 'Indicate if capabilitygroups is populated'),
  81                  'capabilitygroups' => new external_multiple_structure(
  82                      new external_value(PARAM_TEXT, 'Tool type capability groups enabled'),
  83                      'Array of capability groups', VALUE_DEFAULT, array()
  84                  ),
  85                  'courseid' => new external_value(PARAM_INT, 'Tool type course', VALUE_DEFAULT, 0),
  86                  'instanceids' => new external_multiple_structure(
  87                      new external_value(PARAM_INT, 'LTI instance ID'),
  88                      'IDs for the LTI instances using this type', VALUE_DEFAULT, array()
  89                  ),
  90                  'instancecount' => new external_value(PARAM_INT, 'The number of times this tool is being used')
  91              ), 'Tool'
  92          );
  93      }
  94  
  95      /**
  96       * Returns description of a tool proxy
  97       *
  98       * @return external_function_parameters
  99       * @since Moodle 3.1
 100       */
 101      private static function tool_proxy_return_structure() {
 102          return new external_function_parameters(
 103              array(
 104                  'id' => new external_value(PARAM_INT, 'Tool proxy id'),
 105                  'name' => new external_value(PARAM_TEXT, 'Tool proxy name'),
 106                  'regurl' => new external_value(PARAM_URL, 'Tool proxy registration URL'),
 107                  'state' => new external_value(PARAM_INT, 'Tool proxy state'),
 108                  'guid' => new external_value(PARAM_TEXT, 'Tool proxy globally unique identifier'),
 109                  'secret' => new external_value(PARAM_TEXT, 'Tool proxy shared secret'),
 110                  'vendorcode' => new external_value(PARAM_TEXT, 'Tool proxy consumer code'),
 111                  'capabilityoffered' => new external_value(PARAM_TEXT, 'Tool proxy capabilities offered'),
 112                  'serviceoffered' => new external_value(PARAM_TEXT, 'Tool proxy services offered'),
 113                  'toolproxy' => new external_value(PARAM_TEXT, 'Tool proxy'),
 114                  'timecreated' => new external_value(PARAM_INT, 'Tool proxy time created'),
 115                  'timemodified' => new external_value(PARAM_INT, 'Tool proxy modified'),
 116              )
 117          );
 118      }
 119  
 120      /**
 121       * Returns description of method parameters
 122       *
 123       * @return external_function_parameters
 124       * @since Moodle 3.1
 125       */
 126      public static function get_tool_proxies_parameters() {
 127          return new external_function_parameters(
 128              array(
 129                  'orphanedonly' => new external_value(PARAM_BOOL, 'Orphaned tool types only', VALUE_DEFAULT, 0)
 130              )
 131          );
 132      }
 133  
 134      /**
 135       * Returns the tool types.
 136       *
 137       * @param bool $orphanedonly Retrieve only tool proxies that do not have a corresponding tool type
 138       * @return array of tool types
 139       * @since Moodle 3.1
 140       * @throws moodle_exception
 141       */
 142      public static function get_tool_proxies($orphanedonly) {
 143          $params = self::validate_parameters(self::get_tool_proxies_parameters(),
 144                                              array(
 145                                                  'orphanedonly' => $orphanedonly
 146                                              ));
 147          $orphanedonly = $params['orphanedonly'];
 148  
 149          $context = context_system::instance();
 150  
 151          self::validate_context($context);
 152          require_capability('moodle/site:config', $context);
 153  
 154          return lti_get_tool_proxies($orphanedonly);
 155      }
 156  
 157      /**
 158       * Returns description of method result value.
 159       *
 160       * @return external_description
 161       * @since Moodle 3.1
 162       */
 163      public static function get_tool_proxies_returns() {
 164          return new external_multiple_structure(
 165              self::tool_proxy_return_structure()
 166          );
 167      }
 168  
 169      /**
 170       * Returns description of method parameters.
 171       *
 172       * @return external_function_parameters
 173       * @since Moodle 3.0
 174       */
 175      public static function get_tool_launch_data_parameters() {
 176          return new external_function_parameters(
 177              array(
 178                  'toolid' => new external_value(PARAM_INT, 'external tool instance id')
 179              )
 180          );
 181      }
 182  
 183      /**
 184       * Return the launch data for a given external tool.
 185       *
 186       * @param int $toolid the external tool instance id
 187       * @return array of warnings and launch data
 188       * @since Moodle 3.0
 189       * @throws moodle_exception
 190       */
 191      public static function get_tool_launch_data($toolid) {
 192          global $DB, $CFG;
 193          require_once($CFG->dirroot . '/mod/lti/lib.php');
 194  
 195          $params = self::validate_parameters(self::get_tool_launch_data_parameters(),
 196                                              array(
 197                                                  'toolid' => $toolid
 198                                              ));
 199          $warnings = array();
 200  
 201          // Request and permission validation.
 202          $lti = $DB->get_record('lti', array('id' => $params['toolid']), '*', MUST_EXIST);
 203          list($course, $cm) = get_course_and_cm_from_instance($lti, 'lti');
 204  
 205          $context = context_module::instance($cm->id);
 206          self::validate_context($context);
 207  
 208          require_capability('mod/lti:view', $context);
 209  
 210          $lti->cmid = $cm->id;
 211          list($endpoint, $parms) = lti_get_launch_data($lti);
 212  
 213          $parameters = array();
 214          foreach ($parms as $name => $value) {
 215              $parameters[] = array(
 216                  'name' => $name,
 217                  'value' => $value
 218              );
 219          }
 220  
 221          $result = array();
 222          $result['endpoint'] = $endpoint;
 223          $result['parameters'] = $parameters;
 224          $result['warnings'] = $warnings;
 225          return $result;
 226      }
 227  
 228      /**
 229       * Returns description of method result value
 230       *
 231       * @return external_description
 232       * @since Moodle 3.0
 233       */
 234      public static function get_tool_launch_data_returns() {
 235          return new external_single_structure(
 236              array(
 237                  'endpoint' => new external_value(PARAM_RAW, 'Endpoint URL'), // Using PARAM_RAW as is defined in the module.
 238                  'parameters' => new external_multiple_structure(
 239                      new external_single_structure(
 240                          array(
 241                              'name' => new external_value(PARAM_NOTAGS, 'Parameter name'),
 242                              'value' => new external_value(PARAM_RAW, 'Parameter value')
 243                          )
 244                      )
 245                  ),
 246                  'warnings' => new external_warnings()
 247              )
 248          );
 249      }
 250  
 251      /**
 252       * Describes the parameters for get_ltis_by_courses.
 253       *
 254       * @return external_function_parameters
 255       * @since Moodle 3.0
 256       */
 257      public static function get_ltis_by_courses_parameters() {
 258          return new external_function_parameters (
 259              array(
 260                  'courseids' => new external_multiple_structure(
 261                      new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
 262                  ),
 263              )
 264          );
 265      }
 266  
 267      /**
 268       * Returns a list of external tools in a provided list of courses,
 269       * if no list is provided all external tools that the user can view will be returned.
 270       *
 271       * @param array $courseids the course ids
 272       * @return array the lti details
 273       * @since Moodle 3.0
 274       */
 275      public static function get_ltis_by_courses($courseids = array()) {
 276          global $CFG;
 277  
 278          $returnedltis = array();
 279          $warnings = array();
 280  
 281          $params = self::validate_parameters(self::get_ltis_by_courses_parameters(), array('courseids' => $courseids));
 282  
 283          $mycourses = array();
 284          if (empty($params['courseids'])) {
 285              $mycourses = enrol_get_my_courses();
 286              $params['courseids'] = array_keys($mycourses);
 287          }
 288  
 289          // Ensure there are courseids to loop through.
 290          if (!empty($params['courseids'])) {
 291  
 292              list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
 293  
 294              // Get the ltis in this course, this function checks users visibility permissions.
 295              // We can avoid then additional validate_context calls.
 296              $ltis = get_all_instances_in_courses("lti", $courses);
 297  
 298              foreach ($ltis as $lti) {
 299  
 300                  $context = context_module::instance($lti->coursemodule);
 301  
 302                  // Entry to return.
 303                  $module = helper_for_get_mods_by_courses::standard_coursemodule_element_values(
 304                          $lti, 'mod_lti', 'moodle/course:manageactivities', 'mod/lti:view');
 305  
 306                  $viewablefields = [];
 307                  if (has_capability('mod/lti:view', $context)) {
 308                      $viewablefields = array('launchcontainer', 'showtitlelaunch', 'showdescriptionlaunch', 'icon', 'secureicon');
 309                  }
 310  
 311                  // Check additional permissions for returning optional private settings.
 312                  if (has_capability('moodle/course:manageactivities', $context)) {
 313                      $additionalfields = array('timecreated', 'timemodified', 'typeid', 'toolurl', 'securetoolurl',
 314                          'instructorchoicesendname', 'instructorchoicesendemailaddr', 'instructorchoiceallowroster',
 315                          'instructorchoiceallowsetting', 'instructorcustomparameters', 'instructorchoiceacceptgrades', 'grade',
 316                          'resourcekey', 'password', 'debuglaunch', 'servicesalt');
 317                      $viewablefields = array_merge($viewablefields, $additionalfields);
 318                  }
 319  
 320                  foreach ($viewablefields as $field) {
 321                      $module[$field] = $lti->{$field};
 322                  }
 323  
 324                  $returnedltis[] = $module;
 325              }
 326          }
 327  
 328          $result = array();
 329          $result['ltis'] = $returnedltis;
 330          $result['warnings'] = $warnings;
 331          return $result;
 332      }
 333  
 334      /**
 335       * Describes the get_ltis_by_courses return value.
 336       *
 337       * @return external_single_structure
 338       * @since Moodle 3.0
 339       */
 340      public static function get_ltis_by_courses_returns() {
 341  
 342          return new external_single_structure(
 343              array(
 344                  'ltis' => new external_multiple_structure(
 345                      new external_single_structure(array_merge(
 346                          helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(true),
 347                          [
 348                              'timecreated' => new external_value(PARAM_INT, 'Time of creation', VALUE_OPTIONAL),
 349                              'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
 350                              'typeid' => new external_value(PARAM_INT, 'Type id', VALUE_OPTIONAL),
 351                              'toolurl' => new external_value(PARAM_URL, 'Tool url', VALUE_OPTIONAL),
 352                              'securetoolurl' => new external_value(PARAM_RAW, 'Secure tool url', VALUE_OPTIONAL),
 353                              'instructorchoicesendname' => new external_value(PARAM_TEXT, 'Instructor choice send name',
 354                                                                                 VALUE_OPTIONAL),
 355                              'instructorchoicesendemailaddr' => new external_value(PARAM_INT, 'instructor choice send mail address',
 356                                                                                      VALUE_OPTIONAL),
 357                              'instructorchoiceallowroster' => new external_value(PARAM_INT, 'Instructor choice allow roster',
 358                                                                                  VALUE_OPTIONAL),
 359                              'instructorchoiceallowsetting' => new external_value(PARAM_INT, 'Instructor choice allow setting',
 360                                                                                   VALUE_OPTIONAL),
 361                              'instructorcustomparameters' => new external_value(PARAM_RAW, 'instructor custom parameters',
 362                                                                                  VALUE_OPTIONAL),
 363                              'instructorchoiceacceptgrades' => new external_value(PARAM_INT, 'instructor choice accept grades',
 364                                                                                      VALUE_OPTIONAL),
 365                              'grade' => new external_value(PARAM_INT, 'Enable grades', VALUE_OPTIONAL),
 366                              'launchcontainer' => new external_value(PARAM_INT, 'Launch container mode', VALUE_OPTIONAL),
 367                              'resourcekey' => new external_value(PARAM_RAW, 'Resource key', VALUE_OPTIONAL),
 368                              'password' => new external_value(PARAM_RAW, 'Shared secret', VALUE_OPTIONAL),
 369                              'debuglaunch' => new external_value(PARAM_INT, 'Debug launch', VALUE_OPTIONAL),
 370                              'showtitlelaunch' => new external_value(PARAM_INT, 'Show title launch', VALUE_OPTIONAL),
 371                              'showdescriptionlaunch' => new external_value(PARAM_INT, 'Show description launch', VALUE_OPTIONAL),
 372                              'servicesalt' => new external_value(PARAM_RAW, 'Service salt', VALUE_OPTIONAL),
 373                              'icon' => new external_value(PARAM_URL, 'Alternative icon URL', VALUE_OPTIONAL),
 374                              'secureicon' => new external_value(PARAM_URL, 'Secure icon URL', VALUE_OPTIONAL),
 375                          ]
 376                      ), 'Tool')
 377                  ),
 378                  'warnings' => new external_warnings(),
 379              )
 380          );
 381      }
 382  
 383      /**
 384       * Returns description of method parameters
 385       *
 386       * @return external_function_parameters
 387       * @since Moodle 3.0
 388       */
 389      public static function view_lti_parameters() {
 390          return new external_function_parameters(
 391              array(
 392                  'ltiid' => new external_value(PARAM_INT, 'lti instance id')
 393              )
 394          );
 395      }
 396  
 397      /**
 398       * Trigger the course module viewed event and update the module completion status.
 399       *
 400       * @param int $ltiid the lti instance id
 401       * @return array of warnings and status result
 402       * @since Moodle 3.0
 403       * @throws moodle_exception
 404       */
 405      public static function view_lti($ltiid) {
 406          global $DB;
 407  
 408          $params = self::validate_parameters(self::view_lti_parameters(),
 409                                              array(
 410                                                  'ltiid' => $ltiid
 411                                              ));
 412          $warnings = array();
 413  
 414          // Request and permission validation.
 415          $lti = $DB->get_record('lti', array('id' => $params['ltiid']), '*', MUST_EXIST);
 416          list($course, $cm) = get_course_and_cm_from_instance($lti, 'lti');
 417  
 418          $context = context_module::instance($cm->id);
 419          self::validate_context($context);
 420          require_capability('mod/lti:view', $context);
 421  
 422          // Trigger course_module_viewed event and completion.
 423          lti_view($lti, $course, $cm, $context);
 424  
 425          $result = array();
 426          $result['status'] = true;
 427          $result['warnings'] = $warnings;
 428          return $result;
 429      }
 430  
 431      /**
 432       * Returns description of method result value
 433       *
 434       * @return external_description
 435       * @since Moodle 3.0
 436       */
 437      public static function view_lti_returns() {
 438          return new external_single_structure(
 439              array(
 440                  'status' => new external_value(PARAM_BOOL, 'status: true if success'),
 441                  'warnings' => new external_warnings()
 442              )
 443          );
 444      }
 445  
 446      /**
 447       * Returns description of method parameters
 448       *
 449       * @return external_function_parameters
 450       * @since Moodle 3.1
 451       */
 452      public static function create_tool_proxy_parameters() {
 453          return new external_function_parameters(
 454              array(
 455                  'name' => new external_value(PARAM_TEXT, 'Tool proxy name', VALUE_DEFAULT, ''),
 456                  'regurl' => new external_value(PARAM_URL, 'Tool proxy registration URL'),
 457                  'capabilityoffered' => new external_multiple_structure(
 458                      new external_value(PARAM_TEXT, 'Tool proxy capabilities offered'),
 459                      'Array of capabilities', VALUE_DEFAULT, array()
 460                  ),
 461                  'serviceoffered' => new external_multiple_structure(
 462                      new external_value(PARAM_TEXT, 'Tool proxy services offered'),
 463                      'Array of services', VALUE_DEFAULT, array()
 464                  )
 465              )
 466          );
 467      }
 468  
 469      /**
 470       * Creates a new tool proxy
 471       *
 472       * @param string $name Tool proxy name
 473       * @param string $registrationurl Registration url
 474       * @param string[] $capabilityoffered List of capabilities this tool proxy should be offered
 475       * @param string[] $serviceoffered List of services this tool proxy should be offered
 476       * @return object The new tool proxy
 477       * @since Moodle 3.1
 478       * @throws moodle_exception
 479       */
 480      public static function create_tool_proxy($name, $registrationurl, $capabilityoffered, $serviceoffered) {
 481          $params = self::validate_parameters(self::create_tool_proxy_parameters(),
 482                                              array(
 483                                                  'name' => $name,
 484                                                  'regurl' => $registrationurl,
 485                                                  'capabilityoffered' => $capabilityoffered,
 486                                                  'serviceoffered' => $serviceoffered
 487                                              ));
 488          $name = $params['name'];
 489          $regurl = $params['regurl'];
 490          $capabilityoffered = $params['capabilityoffered'];
 491          $serviceoffered = $params['serviceoffered'];
 492  
 493          $context = context_system::instance();
 494          self::validate_context($context);
 495          require_capability('moodle/site:config', $context);
 496  
 497          // Can't create duplicate proxies with the same URL.
 498          $duplicates = lti_get_tool_proxies_from_registration_url($registrationurl);
 499          if (!empty($duplicates)) {
 500              throw new moodle_exception('duplicateregurl', 'mod_lti');
 501          }
 502  
 503          $config = new stdClass();
 504          $config->lti_registrationurl = $registrationurl;
 505  
 506          if (!empty($name)) {
 507              $config->lti_registrationname = $name;
 508          }
 509  
 510          if (!empty($capabilityoffered)) {
 511              $config->lti_capabilities = $capabilityoffered;
 512          }
 513  
 514          if (!empty($serviceoffered)) {
 515              $config->lti_services = $serviceoffered;
 516          }
 517  
 518          $id = lti_add_tool_proxy($config);
 519          $toolproxy = lti_get_tool_proxy($id);
 520  
 521          // Pending makes more sense than configured as the first state, since
 522          // the next step is to register, which requires the state be pending.
 523          $toolproxy->state = LTI_TOOL_PROXY_STATE_PENDING;
 524          lti_update_tool_proxy($toolproxy);
 525  
 526          return $toolproxy;
 527      }
 528  
 529      /**
 530       * Returns description of method result value
 531       *
 532       * @return external_description
 533       * @since Moodle 3.1
 534       */
 535      public static function create_tool_proxy_returns() {
 536          return self::tool_proxy_return_structure();
 537      }
 538  
 539      /**
 540       * Returns description of method parameters
 541       *
 542       * @return external_function_parameters
 543       * @since Moodle 3.1
 544       */
 545      public static function delete_tool_proxy_parameters() {
 546          return new external_function_parameters(
 547              array(
 548                  'id' => new external_value(PARAM_INT, 'Tool proxy id'),
 549              )
 550          );
 551      }
 552  
 553      /**
 554       * Trigger the course module viewed event and update the module completion status.
 555       *
 556       * @param int $id the lti instance id
 557       * @return object The tool proxy
 558       * @since Moodle 3.1
 559       * @throws moodle_exception
 560       */
 561      public static function delete_tool_proxy($id) {
 562          $params = self::validate_parameters(self::delete_tool_proxy_parameters(),
 563                                              array(
 564                                                  'id' => $id,
 565                                              ));
 566          $id = $params['id'];
 567  
 568          $context = context_system::instance();
 569          self::validate_context($context);
 570          require_capability('moodle/site:config', $context);
 571  
 572          $toolproxy = lti_get_tool_proxy($id);
 573  
 574          lti_delete_tool_proxy($id);
 575  
 576          return $toolproxy;
 577      }
 578  
 579      /**
 580       * Returns description of method result value
 581       *
 582       * @return external_description
 583       * @since Moodle 3.1
 584       */
 585      public static function delete_tool_proxy_returns() {
 586          return self::tool_proxy_return_structure();
 587      }
 588  
 589      /**
 590       * Returns description of method parameters
 591       *
 592       * @return external_function_parameters
 593       * @since Moodle 3.0
 594       */
 595      public static function get_tool_proxy_registration_request_parameters() {
 596          return new external_function_parameters(
 597              array(
 598                  'id' => new external_value(PARAM_INT, 'Tool proxy id'),
 599              )
 600          );
 601      }
 602  
 603      /**
 604       * Returns the registration request for a tool proxy.
 605       *
 606       * @param int $id the lti instance id
 607       * @return array of registration parameters
 608       * @since Moodle 3.1
 609       * @throws moodle_exception
 610       */
 611      public static function get_tool_proxy_registration_request($id) {
 612          $params = self::validate_parameters(self::get_tool_proxy_registration_request_parameters(),
 613                                              array(
 614                                                  'id' => $id,
 615                                              ));
 616          $id = $params['id'];
 617  
 618          $context = context_system::instance();
 619          self::validate_context($context);
 620          require_capability('moodle/site:config', $context);
 621  
 622          $toolproxy = lti_get_tool_proxy($id);
 623          return lti_build_registration_request($toolproxy);
 624      }
 625  
 626      /**
 627       * Returns description of method result value
 628       *
 629       * @return external_description
 630       * @since Moodle 3.1
 631       */
 632      public static function get_tool_proxy_registration_request_returns() {
 633          return new external_function_parameters(
 634              array(
 635                  'lti_message_type' => new external_value(PARAM_ALPHANUMEXT, 'LTI message type'),
 636                  'lti_version' => new external_value(PARAM_ALPHANUMEXT, 'LTI version'),
 637                  'reg_key' => new external_value(PARAM_TEXT, 'Tool proxy registration key'),
 638                  'reg_password' => new external_value(PARAM_TEXT, 'Tool proxy registration password'),
 639                  'reg_url' => new external_value(PARAM_TEXT, 'Tool proxy registration url'),
 640                  'tc_profile_url' => new external_value(PARAM_URL, 'Tool consumers profile URL'),
 641                  'launch_presentation_return_url' => new external_value(PARAM_URL, 'URL to redirect on registration completion'),
 642              )
 643          );
 644      }
 645  
 646      /**
 647       * Returns description of method parameters
 648       *
 649       * @return external_function_parameters
 650       * @since Moodle 3.1
 651       */
 652      public static function get_tool_types_parameters() {
 653          return new external_function_parameters(
 654              array(
 655                  'toolproxyid' => new external_value(PARAM_INT, 'Tool proxy id', VALUE_DEFAULT, 0)
 656              )
 657          );
 658      }
 659  
 660      /**
 661       * Returns the tool types.
 662       *
 663       * @param int $toolproxyid The tool proxy id
 664       * @return array of tool types
 665       * @since Moodle 3.1
 666       * @throws moodle_exception
 667       */
 668      public static function get_tool_types($toolproxyid) {
 669          global $PAGE;
 670          $params = self::validate_parameters(self::get_tool_types_parameters(),
 671                                              array(
 672                                                  'toolproxyid' => $toolproxyid
 673                                              ));
 674          $toolproxyid = $params['toolproxyid'];
 675  
 676          $types = array();
 677          $context = context_system::instance();
 678  
 679          self::validate_context($context);
 680          require_capability('moodle/site:config', $context);
 681  
 682          if (!empty($toolproxyid)) {
 683              $types = lti_get_lti_types_from_proxy_id($toolproxyid);
 684          } else {
 685              $types = lti_get_lti_types();
 686          }
 687  
 688          return array_map("serialise_tool_type", array_values($types));
 689      }
 690  
 691      /**
 692       * Returns description of method result value
 693       *
 694       * @return external_description
 695       * @since Moodle 3.1
 696       */
 697      public static function get_tool_types_returns() {
 698          return new external_multiple_structure(
 699              self::tool_type_return_structure()
 700          );
 701      }
 702  
 703      /**
 704       * Returns description of method parameters
 705       *
 706       * @return external_function_parameters
 707       * @since Moodle 3.1
 708       */
 709      public static function create_tool_type_parameters() {
 710          return new external_function_parameters(
 711              array(
 712                  'cartridgeurl' => new external_value(PARAM_URL, 'URL to cardridge to load tool information', VALUE_DEFAULT, ''),
 713                  'key' => new external_value(PARAM_TEXT, 'Consumer key', VALUE_DEFAULT, ''),
 714                  'secret' => new external_value(PARAM_TEXT, 'Shared secret', VALUE_DEFAULT, ''),
 715              )
 716          );
 717      }
 718  
 719      /**
 720       * Creates a tool type.
 721       *
 722       * @param string $cartridgeurl Url of the xml cartridge representing the LTI tool
 723       * @param string $key The consumer key to identify this consumer
 724       * @param string $secret The secret
 725       * @return array created tool type
 726       * @since Moodle 3.1
 727       * @throws moodle_exception If the tool type could not be created
 728       */
 729      public static function create_tool_type($cartridgeurl, $key, $secret) {
 730          $params = self::validate_parameters(self::create_tool_type_parameters(),
 731                                              array(
 732                                                  'cartridgeurl' => $cartridgeurl,
 733                                                  'key' => $key,
 734                                                  'secret' => $secret
 735                                              ));
 736          $cartridgeurl = $params['cartridgeurl'];
 737          $key = $params['key'];
 738          $secret = $params['secret'];
 739  
 740          $context = context_system::instance();
 741          self::validate_context($context);
 742          require_capability('moodle/site:config', $context);
 743  
 744          $id = null;
 745  
 746          if (!empty($cartridgeurl)) {
 747              $type = new stdClass();
 748              $data = new stdClass();
 749              $type->state = LTI_TOOL_STATE_CONFIGURED;
 750              $data->lti_coursevisible = 1;
 751              $data->lti_sendname = LTI_SETTING_DELEGATE;
 752              $data->lti_sendemailaddr = LTI_SETTING_DELEGATE;
 753              $data->lti_acceptgrades = LTI_SETTING_DELEGATE;
 754              $data->lti_forcessl = 0;
 755  
 756              if (!empty($key)) {
 757                  $data->lti_resourcekey = $key;
 758              }
 759  
 760              if (!empty($secret)) {
 761                  $data->lti_password = $secret;
 762              }
 763  
 764              lti_load_type_from_cartridge($cartridgeurl, $data);
 765              if (empty($data->lti_toolurl)) {
 766                  throw new moodle_exception('unabletocreatetooltype', 'mod_lti');
 767              } else {
 768                  $id = lti_add_type($type, $data);
 769              }
 770          }
 771  
 772          if (!empty($id)) {
 773              $type = lti_get_type($id);
 774              return serialise_tool_type($type);
 775          } else {
 776              throw new moodle_exception('unabletocreatetooltype', 'mod_lti');
 777          }
 778      }
 779  
 780      /**
 781       * Returns description of method result value
 782       *
 783       * @return external_description
 784       * @since Moodle 3.1
 785       */
 786      public static function create_tool_type_returns() {
 787          return self::tool_type_return_structure();
 788      }
 789  
 790      /**
 791       * Returns description of method parameters
 792       *
 793       * @return external_function_parameters
 794       * @since Moodle 3.1
 795       */
 796      public static function update_tool_type_parameters() {
 797          return new external_function_parameters(
 798              array(
 799                  'id' => new external_value(PARAM_INT, 'Tool type id'),
 800                  'name' => new external_value(PARAM_RAW, 'Tool type name', VALUE_DEFAULT, null),
 801                  'description' => new external_value(PARAM_RAW, 'Tool type description', VALUE_DEFAULT, null),
 802                  'state' => new external_value(PARAM_INT, 'Tool type state', VALUE_DEFAULT, null)
 803              )
 804          );
 805      }
 806  
 807      /**
 808       * Update a tool type.
 809       *
 810       * @param int $id The id of the tool type to update
 811       * @param string $name The name of the tool type
 812       * @param string $description The name of the tool type
 813       * @param int $state The state of the tool type
 814       * @return array updated tool type
 815       * @since Moodle 3.1
 816       * @throws moodle_exception
 817       */
 818      public static function update_tool_type($id, $name, $description, $state) {
 819          $params = self::validate_parameters(self::update_tool_type_parameters(),
 820                                              array(
 821                                                  'id' => $id,
 822                                                  'name' => $name,
 823                                                  'description' => $description,
 824                                                  'state' => $state,
 825                                              ));
 826          $id = $params['id'];
 827          $name = $params['name'];
 828          $description = $params['description'];
 829          $state = $params['state'];
 830  
 831          $context = context_system::instance();
 832          self::validate_context($context);
 833          require_capability('moodle/site:config', $context);
 834  
 835          $type = lti_get_type($id);
 836  
 837          if (empty($type)) {
 838              throw new moodle_exception('unabletofindtooltype', 'mod_lti', '', array('id' => $id));
 839          }
 840  
 841          if (!empty($name)) {
 842              $type->name = $name;
 843          }
 844  
 845          if (!empty($description)) {
 846              $type->description = $description;
 847          }
 848  
 849          if (!empty($state)) {
 850              // Valid state range.
 851              if (in_array($state, array(1, 2, 3))) {
 852                  $type->state = $state;
 853              } else {
 854                  throw new moodle_exception("Invalid state: $state - must be 1, 2, or 3");
 855              }
 856          }
 857  
 858          lti_update_type($type, new stdClass());
 859  
 860          return serialise_tool_type($type);
 861      }
 862  
 863      /**
 864       * Returns description of method result value
 865       *
 866       * @return external_description
 867       * @since Moodle 3.1
 868       */
 869      public static function update_tool_type_returns() {
 870          return self::tool_type_return_structure();
 871      }
 872  
 873      /**
 874       * Returns description of method parameters
 875       *
 876       * @return external_function_parameters
 877       * @since Moodle 3.1
 878       */
 879      public static function delete_tool_type_parameters() {
 880          return new external_function_parameters(
 881              array(
 882                  'id' => new external_value(PARAM_INT, 'Tool type id'),
 883              )
 884          );
 885      }
 886  
 887      /**
 888       * Delete a tool type.
 889       *
 890       * @param int $id The id of the tool type to be deleted
 891       * @return array deleted tool type
 892       * @since Moodle 3.1
 893       * @throws moodle_exception
 894       */
 895      public static function delete_tool_type($id) {
 896          $params = self::validate_parameters(self::delete_tool_type_parameters(),
 897                                              array(
 898                                                  'id' => $id,
 899                                              ));
 900          $id = $params['id'];
 901  
 902          $context = context_system::instance();
 903          self::validate_context($context);
 904          require_capability('moodle/site:config', $context);
 905  
 906          $type = lti_get_type($id);
 907  
 908          if (!empty($type)) {
 909              lti_delete_type($id);
 910  
 911              // If this is the last type for this proxy then remove the proxy
 912              // as well so that it isn't orphaned.
 913              $types = lti_get_lti_types_from_proxy_id($type->toolproxyid);
 914              if (empty($types)) {
 915                  lti_delete_tool_proxy($type->toolproxyid);
 916              }
 917          }
 918  
 919          return array('id' => $id);
 920      }
 921  
 922      /**
 923       * Returns description of method result value
 924       *
 925       * @return external_description
 926       * @since Moodle 3.1
 927       */
 928      public static function delete_tool_type_returns() {
 929          return new external_function_parameters(
 930              array(
 931                  'id' => new external_value(PARAM_INT, 'Tool type id'),
 932              )
 933          );
 934      }
 935  
 936      /**
 937       * Returns description of method parameters
 938       *
 939       * @return external_function_parameters
 940       * @since Moodle 3.1
 941       */
 942      public static function is_cartridge_parameters() {
 943          return new external_function_parameters(
 944              array(
 945                  'url' => new external_value(PARAM_URL, 'Tool url'),
 946              )
 947          );
 948      }
 949  
 950      /**
 951       * Determine if the url to a tool is for a cartridge.
 952       *
 953       * @param string $url Url that may or may not be an xml cartridge
 954       * @return bool True if the url is for a cartridge.
 955       * @since Moodle 3.1
 956       * @throws moodle_exception
 957       */
 958      public static function is_cartridge($url) {
 959          $params = self::validate_parameters(self::is_cartridge_parameters(),
 960                                              array(
 961                                                  'url' => $url,
 962                                              ));
 963          $url = $params['url'];
 964  
 965          $context = context_system::instance();
 966          self::validate_context($context);
 967          require_capability('moodle/site:config', $context);
 968  
 969          $iscartridge = lti_is_cartridge($url);
 970  
 971          return array('iscartridge' => $iscartridge);
 972      }
 973  
 974      /**
 975       * Returns description of method result value
 976       *
 977       * @return external_description
 978       * @since Moodle 3.1
 979       */
 980      public static function is_cartridge_returns() {
 981          return new external_function_parameters(
 982              array(
 983                  'iscartridge' => new external_value(PARAM_BOOL, 'True if the URL is a cartridge'),
 984              )
 985          );
 986      }
 987  }