00001 <?php
00002
00012 class SpecialVersion extends SpecialPage {
00013 private $firstExtOpened = true;
00014
00015 function __construct(){
00016 parent::__construct( 'Version' );
00017 }
00018
00022 function execute( $par ) {
00023 global $wgOut, $wgMessageCache, $wgSpecialVersionShowHooks;
00024 $wgMessageCache->loadAllMessages();
00025
00026 $this->setHeaders();
00027 $this->outputHeader();
00028
00029 $wgOut->addHTML( '<div dir="ltr">' );
00030 $text =
00031 $this->MediaWikiCredits() .
00032 $this->softwareInformation() .
00033 $this->extensionCredits();
00034 if ( $wgSpecialVersionShowHooks ) {
00035 $text .= $this->wgHooks();
00036 }
00037 $wgOut->addWikiText( $text );
00038 $wgOut->addHTML( $this->IPInfo() );
00039 $wgOut->addHTML( '</div>' );
00040 }
00041
00049 static function MediaWikiCredits() {
00050 $ret = Xml::element( 'h2', array( 'id' => 'mw-version-license' ), wfMsg( 'version-license' ) ) .
00051 "__NOTOC__
00052 This wiki is powered by '''[http://www.mediawiki.org/ MediaWiki]''',
00053 copyright (C) 2001-2009 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
00054 Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason,
00055 Niklas Laxström, Domas Mituzas, Rob Church, Yuri Astrakhan, Aryeh Gregor,
00056 Aaron Schulz and others.
00057
00058 MediaWiki is free software; you can redistribute it and/or modify
00059 it under the terms of the GNU General Public License as published by
00060 the Free Software Foundation; either version 2 of the License, or
00061 (at your option) any later version.
00062
00063 MediaWiki is distributed in the hope that it will be useful,
00064 but WITHOUT ANY WARRANTY; without even the implied warranty of
00065 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00066 GNU General Public License for more details.
00067
00068 You should have received [{{SERVER}}{{SCRIPTPATH}}/COPYING a copy of the GNU General Public License]
00069 along with this program; if not, write to the Free Software
00070 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00071 or [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html read it online].
00072 ";
00073
00074 return str_replace( "\t\t", '', $ret ) . "\n";
00075 }
00076
00080 static function softwareInformation() {
00081 $dbr = wfGetDB( DB_SLAVE );
00082
00083 return Xml::element( 'h2', array( 'id' => 'mw-version-software' ), wfMsg( 'version-software' ) ) .
00084 Xml::openElement( 'table', array( 'id' => 'sv-software' ) ) .
00085 "<tr>
00086 <th>" . wfMsg( 'version-software-product' ) . "</th>
00087 <th>" . wfMsg( 'version-software-version' ) . "</th>
00088 </tr>\n
00089 <tr>
00090 <td>[http://www.mediawiki.org/ MediaWiki]</td>
00091 <td>" . self::getVersionLinked() . "</td>
00092 </tr>\n
00093 <tr>
00094 <td>[http://www.php.net/ PHP]</td>
00095 <td>" . phpversion() . " (" . php_sapi_name() . ")</td>
00096 </tr>\n
00097 <tr>
00098 <td>" . $dbr->getSoftwareLink() . "</td>
00099 <td>" . $dbr->getServerVersion() . "</td>
00100 </tr>\n" .
00101 Xml::closeElement( 'table' );
00102 }
00103
00109 public static function getVersion() {
00110 global $wgVersion, $IP;
00111 wfProfileIn( __METHOD__ );
00112 $svn = self::getSvnRevision( $IP );
00113 $version = $svn ? "$wgVersion (r$svn)" : $wgVersion;
00114 wfProfileOut( __METHOD__ );
00115 return $version;
00116 }
00117
00124 public static function getVersionLinked() {
00125 global $wgVersion, $IP;
00126 wfProfileIn( __METHOD__ );
00127 $svn = self::getSvnRevision( $IP );
00128 $viewvc = 'http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/?pathrev=';
00129 $version = $svn ? "$wgVersion ([{$viewvc}{$svn} r$svn])" : $wgVersion;
00130 wfProfileOut( __METHOD__ );
00131 return $version;
00132 }
00133
00135 function extensionCredits() {
00136 global $wgExtensionCredits, $wgExtensionFunctions, $wgParser, $wgSkinExtensionFunctions;
00137
00138 if ( ! count( $wgExtensionCredits ) && ! count( $wgExtensionFunctions ) && ! count( $wgSkinExtensionFunctions ) )
00139 return '';
00140
00141 $extensionTypes = array(
00142 'specialpage' => wfMsg( 'version-specialpages' ),
00143 'parserhook' => wfMsg( 'version-parserhooks' ),
00144 'variable' => wfMsg( 'version-variables' ),
00145 'media' => wfMsg( 'version-mediahandlers' ),
00146 'other' => wfMsg( 'version-other' ),
00147 );
00148 wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );
00149
00150 $out = Xml::element( 'h2', array( 'id' => 'mw-version-ext' ), wfMsg( 'version-extensions' ) ) .
00151 Xml::openElement( 'table', array( 'id' => 'sv-ext' ) );
00152
00153 foreach ( $extensionTypes as $type => $text ) {
00154 if ( isset ( $wgExtensionCredits[$type] ) && count ( $wgExtensionCredits[$type] ) ) {
00155 $out .= $this->openExtType( $text );
00156
00157 usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
00158
00159 foreach ( $wgExtensionCredits[$type] as $extension ) {
00160 $version = null;
00161 $subVersion = '';
00162 if ( isset( $extension['version'] ) ) {
00163 $version = $extension['version'];
00164 }
00165 if ( isset( $extension['svn-revision'] ) &&
00166 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
00167 $extension['svn-revision'], $m ) ) {
00168 $subVersion = 'r' . $m[1];
00169 }
00170
00171 if( $version && $subVersion ) {
00172 $version = $version . ' [' . $subVersion . ']';
00173 } elseif ( !$version && $subVersion ) {
00174 $version = $subVersion;
00175 }
00176
00177 $out .= $this->formatCredits(
00178 isset ( $extension['name'] ) ? $extension['name'] : '',
00179 $version,
00180 isset ( $extension['author'] ) ? $extension['author'] : '',
00181 isset ( $extension['url'] ) ? $extension['url'] : null,
00182 isset ( $extension['description'] ) ? $extension['description'] : '',
00183 isset ( $extension['descriptionmsg'] ) ? $extension['descriptionmsg'] : ''
00184 );
00185 }
00186 }
00187 }
00188
00189 if ( count( $wgExtensionFunctions ) ) {
00190 $out .= $this->openExtType( wfMsg( 'version-extension-functions' ) );
00191 $out .= '<tr><td colspan="3">' . $this->listToText( $wgExtensionFunctions ) . "</td></tr>\n";
00192 }
00193
00194 if ( $cnt = count( $tags = $wgParser->getTags() ) ) {
00195 for ( $i = 0; $i < $cnt; ++$i )
00196 $tags[$i] = "<{$tags[$i]}>";
00197 $out .= $this->openExtType( wfMsg( 'version-parser-extensiontags' ) );
00198 $out .= '<tr><td colspan="3">' . $this->listToText( $tags ). "</td></tr>\n";
00199 }
00200
00201 if( $cnt = count( $fhooks = $wgParser->getFunctionHooks() ) ) {
00202 $out .= $this->openExtType( wfMsg( 'version-parser-function-hooks' ) );
00203 $out .= '<tr><td colspan="3">' . $this->listToText( $fhooks ) . "</td></tr>\n";
00204 }
00205
00206 if ( count( $wgSkinExtensionFunctions ) ) {
00207 $out .= $this->openExtType( wfMsg( 'version-skin-extension-functions' ) );
00208 $out .= '<tr><td colspan="3">' . $this->listToText( $wgSkinExtensionFunctions ) . "</td></tr>\n";
00209 }
00210 $out .= Xml::closeElement( 'table' );
00211 return $out;
00212 }
00213
00215 function compare( $a, $b ) {
00216 global $wgLang;
00217 if( $a['name'] === $b['name'] ) {
00218 return 0;
00219 } else {
00220 return $wgLang->lc( $a['name'] ) > $wgLang->lc( $b['name'] )
00221 ? 1
00222 : -1;
00223 }
00224 }
00225
00226 function formatCredits( $name, $version = null, $author = null, $url = null, $description = null, $descriptionMsg = null ) {
00227 $extension = isset( $url ) ? "[$url $name]" : $name;
00228 $version = isset( $version ) ? "(" . wfMsg( 'version-version' ) . " $version)" : '';
00229
00230 # Look for a localized description
00231 if( isset( $descriptionMsg ) ) {
00232 $msg = wfMsg( $descriptionMsg );
00233 if ( !wfEmptyMsg( $descriptionMsg, $msg ) && $msg != '' ) {
00234 $description = $msg;
00235 }
00236 }
00237
00238 return "<tr>
00239 <td><em>$extension $version</em></td>
00240 <td>$description</td>
00241 <td>" . $this->listToText( (array)$author ) . "</td>
00242 </tr>\n";
00243 }
00244
00248 function wgHooks() {
00249 global $wgHooks;
00250
00251 if ( count( $wgHooks ) ) {
00252 $myWgHooks = $wgHooks;
00253 ksort( $myWgHooks );
00254
00255 $ret = Xml::element( 'h2', array( 'id' => 'mw-version-hooks' ), wfMsg( 'version-hooks' ) ) .
00256 Xml::openElement( 'table', array( 'id' => 'sv-hooks' ) ) .
00257 "<tr>
00258 <th>" . wfMsg( 'version-hook-name' ) . "</th>
00259 <th>" . wfMsg( 'version-hook-subscribedby' ) . "</th>
00260 </tr>\n";
00261
00262 foreach ( $myWgHooks as $hook => $hooks )
00263 $ret .= "<tr>
00264 <td>$hook</td>
00265 <td>" . $this->listToText( $hooks ) . "</td>
00266 </tr>\n";
00267
00268 $ret .= Xml::closeElement( 'table' );
00269 return $ret;
00270 } else
00271 return '';
00272 }
00273
00274 private function openExtType($text, $name = null) {
00275 $opt = array( 'colspan' => 3 );
00276 $out = '';
00277
00278 if(!$this->firstExtOpened) {
00279
00280 $out .= '<tr class="sv-space">' . Xml::element( 'td', $opt ) . "</tr>\n";
00281 }
00282 $this->firstExtOpened = false;
00283
00284 if($name) { $opt['id'] = "sv-$name"; }
00285
00286 $out .= "<tr>" . Xml::element( 'th', $opt, $text) . "</tr>\n";
00287 return $out;
00288 }
00289
00293 function IPInfo() {
00294 $ip = str_replace( '--', ' - ', htmlspecialchars( wfGetIP() ) );
00295 return "<!-- visited from $ip -->\n" .
00296 "<span style='display:none'>visited from $ip</span>";
00297 }
00298
00303 function listToText( $list ) {
00304 $cnt = count( $list );
00305
00306 if ( $cnt == 1 ) {
00307
00308 return (string)self::arrayToString( $list[0] );
00309 } elseif ( $cnt == 0 ) {
00310 return '';
00311 } else {
00312 global $wgLang;
00313 sort( $list );
00314 return $wgLang->listToText( array_map( array( __CLASS__, 'arrayToString' ), $list ) );
00315 }
00316 }
00317
00323 static function arrayToString( $list ) {
00324 if( is_array( $list ) && count( $list ) == 1 )
00325 $list = $list[0];
00326 if( is_object( $list ) ) {
00327 $class = get_class( $list );
00328 return "($class)";
00329 } elseif ( !is_array( $list ) ) {
00330 return $list;
00331 } else {
00332 if( is_object( $list[0] ) )
00333 $class = get_class( $list[0] );
00334 else
00335 $class = $list[0];
00336 return "($class, {$list[1]})";
00337 }
00338 }
00339
00346 public static function getSvnRevision( $dir ) {
00347
00348 $entries = $dir . '/.svn/entries';
00349
00350 if( !file_exists( $entries ) ) {
00351 return false;
00352 }
00353
00354 $content = file( $entries );
00355
00356
00357 if( preg_match( '/^<\?xml/', $content[0] ) ) {
00358
00359 if( !function_exists( 'simplexml_load_file' ) ) {
00360
00361 return false;
00362 }
00363
00364
00365 wfSuppressWarnings();
00366 $xml = simplexml_load_file( $entries );
00367 wfRestoreWarnings();
00368
00369 if( $xml ) {
00370 foreach( $xml->entry as $entry ) {
00371 if( $xml->entry[0]['name'] == '' ) {
00372
00373 if( $entry['revision'] ) {
00374 return intval( $entry['revision'] );
00375 }
00376 }
00377 }
00378 }
00379 return false;
00380 } else {
00381
00382 return intval( $content[3] );
00383 }
00384 }
00385
00387 }