MDL-25973 add missing charset
[moodle.git] / webservice / rest / locallib.php
CommitLineData
e6bdd128 1<?php
cc93c7da 2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
e6bdd128 18/**
cc93c7da 19 * REST web service implementation classes and methods.
06e7fadc 20 *
06e7fadc 21 * @package webservice
cc93c7da 22 * @copyright 2009 Moodle Pty Ltd (http://moodle.com)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
06e7fadc 24 */
25
cc93c7da 26require_once("$CFG->dirroot/webservice/lib.php");
06e7fadc 27
28/**
cc93c7da 29 * REST service server implementation.
30 * @author Petr Skoda (skodak)
e6bdd128 31 */
cc93c7da 32class webservice_rest_server extends webservice_base_server {
33 /**
34 * Contructor
35 */
2d0acbd5
JP
36 public function __construct($authmethod) {
37 parent::__construct($authmethod);
cc93c7da 38 $this->wsname = 'rest';
89b8ce51 39 }
40
cc93c7da 41 /**
42 * This method parses the $_REQUEST superglobal and looks for
43 * the following information:
44 * 1/ user authentication - username+password or token (wsusername, wspassword and wstoken parameters)
45 * 2/ function name (wsfunction parameter)
46 * 3/ function parameters (all other parameters except those above)
47 *
48 * @return void
49 */
50 protected function parse_request() {
ad8b5ba2 51 if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) {
cc93c7da 52 $this->username = isset($_REQUEST['wsusername']) ? $_REQUEST['wsusername'] : null;
53 unset($_REQUEST['wsusername']);
13036898 54
cc93c7da 55 $this->password = isset($_REQUEST['wspassword']) ? $_REQUEST['wspassword'] : null;
56 unset($_REQUEST['wspassword']);
7c9152bc 57
cc93c7da 58 $this->functionname = isset($_REQUEST['wsfunction']) ? $_REQUEST['wsfunction'] : null;
59 unset($_REQUEST['wsfunction']);
e6bdd128 60
cc93c7da 61 $this->parameters = $_REQUEST;
e6bdd128 62
cc93c7da 63 } else {
01482a4a
PS
64 $this->token = isset($_REQUEST['wstoken']) ? $_REQUEST['wstoken'] : null;
65 unset($_REQUEST['wstoken']);
66
67 $this->functionname = isset($_REQUEST['wsfunction']) ? $_REQUEST['wsfunction'] : null;
68 unset($_REQUEST['wsfunction']);
8a7703ce 69
01482a4a 70 $this->parameters = $_REQUEST;
338bf5a7 71 }
89b8ce51 72 }
e6bdd128 73
cc93c7da 74 /**
75 * Send the result of function call to the WS client
76 * formatted as XML document.
77 * @return void
40f024c9 78 */
cc93c7da 79 protected function send_response() {
80 $this->send_headers();
81 $xml = '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
82 $xml .= '<RESPONSE>'."\n";
83 $xml .= self::xmlize_result($this->returns, $this->function->returns_desc);
84 $xml .= '</RESPONSE>'."\n";
85 echo $xml;
40f024c9 86 }
87
cc93c7da 88 /**
89 * Send the error information to the WS client
90 * formatted as XML document.
91 * @param exception $ex
92 * @return void
93 */
94 protected function send_error($ex=null) {
95 $this->send_headers();
96 $xml = '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
97 $xml .= '<EXCEPTION class="'.get_class($ex).'">'."\n";
98 $xml .= '<MESSAGE>'.htmlentities($ex->getMessage(), ENT_COMPAT, 'UTF-8').'</MESSAGE>'."\n";
99 if (debugging() and isset($ex->debuginfo)) {
100 $xml .= '<DEBUGINFO>'.htmlentities($ex->debuginfo, ENT_COMPAT, 'UTF-8').'</DEBUGINFO>'."\n";
b721783a 101 }
cc93c7da 102 $xml .= '</EXCEPTION>'."\n";
103 echo $xml;
b721783a 104 }
e6bdd128 105
cc93c7da 106 /**
107 * Internal implementation - sending of page headers.
108 * @return void
109 */
110 protected function send_headers() {
8a7703ce 111 header('Content-Type: application/xml; charset=utf-8');
cc93c7da 112 header('Content-Disposition: inline; filename="response.xml"');
113 header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
114 header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT');
115 header('Pragma: no-cache');
116 header('Accept-Ranges: none');
13036898 117 }
118
cc93c7da 119 /**
120 * Internal implementation - recursive function producing XML markup.
121 * @param mixed $returns
122 * @param $desc
123 * @return unknown_type
124 */
125 protected static function xmlize_result($returns, $desc) {
126 if ($desc === null) {
127 return '';
128
129 } else if ($desc instanceof external_value) {
4f0c6ad1
PS
130 if (is_bool($returns)) {
131 // we want 1/0 instead of true/false here
132 $returns = (int)$returns;
133 }
f0dafb3c 134 if (is_null($returns)) {
135 return '<VALUE null="null"/>'."\n";
136 } else {
137 return '<VALUE>'.htmlentities($returns, ENT_COMPAT, 'UTF-8').'</VALUE>'."\n";
138 }
cc93c7da 139
140 } else if ($desc instanceof external_multiple_structure) {
141 $mult = '<MULTIPLE>'."\n";
17ecdd29 142 if (!empty($returns)) {
143 foreach ($returns as $val) {
144 $mult .= self::xmlize_result($val, $desc->content);
8a7703ce 145 }
cc93c7da 146 }
147 $mult .= '</MULTIPLE>'."\n";
148 return $mult;
149
150 } else if ($desc instanceof external_single_structure) {
151 $single = '<SINGLE>'."\n";
152 foreach ($desc->keys as $key=>$subdesc) {
153 if (!array_key_exists($key, $returns)) {
82ff8eb0 154 if ($subdesc->required == VALUE_REQUIRED) {
246f6da2 155 $single .= '<ERROR>Missing required key "'.$key.'"</ERROR>';
cc93c7da 156 continue;
157 } else {
158 //optional field
159 continue;
160 }
161 }
162 $single .= '<KEY name="'.$key.'">'.self::xmlize_result($returns[$key], $subdesc).'</KEY>'."\n";
163 }
164 $single .= '</SINGLE>'."\n";
165 return $single;
13036898 166 }
13036898 167 }
e6bdd128 168}
169
f0dafb3c 170
171/**
172 * REST test client class
173 */
174class webservice_rest_test_client implements webservice_test_client_interface {
175 /**
176 * Execute test client WS request
177 * @param string $serverurl
178 * @param string $function
179 * @param array $params
180 * @return mixed
181 */
182 public function simpletest($serverurl, $function, $params) {
183 return download_file_content($serverurl.'&wsfunction='.$function, null, $params);
184 }
185}