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