API * simple backlinks module (no redirect resolution yet)
[lhc/web/wiklou.git] / includes / api / ApiQueryBase.php
1 <?php
2
3
4 /*
5 * Created on Sep 7, 2006
6 *
7 * API for MediaWiki 1.8+
8 *
9 * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * http://www.gnu.org/copyleft/gpl.html
25 */
26
27 if (!defined('MEDIAWIKI')) {
28 // Eclipse helper - will be ignored in production
29 require_once ('ApiBase.php');
30 }
31
32 abstract class ApiQueryBase extends ApiBase {
33
34 private $mQueryModule, $tables, $where, $fields, $options;
35
36 public function __construct($query, $moduleName, $paramPrefix = '') {
37 parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
38 $this->mQueryModule = $query;
39
40 $this->tables = array ();
41 $this->where = array ();
42 $this->fields = array();
43 $this->options = array ();
44 }
45
46 protected function addTables($value) {
47 if(is_array($value))
48 $this->tables = array_merge($this->tables, $value);
49 else
50 $this->tables[] = $value;
51 }
52
53 protected function addFields($value) {
54 if(is_array($value))
55 $this->fields = array_merge($this->fields, $value);
56 else
57 $this->fields[] = $value;
58 }
59
60 protected function addFieldsIf($value, $condition) {
61 if ($condition) {
62 $this->addFields($value);
63 return true;
64 }
65 return false;
66 }
67
68 protected function addWhere($value) {
69 if(is_array($value))
70 $this->where = array_merge($this->where, $value);
71 else
72 $this->where[] = $value;
73 }
74
75 protected function addWhereIf($value, $condition) {
76 if ($condition) {
77 $this->addWhere($value);
78 return true;
79 }
80 return false;
81 }
82
83 protected function addWhereFld($field, $value) {
84 if(!is_null($value))
85 $this->where[$field] = $value;
86 }
87
88 protected function addWhereRange($field, $dir, $start, $end) {
89 $isDirNewer = ($dir === 'newer');
90 $after = ($isDirNewer ? '<=' : '>=');
91 $before = ($isDirNewer ? '>=' : '<=');
92 $db = & $this->getDB();
93
94 if (!is_null($start))
95 $this->addWhere($field . $after . $db->addQuotes($start));
96
97 if (!is_null($end))
98 $this->addWhere($field . $before . $db->addQuotes($end));
99
100 $this->addOption('ORDER BY', $field . ($isDirNewer ? '' : ' DESC'));
101 }
102
103 protected function addOption($name, $value) {
104 $this->options[$name] = $value;
105 }
106
107 protected function select($method) {
108
109 // getDB has its own profileDBIn/Out calls
110 $db = & $this->getDB();
111
112 $this->profileDBIn();
113 $res = $db->select($this->tables, $this->fields, $this->where, $method, $this->options);
114 $this->profileDBOut();
115
116 return $res;
117 }
118
119
120 protected function addRowInfo($prefix, $row) {
121
122 $vals = array();
123
124 // ID
125 @$tmp = $row->{$prefix . '_id'};
126 if(!is_null($tmp)) $vals[$prefix . 'id'] = intval($tmp);
127
128 // Title
129 $title = ApiQueryBase::addRowInfo_title($row, $prefix . '_namespace', $prefix . '_title');
130 if ($title) {
131 if (!$title->userCanRead())
132 return false;
133 $vals['ns'] = $title->getNamespace();
134 $vals['title'] = $title->getPrefixedText();
135 }
136
137 switch($prefix) {
138
139 case 'page':
140 // page_is_redirect
141 @$tmp = $row->page_is_redirect;
142 if($tmp) $vals['redirect'] = '';
143
144 break;
145
146 case 'rc':
147 // PageId
148 @$tmp = $row->rc_cur_id;
149 if(!is_null($tmp)) $vals['pageid'] = intval($tmp);
150
151 @$tmp = $row->rc_this_oldid;
152 if(!is_null($tmp)) $vals['revid'] = intval($tmp);
153
154 @$tmp = $row->rc_last_oldid;
155 if(!is_null($tmp)) $vals['old_revid'] = intval($tmp);
156
157 $title = ApiQueryBase::addRowInfo_title($row, 'rc_moved_to_ns', 'rc_moved_to_title');
158 if ($title) {
159 if (!$title->userCanRead())
160 return false;
161 $vals['new_ns'] = $title->getNamespace();
162 $vals['new_title'] = $title->getPrefixedText();
163 }
164
165 @$tmp = $row->rc_patrolled;
166 if(!is_null($tmp)) $vals['patrolled'] = '';
167
168 break;
169
170 case 'log':
171 // PageId
172 @$tmp = $row->page_id;
173 if(!is_null($tmp)) $vals['pageid'] = intval($tmp);
174
175 if ($row->log_params !== '') {
176 $params = explode("\n", $row->log_params);
177 if ($row->log_type == 'move' && isset ($params[0])) {
178 $newTitle = Title :: newFromText($params[0]);
179 if ($newTitle) {
180 $vals['new_ns'] = $newTitle->getNamespace();
181 $vals['new_title'] = $newTitle->getPrefixedText();
182 $params = null;
183 }
184 }
185
186 if (!empty ($params)) {
187 $this->getResult()->setIndexedTagName($params, 'param');
188 $vals = array_merge($vals, $params);
189 }
190 }
191
192 break;
193 }
194
195 // Type
196 @$tmp = $row->{$prefix . '_type'};
197 if(!is_null($tmp)) $vals['type'] = $tmp;
198
199 // Action
200 @$tmp = $row->{$prefix . '_action'};
201 if(!is_null($tmp)) $vals['action'] = $tmp;
202
203 // Old ID
204 @$tmp = $row->{$prefix . '_text_id'};
205 if(!is_null($tmp)) $vals['oldid'] = intval($tmp);
206
207 // User Name / Anon IP
208 @$tmp = $row->{$prefix . '_user_text'};
209 if(is_null($tmp)) @$tmp = $row->user_name;
210 if(!is_null($tmp)) {
211 $vals['user'] = $tmp;
212 @$tmp = !$row->{$prefix . '_user'};
213 if(!is_null($tmp) && $tmp)
214 $vals['anon'] = '';
215 }
216
217 // Bot Edit
218 @$tmp = $row->{$prefix . '_bot'};
219 if(!is_null($tmp) && $tmp) $vals['bot'] = '';
220
221 // New Edit
222 @$tmp = $row->{$prefix . '_new'};
223 if(is_null($tmp)) @$tmp = $row->{$prefix . '_is_new'};
224 if(!is_null($tmp) && $tmp) $vals['new'] = '';
225
226 // Minor Edit
227 @$tmp = $row->{$prefix . '_minor_edit'};
228 if(is_null($tmp)) @$tmp = $row->{$prefix . '_minor'};
229 if(!is_null($tmp) && $tmp) $vals['minor'] = '';
230
231 // Timestamp
232 @$tmp = $row->{$prefix . '_timestamp'};
233 if(!is_null($tmp))
234 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $tmp);
235
236 // Comment
237 @$tmp = $row->{$prefix . '_comment'};
238 if(!empty($tmp)) // optimize bandwidth
239 $vals['comment'] = $tmp;
240
241 return $vals;
242 }
243
244 private static function addRowInfo_title($row, $nsfld, $titlefld) {
245 @$ns = $row->$nsfld;
246 if(!is_null($ns)) {
247 @$title = $row->$titlefld;
248 if(!empty($title))
249 return Title :: makeTitle($ns, $title);
250 }
251 return false;
252 }
253
254 /**
255 * Override this method to request extra fields from the pageSet
256 * using $this->getPageSet()->requestField('fieldName')
257 */
258 public function requestExtraData() {
259 }
260
261 /**
262 * Get the main Query module
263 */
264 public function getQuery() {
265 return $this->mQueryModule;
266 }
267
268 protected function setContinueEnumParameter($paramName, $paramValue) {
269 $msg = array (
270 $this->encodeParamName($paramName
271 ) => $paramValue);
272 $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
273 }
274
275 /**
276 * Get the Query database connection (readonly)
277 */
278 protected function getDB() {
279 return $this->getQuery()->getDB();
280 }
281
282 /**
283 * Get the PageSet object to work on
284 * @return ApiPageSet data
285 */
286 protected function getPageSet() {
287 return $this->mQueryModule->getPageSet();
288 }
289
290 /**
291 * This is a very simplistic utility function
292 * to convert a non-namespaced title string to a db key.
293 * It will replace all ' ' with '_'
294 */
295 public static function titleToKey($title) {
296 return str_replace(' ', '_', $title);
297 }
298
299 public static function keyToTitle($key) {
300 return str_replace('_', ' ', $key);
301 }
302
303 public static function getBaseVersion() {
304 return __CLASS__ . ': $Id$';
305 }
306 }
307
308 abstract class ApiQueryGeneratorBase extends ApiQueryBase {
309
310 private $mIsGenerator;
311
312 public function __construct($query, $moduleName, $paramPrefix = '') {
313 parent :: __construct($query, $moduleName, $paramPrefix);
314 $this->mIsGenerator = false;
315 }
316
317 public function setGeneratorMode() {
318 $this->mIsGenerator = true;
319 }
320
321 /**
322 * Overrides base class to prepend 'g' to every generator parameter
323 */
324 public function encodeParamName($paramName) {
325 if ($this->mIsGenerator)
326 return 'g' . parent :: encodeParamName($paramName);
327 else
328 return parent :: encodeParamName($paramName);
329 }
330
331 /**
332 * Execute this module as a generator
333 * @param $resultPageSet PageSet: All output should be appended to this object
334 */
335 public abstract function executeGenerator($resultPageSet);
336 }
337 ?>