jenkins-bot has submitted this change and it was merged.
Change subject: API: Add license info to API help output
......................................................................
API: Add license info to API help output
Which also involves some fun magic to figure out which extension a
module belongs to.
Bug: T93994
Change-Id: I236f573d79a5c683ae5714fa311f422c1c147cec
---
M includes/api/ApiBase.php
M includes/api/ApiHelp.php
M includes/api/ApiParamInfo.php
M includes/api/i18n/en.json
M includes/api/i18n/qqq.json
M resources/src/mediawiki/mediawiki.apihelp.css
6 files changed, 172 insertions(+), 18 deletions(-)
Approvals:
Mattflaschen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index 74e51c8..6e289dc 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -98,12 +98,17 @@
*/
const GET_VALUES_FOR_HELP = 1;
+ /** @var array Maps extension paths to info arrays */
+ private static $extensionInfo = null;
+
/** @var ApiMain */
private $mMainModule;
/** @var string */
private $mModuleName, $mModulePrefix;
private $mSlaveDB = null;
private $mParamCache = array();
+ /** @var array|null|bool */
+ private $mModuleSource = false;
/**
* @param ApiMain $mainModule
@@ -2185,6 +2190,93 @@
}
/**
+ * Returns information about the source of this module, if known
+ *
+ * Returned array is an array with the following keys:
+ * - path: Install path
+ * - name: Extension name, or "MediaWiki" for core
+ * - namemsg: (optional) i18n message key for a display name
+ * - license-name: (optional) Name of license
+ *
+ * @return array|null
+ */
+ protected function getModuleSourceInfo() {
+ global $IP;
+
+ if ( $this->mModuleSource !== false ) {
+ return $this->mModuleSource;
+ }
+
+ // First, try to find where the module comes from...
+ $rClass = new ReflectionClass( $this );
+ $path = $rClass->getFileName();
+ if ( !$path ) {
+ // No path known?
+ $this->mModuleSource = null;
+ return null;
+ }
+ $path = realpath( $path ) ?: $path;
+
+ // Build map of extension directories to extension info
+ if ( self::$extensionInfo === null ) {
+ self::$extensionInfo = array(
+ realpath( __DIR__ ) ?: __DIR__ => array(
+ 'path' => $IP,
+ 'name' => 'MediaWiki',
+ 'license-name' => 'GPL-2.0+',
+ ),
+ realpath( "$IP/extensions" ) ?:
"$IP/extensions" => null,
+ );
+ $keep = array(
+ 'path' => null,
+ 'name' => null,
+ 'namemsg' => null,
+ 'license-name' => null,
+ );
+ foreach ( $this->getConfig()->get( 'ExtensionCredits' )
as $group ) {
+ foreach ( $group as $ext ) {
+ if ( !isset( $ext['path'] ) || !isset(
$ext['name'] ) ) {
+ // This shouldn't happen, but
does anyway.
+ continue;
+ }
+
+ $extpath = $ext['path'];
+ if ( !is_dir( $extpath ) ) {
+ $extpath = dirname( $extpath );
+ }
+ self::$extensionInfo[realpath( $extpath
) ?: $extpath] =
+ array_intersect_key( $ext,
$keep );
+ }
+ }
+ foreach (
ExtensionRegistry::getInstance()->getAllThings() as $ext ) {
+ $extpath = $ext['path'];
+ if ( !is_dir( $extpath ) ) {
+ $extpath = dirname( $extpath );
+ }
+ self::$extensionInfo[realpath( $extpath ) ?:
$extpath] =
+ array_intersect_key( $ext, $keep );
+ }
+ }
+
+ // Now traverse parent directories until we find a match or run
out of
+ // parents.
+ do {
+ if ( array_key_exists( $path, self::$extensionInfo ) ) {
+ // Found it!
+ $this->mModuleSource =
self::$extensionInfo[$path];
+ return $this->mModuleSource;
+ }
+
+ $oldpath = $path;
+ $path = dirname( $path );
+ } while ( $path !== $oldpath );
+
+ // No idea what extension this might be.
+ $this->mModuleSource = null;
+ return null;
+ }
+
+ /**
* Called from ApiHelp before the pieces are joined together and
returned.
*
* This exists mainly for ApiMain to add the Permissions and Credits
diff --git a/includes/api/ApiHelp.php b/includes/api/ApiHelp.php
index dd05f45..d2d5e7c 100644
--- a/includes/api/ApiHelp.php
+++ b/includes/api/ApiHelp.php
@@ -277,25 +277,55 @@
);
}
- $flags = $module->getHelpFlags();
- if ( $flags ) {
- $help['flags'] .= Html::openElement( 'div',
- array( 'class' => 'apihelp-block
apihelp-flags' ) );
- $msg = $context->msg( 'api-help-flags' );
- if ( !$msg->isDisabled() ) {
- $help['flags'] .= self::wrap(
- $msg->numParams( count( $flags
) ), 'apihelp-block-head', 'div'
- );
- }
- $help['flags'] .= Html::openElement( 'ul' );
- foreach ( $flags as $flag ) {
- $help['flags'] .= Html::rawElement(
'li', null,
- self::wrap( $context->msg(
"api-help-flag-$flag" ), "apihelp-flag-$flag" )
- );
- }
- $help['flags'] .= Html::closeElement( 'ul' );
- $help['flags'] .= Html::closeElement( 'div' );
+ $help['flags'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-flags'
) );
+ $msg = $context->msg( 'api-help-flags' );
+ if ( !$msg->isDisabled() ) {
+ $help['flags'] .= self::wrap(
+ $msg->numParams( count( $flags ) ),
'apihelp-block-head', 'div'
+ );
}
+ $help['flags'] .= Html::openElement( 'ul' );
+ foreach ( $module->getHelpFlags() as $flag ) {
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap( $context->msg(
"api-help-flag-$flag" ), "apihelp-flag-$flag" )
+ );
+ }
+ $sourceInfo = $module->getModuleSourceInfo();
+ if ( $sourceInfo ) {
+ if ( isset( $sourceInfo['namemsg'] ) ) {
+ $extname = $context->msg(
$sourceInfo['namemsg'] )->text();
+ } else {
+ $extname = $sourceInfo['name'];
+ }
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap(
+ $context->msg(
'api-help-source', $extname, $sourceInfo['name'] ),
+ 'apihelp-source'
+ )
+ );
+
+ $link = SpecialPage::getTitleFor( 'Version',
'License/' . $sourceInfo['name'] );
+ if ( isset( $sourceInfo['license-name'] ) ) {
+ $msg = $context->msg(
'api-help-license', $link, $sourceInfo['license-name'] );
+ } elseif (
SpecialVersion::getExtLicenseFileName( dirname( $sourceInfo['path'] ) ) ) {
+ $msg = $context->msg(
'api-help-license-noname', $link );
+ } else {
+ $msg = $context->msg(
'api-help-license-unknown' );
+ }
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap( $msg, 'apihelp-license' )
+ );
+ } else {
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap( $context->msg(
'api-help-source-unknown' ), 'apihelp-source' )
+ );
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap( $context->msg(
'api-help-license-unknown' ), 'apihelp-license' )
+ );
+ }
+ $help['flags'] .= Html::closeElement( 'ul' );
+ $help['flags'] .= Html::closeElement( 'div' );
foreach ( $module->getFinalDescription() as $msg ) {
$msg->setContext( $context );
diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php
index f0a5daf..bb4967b 100644
--- a/includes/api/ApiParamInfo.php
+++ b/includes/api/ApiParamInfo.php
@@ -195,6 +195,24 @@
}
$ret['prefix'] = $module->getModulePrefix();
+ $sourceInfo = $module->getModuleSourceInfo();
+ if ( $sourceInfo ) {
+ $ret['source'] = $sourceInfo['name'];
+ if ( isset( $sourceInfo['namemsg'] ) ) {
+ $ret['sourcename'] = $this->context->msg(
$sourceInfo['namemsg'] )->text();
+ } else {
+ $ret['sourcename'] = $ret['source'];
+ }
+
+ $link = SpecialPage::getTitleFor( 'Version', 'License/'
. $sourceInfo['name'] )->getFullUrl();
+ if ( isset( $sourceInfo['license-name'] ) ) {
+ $ret['licensetag'] =
$sourceInfo['license-name'];
+ $ret['licenselink'] = (string)$link;
+ } elseif ( SpecialVersion::getExtLicenseFileName(
dirname( $sourceInfo['path'] ) ) ) {
+ $ret['licenselink'] = (string)$link;
+ }
+ }
+
$this->formatHelpMessages( $ret, 'description',
$module->getFinalDescription() );
foreach ( $module->getHelpFlags() as $flag ) {
diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json
index 9d0663c..d1d408f 100644
--- a/includes/api/i18n/en.json
+++ b/includes/api/i18n/en.json
@@ -1121,6 +1121,11 @@
"api-help-flag-writerights": "This module requires write rights.",
"api-help-flag-mustbeposted": "This module only accepts POST requests.",
"api-help-flag-generator": "This module can be used as a generator.",
+ "api-help-source": "Source: $1",
+ "api-help-source-unknown": "Source: <span
class=\"apihelp-unknown\">unknown</span>",
+ "api-help-license": "License: [[$1|$2]]",
+ "api-help-license-noname": "License: [[$1|See link]]",
+ "api-help-license-unknown": "License: <span
class=\"apihelp-unknown\">unknown</span>",
"api-help-help-urls": "",
"api-help-parameters": "{{PLURAL:$1|Parameter|Parameters}}:",
"api-help-param-deprecated": "Deprecated.",
diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json
index 05b7722..5ef5b3d 100644
--- a/includes/api/i18n/qqq.json
+++ b/includes/api/i18n/qqq.json
@@ -1023,6 +1023,11 @@
"api-help-flag-writerights": "Flag displayed for an API module that
requires write rights",
"api-help-flag-mustbeposted": "Flag displayed for an API module that
only accepts POST requests",
"api-help-flag-generator": "Flag displayed for an API module that can
be used as a generator",
+ "api-help-source": "Displayed in the flags box to indicate the source
of an API module.\n\nParameters:\n* $1 - Possibly-localised extension name, or
\"MediaWiki\" if it's a core module\n* $2 - Non-localised extension
name.\n\nSee also:\n* {{msg-mw|api-help-source-unknown}}",
+ "api-help-source-unknown": "Displayed in the flags box to indicate that
the source of an API module is not known.\n\nSee also:\n*
{{msg-mw|api-help-source}}",
+ "api-help-license": "Displayed in the flags box to indicate the license
of an API module.\n\nParameters:\n* $1 - Page to link to display the full
license text\n* $2 - Display text for the link\n\nSee also:\n*
{{msg-mw|api-help-license-noname}}\n* {{msg-mw|api-help-license-unknown}}",
+ "api-help-license-noname": "Displayed in the flags box to indicate the
license of an API module, when the tag for the license is not
known.\n\nParameters:\n* $1 - Page to link to display the full license
text\n\nSee also:\n* {{msg-mw|api-help-license}}\n*
{{msg-mw|api-help-license-unknown}}",
+ "api-help-license-unknown": "Displayed in the flags box to indicate
that the license of the API module is not known.\n\nSee also:\n*
{{msg-mw|api-help-license}}\n* {{msg-mw|api-help-license-noname}}",
"api-help-help-urls": "{{optional}} Label for the API help urls
section\n\nParameters:\n* $1 - Number of urls to be displayed",
"api-help-parameters": "Label for the API help parameters
section\n\nParameters:\n* $1 - Number of parameters to be
displayed\n{{Identical|Parameter}}",
"api-help-param-deprecated": "Displayed in the API help for any
deprecated parameter\n{{Identical|Deprecated}}",
diff --git a/resources/src/mediawiki/mediawiki.apihelp.css
b/resources/src/mediawiki/mediawiki.apihelp.css
index d127232..7d7b413 100644
--- a/resources/src/mediawiki/mediawiki.apihelp.css
+++ b/resources/src/mediawiki/mediawiki.apihelp.css
@@ -29,6 +29,10 @@
color: red;
}
+.apihelp-unknown {
+ color: #888;
+}
+
.apihelp-empty {
color: #888;
}
--
To view, visit https://gerrit.wikimedia.org/r/202415
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I236f573d79a5c683ae5714fa311f422c1c147cec
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Mattflaschen <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits