71d4b0c1004fc95bd19757671b4fbe280863a191
[lhc/web/wiklou.git] / soap / index.php
1 <?php
2 # SOAP remote API for MediaWiki
3 #
4 # Copyright (C) 2004 Jens Frank, jeluf@gmx.de
5 # http://www.mediawiki.org/
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License along
18 # with this program; if not, write to the Free Software Foundation, Inc.,
19 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 # http://www.gnu.org/copyleft/gpl.html
21
22 require_once('nusoap.php');
23
24 #
25 # Initialize the environment
26 #
27 unset( $wgEnableSOAP );
28 unset( $IP );
29 @ini_set( "allow_url_fopen", 0 ); # For security...
30
31 if(!file_exists("../LocalSettings.php")) {
32 die( "You'll have to <a href='../config/index.php'>set the wiki up</a> first!" );
33 }
34
35 define( "MEDIAWIKI", true );
36
37 require_once( '../includes/Defines.php' );
38 require_once( '../LocalSettings.php' );
39
40 ini_set( "include_path", "$IP:" . ini_get("include_path") );
41
42 require_once( '../includes/Setup.php' );
43
44 #
45 # SOAP must be activated in the Configuration. Else, exit.
46 #
47 if ( ! $wgEnableSOAP ) {
48 print "You have to enable SOAP by setting \$wgEnableSoap=true; in LocalSettings.php\n";
49 exit;
50 }
51
52 #
53 # Set up server and register methods.
54 #
55
56 $s = new soap_server;
57
58 $s->register('echoString'); # For testing
59 $s->register('getArticle'); # For testing
60 $s->register('getArticleByVersion');
61 $s->register('getArticleRevisions');
62 $s->register('searchTitles');
63
64 # Convert decimal to ASCII-encoded
65 #
66 function decasc( $n ) {
67 return strtoupper(base_convert( $n, 10, 36));
68 }
69 # Test function
70 # Return the string.
71 #
72 function echoString( $in ) {
73 if ( is_string( $in ) ) {
74 return $in;
75 } else {
76 return new soap_fault('Client', 'The parameter to this service must be a string');
77 }
78 }
79
80 # Test function
81 # Return an array:
82 # name IN name of the page to get, e.g. Wikipedia talk:Village Pump
83 # title OUT Title of the page, DB form, e.g. Village_Pump
84 # namespace OUT Namespace of the article, e.g. 3 for Wikipedia_talk.
85 # text OUT Wikitext of the requested page
86 #
87 function getArticle( $name ) {
88 global $wgWhitelistEdit, $wgWhitelistRead;
89
90 if ( $wgWhitelistEdit || $wgWhitelistRead ) {
91 return new soap_fault('Client', 'SOAP not available in whitelist mode.');
92 }
93
94 if ( ! is_string( $name ) ) {
95 return new soap_fault('Client', 'The parameter to this service must be a string');
96 }
97 require_once('Title.php');
98 if( $name == '' ) {
99 $name = wfMsg( "mainpage" );
100 }
101 $wgTitle = Title::newFromText( $name );
102 $dbr =& wfGetDB( DB_SLAVE );
103 $text = $dbr->selectField( 'cur', 'cur_text',
104 "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".$wgTitle->getNamespace(),
105 'SOAP::getArticle' );
106 if ( false === $text ) {
107 return new soap_fault('Client', 'Page does not exist.');
108 }
109 return array(
110 'title' => $wgTitle->getDBkey(),
111 'namespace' => $wgTitle->getNamespace(),
112 'text' => $text
113 );
114 }
115
116 # getArticleByVersion
117 # Returns the wikitext and metadata of an article, either current or old revision.
118 # title IN title of the page, including namespace prefix
119 # version IN version number of the page, or 0 for cur.
120 #
121 # title OUT title of the page, without namespace prefix
122 # namespace OUT namespace number of that article
123 # id OUT ID number of this page
124 # timestamp OUT timestamp of this page
125 # text OUT wikitext of this page
126 #
127 function getArticleByVersion( $title, $version ) {
128 global $wgWhitelistEdit, $wgWhitelistRead;
129 $fname = 'SOAP::getArticleByVersion';
130
131 # Check parameters
132 #
133 if ( $wgWhitelistEdit || $wgWhitelistRead ) {
134 return new soap_fault('Client', 'SOAP not available in whitelist mode.');
135 }
136 if ( ! is_string( $title ) ) {
137 return new soap_fault('Client', 'The first parameter to this service must be a string');
138 }
139 if ( intval( $version ) != $version ) {
140 return new soap_fault('Client', 'The second parameter to this service must be an integer');
141 }
142
143 # Instantiate a title object
144 #
145 require_once('Title.php');
146 if( $title == '' ) {
147 $title = wfMsg( "mainpage" );
148 }
149 $wgTitle = Title::newFromText( $title );
150
151 $dbr =& wfGetDB( DB_SLAVE );
152
153 # set up SQL query
154 #
155 if ( $version == 0 ) {
156 # Get current revision
157 #
158 $sql = "SELECT cur_title AS title, cur_namespace AS namespace, cur_id AS id,
159 cur_timestamp AS timestamp, cur_text as text FROM cur
160 WHERE cur_title = '" . $wgTitle->getDBkey()."' AND cur_namespace=".$wgTitle->getNamespace();
161 } else {
162 $sql = "SELECT old_title AS title, old_namespace AS namespace, old_id AS id,
163 old_timestamp AS timestamp, old_text AS text FROM old
164 WHERE old_title = '" . $wgTitle->getDBkey()."' AND old_id=".intval( $version );
165 }
166
167 $res = $dbr->query( $sql, $fname, true );
168
169 if ( ! $res ) {
170 return new soap_fault( 'Server', $dbr->lastError() );
171 }
172
173 if ( ! ( $line = $dbr->fetchObject( $res ) ) ) {
174 return new soap_fault( 'Client', 'That page or revision does not exist.' );
175 }
176
177 $answer['title'] = $line->title;
178 $answer['namespace'] = $line->namespace;
179 $answer['id'] = $line->id;
180 $answer['timestamp'] = $line->timestamp;
181 $answer['text'] = $line->text;
182
183 return $answer;
184 }
185
186 # getArticleRevisions
187 # Return a list of all revisions of a page.
188 # title IN title of the page, including namespace prefix
189 #
190 # title OUT title of the page, without namespace prefix
191 # namespace OUT namespace number of that article
192 # id OUT ID number of this page
193 # revisions OUT list of revisions of this page. Array consisting of elements with
194 # the following fields:
195 # id OUT revision id of this revision
196 # comment OUT edit comment of this revision
197 # user OUT user name of the user adding this revision
198 # timestamp OUT timestamp of this revision
199 # minor OUT is this change a minor change
200 # unique OUT unique ID of this revision. built from (curid,timestamp,hash(text))
201 #
202 function getArticleRevisions( $title ) {
203 global $wgWhitelistEdit, $wgWhitelistRead;
204 $fname = 'SOAP::getArticleRevisions';
205
206 # Check parameters
207 #
208 if ( $wgWhitelistEdit || $wgWhitelistRead ) {
209 return new soap_fault('Client', 'SOAP not available in whitelist mode.');
210 }
211 if ( ! is_string( $title ) ) {
212 return new soap_fault('Client', 'The first parameter to this service must be a string');
213 }
214
215 # Instantiate a title object
216 #
217 require_once('Title.php');
218 if( $title == '' ) {
219 $title = wfMsg( "mainpage" );
220 }
221 $wgTitle = Title::newFromText( $title );
222
223 $dbr =& wfGetDB( DB_SLAVE );
224
225 # set up SQL query
226 #
227 $sql1 = "SELECT cur_id, cur_comment, cur_user_text, cur_timestamp, cur_minor_edit, cur_text
228 FROM cur
229 WHERE cur_title = '" . $wgTitle->getDBkey()."' AND cur_namespace=".$wgTitle->getNamespace();
230
231 $sql2 = "SELECT old_id, old_comment, old_user_text, old_timestamp, old_minor_edit, old_text
232 FROM old
233 WHERE old_title = '" . $wgTitle->getDBkey()."' AND old_namespace=".$wgTitle->getNamespace();
234
235 $res = $dbr->query( $sql1, $fname, true );
236
237 if ( ! $res ) {
238 return new soap_fault( 'Server', $dbr->lastError() );
239 }
240
241 if ( ! ( $line = $dbr->fetchObject( $res ) ) ) {
242 return new soap_fault( 'Client', 'That page or revision does not exist.' );
243 }
244
245 $curid = $line->cur_id;
246
247 $revisions[] = array(
248 'id' => 0,
249 'comment' => $line->cur_comment,
250 'user' => $line->cur_user_text,
251 'timestamp' => $line->cur_timestamp,
252 'minor' => $line->cur_minor_edit,
253 'unique' => decasc($curid).'-'.
254 decasc(wfTimestamp2Unix($line->cur_timestamp)).'-'.
255 decasc(crc32($line->cur_text))
256 );
257
258 $answer = array(
259 'title' => $wgTitle->getDBkey(),
260 'namespace' => $wgTitle->getNamespace(),
261 'id' => $curid
262 );
263
264
265 $res = $dbr->query( $sql2, $fname, true );
266 $answer['count'] = 1;
267
268 if ( $res ) {
269 while ( $line = $dbr->fetchObject( $res ) ) {
270 $revisions[] = array(
271 'id' => $line->old_id,
272 'comment' => $line->old_comment,
273 'user' => $line->old_user_text,
274 'timestamp' => $line->old_timestamp,
275 'minor' => $line->old_minor_edit,
276 'unique' => decasc($curid).'-'.
277 decasc(wfTimestamp2Unix($line->old_timestamp)).'-'.
278 decasc(crc32($line->old_text))
279 );
280 $answer['count'] ++;
281 }
282 }
283 $answer['revisions'] = $revisions;
284
285 return $answer;
286 }
287
288 # searchTitles
289 # Returns a list of article titles matching a search string
290 # pattern IN search pattern
291 # main_only IN if 1, search only the main namespace, if 0, search all namespaces
292 #
293 # count OUT number of results
294 # base OUT base URL of the hits. Concatenate with title_url to get full url.
295 # hits OUT list of hits. Array consisting of elements with the following fields:
296 # title OUT title of the hit. "Display style". Does not include namespace.
297 # title_ns OUT title of the hit. "Display style". Includes namespace.
298 # title_url OUT title of the hit. URL escaped. Includes namespace prefix.
299 # namespace OUT numerical namespace ID
300 #
301 function searchTitles( $pattern, $main_only ) {
302 global $wgWhitelistEdit, $wgWhitelistRead, $wgLang, $wgServer, $wgArticlePath;
303 $fname = 'SOAP::getArticleRevisions';
304
305 # Check parameters
306 #
307 if ( $wgWhitelistEdit || $wgWhitelistRead ) {
308 return new soap_fault('Client', 'SOAP not available in whitelist mode.');
309 }
310 if ( ! is_string( $pattern ) ) {
311 return new soap_fault('Client', 'The first parameter to this service must be a string');
312 }
313 if ( $main_only != 0 && $main_only != 1 ) {
314 return new soap_fault('Client', 'The second parameter to this service must be 0 or 1');
315 }
316
317
318 # Connect to the DB
319 $dbr =& wfGetDB( DB_SLAVE );
320
321 # Normalize the search pattern
322 $pattern = $dbr->strencode( $wgLang->stripForSearch( $pattern ) );
323
324 # Prepare the query
325
326 $sql = 'SELECT cur_id, cur_namespace, cur_title FROM cur, searchindex WHERE '
327 . ( $main_only ? 'cur_namespace=0 AND ' :'' )
328 . "cur_id=si_page AND MATCH(si_title) AGAINST('{$pattern}' IN BOOLEAN MODE)";
329
330 $res = $dbr->query( $sql, $fname, true );
331
332 if ( ! $res ) {
333 return new soap_fault( 'Server', $dbr->lastError() );
334 }
335
336 $answer = array(
337 'count' => 0,
338 'base' => $wgServer.$wgArticlePath,
339 'hits' => array(),
340 );
341 while ( ($line = $dbr->fetchObject( $res )) && $answer['count'] < 200 ) {
342 $nt = Title::newFromDBkey( $wgLang->getNsText( $line->cur_namespace ) . ':' . $line->cur_title );
343 $answer['hits'][] = array(
344 'title' => $nt->getText(),
345 'title_ns' => $nt->getPrefixedText(),
346 'title_url' => $nt->getPartialURL(),
347 'namespace' => $line->cur_namespace
348 );
349 $answer['count']++;
350 }
351
352 return $answer;
353 }
354
355 # SOAP uses POST, if POST data is available, process it. Else produce an error.
356 if ( isset( $HTTP_RAW_POST_DATA ) ) {
357 $s->service( $HTTP_RAW_POST_DATA );
358 } else {
359 print( "You need a SOAP client to access SOAP services." );
360 }
361
362 ?>