/**#@+
* Give information about the version of MediaWiki, PHP, the DB and extensions
*
- * @package MediaWiki
- * @subpackage SpecialPage
- *
- * @bug 2019, 4531
+ * @addtogroup SpecialPage
*
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
}
class SpecialVersion {
+ private $firstExtOpened = true;
+
/**
* main()
*/
*/
/**
+ * Return wiki text showing the licence information and third party
+ * software versions (apache, php, mysql).
* @static
*/
function MediaWikiCredits() {
- $version = $this->getVersion();
- $dbr =& wfGetDB( DB_SLAVE );
+ $version = self::getVersion();
+ $dbr = wfGetDB( DB_SLAVE );
$ret =
"__NOTOC__
This wiki is powered by '''[http://www.mediawiki.org/ MediaWiki]''',
- copyright (C) 2001-2006 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
+ copyright (C) 2001-2007 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason,
Niklas Laxström, Domas Mituzas, Rob Church and others.
* [http://www.php.net/ PHP]: " . phpversion() . " (" . php_sapi_name() . ")
* " . $dbr->getSoftwareLink() . ": " . $dbr->getServerVersion();
- return str_replace( "\t\t", '', $ret );
+ return str_replace( "\t\t", '', $ret ) . "\n";
}
-
- function getVersion() {
+
+ /** Return a string of the MediaWiki version with SVN revision if available */
+ public static function getVersion() {
global $wgVersion, $IP;
- $svn = $this->getSvnRevision( $IP );
+ $svn = self::getSvnRevision( $IP );
return $svn ? "$wgVersion (r$svn)" : $wgVersion;
}
+ /** Generate wikitext showing extensions name, URL, author and description */
function extensionCredits() {
global $wgExtensionCredits, $wgExtensionFunctions, $wgParser, $wgSkinExtensionFunction;
);
wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );
- $out = "\n* Extensions:\n";
+ $out = "<h2>Extensions</h2>\n";
+ $out .= wfOpenElement('table', array('id' => 'sv-ext') );
+
foreach ( $extensionTypes as $type => $text ) {
- if ( count( @$wgExtensionCredits[$type] ) ) {
- $out .= "** $text:\n";
+ if ( isset ( $wgExtensionCredits[$type] ) && count ( $wgExtensionCredits[$type] ) ) {
+ $out .= $this->openExtType( $text );
usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
foreach ( $wgExtensionCredits[$type] as $extension ) {
- wfSuppressWarnings();
$out .= $this->formatCredits(
- $extension['name'],
- $extension['version'],
- $extension['author'],
- $extension['url'],
- $extension['description']
+ isset ( $extension['name'] ) ? $extension['name'] : '',
+ isset ( $extension['version'] ) ? $extension['version'] : null,
+ isset ( $extension['author'] ) ? $extension['author'] : '',
+ isset ( $extension['url'] ) ? $extension['url'] : null,
+ isset ( $extension['description'] ) ? $extension['description'] : ''
);
- wfRestoreWarnings();
}
}
}
if ( count( $wgExtensionFunctions ) ) {
- $out .= "** Extension functions:\n";
- $out .= '***' . $this->listToText( $wgExtensionFunctions ) . "\n";
+ $out .= $this->openExtType('Extension functions');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $wgExtensionFunctions ) . "</td></tr>\n";
}
if ( $cnt = count( $tags = $wgParser->getTags() ) ) {
for ( $i = 0; $i < $cnt; ++$i )
$tags[$i] = "<{$tags[$i]}>";
- $out .= "** Parser extension tags:\n";
- $out .= '***' . $this->listToText( $tags ). "\n";
+ $out .= $this->openExtType('Parser extension tags');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $tags ). "</td></tr>\n";
}
-
+
if( $cnt = count( $fhooks = $wgParser->getFunctionHooks() ) ) {
- $out .= "** Parser function hooks:\n";
- $out .= '***' . $this->listToText( $fhooks ) . "\n";
+ $out .= $this->openExtType('Parser function hooks');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $fhooks ) . "</td></tr>\n";
}
if ( count( $wgSkinExtensionFunction ) ) {
- $out .= "** Skin extension functions:\n";
- $out .= '***' . $this->listToText( $wgSkinExtensionFunction ) . "\n";
+ $out .= $this->openExtType('Skin extension functions');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $wgSkinExtensionFunction ) . "</td></tr>\n";
}
-
+ $out .= wfCloseElement( 'table' );
return $out;
}
+ /** Callback to sort extensions by type */
function compare( $a, $b ) {
if ( $a['name'] === $b['name'] )
return 0;
}
function formatCredits( $name, $version = null, $author = null, $url = null, $description = null) {
- $ret = '*** ';
+ $ret = '<tr><td>';
if ( isset( $url ) )
$ret .= "[$url ";
$ret .= "''$name";
$ret .= "''";
if ( isset( $url ) )
$ret .= ']';
- if ( isset( $description ) )
- $ret .= ', ' . $description;
- if ( isset( $description ) && isset( $author ) )
- $ret .= ', ';
- if ( isset( $author ) )
- $ret .= ' by ' . $this->listToText( (array)$author );
-
+ $ret .= '</td>';
+ $ret .= "<td>$description</td>";
+ $ret .= "<td>" . $this->listToText( (array)$author ) . "</td>";
+ $ret .= '</tr>';
return "$ret\n";
}
if ( count( $wgHooks ) ) {
$myWgHooks = $wgHooks;
ksort( $myWgHooks );
-
- $ret = "* Hooks:\n";
+
+ $ret = "<h2>Hooks</h2>\n"
+ . wfOpenElement('table', array('id' => 'sv-hooks') )
+ . "<tr><th>Hook name</th><th>Subscribed by</th></tr>\n";
+
foreach ($myWgHooks as $hook => $hooks)
- $ret .= "** $hook: " . $this->listToText( $hooks ) . "\n";
-
+ $ret .= "<tr><td>$hook</td><td>" . $this->listToText( $hooks ) . "</td></tr>\n";
+
+ $ret .= '</table>';
return $ret;
} else
return '';
}
+ private function openExtType($text, $name = null) {
+ $opt = array( 'colspan' => 3 );
+ $out = '';
+
+ if(!$this->firstExtOpened) {
+ // Insert a spacing line
+ $out .= '<tr class="sv-space">' . wfElement( 'td', $opt ) . "</tr>\n";
+ }
+ $this->firstExtOpened = false;
+
+ if($name) { $opt['id'] = "sv-$name"; }
+
+ $out .= "<tr>" . wfElement( 'th', $opt, $text) . "</tr>\n";
+ return $out;
+ }
+
/**
* @static
*
function listToText( $list ) {
$cnt = count( $list );
- if ( $cnt == 1 )
+ if ( $cnt == 1 ) {
// Enforce always returning a string
return (string)$this->arrayToString( $list[0] );
- else {
+ } elseif ( $cnt == 0 ) {
+ return '';
+ } else {
$t = array_slice( $list, 0, $cnt - 1 );
$one = array_map( array( &$this, 'arrayToString' ), $t );
$two = $this->arrayToString( $list[$cnt - 1] );
-
+
return implode( ', ', $one ) . " and $two";
}
}
* @return mixed
*/
function arrayToString( $list ) {
- if ( ! is_array( $list ) )
+ if( is_object( $list ) ) {
+ $class = get_class( $list );
+ return "($class)";
+ } elseif ( ! is_array( $list ) ) {
return $list;
- else {
+ } else {
$class = get_class( $list[0] );
return "($class, {$list[1]})";
}
* @param string $dir
* @return mixed revision number as int, or false if not a SVN checkout
*/
- function getSvnRevision( $dir ) {
- if( !function_exists( 'simplexml_load_file' ) ) {
- // We could fall back to expat... YUCK
- return false;
- }
-
+ public static function getSvnRevision( $dir ) {
// http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
$entries = $dir . '/.svn/entries';
-
- // SimpleXml whines about the xmlns...
- wfSuppressWarnings();
- $xml = simplexml_load_file( $entries );
- wfRestoreWarnings();
-
- if( $xml ) {
- foreach( $xml->entry as $entry ) {
- if( $xml->entry[0]['name'] == '' ) {
- // The directory entry should always have a revision marker.
- if( $entry['revision'] ) {
- return intval( $entry['revision'] );
+
+ if( !file_exists( $entries ) ) {
+ return false;
+ }
+
+ $content = file( $entries );
+
+ // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
+ if( preg_match( '/^<\?xml/', $content[0] ) ) {
+ // subversion is release <= 1.3
+ if( !function_exists( 'simplexml_load_file' ) ) {
+ // We could fall back to expat... YUCK
+ return false;
+ }
+
+ // SimpleXml whines about the xmlns...
+ wfSuppressWarnings();
+ $xml = simplexml_load_file( $entries );
+ wfRestoreWarnings();
+
+ if( $xml ) {
+ foreach( $xml->entry as $entry ) {
+ if( $xml->entry[0]['name'] == '' ) {
+ // The directory entry should always have a revision marker.
+ if( $entry['revision'] ) {
+ return intval( $entry['revision'] );
+ }
}
}
}
+ return false;
+ } else {
+ // subversion is release 1.4
+ return intval( $content[3] );
}
- return false;
}
/**#@-*/