Index: trunk/extensions/Deployment/specials/SpecialExtensions.php |
— | — | @@ -95,7 +95,7 @@ |
96 | 96 | |
97 | 97 | $this->displayBulkActions(); |
98 | 98 | |
99 | | - $wgOut->addWikiText( $this->getExtensionList() ); |
| 99 | + $this->displayExtensionList(); |
100 | 100 | } |
101 | 101 | |
102 | 102 | /** |
— | — | @@ -167,286 +167,168 @@ |
168 | 168 | } |
169 | 169 | |
170 | 170 | /** |
171 | | - * Creates and returns the HTML for the extension list. |
| 171 | + * Displays the installed extensions (of the selected type). |
172 | 172 | * |
173 | 173 | * @since 0.1 |
174 | 174 | * |
175 | 175 | * @return string |
176 | 176 | */ |
177 | | - protected function getExtensionList() { |
178 | | - global $wgExtensionCredits; |
| 177 | + protected function displayExtensionList() { |
| 178 | + global $wgOut, $wgExtensionCredits; |
179 | 179 | |
180 | | - $out = Xml::openElement( 'table', array( 'class' => 'wikitable', 'id' => 'sv-ext' ) ); |
181 | | - |
182 | | - $extensionTypes = SpecialVersion::getExtensionTypes(); |
183 | | - |
184 | | - // Make sure the 'other' type is set to an array. |
185 | | - if ( !array_key_exists( 'other', $wgExtensionCredits ) ) { |
186 | | - $wgExtensionCredits['other'] = array(); |
| 180 | + if ( !array_key_exists( $this->typeFilter, $wgExtensionCredits ) && $this->typeFilter != 'all' ) { |
| 181 | + // TODO |
187 | 182 | } |
188 | | - |
189 | | - // Find all extensions that do not have a valid type and give them the type 'other'. |
190 | | - foreach ( $wgExtensionCredits as $type => $extensions ) { |
191 | | - if ( !array_key_exists( $type, $extensionTypes ) ) { |
192 | | - $wgExtensionCredits['other'] = array_merge( $wgExtensionCredits['other'], $extensions ); |
| 183 | + else { |
| 184 | + $extensions = array(); |
| 185 | + |
| 186 | + if ( $this->typeFilter == 'all' ) { |
| 187 | + foreach ( $wgExtensionCredits as $type => $exts ) { |
| 188 | + $extensions = array_merge( $extensions, $exts ); |
| 189 | + } |
193 | 190 | } |
194 | | - } |
195 | | - |
196 | | - // Loop through the extension categories to display their extensions in the list. |
197 | | - foreach ( $extensionTypes as $type => $message ) { |
198 | | - if ( $type != 'other' ) { |
199 | | - $out .= $this->getExtensionCategory( $type, $message ); |
| 191 | + else { |
| 192 | + $extensions = $wgExtensionCredits[$this->typeFilter]; |
200 | 193 | } |
| 194 | + |
| 195 | + if ( count( $extensions ) == 0 ) { |
| 196 | + // TODO |
| 197 | + } |
| 198 | + else { |
| 199 | + $listHtml = Html::openElement( |
| 200 | + 'table', |
| 201 | + array( 'class' => 'wikitable', 'style' => 'width:100%' ) |
| 202 | + ); |
| 203 | + |
| 204 | + $listHtml .= '<tr>' . |
| 205 | + Html::element( 'th', array(), wfMsg( 'extensionlist-name' ) ) . |
| 206 | + Html::element( 'th', array(), wfMsg( 'extensionlist-description' ) ) |
| 207 | + . '</tr>'; |
| 208 | + |
| 209 | + foreach ( $extensions as $extension ) { |
| 210 | + $listHtml .= $this->getExtensionForList( $extension ); |
| 211 | + } |
| 212 | + |
| 213 | + $listHtml .= Html::closeElement( 'table' ); |
| 214 | + |
| 215 | + $wgOut->addHTML( $listHtml ); |
| 216 | + } |
201 | 217 | } |
202 | | - |
203 | | - // We want the 'other' type to be last in the list. |
204 | | - $out .= $this->getExtensionCategory( 'other', $extensionTypes['other'] ); |
205 | | - |
206 | | - return $out; |
207 | 218 | } |
208 | 219 | |
209 | 220 | /** |
210 | | - * Creates and returns the HTML for a single extension category. |
| 221 | + * Creates and returns the html for a single extension in the list. |
211 | 222 | * |
212 | 223 | * @since 0.1 |
213 | 224 | * |
214 | | - * @param $type String |
215 | | - * @param $message String |
| 225 | + * @param $extensions Array |
216 | 226 | * |
217 | 227 | * @return string |
218 | | - */ |
219 | | - protected function getExtensionCategory( $type, $message ) { |
220 | | - global $wgExtensionCredits; |
| 228 | + */ |
| 229 | + protected function getExtensionForList( array $extension ) { |
| 230 | + $html = '<tr>'; |
221 | 231 | |
222 | | - $out = ''; |
| 232 | + $html .= Html::rawElement( |
| 233 | + 'td', |
| 234 | + array(), |
| 235 | + Html::element( 'b', array(), $extension['name'] ) . |
| 236 | + '<br />' . |
| 237 | + Html::element( |
| 238 | + 'a', |
| 239 | + array( |
| 240 | + 'href' => $extension['url'], |
| 241 | + 'class' => 'external text' |
| 242 | + ), |
| 243 | + wfMsg( 'extensionlist-details' ) |
| 244 | + ) . |
| 245 | + ' | ' . |
| 246 | + Html::element( |
| 247 | + 'a', |
| 248 | + array( |
| 249 | + 'href' => '', |
| 250 | + 'class' => 'external text' |
| 251 | + ), |
| 252 | + wfMsg( 'extensionlist-download' ) |
| 253 | + ) |
| 254 | + ); |
223 | 255 | |
224 | | - if ( array_key_exists( $type, $wgExtensionCredits ) && count( $wgExtensionCredits[$type] ) > 0 ) { |
225 | | - $out .= $this->getExtensionTypeHeader( $message, 'credits-' . $type ); |
226 | | - |
227 | | - usort( $wgExtensionCredits[$type], array( $this, 'compare' ) ); |
228 | | - |
229 | | - foreach ( $wgExtensionCredits[$type] as $extension ) { |
230 | | - $out .= $this->getExtensionForList( $extension ); |
231 | | - } |
232 | | - } |
233 | | - |
234 | | - return $out; |
| 256 | + $description = self::getExtensionDescription( $extension ); |
| 257 | + $authors = self::getExtensionAuthors( $extension ); |
| 258 | + $version = self::getExtensionVersion( $extension ); |
| 259 | + |
| 260 | + $html .= Html::rawElement( |
| 261 | + 'td', |
| 262 | + array(), |
| 263 | + $description . '<br />' . $version . ' | ' . $authors |
| 264 | + ); |
| 265 | + |
| 266 | + return $html . '</tr>'; |
235 | 267 | } |
236 | 268 | |
237 | 269 | /** |
238 | | - * Gets the HTML for an extension type header. |
| 270 | + * Returns the decription for an extension. |
239 | 271 | * |
240 | 272 | * @since 0.1 |
241 | 273 | * |
242 | | - * @param $text String |
243 | | - * @param $name String |
| 274 | + * @param $extension Array |
244 | 275 | * |
245 | 276 | * @return string |
246 | 277 | */ |
247 | | - protected function getExtensionTypeHeader( $text, $name ) { |
248 | | - $opt = array( 'colspan' => 4 ); |
249 | | - $out = ''; |
250 | | - |
251 | | - if( $this->openedFirstExtension ) { |
252 | | - // Insert a spacing line |
253 | | - $out .= '<tr class="sv-space">' . Html::element( 'td', $opt ) . "</tr>\n"; |
| 278 | + public static function getExtensionDescription( array $extension ) { |
| 279 | + $description = array_key_exists( 'description', $extension ) ? $extension['description'] : ''; |
| 280 | + |
| 281 | + if ( array_key_exists( 'descriptionmsg', $extension ) ) { |
| 282 | + if( is_array( $extension['descriptionmsg'] ) ) { |
| 283 | + $descriptionMsgKey = $extension['descriptionmsg'][0]; |
| 284 | + |
| 285 | + array_shift( $extension['descriptionmsg'] ); |
| 286 | + array_map( 'htmlspecialchars', $extension['descriptionmsg'] ); |
| 287 | + |
| 288 | + $msg = wfMsg( $descriptionMsgKey, $extension['descriptionmsg'] ); |
| 289 | + } else { |
| 290 | + $msg = wfMsg( $extension['descriptionmsg'] ); |
| 291 | + } |
| 292 | + |
| 293 | + if ( !wfEmptyMsg( $extension['descriptionmsg'], $msg ) && $msg != '' ) { |
| 294 | + $description = $msg; |
| 295 | + } |
254 | 296 | } |
255 | | - $this->openedFirstExtension = true; |
256 | 297 | |
257 | | - if( $name ) { |
258 | | - $opt['id'] = "sv-$name"; |
259 | | - } |
260 | | - |
261 | | - $out .= "<tr>" . Xml::element( 'th', $opt, $text ) . "</tr>\n"; |
262 | | - |
263 | | - return $out; |
264 | | - } |
| 298 | + return $description; |
| 299 | + } |
265 | 300 | |
266 | 301 | /** |
267 | | - * Gets the HTML for a single extension for the extension list. |
| 302 | + * Returns "created by [authors]" or an empty string when there are none. |
268 | 303 | * |
269 | 304 | * @since 0.1 |
270 | 305 | * |
271 | 306 | * @param $extension Array |
272 | 307 | * |
273 | 308 | * @return string |
274 | | - */ |
275 | | - protected function getExtensionForList( array $extension ) { |
276 | | - global $wgLang; |
| 309 | + */ |
| 310 | + public static function getExtensionAuthors( array $extension ) { |
| 311 | + global $wgLang; |
277 | 312 | |
278 | | - $name = isset( $extension['name'] ) ? $extension['name'] : '[no name]'; |
279 | | - |
280 | | - if ( isset( $extension['path'] ) ) { |
281 | | - $svnInfo = self::getSvnInfo( dirname($extension['path']) ); |
282 | | - $directoryRev = isset( $svnInfo['directory-rev'] ) ? $svnInfo['directory-rev'] : null; |
283 | | - $checkoutRev = isset( $svnInfo['checkout-rev'] ) ? $svnInfo['checkout-rev'] : null; |
284 | | - $viewvcUrl = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : null; |
285 | | - } else { |
286 | | - $directoryRev = null; |
287 | | - $checkoutRev = null; |
288 | | - $viewvcUrl = null; |
| 313 | + if ( !array_key_exists( 'author', $extension ) ) { |
| 314 | + return ''; |
289 | 315 | } |
290 | | - |
291 | | - # Make main link (or just the name if there is no URL). |
292 | | - if ( isset( $extension['url'] ) ) { |
293 | | - $mainLink = "[{$extension['url']} $name]"; |
294 | | - } else { |
295 | | - $mainLink = $name; |
296 | | - } |
297 | 316 | |
298 | | - if ( isset( $extension['version'] ) ) { |
299 | | - $versionText = '<span class="mw-version-ext-version">' . |
300 | | - wfMsg( 'version-version', $extension['version'] ) . |
301 | | - '</span>'; |
302 | | - } else { |
303 | | - $versionText = ''; |
304 | | - } |
305 | | - |
306 | | - # Make subversion text/link. |
307 | | - if ( $checkoutRev ) { |
308 | | - $svnText = wfMsg( 'version-svn-revision', $directoryRev, $checkoutRev ); |
309 | | - $svnText = isset( $viewvcUrl ) ? "[$viewvcUrl $svnText]" : $svnText; |
310 | | - } else { |
311 | | - $svnText = false; |
312 | | - } |
313 | | - |
314 | | - # Make description text. |
315 | | - $description = isset ( $extension['description'] ) ? $extension['description'] : ''; |
316 | | - |
317 | | - if( isset ( $extension['descriptionmsg'] ) ) { |
318 | | - # Look for a localized description. |
319 | | - $descriptionMsg = $extension['descriptionmsg']; |
320 | | - |
321 | | - if( is_array( $descriptionMsg ) ) { |
322 | | - $descriptionMsgKey = $descriptionMsg[0]; // Get the message key |
323 | | - array_shift( $descriptionMsg ); // Shift out the message key to get the parameters only |
324 | | - array_map( "htmlspecialchars", $descriptionMsg ); // For sanity |
325 | | - $msg = wfMsg( $descriptionMsgKey, $descriptionMsg ); |
326 | | - } else { |
327 | | - $msg = wfMsg( $descriptionMsg ); |
328 | | - } |
329 | | - if ( !wfEmptyMsg( $descriptionMsg, $msg ) && $msg != '' ) { |
330 | | - $description = $msg; |
331 | | - } |
332 | | - } |
333 | | - |
334 | | - if ( $svnText !== false ) { |
335 | | - $extNameVer = "<tr> |
336 | | - <td><em>$mainLink $versionText</em></td> |
337 | | - <td><em>$svnText</em></td>"; |
338 | | - } else { |
339 | | - $extNameVer = "<tr> |
340 | | - <td colspan=\"2\"><em>$mainLink $versionText</em></td>"; |
341 | | - } |
342 | | - |
343 | | - $author = isset ( $extension['author'] ) ? $extension['author'] : array(); |
344 | | - $extDescAuthor = "<td>$description</td> |
345 | | - <td>" . $wgLang->listToText( (array)$author ) . "</td> |
346 | | - </tr>\n"; |
347 | | - |
348 | | - return $extNameVer . $extDescAuthor; |
| 317 | + // TODO: resolve wikitext |
| 318 | + return wfMsgExt( 'extensionlist-createdby', 'parsemag', $wgLang->listToText( (array)$extension['author'] ) ); |
349 | 319 | } |
350 | 320 | |
351 | 321 | /** |
352 | | - * Callback to sort extensions by type. |
| 322 | + * Returns version of an extension or an empty string when not available. |
353 | 323 | * |
354 | 324 | * @since 0.1 |
355 | | - */ |
356 | | - public function compare( $a, $b ) { |
357 | | - global $wgLang; |
358 | | - if( $a['name'] === $b['name'] ) { |
359 | | - return 0; |
360 | | - } else { |
361 | | - return $wgLang->lc( $a['name'] ) > $wgLang->lc( $b['name'] ) |
362 | | - ? 1 |
363 | | - : -1; |
364 | | - } |
| 325 | + * |
| 326 | + * @param $extension Array |
| 327 | + * |
| 328 | + * @return string |
| 329 | + */ |
| 330 | + public static function getExtensionVersion( array $extension ) { |
| 331 | + // TODO: add "version " i18n stuff and escape |
| 332 | + return array_key_exists( 'version', $extension ) ? $extension['version'] : ''; |
365 | 333 | } |
366 | 334 | |
367 | | - /** |
368 | | - * Get an associative array of information about a given path, from its .svn |
369 | | - * subdirectory. Returns false on error, such as if the directory was not |
370 | | - * checked out with subversion. |
371 | | - * |
372 | | - * Returned keys are: |
373 | | - * Required: |
374 | | - * checkout-rev The revision which was checked out |
375 | | - * Optional: |
376 | | - * directory-rev The revision when the directory was last modified |
377 | | - * url The subversion URL of the directory |
378 | | - * repo-url The base URL of the repository |
379 | | - * viewvc-url A ViewVC URL pointing to the checked-out revision |
380 | | - * |
381 | | - * @since 0.1 |
382 | | - * |
383 | | - * @return array |
384 | | - */ |
385 | | - public static function getSvnInfo( $dir ) { |
386 | | - // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html |
387 | | - $entries = $dir . '/.svn/entries'; |
388 | | - |
389 | | - if( !file_exists( $entries ) ) { |
390 | | - return false; |
391 | | - } |
392 | | - |
393 | | - $lines = file( $entries ); |
394 | | - if ( !count( $lines ) ) { |
395 | | - return false; |
396 | | - } |
397 | | - |
398 | | - // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4) |
399 | | - if( preg_match( '/^<\?xml/', $lines[0] ) ) { |
400 | | - // subversion is release <= 1.3 |
401 | | - if( !function_exists( 'simplexml_load_file' ) ) { |
402 | | - // We could fall back to expat... YUCK |
403 | | - return false; |
404 | | - } |
405 | | - |
406 | | - // SimpleXml whines about the xmlns... |
407 | | - wfSuppressWarnings(); |
408 | | - $xml = simplexml_load_file( $entries ); |
409 | | - wfRestoreWarnings(); |
410 | | - |
411 | | - if( $xml ) { |
412 | | - foreach( $xml->entry as $entry ) { |
413 | | - if( $xml->entry[0]['name'] == '' ) { |
414 | | - // The directory entry should always have a revision marker. |
415 | | - if( $entry['revision'] ) { |
416 | | - return array( 'checkout-rev' => intval( $entry['revision'] ) ); |
417 | | - } |
418 | | - } |
419 | | - } |
420 | | - } |
421 | | - |
422 | | - return false; |
423 | | - } |
424 | | - |
425 | | - // Subversion is release 1.4 or above. |
426 | | - if ( count( $lines ) < 11 ) { |
427 | | - return false; |
428 | | - } |
429 | | - |
430 | | - $info = array( |
431 | | - 'checkout-rev' => intval( trim( $lines[3] ) ), |
432 | | - 'url' => trim( $lines[4] ), |
433 | | - 'repo-url' => trim( $lines[5] ), |
434 | | - 'directory-rev' => intval( trim( $lines[10] ) ) |
435 | | - ); |
436 | | - |
437 | | - if ( isset( self::$viewvcUrls[$info['repo-url']] ) ) { |
438 | | - $viewvc = str_replace( |
439 | | - $info['repo-url'], |
440 | | - self::$viewvcUrls[$info['repo-url']], |
441 | | - $info['url'] |
442 | | - ); |
443 | | - |
444 | | - $pathRelativeToRepo = substr( $info['url'], strlen( $info['repo-url'] ) ); |
445 | | - $viewvc .= '/?pathrev='; |
446 | | - $viewvc .= urlencode( $info['checkout-rev'] ); |
447 | | - $info['viewvc-url'] = $viewvc; |
448 | | - } |
449 | | - |
450 | | - return $info; |
451 | | - } |
452 | | - |
453 | 335 | } |
\ No newline at end of file |