Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 75 |
|
0.00% |
0 / 25 |
CRAP | |
0.00% |
0 / 1 |
MessageBundleMessageGroup | |
0.00% |
0 / 75 |
|
0.00% |
0 / 25 |
1260 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
getGroupId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getBundlePageId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getData | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
30 | |||
makeGroupKeys | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLabel | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDescription | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
getIcon | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getNamespace | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isMeta | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
exists | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getValidator | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMangler | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
initCollection | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
load | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefinitions | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
getKeys | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getTags | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMessage | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getSourceLanguage | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMessageGroupStates | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
getTranslatableLanguages | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSupportConfig | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRelatedPage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | declare( strict_types = 1 ); |
4 | |
5 | namespace MediaWiki\Extension\Translate\MessageBundleTranslation; |
6 | |
7 | use LogicException; |
8 | use MediaWiki\Context\IContextSource; |
9 | use MediaWiki\Extension\Translate\MessageGroupProcessing\MessageGroupStates; |
10 | use MediaWiki\Extension\Translate\MessageLoading\MessageCollection; |
11 | use MediaWiki\Extension\Translate\MessageLoading\MessageDefinitions; |
12 | use MediaWiki\Extension\Translate\MessageProcessing\StringMatcher; |
13 | use MediaWiki\Extension\Translate\Services; |
14 | use MediaWiki\Extension\Translate\Validation\ValidationRunner; |
15 | use MediaWiki\Linker\LinkTarget; |
16 | use MediaWiki\MediaWikiServices; |
17 | use MediaWiki\Revision\SlotRecord; |
18 | use MediaWiki\Title\Title; |
19 | use MessageGroup; |
20 | use const NS_TRANSLATIONS; |
21 | |
22 | /** |
23 | * @author Niklas Laxström |
24 | * @license GPL-2.0-or-later |
25 | * @since 2021.12 |
26 | */ |
27 | class MessageBundleMessageGroup implements MessageGroup { |
28 | /** Name of the bundle (prefixed text of the bundle page) */ |
29 | private string $name; |
30 | private string $groupId; |
31 | private int $pageId; |
32 | private int $revisionId; |
33 | private ?array $data = null; |
34 | private ?string $description; |
35 | private ?string $label; |
36 | private ?Title $title; |
37 | |
38 | public function __construct( |
39 | string $groupId, |
40 | string $name, |
41 | int $pageId, |
42 | int $revisionId, |
43 | ?string $description, |
44 | ?string $label |
45 | ) { |
46 | $this->groupId = $groupId; |
47 | $this->name = $name; |
48 | $this->pageId = $pageId; |
49 | $this->revisionId = $revisionId; |
50 | $this->description = $description; |
51 | $this->label = $label; |
52 | } |
53 | |
54 | /** Suggested default naming pattern */ |
55 | public static function getGroupId( string $name ): string { |
56 | return "messagebundle-$name"; |
57 | } |
58 | |
59 | public function getBundlePageId(): int { |
60 | return $this->pageId; |
61 | } |
62 | |
63 | private function getData(): array { |
64 | if ( $this->data !== null ) { |
65 | return $this->data; |
66 | } |
67 | |
68 | $revisionStore = MediaWikiServices::getInstance()->getRevisionStore(); |
69 | $revision = $revisionStore->getRevisionById( $this->revisionId ); |
70 | |
71 | if ( $revision === null ) { |
72 | throw new LogicException( "Could not find revision id $this->revisionId" ); |
73 | } |
74 | |
75 | $content = $revision->getContent( SlotRecord::MAIN ); |
76 | if ( !$content instanceof MessageBundleContent ) { |
77 | throw new LogicException( |
78 | "Content with revision id $this->revisionId has wrong content format" |
79 | ); |
80 | } |
81 | |
82 | $data = json_decode( $content->getText(), true ); |
83 | if ( !$data ) { |
84 | throw new LogicException( |
85 | "Content with revision id $this->revisionId is not valid JSON" |
86 | ); |
87 | } |
88 | |
89 | $this->data = $data; |
90 | return $this->data; |
91 | } |
92 | |
93 | private function makeGroupKeys( array $keys ): array { |
94 | $result = []; |
95 | foreach ( $keys as $key ) { |
96 | $result[] = str_replace( ' ', '_', "$this->name/$key" ); |
97 | } |
98 | return $result; |
99 | } |
100 | |
101 | /** @inheritDoc */ |
102 | public function getId(): string { |
103 | return $this->groupId; |
104 | } |
105 | |
106 | /** @inheritDoc */ |
107 | public function getLabel( ?IContextSource $context = null ): string { |
108 | return $this->label ?? $this->name; |
109 | } |
110 | |
111 | /** @inheritDoc */ |
112 | public function getDescription( ?IContextSource $context = null ): string { |
113 | $titleText = Title::newFromID( $this->pageId )->getPrefixedText(); |
114 | $linkTargetText = ":$titleText"; |
115 | if ( $context ) { |
116 | $message = $context->msg( 'translate-messagebundle-group-description' ); |
117 | } else { |
118 | $message = wfMessage( 'translate-messagebundle-group-description' ) |
119 | ->inContentLanguage(); |
120 | } |
121 | |
122 | $plainMessage = $message->params( $titleText, $linkTargetText )->plain(); |
123 | |
124 | if ( $this->description === null ) { |
125 | return $plainMessage; |
126 | } |
127 | |
128 | return $plainMessage . ' ' . $this->description; |
129 | } |
130 | |
131 | /** @inheritDoc */ |
132 | public function getIcon(): ?string { |
133 | return null; |
134 | } |
135 | |
136 | /** @inheritDoc */ |
137 | public function getNamespace(): int { |
138 | return NS_TRANSLATIONS; |
139 | } |
140 | |
141 | /** @inheritDoc */ |
142 | public function isMeta(): bool { |
143 | return false; |
144 | } |
145 | |
146 | /** @inheritDoc */ |
147 | public function exists(): bool { |
148 | return true; |
149 | } |
150 | |
151 | /** @inheritDoc */ |
152 | public function getValidator(): ?ValidationRunner { |
153 | return null; |
154 | } |
155 | |
156 | /** @inheritDoc */ |
157 | public function getMangler(): ?StringMatcher { |
158 | return null; |
159 | } |
160 | |
161 | /** @inheritDoc */ |
162 | public function initCollection( $code ): MessageCollection { |
163 | $defs = new MessageDefinitions( $this->getDefinitions(), $this->getNamespace() ); |
164 | $collection = MessageCollection::newFromDefinitions( $defs, $code ); |
165 | |
166 | foreach ( $this->getTags() as $type => $tags ) { |
167 | $collection->setTags( $type, $tags ); |
168 | } |
169 | |
170 | return $collection; |
171 | } |
172 | |
173 | /** @inheritDoc */ |
174 | public function load( $code ): array { |
175 | return []; |
176 | } |
177 | |
178 | /** @inheritDoc */ |
179 | public function getDefinitions(): array { |
180 | $data = $this->getData(); |
181 | unset( $data['@metadata'] ); |
182 | |
183 | return array_combine( |
184 | $this->makeGroupKeys( array_keys( $data ) ), |
185 | array_values( $data ) |
186 | ); |
187 | } |
188 | |
189 | /** @inheritDoc */ |
190 | public function getKeys(): array { |
191 | return array_keys( $this->getDefinitions() ); |
192 | } |
193 | |
194 | /** @inheritDoc */ |
195 | public function getTags( $type = null ): array { |
196 | return []; |
197 | } |
198 | |
199 | /** @inheritDoc */ |
200 | public function getMessage( $key, $code ): ?string { |
201 | if ( $code === $this->getSourceLanguage() ) { |
202 | return $this->getDefinitions()[$key] ?? null; |
203 | } |
204 | |
205 | return null; |
206 | } |
207 | |
208 | /** @inheritDoc */ |
209 | public function getSourceLanguage(): string { |
210 | return Title::newFromText( $this->name )->getPageLanguage()->getCode(); |
211 | } |
212 | |
213 | /** @inheritDoc */ |
214 | public function getMessageGroupStates(): MessageGroupStates { |
215 | global $wgTranslateWorkflowStates; |
216 | $conf = $wgTranslateWorkflowStates ?: []; |
217 | |
218 | Services::getInstance()->getHookRunner() |
219 | ->onTranslate_modifyMessageGroupStates( $this->getId(), $conf ); |
220 | |
221 | return new MessageGroupStates( $conf ); |
222 | } |
223 | |
224 | /** @inheritDoc */ |
225 | public function getTranslatableLanguages(): ?array { |
226 | return null; |
227 | } |
228 | |
229 | /** @inheritDoc */ |
230 | public function getSupportConfig(): ?array { |
231 | return null; |
232 | } |
233 | |
234 | /** @inheritDoc */ |
235 | public function getRelatedPage(): ?LinkTarget { |
236 | $this->title ??= Title::newFromID( $this->pageId ); |
237 | return $this->title; |
238 | } |
239 | } |