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.

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