Mwalker has uploaded a new change for review.
https://gerrit.wikimedia.org/r/65299
Change subject: WIP: Update Special:Version Licensing (Part 1)
......................................................................
WIP: Update Special:Version Licensing (Part 1)
Allow extensions to present license information and credits.
Change-Id: I388f3b630462f1909f30751c987f7af585e98881
---
M CREDITS
M includes/specials/SpecialVersion.php
M languages/messages/MessagesEn.php
3 files changed, 291 insertions(+), 82 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/99/65299/1
diff --git a/CREDITS b/CREDITS
index 417bec3..5973893 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,8 +1,11 @@
+{{int:version-credits-summary}}
+<!--
MediaWiki 1.22 is a collaborative project released under the
GNU General Public License v2. We would like to recognize the
following names for their contribution to the product.
-
+-->
<!-- Please notice that the following can be found parsed under
Special:Version/Credits -->
+
== Developers ==
* Aaron Schulz
* Alex Z.
diff --git a/includes/specials/SpecialVersion.php
b/includes/specials/SpecialVersion.php
index c257dd4..1996e07 100644
--- a/includes/specials/SpecialVersion.php
+++ b/includes/specials/SpecialVersion.php
@@ -48,41 +48,84 @@
* main()
*/
public function execute( $par ) {
- global $wgSpecialVersionShowHooks, $IP;
+ global $wgSpecialVersionShowHooks, $IP, $wgExtensionCredits;
$this->setHeaders();
$this->outputHeader();
$out = $this->getOutput();
$out->allowClickjacking();
- if ( $par !== 'Credits' ) {
- $text =
- $this->getMediaWikiCredits() .
- $this->softwareInformation() .
- $this->getEntryPointInfo() .
- $this->getExtensionCredits();
- if ( $wgSpecialVersionShowHooks ) {
- $text .= $this->getWgHooks();
- }
-
- $out->addWikiText( $text );
- $out->addHTML( $this->IPInfo() );
-
- if ( $this->getRequest()->getVal( 'easteregg' ) ) {
- // TODO: put something interesting here
+ // Explode the sub page information into useful bits
+ $parts = explode( '/', (string)$par );
+ if ( isset( $parts[1] ) ) {
+ $extName = $parts[1];
+ $extNode = null;
+ // Find it!
+ foreach ( $wgExtensionCredits as $group => $extensions
) {
+ foreach( $extensions as $ext ) {
+ if ( isset( $ext['name'] ) && (
$ext['name'] === $extName ) ) {
+ $extNode = &$ext;
+ break 2;
+ }
+ }
}
} else {
- // Credits sub page
+ $extName = 'MediaWiki';
+ $extGroup = null;
+ }
- // Header
- $out->addHTML( wfMessage( 'version-credits-summary'
)->parseAsBlock() );
+ // Now figure out what to do
+ switch ( strtolower( $parts[0] ) ) {
+ case 'credits':
+ $wikiText = '{{int:version-credits-not-found}}';
+ if ( $extName === 'MediaWiki' ) {
+ $wikiText = file_get_contents( $IP .
'/CREDITS' );
+ } elseif ( ( $extNode !== null ) && isset(
$extNode['path'] ) ) {
+ $file = $this->getExtAuthorsFileName(
$extNode['path'] );
+ if ( $file ) {
+ $wikiText = file_get_contents(
$file );
+ }
+ }
- $wikiText = file_get_contents( $IP . '/CREDITS' );
+ $out->setPageTitle( new Message(
'version-credits-title', array( $extName ) ) );
+ $out->addWikiText( $wikiText );
+ break;
- // Take everything from the first section onwards, to
remove the (not localized) header
- $wikiText = substr( $wikiText, strpos( $wikiText, '=='
) );
+ case 'license':
+ $wikiText = '{{int:version-license-not-found}}';
+ if ( $extName === 'MediaWiki' ) {
+ $wikiText = file_get_contents( $IP .
'/COPYING' );
+ } elseif ( ( $extNode !== null ) && isset(
$extNode['path'] ) ) {
+ $file = $this->getExtLicenseFileName(
dirname( $extNode['path'] ) );
+ if ( $file ) {
+ $wikiText = file_get_contents(
$file );
+ if ( !isset(
$extNode['license-name'] ) ) {
+ // If the developer did
not explicitly set license-name they probably
+ // are unaware that
we're now sucking this file in and thus it's probably
+ // now wikitext
friendly.
+ $wikiText =
"<pre>$wikiText</pre>";
+ }
+ }
+ }
- $out->addWikiText( $wikiText );
+ $out->setPageTitle( new Message(
'version-license-title', array( $extName ) ) );
+ $out->addWikiText( $wikiText );
+ break;
+
+ default:
+ $out->addWikiText(
+ $this->getMediaWikiCredits() .
+ $this->softwareInformation() .
+ $this->getEntryPointInfo()
+ );
+ $out->addHtml( $this->getExtensionCredits() );
+ if ( $wgSpecialVersionShowHooks ) {
+ $out->addWikiText( $this->getWgHooks()
);
+ }
+
+ $out->addHTML( $this->IPInfo() );
+
+ break;
}
}
@@ -462,63 +505,115 @@
}
/**
- * Creates and formats the credits for a single extension and returns
this.
+ * Creates and formats a version line for a single extension.
+ *
+ * Information for four columns will be created. Parameters required in
the
+ * $extension array for part rendering are indicated in ()
+ * - The name of (name), and URL link to (url), the extension
+ * -- Also if available the short name of the license (license-name)
and a linke
+ * to ((LICENSE)|(COPYING))(\.txt)? if it exists.
+ * - Official version number (version) and if available version
control system
+ * revision (path), link, and date
+ * - Description of extension (descriptionmsg or description)
+ * - List of authors (author) and link to a
((AUTHORS)|(CREDITS))(\.txt)? file if it exists
*
* @param $extension Array
*
* @return string
*/
function getCreditsForExtension( array $extension ) {
- global $wgLang;
+ $out = $this->getOutput();
- $name = isset( $extension['name'] ) ? $extension['name'] : '[no
name]';
+ /* === Obtain the information for all the bits and pieces === */
+ /* --- Extension name and link --- */
+ $extensionName = isset( $extension['name'] ) ?
$extension['name'] : '[no name]';
+ if ( isset( $extension['url'] ) ) {
+ $extensionNameLink = Linker::makeExternalLink(
+ $extension['url'],
+ $extensionName,
+ true,
+ '',
+ array( 'class' => 'mw-version-ext-name' )
+ );
+ } else {
+ $extensionNameLink = $extensionName;
+ }
- $vcsText = false;
+ /* --- Version information ---
+ If the extension path is set we will check that directory
for GIT and SVN
+ metadata in an attempt to extract date and vcs commit
metadata.
+ */
+ $canonicalVersion = '-';
+ $extensionPath = null;
+ $vcsVersion = null;
+ $vcsLink = null;
+ $vcsDate = null;
+
+ if ( isset( $extension['version'] ) ) {
+ $canonicalVersion = $out->parseInline(
$extension['version'] );
+ }
if ( isset( $extension['path'] ) ) {
- $gitInfo = new GitInfo( dirname( $extension['path'] ) );
- $gitHeadSHA1 = $gitInfo->getHeadSHA1();
- if ( $gitHeadSHA1 !== false ) {
- $vcsText = '(' . substr( $gitHeadSHA1, 0, 7 ) .
')';
- $gitViewerUrl = $gitInfo->getHeadViewUrl();
- if ( $gitViewerUrl !== false ) {
- $vcsText = "[$gitViewerUrl $vcsText]";
- }
- $gitHeadCommitDate =
$gitInfo->getHeadCommitDate();
- if ( $gitHeadCommitDate ) {
- $vcsText .= "<br/>" .
$wgLang->timeanddate( $gitHeadCommitDate, true );
- }
+ $extensionPath = dirname( $extension['path'] );
+ $gitInfo = new GitInfo( $extensionPath );
+ $vcsVersion = $gitInfo->getHeadSHA1();
+ if ( $vcsVersion !== false ) {
+ $vcsVersion = substr( $vcsVersion, 0, 7 );
+ $vcsLink = $gitInfo->getHeadViewUrl();
+ $vcsDate = $gitInfo->getHeadCommitDate();
} else {
- $svnInfo = self::getSvnInfo( dirname(
$extension['path'] ) );
- # Make subversion text/link.
+ $svnInfo = self::getSvnInfo( $extensionPath );
if ( $svnInfo !== false ) {
- $directoryRev = isset(
$svnInfo['directory-rev'] ) ? $svnInfo['directory-rev'] : null;
- $vcsText = $this->msg(
'version-svn-revision', $directoryRev, $svnInfo['checkout-rev'] )->text();
- $vcsText = isset(
$svnInfo['viewvc-url'] ) ? '[' . $svnInfo['viewvc-url'] . " $vcsText]" :
$vcsText;
+ $vcsVersion = $this->msg(
'version-svn-revision', $svnInfo['checkout-rev'] )->text();
+ $vcsLink = isset(
$svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
}
}
}
- # Make main link (or just the name if there is no URL).
- if ( isset( $extension['url'] ) ) {
- $mainLink = "[{$extension['url']} $name]";
- } else {
- $mainLink = $name;
+ if ( $vcsVersion ) {
+ if ( $vcsLink ) {
+ $vcsVerString = Linker::makeExternalLink(
+ $vcsLink,
+ "({$vcsVersion})",
+ true,
+ '',
+ array( 'class' =>
'mw-version-ext-vcs-version' )
+ );
+ } else {
+ $vcsVerString = Xml::openElement( 'span',
array( 'class' => 'mw-version-ext-vcs-version') ) .
+ "({$vcsVersion})" .
+ Xml::closeElement( 'span' );
+ }
+
+ if ( $vcsDate ) {
+ $vcsTimeString = '<br />' .
+ Xml::openElement( 'span', array(
'class' => 'mw-version-ext-vcs-timestamp') ) .
+ $this->getLanguage()->timeanddate(
$vcsDate ) .
+ Xml::closeElement( 'span' );
+ }
+ }
+ $versionString = Xml::span( $canonicalVersion,
'mw-version-ext-version' ) .
+ " {$vcsVerString} {$vcsTimeString}";
+
+ /* --- Get license information if it exists --- */
+ $licenseLink = '';
+ if ( isset( $extension['license-name'] ) ) {
+ $licenseLink = Linker::link(
+ $this->getTitle( 'License/' . $extensionName ),
+ $out->parseInline( $extension['license-name'] ),
+ array( 'class' => 'mw-version-ext-license' )
+ );
+ } elseif ( $this->getExtLicenseFileName( $extensionPath ) ) {
+ $licenseLink = Linker::link(
+ $this->getTitle( 'License/' . $extensionName ),
+ $this->msg( 'version-ext-license' ),
+ array( 'class' => 'mw-version-ext-license' )
+ );
}
- if ( isset( $extension['version'] ) ) {
- $versionText = '<span class="mw-version-ext-version">' .
- $this->msg( 'version-version',
$extension['version'] )->text() .
- '</span>';
- } else {
- $versionText = '';
- }
-
- # Make description text.
- $description = isset( $extension['description'] ) ?
$extension['description'] : '';
-
+ /* --- Description Text --- */
if ( isset( $extension['descriptionmsg'] ) ) {
- # Look for a localized description.
+ // Localized description of extension
$descriptionMsg = $extension['descriptionmsg'];
if ( is_array( $descriptionMsg ) ) {
@@ -529,23 +624,33 @@
} else {
$description = $this->msg( $descriptionMsg
)->text();
}
- }
-
- if ( $vcsText !== false ) {
- $extNameVer = "<tr>
- <td><em>$mainLink $versionText</em></td>
- <td><em>$vcsText</em></td>";
+ } elseif ( isset( $extension['description'] ) ) {
+ // Non localized version
+ $description = $out->parseInline(
$extension['description'] );
} else {
- $extNameVer = "<tr>
- <td colspan=\"2\"><em>$mainLink
$versionText</em></td>";
+ $description = '';
}
+ $description = $out->parseInline( $description );
- $author = isset( $extension['author'] ) ? $extension['author']
: array();
- $extDescAuthor = "<td>$description</td>
- <td>" . $this->listAuthors( $author, false ) . "</td>
- </tr>\n";
+ /* --- Authors list --- */
+ $authors = isset( $extension['author'] ) ? $extension['author']
: array();
+ $authors = $this->listAuthors( $authors, $extensionName,
$extensionPath );
- return $extNameVer . $extDescAuthor;
+ /* === Create the five columned table === */
+ $html = Xml::openElement( 'tr', array(
+ 'class' => 'mw-version-ext',
+ 'id' => "mw-version-ext-{$extensionName}"
+ )
+ );
+
+ $html .= Html::rawElement( 'td', array(), '<b>' .
$extensionNameLink . '</b><br />' . $versionString );
+ $html .= Html::rawElement( 'td', array(), $licenseLink );
+ $html .= Html::rawElement( 'td', array( 'class' =>
'mw-version-ext-description' ), $description );
+ $html .= Html::rawElement( 'td', array( 'class' =>
'mw-version-ext-authors' ), $authors );
+
+ $html .= Xml::closeElement( 'td' );
+
+ return $html;
}
/**
@@ -613,24 +718,120 @@
/**
* Return a formatted unsorted list of authors
*
+ * 'And Others'
+ * If an item in the $authors array is '...' it is assumed to
indicate an
+ * 'and others' string which will then be linked to an
((AUTHORS)|(CREDITS))(\.txt)?
+ * file if it exists in $dir.
+ *
+ * Similarly an entry ending with ' ...]' is assumed to be a link to
an
+ * 'and others' page.
+ *
+ * If no '...' string variant is found, but an authors file is found
an
+ * 'and others' will be added to the end of the credits.
+ *
* @param $authors mixed: string or array of strings
+ * @param $extName string: name of the extension for link creation
+ * @param $extDir string: path to the extension root directory
+ *
* @return String: HTML fragment
*/
- function listAuthors( $authors ) {
+ function listAuthors( $authors, $extName, $extDir ) {
+ $hasOthers = false;
+
$list = array();
foreach ( (array)$authors as $item ) {
if ( $item == '...' ) {
- $list[] = $this->msg(
'version-poweredby-others' )->text();
+ $hasOthers = true;
+ $text = $this->msg( 'version-poweredby-others'
)->text();
+
+ if ( $this->getExtAuthorsFileName( $extDir ) ) {
+ $text = Linker::link(
+ $this->getTitle(
"Credits/$extName" ),
+ $text
+ );
+ }
+ $list[] = $text;
+
} elseif ( substr( $item, -5 ) == ' ...]' ) {
- $list[] = substr( $item, 0, -4 ) . $this->msg(
'version-poweredby-others' )->text() . "]";
+ $hasOthers = true;
+ $list[] = $this->getOutput()->parseinline(
+ substr( $item, 0, -4 ) . $this->msg(
'version-poweredby-others' )->text() . "]"
+ );
+
} else {
- $list[] = $item;
+ $list[] = $this->getOutput()->parseinline(
$item );
}
}
+
+ if ( !$hasOthers && $this->getExtAuthorsFileName( $extDir ) ) {
+ $list[] = $text = Linker::link(
+ $this->getTitle( "Credits/$extName" ),
+ $this->msg( 'version-poweredby-others' )->text()
+ );
+ }
+
return $this->listToText( $list, false );
}
/**
+ * Obtains the full path of an extensions authors or credits file if
+ * one exists.
+ *
+ * @param $extDir string: Path to the extensions root directory
+ *
+ * @since 1.22
+ *
+ * @return bool|string False if no such file exists, otherwise returns
+ * a path to it.
+ */
+ function getExtAuthorsFileName( $extDir ) {
+ if ( !$extDir ) {
+ return false;
+ }
+
+ foreach( scandir( $extDir ) as $file ) {
+ $fullPath = $extDir . DIRECTORY_SEPARATOR . $file;
+ if ( preg_match( '/^((AUTHORS)|(CREDITS))(\.txt)?$/',
$file ) &&
+ is_readable( $fullPath ) &&
+ is_file( $fullPath )
+ ) {
+ return $fullPath;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Obtains the full path of an extensions copying or license file if
+ * one exists.
+ *
+ * @param $extDir string: Path to the extensions root directory
+ *
+ * @since 1.22
+ *
+ * @return bool|string False if no such file exists, otherwise returns
+ * a path to it.
+ */
+ function getExtLicenseFileName( $extDir ) {
+ if ( !$extDir ) {
+ return false;
+ }
+
+ foreach( scandir( $extDir ) as $file ) {
+ $fullPath = $extDir . DIRECTORY_SEPARATOR . $file;
+ if ( preg_match( '/^((COPYING)|(LICENSE))(\.txt)?$/',
$file ) &&
+ is_readable( $fullPath ) &&
+ is_file( $fullPath )
+ ) {
+ return $fullPath;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Convert an array of items into a list for display.
*
* @param array $list of elements to display
diff --git a/languages/messages/MessagesEn.php
b/languages/messages/MessagesEn.php
index bc3a381..61b7b8a 100644
--- a/languages/messages/MessagesEn.php
+++ b/languages/messages/MessagesEn.php
@@ -4792,9 +4792,14 @@
'version-parser-function-hooks' => 'Parser function hooks',
'version-hook-name' => 'Hook name',
'version-hook-subscribedby' => 'Subscribed by',
-'version-version' => '(Version $1)',
-'version-svn-revision' => '(r$2)', # only translate this
message to other languages if you have to change it
-'version-license' => 'License',
+'version-version' => 'Version $1',
+'version-svn-revision' => 'r$1', # only translate this
message to other languages if you have to change it
+'version-license' => 'MediaWiki License',
+'version-license-title' => 'License for $1',
+'version-license-not-found' => 'No detailed license information
was found for this extension.',
+'version-credits-title' => 'Credits for $1',
+'version-credits-not-found' => 'No detailed credits information
was found for this extension.',
+'version-ext-license' => 'License',
'version-poweredby-credits' => "This wiki is powered by
'''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'others',
'version-credits-summary' => 'We would like to recognize the
following persons for their contribution to [[Special:Version|MediaWiki]].',
--
To view, visit https://gerrit.wikimedia.org/r/65299
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I388f3b630462f1909f30751c987f7af585e98881
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Mwalker <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits