From fb4e7a803aed6c4c2a64dc8736ec5a0f166cef60 Mon Sep 17 00:00:00 2001 From: TChin Date: Wed, 13 Oct 2021 14:22:26 -0400 Subject: [PATCH] Add message parameter type for User Groups Bug: T278482 Change-Id: I45da5f73f8920b79b57c02776a05d0268d3480f2 --- includes/language/Language.php | 12 +++++++ includes/language/Message.php | 33 +++++++++++++++++++ includes/libs/Message/MessageValue.php | 11 +++++++ includes/libs/Message/ParamType.php | 7 ++++ includes/specials/SpecialActiveUsers.php | 3 +- includes/user/UserGroupMembership.php | 4 +-- .../includes/Message/TextFormatterTest.php | 25 ++++++++++---- tests/phpunit/includes/MessageTest.php | 15 +++++++++ .../languages/LanguageIntegrationTest.php | 10 ++++++ .../libs/Message/MessageValueTest.php | 10 ++++++ 10 files changed, 121 insertions(+), 9 deletions(-) diff --git a/includes/language/Language.php b/includes/language/Language.php index 786cd148b8a..7dadea4fd2e 100644 --- a/includes/language/Language.php +++ b/includes/language/Language.php @@ -2603,6 +2603,18 @@ class Language { return $ts; } + /** + * Gets the localized friendly name for a group, if it exists. For example, + * "Administrators" or "Bureaucrats" + * + * @param string $group Internal group name + * @return string Localized friendly group name + */ + public function getGroupName( $group ) { + $msg = $this->msg( "group-$group" ); + return $msg->isBlank() ? $group : $msg->text(); + } + /** * @param string $key * @return string|null diff --git a/includes/language/Message.php b/includes/language/Message.php index 80e757e6d1b..2fbe59aab5d 100644 --- a/includes/language/Message.php +++ b/includes/language/Message.php @@ -629,6 +629,26 @@ class Message implements MessageSpecifier, Serializable { return $this; } + /** + * Add parameters that represent user groups + * + * @since 1.38 + * + * @param string|string[] ...$params User Group parameters, or a single argument that is + * an array of user group parameters. + * + * @return Message $this + */ + public function userGroupParams( ...$params ) { + if ( isset( $params[0] ) && is_array( $params[0] ) ) { + $params = $params[0]; + } + foreach ( $params as $param ) { + $this->parameters[] = self::userGroupParam( $param ); + } + return $this; + } + /** * Add parameters that are times and will be passed through * Language::time before substitution @@ -1142,6 +1162,17 @@ class Message implements MessageSpecifier, Serializable { return [ 'time' => $time ]; } + /** + * @since 1.38 + * + * @param string $userGroup + * + * @return string[] Array with a single "group" key. + */ + public static function userGroupParam( string $userGroup ) { + return [ 'group' => $userGroup ]; + } + /** * @since 1.22 * @@ -1268,6 +1299,8 @@ class Message implements MessageSpecifier, Serializable { return [ 'before', $this->getLanguage()->date( $param['date'] ) ]; } elseif ( isset( $param['time'] ) ) { return [ 'before', $this->getLanguage()->time( $param['time'] ) ]; + } elseif ( isset( $param['group'] ) ) { + return [ 'before', $this->getLanguage()->getGroupName( $param['group'] ) ]; } elseif ( isset( $param['period'] ) ) { return [ 'before', $this->getLanguage()->formatTimePeriod( $param['period'] ) ]; } elseif ( isset( $param['size'] ) ) { diff --git a/includes/libs/Message/MessageValue.php b/includes/libs/Message/MessageValue.php index ae4e36da5a0..4abfe6919f4 100644 --- a/includes/libs/Message/MessageValue.php +++ b/includes/libs/Message/MessageValue.php @@ -199,6 +199,17 @@ class MessageValue { return $this->textParamsOfType( ParamType::TIME, ...$values ); } + /** + * Chainable mutator which adds parameters which are a user group (ParamType::GROUP). + * + * @since 1.38 + * @param string ...$values User Groups + * @return $this + */ + public function userGroupParams( ...$values ) { + return $this->textParamsOfType( ParamType::GROUP, ...$values ); + } + /** * Chainable mutator which adds parameters which are a number of bytes (ParamType::SIZE). * diff --git a/includes/libs/Message/ParamType.php b/includes/libs/Message/ParamType.php index a23ca544f7a..8287a707931 100644 --- a/includes/libs/Message/ParamType.php +++ b/includes/libs/Message/ParamType.php @@ -59,6 +59,13 @@ class ParamType { */ public const TIME = 'time'; + /** + * @since 1.38 + * + * User Group + */ + public const GROUP = 'group'; + /** A number of bytes. The output will be rounded to an appropriate magnitude. */ public const SIZE = 'size'; diff --git a/includes/specials/SpecialActiveUsers.php b/includes/specials/SpecialActiveUsers.php index 944b0da47e4..c49ea834bee 100644 --- a/includes/specials/SpecialActiveUsers.php +++ b/includes/specials/SpecialActiveUsers.php @@ -112,8 +112,9 @@ class SpecialActiveUsers extends SpecialPage { $groups = $this->userGroupManager->listAllGroups(); $options = []; + $lang = $this->getLanguage(); foreach ( $groups as $group ) { - $msg = htmlspecialchars( UserGroupMembership::getGroupName( $group ) ); + $msg = htmlspecialchars( $lang->getGroupName( $group ) ); $options[$msg] = $group; } ksort( $options ); diff --git a/includes/user/UserGroupMembership.php b/includes/user/UserGroupMembership.php index 3ed766a9aeb..51adae89070 100644 --- a/includes/user/UserGroupMembership.php +++ b/includes/user/UserGroupMembership.php @@ -164,10 +164,10 @@ class UserGroupMembership { * * @param string $group Internal group name * @return string Localized friendly group name + * @deprecated since 1.38, use Language::getGroupName or Message::userGroupParams */ public static function getGroupName( $group ) { - $msg = wfMessage( "group-$group" ); - return $msg->isBlank() ? $group : $msg->text(); + return RequestContext::getMain()->getLanguage()->getGroupName( $group ); } /** diff --git a/tests/phpunit/includes/Message/TextFormatterTest.php b/tests/phpunit/includes/Message/TextFormatterTest.php index 189a16c0ad9..3f439e5e65d 100644 --- a/tests/phpunit/includes/Message/TextFormatterTest.php +++ b/tests/phpunit/includes/Message/TextFormatterTest.php @@ -77,17 +77,30 @@ class TextFormatterTest extends MediaWikiIntegrationTestCase { $this->assertSame( 'test a, 100 bps $2', $result ); } - public function testFormatMessage() { - $formatter = $this->createTextFormatter( 'en' ); - $mv = ( new MessageValue( 'test' ) ) + public function provideTestFormatMessage() { + yield [ ( new MessageValue( 'test' ) ) ->params( new MessageValue( 'test2', [ 'a', 'b' ] ) ) ->commaListParams( [ 'x', new ScalarParam( ParamType::BITRATE, 100 ), new MessageValue( 'test3', [ 'c', new MessageValue( 'test4', [ 'd', 'e' ] ) ] ) - ] ); - $result = $formatter->format( $mv ); - $this->assertSame( 'test test2 a b x, 100 bps, test3 c test4 d e', $result ); + ] ), + 'test test2 a b x(comma-separator)(bitrate-bits)(comma-separator)test3 c test4 d e' + ]; + + yield [ ( new MessageValue( 'test' ) ) + ->userGroupParams( 'bot' ), + 'test (group-bot) $2' + ]; + } + + /** + * @dataProvider provideTestFormatMessage + */ + public function testFormatMessage( $message, $expected ) { + $formatter = $this->createTextFormatter( 'qqx' ); + $result = $formatter->format( $message ); + $this->assertSame( $expected, $result ); } public function testFormatMessageFormatsWikitext() { diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index 945836449f0..13150cc0ece 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -536,6 +536,21 @@ class MessageTest extends MediaWikiLangTestCase { ); } + /** + * @covers Message::userGroupParam + * @covers Message::userGroupParams + */ + public function testUserGroupParams() { + $lang = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'qqx' ); + $msg = new RawMessage( '$1' ); + $this->setUserLang( $lang ); + $this->assertSame( + '(group-bot)', + $msg->userGroupParams( 'bot' )->plain(), + 'user group is handled correctly' + ); + } + /** * @covers Message::timeperiodParam * @covers Message::timeperiodParams diff --git a/tests/phpunit/languages/LanguageIntegrationTest.php b/tests/phpunit/languages/LanguageIntegrationTest.php index 014e9d88279..540537352f7 100644 --- a/tests/phpunit/languages/LanguageIntegrationTest.php +++ b/tests/phpunit/languages/LanguageIntegrationTest.php @@ -2190,4 +2190,14 @@ class LanguageIntegrationTest extends LanguageClassesTestCase { ], ]; } + + /** + * @covers Language::getGroupName + */ + public function testGetGroupName() { + $lang = $this->getLang(); + $groupName = $lang->getGroupName( 'bot' ); + $this->assertSame( 'Bots', $groupName ); + } + } diff --git a/tests/phpunit/unit/includes/libs/Message/MessageValueTest.php b/tests/phpunit/unit/includes/libs/Message/MessageValueTest.php index 1b69f92cace..9b553a593d4 100644 --- a/tests/phpunit/unit/includes/libs/Message/MessageValueTest.php +++ b/tests/phpunit/unit/includes/libs/Message/MessageValueTest.php @@ -173,6 +173,16 @@ class MessageValueTest extends \PHPUnit\Framework\TestCase { $this->assertSame( $mv, $mv2 ); } + public function testUserGroupParams() { + $mv = new MessageValue( 'key' ); + $mv2 = $mv->userGroupParams( 'bot' ); + $this->assertSame( '' . + "bot" . + '', + $mv->dump() ); + $this->assertSame( $mv, $mv2 ); + } + public function testSizeParams() { $mv = new MessageValue( 'key' ); $mv2 = $mv->sizeParams( 1, 2 );