Add Message/MessageValue user group member parameter type
* Added ParamType::OBJECT, which allows Stringable objects to be passed into MessageValue Bug: T278482 Change-Id: Ib4990f87d4ad70b7525d7aa05c8b97e90c121674
This commit is contained in:
parent
80d3ece54a
commit
349819dc5a
11 changed files with 211 additions and 11 deletions
52
includes/Message/UserGroupMembershipParam.php
Normal file
52
includes/Message/UserGroupMembershipParam.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Represents a Message/MessageValue parameter user group membership to be used with ParamType::OBJECT.
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Message;
|
||||
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use Stringable;
|
||||
|
||||
class UserGroupMembershipParam implements Stringable {
|
||||
/** @var string */
|
||||
private $group;
|
||||
|
||||
/** @var UserIdentity */
|
||||
private $member;
|
||||
|
||||
public function __construct( string $group, UserIdentity $member ) {
|
||||
$this->group = $group;
|
||||
$this->member = $member;
|
||||
}
|
||||
|
||||
public function getGroup(): string {
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
public function getMember(): UserIdentity {
|
||||
return $this->member;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->group . ':' . $this->member->getName();
|
||||
}
|
||||
}
|
||||
|
|
@ -899,10 +899,11 @@ class Language {
|
|||
* Get message object in this language. Only for use inside this class.
|
||||
*
|
||||
* @param string $msg Message name
|
||||
* @param mixed ...$params Message parameters
|
||||
* @return Message
|
||||
*/
|
||||
protected function msg( $msg ) {
|
||||
return wfMessage( $msg )->inLanguage( $this );
|
||||
protected function msg( $msg, ...$params ) {
|
||||
return wfMessage( $msg, ...$params )->inLanguage( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2615,6 +2616,22 @@ class Language {
|
|||
return $msg->isBlank() ? $group : $msg->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the localized name for a member of a group, if it exists. For example,
|
||||
* "administrator" or "bureaucrat"
|
||||
*
|
||||
* @param string $group Internal group name
|
||||
* @param string|UserIdentity $member
|
||||
* @return string Localized name for group member
|
||||
*/
|
||||
public function getGroupMemberName( string $group, $member ) {
|
||||
if ( $member instanceof UserIdentity ) {
|
||||
$member = $member->getName();
|
||||
}
|
||||
$msg = $this->msg( "group-$group-member", $member );
|
||||
return $msg->isBlank() ? $group : $msg->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return string|null
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Message\UserGroupMembershipParam;
|
||||
use MediaWiki\Page\PageReference;
|
||||
use MediaWiki\Page\PageReferenceValue;
|
||||
|
||||
|
|
@ -649,6 +650,26 @@ class Message implements MessageSpecifier, Serializable {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add parameters that represent stringable objects
|
||||
*
|
||||
* @since 1.38
|
||||
*
|
||||
* @param Stringable|Stringable[] ...$params stringable parameters,
|
||||
* or a single argument that is an array of stringable parameters.
|
||||
*
|
||||
* @return Message $this
|
||||
*/
|
||||
public function objectParams( ...$params ) {
|
||||
if ( isset( $params[0] ) && is_array( $params[0] ) ) {
|
||||
$params = $params[0];
|
||||
}
|
||||
foreach ( $params as $param ) {
|
||||
$this->parameters[] = self::objectParam( $param );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add parameters that are times and will be passed through
|
||||
* Language::time before substitution
|
||||
|
|
@ -1173,6 +1194,17 @@ class Message implements MessageSpecifier, Serializable {
|
|||
return [ 'group' => $userGroup ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.38
|
||||
*
|
||||
* @param Stringable $object
|
||||
*
|
||||
* @return Stringable[] Array with a single "object" key.
|
||||
*/
|
||||
public static function objectParam( Stringable $object ) {
|
||||
return [ 'object' => $object ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.22
|
||||
*
|
||||
|
|
@ -1311,6 +1343,16 @@ class Message implements MessageSpecifier, Serializable {
|
|||
return [ 'after', $this->formatPlaintext( $param['plaintext'], $format ) ];
|
||||
} elseif ( isset( $param['list'] ) ) {
|
||||
return $this->formatListParam( $param['list'], $param['type'], $format );
|
||||
} elseif ( isset( $param['object'] ) ) {
|
||||
$obj = $param['object'];
|
||||
if ( $obj instanceof UserGroupMembershipParam ) {
|
||||
return [
|
||||
'before',
|
||||
$this->getLanguage()->getGroupMemberName( $obj->getGroup(), $obj->getMember() )
|
||||
];
|
||||
} else {
|
||||
return [ 'before', $obj->__toString() ];
|
||||
}
|
||||
} else {
|
||||
LoggerFactory::getInstance( 'Bug58676' )->warning(
|
||||
'Invalid parameter for message "{msgkey}": {param}',
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Wikimedia\Message;
|
||||
|
||||
use Stringable;
|
||||
|
||||
/**
|
||||
* Value object representing a message for i18n.
|
||||
*
|
||||
|
|
@ -92,6 +94,19 @@ class MessageValue {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chainable mutator which adds object parameters
|
||||
*
|
||||
* @param Stringable ...$values stringable object values
|
||||
* @return $this
|
||||
*/
|
||||
public function objectParams( ...$values ) {
|
||||
foreach ( $values as $value ) {
|
||||
$this->params[] = new ScalarParam( ParamType::OBJECT, $value );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chainable mutator which adds list parameters with a common type
|
||||
*
|
||||
|
|
|
|||
|
|
@ -60,12 +60,17 @@ class ParamType {
|
|||
public const TIME = 'time';
|
||||
|
||||
/**
|
||||
* @since 1.38
|
||||
*
|
||||
* User Group
|
||||
* @since 1.38
|
||||
*/
|
||||
public const GROUP = 'group';
|
||||
|
||||
/**
|
||||
* For arbitrary stringable objects
|
||||
* @since 1.38
|
||||
*/
|
||||
public const OBJECT = 'object';
|
||||
|
||||
/** A number of bytes. The output will be rounded to an appropriate magnitude. */
|
||||
public const SIZE = 'size';
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Wikimedia\Message;
|
||||
|
||||
use Stringable;
|
||||
|
||||
/**
|
||||
* Value object representing a message parameter holding a single value.
|
||||
*
|
||||
|
|
@ -16,7 +18,7 @@ class ScalarParam extends MessageParam {
|
|||
* @stable to call.
|
||||
*
|
||||
* @param string $type One of the ParamType constants.
|
||||
* @param string|int|float|MessageValue $value
|
||||
* @param string|int|float|MessageValue|Stringable $value
|
||||
*/
|
||||
public function __construct( $type, $value ) {
|
||||
if ( $type === ParamType::LIST ) {
|
||||
|
|
@ -24,7 +26,8 @@ class ScalarParam extends MessageParam {
|
|||
'ParamType::LIST cannot be used with ScalarParam; use ListParam instead'
|
||||
);
|
||||
}
|
||||
if ( !is_string( $value ) && !is_numeric( $value ) && !$value instanceof MessageValue ) {
|
||||
if ( !is_string( $value ) && !is_numeric( $value ) &&
|
||||
!$value instanceof MessageValue && !$value instanceof Stringable ) {
|
||||
$type = is_object( $value ) ? get_class( $value ) : gettype( $value );
|
||||
throw new \InvalidArgumentException(
|
||||
"Scalar parameter must be a string, number, or MessageValue; got $type"
|
||||
|
|
@ -39,7 +42,7 @@ class ScalarParam extends MessageParam {
|
|||
if ( $this->value instanceof MessageValue ) {
|
||||
$contents = $this->value->dump();
|
||||
} else {
|
||||
$contents = htmlspecialchars( $this->value );
|
||||
$contents = htmlspecialchars( (string)$this->value );
|
||||
}
|
||||
return "<{$this->type}>" . $contents . "</{$this->type}>";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
/**
|
||||
* Represents a "user group membership" -- a specific instance of a user belonging
|
||||
|
|
@ -175,12 +176,11 @@ class UserGroupMembership {
|
|||
* "administrator" or "bureaucrat"
|
||||
*
|
||||
* @param string $group Internal group name
|
||||
* @param string $username Username for gender
|
||||
* @param string|UserIdentity $member Username or UserIdentity of member for gender
|
||||
* @return string Localized name for group member
|
||||
*/
|
||||
public static function getGroupMemberName( $group, $username ) {
|
||||
$msg = wfMessage( "group-$group-member", $username );
|
||||
return $msg->isBlank() ? $group : $msg->text();
|
||||
public static function getGroupMemberName( $group, $member ) {
|
||||
return RequestContext::getMain()->getLanguage()->getGroupMemberName( $group, $member );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace MediaWiki\Tests\Message;
|
|||
|
||||
use MediaWiki\Message\Converter;
|
||||
use MediaWiki\Message\TextFormatter;
|
||||
use MediaWiki\Message\UserGroupMembershipParam;
|
||||
use MediaWiki\User\UserIdentityValue;
|
||||
use MediaWikiIntegrationTestCase;
|
||||
use Message;
|
||||
use Wikimedia\Message\MessageValue;
|
||||
|
|
@ -92,6 +94,13 @@ class TextFormatterTest extends MediaWikiIntegrationTestCase {
|
|||
->userGroupParams( 'bot' ),
|
||||
'test (group-bot) $2'
|
||||
];
|
||||
|
||||
yield [ ( new MessageValue( 'test' ) )
|
||||
->objectParams(
|
||||
new UserGroupMembershipParam( 'bot', new UserIdentityValue( 1, 'user' ) )
|
||||
),
|
||||
'test (group-bot-member: user) $2'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Message\UserGroupMembershipParam;
|
||||
use MediaWiki\Page\PageReference;
|
||||
use MediaWiki\Page\PageReferenceValue;
|
||||
use MediaWiki\User\UserIdentityValue;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
|
|
@ -551,6 +553,23 @@ class MessageTest extends MediaWikiLangTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Message::objectParam
|
||||
* @covers Message::objectParams
|
||||
*/
|
||||
public function testUserGroupMemberParams() {
|
||||
$lang = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'qqx' );
|
||||
$msg = new RawMessage( '$1' );
|
||||
$this->setUserLang( $lang );
|
||||
$this->assertSame(
|
||||
'(group-bot-member: user)',
|
||||
$msg->objectParams(
|
||||
new UserGroupMembershipParam( 'bot', new UserIdentityValue( 1, 'user' ) )
|
||||
)->plain(),
|
||||
'user group member is handled correctly'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Message::timeperiodParam
|
||||
* @covers Message::timeperiodParams
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ use MediaWiki\Languages\LanguageConverterFactory;
|
|||
use MediaWiki\Languages\LanguageFallback;
|
||||
use MediaWiki\Languages\LanguageNameUtils;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\UserIdentityValue;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
* @group Language
|
||||
|
|
@ -2200,4 +2202,26 @@ class LanguageIntegrationTest extends LanguageClassesTestCase {
|
|||
$this->assertSame( 'Bots', $groupName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Language::getGroupMemberName
|
||||
*/
|
||||
public function testGetGroupMemberName() {
|
||||
$lang = $this->getLang();
|
||||
$user = new UserIdentityValue( 1, 'user' );
|
||||
$groupMemberName = $lang->getGroupMemberName( 'bot', $user );
|
||||
$this->assertSame( 'bot', $groupMemberName );
|
||||
|
||||
$lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'qqx' );
|
||||
$groupMemberName = $lang->getGroupMemberName( 'bot', $user );
|
||||
$this->assertSame( '(group-bot-member: user)', $groupMemberName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Language::msg
|
||||
*/
|
||||
public function testMsg() {
|
||||
$lang = TestingAccessWrapper::newFromObject( $this->getLang() );
|
||||
$this->assertSame( 'December 1', $lang->msg( 'december-date', '1' )->text() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Wikimedia\Tests\Message;
|
||||
|
||||
use MediaWiki\Message\UserGroupMembershipParam;
|
||||
use MediaWiki\User\UserIdentityValue;
|
||||
use Wikimedia\Message\ListType;
|
||||
use Wikimedia\Message\MessageValue;
|
||||
use Wikimedia\Message\ParamType;
|
||||
|
|
@ -183,6 +185,18 @@ class MessageValueTest extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertSame( $mv, $mv2 );
|
||||
}
|
||||
|
||||
public function testUserGroupMemberParams() {
|
||||
$mv = new MessageValue( 'key' );
|
||||
$mv2 = $mv->objectParams(
|
||||
new UserGroupMembershipParam( 'bot', new UserIdentityValue( 1, 'user' ) )
|
||||
);
|
||||
$this->assertSame( '<message key="key">' .
|
||||
'<object>bot:user</object>' .
|
||||
'</message>',
|
||||
$mv->dump() );
|
||||
$this->assertSame( $mv, $mv2 );
|
||||
}
|
||||
|
||||
public function testSizeParams() {
|
||||
$mv = new MessageValue( 'key' );
|
||||
$mv2 = $mv->sizeParams( 1, 2 );
|
||||
|
|
|
|||
Loading…
Reference in a new issue