Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/88251
Change subject: Added Special:MWOAuthListConsumers page
......................................................................
Added Special:MWOAuthListConsumers page
* Added convenience links here from the management page
Change-Id: I3bb759ee5c93d7496d05c6bdfac0b5d6d3cfe695
---
M OAuth.setup.php
M backend/MWOAuthConsumer.php
M frontend/MWOAuthUI.setup.php
M frontend/language/MWOAuth.alias.php
M frontend/language/MWOAuth.i18n.php
A frontend/specialpages/SpecialMWOAuthListConsumers.php
M frontend/specialpages/SpecialMWOAuthManageConsumers.php
7 files changed, 450 insertions(+), 2 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/OAuth
refs/changes/51/88251/1
diff --git a/OAuth.setup.php b/OAuth.setup.php
index d1a4bcf..c496299 100644
--- a/OAuth.setup.php
+++ b/OAuth.setup.php
@@ -41,6 +41,8 @@
"$specialsDir/SpecialMWOAuthManageConsumers.php";
$classes['SpecialMWOAuthManageMyGrants'] =
"$specialsDir/SpecialMWOAuthManageMyGrants.php";
+ $classes['SpecialMWOAuthListConsumers'] =
+ "$specialsDir/SpecialMWOAuthListConsumers.php";
# Utility functions
$classes['MWOAuthUtils'] = "$backendDir/MWOAuthUtils.php";
diff --git a/backend/MWOAuthConsumer.php b/backend/MWOAuthConsumer.php
index 3a9983c..c1eb5a8 100644
--- a/backend/MWOAuthConsumer.php
+++ b/backend/MWOAuthConsumer.php
@@ -169,6 +169,19 @@
}
/**
+ * @return array
+ */
+ public static function getAllStages() {
+ return array(
+ MWOAuthConsumer::STAGE_PROPOSED,
+ MWOAuthConsumer::STAGE_REJECTED,
+ MWOAuthConsumer::STAGE_EXPIRED,
+ MWOAuthConsumer::STAGE_APPROVED,
+ MWOAuthConsumer::STAGE_DISABLED,
+ );
+ }
+
+ /**
* @param string $verifyCode verification code
* @param string $requestKey original request key from /initiate
* @return string the url for redirection
diff --git a/frontend/MWOAuthUI.setup.php b/frontend/MWOAuthUI.setup.php
index c05dd43..65e2981 100644
--- a/frontend/MWOAuthUI.setup.php
+++ b/frontend/MWOAuthUI.setup.php
@@ -47,6 +47,8 @@
$wgSpecialPageGroups['MWOAuthConsumerRegistration'] =
'users';
$wgSpecialPages['MWOAuthManageConsumers'] =
'SpecialMWOAuthManageConsumers';
$wgSpecialPageGroups['MWOAuthManageConsumers'] =
'users';
+ $wgSpecialPages['MWOAuthListConsumers'] =
'SpecialMWOAuthListConsumers';
+ $wgSpecialPageGroups['MWOAuthListConsumers'] = 'users';
$wgLogTypes[] = 'mwoauthconsumer';
$wgLogNames['mwoauthconsumer'] =
'mwoauthconsumer-consumer-logpage';
diff --git a/frontend/language/MWOAuth.alias.php
b/frontend/language/MWOAuth.alias.php
index 2df63e8..d4c1593 100644
--- a/frontend/language/MWOAuth.alias.php
+++ b/frontend/language/MWOAuth.alias.php
@@ -12,6 +12,7 @@
$specialPageAliases['en'] = array(
'MWOAuthConsumerRegistration' => array( 'MWOAuthConsumerRegistration',
'OAuthRegistration' ),
'MWOAuthManageConsumers' => array( 'MWOAuthManageConsumers',
'OAuthManageConsumers' ),
+ 'MWOAuthListConsumers' => array( 'MWOAuthListConsumers',
'OAuthListConsumers' ),
'MWOAuthManageMyGrants' => array( 'MWOAuthManageMyGrants',
'OAuthGrants' ),
'MWOAuth' => array( 'MWOAuth', 'OAuth' ),
);
diff --git a/frontend/language/MWOAuth.i18n.php
b/frontend/language/MWOAuth.i18n.php
index 84220a2..57d4047 100644
--- a/frontend/language/MWOAuth.i18n.php
+++ b/frontend/language/MWOAuth.i18n.php
@@ -152,6 +152,28 @@
'mwoauthmanageconsumers-success-rejected' => 'Request has been
rejected.',
'mwoauthmanageconsumers-success-disabled' => 'Consumer has been
disabled.',
'mwoauthmanageconsumers-success-reanable' => 'Consumer has been
re-enabled.',
+ 'mwoauthmanageconsumers-search-name' => 'consumers with this name',
+ 'mwoauthmanageconsumers-search-publisher' => 'consumers by this user',
+
+ 'mwoauthlistconsumers' => 'List OAuth consumers',
+ 'mwoauthlistconsumers-legend' => 'Browse OAuth consumers',
+ 'mwoauthlistconsumers-view' => 'details',
+ 'mwoauthlistconsumers-none' => 'No consumers found meeting this
criteria.',
+ 'mwoauthlistconsumers-name' => 'Application name',
+ 'mwoauthlistconsumers-version' => 'Consumer version',
+ 'mwoauthlistconsumers-user' => 'Publisher',
+ 'mwoauthlistconsumers-description' => 'Description',
+ 'mwoauthlistconsumers-wiki' => 'Applicable wiki',
+ 'mwoauthlistconsumers-callbackurl' => 'OAuth "callback URL"',
+ 'mwoauthlistconsumers-grants' => 'Applicable grants',
+ 'mwoauthlistconsumers-basicgrantsonly' => '(basic access only)',
+ 'mwoauthlistconsumers-status' => 'Status',
+ 'mwoauth-consumer-stage-any' => 'any',
+ 'mwoauthlistconsumers-status-proposed' => 'proposed',
+ 'mwoauthlistconsumers-status-approved' => 'approved',
+ 'mwoauthlistconsumers-status-disabled' => 'disabled',
+ 'mwoauthlistconsumers-status-rejected' => 'rejected',
+ 'mwoauthlistconsumers-status-expired' => 'expired',
'mwoauthmanagemygrants' => 'Manage account OAuth grants',
'mwoauthmanagemygrants-notloggedin' => 'You have to be logged in to
access this page.',
@@ -829,6 +851,28 @@
'action-mwoauthproposeconsumer' =>
'{{Doc-action|mwoauthproposeconsumer}}',
'action-mwoauthupdateownconsumer' =>
'{{Doc-action|mwoauthupdateownconsumer}}',
'action-mwoauthviewsuppressed' =>
'{{Doc-action|mwoauthviewsuppressed}}',
+
+ 'mwoauthmanageconsumers-search-name' => 'Link to search for consumers
with the same name',
+ 'mwoauthmanageconsumers-search-publisher' => 'Link to search for
consumers by the same user',
+ 'mwoauthlistconsumers' => 'Used as special page name',
+ 'mwoauthlistconsumers-view' => 'Link to view consumer details',
+ 'mwoauthlistconsumers-none' => 'Shown when a list of consumers is
empty',
+ 'mwoauthlistconsumers-name' => 'Used as a field name in consumer lists',
+ 'mwoauthlistconsumers-user' => 'Used as a field name in consumer lists',
+ 'mwoauthlistconsumers-description' => 'Used as a field name in consumer
lists',
+ 'mwoauthlistconsumers-wiki' => 'Used as a field name in consumer lists',
+ 'mwoauthlistconsumers-status' => 'Used as a field name in consumer
lists',
+ 'mwoauth-consumer-stage-any' => 'Used as special selector field for
"all consumer states"',
+ 'mwoauthlistconsumers-status-proposed' =>
'{{Related|Mwoauth-consumer-stage}}',
+ 'mwoauthlistconsumers-status-approved' =>
'{{Related|Mwoauth-consumer-stage}}',
+ 'mwoauthlistconsumers-status-disabled' =>
'{{Related|Mwoauth-consumer-stage}}',
+ 'mwoauthlistconsumers-status-rejected' =>
'{{Related|Mwoauth-consumer-stage}}',
+ 'mwoauthlistconsumers-status-expired' =>
'{{Related|Mwoauth-consumer-stage}}',
+ 'mwoauthlistconsumers-legend' => 'Legend used for filter form fieldset',
+ 'mwoauthlistconsumers-version' => 'Used as a field name in consumer
lists',
+ 'mwoauthlistconsumers-callbackurl' => 'Used as a field name in consumer
lists',
+ 'mwoauthlistconsumers-grants' => 'Used as a field name in consumer
lists',
+ 'mwoauthlistconsumers-basicgrantsonly' => 'Message used when only
hidden grants are used by a consumer (or none at all)',
);
/** Asturian (asturianu)
diff --git a/frontend/specialpages/SpecialMWOAuthListConsumers.php
b/frontend/specialpages/SpecialMWOAuthListConsumers.php
new file mode 100644
index 0000000..34deb0c
--- /dev/null
+++ b/frontend/specialpages/SpecialMWOAuthListConsumers.php
@@ -0,0 +1,365 @@
+<?php
+/*
+ (c) Aaron Schulz 2013, GPL
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ http://www.gnu.org/copyleft/gpl.html
+*/
+
+/**
+ * Special page for listing the queue of consumer requests and managing
+ * their approval/rejection and also for listing approved/disabled consumers
+ */
+class SpecialMWOAuthListConsumers extends SpecialPage {
+ protected static $stageKeyMap = array(
+ MWOAuthConsumer::STAGE_PROPOSED => 'proposed',
+ MWOAuthConsumer::STAGE_REJECTED => 'rejected',
+ MWOAuthConsumer::STAGE_EXPIRED => 'expired',
+ MWOAuthConsumer::STAGE_APPROVED => 'approved',
+ MWOAuthConsumer::STAGE_DISABLED => 'disabled',
+ );
+
+ public function __construct() {
+ parent::__construct( 'MWOAuthListConsumers' );
+ }
+
+ public function execute( $par ) {
+ $this->setHeaders();
+
+ // Format is
Special:MWOAuthListConsumers[/list|/view/[<consumer key>]]
+ $navigation = explode( '/', $par );
+ $type = isset( $navigation[0] ) ? $navigation[0] : null;
+ $consumerKey = isset( $navigation[1] ) ? $navigation[1] : null;
+
+ $this->showConsumerListForm();
+
+ switch ( $type ) {
+ case 'view':
+ $this->showConsumerInfo( $consumerKey );
+ break;
+ default:
+ $this->showConsumerList();
+ break;
+ }
+
+ $this->getOutput()->addModuleStyles( 'ext.MWOAuth.BasicStyles'
);
+ }
+
+ /**
+ * Show the form to approve/reject/disable/re-enable consumers
+ *
+ * @param string $consumerKey
+ * @throws PermissionsError
+ */
+ protected function showConsumerInfo( $consumerKey ) {
+ $user = $this->getUser();
+
+ $dbr = MWOAuthUtils::getCentralDB( DB_SLAVE );
+ $cmr = MWOAuthDAOAccessControl::wrap(
+ MWOAuthConsumer::newFromKey( $dbr, $consumerKey ),
$this->getContext() );
+ if ( !$cmr ) {
+ $this->getOutput()->addWikiMsg(
'mwoauth-invalid-consumer-key' );
+ return;
+ } elseif ( $cmr->get( 'deleted' ) && !$user->isAllowed(
'mwoauthviewsuppressed' ) ) {
+ throw new PermissionsError( 'mwoauthviewsuppressed' );
+ }
+
+ // @TODO: this is similar to getGrantsWikiText()
+ $s = '';
+ foreach ( MWOAuthUtils::getGrantGroups( $cmr->get( 'grants' ) )
as $group => $grants ) {
+ if ( $group === 'hidden' ) {
+ continue; // implicitly granted
+ }
+ $s .= "*<strong>" . wfMessage(
"mwoauth-grant-group-$group" )->text() . "</strong>\n";
+ $s .= ":" . $this->getLanguage()->semicolonList(
+ array_map( 'MWOAuthUtils::grantName', $grants )
) . "\n";
+ }
+ if ( $s == '' ) {
+ $s = wfMessage( 'mwoauthlistconsumers-basicgrantsonly'
)->text();
+ } else {
+ $s .= "\n";
+ }
+
+ $stageKey = self::$stageKeyMap[$cmr->get( 'stage' )];
+ $data = array(
+ 'mwoauthlistconsumers-name' => htmlspecialchars(
+ $cmr->get( 'name' )
+ ),
+ 'mwoauthlistconsumers-version' => htmlspecialchars(
+ $cmr->get( 'version' )
+ ),
+ 'mwoauthlistconsumers-user' => htmlspecialchars(
+ $cmr->get( 'userId',
'MWOAuthUtils::getCentralUserNameFromId' )
+ ),
+ 'mwoauthlistconsumers-status' => htmlspecialchars(
+ wfMessage(
"mwoauthlistconsumers-status-$stageKey" )
+ ),
+ 'mwoauthlistconsumers-description' => htmlspecialchars(
+ $cmr->get( 'description' )
+ ),
+ 'mwoauthlistconsumers-wiki' => htmlspecialchars(
+ $cmr->get( 'wiki',
'MWOAuthUtils::getWikiIdName' )
+ ),
+ 'mwoauthlistconsumers-callbackurl' => htmlspecialchars(
+ $cmr->get( 'callbackUrl' )
+ ),
+ 'mwoauthlistconsumers-grants' =>
$this->getOutput()->parseInline( $s ),
+ );
+
+ $r = '';
+ foreach ( $data as $msg => $encValue ) {
+ $r .= '<p><b>' . $this->msg( $msg )->escaped() . '</b>:
' . $encValue . '</p>';
+ }
+
+ $this->getOutput()->addHtml( $r );
+ }
+
+ /**
+ * Show a form for the paged list of consumers
+ */
+ protected function showConsumerListForm() {
+ $form = new HTMLForm(
+ array(
+ 'name' => array(
+ 'name' => 'name',
+ 'type' => 'text',
+ 'label-message' =>
'mwoauth-consumer-name',
+ 'required' => false,
+ ),
+ 'publisher' => array(
+ 'name' => 'publisher',
+ 'type' => 'text',
+ 'label-message' =>
'mwoauth-consumer-user',
+ 'required' => false
+ ),
+ 'stage' => array(
+ 'name' => 'stage',
+ 'type' => 'select',
+ 'label-message' =>
'mwoauth-consumer-stage',
+ 'options' => array(
+ wfMessage(
'mwoauth-consumer-stage-any' )->escaped() => -1,
+ wfMessage(
'mwoauth-consumer-stage-proposed' )->escaped()
+ =>
MWOAuthConsumer::STAGE_PROPOSED,
+ wfMessage(
'mwoauth-consumer-stage-approved' )->escaped()
+ =>
MWOAuthConsumer::STAGE_APPROVED,
+ wfMessage(
'mwoauth-consumer-stage-rejected' )->escaped()
+ =>
MWOAuthConsumer::STAGE_REJECTED,
+ wfMessage(
'mwoauth-consumer-stage-disabled' )->escaped()
+ =>
MWOAuthConsumer::STAGE_DISABLED,
+ wfMessage(
'mwoauth-consumer-stage-expired' )->escaped()
+ =>
MWOAuthConsumer::STAGE_EXPIRED
+ ),
+ 'default' =>
MWOAuthConsumer::STAGE_APPROVED,
+ 'required' => false
+ )
+ ),
+ $this->getContext()
+ );
+ $form->setAction( $this->getTitle()->getFullUrl() ); // always
go back to listings
+ $form->setSubmitCallback( function() { return false; } );
+ $form->setMethod( 'get' );
+ $form->setSubmitTextMsg( 'go' );
+ $form->setWrapperLegendMsg( 'mwoauthlistconsumers-legend' );
+ $form->show();
+ }
+
+ /**
+ * Show a paged list of consumers with links to details
+ */
+ protected function showConsumerList() {
+ $request = $this->getRequest();
+
+ $name = $request->getVal( 'name', '' );
+ $stage = $request->getInt( 'stage', -1 );
+ if ( $request->getVal( 'publisher', '' ) !== '' ) {
+ // @TODO: make a MWOAuthUtils::getCentralIdFromUserName
method
+ // This page is only on the central wiki, so this works
though.
+ $lUser = User::newFromName( $request->getVal(
'publisher' ) );
+ $centralId = $lUser ?
MWOAuthUtils::getCentralIdFromLocalUser( $lUser ) : 0;
+ } else {
+ $centralId = null;
+ }
+
+ $pager = new MWOAuthListConsumersPager( $this, array(), $name,
$centralId, $stage );
+ if ( $pager->getNumRows() ) {
+ $this->getOutput()->addHTML( $pager->getNavigationBar()
);
+ $this->getOutput()->addHTML( $pager->getBody() );
+ $this->getOutput()->addHTML( $pager->getNavigationBar()
);
+ } else {
+ // Messages: mwoauthlistconsumers-none-proposed,
mwoauthlistconsumers-none-rejected,
+ // mwoauthlistconsumers-none-expired,
mwoauthlistconsumers-none-approved,
+ // mwoauthlistconsumers-none-disabled
+ $this->getOutput()->addWikiMsg(
"mwoauthlistconsumers-none" );
+ }
+ # Every 30th view, prune old deleted items
+ if ( 0 == mt_rand( 0, 29 ) ) {
+ MWOAuthUtils::runAutoMaintenance(
MWOAuthUtils::getCentralDB( DB_MASTER ) );
+ }
+ }
+
+ /**
+ * @param DBConnRef $db
+ * @param sdtclass $row
+ * @return string
+ */
+ public function formatRow( DBConnRef $db, $row ) {
+ $cmr = MWOAuthDAOAccessControl::wrap(
+ MWOAuthConsumer::newFromRow( $db, $row ),
$this->getContext() );
+
+ $cmrKey = $cmr->get( 'consumerKey' );
+ $stageKey = self::$stageKeyMap[$cmr->get( 'stage' )];
+
+ $link = Linker::linkKnown(
+ $this->getTitle( "view/{$cmrKey}" ),
+ $this->msg( 'mwoauthlistconsumers-view' )->escaped(),
+ array(),
+ $this->getRequest()->getValues( 'name', 'publisher',
'stage' ) // stick
+ );
+
+ $time = $this->getLanguage()->timeanddate(
+ wfTimestamp( TS_MW, $cmr->get( 'registration' ) ), true
);
+
+ $encStageKey = htmlspecialchars( $stageKey ); // sanity
+ $r = "<li class='mw-mwoauthlistconsumers-{$encStageKey}'>";
+
+ $name = $cmr->get( 'name', function( $s ) use ( $cmr ) {
+ return $s . ' [' . $cmr->get( 'version' ) . ']'; } );
+ $r .= "<strong>" . htmlspecialchars( $name ) . "</strong>
(<strong>{$link}</strong>)";
+
+ $lang = $this->getLanguage();
+ $data = array(
+ 'mwoauthlistconsumers-user' => htmlspecialchars(
+ $cmr->get( 'userId',
'MWOAuthUtils::getCentralUserNameFromId' )
+ ),
+ 'mwoauthlistconsumers-description' => htmlspecialchars(
+ $cmr->get( 'description', function( $s ) use (
$lang ) {
+ return $lang->truncate( $s, 10024 ); } )
+ ),
+ 'mwoauthlistconsumers-wiki' => htmlspecialchars(
+ $cmr->get( 'wiki',
'MWOAuthUtils::getWikiIdName' )
+ ),
+ 'mwoauthlistconsumers-status' => htmlspecialchars(
+ wfMessage(
"mwoauthlistconsumers-status-$stageKey" )
+ )
+ );
+
+ foreach ( $data as $msg => $encValue ) {
+ $r .= '<p>' . $this->msg( $msg )->escaped() . ': ' .
$encValue . '</p>';
+ }
+
+ $r .= '</li>';
+
+ return $r;
+ }
+}
+
+/**
+ * Query to list out consumers
+ *
+ * @TODO: use UserCache
+ */
+class MWOAuthListConsumersPager extends AlphabeticPager {
+ public $mForm, $mConds;
+
+ function __construct( $form, $conds, $name, $centralUserID, $stage ) {
+ $this->mForm = $form;
+ $this->mConds = $conds;
+
+ $this->mIndexField = null;
+ if ( $name !== '' ) {
+ $this->mConds['oarc_name'] = $name;
+ $this->mIndexField = 'oarc_id';
+ }
+ if ( $centralUserID !== null ) {
+ $this->mConds['oarc_user_id'] = $centralUserID;
+ $this->mIndexField = 'oarc_id';
+ }
+ if ( $stage >= 0 ) {
+ $this->mConds['oarc_stage'] = $stage;
+ if ( !$this->mIndexField ) {
+ $this->mIndexField = 'oarc_stage_timestamp';
+ }
+ }
+ if ( !$this->mIndexField ) {
+ $this->mIndexField = 'oarc_id';
+ }
+
+ if ( !$this->getUser()->isAllowed( 'mwoauthviewsuppressed' ) ) {
+ $this->mConds['oarc_deleted'] = 0;
+ }
+
+ $this->mDb = MWOAuthUtils::getCentralDB( DB_SLAVE );
+ parent::__construct();
+
+ # Treat 20 as the default limit, since each entry takes up 5
rows.
+ $urlLimit = $this->mRequest->getInt( 'limit' );
+ $this->mLimit = $urlLimit ? $urlLimit : 20;
+ }
+
+ /**
+ * @return Title
+ */
+ function getTitle() {
+ return $this->mForm->getFullTitle();
+ }
+
+ /**
+ * @param $row
+ * @return string
+ */
+ function formatRow( $row ) {
+ return $this->mForm->formatRow( $this->mDb, $row );
+ }
+
+ /**
+ * @return string
+ */
+ function getStartBody() {
+ if ( $this->getNumRows() ) {
+ return '<ul>';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * @return string
+ */
+ function getEndBody() {
+ if ( $this->getNumRows() ) {
+ return '</ul>';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * @return array
+ */
+ function getQueryInfo() {
+ return array(
+ 'tables' => array( 'oauth_registered_consumer' ),
+ 'fields' => array( '*' ),
+ 'conds' => $this->mConds
+ );
+ }
+
+ /**
+ * @return string
+ */
+ function getIndexField() {
+ return $this->mIndexField;
+ }
+}
diff --git a/frontend/specialpages/SpecialMWOAuthManageConsumers.php
b/frontend/specialpages/SpecialMWOAuthManageConsumers.php
index 9617f15..ac6c167 100644
--- a/frontend/specialpages/SpecialMWOAuthManageConsumers.php
+++ b/frontend/specialpages/SpecialMWOAuthManageConsumers.php
@@ -247,7 +247,17 @@
'name' => array(
'type' => 'info',
'label-message' =>
'mwoauth-consumer-name',
- 'default' => $cmr->get( 'name' )
+ 'default' => $cmr->get( 'name',
function( $s ) {
+ $link = Linker::linkKnown(
+
SpecialPage::getTitleFor( 'MWOAuthListConsumers' ),
+ wfMessage(
'mwoauthmanageconsumers-search-name' )->escaped(),
+ array(),
+ array( 'name' => $s )
+ );
+ return htmlspecialchars( $s ) .
' ' .
+ wfMessage(
'parentheses' )->rawParams( $link )->escaped();
+ } ),
+ 'raw' => true
),
'version' => array(
'type' => 'info',
@@ -257,7 +267,18 @@
'user' => array(
'type' => 'info',
'label-message' =>
'mwoauth-consumer-user',
- 'default' => $cmr->get( 'userId',
'MWOAuthUtils::getCentralUserNameFromId' )
+ 'default' => $cmr->get( 'userId',
function( $s ) {
+ $name =
MWOAuthUtils::getCentralUserNameFromId( $s );
+ $link = Linker::linkKnown(
+ $title =
SpecialPage::getTitleFor( 'MWOAuthListConsumers' ),
+ wfMessage(
'mwoauthmanageconsumers-search-publisher' )->escaped(),
+ array(),
+ array( 'publisher' =>
$name )
+ );
+ return htmlspecialchars( $name
) . ' ' .
+ wfMessage(
'parentheses' )->rawParams( $link )->escaped();
+ } ),
+ 'raw' => true
),
'description' => array(
'type' => 'info',
--
To view, visit https://gerrit.wikimedia.org/r/88251
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3bb759ee5c93d7496d05c6bdfac0b5d6d3cfe695
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/OAuth
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits