Commit | Line | Data |
---|---|---|
11e76602 JM |
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 | /** | |
19 | * external API for core library | |
20 | * | |
21 | * @package core_webservice | |
22 | * @category external | |
23 | * @copyright 2012 Jerome Mouneyrac <jerome@moodle.com> | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | */ | |
26 | ||
27 | defined('MOODLE_INTERNAL') || die; | |
28 | ||
29 | require_once("$CFG->libdir/externallib.php"); | |
30 | ||
31 | /** | |
32 | * Web service related functions | |
33 | * | |
34 | * @package core | |
35 | * @category external | |
36 | * @copyright 2012 Jerome Mouneyrac <jerome@moodle.com> | |
37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
38 | * @since Moodle 2.4 | |
39 | */ | |
40 | class core_external extends external_api { | |
41 | ||
42 | ||
43 | /** | |
44 | * Format the received string parameters to be sent to the core get_string() function. | |
45 | * | |
46 | * @param array $stringparams | |
47 | * @return object|string | |
5bcfd504 | 48 | * @since Moodle 2.4 |
11e76602 JM |
49 | */ |
50 | public static function format_string_parameters($stringparams) { | |
51 | // Check if there are some string params. | |
52 | $strparams = new stdClass(); | |
53 | if (!empty($stringparams)) { | |
54 | // There is only one string parameter. | |
55 | if (count($stringparams) == 1) { | |
56 | $stringparam = array_pop($stringparams); | |
57 | if (isset($stringparam['name'])) { | |
58 | $strparams->{$stringparam['name']} = $stringparam['value']; | |
59 | } else { | |
60 | // It is a not named string parameter. | |
61 | $strparams = $stringparam['value']; | |
62 | } | |
63 | } else { | |
64 | // There are more than one parameter. | |
65 | foreach ($stringparams as $stringparam) { | |
66 | ||
67 | // If a parameter is unnamed throw an exception | |
68 | // unnamed param is only possible if one only param is sent. | |
69 | if (empty($stringparam['name'])) { | |
fd6ab92b | 70 | throw new moodle_exception('unnamedstringparam', 'webservice'); |
11e76602 JM |
71 | } |
72 | ||
73 | $strparams->{$stringparam['name']} = $stringparam['value']; | |
74 | } | |
75 | } | |
76 | } | |
77 | return $strparams; | |
78 | } | |
79 | ||
80 | /** | |
81 | * Returns description of get_string parameters | |
82 | * | |
83 | * @return external_function_parameters | |
84 | * @since Moodle 2.4 | |
85 | */ | |
86 | public static function get_string_parameters() { | |
87 | return new external_function_parameters( | |
88 | array('stringid' => new external_value(PARAM_STRINGID, 'string identifier'), | |
89 | 'component' => new external_value(PARAM_COMPONENT,'component', VALUE_DEFAULT, 'moodle'), | |
90 | 'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null), | |
91 | 'stringparams' => new external_multiple_structure ( | |
92 | new external_single_structure(array( | |
93 | 'name' => new external_value(PARAM_ALPHANUMEXT, 'param name | |
94 | - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL), | |
95 | 'value' => new external_value(PARAM_TEXT,'param value'))), | |
96 | 'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array() | |
97 | ) | |
98 | ) | |
99 | ); | |
100 | } | |
101 | ||
102 | /** | |
103 | * Return a core get_string() call | |
104 | * | |
105 | * @param string $identifier string identifier | |
106 | * @param string $component string component | |
107 | * @param array $stringparams the string params | |
108 | * @return string | |
109 | * @since Moodle 2.4 | |
110 | */ | |
bef63c52 | 111 | public static function get_string($stringid, $component = 'moodle', $lang = null, $stringparams = array()) { |
11e76602 | 112 | $params = self::validate_parameters(self::get_string_parameters(), |
bef63c52 | 113 | array('stringid'=>$stringid, 'component' => $component, 'lang' => $lang, 'stringparams' => $stringparams)); |
11e76602 | 114 | |
bef63c52 DW |
115 | $stringmanager = get_string_manager(); |
116 | return $stringmanager->get_string($params['stringid'], $params['component'], | |
11e76602 JM |
117 | core_external::format_string_parameters($params['stringparams']), $params['lang']); |
118 | } | |
119 | ||
120 | /** | |
121 | * Returns description of get_string() result value | |
122 | * | |
123 | * @return string | |
124 | * @since Moodle 2.4 | |
125 | */ | |
126 | public static function get_string_returns() { | |
127 | return new external_value(PARAM_TEXT, 'translated string'); | |
128 | } | |
129 | ||
130 | /** | |
131 | * Returns description of get_string parameters | |
132 | * | |
133 | * @return external_function_parameters | |
134 | * @since Moodle 2.4 | |
135 | */ | |
136 | public static function get_strings_parameters() { | |
137 | return new external_function_parameters( | |
138 | array('strings' => new external_multiple_structure ( | |
139 | new external_single_structure (array( | |
140 | 'stringid' => new external_value(PARAM_STRINGID, 'string identifier'), | |
141 | 'component' => new external_value(PARAM_COMPONENT, 'component', VALUE_DEFAULT, 'moodle'), | |
142 | 'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null), | |
143 | 'stringparams' => new external_multiple_structure ( | |
144 | new external_single_structure(array( | |
145 | 'name' => new external_value(PARAM_ALPHANUMEXT, 'param name | |
146 | - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL), | |
147 | 'value' => new external_value(PARAM_TEXT, 'param value'))), | |
148 | 'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array() | |
149 | )) | |
150 | ) | |
151 | ) | |
152 | ) | |
153 | ); | |
154 | } | |
155 | ||
156 | /** | |
157 | * Return multiple call to core get_string() | |
158 | * | |
159 | * @param array $strings strings to translate | |
160 | * @return array | |
161 | * | |
162 | * @since Moodle 2.4 | |
163 | */ | |
164 | public static function get_strings($strings) { | |
165 | $params = self::validate_parameters(self::get_strings_parameters(), | |
166 | array('strings'=>$strings)); | |
bef63c52 | 167 | $stringmanager = get_string_manager(); |
11e76602 JM |
168 | |
169 | $translatedstrings = array(); | |
170 | foreach($params['strings'] as $string) { | |
171 | ||
bef63c52 | 172 | if (!empty($string['lang'])) { |
11e76602 JM |
173 | $lang = $string['lang']; |
174 | } else { | |
175 | $lang = current_language(); | |
176 | } | |
177 | ||
178 | $translatedstrings[] = array( | |
179 | 'stringid' => $string['stringid'], | |
180 | 'component' => $string['component'], | |
181 | 'lang' => $lang, | |
bef63c52 | 182 | 'string' => $stringmanager->get_string($string['stringid'], $string['component'], |
11e76602 JM |
183 | core_external::format_string_parameters($string['stringparams']), $lang)); |
184 | } | |
185 | ||
186 | return $translatedstrings; | |
187 | } | |
188 | ||
189 | /** | |
190 | * Returns description of get_string() result value | |
191 | * | |
192 | * @return array | |
193 | * @since Moodle 2.4 | |
194 | */ | |
195 | public static function get_strings_returns() { | |
196 | return new external_multiple_structure( | |
197 | new external_single_structure(array( | |
198 | 'stringid' => new external_value(PARAM_STRINGID, 'string id'), | |
199 | 'component' => new external_value(PARAM_COMPONENT, 'string component'), | |
200 | 'lang' => new external_value(PARAM_LANG, 'lang'), | |
201 | 'string' => new external_value(PARAM_TEXT, 'translated string')) | |
202 | )); | |
203 | } | |
204 | ||
205 | /** | |
206 | * Returns description of get_component_strings parameters | |
207 | * | |
208 | * @return external_function_parameters | |
209 | * @since Moodle 2.4 | |
210 | */ | |
211 | public static function get_component_strings_parameters() { | |
212 | return new external_function_parameters( | |
213 | array('component' => new external_value(PARAM_COMPONENT, 'component'), | |
214 | 'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null), | |
215 | ) | |
216 | ); | |
217 | } | |
218 | ||
219 | /** | |
220 | * Return all lang strings of a component - call to core get_component_strings(). | |
221 | * | |
222 | * @param string $component component name | |
223 | * @return array | |
224 | * | |
225 | * @since Moodle 2.4 | |
226 | */ | |
227 | public static function get_component_strings($component, $lang = null) { | |
228 | ||
229 | if (empty($lang)) { | |
230 | $lang = current_language(); | |
231 | } | |
232 | ||
233 | $params = self::validate_parameters(self::get_component_strings_parameters(), | |
234 | array('component'=>$component, 'lang' => $lang)); | |
235 | ||
236 | $stringmanager = get_string_manager(); | |
237 | ||
238 | $wsstrings = array(); | |
239 | $componentstrings = $stringmanager->load_component_strings($params['component'], $params['lang']); | |
240 | foreach($componentstrings as $stringid => $string) { | |
c5f7628d JM |
241 | $wsstring = array(); |
242 | $wsstring['stringid'] = $stringid; | |
243 | $wsstring['string'] = $string; | |
244 | $wsstrings[] = $wsstring; | |
11e76602 JM |
245 | } |
246 | ||
247 | return $wsstrings; | |
248 | } | |
249 | ||
250 | /** | |
251 | * Returns description of get_component_strings() result value | |
252 | * | |
253 | * @return array | |
254 | * @since Moodle 2.4 | |
255 | */ | |
256 | public static function get_component_strings_returns() { | |
257 | return new external_multiple_structure( | |
258 | new external_single_structure(array( | |
259 | 'stringid' => new external_value(PARAM_STRINGID, 'string id'), | |
c5f7628d | 260 | 'string' => new external_value(PARAM_RAW, 'translated string')) |
11e76602 JM |
261 | )); |
262 | } | |
cc73ea07 AG |
263 | |
264 | /** | |
265 | * Returns description of get_fragment parameters | |
266 | * | |
267 | * @return external_function_parameters | |
268 | * @since Moodle 3.1 | |
269 | */ | |
270 | public static function get_fragment_parameters() { | |
271 | return new external_function_parameters( | |
272 | array( | |
a2161d57 AG |
273 | 'component' => new external_value(PARAM_COMPONENT, 'Component for the callback e.g. mod_assign'), |
274 | 'callback' => new external_value(PARAM_ALPHANUMEXT, 'Name of the callback to execute'), | |
275 | 'contextid' => new external_value(PARAM_INT, 'Context ID that the fragment is from'), | |
cc73ea07 AG |
276 | 'args' => new external_multiple_structure( |
277 | new external_single_structure( | |
278 | array( | |
279 | 'name' => new external_value(PARAM_ALPHANUMEXT, 'param name'), | |
a2161d57 | 280 | 'value' => new external_value(PARAM_RAW, 'param value') |
cc73ea07 AG |
281 | ) |
282 | ), 'args for the callback are optional', VALUE_OPTIONAL | |
283 | ) | |
284 | ) | |
285 | ); | |
286 | } | |
287 | ||
288 | /** | |
289 | * Get a HTML fragment for inserting into something. Initial use is for inserting mforms into | |
290 | * a page using AJAX. | |
a2161d57 AG |
291 | * This web service is designed to be called only via AJAX and not directly. |
292 | * Callbacks that are called by this web service are responsible for doing the appropriate security checks | |
293 | * to access the information returned. This only does minimal validation on the context. | |
cc73ea07 AG |
294 | * |
295 | * @param string $component Name of the component. | |
296 | * @param string $callback Function callback name. | |
a2161d57 | 297 | * @param int $contextid Context ID this fragment is in. |
cc73ea07 AG |
298 | * @param array $args optional arguments for the callback. |
299 | * @return array HTML and JavaScript fragments for insertion into stuff. | |
300 | * @since Moodle 3.1 | |
301 | */ | |
a2161d57 | 302 | public static function get_fragment($component, $callback, $contextid, $args = null) { |
0b39d21a | 303 | global $OUTPUT, $PAGE; |
cc73ea07 AG |
304 | |
305 | $params = self::validate_parameters(self::get_fragment_parameters(), | |
306 | array( | |
307 | 'component' => $component, | |
308 | 'callback' => $callback, | |
a2161d57 | 309 | 'contextid' => $contextid, |
cc73ea07 AG |
310 | 'args' => $args |
311 | ) | |
312 | ); | |
313 | ||
314 | // Reformat arguments into something less unwieldy. | |
315 | $arguments = array(); | |
316 | foreach ($params['args'] as $paramargument) { | |
317 | $arguments[$paramargument['name']] = $paramargument['value']; | |
318 | } | |
319 | ||
a2161d57 AG |
320 | $context = context::instance_by_id($contextid); |
321 | self::validate_context($context); | |
cc73ea07 | 322 | |
0b39d21a DM |
323 | // Hack alert: Forcing bootstrap_renderer to initiate moodle page. |
324 | $OUTPUT->header(); | |
325 | ||
326 | // Overwriting page_requirements_manager with the fragment one so only JS included from | |
327 | // this point is returned to the user. | |
a2161d57 AG |
328 | $PAGE->start_collecting_javascript_requirements(); |
329 | $data = component_callback($params['component'], 'output_fragment_' . $params['callback'], $arguments); | |
cc73ea07 AG |
330 | $jsfooter = $PAGE->requires->get_end_code(); |
331 | $output = array('html' => $data, 'javascript' => $jsfooter); | |
332 | return $output; | |
333 | } | |
334 | ||
335 | /** | |
336 | * Returns description of get_fragment() result value | |
337 | * | |
338 | * @return array | |
339 | * @since Moodle 3.1 | |
340 | */ | |
341 | public static function get_fragment_returns() { | |
342 | return new external_single_structure( | |
343 | array( | |
344 | 'html' => new external_value(PARAM_RAW, 'HTML fragment.'), | |
345 | 'javascript' => new external_value(PARAM_RAW, 'JavaScript fragment') | |
346 | ) | |
347 | ); | |
348 | } | |
cdc5f978 MG |
349 | |
350 | /** | |
351 | * Parameters for function update_inplace_editable() | |
352 | * | |
353 | * @since Moodle 3.1 | |
354 | * @return external_function_parameters | |
355 | */ | |
356 | public static function update_inplace_editable_parameters() { | |
357 | return new external_function_parameters( | |
358 | array( | |
359 | 'component' => new external_value(PARAM_COMPONENT, 'component responsible for the update', VALUE_REQUIRED), | |
360 | 'itemtype' => new external_value(PARAM_NOTAGS, 'type of the updated item inside the component', VALUE_REQUIRED), | |
361 | 'itemid' => new external_value(PARAM_INT, 'identifier of the updated item', VALUE_REQUIRED), | |
362 | 'value' => new external_value(PARAM_RAW, 'new value', VALUE_REQUIRED), | |
363 | )); | |
364 | } | |
365 | ||
366 | /** | |
367 | * Update any component's editable value assuming that component implements necessary callback | |
368 | * | |
369 | * @since Moodle 3.1 | |
370 | * @param string $component | |
371 | * @param string $itemtype | |
372 | * @param string $itemid | |
373 | * @param string $value | |
374 | */ | |
375 | public static function update_inplace_editable($component, $itemtype, $itemid, $value) { | |
376 | global $PAGE; | |
377 | // Validate and normalize parameters. | |
378 | $params = self::validate_parameters(self::update_inplace_editable_parameters(), | |
379 | array('component' => $component, 'itemtype' => $itemtype, 'itemid' => $itemid, 'value' => $value)); | |
380 | if (!$functionname = component_callback_exists($component, 'inplace_editable')) { | |
381 | throw new \moodle_exception('inplaceeditableerror'); | |
382 | } | |
383 | $tmpl = component_callback($params['component'], 'inplace_editable', | |
384 | array($params['itemtype'], $params['itemid'], $params['value'])); | |
385 | if (!$tmpl || !($tmpl instanceof \core\output\inplace_editable)) { | |
386 | throw new \moodle_exception('inplaceeditableerror'); | |
387 | } | |
388 | return $tmpl->export_for_template($PAGE->get_renderer('core')); | |
389 | } | |
390 | ||
391 | /** | |
392 | * Return structure for update_inplace_editable() | |
393 | * | |
394 | * @since Moodle 3.1 | |
395 | * @return external_description | |
396 | */ | |
397 | public static function update_inplace_editable_returns() { | |
398 | return new external_single_structure( | |
399 | array( | |
400 | 'displayvalue' => new external_value(PARAM_RAW, 'display value (may contain link or other html tags)'), | |
401 | 'component' => new external_value(PARAM_NOTAGS, 'component responsible for the update', VALUE_OPTIONAL), | |
402 | 'itemtype' => new external_value(PARAM_NOTAGS, 'itemtype', VALUE_OPTIONAL), | |
403 | 'value' => new external_value(PARAM_RAW, 'value of the item as it is stored', VALUE_OPTIONAL), | |
404 | 'itemid' => new external_value(PARAM_RAW, 'identifier of the updated item', VALUE_OPTIONAL), | |
405 | 'edithint' => new external_value(PARAM_NOTAGS, 'hint for editing element', VALUE_OPTIONAL), | |
406 | 'editlabel' => new external_value(PARAM_NOTAGS, 'label for editing element', VALUE_OPTIONAL), | |
407 | ) | |
408 | ); | |
409 | } | |
0346323c AN |
410 | |
411 | /** | |
412 | * Returns description of fetch_notifications() parameters. | |
413 | * | |
414 | * @return external_function_parameters | |
415 | * @since Moodle 3.1 | |
416 | */ | |
417 | public static function fetch_notifications_parameters() { | |
418 | return new external_function_parameters( | |
419 | array( | |
420 | 'contextid' => new external_value(PARAM_INT, 'Context ID', VALUE_REQUIRED), | |
421 | )); | |
422 | } | |
423 | ||
424 | /** | |
425 | * Returns description of fetch_notifications() result value. | |
426 | * | |
427 | * @return external_description | |
428 | * @since Moodle 3.1 | |
429 | */ | |
430 | public static function fetch_notifications_returns() { | |
431 | return new external_multiple_structure( | |
432 | new external_single_structure( | |
433 | array( | |
434 | 'template' => new external_value(PARAM_RAW, 'Name of the template'), | |
435 | 'variables' => new external_single_structure(array( | |
436 | 'message' => new external_value(PARAM_RAW, 'HTML content of the Notification'), | |
437 | 'extraclasses' => new external_value(PARAM_RAW, 'Extra classes to provide to the tmeplate'), | |
438 | 'announce' => new external_value(PARAM_RAW, 'Whether to announce'), | |
439 | 'closebutton' => new external_value(PARAM_RAW, 'Whether to close'), | |
440 | )), | |
441 | ) | |
442 | ) | |
443 | ); | |
444 | } | |
445 | ||
446 | /** | |
447 | * Returns the list of notifications against the current session. | |
448 | * | |
449 | * @return array | |
450 | * @since Moodle 3.1 | |
451 | */ | |
452 | public static function fetch_notifications($contextid) { | |
453 | global $PAGE; | |
454 | ||
455 | self::validate_parameters(self::fetch_notifications_parameters(), [ | |
456 | 'contextid' => $contextid, | |
457 | ]); | |
458 | ||
459 | $context = \context::instance_by_id($contextid); | |
460 | $PAGE->set_context($context); | |
461 | ||
462 | return \core\notification::fetch_as_array($PAGE->get_renderer('core')); | |
463 | } | |
11e76602 | 464 | } |