mediawiki-extensions-Discus.../includes/ResourceLoaderData.php
Bartosz Dziewoński 4613ae78e7 Change CommentParser into a service
Goal:
-----
To have a method like CommentParser::parse(), which just takes a node
to parse and a title and returns plain data, so that we don't need to
keep track of the config to construct a CommentParser object (the
required config like content language is provided by services) and
we don't need to keep that object around after parsing.

Changes:
--------
CommentParser.php:
* …is now a service. Constructor only takes services as arguments.
  The node and title are passed to a new parse() method.
* parse() should return plain data, but I split this part to a separate
  patch for ease of review: I49bfe019aa460651447fd383f73eafa9d7180a92.
* CommentParser still cheats and accesses global state in a few places,
  e.g. calling Title::makeTitleSafe or CommentUtils::getTitleFromUrl,
  so we can't turn its tests into true unit tests. This work is left
  for future commits.

LanguageData.php:
* …is now a service, instead of a static class.

Parser.js:
* …is not a real service, but it's changed to behave in a similar way.
  Constructor takes only the required config as argument,
  and node and title are instead passed to a new parse() method.

CommentParserTest.php:
parser.test.js:
* Can be simplified, now that we don't need a useless node and title
  to test internal methods that don't use them.

testUtils.js:
* Can be simplified, now that we don't need to override internal
  ResourceLoader stuff just to change the parser config.

Change-Id: Iadb7757debe000025e52770ca51ebcf24ca8ee66
2022-02-19 19:51:57 +01:00

154 lines
4.5 KiB
PHP

<?php
/**
* Utilities for ResourceLoader modules used by DiscussionTools.
*
* @file
* @ingroup Extensions
* @license MIT
*/
namespace MediaWiki\Extension\DiscussionTools;
use Config;
use ExtensionRegistry;
use MediaWiki\MediaWikiServices;
use MessageLocalizer;
use ResourceLoaderContext;
use ResourceLoaderFileModule;
use ResourceLoaderModule;
use Title;
class ResourceLoaderData {
/**
* Used for the 'ext.discussionTools.init' module and the test module.
*
* We need all of this data *in content language*. Some of it is already available in JS, but only
* in client language, so it's useless for us (e.g. digit transform table, month name messages).
*
* @param ResourceLoaderContext $context
* @param Config $config
* @param string|null $langCode
* @return array
*/
public static function getLocalData(
ResourceLoaderContext $context, Config $config, ?string $langCode = null
): array {
$services = MediaWikiServices::getInstance();
if ( $langCode === null ) {
$langData = $services->getService( 'DiscussionTools.LanguageData' );
} else {
$langData = new LanguageData(
$services->getMainConfig(),
$services->getLanguageFactory()->getLanguage( $langCode ),
$services->getLanguageConverterFactory(),
$services->getSpecialPageFactory()
);
}
return $langData->getLocalData();
}
/**
* Return messages in content language, for use in a ResourceLoader module.
*
* @param ResourceLoaderContext $context
* @param Config $config
* @param array $messagesKeys
* @return array
*/
public static function getContentLanguageMessages(
ResourceLoaderContext $context, Config $config, array $messagesKeys = []
): array {
return array_combine(
$messagesKeys,
array_map( static function ( $key ) {
return wfMessage( $key )->inContentLanguage()->text();
}, $messagesKeys )
);
}
/**
* Return information about terms-of-use messages.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array Map from internal name to array of parameters for MessageLocalizer::msg()
*/
private static function getTermsOfUseMessages(
MessageLocalizer $context, Config $config
): array {
$messages = [
'reply' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-reply' )->text() ],
'newtopic' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-newtopic' )->text() ],
];
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
$hookContainer->run( 'DiscussionToolsTermsOfUseMessages', [ &$messages, $context, $config ] );
return $messages;
}
/**
* Return parsed terms-of-use messages, for use in a ResourceLoader module.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesParsed(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$msg = $context->msg( ...$msg )->parse();
}
return $messages;
}
/**
* Return information about terms-of-use messages, for use in a ResourceLoader module as
* 'versionCallback'. This is to avoid calling the parser from version invalidation code.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesVersion(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$message = $context->msg( ...$msg );
$msg = [
// Include the text of the message, in case the canonical translation changes
$message->plain(),
// Include the page touched time, in case the on-wiki override is invalidated
Title::makeTitle( NS_MEDIAWIKI, ucfirst( $message->getKey() ) )->getTouched(),
];
}
return $messages;
}
/**
* Add optional dependencies to a ResourceLoader module definition depending on loaded extensions.
*
* @param array $info
* @return ResourceLoaderModule
*/
public static function addOptionalDependencies( array $info ): ResourceLoaderModule {
$extensionRegistry = ExtensionRegistry::getInstance();
foreach ( $info['optionalDependencies'] as $ext => $deps ) {
if ( $extensionRegistry->isLoaded( $ext ) ) {
$info['dependencies'] = array_merge( $info['dependencies'], (array)$deps );
}
}
$class = $info['class'] ?? ResourceLoaderFileModule::class;
return new $class( $info );
}
}