Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslationsSpecialPage.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorInterface;
5
6use DerivativeContext;
7use Html;
8use HtmlArmor;
9use HTMLForm;
10use Language;
11use MediaWiki\Languages\LanguageNameUtils;
13use SpecialAllPages;
14use Title;
16use Xml;
17
27class TranslationsSpecialPage extends SpecialAllPages {
29 private $contentLanguage;
31 private $languageNameUtils;
32
33 public function __construct( Language $contentLanguage, LanguageNameUtils $languageNameUtils ) {
34 parent::__construct();
35 $this->mName = 'Translations';
36 $this->contentLanguage = $contentLanguage;
37 $this->languageNameUtils = $languageNameUtils;
38 }
39
40 protected function getGroupName() {
41 return 'translation';
42 }
43
44 public function getDescription() {
45 return $this->msg( 'translations' )->text();
46 }
47
53 public function execute( $par ) {
54 $this->setHeaders();
55 $this->outputHeader();
56
57 $out = $this->getOutput();
58 $out->addModuleStyles( 'ext.translate.specialpages.styles' );
59
60 $par = (string)$par;
61
62 if ( $this->including() ) {
63 $title = Title::newFromText( $par );
64 if ( !$title ) {
65 $out->addWikiMsg( 'translate-translations-including-no-param' );
66 } else {
67 $this->showTranslations( $title );
68 }
69
70 return;
71 }
72
76 $request = $this->getRequest();
77 $message = $request->getText( 'message' );
78 $namespace = $request->getInt( 'namespace', NS_MAIN );
79
80 if ( $message !== '' ) {
81 $title = Title::newFromText( $message, $namespace );
82 } else {
83 $title = Title::newFromText( $par, $namespace );
84 }
85
86 $out->addHelpLink(
87 'Help:Extension:Translate/Statistics_and_reporting#Translations_in_all_languages'
88 );
89
90 if ( !$title ) {
91 $title = Title::makeTitle( NS_MEDIAWIKI, '' );
92 $this->namespaceMessageForm( $title );
93 } else {
94 $this->namespaceMessageForm( $title );
95 $out->addHTML( '<br />' );
96 $this->showTranslations( $title );
97 }
98 }
99
105 protected function namespaceMessageForm( Title $title = null ): void {
106 $options = [];
107
108 foreach ( $this->getSortedNamespaces() as $text => $index ) {
109 $options[ $text ] = $index;
110 }
111
112 $formDescriptor = [
113 'textbox' => [
114 'type' => 'text',
115 'name' => 'message',
116 'id' => 'message',
117 'label-message' => 'translate-translations-messagename',
118 'size' => 30,
119 'default' => $title->getText(),
120 ],
121 'selector' => [
122 'type' => 'select',
123 'name' => 'namespace',
124 'id' => 'namespace',
125 'label-message' => 'translate-translations-project',
126 'options' => $options,
127 'default' => $title->getNamespace(),
128 ]
129 ];
130
131 $context = new DerivativeContext( $this->getContext() );
132 $context->setTitle( $this->getPageTitle() ); // Remove subpage
133
134 HTMLForm::factory( 'ooui', $formDescriptor, $context )
135 ->setMethod( 'get' )
136 ->setSubmitTextMsg( 'allpagessubmit' )
137 ->setWrapperLegendMsg( 'translate-translations-fieldset-title' )
138 ->prepareForm()
139 ->displayForm( false );
140 }
141
147 public function getSortedNamespaces(): array {
148 global $wgTranslateMessageNamespaces;
149
150 $nslist = [];
151 foreach ( $wgTranslateMessageNamespaces as $ns ) {
152 $nslist[$this->contentLanguage->getFormattedNsText( $ns )] = $ns;
153 }
154 ksort( $nslist );
155
156 return $nslist;
157 }
158
164 protected function showTranslations( Title $title ): void {
165 $handle = new MessageHandle( $title );
166 $namespace = $title->getNamespace();
167 $message = $handle->getKey();
168
169 if ( !$handle->isValid() ) {
170 $this->getOutput()->addWikiMsg( 'translate-translations-no-message', $title->getPrefixedText() );
171
172 return;
173 }
174
175 $dbr = wfGetDB( DB_REPLICA );
176
177 $res = $dbr->select( 'page',
178 [ 'page_namespace', 'page_title' ],
179 [
180 'page_namespace' => $namespace,
181 'page_title ' . $dbr->buildLike( "$message/", $dbr->anyString() ),
182 ],
183 __METHOD__,
184 [ 'ORDER BY' => 'page_title', ]
185 );
186
187 if ( !$res->numRows() ) {
188 $this->getOutput()->addWikiMsg(
189 'translate-translations-no-message',
190 $title->getPrefixedText()
191 );
192
193 return;
194 } else {
195 $this->getOutput()->addWikiMsg(
196 'translate-translations-count',
197 $this->getLanguage()->formatNum( $res->numRows() )
198 );
199 }
200
201 // Normal output.
202 $titles = [];
203
204 foreach ( $res as $s ) {
205 $titles[] = $s->page_title;
206 }
207
208 $pageInfo = TranslateUtils::getContents( $titles, $namespace );
209
210 $tableheader = Xml::openElement( 'table', [
211 'class' => 'mw-sp-translate-table sortable wikitable'
212 ] );
213
214 $tableheader .= Xml::openElement( 'tr' );
215 $tableheader .= Xml::element( 'th', null, $this->msg( 'allmessagesname' )->text() );
216 $tableheader .= Xml::element( 'th', null, $this->msg( 'allmessagescurrent' )->text() );
217 $tableheader .= Xml::closeElement( 'tr' );
218
219 // Adapted version of TranslateUtils:makeListing() by Nikerabbit.
220 $out = $tableheader;
221
222 $historyText = '&#160;<sup>' .
223 $this->msg( 'translate-translations-history-short' )->escaped() .
224 '</sup>&#160;';
225 $separator = $this->msg( 'word-separator' )->plain();
226
227 $tools = [];
228 foreach ( $res as $s ) {
229 $key = $s->page_title;
230 $tTitle = Title::makeTitle( $s->page_namespace, $key );
231 $tHandle = new MessageHandle( $tTitle );
232
233 $code = $tHandle->getCode();
234
235 $text = TranslateUtils::getLanguageName( $code, $this->getLanguage()->getCode() );
236 $text .= $separator;
237 $text .= $this->msg( 'parentheses' )->params( $code )->plain();
238 $tools['edit'] = Html::element(
239 'a',
240 [ 'href' => TranslateUtils::getEditorUrl( $tHandle ) ],
241 $text
242 );
243
244 $tools['history'] = $this->getLinkRenderer()->makeLink(
245 $tTitle,
246 new HtmlArmor( $historyText ),
247 [
248 'title' => $this->msg( 'history-title', $tTitle->getPrefixedDBkey() )->text()
249 ],
250 [ 'action' => 'history' ]
251 );
252
253 $class = '';
254 if ( MessageHandle::hasFuzzyString( $pageInfo[$key][0] ) || $tHandle->isFuzzy() ) {
255 $class = 'mw-sp-translate-fuzzy';
256 }
257
258 $languageAttributes = [];
259 if ( $this->languageNameUtils->isKnownLanguageTag( $code ) ) {
260 $language = $tHandle->getEffectiveLanguage();
261 $languageAttributes = [
262 'lang' => $language->getHtmlCode(),
263 'dir' => $language->getDir(),
264 ];
265 }
266
267 $formattedContent = TranslateUtils::convertWhiteSpaceToHTML( $pageInfo[$key][0] );
268
269 $leftColumn = $tools['history'] . $tools['edit'];
270 $out .= Xml::tags( 'tr', [ 'class' => $class ],
271 Xml::tags( 'td', null, $leftColumn ) .
272 Xml::tags( 'td', $languageAttributes, $formattedContent )
273 );
274 }
275
276 $out .= Xml::closeElement( 'table' );
277 $this->getOutput()->addHTML( $out );
278 }
279}
Implements a special page which shows all translations for a message.
execute( $par)
Entry point : initialise variables and call subfunctions.
showTranslations(Title $title)
Builds a table with all translations of $title.
Class for pointing to messages, like Title class is for titles.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
static convertWhiteSpaceToHTML( $message)
Escapes the message, and does some mangling to whitespace, so that it is preserved when outputted as-...