MediaWiki  REL1_22
SpecialVersion.php
Go to the documentation of this file.
00001 <?php
00031 class SpecialVersion extends SpecialPage {
00032 
00033     protected $firstExtOpened = false;
00034 
00035     protected static $extensionTypes = false;
00036 
00037     protected static $viewvcUrls = array(
00038         'svn+ssh://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
00039         'http://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
00040         'https://svn.wikimedia.org/svnroot/mediawiki' => 'https://svn.wikimedia.org/viewvc/mediawiki',
00041     );
00042 
00043     public function __construct() {
00044         parent::__construct( 'Version' );
00045     }
00046 
00050     public function execute( $par ) {
00051         global $wgSpecialVersionShowHooks, $IP;
00052 
00053         $this->setHeaders();
00054         $this->outputHeader();
00055         $out = $this->getOutput();
00056         $out->allowClickjacking();
00057 
00058         if ( $par !== 'Credits' ) {
00059             $text =
00060                 $this->getMediaWikiCredits() .
00061                 $this->softwareInformation() .
00062                 $this->getEntryPointInfo() .
00063                 $this->getExtensionCredits();
00064             if ( $wgSpecialVersionShowHooks ) {
00065                 $text .= $this->getWgHooks();
00066             }
00067 
00068             $out->addWikiText( $text );
00069             $out->addHTML( $this->IPInfo() );
00070 
00071             if ( $this->getRequest()->getVal( 'easteregg' ) ) {
00072                 // TODO: put something interesting here
00073             }
00074         } else {
00075             // Credits sub page
00076 
00077             // Header
00078             $out->addHTML( wfMessage( 'version-credits-summary' )->parseAsBlock() );
00079 
00080             $wikiText = file_get_contents( $IP . '/CREDITS' );
00081 
00082             // Take everything from the first section onwards, to remove the (not localized) header
00083             $wikiText = substr( $wikiText, strpos( $wikiText, '==' ) );
00084 
00085             $out->addWikiText( $wikiText );
00086         }
00087     }
00088 
00094     private static function getMediaWikiCredits() {
00095         $ret = Xml::element( 'h2', array( 'id' => 'mw-version-license' ), wfMessage( 'version-license' )->text() );
00096 
00097         // This text is always left-to-right.
00098         $ret .= '<div class="plainlinks">';
00099         $ret .= "__NOTOC__
00100         " . self::getCopyrightAndAuthorList() . "\n
00101         " . wfMessage( 'version-license-info' )->text();
00102         $ret .= '</div>';
00103 
00104         return str_replace( "\t\t", '', $ret ) . "\n";
00105     }
00106 
00112     public static function getCopyrightAndAuthorList() {
00113         global $wgLang;
00114 
00115         if ( defined( 'MEDIAWIKI_INSTALL' ) ) {
00116             $othersLink = '[//www.mediawiki.org/wiki/Special:Version/Credits ' . wfMessage( 'version-poweredby-others' )->text() . ']';
00117         } else {
00118             $othersLink = '[[Special:Version/Credits|' . wfMessage( 'version-poweredby-others' )->text() . ']]';
00119         }
00120 
00121         $translatorsLink = '[//translatewiki.net/wiki/Translating:MediaWiki/Credits ' . wfMessage( 'version-poweredby-translators' )->text() . ']';
00122 
00123         $authorList = array(
00124             'Magnus Manske', 'Brion Vibber', 'Lee Daniel Crocker',
00125             'Tim Starling', 'Erik Möller', 'Gabriel Wicke', 'Ævar Arnfjörð Bjarmason',
00126             'Niklas Laxström', 'Domas Mituzas', 'Rob Church', 'Yuri Astrakhan',
00127             'Aryeh Gregor', 'Aaron Schulz', 'Andrew Garrett', 'Raimond Spekking',
00128             'Alexandre Emsenhuber', 'Siebrand Mazeland', 'Chad Horohoe',
00129             'Roan Kattouw', 'Trevor Parscal', 'Bryan Tong Minh', 'Sam Reed',
00130             'Victor Vasiliev', 'Rotem Liss', 'Platonides', 'Antoine Musso',
00131             'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw', $othersLink,
00132             $translatorsLink
00133         );
00134 
00135         return wfMessage( 'version-poweredby-credits', MWTimestamp::getLocalInstance()->format( 'Y' ),
00136             $wgLang->listToText( $authorList ) )->text();
00137     }
00138 
00144     static function softwareInformation() {
00145         $dbr = wfGetDB( DB_SLAVE );
00146 
00147         // Put the software in an array of form 'name' => 'version'. All messages should
00148         // be loaded here, so feel free to use wfMessage in the 'name'. Raw HTML or
00149         // wikimarkup can be used.
00150         $software = array();
00151         $software['[https://www.mediawiki.org/ MediaWiki]'] = self::getVersionLinked();
00152         $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . PHP_SAPI . ")";
00153         $software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
00154 
00155         // Allow a hook to add/remove items.
00156         wfRunHooks( 'SoftwareInfo', array( &$software ) );
00157 
00158         $out = Xml::element( 'h2', array( 'id' => 'mw-version-software' ), wfMessage( 'version-software' )->text() ) .
00159                 Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-software' ) ) .
00160                 "<tr>
00161                     <th>" . wfMessage( 'version-software-product' )->text() . "</th>
00162                     <th>" . wfMessage( 'version-software-version' )->text() . "</th>
00163                 </tr>\n";
00164 
00165         foreach ( $software as $name => $version ) {
00166             $out .= "<tr>
00167                     <td>" . $name . "</td>
00168                     <td dir=\"ltr\">" . $version . "</td>
00169                 </tr>\n";
00170         }
00171 
00172         return $out . Xml::closeElement( 'table' );
00173     }
00174 
00181     public static function getVersion( $flags = '' ) {
00182         global $wgVersion, $IP;
00183         wfProfileIn( __METHOD__ );
00184 
00185         $gitInfo = self::getGitHeadSha1( $IP );
00186         $svnInfo = self::getSvnInfo( $IP );
00187         if ( !$svnInfo && !$gitInfo ) {
00188             $version = $wgVersion;
00189         } elseif ( $gitInfo && $flags === 'nodb' ) {
00190             $shortSha1 = substr( $gitInfo, 0, 7 );
00191             $version = "$wgVersion ($shortSha1)";
00192         } elseif ( $gitInfo ) {
00193             $shortSha1 = substr( $gitInfo, 0, 7 );
00194             $shortSha1 = wfMessage( 'parentheses' )->params( $shortSha1 )->escaped();
00195             $version = "$wgVersion $shortSha1";
00196         } elseif ( $flags === 'nodb' ) {
00197             $version = "$wgVersion (r{$svnInfo['checkout-rev']})";
00198         } else {
00199             $version = $wgVersion . ' ' .
00200                 wfMessage(
00201                     'version-svn-revision',
00202                     isset( $info['directory-rev'] ) ? $info['directory-rev'] : '',
00203                     $info['checkout-rev']
00204                 )->text();
00205         }
00206 
00207         wfProfileOut( __METHOD__ );
00208         return $version;
00209     }
00210 
00219     public static function getVersionLinked() {
00220         global $wgVersion;
00221         wfProfileIn( __METHOD__ );
00222 
00223         $gitVersion = self::getVersionLinkedGit();
00224         if ( $gitVersion ) {
00225             $v = $gitVersion;
00226         } else {
00227             $svnVersion = self::getVersionLinkedSvn();
00228             if ( $svnVersion ) {
00229                 $v = $svnVersion;
00230             } else {
00231                 $v = $wgVersion; // fallback
00232             }
00233         }
00234 
00235         wfProfileOut( __METHOD__ );
00236         return $v;
00237     }
00238 
00242     private static function getVersionLinkedSvn() {
00243         global $IP;
00244 
00245         $info = self::getSvnInfo( $IP );
00246         if ( !isset( $info['checkout-rev'] ) ) {
00247             return false;
00248         }
00249 
00250         $linkText = wfMessage(
00251             'version-svn-revision',
00252             isset( $info['directory-rev'] ) ? $info['directory-rev'] : '',
00253             $info['checkout-rev']
00254         )->text();
00255 
00256         if ( isset( $info['viewvc-url'] ) ) {
00257             $version = "[{$info['viewvc-url']} $linkText]";
00258         } else {
00259             $version = $linkText;
00260         }
00261 
00262         return self::getwgVersionLinked() . " $version";
00263     }
00264 
00268     private static function getwgVersionLinked() {
00269         global $wgVersion;
00270         $versionUrl = "";
00271         if ( wfRunHooks( 'SpecialVersionVersionUrl', array( $wgVersion, &$versionUrl ) ) ) {
00272             $versionParts = array();
00273             preg_match( "/^(\d+\.\d+)/", $wgVersion, $versionParts );
00274             $versionUrl = "https://www.mediawiki.org/wiki/MediaWiki_{$versionParts[1]}";
00275         }
00276         return "[$versionUrl $wgVersion]";
00277     }
00278 
00283     private static function getVersionLinkedGit() {
00284         global $IP, $wgLang;
00285 
00286         $gitInfo = new GitInfo( $IP );
00287         $headSHA1 = $gitInfo->getHeadSHA1();
00288         if ( !$headSHA1 ) {
00289             return false;
00290         }
00291 
00292         $shortSHA1 = '(' . substr( $headSHA1, 0, 7 ) . ')';
00293 
00294         $gitHeadUrl = $gitInfo->getHeadViewUrl();
00295         if ( $gitHeadUrl !== false ) {
00296             $shortSHA1 = "[$gitHeadUrl $shortSHA1]";
00297         }
00298 
00299         $gitHeadCommitDate = $gitInfo->getHeadCommitDate();
00300         if ( $gitHeadCommitDate ) {
00301             $shortSHA1 .= "<br/>" . $wgLang->timeanddate( $gitHeadCommitDate, true );
00302         }
00303 
00304         return self::getwgVersionLinked() . " $shortSHA1";
00305     }
00306 
00319     public static function getExtensionTypes() {
00320         if ( self::$extensionTypes === false ) {
00321             self::$extensionTypes = array(
00322                 'specialpage' => wfMessage( 'version-specialpages' )->text(),
00323                 'parserhook' => wfMessage( 'version-parserhooks' )->text(),
00324                 'variable' => wfMessage( 'version-variables' )->text(),
00325                 'media' => wfMessage( 'version-mediahandlers' )->text(),
00326                 'antispam' => wfMessage( 'version-antispam' )->text(),
00327                 'skin' => wfMessage( 'version-skins' )->text(),
00328                 'api' => wfMessage( 'version-api' )->text(),
00329                 'other' => wfMessage( 'version-other' )->text(),
00330             );
00331 
00332             wfRunHooks( 'ExtensionTypes', array( &self::$extensionTypes ) );
00333         }
00334 
00335         return self::$extensionTypes;
00336     }
00337 
00347     public static function getExtensionTypeName( $type ) {
00348         $types = self::getExtensionTypes();
00349         return isset( $types[$type] ) ? $types[$type] : $types['other'];
00350     }
00351 
00357     function getExtensionCredits() {
00358         global $wgExtensionCredits, $wgExtensionFunctions, $wgParser;
00359 
00360         if ( !count( $wgExtensionCredits ) && !count( $wgExtensionFunctions ) ) {
00361             return '';
00362         }
00363 
00364         $extensionTypes = self::getExtensionTypes();
00365 
00369         wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );
00370 
00371         $out = Xml::element( 'h2', array( 'id' => 'mw-version-ext' ), $this->msg( 'version-extensions' )->text() ) .
00372             Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-ext' ) );
00373 
00374         // Make sure the 'other' type is set to an array.
00375         if ( !array_key_exists( 'other', $wgExtensionCredits ) ) {
00376             $wgExtensionCredits['other'] = array();
00377         }
00378 
00379         // Find all extensions that do not have a valid type and give them the type 'other'.
00380         foreach ( $wgExtensionCredits as $type => $extensions ) {
00381             if ( !array_key_exists( $type, $extensionTypes ) ) {
00382                 $wgExtensionCredits['other'] = array_merge( $wgExtensionCredits['other'], $extensions );
00383             }
00384         }
00385 
00386         // Loop through the extension categories to display their extensions in the list.
00387         foreach ( $extensionTypes as $type => $message ) {
00388             if ( $type != 'other' ) {
00389                 $out .= $this->getExtensionCategory( $type, $message );
00390             }
00391         }
00392 
00393         // We want the 'other' type to be last in the list.
00394         $out .= $this->getExtensionCategory( 'other', $extensionTypes['other'] );
00395 
00396         $tags = $wgParser->getTags();
00397         $cnt = count( $tags );
00398 
00399         if ( $cnt ) {
00400             for ( $i = 0; $i < $cnt; ++$i ) {
00401                 $tags[$i] = "&lt;{$tags[$i]}&gt;";
00402             }
00403             $out .= $this->openExtType( $this->msg( 'version-parser-extensiontags' )->text(), 'parser-tags' );
00404             $out .= '<tr><td colspan="4">' . $this->listToText( $tags ) . "</td></tr>\n";
00405         }
00406 
00407         $fhooks = $wgParser->getFunctionHooks();
00408         if ( count( $fhooks ) ) {
00409             $out .= $this->openExtType( $this->msg( 'version-parser-function-hooks' )->text(), 'parser-function-hooks' );
00410             $out .= '<tr><td colspan="4">' . $this->listToText( $fhooks ) . "</td></tr>\n";
00411         }
00412 
00413         $out .= Xml::closeElement( 'table' );
00414 
00415         return $out;
00416     }
00417 
00428     protected function getExtensionCategory( $type, $message ) {
00429         global $wgExtensionCredits;
00430 
00431         $out = '';
00432 
00433         if ( array_key_exists( $type, $wgExtensionCredits ) && count( $wgExtensionCredits[$type] ) > 0 ) {
00434             $out .= $this->openExtType( $message, 'credits-' . $type );
00435 
00436             usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
00437 
00438             foreach ( $wgExtensionCredits[$type] as $extension ) {
00439                 $out .= $this->getCreditsForExtension( $extension );
00440             }
00441         }
00442 
00443         return $out;
00444     }
00445 
00452     function compare( $a, $b ) {
00453         if ( $a['name'] === $b['name'] ) {
00454             return 0;
00455         } else {
00456             return $this->getLanguage()->lc( $a['name'] ) > $this->getLanguage()->lc( $b['name'] )
00457                 ? 1
00458                 : -1;
00459         }
00460     }
00461 
00469     function getCreditsForExtension( array $extension ) {
00470         global $wgLang;
00471 
00472         $name = isset( $extension['name'] ) ? $extension['name'] : '[no name]';
00473 
00474         $vcsText = false;
00475 
00476         if ( isset( $extension['path'] ) ) {
00477             $gitInfo = new GitInfo( dirname( $extension['path'] ) );
00478             $gitHeadSHA1 = $gitInfo->getHeadSHA1();
00479             if ( $gitHeadSHA1 !== false ) {
00480                 $vcsText = '(' . substr( $gitHeadSHA1, 0, 7 ) . ')';
00481                 $gitViewerUrl = $gitInfo->getHeadViewUrl();
00482                 if ( $gitViewerUrl !== false ) {
00483                     $vcsText = "[$gitViewerUrl $vcsText]";
00484                 }
00485                 $gitHeadCommitDate = $gitInfo->getHeadCommitDate();
00486                 if ( $gitHeadCommitDate ) {
00487                     $vcsText .= "<br/>" . $wgLang->timeanddate( $gitHeadCommitDate, true );
00488                 }
00489             } else {
00490                 $svnInfo = self::getSvnInfo( dirname( $extension['path'] ) );
00491                 # Make subversion text/link.
00492                 if ( $svnInfo !== false ) {
00493                     $directoryRev = isset( $svnInfo['directory-rev'] ) ? $svnInfo['directory-rev'] : null;
00494                     $vcsText = $this->msg( 'version-svn-revision', $directoryRev, $svnInfo['checkout-rev'] )->text();
00495                     $vcsText = isset( $svnInfo['viewvc-url'] ) ? '[' . $svnInfo['viewvc-url'] . " $vcsText]" : $vcsText;
00496                 }
00497             }
00498         }
00499 
00500         # Make main link (or just the name if there is no URL).
00501         if ( isset( $extension['url'] ) ) {
00502             $mainLink = "[{$extension['url']} $name]";
00503         } else {
00504             $mainLink = $name;
00505         }
00506 
00507         if ( isset( $extension['version'] ) ) {
00508             $versionText = '<span class="mw-version-ext-version">' .
00509                 $this->msg( 'version-version', $extension['version'] )->text() .
00510                 '</span>';
00511         } else {
00512             $versionText = '';
00513         }
00514 
00515         # Make description text.
00516         $description = isset( $extension['description'] ) ? $extension['description'] : '';
00517 
00518         if ( isset( $extension['descriptionmsg'] ) ) {
00519             # Look for a localized description.
00520             $descriptionMsg = $extension['descriptionmsg'];
00521 
00522             if ( is_array( $descriptionMsg ) ) {
00523                 $descriptionMsgKey = $descriptionMsg[0]; // Get the message key
00524                 array_shift( $descriptionMsg ); // Shift out the message key to get the parameters only
00525                 array_map( "htmlspecialchars", $descriptionMsg ); // For sanity
00526                 $description = $this->msg( $descriptionMsgKey, $descriptionMsg )->text();
00527             } else {
00528                 $description = $this->msg( $descriptionMsg )->text();
00529             }
00530         }
00531 
00532         if ( $vcsText !== false ) {
00533             $extNameVer = "<tr>
00534                 <td><em>$mainLink $versionText</em></td>
00535                 <td><em>$vcsText</em></td>";
00536         } else {
00537             $extNameVer = "<tr>
00538                 <td colspan=\"2\"><em>$mainLink $versionText</em></td>";
00539         }
00540 
00541         $author = isset( $extension['author'] ) ? $extension['author'] : array();
00542         $extDescAuthor = "<td>$description</td>
00543             <td>" . $this->listAuthors( $author, false ) . "</td>
00544             </tr>\n";
00545 
00546         return $extNameVer . $extDescAuthor;
00547     }
00548 
00554     private function getWgHooks() {
00555         global $wgHooks;
00556 
00557         if ( count( $wgHooks ) ) {
00558             $myWgHooks = $wgHooks;
00559             ksort( $myWgHooks );
00560 
00561             $ret = Xml::element( 'h2', array( 'id' => 'mw-version-hooks' ), $this->msg( 'version-hooks' )->text() ) .
00562                 Xml::openElement( 'table', array( 'class' => 'wikitable', 'id' => 'sv-hooks' ) ) .
00563                 "<tr>
00564                     <th>" . $this->msg( 'version-hook-name' )->text() . "</th>
00565                     <th>" . $this->msg( 'version-hook-subscribedby' )->text() . "</th>
00566                 </tr>\n";
00567 
00568             foreach ( $myWgHooks as $hook => $hooks ) {
00569                 $ret .= "<tr>
00570                         <td>$hook</td>
00571                         <td>" . $this->listToText( $hooks ) . "</td>
00572                     </tr>\n";
00573             }
00574 
00575             $ret .= Xml::closeElement( 'table' );
00576             return $ret;
00577         } else {
00578             return '';
00579         }
00580     }
00581 
00582     private function openExtType( $text, $name = null ) {
00583         $opt = array( 'colspan' => 4 );
00584         $out = '';
00585 
00586         if ( $this->firstExtOpened ) {
00587             // Insert a spacing line
00588             $out .= '<tr class="sv-space">' . Html::element( 'td', $opt ) . "</tr>\n";
00589         }
00590         $this->firstExtOpened = true;
00591 
00592         if ( $name ) {
00593             $opt['id'] = "sv-$name";
00594         }
00595 
00596         $out .= "<tr>" . Xml::element( 'th', $opt, $text ) . "</tr>\n";
00597 
00598         return $out;
00599     }
00600 
00606     private function IPInfo() {
00607         $ip = str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
00608         return "<!-- visited from $ip -->\n<span style='display:none'>visited from $ip</span>";
00609     }
00610 
00617     function listAuthors( $authors ) {
00618         $list = array();
00619         foreach ( (array)$authors as $item ) {
00620             if ( $item == '...' ) {
00621                 $list[] = $this->msg( 'version-poweredby-others' )->text();
00622             } elseif ( substr( $item, -5 ) == ' ...]' ) {
00623                 $list[] = substr( $item, 0, -4 ) . $this->msg( 'version-poweredby-others' )->text() . "]";
00624             } else {
00625                 $list[] = $item;
00626             }
00627         }
00628         return $this->listToText( $list, false );
00629     }
00630 
00639     function listToText( $list, $sort = true ) {
00640         $cnt = count( $list );
00641 
00642         if ( $cnt == 1 ) {
00643             // Enforce always returning a string
00644             return (string)self::arrayToString( $list[0] );
00645         } elseif ( $cnt == 0 ) {
00646             return '';
00647         } else {
00648             if ( $sort ) {
00649                 sort( $list );
00650             }
00651             return $this->getLanguage()->listToText( array_map( array( __CLASS__, 'arrayToString' ), $list ) );
00652         }
00653     }
00654 
00663     public static function arrayToString( $list ) {
00664         if ( is_array( $list ) && count( $list ) == 1 ) {
00665             $list = $list[0];
00666         }
00667         if ( is_object( $list ) ) {
00668             $class = wfMessage( 'parentheses' )->params( get_class( $list ) )->escaped();
00669             return $class;
00670         } elseif ( !is_array( $list ) ) {
00671             return $list;
00672         } else {
00673             if ( is_object( $list[0] ) ) {
00674                 $class = get_class( $list[0] );
00675             } else {
00676                 $class = $list[0];
00677             }
00678             return wfMessage( 'parentheses' )->params( "$class, {$list[1]}" )->escaped();
00679         }
00680     }
00681 
00698     public static function getSvnInfo( $dir ) {
00699         // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
00700         $entries = $dir . '/.svn/entries';
00701 
00702         if ( !file_exists( $entries ) ) {
00703             return false;
00704         }
00705 
00706         $lines = file( $entries );
00707         if ( !count( $lines ) ) {
00708             return false;
00709         }
00710 
00711         // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
00712         if ( preg_match( '/^<\?xml/', $lines[0] ) ) {
00713             // subversion is release <= 1.3
00714             if ( !function_exists( 'simplexml_load_file' ) ) {
00715                 // We could fall back to expat... YUCK
00716                 return false;
00717             }
00718 
00719             // SimpleXml whines about the xmlns...
00720             wfSuppressWarnings();
00721             $xml = simplexml_load_file( $entries );
00722             wfRestoreWarnings();
00723 
00724             if ( $xml ) {
00725                 foreach ( $xml->entry as $entry ) {
00726                     if ( $xml->entry[0]['name'] == '' ) {
00727                         // The directory entry should always have a revision marker.
00728                         if ( $entry['revision'] ) {
00729                             return array( 'checkout-rev' => intval( $entry['revision'] ) );
00730                         }
00731                     }
00732                 }
00733             }
00734 
00735             return false;
00736         }
00737 
00738         // Subversion is release 1.4 or above.
00739         if ( count( $lines ) < 11 ) {
00740             return false;
00741         }
00742 
00743         $info = array(
00744             'checkout-rev' => intval( trim( $lines[3] ) ),
00745             'url' => trim( $lines[4] ),
00746             'repo-url' => trim( $lines[5] ),
00747             'directory-rev' => intval( trim( $lines[10] ) )
00748         );
00749 
00750         if ( isset( self::$viewvcUrls[$info['repo-url']] ) ) {
00751             $viewvc = str_replace(
00752                 $info['repo-url'],
00753                 self::$viewvcUrls[$info['repo-url']],
00754                 $info['url']
00755             );
00756 
00757             $viewvc .= '/?pathrev=';
00758             $viewvc .= urlencode( $info['checkout-rev'] );
00759             $info['viewvc-url'] = $viewvc;
00760         }
00761 
00762         return $info;
00763     }
00764 
00772     public static function getSvnRevision( $dir ) {
00773         $info = self::getSvnInfo( $dir );
00774 
00775         if ( $info === false ) {
00776             return false;
00777         } elseif ( isset( $info['checkout-rev'] ) ) {
00778             return $info['checkout-rev'];
00779         } else {
00780             return false;
00781         }
00782     }
00783 
00788     public static function getGitHeadSha1( $dir ) {
00789         $repo = new GitInfo( $dir );
00790         return $repo->getHeadSHA1();
00791     }
00792 
00797     public function getEntryPointInfo() {
00798         global $wgArticlePath, $wgScriptPath;
00799         $scriptPath = $wgScriptPath ? $wgScriptPath : "/";
00800         $entryPoints = array(
00801             'version-entrypoints-articlepath' => $wgArticlePath,
00802             'version-entrypoints-scriptpath' => $scriptPath,
00803             'version-entrypoints-index-php' => wfScript( 'index' ),
00804             'version-entrypoints-api-php' => wfScript( 'api' ),
00805             'version-entrypoints-load-php' => wfScript( 'load' ),
00806         );
00807 
00808         $language = $this->getLanguage();
00809         $thAttribures = array(
00810             'dir' => $language->getDir(),
00811             'lang' => $language->getCode()
00812         );
00813         $out = Html::element( 'h2', array( 'id' => 'mw-version-entrypoints' ), $this->msg( 'version-entrypoints' )->text() ) .
00814             Html::openElement( 'table',
00815                 array(
00816                     'class' => 'wikitable plainlinks',
00817                     'id' => 'mw-version-entrypoints-table',
00818                     'dir' => 'ltr',
00819                     'lang' => 'en'
00820                 )
00821             ) .
00822             Html::openElement( 'tr' ) .
00823             Html::element( 'th', $thAttribures, $this->msg( 'version-entrypoints-header-entrypoint' )->text() ) .
00824             Html::element( 'th', $thAttribures, $this->msg( 'version-entrypoints-header-url' )->text() ) .
00825             Html::closeElement( 'tr' );
00826 
00827         foreach ( $entryPoints as $message => $value ) {
00828             $url = wfExpandUrl( $value, PROTO_RELATIVE );
00829             $out .= Html::openElement( 'tr' ) .
00830                 // ->text() looks like it should be ->parse(), but this function
00831                 // returns wikitext, not HTML, boo
00832                 Html::rawElement( 'td', array(), $this->msg( $message )->text() ) .
00833                 Html::rawElement( 'td', array(), Html::rawElement( 'code', array(), "[$url $value]" ) ) .
00834                 Html::closeElement( 'tr' );
00835         }
00836 
00837         $out .= Html::closeElement( 'table' );
00838         return $out;
00839     }
00840 
00841     protected function getGroupName() {
00842         return 'wiki';
00843     }
00844 
00845 }