r70674 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r70673‎ | r70674 | r70675 >
Date:07:32, 8 August 2010
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Started work on Special:Extensions, based on Special:version. Also registered special pages and added INSTALL file.
Modified paths:
  • /trunk/extensions/Deployment/Deployment.i18n.php (modified) (history)
  • /trunk/extensions/Deployment/Deployment.php (modified) (history)
  • /trunk/extensions/Deployment/INSTALL (modified) (history)
  • /trunk/extensions/Deployment/api/ApiExtensions.php (deleted) (history)
  • /trunk/extensions/Deployment/api/ApiQueryExtensions.php (deleted) (history)
  • /trunk/extensions/Deployment/specials/SpecialExtensions.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Deployment/specials/SpecialExtensions.php
@@ -21,12 +21,233 @@
2222 */
2323 class SpecialExtensions extends SpecialPage {
2424
 25+ protected $firstExtOpened = true;
 26+
 27+ protected static $viewvcUrls = array(
 28+ 'svn+ssh://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
 29+ 'http://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
 30+ # Doesn't work at the time of writing but maybe some day:
 31+ 'https://svn.wikimedia.org/viewvc/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
 32+ );
 33+
2534 public function __construct() {
2635 parent::__construct( 'Extensions' );
2736 }
2837
2938 public function execute( $arg ) {
 39+ global $wgOut;
 40+ $wgOut->addWikiText( $this->getExtensionList() );
 41+ }
 42+
 43+ protected function getExtensionList() {
 44+ global $wgExtensionCredits;
3045
 46+ $out = Xml::element( 'h2', array( 'id' => 'mw-version-ext' ), wfMsg( 'version-extensions' ) ) .
 47+ Xml::openElement( 'table', array( 'class' => 'wikitable', 'id' => 'sv-ext' ) );
 48+
 49+ foreach ( $wgExtensionCredits as $type => $extensions ) {
 50+ if ( count( $wgExtensionCredits[$type] ) > 0 ) {
 51+ $out .= $this->getExtensionTypeHeader( $type, 'credits-' . $type );
 52+
 53+ usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
 54+
 55+ foreach ( $wgExtensionCredits[$type] as $extension ) {
 56+ $out .= $this->getExtensionForList( $extension );
 57+ }
 58+ }
 59+ }
 60+
 61+ return $out;
3162 }
3263
 64+ protected function getExtensionTypeHeader( $text, $name ) {
 65+ $opt = array( 'colspan' => 4 );
 66+ $out = '';
 67+
 68+ if( !$this->firstExtOpened ) {
 69+ // Insert a spacing line
 70+ $out .= '<tr class="sv-space">' . Html::element( 'td', $opt ) . "</tr>\n";
 71+ $this->firstExtOpened = true;
 72+ }
 73+
 74+ if( $name ) {
 75+ $opt['id'] = "sv-$name";
 76+ }
 77+
 78+ $out .= "<tr>" . Xml::element( 'th', $opt, $text ) . "</tr>\n";
 79+ return $out;
 80+ }
 81+
 82+ protected function getExtensionForList( array $extension ) {
 83+ global $wgLang;
 84+
 85+ $name = isset( $extension['name'] ) ? $extension['name'] : '[no name]';
 86+
 87+ if ( isset( $extension['path'] ) ) {
 88+ $svnInfo = self::getSvnInfo( dirname($extension['path']) );
 89+ $directoryRev = isset( $svnInfo['directory-rev'] ) ? $svnInfo['directory-rev'] : null;
 90+ $checkoutRev = isset( $svnInfo['checkout-rev'] ) ? $svnInfo['checkout-rev'] : null;
 91+ $viewvcUrl = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : null;
 92+ } else {
 93+ $directoryRev = null;
 94+ $checkoutRev = null;
 95+ $viewvcUrl = null;
 96+ }
 97+
 98+ # Make main link (or just the name if there is no URL).
 99+ if ( isset( $extension['url'] ) ) {
 100+ $mainLink = "[{$extension['url']} $name]";
 101+ } else {
 102+ $mainLink = $name;
 103+ }
 104+
 105+ if ( isset( $extension['version'] ) ) {
 106+ $versionText = '<span class="mw-version-ext-version">' .
 107+ wfMsg( 'version-version', $extension['version'] ) .
 108+ '</span>';
 109+ } else {
 110+ $versionText = '';
 111+ }
 112+
 113+ # Make subversion text/link.
 114+ if ( $checkoutRev ) {
 115+ $svnText = wfMsg( 'version-svn-revision', $directoryRev, $checkoutRev );
 116+ $svnText = isset( $viewvcUrl ) ? "[$viewvcUrl $svnText]" : $svnText;
 117+ } else {
 118+ $svnText = false;
 119+ }
 120+
 121+ # Make description text.
 122+ $description = isset ( $extension['description'] ) ? $extension['description'] : '';
 123+
 124+ if( isset ( $extension['descriptionmsg'] ) ) {
 125+ # Look for a localized description.
 126+ $descriptionMsg = $extension['descriptionmsg'];
 127+
 128+ if( is_array( $descriptionMsg ) ) {
 129+ $descriptionMsgKey = $descriptionMsg[0]; // Get the message key
 130+ array_shift( $descriptionMsg ); // Shift out the message key to get the parameters only
 131+ array_map( "htmlspecialchars", $descriptionMsg ); // For sanity
 132+ $msg = wfMsg( $descriptionMsgKey, $descriptionMsg );
 133+ } else {
 134+ $msg = wfMsg( $descriptionMsg );
 135+ }
 136+ if ( !wfEmptyMsg( $descriptionMsg, $msg ) && $msg != '' ) {
 137+ $description = $msg;
 138+ }
 139+ }
 140+
 141+ if ( $svnText !== false ) {
 142+ $extNameVer = "<tr>
 143+ <td><em>$mainLink $versionText</em></td>
 144+ <td><em>$svnText</em></td>";
 145+ } else {
 146+ $extNameVer = "<tr>
 147+ <td colspan=\"2\"><em>$mainLink $versionText</em></td>";
 148+ }
 149+
 150+ $author = isset ( $extension['author'] ) ? $extension['author'] : array();
 151+ $extDescAuthor = "<td>$description</td>
 152+ <td>" . $wgLang->listToText( (array)$author ) . "</td>
 153+ </tr>\n";
 154+
 155+ return $extNameVer . $extDescAuthor;
 156+ }
 157+
 158+ /**
 159+ * Callback to sort extensions by type.
 160+ */
 161+ public function compare( $a, $b ) {
 162+ global $wgLang;
 163+ if( $a['name'] === $b['name'] ) {
 164+ return 0;
 165+ } else {
 166+ return $wgLang->lc( $a['name'] ) > $wgLang->lc( $b['name'] )
 167+ ? 1
 168+ : -1;
 169+ }
 170+ }
 171+
 172+ /**
 173+ * Get an associative array of information about a given path, from its .svn
 174+ * subdirectory. Returns false on error, such as if the directory was not
 175+ * checked out with subversion.
 176+ *
 177+ * Returned keys are:
 178+ * Required:
 179+ * checkout-rev The revision which was checked out
 180+ * Optional:
 181+ * directory-rev The revision when the directory was last modified
 182+ * url The subversion URL of the directory
 183+ * repo-url The base URL of the repository
 184+ * viewvc-url A ViewVC URL pointing to the checked-out revision
 185+ */
 186+ public static function getSvnInfo( $dir ) {
 187+ // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
 188+ $entries = $dir . '/.svn/entries';
 189+
 190+ if( !file_exists( $entries ) ) {
 191+ return false;
 192+ }
 193+
 194+ $lines = file( $entries );
 195+ if ( !count( $lines ) ) {
 196+ return false;
 197+ }
 198+
 199+ // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
 200+ if( preg_match( '/^<\?xml/', $lines[0] ) ) {
 201+ // subversion is release <= 1.3
 202+ if( !function_exists( 'simplexml_load_file' ) ) {
 203+ // We could fall back to expat... YUCK
 204+ return false;
 205+ }
 206+
 207+ // SimpleXml whines about the xmlns...
 208+ wfSuppressWarnings();
 209+ $xml = simplexml_load_file( $entries );
 210+ wfRestoreWarnings();
 211+
 212+ if( $xml ) {
 213+ foreach( $xml->entry as $entry ) {
 214+ if( $xml->entry[0]['name'] == '' ) {
 215+ // The directory entry should always have a revision marker.
 216+ if( $entry['revision'] ) {
 217+ return array( 'checkout-rev' => intval( $entry['revision'] ) );
 218+ }
 219+ }
 220+ }
 221+ }
 222+
 223+ return false;
 224+ }
 225+
 226+ // Subversion is release 1.4 or above.
 227+ if ( count( $lines ) < 11 ) {
 228+ return false;
 229+ }
 230+
 231+ $info = array(
 232+ 'checkout-rev' => intval( trim( $lines[3] ) ),
 233+ 'url' => trim( $lines[4] ),
 234+ 'repo-url' => trim( $lines[5] ),
 235+ 'directory-rev' => intval( trim( $lines[10] ) )
 236+ );
 237+
 238+ if ( isset( self::$viewvcUrls[$info['repo-url']] ) ) {
 239+ $viewvc = str_replace(
 240+ $info['repo-url'],
 241+ self::$viewvcUrls[$info['repo-url']],
 242+ $info['url']
 243+ );
 244+
 245+ $pathRelativeToRepo = substr( $info['url'], strlen( $info['repo-url'] ) );
 246+ $viewvc .= '/?pathrev=';
 247+ $viewvc .= urlencode( $info['checkout-rev'] );
 248+ $info['viewvc-url'] = $viewvc;
 249+ }
 250+
 251+ return $info;
 252+ }
 253+
33254 }
\ No newline at end of file
Index: trunk/extensions/Deployment/Deployment.i18n.php
@@ -18,7 +18,12 @@
1919 // General
2020 'deployment-desc' => 'Provides a way to install extensions via GUI and update them and the wiki itself via another GUI',
2121
22 - // Filesystem: Direct
 22+ // Special pages
 23+ 'specialpages-group-administration' => 'Wiki administration',
 24+ 'dashboard' => 'Administration dashboard',
 25+ 'extensions' => 'Manage extensions',
 26+ 'update' => 'Update wiki and extensions',
 27+ 'install' => 'Install extensions',
