Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
QueryManageMessageGroupsActionApi.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
6use ApiQuery;
7use ApiQueryBase;
12use Title;
14use Wikimedia\ParamValidator\ParamValidator;
15
23class QueryManageMessageGroupsActionApi extends ApiQueryBase {
24 private const RIGHT = 'translate-manage';
25
26 public function __construct( ApiQuery $query, string $moduleName ) {
27 parent::__construct( $query, $moduleName, 'mmg' );
28 }
29
30 public function execute() {
31 $params = $this->extractRequestParams();
32 $groupId = $params['groupId'];
33 $msgKey = $params['messageKey'];
34 $name = $params['changesetName'] ?? MessageChangeStorage::DEFAULT_NAME;
35
36 $user = $this->getUser();
37 $allowed = $user->isAllowed( self::RIGHT );
38
39 if ( !$allowed ) {
40 $this->dieWithError( 'apierror-permissiondenied-generic', 'permissiondenied' );
41 }
42
43 $group = MessageGroups::getGroup( $groupId );
44 if ( !$group ) {
45 $this->dieWithError( 'apierror-translate-invalidgroup', 'invalidgroup' );
46 }
47
48 if ( !MessageChangeStorage::isValidCdbName( $name ) ) {
49 $this->dieWithError(
50 [ 'apierror-translate-invalid-changeset-name', wfEscapeWikiText( $name ) ],
51 'invalidchangeset'
52 );
53 }
54 $cdbPath = MessageChangeStorage::getCdbPath( $name );
55
56 $sourceChanges = MessageChangeStorage::getGroupChanges( $cdbPath, $groupId );
57
58 if ( $sourceChanges->getAllModifications() === [] ) {
59 $this->dieWithError( [ 'apierror-translate-smg-nochanges' ] );
60 }
61
62 $messages = $this->getPossibleRenames(
63 $sourceChanges, $group->getNamespace(), $msgKey, $group->getSourceLanguage()
64 );
65
66 $result = $this->getResult();
67 $result->addValue( [ 'query', $this->getModuleName() ], null, $messages );
68 }
69
71 protected function getPossibleRenames(
72 MessageSourceChange $sourceChanges,
73 int $groupNamespace,
74 string $msgKey,
75 string $languageCode
76 ): array {
77 $deletions = $sourceChanges->getDeletions( $languageCode );
78 $targetMsg = $sourceChanges->findMessage(
79 $languageCode, $msgKey, [ MessageSourceChange::ADDITION, MessageSourceChange::RENAME ]
80 );
81 $stringComparator = new SimpleStringComparator();
82 $renameList = [];
83
84 // compare deleted messages with the target message and get the similarity.
85 foreach ( $deletions as $deletion ) {
86 if ( $deletion['content'] === null ) {
87 continue;
88 }
89
90 $similarity = $stringComparator->getSimilarity(
91 $deletion['content'],
92 // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
93 $targetMsg['content']
94 );
95
96 $title = Title::makeTitle(
97 $groupNamespace,
98 TranslateUtils::title( $deletion['key'], $languageCode, $groupNamespace )
99 );
100
101 $renameList[] = [
102 'key' => $deletion['key'],
103 'content' => $deletion['content'],
104 'similarity' => $similarity,
105 'link' => $title->getFullURL(),
106 'title' => $title->getPrefixedText()
107 ];
108 }
109
110 // sort them based on similarity
111 usort( $renameList, static function ( $a, $b ) {
112 return -( $a['similarity'] <=> $b['similarity'] );
113 } );
114
115 return $renameList;
116 }
117
118 protected function getAllowedParams(): array {
119 $params = parent::getAllowedParams();
120 $params['groupId'] = [
121 ParamValidator::PARAM_TYPE => 'string',
122 ParamValidator::PARAM_REQUIRED => true,
123 ];
124
125 $params['messageKey'] = [
126 ParamValidator::PARAM_TYPE => 'string',
127 ParamValidator::PARAM_REQUIRED => true,
128 ];
129
130 $params['changesetName'] = [
131 ParamValidator::PARAM_TYPE => 'string',
132 ParamValidator::PARAM_DEFAULT => MessageChangeStorage::DEFAULT_NAME
133 ];
134
135 return $params;
136 }
137
138 protected function getExamplesMessages(): array {
139 return [
140 'action=query&meta=managemessagegroup&mmggroupId=hello
141 &mmgchangesetName=default&mmgmessageKey=world' => 'apihelp-query+managemessagegroups-example-1',
142 ];
143 }
144}
return[ 'Translate:ConfigHelper'=> static function():ConfigHelper { return new ConfigHelper();}, 'Translate:CsvTranslationImporter'=> static function(MediaWikiServices $services):CsvTranslationImporter { return new CsvTranslationImporter( $services->getWikiPageFactory());}, 'Translate:EntitySearch'=> static function(MediaWikiServices $services):EntitySearch { return new EntitySearch($services->getMainWANObjectCache(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), MessageGroups::singleton(), $services->getNamespaceInfo(), $services->get( 'Translate:MessageIndex'), $services->getTitleParser(), $services->getTitleFormatter());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->getMainConfig(), $services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance( 'Translate.GroupSynchronization'), MessageIndex::singleton());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore(new RevTagStore(), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReview'=> static function(MediaWikiServices $services):MessageGroupReview { return new MessageGroupReview($services->getDBLoadBalancer(), $services->getHookContainer());}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=$services->getMainConfig() ->get( 'TranslateMessageIndex');if(is_string( $params)) { $params=(array) $params;} $class=array_shift( $params);return new $class( $params);}, 'Translate:ParsingPlaceholderFactory'=> static function():ParsingPlaceholderFactory { return new ParsingPlaceholderFactory();}, 'Translate:PersistentCache'=> static function(MediaWikiServices $services):PersistentCache { return new PersistentDatabaseCache($services->getDBLoadBalancer(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'));}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, 'Translate:TranslatableBundleMover'=> static function(MediaWikiServices $services):TranslatableBundleMover { return new TranslatableBundleMover($services->getMovePageFactory(), $services->getJobQueueGroup(), $services->getLinkBatchFactory(), $services->get( 'Translate:TranslatableBundleFactory'), $services->get( 'Translate:SubpageListBuilder'), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), new RevTagStore(), $services->getDBLoadBalancer());}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnectionRef(DB_REPLICA);return new TranslationStashStorage( $db);}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory());}, 'Translate:TranslationUnitStoreFactory'=> static function(MediaWikiServices $services):TranslationUnitStoreFactory { return new TranslationUnitStoreFactory( $services->getDBLoadBalancer());}, 'Translate:TranslatorActivity'=> static function(MediaWikiServices $services):TranslatorActivity { $query=new TranslatorActivityQuery($services->getMainConfig(), $services->getDBLoadBalancer());return new TranslatorActivity($services->getMainObjectStash(), $query, $services->getJobQueueGroup());}, 'Translate:TtmServerFactory'=> static function(MediaWikiServices $services):TtmServerFactory { $config=$services->getMainConfig();$default=$config->get( 'TranslateTranslationDefaultService');if( $default===false) { $default=null;} return new TtmServerFactory( $config->get( 'TranslateTranslationServices'), $default);}]
@phpcs-require-sorted-array
getPossibleRenames(MessageSourceChange $sourceChanges, int $groupNamespace, string $msgKey, string $languageCode)
Fetches the messages that can be used as possible renames for a given message.
Class is use to track the changes made when importing messages from the remote sources using processM...
findMessage( $language, $key, $possibleStates=[], &$modificationType=null)
Finds a message with the given key across different types of modifications.
A simple string comparator, that compares two strings and determines if they are an exact match.
Factory class for accessing message groups individually by id or all of them as an list.
Essentially random collection of helper functions, similar to GlobalFunctions.php.