Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

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