webservice MDL-21792 refactor webservice authorised users pages
[moodle.git] / webservice / renderer.php
1 <?php
3 ///////////////////////////////////////////////////////////////////////////
4 //                                                                       //
5 // This file is part of Moodle - http://moodle.org/                      //
6 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
7 //                                                                       //
8 // Moodle is free software: you can redistribute it and/or modify        //
9 // it under the terms of the GNU General Public License as published by  //
10 // the Free Software Foundation, either version 3 of the License, or     //
11 // (at your option) any later version.                                   //
12 //                                                                       //
13 // Moodle is distributed in the hope that it will be useful,             //
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
16 // GNU General Public License for more details.                          //
17 //                                                                       //
18 // You should have received a copy of the GNU General Public License     //
19 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.       //
20 //                                                                       //
21 ///////////////////////////////////////////////////////////////////////////
23 /**
24  * Web service documentation renderer.
25  * @package   webservice
26  * @copyright 2009 Moodle Pty Ltd (http://moodle.com)
27  * @author    Jerome Mouneyrac
28  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29  */
30 class core_webservice_renderer extends plugin_renderer_base {
32     /**
33      * Display the authorised user selector
34      * @param object $options
35      * @return string html
36      */
37     public function admin_authorised_user_selector(&$options) {
38         global $OUTPUT;
40         $formcontent = html_writer::empty_tag('input',
41                 array('name' => 'sesskey', 'value' => sesskey(), 'type' => 'hidden'));
43         $table = new html_table();
44         $table->size = array('45%', '10%', '45%');
45         $table->attributes['class'] = 'roleassigntable generaltable generalbox boxaligncenter';
46         $table->summary = '';
47         $table->cellspacing = 0;
48         $table->cellpadding = 0;
50         //create the add and remove button
51         $addinput = html_writer::empty_tag('input',
52                         array('name' => 'add', 'id' => 'add', 'type' => 'submit',
53                             'value' => '◀' . ' ' . get_string('add'),
54                             'title' => get_string('add')));
55         $addbutton = html_writer::tag('div', $addinput, array('id' => 'addcontrols'));
56         $removeinput = html_writer::empty_tag('input',
57                         array('name' => 'remove', 'id' => 'remove', 'type' => 'submit',
58                             'value' => '▶' . ' ' . get_string('remove'),
59                             'title' => get_string('remove')));
60         $removebutton = html_writer::tag('div', $removeinput, array('id' => 'removecontrols'));
63         //create the three cells
64         $label = html_writer::tag('label', get_string('serviceusers', 'webservice'),
65                 array('for' => 'removeselect'));
66         $label = html_writer::tag('p', $label);
67         $authoriseduserscell = new html_table_cell($label . $options->alloweduserselector->display(true));
68         $authoriseduserscell->id = 'existingcell';
69         $buttonscell = new html_table_cell($addbutton . html_writer::empty_tag('br') . $removebutton);
70         $buttonscell->id = 'buttonscell';
71         $label = html_writer::tag('label', get_string('potusers', 'webservice'),
72                 array('for' => 'addselect'));
73         $label = html_writer::tag('p', $label);
74         $otheruserscell = new html_table_cell($label . $options->potentialuserselector->display(true));
75         $otheruserscell->id = 'potentialcell';
77         $cells = array($authoriseduserscell, $buttonscell, $otheruserscell);
78         $row = new html_table_row($cells);
79         $table->data[] = $row;
80         $formcontent .= html_writer::table($table);
82         $formcontent = html_writer::tag('div', $formcontent);
84         $actionurl = new moodle_url('/admin/webservice/service_users.php',
85                         array('id' => $options->serviceid));
86         $html = html_writer::tag('form', $formcontent,
87                 array('id' => 'assignform', 'action' => $actionurl, 'method' => 'post'));
88         return $html;
89     }
91     /**
92      * Display list of authorised user
93      * @param array $users
94      * @return string $html
95      */
96     public function admin_authorised_user_list($users, $serviceid) {
97         global $OUTPUT;
98         $html = $OUTPUT->box_start('generalbox', 'alloweduserlist');
99         foreach ($users as $user) {
100             $modifiedauthoriseduserurl = new moodle_url('/admin/webservice/service_user_settings.php',
101                             array('userid' => $user->id, 'serviceid' => $serviceid));
102             $html .= html_writer::tag('a', $user->firstname . " " . $user->lastname . ", " . $user->email,
103                             array('href' => $modifiedauthoriseduserurl));
104             $html .= html_writer::empty_tag('br');
105         }
106         $html .= $OUTPUT->box_end();
107         return $html;
108     }
110     /**
111      *  Display Reset token confirmation box
112      * @param object $token to reset
113      * @return string html
114      */
115     public function user_reset_token_confirmation($token) {
116         global $OUTPUT, $CFG;
117         $managetokenurl = $CFG->wwwroot . "/user/managetoken.php?sesskey=" . sesskey();
118         $optionsyes = array('tokenid' => $token->id, 'action' => 'resetwstoken', 'confirm' => 1, 'sesskey' => sesskey());
119         $optionsno = array('section' => 'webservicetokens', 'sesskey' => sesskey());
120         $formcontinue = new single_button(new moodle_url($managetokenurl, $optionsyes), get_string('reset'));
121         $formcancel = new single_button(new moodle_url($managetokenurl, $optionsno), get_string('cancel'), 'get');
122         $html = $OUTPUT->confirm(get_string('resettokenconfirm', 'webservice',
123                                 (object) array('user' => $token->firstname . " " . $token->lastname, 'service' => $token->name)),
124                         $formcontinue, $formcancel);
125         return $html;
126     }
128     /**
129      * Display user tokens with buttons to reset them
130      * @param object $tokens
131      * @param int $userid
132      * @return string html code
133      */
134     public function user_webservice_tokens_box($tokens, $userid) {
135         global $OUTPUT, $CFG;
137         // display strings
138         $stroperation = get_string('operation', 'webservice');
139         $strtoken = get_string('key', 'webservice');
140         $strservice = get_string('service', 'webservice');
141         $strcreator = get_string('tokencreator', 'webservice');
142         $strcontext = get_string('context', 'webservice');
143         $strvaliduntil = get_string('validuntil', 'webservice');
145         $return = $OUTPUT->heading(get_string('securitykeys', 'webservice'), 3, 'main', true);
146         $return .= $OUTPUT->box_start('generalbox webservicestokenui');
148         $return .= get_string('keyshelp', 'webservice');
150         $table = new html_table();
151         $table->head = array($strtoken, $strservice, $strvaliduntil, $strcreator, $stroperation);
152         $table->align = array('left', 'left', 'left', 'center', 'left', 'center');
153         $table->width = '100%';
154         $table->data = array();
156         if (!empty($tokens)) {
157             foreach ($tokens as $token) {
158                 //TODO: retrieve context
160                 if ($token->creatorid == $userid) {
161                     $reset = "<a href=\"" . $CFG->wwwroot . "/user/managetoken.php?sesskey=" . sesskey() .
162                             "&amp;action=resetwstoken&amp;tokenid=" . $token->id . "\">";
163                     $reset .= get_string('reset') . "</a>";
164                     $creator = $token->firstname . " " . $token->lastname;
165                 } else {
166                     //retrive administrator name
167                     require_once($CFG->dirroot . '/user/lib.php');
168                     $creators = user_get_users_by_id(array($token->creatorid));
169                     $admincreator = $creators[$token->creatorid];
170                     $creator = $admincreator->firstname . " " . $admincreator->lastname;
171                     $reset = '';
172                 }
174                 $userprofilurl = new moodle_url('/user/view.php?id=' . $token->creatorid);
175                 $creatoratag = html_writer::start_tag('a', array('href' => $userprofilurl));
176                 $creatoratag .= $creator;
177                 $creatoratag .= html_writer::end_tag('a');
179                 $validuntil = '';
180                 if (!empty($token->validuntil)) {
181                     $validuntil = date("F j, Y"); //TODO: language support (look for moodle function)
182                 }
184                 $table->data[] = array($token->token, $token->name, $validuntil, $creatoratag, $reset);
185             }
186             $return .= html_writer::table($table);
187         } else {
188             $return .= get_string('notoken', 'webservice');
189         }
191         $return .= $OUTPUT->box_end();
192         return $return;
193     }
195     /**
196      * Return documentation for a ws description object
197      * ws description object can be 'external_multiple_structure', 'external_single_structure' or 'external_value'
198      * Example of documentation for moodle_group_create_groups function:
199       list of (
200       object {
201       courseid int //id of course
202       name string //multilang compatible name, course unique
203       description string //group description text
204       enrolmentkey string //group enrol secret phrase
205       }
206       )
207      * @param object $params a part of parameter/return description
208      * @return string the html to display
209      */
210     public function detailed_description_html($params) {
211         /// retrieve the description of the description object
212         $paramdesc = "";
213         if (!empty($params->desc)) {
214             $paramdesc .= html_writer::start_tag('span', array('style' => "color:#2A33A6"));
215             if ($params->required == VALUE_REQUIRED) {
216                 $required = '';
217             }
218             if ($params->required == VALUE_DEFAULT) {
219                 if ($params->default === null) {
220                     $params->default = "null";
221                 }
222                 $required = html_writer::start_tag('b', array()) . get_string('default', 'webservice', $params->default) . html_writer::end_tag('b');
223             }
224             if ($params->required == VALUE_OPTIONAL) {
225                 $required = html_writer::start_tag('b', array()) . get_string('optional', 'webservice') . html_writer::end_tag('b');
226             }
227             $paramdesc .= " " . $required . " ";
228             $paramdesc .= html_writer::start_tag('i', array());
229             $paramdesc .= "//";
231             $paramdesc .= $params->desc;
233             $paramdesc .= html_writer::end_tag('i');
235             $paramdesc .= html_writer::end_tag('span');
236             $paramdesc .= html_writer::empty_tag('br', array());
237         }
239         /// description object is a list
240         if ($params instanceof external_multiple_structure) {
241             return $paramdesc . "list of ( " . html_writer::empty_tag('br', array()) . $this->detailed_description_html($params->content) . ")";
242         } else if ($params instanceof external_single_structure) {
243             /// description object is an object
244             $singlestructuredesc = $paramdesc . "object {" . html_writer::empty_tag('br', array());
245             foreach ($params->keys as $attributname => $attribut) {
246                 $singlestructuredesc .= html_writer::start_tag('b', array());
247                 $singlestructuredesc .= $attributname;
248                 $singlestructuredesc .= html_writer::end_tag('b');
249                 $singlestructuredesc .= " " . $this->detailed_description_html($params->keys[$attributname]);
250             }
251             $singlestructuredesc .= "} ";
252             $singlestructuredesc .= html_writer::empty_tag('br', array());
253             return $singlestructuredesc;
254         } else {
255             /// description object is a primary type (string, integer)
256             switch ($params->type) {
257                 case PARAM_BOOL: // 0 or 1 only for now
258                 case PARAM_INT:
259                     $type = 'int';
260                     break;
261                 case PARAM_FLOAT;
262                     $type = 'double';
263                     break;
264                 default:
265                     $type = 'string';
266             }
267             return $type . " " . $paramdesc;
268         }
269     }
271     /**
272      * Return a description object in indented xml format (for REST response)
273      * It is indented in order to be displayed into <pre> tag
274      * @param object $returndescription
275      * @param string $indentation composed by space only
276      * @return string the html to diplay
277      */
278     public function description_in_indented_xml_format($returndescription, $indentation = "") {
279         $indentation = $indentation . "    ";
280         $brakeline = <<<EOF
283 EOF;
284         /// description object is a list
285         if ($returndescription instanceof external_multiple_structure) {
286             $return = $indentation . "<MULTIPLE>" . $brakeline;
287             $return .= $this->description_in_indented_xml_format($returndescription->content, $indentation);
288             $return .= $indentation . "</MULTIPLE>" . $brakeline;
289             return $return;
290         } else if ($returndescription instanceof external_single_structure) {
291             /// description object is an object
292             $singlestructuredesc = $indentation . "<SINGLE>" . $brakeline;
293             $keyindentation = $indentation . "    ";
294             foreach ($returndescription->keys as $attributname => $attribut) {
295                 $singlestructuredesc .= $keyindentation . "<KEY name=\"" . $attributname . "\">" . $brakeline .
296                         $this->description_in_indented_xml_format($returndescription->keys[$attributname], $keyindentation) .
297                         $keyindentation . "</KEY>" . $brakeline;
298             }
299             $singlestructuredesc .= $indentation . "</SINGLE>" . $brakeline;
300             return $singlestructuredesc;
301         } else {
302             /// description object is a primary type (string, integer)
303             switch ($returndescription->type) {
304                 case PARAM_BOOL: // 0 or 1 only for now
305                 case PARAM_INT:
306                     $type = 'int';
307                     break;
308                 case PARAM_FLOAT;
309                     $type = 'double';
310                     break;
311                 default:
312                     $type = 'string';
313             }
314             return $indentation . "<VALUE>" . $type . "</VALUE>" . $brakeline;
315         }
316     }
318     /**
319      * Create indented XML-RPC  param description
320      * @param object $paramdescription
321      * @param string $indentation composed by space only
322      * @return string the html to diplay
323      */
324     public function xmlrpc_param_description_html($paramdescription, $indentation = "") {
325         $indentation = $indentation . "    ";
326         $brakeline = <<<EOF
329 EOF;
330         /// description object is a list
331         if ($paramdescription instanceof external_multiple_structure) {
332             $return = $brakeline . $indentation . "Array ";
333             $indentation = $indentation . "    ";
334             $return .= $brakeline . $indentation . "(";
335             $return .= $brakeline . $indentation . "[0] =>";
336             $return .= $this->xmlrpc_param_description_html($paramdescription->content, $indentation);
337             $return .= $brakeline . $indentation . ")";
338             return $return;
339         } else if ($paramdescription instanceof external_single_structure) {
340             /// description object is an object
341             $singlestructuredesc = $brakeline . $indentation . "Array ";
342             $keyindentation = $indentation . "    ";
343             $singlestructuredesc .= $brakeline . $keyindentation . "(";
344             foreach ($paramdescription->keys as $attributname => $attribut) {
345                 $singlestructuredesc .= $brakeline . $keyindentation . "[" . $attributname . "] =>" .
346                         $this->xmlrpc_param_description_html($paramdescription->keys[$attributname], $keyindentation) .
347                         $keyindentation;
348             }
349             $singlestructuredesc .= $brakeline . $keyindentation . ")";
350             return $singlestructuredesc;
351         } else {
352             /// description object is a primary type (string, integer)
353             switch ($paramdescription->type) {
354                 case PARAM_BOOL: // 0 or 1 only for now
355                 case PARAM_INT:
356                     $type = 'int';
357                     break;
358                 case PARAM_FLOAT;
359                     $type = 'double';
360                     break;
361                 default:
362                     $type = 'string';
363             }
364             return " " . $type;
365         }
366     }
368     /**
369      * Return the html of a colored box with content
370      * @param string $title - the title of the box
371      * @param string $content - the content to displayed
372      * @param string $rgb - the background color of the box
373      * @return <type>
374      */
375     public function colored_box_with_pre_tag($title, $content, $rgb = 'FEEBE5') {
376         $coloredbox = html_writer::start_tag('ins', array()); //TODO: this tag removes xhtml strict error but cause warning
377         $coloredbox .= html_writer::start_tag('div', array('style' => "border:solid 1px #DEDEDE;background:#" . $rgb . ";color:#222222;padding:4px;"));
378         $coloredbox .= html_writer::start_tag('pre', array());
379         $coloredbox .= html_writer::start_tag('b', array());
380         $coloredbox .= $title;
381         $coloredbox .= html_writer::end_tag('b', array());
382         $coloredbox .= html_writer::empty_tag('br', array());
383         $coloredbox .= "\n" . $content . "\n";
384         $coloredbox .= html_writer::end_tag('pre', array());
385         $coloredbox .= html_writer::end_tag('div', array());
386         $coloredbox .= html_writer::end_tag('ins', array());
387         return $coloredbox;
388     }
390     /**
391      * Return indented REST param description
392      * @param object $paramdescription
393      * @param string $indentation composed by space only
394      * @return string the html to diplay
395      */
396     public function rest_param_description_html($paramdescription, $paramstring) {
397         $brakeline = <<<EOF
400 EOF;
401         /// description object is a list
402         if ($paramdescription instanceof external_multiple_structure) {
403             $paramstring = $paramstring . '[0]';
404             $return = $this->rest_param_description_html($paramdescription->content, $paramstring);
405             return $return;
406         } else if ($paramdescription instanceof external_single_structure) {
407             /// description object is an object
408             $singlestructuredesc = "";
409             $initialparamstring = $paramstring;
410             foreach ($paramdescription->keys as $attributname => $attribut) {
411                 $paramstring = $initialparamstring . '[' . $attributname . ']';
412                 $singlestructuredesc .= $this->rest_param_description_html($paramdescription->keys[$attributname], $paramstring);
413             }
414             return $singlestructuredesc;
415         } else {
416             /// description object is a primary type (string, integer)
417             $paramstring = $paramstring . '=';
418             switch ($paramdescription->type) {
419                 case PARAM_BOOL: // 0 or 1 only for now
420                 case PARAM_INT:
421                     $type = 'int';
422                     break;
423                 case PARAM_FLOAT;
424                     $type = 'double';
425                     break;
426                 default:
427                     $type = 'string';
428             }
429             return $paramstring . " " . $type . $brakeline;
430         }
431     }
433     /**
434      * This display all the documentation
435      * @param array $functions contains all decription objects
436      * @param array $authparam keys are either 'username'/'password' or 'token'
437      * @param boolean $printableformat true if we want to display the documentation in a printable format
438      * @param array $activatedprotocol
439      * @return string the html to diplay
440      */
441     public function documentation_html($functions, $printableformat, $activatedprotocol, $authparams) {
442         global $OUTPUT, $CFG;
443         $br = html_writer::empty_tag('br', array());
444         $brakeline = <<<EOF
447 EOF;
448         /// Some general information
449         $documentationhtml = html_writer::start_tag('table', array('style' => "margin-left:auto; margin-right:auto;"));
450         $documentationhtml .= html_writer::start_tag('tr', array());
451         $documentationhtml .= html_writer::start_tag('td', array());
452         $documentationhtml .= get_string('wsdocumentationintro', 'webservice', $authparams['wsusername']);
453         $documentationhtml .= $br . $br;
456         /// Print button
457         $authparams['print'] = true;
458         //$parameters = array ('token' => $token, 'wsusername' => $username, 'wspassword' => $password, 'print' => true);
459         $url = new moodle_url('/webservice/wsdoc.php', $authparams); // Required
460         $documentationhtml .= $OUTPUT->single_button($url, get_string('print', 'webservice'));
461         $documentationhtml .= $br;
464         /// each functions will be displayed into a collapsible region (opened if printableformat = true)
465         foreach ($functions as $functionname => $description) {
467             if (empty($printableformat)) {
468                 $documentationhtml .= print_collapsible_region_start('',
469                                 'aera_' . $functionname,
470                                 html_writer::start_tag('strong', array()) . $functionname . html_writer::end_tag('strong'),
471                                 false,
472                                 !$printableformat,
473                                 true);
474             } else {
475                 $documentationhtml .= html_writer::tag('strong', $functionname);
476                 $documentationhtml .= $br;
477             }
479             /// function global description
480             $documentationhtml .= $br;
481             $documentationhtml .= html_writer::start_tag('div', array('style' => 'border:solid 1px #DEDEDE;background:#E2E0E0;color:#222222;padding:4px;'));
482             $documentationhtml .= $description->description;
483             $documentationhtml .= html_writer::end_tag('div');
484             $documentationhtml .= $br . $br;
486             /// function arguments documentation
487             $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6'));
488             $documentationhtml .= get_string('arguments', 'webservice');
489             $documentationhtml .= html_writer::end_tag('span');
490             $documentationhtml .= $br;
491             foreach ($description->parameters_desc->keys as $paramname => $paramdesc) {
492                 /// a argument documentation
493                 $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%'));
495                 if ($paramdesc->required == VALUE_REQUIRED) {
496                     $required = get_string('required', 'webservice');
497                 }
498                 if ($paramdesc->required == VALUE_DEFAULT) {
499                     if ($paramdesc->default === null) {
500                         $default = "null";
501                     } else {
502                         $default = $paramdesc->default;
503                     }
504                     $required = get_string('default', 'webservice', $default);
505                 }
506                 if ($paramdesc->required == VALUE_OPTIONAL) {
507                     $required = get_string('optional', 'webservice');
508                 }
510                 $documentationhtml .= html_writer::start_tag('b', array());
511                 $documentationhtml .= $paramname;
512                 $documentationhtml .= html_writer::end_tag('b');
513                 $documentationhtml .= " (" . $required . ")"; // argument is required or optional ?
514                 $documentationhtml .= $br;
515                 $documentationhtml .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . $paramdesc->desc; // argument description
516                 $documentationhtml .= $br . $br;
517                 ///general structure of the argument
518                 $documentationhtml .= $this->colored_box_with_pre_tag(get_string('generalstructure', 'webservice'),
519                                 $this->detailed_description_html($paramdesc),
520                                 'FFF1BC');
521                 ///xml-rpc structure of the argument in PHP format
522                 if (!empty($activatedprotocol['xmlrpc'])) {
523                     $documentationhtml .= $this->colored_box_with_pre_tag(get_string('phpparam', 'webservice'),
524                                     htmlentities('[' . $paramname . '] =>' . $this->xmlrpc_param_description_html($paramdesc)),
525                                     'DFEEE7');
526                 }
527                 ///POST format for the REST protocol for the argument
528                 if (!empty($activatedprotocol['rest'])) {
529                     $documentationhtml .= $this->colored_box_with_pre_tag(get_string('restparam', 'webservice'),
530                                     htmlentities($this->rest_param_description_html($paramdesc, $paramname)),
531                                     'FEEBE5');
532                 }
533                 $documentationhtml .= html_writer::end_tag('span');
534             }
535             $documentationhtml .= $br . $br;
538             /// function response documentation
539             $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6'));
540             $documentationhtml .= get_string('response', 'webservice');
541             $documentationhtml .= html_writer::end_tag('span');
542             $documentationhtml .= $br;
543             /// function response description
544             $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%'));
545             if (!empty($description->returns_desc->desc)) {
546                 $documentationhtml .= $description->returns_desc->desc;
547                 $documentationhtml .= $br . $br;
548             }
549             if (!empty($description->returns_desc)) {
550                 ///general structure of the response
551                 $documentationhtml .= $this->colored_box_with_pre_tag(get_string('generalstructure', 'webservice'),
552                                 $this->detailed_description_html($description->returns_desc),
553                                 'FFF1BC');
554                 ///xml-rpc structure of the response in PHP format
555                 if (!empty($activatedprotocol['xmlrpc'])) {
556                     $documentationhtml .= $this->colored_box_with_pre_tag(get_string('phpresponse', 'webservice'),
557                                     htmlentities($this->xmlrpc_param_description_html($description->returns_desc)),
558                                     'DFEEE7');
559                 }
560                 ///XML response for the REST protocol
561                 if (!empty($activatedprotocol['rest'])) {
562                     $restresponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" . $brakeline . "<RESPONSE>" . $brakeline;
563                     $restresponse .= $this->description_in_indented_xml_format($description->returns_desc);
564                     $restresponse .="</RESPONSE>" . $brakeline;
565                     $documentationhtml .= $this->colored_box_with_pre_tag(get_string('restcode', 'webservice'),
566                                     htmlentities($restresponse),
567                                     'FEEBE5');
568                 }
569             }
570             $documentationhtml .= html_writer::end_tag('span');
571             $documentationhtml .= $br . $br;
573             /// function errors documentation for REST protocol
574             if (!empty($activatedprotocol['rest'])) {
575                 $documentationhtml .= html_writer::start_tag('span', array('style' => 'color:#EA33A6'));
576                 $documentationhtml .= get_string('errorcodes', 'webservice');
577                 $documentationhtml .= html_writer::end_tag('span');
578                 $documentationhtml .= $br . $br;
579                 $documentationhtml .= html_writer::start_tag('span', array('style' => 'font-size:80%'));
580                 $errormessage = get_string('invalidparameter', 'debug');
581                 $restexceptiontext = <<<EOF
582 <?xml version="1.0" encoding="UTF-8"?>
583 <EXCEPTION class="invalid_parameter_exception">
584     <MESSAGE>{$errormessage}</MESSAGE>
585     <DEBUGINFO></DEBUGINFO>
586 </EXCEPTION>
587 EOF;
588                 $documentationhtml .= $this->colored_box_with_pre_tag(get_string('restexception', 'webservice'),
589                                 htmlentities($restexceptiontext),
590                                 'FEEBE5');
592                 $documentationhtml .= html_writer::end_tag('span');
593             }
594             $documentationhtml .= $br . $br;
595             if (empty($printableformat)) {
596                 $documentationhtml .= print_collapsible_region_end(true);
597             }
598         }
600         /// close the table and return the documentation
601         $documentationhtml .= html_writer::end_tag('td');
602         $documentationhtml .= html_writer::end_tag('tr');
603         $documentationhtml .= html_writer::end_tag('table');
605         return $documentationhtml;
606     }
608     /**
609      * Return the login page html
610      * @param string $errormessage - the error message to display
611      * @return string the html to diplay
612      */
613     public function login_page_html($errormessage) {
614         global $CFG, $OUTPUT;
616         $br = html_writer::empty_tag('br', array());
618         $htmlloginpage = html_writer::start_tag('table', array('style' => "margin-left:auto; margin-right:auto;"));
619         $htmlloginpage .= html_writer::start_tag('tr', array());
620         $htmlloginpage .= html_writer::start_tag('td', array());
622 //        /// Display detailed error message when can't login
623 //        $htmlloginpage .= get_string('error','webservice',$errormessage);
624 //        $htmlloginpage .= html_writer::empty_tag('br', array());
625 //        $htmlloginpage .= html_writer::empty_tag('br', array());
626         //login form - we cannot use moodle form as we don't have sessionkey
627         $target = new moodle_url('/webservice/wsdoc.php', array()); // Required
629         $contents = get_string('entertoken', 'webservice');
630         $contents .= $br . $br;
631         $contents .= html_writer::empty_tag('input', array('type' => 'text', 'name' => 'token', 'style' => 'width: 30em;'));
633         $contents .= $br . $br;
634         $contents .= get_string('wsdocumentationlogin', 'webservice');
635         $contents .= $br . $br;
636         $contents .= html_writer::empty_tag('input', array('type' => 'text', 'name' => 'wsusername', 'style' => 'width: 30em;', 'value' => get_string('wsusername', 'webservice')));
637         $contents .= $br . $br;
638         $contents .= html_writer::empty_tag('input', array('type' => 'text', 'name' => 'wspassword', 'style' => 'width: 30em;', 'value' => get_string('wspassword', 'webservice')));
639         $contents .= $br . $br;
640         $contents .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'submit', 'value' => get_string('wsdocumentation', 'webservice')));
642         $htmlloginpage .= html_writer::tag('form', "<div>$contents</div>", array('method' => 'post', 'target' => $target));
644         $htmlloginpage .= html_writer::end_tag('td');
645         $htmlloginpage .= html_writer::end_tag('tr');
646         $htmlloginpage .= html_writer::end_tag('table');
648         return $htmlloginpage;
649     }