2328
2429 // Filesystem: FTP
2530 'deploy-ftp-not-loaded' => 'The FTP PHP extension is not available',
@@ -38,5 +43,4 @@
3944 'deploy-ssh2-key-authentication-failed' => 'Public and private keys are incorrect for username $1',
4045 'deploy-ssh2-password-authentication-failed' => 'Username or password incorrect for username $1',
4146 'deploy-ssh2-command-failed' => 'Unable to perform command: $1',
42 -
4347 );
Index: trunk/extensions/Deployment/Deployment.php
@@ -14,7 +14,7 @@
1515 die( 'Not an entry point.' );
1616 }
1717
18 -define( 'Deployment_VERSION', '0.0.0' );
 18+define( 'Deployment_VERSION', '0.1 alpha' );
1919
2020 // Register the initialization function.
2121 $wgExtensionFunctions[] = 'efDeploymentSetup';
@@ -22,6 +22,27 @@
2323 // Register the internationalization file.
2424 $wgExtensionMessagesFiles['Deployment'] = dirname( __FILE__ ) . '/Deployment.i18n.php';
2525
 26+// Load and register Special:Dashboard.
 27+$wgAutoloadClasses['SpecialDashboard'] = dirname( __FILE__ ) . '/specials/SpecialDashboard.php';
 28+$wgSpecialPages['Dashboard'] = 'SpecialDashboard';
 29+$wgSpecialPageGroups['Dashboard'] = 'administration';
 30+
 31+// Load and register Special:Extensions.
 32+$wgAutoloadClasses['SpecialExtensions'] = dirname( __FILE__ ) . '/specials/SpecialExtensions.php';
 33+$wgSpecialPages['Extensions'] = 'SpecialExtensions';
 34+$wgSpecialPageGroups['Extensions'] = 'administration';
 35+
 36+// Load and register Special:Install.
 37+$wgAutoloadClasses['SpecialInstall'] = dirname( __FILE__ ) . '/specials/SpecialInstall.php';
 38+$wgSpecialPages['Install'] = 'SpecialInstall';
 39+$wgSpecialPageGroups['Install'] = 'administration';
 40+
 41+// Load and register Special:Update.
 42+$wgAutoloadClasses['SpecialUpdate'] = dirname( __FILE__ ) . '/specials/SpecialUpdate.php';
 43+$wgSpecialPages['Update'] = 'SpecialUpdate';
 44+$wgSpecialPageGroups['Update'] = 'administration';
 45+
 46+
2647 /**
2748 * Initialization function for the Deployment extension.
2849 */
Index: trunk/extensions/Deployment/INSTALL
@@ -0,0 +1,5 @@
 2+Once you have downloaded the code, place the 'Deployment' directory within your MediaWiki 'extensions' directory.
 3+Then add the following code to your LocalSettings.php file:
 4+
 5+# Distribution
 6+require_once( "$IP/extensions/Deployment/Deployment.php" );
\ No newline at end of file
Index: trunk/extensions/Deployment/api/ApiExtensions.php
@@ -1 +0,0 @@
2 -<?php
Index: trunk/extensions/Deployment/api/ApiQueryExtensions.php
@@ -1 +0,0 @@
2 -<?php

Status & tagging log