Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
QueryMessageGroupsActionApi.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
7use MediaWiki\Api\ApiBase;
8use MediaWiki\Api\ApiQuery;
9use MediaWiki\Api\ApiQueryBase;
14use MessageGroup;
15use Wikimedia\ParamValidator\ParamValidator;
16use function array_key_exists;
17
26class QueryMessageGroupsActionApi extends ApiQueryBase {
27
28 public function __construct(
29 ApiQuery $query,
30 string $moduleName,
31 private readonly HookRunner $hookRunner,
32 private readonly MessageGroupMetadata $messageGroupMetadata,
33 private readonly MessageGroupSubscription $groupSubscription,
34 ) {
35 parent::__construct( $query, $moduleName, 'mg' );
36 }
37
38 public function execute(): void {
39 $params = $this->extractRequestParams();
40 $filter = $params['filter'];
41
42 $groups = [];
43 $props = array_flip( $params['prop'] );
44
45 $needsMetadata = isset( $props['prioritylangs'] ) || isset( $props['priorityforce'] );
46
47 if ( $params['format'] === 'flat' ) {
48 if ( $params['root'] !== '' ) {
49 $group = MessageGroups::getGroup( $params['root'] );
50 if ( $group ) {
51 $groups[$params['root']] = $group;
52 }
53 } else {
55 usort( $groups, [ MessageGroups::class, 'groupLabelSort' ] );
56 }
57 } elseif ( $params['root'] !== '' ) {
58 // format=tree from now on, as it is the only other valid option
59 $group = MessageGroups::getGroup( $params['root'] );
60 if ( $group instanceof AggregateMessageGroup ) {
61 $childIds = [];
62 $groups = MessageGroups::subGroups( $group, $childIds );
63 // The parent group is the first, ignore it
64 array_shift( $groups );
65 }
66 } else {
68 }
69
70 if ( $params['root'] === '' ) {
71 $dynamicGroups = [];
72 foreach ( array_keys( MessageGroups::getDynamicGroups() ) as $id ) {
73 $dynamicGroups[$id] = MessageGroups::getGroup( $id );
74 }
75 // Have dynamic groups appear first in the list
76 $groups = $dynamicGroups + $groups;
77 }
78 '@phan-var (MessageGroup|array)[] $groups';
79
80 // Do not list the sandbox group. The code that knows it
81 // exists can access it directly.
82 if ( isset( $groups['!sandbox'] ) ) {
83 unset( $groups['!sandbox'] );
84 }
85
86 $result = $this->getResult();
87 $matcher = new StringMatcher( '', $filter );
89 foreach ( $groups as $index => $mixed ) {
90 // array when Format = tree
91 $group = is_array( $mixed ) ? reset( $mixed ) : $mixed;
92 if ( $filter !== [] && !$matcher->matches( $group->getId() ) ) {
93 unset( $groups[$index] );
94 continue;
95 }
96
97 if (
98 $params['languageFilter'] !== '' &&
99 $this->messageGroupMetadata->isExcluded( $group, $params['languageFilter'] )
100 ) {
101 unset( $groups[$index] );
102 }
103 }
104
105 if ( $needsMetadata && $groups ) {
106 // Collect all message group ids. Handles tree format and removes duplicates.
107 // This is one of the few cases where array_walk_recursive actually does what we want.
108 $messageGroupIds = [];
109 array_walk_recursive(
110 array: $groups,
111 callback: static function ( MessageGroup $value ) use ( &$messageGroupIds ) {
112 $messageGroupIds[$value->getId()] = true;
113 }
114 );
115 $this->messageGroupMetadata->preloadGroups( array_keys( $messageGroupIds ), __METHOD__ );
116 }
117
118 $subscriptions = [];
119 if ( isset( $props['subscription'] ) ) {
120 $subscriptions = array_flip( $this->groupSubscription->getUserSubscriptions( $this->getUser() ) );
121 }
122
124 foreach ( $groups as $index => $mixed ) {
125 $a = $this->formatGroup( $mixed, $props, $subscriptions );
126
127 $result->setIndexedTagName( $a, 'group' );
128
129 // @todo Add a continue?
130 $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $a );
131 if ( !$fit ) {
132 // Even if we're not going to give a continue, no point carrying on
133 // if the result is full
134 break;
135 }
136 }
137
138 $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'group' );
139 }
140
147 protected function formatGroup( $mixed, array $props, array $subscriptions, int $depth = 0 ): array {
148 $params = $this->extractRequestParams();
149 $context = $this->getContext();
150
151 // Default
152 $g = $mixed;
153 $subgroups = [];
154
155 // Format = tree and has subgroups
156 if ( is_array( $mixed ) ) {
158 $g = array_shift( $mixed );
159 $subgroups = $mixed;
160 }
161
162 $a = [];
163
164 $groupId = $g->getId();
165
166 if ( isset( $props['id'] ) ) {
167 $a['id'] = $groupId;
168 }
169
170 if ( isset( $props['label'] ) ) {
171 $a['label'] = $g->getLabel( $context );
172 }
173
174 if ( isset( $props['description'] ) ) {
175 $a['description'] = $g->getDescription( $context );
176 }
177
178 if ( isset( $props['class'] ) ) {
179 $a['class'] = get_class( $g );
180 }
181
182 if ( isset( $props['namespace'] ) ) {
183 $a['namespace'] = $g->getNamespace();
184 }
185
186 if ( isset( $props['exists'] ) ) {
187 $a['exists'] = $g->exists();
188 }
189
190 if ( isset( $props['icon'] ) ) {
191 $formats = Utilities::getIcon( $g, $params['iconsize'] );
192 if ( $formats ) {
193 $a['icon'] = $formats;
194 }
195 }
196
197 if ( isset( $props['priority'] ) ) {
198 $priority = MessageGroups::getPriority( $g );
199 $a['priority'] = $priority ?: 'default';
200 }
201
202 if ( isset( $props['prioritylangs'] ) ) {
203 $prioritylangs = $this->messageGroupMetadata->get( $groupId, 'prioritylangs' );
204 $a['prioritylangs'] = $prioritylangs ? explode( ',', $prioritylangs ) : false;
205 }
206
207 if ( isset( $props['priorityforce'] ) ) {
208 $a['priorityforce'] = ( $this->messageGroupMetadata->get( $groupId, 'priorityforce' ) === 'on' );
209 }
210
211 if ( isset( $props['workflowstates'] ) ) {
212 $a['workflowstates'] = $this->getWorkflowStates( $g );
213 }
214
215 if ( isset( $props['sourcelanguage'] ) ) {
216 $a['sourcelanguage'] = $g->getSourceLanguage();
217 }
218
219 if (
220 isset( $props['subscription'] ) &&
221 $this->groupSubscription->canUserSubscribeToGroup( $g, $this->getUser() )->isOK()
222 ) {
223 $a['subscription'] = array_key_exists( $groupId, $subscriptions );
224 }
225
226 $this->hookRunner->onTranslateProcessAPIMessageGroupsProperties( $a, $props, $params, $g );
227
228 // Depth only applies to tree format
229 if ( $depth >= $params['depth'] && $params['format'] === 'tree' ) {
230 $a['groupcount'] = count( $subgroups );
231
232 // Prevent going further down in the three
233 return $a;
234 }
235
236 // Always empty array for flat format, only sometimes for tree format
237 if ( $subgroups !== [] ) {
238 foreach ( $subgroups as $sg ) {
239 $a['groups'][] = $this->formatGroup( $sg, $props, $subscriptions, $depth + 1 );
240 }
241 $result = $this->getResult();
242 $result->setIndexedTagName( $a['groups'], 'group' );
243 }
244
245 return $a;
246 }
247
253 private function getWorkflowStates( MessageGroup $group ) {
254 if ( MessageGroups::isDynamic( $group ) ) {
255 return false;
256 }
257
258 $stateConfig = $group->getMessageGroupStates()->getStates();
259
260 if ( !is_array( $stateConfig ) || $stateConfig === [] ) {
261 return false;
262 }
263
264 $user = $this->getUser();
265
266 foreach ( $stateConfig as $state => $config ) {
267 if ( is_array( $config ) ) {
268 // Check if user is allowed to change states generally
269 $allowed = $user->isAllowed( 'translate-groupreview' );
270 // Check further restrictions
271 if ( $allowed && isset( $config['right'] ) ) {
272 $allowed = $user->isAllowed( $config['right'] );
273 }
274
275 if ( $allowed ) {
276 $stateConfig[$state]['canchange'] = 1;
277 }
278
279 $stateConfig[$state]['name'] =
280 $this->msg( "translate-workflow-state-$state" )->text();
281 }
282 }
283
284 return $stateConfig;
285 }
286
287 protected function getAllowedParams(): array {
288 $allowedParams = [
289 'depth' => [
290 ParamValidator::PARAM_TYPE => 'integer',
291 ParamValidator::PARAM_DEFAULT => 100,
292 ],
293 'filter' => [
294 ParamValidator::PARAM_TYPE => 'string',
295 ParamValidator::PARAM_DEFAULT => '',
296 ParamValidator::PARAM_ISMULTI => true,
297 ],
298 'format' => [
299 ParamValidator::PARAM_TYPE => [ 'flat', 'tree' ],
300 ParamValidator::PARAM_DEFAULT => 'flat',
301 ],
302 'iconsize' => [
303 ParamValidator::PARAM_TYPE => 'integer',
304 ParamValidator::PARAM_DEFAULT => 64,
305 ],
306 'prop' => [
307 ParamValidator::PARAM_TYPE => array_keys( $this->getPropertyList() ),
308 ParamValidator::PARAM_DEFAULT => 'id|label|description|class|exists',
309 ParamValidator::PARAM_ISMULTI => true,
310 ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
311 ],
312 'root' => [
313 ParamValidator::PARAM_TYPE => 'string',
314 ParamValidator::PARAM_DEFAULT => '',
315 ],
316 'languageFilter' => [
317 ParamValidator::PARAM_TYPE => 'string',
318 ParamValidator::PARAM_DEFAULT => '',
319 ]
320 ];
321
322 return $allowedParams;
323 }
324
332 private function getPropertyList(): array {
333 $properties = array_flip( [
334 'id',
335 'label',
336 'description',
337 'class',
338 'namespace',
339 'exists',
340 'icon',
341 'priority',
342 'prioritylangs',
343 'priorityforce',
344 'workflowstates',
345 'sourcelanguage',
346 'subscription'
347 ] );
348
349 return $properties;
350 }
351
352 protected function getExamplesMessages(): array {
353 return [
354 'action=query&meta=messagegroups' => 'apihelp-query+messagegroups-example-1',
355 ];
356 }
357}
return[ 'Translate:AggregateGroupManager'=> static function(MediaWikiServices $services):AggregateGroupManager { return new AggregateGroupManager($services->getTitleFactory(), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:AggregateGroupMessageGroupFactory'=> static function(MediaWikiServices $services):AggregateGroupMessageGroupFactory { return new AggregateGroupMessageGroupFactory($services->get( 'Translate:MessageGroupMetadata'));}, '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:ExternalMessageSourceStateComparator'=> static function(MediaWikiServices $services):ExternalMessageSourceStateComparator { return new ExternalMessageSourceStateComparator(new SimpleStringComparator(), $services->getRevisionLookup(), $services->getPageStore());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance(LogNames::GROUP_SYNCHRONIZATION), $services->get( 'Translate:MessageIndex'), $services->getTitleFactory(), $services->get( 'Translate:MessageGroupSubscription'), new ServiceOptions(ExternalMessageSourceStateImporter::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:FileBasedMessageGroupFactory'=> static function(MediaWikiServices $services):FileBasedMessageGroupFactory { return new FileBasedMessageGroupFactory(new MessageGroupConfigurationParser(), $services->getContentLanguageCode() ->toString(), new ServiceOptions(FileBasedMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:FileFormatFactory'=> static function(MediaWikiServices $services):FileFormatFactory { return new FileFormatFactory( $services->getObjectFactory());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:HookDefinedMessageGroupFactory'=> static function(MediaWikiServices $services):HookDefinedMessageGroupFactory { return new HookDefinedMessageGroupFactory( $services->get( 'Translate:HookRunner'));}, 'Translate:HookRunner'=> static function(MediaWikiServices $services):HookRunner { return new HookRunner( $services->getHookContainer());}, 'Translate:MessageBundleDependencyPurger'=> static function(MediaWikiServices $services):MessageBundleDependencyPurger { return new MessageBundleDependencyPurger( $services->get( 'Translate:TranslatableBundleFactory'));}, 'Translate:MessageBundleMessageGroupFactory'=> static function(MediaWikiServices $services):MessageBundleMessageGroupFactory { return new MessageBundleMessageGroupFactory($services->get( 'Translate:MessageGroupMetadata'), new ServiceOptions(MessageBundleMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore($services->get( 'Translate:RevTagStore'), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:MessageBundleTranslationLoader'=> static function(MediaWikiServices $services):MessageBundleTranslationLoader { return new MessageBundleTranslationLoader( $services->getLanguageFallback());}, 'Translate:MessageGroupMetadata'=> static function(MediaWikiServices $services):MessageGroupMetadata { return new MessageGroupMetadata( $services->getConnectionProvider());}, 'Translate:MessageGroupReviewStore'=> static function(MediaWikiServices $services):MessageGroupReviewStore { return new MessageGroupReviewStore($services->getConnectionProvider(), $services->get( 'Translate:HookRunner'));}, 'Translate:MessageGroupStatsTableFactory'=> static function(MediaWikiServices $services):MessageGroupStatsTableFactory { return new MessageGroupStatsTableFactory($services->get( 'Translate:ProgressStatsTableFactory'), $services->getLinkRenderer(), $services->get( 'Translate:MessageGroupReviewStore'), $services->get( 'Translate:MessageGroupMetadata'), $services->getMainConfig() ->get( 'TranslateWorkflowStates') !==false);}, 'Translate:MessageGroupSubscription'=> static function(MediaWikiServices $services):MessageGroupSubscription { return new MessageGroupSubscription($services->get( 'Translate:MessageGroupSubscriptionStore'), $services->getJobQueueGroup(), $services->getUserIdentityLookup(), LoggerFactory::getInstance(LogNames::GROUP_SUBSCRIPTION), new ServiceOptions(MessageGroupSubscription::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:MessageGroupSubscriptionHookHandler'=> static function(MediaWikiServices $services):?MessageGroupSubscriptionHookHandler { if(! $services->getExtensionRegistry() ->isLoaded( 'Echo')) { return null;} return new MessageGroupSubscriptionHookHandler($services->get( 'Translate:MessageGroupSubscription'), $services->getUserFactory());}, 'Translate:MessageGroupSubscriptionStore'=> static function(MediaWikiServices $services):MessageGroupSubscriptionStore { return new MessageGroupSubscriptionStore( $services->getConnectionProvider());}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=(array) $services->getMainConfig() ->get( 'TranslateMessageIndex');$class=array_shift( $params);$implementationMap=['HashMessageIndex'=> HashMessageIndex::class, 'CDBMessageIndex'=> CDBMessageIndex::class, 'DatabaseMessageIndex'=> DatabaseMessageIndex::class, 'hash'=> HashMessageIndex::class, 'cdb'=> CDBMessageIndex::class, 'database'=> DatabaseMessageIndex::class,];$messageIndexStoreClass=$implementationMap[$class] ?? $implementationMap['database'];return new MessageIndex(new $messageIndexStoreClass, $services->getMainWANObjectCache(), $services->getJobQueueGroup(), $services->get( 'Translate:HookRunner'), LoggerFactory::getInstance(LogNames::MAIN), $services->getMainObjectStash(), $services->getConnectionProvider(), new ServiceOptions(MessageIndex::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:MessagePrefixStats'=> static function(MediaWikiServices $services):MessagePrefixStats { return new MessagePrefixStats( $services->getTitleParser());}, 'Translate:ParsingPlaceholderFactory'=> static function():ParsingPlaceholderFactory { return new ParsingPlaceholderFactory();}, 'Translate:PersistentCache'=> static function(MediaWikiServices $services):PersistentCache { return new PersistentDatabaseCache($services->getConnectionProvider(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:RevTagStore'=> static function(MediaWikiServices $services):RevTagStore { return new RevTagStore( $services->getConnectionProvider());}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleDeleter'=> static function(MediaWikiServices $services):TranslatableBundleDeleter { return new TranslatableBundleDeleter($services->getMainObjectStash(), $services->getJobQueueGroup(), $services->get( 'Translate:SubpageListBuilder'), $services->get( 'Translate:TranslatableBundleFactory'));}, 'Translate:TranslatableBundleExporter'=> static function(MediaWikiServices $services):TranslatableBundleExporter { return new TranslatableBundleExporter($services->get( 'Translate:SubpageListBuilder'), $services->getWikiExporterFactory(), $services->getConnectionProvider());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, 'Translate:TranslatableBundleImporter'=> static function(MediaWikiServices $services):TranslatableBundleImporter { return new TranslatableBundleImporter($services->getWikiImporterFactory(), $services->get( 'Translate:TranslatablePageParser'), $services->getRevisionLookup(), $services->getNamespaceInfo(), $services->getTitleFactory(), $services->getFormatterFactory());}, '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->getConnectionProvider(), $services->getObjectCacheFactory(), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatableBundleStatusStore'=> static function(MediaWikiServices $services):TranslatableBundleStatusStore { return new TranslatableBundleStatusStore($services->getConnectionProvider() ->getPrimaryDatabase(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), $services->getDBLoadBalancer() ->getMaintenanceConnectionRef(DB_PRIMARY));}, 'Translate:TranslatablePageMarker'=> static function(MediaWikiServices $services):TranslatablePageMarker { return new TranslatablePageMarker($services->getConnectionProvider(), $services->getJobQueueGroup(), $services->getLinkRenderer(), MessageGroups::singleton(), $services->get( 'Translate:MessageIndex'), $services->getTitleFormatter(), $services->getTitleParser(), $services->get( 'Translate:TranslatablePageParser'), $services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:TranslatablePageStateStore'), $services->get( 'Translate:TranslationUnitStoreFactory'), $services->get( 'Translate:MessageGroupMetadata'), $services->getWikiPageFactory(), $services->get( 'Translate:TranslatablePageView'), $services->get( 'Translate:MessageGroupSubscription'), $services->getFormatterFactory(), $services->get( 'Translate:HookRunner'),);}, 'Translate:TranslatablePageMessageGroupFactory'=> static function(MediaWikiServices $services):TranslatablePageMessageGroupFactory { return new TranslatablePageMessageGroupFactory(new ServiceOptions(TranslatablePageMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStateStore'=> static function(MediaWikiServices $services):TranslatablePageStateStore { return new TranslatablePageStateStore($services->get( 'Translate:PersistentCache'), $services->getPageStore());}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), $services->get( 'Translate:RevTagStore'), $services->getConnectionProvider(), $services->get( 'Translate:TranslatableBundleStatusStore'), $services->get( 'Translate:TranslatablePageParser'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:TranslatablePageView'=> static function(MediaWikiServices $services):TranslatablePageView { return new TranslatablePageView($services->getConnectionProvider(), $services->get( 'Translate:TranslatablePageStateStore'), new ServiceOptions(TranslatablePageView::SERVICE_OPTIONS, $services->getMainConfig()));}, 'Translate:TranslateSandbox'=> static function(MediaWikiServices $services):TranslateSandbox { return new TranslateSandbox($services->getUserFactory(), $services->getConnectionProvider(), $services->getPermissionManager(), $services->getAuthManager(), $services->getUserGroupManager(), $services->getActorStore(), $services->getUserOptionsManager(), $services->getJobQueueGroup(), $services->get( 'Translate:HookRunner'), new ServiceOptions(TranslateSandbox::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { return new TranslationStashStorage( $services->getConnectionProvider() ->getPrimaryDatabase());}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory(), $services->getConnectionProvider());}, '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->getConnectionProvider());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);}, 'Translate:WorkflowStatesMessageGroupLoader'=> static function(MediaWikiServices $services):WorkflowStatesMessageGroupLoader { return new WorkflowStatesMessageGroupLoader(new ServiceOptions(WorkflowStatesMessageGroupLoader::CONSTRUCTOR_OPTIONS, $services->getMainConfig()),);},]
@phpcs-require-sorted-array
Groups multiple message groups together as one group.
Hook runner for the Translate extension.
Manage user subscriptions to message groups and trigger notifications.
static getGroup(string $id)
Fetch a message group by id.
static getDynamicGroups()
Contents on these groups changes on a whim.
static getGroupStructure()
Returns a tree of message groups.
static subGroups(AggregateMessageGroup $parent, array &$childIds=[], string $fname='caller')
Like getGroupStructure but start from one root which must be an AggregateMessageGroup.
static getPriority(MessageGroup|string $group)
We want to de-emphasize time sensitive groups like news for 2009.
Offers functionality for reading and updating Translate group related metadata.
The versatile default implementation of StringMangler interface.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:30
Interface for message groups.
getMessageGroupStates()
Get the message group workflow state configuration.