See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 18 /** 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 48 * @since Moodle 2.4 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'])) { 70 throw new moodle_exception('unnamedstringparam', 'webservice'); 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_RAW,'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 */ 111 public static function get_string($stringid, $component = 'moodle', $lang = null, $stringparams = array()) { 112 $params = self::validate_parameters(self::get_string_parameters(), 113 array('stringid'=>$stringid, 'component' => $component, 'lang' => $lang, 'stringparams' => $stringparams)); 114 115 $stringmanager = get_string_manager(); 116 return $stringmanager->get_string($params['stringid'], $params['component'], 117 core_external::format_string_parameters($params['stringparams']), $params['lang']); 118 } 119 120 /** 121 * Returns description of get_string() result value 122 * 123 * @return external_description 124 * @since Moodle 2.4 125 */ 126 public static function get_string_returns() { 127 return new external_value(PARAM_RAW, '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_RAW, '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)); 167 $stringmanager = get_string_manager(); 168 169 $translatedstrings = array(); 170 foreach($params['strings'] as $string) { 171 172 if (!empty($string['lang'])) { 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, 182 'string' => $stringmanager->get_string($string['stringid'], $string['component'], 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 external_description 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_RAW, 'translated string')) 202 )); 203 } 204 205 /** 206 * Returns description of get_user_dates parameters 207 * 208 * @return external_function_parameters 209 */ 210 public static function get_user_dates_parameters() { 211 return new external_function_parameters( 212 [ 213 'contextid' => new external_value( 214 PARAM_INT, 215 'Context ID. Either use this value, or level and instanceid.', 216 VALUE_DEFAULT, 217 0 218 ), 219 'contextlevel' => new external_value( 220 PARAM_ALPHA, 221 'Context level. To be used with instanceid.', 222 VALUE_DEFAULT, 223 '' 224 ), 225 'instanceid' => new external_value( 226 PARAM_INT, 227 'Context instance ID. To be used with level', 228 VALUE_DEFAULT, 229 0 230 ), 231 'timestamps' => new external_multiple_structure ( 232 new external_single_structure ( 233 [ 234 'timestamp' => new external_value(PARAM_INT, 'unix timestamp'), 235 'format' => new external_value(PARAM_TEXT, 'format string'), 236 'type' => new external_value(PARAM_PLUGIN, 'The calendar type', VALUE_DEFAULT), 237 'fixday' => new external_value(PARAM_INT, 'Remove leading zero for day', VALUE_DEFAULT, 1), 238 'fixhour' => new external_value(PARAM_INT, 'Remove leading zero for hour', VALUE_DEFAULT, 1), 239 ] 240 ) 241 ) 242 ] 243 ); 244 } 245 246 /** 247 * Format an array of timestamps. 248 * 249 * @param int|null $contextid The contenxt id 250 * @param string|null $contextlevel The context level 251 * @param int|null $instanceid The instnace id for the context level 252 * @param array $timestamps Timestamps to format 253 * @return array 254 */ 255 public static function get_user_dates($contextid, $contextlevel, $instanceid, $timestamps) { 256 $params = self::validate_parameters( 257 self::get_user_dates_parameters(), 258 [ 259 'contextid' => $contextid, 260 'contextlevel' => $contextlevel, 261 'instanceid' => $instanceid, 262 'timestamps' => $timestamps, 263 ] 264 ); 265 266 $context = self::get_context_from_params($params); 267 self::validate_context($context); 268 269 $formatteddates = array_map(function($timestamp) { 270 271 $calendartype = $timestamp['type']; 272 $fixday = !empty($timestamp['fixday']); 273 $fixhour = !empty($timestamp['fixhour']); 274 $calendar = \core_calendar\type_factory::get_calendar_instance($calendartype); 275 return $calendar->timestamp_to_date_string($timestamp['timestamp'], $timestamp['format'], 99, $fixday, $fixhour); 276 }, $params['timestamps']); 277 278 return ['dates' => $formatteddates]; 279 } 280 281 /** 282 * Returns description of get_user_dates() result value 283 * 284 * @return external_description 285 */ 286 public static function get_user_dates_returns() { 287 return new external_single_structure( 288 [ 289 'dates' => new external_multiple_structure ( 290 new external_value(PARAM_TEXT, 'formatted dates strings') 291 ) 292 ] 293 ); 294 } 295 296 /** 297 * Returns description of get_component_strings parameters 298 * 299 * @return external_function_parameters 300 * @since Moodle 2.4 301 */ 302 public static function get_component_strings_parameters() { 303 return new external_function_parameters( 304 array('component' => new external_value(PARAM_COMPONENT, 'component'), 305 'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null), 306 ) 307 ); 308 } 309 310 /** 311 * Return all lang strings of a component - call to core get_component_strings(). 312 * 313 * @param string $component component name 314 * @return array 315 * 316 * @since Moodle 2.4 317 */ 318 public static function get_component_strings($component, $lang = null) { 319 320 if (empty($lang)) { 321 $lang = current_language(); 322 } 323 324 $params = self::validate_parameters(self::get_component_strings_parameters(), 325 array('component'=>$component, 'lang' => $lang)); 326 327 $stringmanager = get_string_manager(); 328 329 $wsstrings = array(); 330 $componentstrings = $stringmanager->load_component_strings($params['component'], $params['lang']); 331 foreach($componentstrings as $stringid => $string) { 332 $wsstring = array(); 333 $wsstring['stringid'] = $stringid; 334 $wsstring['string'] = $string; 335 $wsstrings[] = $wsstring; 336 } 337 338 return $wsstrings; 339 } 340 341 /** 342 * Returns description of get_component_strings() result value 343 * 344 * @return external_description 345 * @since Moodle 2.4 346 */ 347 public static function get_component_strings_returns() { 348 return new external_multiple_structure( 349 new external_single_structure(array( 350 'stringid' => new external_value(PARAM_STRINGID, 'string id'), 351 'string' => new external_value(PARAM_RAW, 'translated string')) 352 )); 353 } 354 355 /** 356 * Returns description of get_fragment parameters 357 * 358 * @return external_function_parameters 359 * @since Moodle 3.1 360 */ 361 public static function get_fragment_parameters() { 362 return new external_function_parameters( 363 array( 364 'component' => new external_value(PARAM_COMPONENT, 'Component for the callback e.g. mod_assign'), 365 'callback' => new external_value(PARAM_ALPHANUMEXT, 'Name of the callback to execute'), 366 'contextid' => new external_value(PARAM_INT, 'Context ID that the fragment is from'), 367 'args' => new external_multiple_structure( 368 new external_single_structure( 369 array( 370 'name' => new external_value(PARAM_ALPHANUMEXT, 'param name'), 371 'value' => new external_value(PARAM_RAW, 'param value') 372 ) 373 ), 'args for the callback are optional', VALUE_OPTIONAL 374 ) 375 ) 376 ); 377 } 378 379 /** 380 * Get a HTML fragment for inserting into something. Initial use is for inserting mforms into 381 * a page using AJAX. 382 * This web service is designed to be called only via AJAX and not directly. 383 * Callbacks that are called by this web service are responsible for doing the appropriate security checks 384 * to access the information returned. This only does minimal validation on the context. 385 * 386 * @param string $component Name of the component. 387 * @param string $callback Function callback name. 388 * @param int $contextid Context ID this fragment is in. 389 * @param array $args optional arguments for the callback. 390 * @return array HTML and JavaScript fragments for insertion into stuff. 391 * @since Moodle 3.1 392 */ 393 public static function get_fragment($component, $callback, $contextid, $args = null) { 394 global $OUTPUT, $PAGE; 395 396 $params = self::validate_parameters(self::get_fragment_parameters(), 397 array( 398 'component' => $component, 399 'callback' => $callback, 400 'contextid' => $contextid, 401 'args' => $args 402 ) 403 ); 404 405 // Reformat arguments into something less unwieldy. 406 $arguments = array(); 407 foreach ($params['args'] as $paramargument) { 408 $arguments[$paramargument['name']] = $paramargument['value']; 409 } 410 411 $context = context::instance_by_id($contextid); 412 self::validate_context($context); 413 $arguments['context'] = $context; 414 415 // Hack alert: Set a default URL to stop the annoying debug. 416 $PAGE->set_url('/'); 417 // Hack alert: Forcing bootstrap_renderer to initiate moodle page. 418 $OUTPUT->header(); 419 420 // Overwriting page_requirements_manager with the fragment one so only JS included from 421 // this point is returned to the user. 422 $PAGE->start_collecting_javascript_requirements(); 423 $data = component_callback($params['component'], 'output_fragment_' . $params['callback'], array($arguments)); 424 $jsfooter = $PAGE->requires->get_end_code(); 425 $output = array('html' => $data, 'javascript' => $jsfooter); 426 return $output; 427 } 428 429 /** 430 * Returns description of get_fragment() result value 431 * 432 * @return external_description 433 * @since Moodle 3.1 434 */ 435 public static function get_fragment_returns() { 436 return new external_single_structure( 437 array( 438 'html' => new external_value(PARAM_RAW, 'HTML fragment.'), 439 'javascript' => new external_value(PARAM_RAW, 'JavaScript fragment') 440 ) 441 ); 442 } 443 444 /** 445 * Parameters for function update_inplace_editable() 446 * 447 * @since Moodle 3.1 448 * @return external_function_parameters 449 */ 450 public static function update_inplace_editable_parameters() { 451 return new external_function_parameters( 452 array( 453 'component' => new external_value(PARAM_COMPONENT, 'component responsible for the update', VALUE_REQUIRED), 454 'itemtype' => new external_value(PARAM_NOTAGS, 'type of the updated item inside the component', VALUE_REQUIRED), 455 'itemid' => new external_value(PARAM_RAW, 'identifier of the updated item', VALUE_REQUIRED), 456 'value' => new external_value(PARAM_RAW, 'new value', VALUE_REQUIRED), 457 )); 458 } 459 460 /** 461 * Update any component's editable value assuming that component implements necessary callback 462 * 463 * @since Moodle 3.1 464 * @param string $component 465 * @param string $itemtype 466 * @param string $itemid 467 * @param string $value 468 */ 469 public static function update_inplace_editable($component, $itemtype, $itemid, $value) { 470 global $PAGE; 471 // Validate and normalize parameters. 472 $params = self::validate_parameters(self::update_inplace_editable_parameters(), 473 array('component' => $component, 'itemtype' => $itemtype, 'itemid' => $itemid, 'value' => $value)); 474 if (!$functionname = component_callback_exists($component, 'inplace_editable')) { 475 throw new \moodle_exception('inplaceeditableerror'); 476 } 477 $tmpl = component_callback($params['component'], 'inplace_editable', 478 array($params['itemtype'], $params['itemid'], $params['value'])); 479 if (!$tmpl || !($tmpl instanceof \core\output\inplace_editable)) { 480 throw new \moodle_exception('inplaceeditableerror'); 481 } 482 return $tmpl->export_for_template($PAGE->get_renderer('core')); 483 } 484 485 /** 486 * Return structure for update_inplace_editable() 487 * 488 * @since Moodle 3.1 489 * @return external_description 490 */ 491 public static function update_inplace_editable_returns() { 492 return new external_single_structure( 493 array( 494 'displayvalue' => new external_value(PARAM_RAW, 'display value (may contain link or other html tags)'), 495 'component' => new external_value(PARAM_NOTAGS, 'component responsible for the update', VALUE_OPTIONAL), 496 'itemtype' => new external_value(PARAM_NOTAGS, 'itemtype', VALUE_OPTIONAL), 497 'value' => new external_value(PARAM_RAW, 'value of the item as it is stored', VALUE_OPTIONAL), 498 'itemid' => new external_value(PARAM_RAW, 'identifier of the updated item', VALUE_OPTIONAL), 499 'edithint' => new external_value(PARAM_NOTAGS, 'hint for editing element', VALUE_OPTIONAL), 500 'editlabel' => new external_value(PARAM_RAW, 'label for editing element', VALUE_OPTIONAL), 501 'editicon' => new external_single_structure([ 502 'key' => new external_value(PARAM_RAW, 'Edit icon key', VALUE_OPTIONAL), 503 'component' => new external_value(PARAM_COMPONENT, 'Edit icon component', VALUE_OPTIONAL), 504 'title' => new external_value(PARAM_NOTAGS, 'Edit icon title', VALUE_OPTIONAL), 505 ]), 506 'type' => new external_value(PARAM_ALPHA, 'type of the element (text, toggle, select)', VALUE_OPTIONAL), 507 'options' => new external_value(PARAM_RAW, 'options of the element, format depends on type', VALUE_OPTIONAL), 508 'linkeverything' => new external_value(PARAM_INT, 'Should everything be wrapped in the edit link or link displayed separately', VALUE_OPTIONAL), 509 ) 510 ); 511 } 512 513 /** 514 * Returns description of fetch_notifications() parameters. 515 * 516 * @return external_function_parameters 517 * @since Moodle 3.1 518 */ 519 public static function fetch_notifications_parameters() { 520 return new external_function_parameters( 521 array( 522 'contextid' => new external_value(PARAM_INT, 'Context ID', VALUE_REQUIRED), 523 )); 524 } 525 526 /** 527 * Returns description of fetch_notifications() result value. 528 * 529 * @return external_description 530 * @since Moodle 3.1 531 */ 532 public static function fetch_notifications_returns() { 533 return new external_multiple_structure( 534 new external_single_structure( 535 array( 536 'template' => new external_value(PARAM_RAW, 'Name of the template'), 537 'variables' => new external_single_structure(array( 538 'message' => new external_value(PARAM_RAW, 'HTML content of the Notification'), 539 'extraclasses' => new external_value(PARAM_RAW, 'Extra classes to provide to the tmeplate'), 540 'announce' => new external_value(PARAM_RAW, 'Whether to announce'), 541 'closebutton' => new external_value(PARAM_RAW, 'Whether to close'), 542 )), 543 ) 544 ) 545 ); 546 } 547 548 /** 549 * Returns the list of notifications against the current session. 550 * 551 * @return array 552 * @since Moodle 3.1 553 */ 554 public static function fetch_notifications($contextid) { 555 global $PAGE; 556 557 self::validate_parameters(self::fetch_notifications_parameters(), [ 558 'contextid' => $contextid, 559 ]); 560 561 $context = \context::instance_by_id($contextid); 562 self::validate_context($context); 563 564 return \core\notification::fetch_as_array($PAGE->get_renderer('core')); 565 } 566 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body