See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 * Web service documentation renderer. 20 * 21 * @package core_webservice 22 * @category output 23 * @copyright 2009 Jerome Mouneyrac <jerome@moodle.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class core_webservice_renderer extends plugin_renderer_base { 27 28 /** 29 * Display the authorised user selector 30 * 31 * @param stdClass $options It contains alloweduserselector, potentialuserselector and serviceid 32 * @return string html 33 */ 34 public function admin_authorised_user_selector(&$options) { 35 global $CFG; 36 $formcontent = html_writer::empty_tag('input', 37 array('name' => 'sesskey', 'value' => sesskey(), 'type' => 'hidden')); 38 39 $table = new html_table(); 40 $table->size = array('45%', '10%', '45%'); 41 $table->attributes['class'] = 'roleassigntable generaltable generalbox boxaligncenter'; 42 $table->summary = ''; 43 $table->cellspacing = 0; 44 $table->cellpadding = 0; 45 46 // LTR/RTL support, for drawing button arrows in the right direction 47 if (right_to_left()) { 48 $addarrow = '▶'; 49 $removearrow = '◀'; 50 } else { 51 $addarrow = '◀'; 52 $removearrow = '▶'; 53 } 54 55 //create the add and remove button 56 $addinput = html_writer::empty_tag('input', 57 array('name' => 'add', 'id' => 'add', 'type' => 'submit', 58 'value' => $addarrow . ' ' . get_string('add'), 59 'title' => get_string('add'))); 60 $addbutton = html_writer::tag('div', $addinput, array('id' => 'addcontrols')); 61 $removeinput = html_writer::empty_tag('input', 62 array('name' => 'remove', 'id' => 'remove', 'type' => 'submit', 63 'value' => $removearrow . ' ' . get_string('remove'), 64 'title' => get_string('remove'))); 65 $removebutton = html_writer::tag('div', $removeinput, array('id' => 'removecontrols')); 66 67 68 //create the three cells 69 $label = html_writer::tag('label', get_string('serviceusers', 'webservice'), 70 array('for' => 'removeselect')); 71 $label = html_writer::tag('p', $label); 72 $authoriseduserscell = new html_table_cell($label . 73 $options->alloweduserselector->display(true)); 74 $authoriseduserscell->id = 'existingcell'; 75 $buttonscell = new html_table_cell($addbutton . html_writer::empty_tag('br') . $removebutton); 76 $buttonscell->id = 'buttonscell'; 77 $label = html_writer::tag('label', get_string('potusers', 'webservice'), 78 array('for' => 'addselect')); 79 $label = html_writer::tag('p', $label); 80 $otheruserscell = new html_table_cell($label . 81 $options->potentialuserselector->display(true)); 82 $otheruserscell->id = 'potentialcell'; 83 84 $cells = array($authoriseduserscell, $buttonscell, $otheruserscell); 85 $row = new html_table_row($cells); 86 $table->data[] = $row; 87 $formcontent .= html_writer::table($table); 88 89 $formcontent = html_writer::tag('div', $formcontent); 90 91 $actionurl = new moodle_url('/' . $CFG->admin . '/webservice/service_users.php', 92 array('id' => $options->serviceid)); 93 $html = html_writer::tag('form', $formcontent, 94 array('id' => 'assignform', 'action' => $actionurl, 'method' => 'post')); 95 return $html; 96 } 97 98 /** 99 * Display list of authorised users 100 * 101 * @param array $users authorised users 102 * @param int $serviceid service id 103 * @return string $html 104 */ 105 public function admin_authorised_user_list($users, $serviceid) { 106 global $CFG; 107 $html = $this->output->box_start('generalbox', 'alloweduserlist'); 108 foreach ($users as $user) { 109 $modifiedauthoriseduserurl = new moodle_url('/' . $CFG->admin . '/webservice/service_user_settings.php', 110 array('userid' => $user->id, 'serviceid' => $serviceid)); 111 $html .= html_writer::tag('a', $user->firstname . " " 112 . $user->lastname . ", " . s($user->email), 113 array('href' => $modifiedauthoriseduserurl)); 114 //add missing capabilities 115 if (!empty($user->missingcapabilities)) { 116 $html .= html_writer::tag('div', 117 get_string('usermissingcaps', 'webservice', $user->missingcapabilities) 118 . ' ' . $this->output->help_icon('missingcaps', 'webservice'), 119 array('class' => 'missingcaps', 'id' => 'usermissingcaps')); 120 $html .= html_writer::empty_tag('br'); 121 } else { 122 $html .= html_writer::empty_tag('br') . html_writer::empty_tag('br'); 123 } 124 } 125 $html .= $this->output->box_end(); 126 return $html; 127 } 128 129 /** 130 * Display a confirmation page to remove a function from a service 131 * 132 * @param stdClass $function It needs function id + function name properties. 133 * @param stdClass $service It needs service id + service name properties. 134 * @return string html 135 */ 136 public function admin_remove_service_function_confirmation($function, $service) { 137 $optionsyes = array('id' => $service->id, 'action' => 'delete', 138 'confirm' => 1, 'sesskey' => sesskey(), 'fid' => $function->id); 139 $optionsno = array('id' => $service->id); 140 $formcontinue = new single_button(new moodle_url('service_functions.php', 141 $optionsyes), get_string('remove')); 142 $formcancel = new single_button(new moodle_url('service_functions.php', 143 $optionsno), get_string('cancel'), 'get'); 144 return $this->output->confirm(get_string('removefunctionconfirm', 'webservice', 145 (object) array('service' => $service->name, 'function' => $function->name)), 146 $formcontinue, $formcancel); 147 } 148 149 /** 150 * Display a confirmation page to remove a service 151 * 152 * @param stdClass $service It needs service id + service name properties. 153 * @return string html 154 */ 155 public function admin_remove_service_confirmation($service) { 156 global $CFG; 157 $optionsyes = array('id' => $service->id, 'action' => 'delete', 158 'confirm' => 1, 'sesskey' => sesskey()); 159 $optionsno = array('section' => 'externalservices'); 160 $formcontinue = new single_button(new moodle_url('service.php', $optionsyes), 161 get_string('delete'), 'post'); 162 $formcancel = new single_button( 163 new moodle_url($CFG->wwwroot . "/" . $CFG->admin . "/settings.php", $optionsno), 164 get_string('cancel'), 'get'); 165 return $this->output->confirm(get_string('deleteserviceconfirm', 'webservice', $service->name), 166 $formcontinue, $formcancel); 167 } 168 169 /** 170 * Display a confirmation page to delete a token 171 * 172 * @param stdClass $token Required properties: id (token id), firstname (user firstname), lastname (user lastname), name (service name) 173 * @return string html 174 */ 175 public function admin_delete_token_confirmation($token) { 176 global $CFG; 177 $optionsyes = array('tokenid' => $token->id, 'action' => 'delete', 178 'confirm' => 1, 'sesskey' => sesskey()); 179 $optionsno = array('section' => 'webservicetokens', 'sesskey' => sesskey()); 180 $formcontinue = new single_button( 181 new moodle_url('/' . $CFG->admin . '/webservice/tokens.php', $optionsyes), 182 get_string('delete')); 183 $formcancel = new single_button( 184 new moodle_url('/' . $CFG->admin . '/settings.php', $optionsno), 185 get_string('cancel'), 'get'); 186 return $this->output->confirm(get_string('deletetokenconfirm', 'webservice', 187 (object) array('user' => $token->firstname . " " 188 . $token->lastname, 'service' => $token->name)), 189 $formcontinue, $formcancel); 190 } 191 192 /** 193 * Display a list of functions for a given service 194 * If the service is built-in, do not display remove/add operation (read-only) 195 * 196 * @param array $functions list of functions 197 * @param stdClass $service the given service 198 * @return string the table html + add operation html 199 */ 200 public function admin_service_function_list($functions, $service) { 201 global $CFG; 202 if (!empty($functions)) { 203 $table = new html_table(); 204 $table->head = array(get_string('function', 'webservice'), 205 get_string('description'), get_string('requiredcaps', 'webservice')); 206 $table->align = array('left', 'left', 'left'); 207 $table->size = array('15%', '40%', '40%'); 208 $table->width = '100%'; 209 $table->align[] = 'left'; 210 211 //display remove function operation (except for build-in service) 212 if (empty($service->component)) { 213 $table->head[] = get_string('edit'); 214 $table->align[] = 'center'; 215 } 216 217 $anydeprecated = false; 218 foreach ($functions as $function) { 219 $function = external_api::external_function_info($function); 220 221 if (!empty($function->deprecated)) { 222 $anydeprecated = true; 223 } 224 $requiredcaps = html_writer::tag('div', 225 empty($function->capabilities) ? '' : $function->capabilities, 226 array('class' => 'functiondesc')); 227 ; 228 $description = html_writer::tag('div', $function->description, 229 array('class' => 'functiondesc')); 230 //display remove function operation (except for build-in service) 231 if (empty($service->component)) { 232 $removeurl = new moodle_url('/' . $CFG->admin . '/webservice/service_functions.php', 233 array('sesskey' => sesskey(), 'fid' => $function->id, 234 'id' => $service->id, 235 'action' => 'delete')); 236 $removelink = html_writer::tag('a', 237 get_string('removefunction', 'webservice'), 238 array('href' => $removeurl)); 239 $table->data[] = array($function->name, $description, $requiredcaps, $removelink); 240 } else { 241 $table->data[] = array($function->name, $description, $requiredcaps); 242 } 243 } 244 245 $html = html_writer::table($table); 246 } else { 247 $html = get_string('nofunctions', 'webservice') . html_writer::empty_tag('br'); 248 } 249 250 //display add function operation (except for build-in service) 251 if (empty($service->component)) { 252 253 if (!empty($anydeprecated)) { 254 debugging('This service uses deprecated functions, replace them by the proposed ones and update your client/s.', DEBUG_DEVELOPER); 255 } 256 $addurl = new moodle_url('/' . $CFG->admin . '/webservice/service_functions.php', 257 array('sesskey' => sesskey(), 'id' => $service->id, 'action' => 'add')); 258 $html .= html_writer::tag('a', get_string('addfunctions', 'webservice'), array('href' => $addurl)); 259 } 260 261 return $html; 262 } 263 264 /** 265 * Display Reset token confirmation box 266 * 267 * @param stdClass $token token to reset 268 * @return string html 269 */ 270 public function user_reset_token_confirmation($token) { 271 global $CFG; 272 $managetokenurl = $CFG->wwwroot . "/user/managetoken.php?sesskey=" . sesskey(); 273 $optionsyes = array('tokenid' => $token->id, 'action' => 'resetwstoken', 'confirm' => 1, 274 'sesskey' => sesskey()); 275 $optionsno = array('section' => 'webservicetokens', 'sesskey' => sesskey()); 276 $formcontinue = new single_button(new moodle_url($managetokenurl, $optionsyes), 277 get_string('reset')); 278 $formcancel = new single_button(new moodle_url($managetokenurl, $optionsno), 279 get_string('cancel'), 'get'); 280 $html = $this->output->confirm(get_string('resettokenconfirm', 'webservice', 281 (object) array('user' => $token->firstname . " " . 282 $token->lastname, 'service' => $token->name)), 283 $formcontinue, $formcancel); 284 return $html; 285 } 286 287 /** 288 * Display user tokens with buttons to reset them 289 * 290 * @param stdClass $tokens user tokens 291 * @param int $userid user id 292 * @param bool $documentation if true display a link to the API documentation 293 * @return string html code 294 */ 295 public function user_webservice_tokens_box($tokens, $userid, $documentation = false) { 296 global $CFG, $DB; 297 298 // display strings 299 $stroperation = get_string('operation', 'webservice'); 300 $strtoken = get_string('key', 'webservice'); 301 $strservice = get_string('service', 'webservice'); 302 $strcreator = get_string('tokencreator', 'webservice'); 303 $strcontext = get_string('context', 'webservice'); 304 $strvaliduntil = get_string('validuntil', 'webservice'); 305 306 $return = $this->output->heading(get_string('securitykeys', 'webservice'), 3, 'main', true); 307 $return .= $this->output->box_start('generalbox webservicestokenui'); 308 309 $return .= get_string('keyshelp', 'webservice'); 310 311 $table = new html_table(); 312 $table->head = array($strtoken, $strservice, $strvaliduntil, $strcreator, $stroperation); 313 $table->align = array('left', 'left', 'left', 'center', 'left', 'center'); 314 $table->width = '100%'; 315 $table->data = array(); 316 317 if ($documentation) { 318 $table->head[] = get_string('doc', 'webservice'); 319 $table->align[] = 'center'; 320 } 321 322 if (!empty($tokens)) { 323 foreach ($tokens as $token) { 324 325 if ($token->creatorid == $userid) { 326 $reset = "<a href=\"" . $CFG->wwwroot . "/user/managetoken.php?sesskey=" 327 . sesskey() . "&action=resetwstoken&tokenid=" . $token->id . "\">"; 328 $reset .= get_string('reset') . "</a>"; 329 $creator = $token->firstname . " " . $token->lastname; 330 } else { 331 //retrieve administrator name 332 $admincreator = $DB->get_record('user', array('id'=>$token->creatorid)); 333 $creator = $admincreator->firstname . " " . $admincreator->lastname; 334 $reset = ''; 335 } 336 337 $userprofilurl = new moodle_url('/user/view.php?id=' . $token->creatorid); 338 $creatoratag = html_writer::start_tag('a', array('href' => $userprofilurl)); 339 $creatoratag .= $creator; 340 $creatoratag .= html_writer::end_tag('a'); 341 342 $validuntil = ''; 343 if (!empty($token->validuntil)) { 344 $validuntil = userdate($token->validuntil, get_string('strftimedatetime', 'langconfig')); 345 } 346 347 $tokenname = $token->name; 348 if (!$token->enabled) { //that is the (1 token-1ws) related ws is not enabled. 349 $tokenname = '<span class="dimmed_text">'.$token->name.'</span>'; 350 } 351 $row = array($token->token, $tokenname, $validuntil, $creatoratag, $reset); 352 353 if ($documentation) { 354 $doclink = new moodle_url('/webservice/wsdoc.php', 355 array('id' => $token->id, 'sesskey' => sesskey())); 356 $row[] = html_writer::tag('a', get_string('doc', 'webservice'), 357 array('href' => $doclink)); 358 } 359 360 $table->data[] = $row; 361 } 362 $return .= html_writer::table($table); 363 } else { 364 $return .= get_string('notoken', 'webservice'); 365 } 366 367 $return .= $this->output->box_end(); 368 return $return; 369 } 370 371 /** 372 * Return documentation for a ws description object 373 * ws description object can be 'external_multiple_structure', 'external_single_structure' 374 * or 'external_value' 375 * 376 * Example of documentation for core_group_create_groups function: 377 * list of ( 378 * object { 379 * courseid int //id of course 380 * name string //multilang compatible name, course unique 381 * description string //group description text 382 * enrolmentkey string //group enrol secret phrase 383 * } 384 * ) 385 * 386 * @param stdClass $params a part of parameter/return description 387 * @return string the html to display 388 */ 389 public function detailed_description_html($params) { 390 // retrieve the description of the description object 391 $paramdesc = ""; 392 if (!empty($params->desc)) { 393 $paramdesc .= html_writer::start_tag('span', array('style' => "color:#2A33A6")); 394 if ($params->required == VALUE_REQUIRED) { 395 $required = ''; 396 } 397 if ($params->required == VALUE_DEFAULT) { 398 if ($params->default === null) { 399 $params->default = "null"; 400 } 401 $required = html_writer::start_tag('b', array()) . 402 get_string('default', 'webservice', print_r($params->default, true)) 403 . html_writer::end_tag('b'); 404 } 405 if ($params->required == VALUE_OPTIONAL) { 406 $required = html_writer::start_tag('b', array()) . 407 get_string('optional', 'webservice') . html_writer::end_tag('b'); 408 } 409 $paramdesc .= " " . $required . " "; 410 $paramdesc .= html_writer::start_tag('i', array()); 411 $paramdesc .= "//"; 412 413 $paramdesc .= s($params->desc); 414 415 $paramdesc .= html_writer::end_tag('i'); 416 417 $paramdesc .= html_writer::end_tag('span'); 418 $paramdesc .= html_writer::empty_tag('br', array()); 419 } 420 421 // description object is a list 422 if ($params instanceof external_multiple_structure) { 423 return $paramdesc . "list of ( " . html_writer::empty_tag('br', array()) 424 . $this->detailed_description_html($params->content) . ")"; 425 } else if ($params instanceof external_single_structure) { 426 // description object is an object 427 $singlestructuredesc = $paramdesc . "object {" . html_writer::empty_tag('br', array()); 428 foreach ($params->keys as $attributname => $attribut) { 429 $singlestructuredesc .= html_writer::start_tag('b', array()); 430 $singlestructuredesc .= $attributname; 431 $singlestructuredesc .= html_writer::end_tag('b'); 432 $singlestructuredesc .= " " . 433 $this->detailed_description_html($params->keys[$attributname]); 434 } 435 $singlestructuredesc .= "} "; 436 $singlestructuredesc .= html_writer::empty_tag('br', array()); 437 return $singlestructuredesc; 438 } else { 439 // description object is a primary type (string, integer) 440 switch ($params->type) { 441 case PARAM_BOOL: // 0 or 1 only for now 442 case PARAM_INT: 443 $type = 'int'; 444 break; 445 case PARAM_FLOAT; 446 $type = 'double'; 447 break; 448 default: 449 $type = 'string'; 450 } 451 return $type . " " . $paramdesc; 452 } 453 } 454 455 /** 456 * Return a description object in indented xml format (for REST response) 457 * It is indented to be output within <pre> tags 458 * 459 * @param external_description $returndescription the description structure of the web service function returned value 460 * @param string $indentation Indentation in the generated HTML code; should contain only spaces. 461 * @return string the html to diplay 462 */ 463 public function description_in_indented_xml_format($returndescription, $indentation = "") { 464 $indentation = $indentation . " "; 465 $brakeline = <<<EOF 466 467 468 EOF; 469 // description object is a list 470 if ($returndescription instanceof external_multiple_structure) { 471 $return = $indentation . "<MULTIPLE>" . $brakeline; 472 $return .= $this->description_in_indented_xml_format($returndescription->content, 473 $indentation); 474 $return .= $indentation . "</MULTIPLE>" . $brakeline; 475 return $return; 476 } else if ($returndescription instanceof external_single_structure) { 477 // description object is an object 478 $singlestructuredesc = $indentation . "<SINGLE>" . $brakeline; 479 $keyindentation = $indentation . " "; 480 foreach ($returndescription->keys as $attributname => $attribut) { 481 $singlestructuredesc .= $keyindentation . "<KEY name=\"" . $attributname . "\">" 482 . $brakeline . 483 $this->description_in_indented_xml_format( 484 $returndescription->keys[$attributname], $keyindentation) . 485 $keyindentation . "</KEY>" . $brakeline; 486 } 487 $singlestructuredesc .= $indentation . "</SINGLE>" . $brakeline; 488 return $singlestructuredesc; 489 } else { 490 // description object is a primary type (string, integer) 491 switch ($returndescription->type) { 492 case PARAM_BOOL: // 0 or 1 only for now 493 case PARAM_INT: 494 $type = 'int'; 495 break; 496 case PARAM_FLOAT; 497 $type = 'double'; 498 break; 499 default: 500 $type = 'string'; 501 } 502 return $indentation . "<VALUE>" . $type . "</VALUE>" . $brakeline; 503 } 504 } 505 506 /** 507 * Create indented XML-RPC param description 508 * 509 * @param external_description $paramdescription the description structure of the web service function parameters 510 * @param string $indentation Indentation in the generated HTML code; should contain only spaces. 511 * @return string the html to diplay 512 */ 513 public function xmlrpc_param_description_html($paramdescription, $indentation = "") { 514 $indentation = $indentation . " "; 515 $brakeline = <<<EOF 516 517 518 EOF; 519 // description object is a list 520 if ($paramdescription instanceof external_multiple_structure) { 521 $return = $brakeline . $indentation . "Array "; 522 $indentation = $indentation . " "; 523 $return .= $brakeline . $indentation . "("; 524 $return .= $brakeline . $indentation . "[0] =>"; 525 $return .= $this->xmlrpc_param_description_html($paramdescription->content, $indentation); 526 $return .= $brakeline . $indentation . ")"; 527 return $return; 528 } else if ($paramdescription instanceof external_single_structure) { 529 // description object is an object 530 $singlestructuredesc = $brakeline . $indentation . "Array "; 531 $keyindentation = $indentation . " "; 532 $singlestructuredesc .= $brakeline . $keyindentation . "("; 533 foreach ($paramdescription->keys as $attributname => $attribut) { 534 $singlestructuredesc .= $brakeline . $keyindentation . "[" . $attributname . "] =>" . 535 $this->xmlrpc_param_description_html( 536 $paramdescription->keys[$attributname], $keyindentation) . 537 $keyindentation; 538 } 539 $singlestructuredesc .= $brakeline . $keyindentation . ")"; 540 return $singlestructuredesc; 541 } else { 542 // description object is a primary type (string, integer) 543 switch ($paramdescription->type) { 544 case PARAM_BOOL: // 0 or 1 only for now 545 case PARAM_INT: 546 $type = 'int'; 547 break; 548 case PARAM_FLOAT; 549 $type = 'double'; 550 break; 551 default: 552 $type = 'string'; 553 } 554 return " " . $type; 555 } 556 } 557 558 /** 559 * Return the html of a coloured box with content 560 * 561 * @param string $title - the title of the box 562 * @param string $content - the content to displayed 563 * @param string $rgb - the background color of the box 564 * @return string HTML code 565 */ 566 public function colored_box_with_pre_tag($title, $content, $rgb = 'FEEBE5') { 567 //TODO MDL-31192 this tag removes xhtml strict error but cause warning 568 $coloredbox = html_writer::start_tag('div', array()); 569 $coloredbox .= html_writer::start_tag('div', 570 array('style' => "border:solid 1px #DEDEDE;background:#" . $rgb 571 . ";color:#222222;padding:4px;")); 572 $coloredbox .= html_writer::start_tag('pre', array()); 573 $coloredbox .= html_writer::start_tag('b', array()); 574 $coloredbox .= $title; 575 $coloredbox .= html_writer::end_tag('b', array()); 576 $coloredbox .= html_writer::empty_tag('br', array()); 577 $coloredbox .= "\n" . $content . "\n"; 578 $coloredbox .= html_writer::end_tag('pre', array()); 579 $coloredbox .= html_writer::end_tag('div', array()); 580 $coloredbox .= html_writer::end_tag('div', array()); 581 return $coloredbox; 582 } 583 584 /** 585 * Return indented REST param description 586 * 587 * @param external_description $paramdescription the description structure of the web service function parameters 588 * @param string $paramstring parameter 589 * @return string the html to diplay 590 */ 591 public function rest_param_description_html($paramdescription, $paramstring) { 592 $brakeline = <<<EOF 593 594 595 EOF; 596 // description object is a list 597 if ($paramdescription instanceof external_multiple_structure) { 598 $paramstring = $paramstring . '[0]'; 599 $return = $this->rest_param_description_html($paramdescription->content, $paramstring); 600 return $return; 601 } else if ($paramdescription instanceof external_single_structure) { 602 // description object is an object 603 $singlestructuredesc = ""; 604 $initialparamstring = $paramstring; 605 foreach ($paramdescription->keys as $attributname => $attribut) { 606 $paramstring = $initialparamstring . '[' . $attributname . ']'; 607 $singlestructuredesc .= $this->rest_param_description_html( 608 $paramdescription->keys[$attributname], $paramstring); 609 } 610 return $singlestructuredesc; 611 } else { 612 // description object is a primary type (string, integer) 613 $paramstring = $paramstring . '='; 614 switch ($paramdescription->type) { 615 case PARAM_BOOL: // 0 or 1 only for now 616 case PARAM_INT: 617 $type = 'int'; 618 break; 619 case PARAM_FLOAT; 620 $type = 'double'; 621 break; 622 default: 623 $type = 'string'; 624 } 625 return $paramstring . " " . $type . $brakeline; 626 } 627 } 628 629 /** 630 * Displays all the documentation 631 * 632 * @param array $functions external_description of all the web service functions 633 * @param boolean $printableformat true if we want to display the documentation in a printable format 634 * @param array $activatedprotocol the currently enabled protocol 635 * @param array $authparams url parameters (it contains 'tokenid' and sometimes 'print') 636 * @param string $parenturl url of the calling page - needed for the print button url: 637 * '/admin/documentation.php' or '/webservice/wsdoc.php' (default) 638 * @return string the html to diplay 639 */ 640 public function documentation_html($functions, $printableformat, $activatedprotocol, 641 $authparams, $parenturl = '/webservice/wsdoc.php') { 642 643 $documentationhtml = $this->output->heading(get_string('wsdocapi', 'webservice')); 644 645 $br = html_writer::empty_tag('br', array()); 646 $brakeline = <<<EOF 647 648 649 EOF; 650 // Some general information 651 $docinfo = new stdClass(); 652 $docurl = new moodle_url('http://docs.moodle.org/dev/Creating_a_web_service_client'); 653 $docinfo->doclink = html_writer::tag('a', 654 get_string('wsclientdoc', 'webservice'), array('href' => $docurl)); 655 $documentationhtml .= get_string('wsdocumentationintro', 'webservice', $docinfo); 656 $documentationhtml .= $br . $br; 657 658 659 // Print button 660 $authparams['print'] = true; 661 $url = new moodle_url($parenturl, $authparams); // Required 662 $documentationhtml .= $this->output->single_button($url, get_string('print', 'webservice')); 663 $documentationhtml .= $br; 664 665 666 // each functions will be displayed into a collapsible region 667 //(opened if printableformat = true) 668 foreach ($functions as $functionname => $description) { 669 670 if (empty($printableformat)) { 671 $documentationhtml .= print_collapsible_region_start('', 672 'aera_' . $functionname, 673 html_writer::start_tag('strong', array()) 674 . $functionname . html_writer::end_tag('strong'), 675 false, 676 !$printableformat, 677 true); 678 } else { 679 $documentationhtml .= html_writer::tag('strong', $functionname); 680 $documentationhtml .= $br; 681 } 682 683 // function global description 684 $documentationhtml .= $br; 685 $documentationhtml .= html_writer::start_tag('div', 686 array('style' => 'border:solid 1px #DEDEDE;background:#E2E0E0; 687 color:#222222;padding:4px;')); 688 $documentationhtml .= s($description->description); 689 $documentationhtml .= html_writer::end_tag('div'); 690 $documentationhtml .= $br . $br; 691 692 // function arguments documentation 693 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6')); 694 $documentationhtml .= get_string('arguments', 'webservice'); 695 $documentationhtml .= html_writer::end_tag('span'); 696 $documentationhtml .= $br; 697 foreach ($description->parameters_desc->keys as $paramname => $paramdesc) { 698 // a argument documentation 699 $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%')); 700 701 if ($paramdesc->required == VALUE_REQUIRED) { 702 $required = get_string('required', 'webservice'); 703 } 704 if ($paramdesc->required == VALUE_DEFAULT) { 705 if ($paramdesc->default === null) { 706 $default = "null"; 707 } else { 708 $default = print_r($paramdesc->default, true); 709 } 710 $required = get_string('default', 'webservice', $default); 711 } 712 if ($paramdesc->required == VALUE_OPTIONAL) { 713 $required = get_string('optional', 'webservice'); 714 } 715 716 $documentationhtml .= html_writer::start_tag('b', array()); 717 $documentationhtml .= $paramname; 718 $documentationhtml .= html_writer::end_tag('b'); 719 $documentationhtml .= " (" . $required . ")"; // argument is required or optional ? 720 $documentationhtml .= $br; 721 $documentationhtml .= " " 722 . s($paramdesc->desc); // Argument description. 723 $documentationhtml .= $br . $br; 724 // general structure of the argument 725 $documentationhtml .= $this->colored_box_with_pre_tag( 726 get_string('generalstructure', 'webservice'), 727 $this->detailed_description_html($paramdesc), 728 'FFF1BC'); 729 // xml-rpc structure of the argument in PHP format 730 if (!empty($activatedprotocol['xmlrpc'])) { 731 $documentationhtml .= $this->colored_box_with_pre_tag( 732 get_string('phpparam', 'webservice'), 733 htmlentities('[' . $paramname . '] =>' 734 . $this->xmlrpc_param_description_html($paramdesc)), 735 'DFEEE7'); 736 } 737 // POST format for the REST protocol for the argument 738 if (!empty($activatedprotocol['rest'])) { 739 $documentationhtml .= $this->colored_box_with_pre_tag( 740 get_string('restparam', 'webservice'), 741 htmlentities($this->rest_param_description_html( 742 $paramdesc, $paramname)), 743 'FEEBE5'); 744 } 745 $documentationhtml .= html_writer::end_tag('span'); 746 } 747 $documentationhtml .= $br . $br; 748 749 750 // function response documentation 751 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6')); 752 $documentationhtml .= get_string('response', 'webservice'); 753 $documentationhtml .= html_writer::end_tag('span'); 754 $documentationhtml .= $br; 755 // function response description 756 $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%')); 757 if (!empty($description->returns_desc->desc)) { 758 $documentationhtml .= $description->returns_desc->desc; 759 $documentationhtml .= $br . $br; 760 } 761 if (!empty($description->returns_desc)) { 762 // general structure of the response 763 $documentationhtml .= $this->colored_box_with_pre_tag( 764 get_string('generalstructure', 'webservice'), 765 $this->detailed_description_html($description->returns_desc), 766 'FFF1BC'); 767 // xml-rpc structure of the response in PHP format 768 if (!empty($activatedprotocol['xmlrpc'])) { 769 $documentationhtml .= $this->colored_box_with_pre_tag( 770 get_string('phpresponse', 'webservice'), 771 htmlentities($this->xmlrpc_param_description_html( 772 $description->returns_desc)), 773 'DFEEE7'); 774 } 775 // XML response for the REST protocol 776 if (!empty($activatedprotocol['rest'])) { 777 $restresponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" 778 . $brakeline . "<RESPONSE>" . $brakeline; 779 $restresponse .= $this->description_in_indented_xml_format( 780 $description->returns_desc); 781 $restresponse .="</RESPONSE>" . $brakeline; 782 $documentationhtml .= $this->colored_box_with_pre_tag( 783 get_string('restcode', 'webservice'), 784 htmlentities($restresponse), 785 'FEEBE5'); 786 } 787 } 788 $documentationhtml .= html_writer::end_tag('span'); 789 $documentationhtml .= $br . $br; 790 791 // function errors documentation for REST protocol 792 if (!empty($activatedprotocol['rest'])) { 793 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6')); 794 $documentationhtml .= get_string('errorcodes', 'webservice'); 795 $documentationhtml .= html_writer::end_tag('span'); 796 $documentationhtml .= $br . $br; 797 $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%')); 798 $errormessage = get_string('invalidparameter', 'debug'); 799 $restexceptiontext = <<<EOF 800 <?xml version="1.0" encoding="UTF-8"?> 801 <EXCEPTION class="invalid_parameter_exception"> 802 <MESSAGE>{$errormessage}</MESSAGE> 803 <DEBUGINFO></DEBUGINFO> 804 </EXCEPTION> 805 EOF; 806 $documentationhtml .= $this->colored_box_with_pre_tag( 807 get_string('restexception', 'webservice'), 808 htmlentities($restexceptiontext), 809 'FEEBE5'); 810 811 $documentationhtml .= html_writer::end_tag('span'); 812 } 813 $documentationhtml .= $br . $br; 814 815 // Login required info. 816 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6')); 817 $documentationhtml .= get_string('loginrequired', 'webservice') . $br; 818 $documentationhtml .= html_writer::end_tag('span'); 819 $documentationhtml .= $description->loginrequired ? get_string('yes') : get_string('no'); 820 $documentationhtml .= $br . $br; 821 822 // Ajax info. 823 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6')); 824 $documentationhtml .= get_string('callablefromajax', 'webservice') . $br; 825 $documentationhtml .= html_writer::end_tag('span'); 826 $documentationhtml .= $description->allowed_from_ajax ? get_string('yes') : get_string('no'); 827 $documentationhtml .= $br . $br; 828 829 if (empty($printableformat)) { 830 $documentationhtml .= print_collapsible_region_end(true); 831 } 832 } 833 834 return $documentationhtml; 835 } 836 837 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body