Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -245,11 +245,10 @@ |
246 | 246 | ) |
247 | 247 | ), |
248 | 248 | 'limit' => array ( |
249 | | - ApiBase :: PARAM_DFLT => null, |
250 | 249 | ApiBase :: PARAM_TYPE => 'limit', |
251 | | - ApiBase :: PARAM_MIN => 0, |
252 | | - ApiBase :: PARAM_MAX1 => 50, |
253 | | - ApiBase :: PARAM_MAX2 => 500 |
| 250 | + ApiBase :: PARAM_MIN => 1, |
| 251 | + ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_SML1, |
| 252 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_SML2 |
254 | 253 | ), |
255 | 254 | 'startid' => array ( |
256 | 255 | ApiBase :: PARAM_TYPE => 'integer' |
Index: trunk/phase3/includes/api/ApiFormatXml.php |
— | — | @@ -104,8 +104,6 @@ |
105 | 105 | $subElements = array (); |
106 | 106 | foreach ($elemValue as $subElemId => & $subElemValue) { |
107 | 107 | if (gettype($subElemId) === 'integer') { |
108 | | - if (!is_array($subElemValue)) |
109 | | - ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has a scalar indexed value."); |
110 | 108 | $indElements[] = $subElemValue; |
111 | 109 | unset ($elemValue[$subElemId]); |
112 | 110 | } elseif (is_array($subElemValue)) { |
— | — | @@ -115,7 +113,7 @@ |
116 | 114 | } |
117 | 115 | |
118 | 116 | if (is_null($subElemIndName) && !empty ($indElements)) |
119 | | - ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has integer keys without _element value"); |
| 117 | + ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName()."); |
120 | 118 | |
121 | 119 | if (!empty ($subElements) && !empty ($indElements) && !is_null($subElemContent)) |
122 | 120 | ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has content and subelements"); |
Index: trunk/phase3/includes/api/ApiBase.php |
— | — | @@ -35,6 +35,11 @@ |
36 | 36 | const PARAM_MAX2 = 4; |
37 | 37 | const PARAM_MIN = 5; |
38 | 38 | |
| 39 | + const LIMIT_BIG1 = 500; // Fast query, user's limit |
| 40 | + const LIMIT_BIG2 = 5000; // Fast query, bot's limit |
| 41 | + const LIMIT_SML1 = 50; // Slow query, user's limit |
| 42 | + const LIMIT_SML2 = 500; // Slow query, bot's limit |
| 43 | + |
39 | 44 | private $mMainModule, $mModuleName, $mParamPrefix; |
40 | 45 | |
41 | 46 | /** |
— | — | @@ -42,7 +47,7 @@ |
43 | 48 | */ |
44 | 49 | public function __construct($mainModule, $moduleName, $paramPrefix = '') { |
45 | 50 | $this->mMainModule = $mainModule; |
46 | | - $this->mModuleName = $moduleName; |
| 51 | + $this->mModuleName = $moduleName; |
47 | 52 | $this->mParamPrefix = $paramPrefix; |
48 | 53 | } |
49 | 54 | |
— | — | @@ -51,22 +56,22 @@ |
52 | 57 | */ |
53 | 58 | public abstract function execute(); |
54 | 59 | |
55 | | - /** |
56 | | - * Get the name of the module being executed by this instance |
57 | | - */ |
58 | | - public function getModuleName() { |
59 | | - return $this->mModuleName; |
60 | | - } |
| 60 | + /** |
| 61 | + * Get the name of the module being executed by this instance |
| 62 | + */ |
| 63 | + public function getModuleName() { |
| 64 | + return $this->mModuleName; |
| 65 | + } |
61 | 66 | |
62 | | - /** |
63 | | - * Get the name of the module as shown in the profiler log |
64 | | - */ |
65 | | - public function getModuleProfileName($db = false) { |
66 | | - if ($db) |
67 | | - return 'API:' . $this->mModuleName . '-DB'; |
68 | | - else |
69 | | - return 'API:' . $this->mModuleName; |
70 | | - } |
| 67 | + /** |
| 68 | + * Get the name of the module as shown in the profiler log |
| 69 | + */ |
| 70 | + public function getModuleProfileName($db = false) { |
| 71 | + if ($db) |
| 72 | + return 'API:' . $this->mModuleName . '-DB'; |
| 73 | + else |
| 74 | + return 'API:' . $this->mModuleName; |
| 75 | + } |
71 | 76 | |
72 | 77 | /** |
73 | 78 | * Get main module |
— | — | @@ -161,23 +166,21 @@ |
162 | 167 | $paramsDescription = $this->getParamDescription(); |
163 | 168 | $msg = ''; |
164 | 169 | $paramPrefix = "\n" . str_repeat(' ', 19); |
165 | | - foreach ($params as $paramName => &$paramSettings) { |
| 170 | + foreach ($params as $paramName => & $paramSettings) { |
166 | 171 | $desc = isset ($paramsDescription[$paramName]) ? $paramsDescription[$paramName] : ''; |
167 | 172 | if (is_array($desc)) |
168 | 173 | $desc = implode($paramPrefix, $desc); |
169 | 174 | if (isset ($paramSettings[self :: PARAM_TYPE])) { |
170 | 175 | $type = $paramSettings[self :: PARAM_TYPE]; |
171 | 176 | if (is_array($type)) { |
172 | | - $desc .= $paramPrefix . 'Allowed values: '. implode(', ', $type); |
| 177 | + $desc .= $paramPrefix . 'Allowed values: ' . implode(', ', $type); |
173 | 178 | } |
174 | 179 | } |
175 | | - |
176 | | - $default = is_array($paramSettings) |
177 | | - ? (isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null) |
178 | | - : $paramSettings; |
| 180 | + |
| 181 | + $default = is_array($paramSettings) ? (isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null) : $paramSettings; |
179 | 182 | if (!is_null($default) && $default !== false) |
180 | 183 | $desc .= $paramPrefix . "Default: $default"; |
181 | | - |
| 184 | + |
182 | 185 | $msg .= sprintf(" %-14s - %s\n", $this->encodeParamName($paramName), $desc); |
183 | 186 | } |
184 | 187 | return $msg; |
— | — | @@ -213,7 +216,7 @@ |
214 | 217 | protected function getParamDescription() { |
215 | 218 | return false; |
216 | 219 | } |
217 | | - |
| 220 | + |
218 | 221 | /** |
219 | 222 | * This method mangles parameter name based on the prefix supplied to the constructor. |
220 | 223 | * Override this method to change parameter name during runtime |
— | — | @@ -250,7 +253,7 @@ |
251 | 254 | * Using the settings determine the value for the given parameter |
252 | 255 | * @param $paramName String: parameter name |
253 | 256 | * @param $paramSettings Mixed: default value or an array of settings using PARAM_* constants. |
254 | | - */ |
| 257 | + */ |
255 | 258 | protected function getParameterFromSettings($paramName, $paramSettings) { |
256 | 259 | |
257 | 260 | // Some classes may decide to change parameter names |
— | — | @@ -284,7 +287,7 @@ |
285 | 288 | } else { |
286 | 289 | $value = $this->getMain()->getRequest()->getVal($paramName, $default); |
287 | 290 | } |
288 | | - |
| 291 | + |
289 | 292 | if (isset ($value) && ($multi || is_array($type))) |
290 | 293 | $value = $this->parseMultiValue($paramName, $value, $multi, is_array($type) ? $type : null); |
291 | 294 | |
— | — | @@ -328,7 +331,7 @@ |
329 | 332 | // There should never be any duplicate values in a list |
330 | 333 | if (is_array($value)) |
331 | 334 | $value = array_unique($value); |
332 | | - |
| 335 | + |
333 | 336 | return $value; |
334 | 337 | } |
335 | 338 | |
— | — | @@ -418,10 +421,22 @@ |
419 | 422 | |
420 | 423 | $this->mModuleTime += microtime(true) - $this->mTimeIn; |
421 | 424 | $this->mTimeIn = 0; |
422 | | - wfProfileOut($this->getModuleProfileName()); |
| 425 | + wfProfileOut($this->getModuleProfileName()); |
423 | 426 | } |
424 | 427 | |
425 | 428 | /** |
| 429 | + * When modules crash, sometimes it is needed to do a profileOut() regardless |
| 430 | + * of the profiling state the module was in. This method does such cleanup. |
| 431 | + */ |
| 432 | + public function safeProfileOut() { |
| 433 | + if ($this->mTimeIn !== 0) { |
| 434 | + if ($this->mDBTimeIn !== 0) |
| 435 | + $this->profileDBOut(); |
| 436 | + $this->profileOut(); |
| 437 | + } |
| 438 | + } |
| 439 | + |
| 440 | + /** |
426 | 441 | * Total time the module was executed |
427 | 442 | */ |
428 | 443 | public function getProfileTime() { |
— | — | @@ -474,7 +489,7 @@ |
475 | 490 | } |
476 | 491 | |
477 | 492 | public abstract function getVersion(); |
478 | | - |
| 493 | + |
479 | 494 | public static function getBaseVersion() { |
480 | 495 | return __CLASS__ . ': $Id$'; |
481 | 496 | } |
Index: trunk/phase3/includes/api/ApiQueryAllpages.php |
— | — | @@ -142,8 +142,8 @@ |
143 | 143 | ApiBase :: PARAM_DFLT => 10, |
144 | 144 | ApiBase :: PARAM_TYPE => 'limit', |
145 | 145 | ApiBase :: PARAM_MIN => 1, |
146 | | - ApiBase :: PARAM_MAX1 => 500, |
147 | | - ApiBase :: PARAM_MAX2 => 5000 |
| 146 | + ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1, |
| 147 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
148 | 148 | )); |
149 | 149 | } |
150 | 150 | |
Index: trunk/phase3/includes/api/ApiFormatJson.php |
— | — | @@ -31,14 +31,21 @@ |
32 | 32 | |
33 | 33 | class ApiFormatJson extends ApiFormatBase { |
34 | 34 | |
| 35 | + private $mIsRaw; |
| 36 | + |
35 | 37 | public function __construct($main, $format) { |
36 | 38 | parent :: __construct($main, $format); |
| 39 | + $this->mIsRaw = ($format === 'raw' || $format === 'rawfm'); |
37 | 40 | } |
38 | 41 | |
39 | 42 | public function getMimeType() { |
40 | 43 | return 'application/json'; |
41 | 44 | } |
42 | | - |
| 45 | + |
| 46 | + public function getNeedsRawData() { |
| 47 | + return $this->mIsRaw; |
| 48 | + } |
| 49 | + |
43 | 50 | public function execute() { |
44 | 51 | if (!function_exists('json_encode') || $this->getIsHtml()) { |
45 | 52 | $json = new Services_JSON(); |
Index: trunk/phase3/includes/api/ApiMain.php |
— | — | @@ -57,6 +57,8 @@ |
58 | 58 | private static $Formats = array ( |
59 | 59 | 'json' => 'ApiFormatJson', |
60 | 60 | 'jsonfm' => 'ApiFormatJson', |
| 61 | + 'raw' => 'ApiFormatJson', |
| 62 | + 'rawfm' => 'ApiFormatJson', |
61 | 63 | 'xml' => 'ApiFormatXml', |
62 | 64 | 'xmlfm' => 'ApiFormatXml', |
63 | 65 | 'yaml' => 'ApiFormatYaml', |
— | — | @@ -169,6 +171,9 @@ |
170 | 172 | ob_clean(); |
171 | 173 | $this->mResult->Reset(); |
172 | 174 | $this->mResult->addValue(null, 'error', $errMessage); |
| 175 | + |
| 176 | + // If the error occured during printing, do a printer->profileOut() |
| 177 | + $this->mPrinter->safeProfileOut(); |
173 | 178 | $this->printResult(true); |
174 | 179 | } |
175 | 180 | |
Index: trunk/phase3/includes/api/ApiQueryWatchlist.php |
— | — | @@ -232,8 +232,8 @@ |
233 | 233 | ApiBase :: PARAM_DFLT => 10, |
234 | 234 | ApiBase :: PARAM_TYPE => 'limit', |
235 | 235 | ApiBase :: PARAM_MIN => 1, |
236 | | - ApiBase :: PARAM_MAX1 => 500, |
237 | | - ApiBase :: PARAM_MAX2 => 5000 |
| 236 | + ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1, |
| 237 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
238 | 238 | ), |
239 | 239 | 'prop' => array ( |
240 | 240 | APIBase :: PARAM_ISMULTI => true, |
Index: trunk/phase3/includes/api/ApiQueryLogEvents.php |
— | — | @@ -36,14 +36,14 @@ |
37 | 37 | } |
38 | 38 | |
39 | 39 | public function execute() { |
40 | | - $limit = $type = $from = $to = $dir = $user = $title = $namespace = null; |
| 40 | + $limit = $type = $start = $end = $dir = $user = $title = null; |
41 | 41 | extract($this->extractRequestParams()); |
42 | 42 | |
43 | 43 | $db = $this->getDB(); |
44 | 44 | |
45 | 45 | extract($db->tableNames('logging', 'page', 'user'), EXTR_PREFIX_ALL, 'tbl'); |
46 | | - |
47 | | - $tables = "$tbl_logging LEFT OUTER JOIN $tbl_page ON log_namespace=page_namespace AND log_title=page_title " . |
| 46 | + $tables = "$tbl_logging LEFT OUTER JOIN $tbl_page ON " . |
| 47 | + "log_namespace=page_namespace AND log_title=page_title " . |
48 | 48 | "INNER JOIN $tbl_user ON user_id=log_user"; |
49 | 49 | |
50 | 50 | $fields = array ( |
— | — | @@ -80,11 +80,19 @@ |
81 | 81 | $where['log_title'] = $titleObj->getDBkey(); |
82 | 82 | } |
83 | 83 | |
84 | | - // $where[] = "log_timestamp $direction '$safetime'"; |
| 84 | + $dirNewer = ($dir === 'newer'); |
| 85 | + $before = ($dirNewer ? '<=' : '>='); |
| 86 | + $after = ($dirNewer ? '>=' : '<='); |
85 | 87 | |
| 88 | + if (!is_null($start)) |
| 89 | + $where[] = 'log_timestamp' . $after . $db->addQuotes($start); |
| 90 | + if (!is_null($end)) |
| 91 | + $where[] = 'log_timestamp' . $before . $db->addQuotes($end); |
| 92 | + |
86 | 93 | $options = array ( |
87 | | - 'LIMIT' => $limit +1 |
88 | | - ); |
| 94 | + 'LIMIT' => $limit +1, |
| 95 | + 'ORDER BY' => 'log_timestamp' . ($dirNewer ? '' : ' DESC' |
| 96 | + )); |
89 | 97 | |
90 | 98 | $this->profileDBIn(); |
91 | 99 | $res = $db->select($tables, $fields, $where, __METHOD__, $options); |
— | — | @@ -95,27 +103,42 @@ |
96 | 104 | while ($row = $db->fetchObject($res)) { |
97 | 105 | if (++ $count > $limit) { |
98 | 106 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
99 | | - $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title)); |
| 107 | + $this->setContinueEnumParameter('start', ApiQueryBase :: keyToTitle($row->log_timestamp)); |
100 | 108 | break; |
101 | 109 | } |
102 | 110 | |
103 | 111 | $vals = array ( |
104 | | - 'type' => $row->log_type, |
105 | | - 'action' => $row->log_action, |
| 112 | + 'action' => "$row->log_type/$row->log_action", |
106 | 113 | 'timestamp' => $row->log_timestamp, |
107 | 114 | 'comment' => $row->log_comment, |
108 | | - 'params' => $row->log_params, |
109 | | - 'pageid' => intval($row->page_id) |
110 | | - ); |
111 | | - |
| 115 | + 'pageid' => intval($row->page_id |
| 116 | + )); |
| 117 | + |
112 | 118 | $title = Title :: makeTitle($row->log_namespace, $row->log_title); |
113 | 119 | $vals['ns'] = $title->getNamespace(); |
114 | 120 | $vals['title'] = $title->getPrefixedText(); |
115 | 121 | |
| 122 | + if ($row->log_params !== '') { |
| 123 | + $params = explode("\n", $row->log_params); |
| 124 | + if ($row->log_type == 'move' && isset ($params[0])) { |
| 125 | + $destTitle = Title :: newFromText($params[0]); |
| 126 | + if ($destTitle) { |
| 127 | + $vals['tons'] = $destTitle->getNamespace(); |
| 128 | + $vals['totitle'] = $destTitle->getPrefixedText(); |
| 129 | + $params = null; |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + if(!empty($params)) { |
| 134 | + ApiResult :: setIndexedTagName($params, 'param'); |
| 135 | + $vals = array_merge($vals, $params); |
| 136 | + } |
| 137 | + } |
| 138 | + |
116 | 139 | if (!$row->log_user) |
117 | 140 | $vals['anon'] = ''; |
118 | 141 | $vals['user'] = $row->user_name; |
119 | | - |
| 142 | + |
120 | 143 | $data[] = $vals; |
121 | 144 | } |
122 | 145 | $db->freeResult($res); |
— | — | @@ -125,21 +148,56 @@ |
126 | 149 | } |
127 | 150 | |
128 | 151 | protected function getAllowedParams() { |
129 | | - |
130 | 152 | return array ( |
131 | 153 | 'limit' => array ( |
132 | 154 | ApiBase :: PARAM_DFLT => 10, |
133 | 155 | ApiBase :: PARAM_TYPE => 'limit', |
134 | 156 | ApiBase :: PARAM_MIN => 1, |
135 | | - ApiBase :: PARAM_MAX1 => 500, |
136 | | - ApiBase :: PARAM_MAX2 => 5000 |
137 | | - ) |
| 157 | + ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1, |
| 158 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
| 159 | + ), |
| 160 | + 'type' => array ( |
| 161 | + ApiBase :: PARAM_ISMULTI => true, |
| 162 | + ApiBase :: PARAM_TYPE => array ( |
| 163 | + 'block', |
| 164 | + 'protect', |
| 165 | + 'rights', |
| 166 | + 'delete', |
| 167 | + 'upload', |
| 168 | + 'move', |
| 169 | + 'import', |
| 170 | + 'renameuser', |
| 171 | + 'newusers', |
| 172 | + 'makebot' |
| 173 | + ) |
| 174 | + ), |
| 175 | + 'start' => array ( |
| 176 | + ApiBase :: PARAM_TYPE => 'timestamp' |
| 177 | + ), |
| 178 | + 'end' => array ( |
| 179 | + ApiBase :: PARAM_TYPE => 'timestamp' |
| 180 | + ), |
| 181 | + 'dir' => array ( |
| 182 | + ApiBase :: PARAM_DFLT => 'older', |
| 183 | + ApiBase :: PARAM_TYPE => array ( |
| 184 | + 'newer', |
| 185 | + 'older' |
| 186 | + ) |
| 187 | + ), |
| 188 | + 'user' => null, |
| 189 | + 'title' => null |
138 | 190 | ); |
139 | 191 | } |
140 | 192 | |
141 | 193 | protected function getParamDescription() { |
142 | 194 | return array ( |
143 | | - 'limit' => 'How many total items to return.' |
| 195 | + 'limit' => '', |
| 196 | + 'type' => '', |
| 197 | + 'start' => '', |
| 198 | + 'end' => '', |
| 199 | + 'dir' => '', |
| 200 | + 'user' => '', |
| 201 | + 'title' => '' |
144 | 202 | ); |
145 | 203 | } |
146 | 204 | |
— | — | @@ -154,7 +212,7 @@ |
155 | 213 | } |
156 | 214 | |
157 | 215 | public function getVersion() { |
158 | | - return __CLASS__ . ': $Id:$'; |
| 216 | + return __CLASS__ . ': $Id$'; |
159 | 217 | } |
160 | 218 | } |
161 | 219 | ?> |
\ No newline at end of file |