diff --git a/includes/api/ApiBlockInfoTrait.php b/includes/api/ApiBlockInfoTrait.php index e0f8bddb9ce..7c94670a0a7 100644 --- a/includes/api/ApiBlockInfoTrait.php +++ b/includes/api/ApiBlockInfoTrait.php @@ -36,7 +36,10 @@ trait ApiBlockInfoTrait { * - blockedbyid - user ID of the blocker * - blockreason - reason provided for the block * - blockedtimestamp - timestamp for when the block was placed/modified + * - blockedtimestampformatted - blockedtimestamp, formatted for the current locale * - blockexpiry - expiry time of the block + * - blockexpiryformatted - blockexpiry formatted for the current locale, omitted if infinite + * - blockexpiryrelative - relative time to blockexpiry (e.g. 'in 5 days'), omitted if infinite * - blockpartial - block only applies to certain pages, namespaces and/or actions * - systemblocktype - system block type, if any */ @@ -57,11 +60,26 @@ trait ApiBlockInfoTrait { $vals['blockreason'] = $block->getReasonComment() ->message->inLanguage( $language )->plain(); $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->getTimestamp() ); - $vals['blockexpiry'] = ApiResult::formatExpiry( $block->getExpiry(), 'infinite' ); + $expiry = ApiResult::formatExpiry( $block->getExpiry(), 'infinite' ); + $vals['blockexpiry'] = $expiry; $vals['blockpartial'] = !$block->isSitewide(); $vals['blocknocreate'] = $block->isCreateAccountBlocked(); $vals['blockanononly'] = !$block->isHardblock(); + $user = $this->getUser(); + // Formatted timestamps + $vals['blockedtimestampformatted'] = $language->formatExpiry( + $block->getTimestamp(), true, 'infinity', $user + ); + if ( $expiry !== 'infinite' ) { + $vals['blockexpiryformatted'] = $language->formatExpiry( + $expiry, true, 'infinity', $user + ); + $vals['blockexpiryrelative'] = $language->getHumanTimestamp( + new MWTimestamp( $expiry ), new MWTimestamp(), $user + ); + } + if ( $block instanceof SystemBlock ) { $vals['systemblocktype'] = $block->getSystemBlockType(); } @@ -80,6 +98,12 @@ trait ApiBlockInfoTrait { */ abstract public function getLanguage(); + /** + * @see IContextSource::getUser + * @return User + */ + abstract public function getUser(); + /** @} */ // endregion -- end of methods required from ApiBase diff --git a/tests/phpunit/includes/api/ApiBaseTest.php b/tests/phpunit/includes/api/ApiBaseTest.php index 4409cf83c1e..223bb42166a 100644 --- a/tests/phpunit/includes/api/ApiBaseTest.php +++ b/tests/phpunit/includes/api/ApiBaseTest.php @@ -1347,7 +1347,8 @@ class ApiBaseTest extends ApiTestCase { MediaWikiServices::getInstance()->getDatabaseBlockStore()->insertBlock( $block ); $mockTrait = $this->getMockForTrait( ApiBlockInfoTrait::class ); - $mockTrait->method( 'getLanguage' )->willReturn( 'en' ); + $language = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' ); + $mockTrait->method( 'getLanguage' )->willReturn( $language ); $userInfoTrait = TestingAccessWrapper::newFromObject( $mockTrait ); $blockinfo = [ 'blockinfo' => $userInfoTrait->getBlockDetails( $block ) ]; @@ -1406,7 +1407,8 @@ class ApiBaseTest extends ApiTestCase { MediaWikiServices::getInstance()->getDatabaseBlockStore()->insertBlock( $block ); $mockTrait = $this->getMockForTrait( ApiBlockInfoTrait::class ); - $mockTrait->method( 'getLanguage' )->willReturn( 'en' ); + $language = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' ); + $mockTrait->method( 'getLanguage' )->willReturn( $language ); $userInfoTrait = TestingAccessWrapper::newFromObject( $mockTrait ); $blockinfo = [ 'blockinfo' => $userInfoTrait->getBlockDetails( $block ) ]; diff --git a/tests/phpunit/includes/api/ApiBlockInfoTraitTest.php b/tests/phpunit/includes/api/ApiBlockInfoTraitTest.php index 65eece7e9d2..70c4e9a196a 100644 --- a/tests/phpunit/includes/api/ApiBlockInfoTraitTest.php +++ b/tests/phpunit/includes/api/ApiBlockInfoTraitTest.php @@ -2,6 +2,7 @@ use MediaWiki\Block\DatabaseBlock; use MediaWiki\Block\SystemBlock; +use MediaWiki\MediaWikiServices; use Wikimedia\TestingAccessWrapper; /** @@ -12,8 +13,9 @@ class ApiBlockInfoTraitTest extends MediaWikiIntegrationTestCase { * @dataProvider provideGetBlockDetails */ public function testGetBlockDetails( $block, $expectedInfo ) { + $language = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' ); $mock = $this->getMockForTrait( ApiBlockInfoTrait::class ); - $mock->method( 'getLanguage' )->willReturn( 'en' ); + $mock->method( 'getLanguage' )->willReturn( $language ); $info = TestingAccessWrapper::newFromObject( $mock )->getBlockDetails( $block ); $subset = array_merge( [ 'blockid' => null,