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

Reply via email to