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 HtmlArmor;
8use HTMLForm;
9use Language;
12use MediaWiki\Html\Html;
13use MediaWiki\Languages\LanguageNameUtils;
14use MediaWiki\Specials\SpecialAllPages;
15use MediaWiki\Title\Title;
16use Wikimedia\Rdbms\ILoadBalancer;
17use Xml;
18
28class TranslationsSpecialPage extends SpecialAllPages {
29 private Language $contentLanguage;
30 private LanguageNameUtils $languageNameUtils;
31 private ILoadBalancer $loadBalancer;
32
33 public function __construct(
34 Language $contentLanguage,
35 LanguageNameUtils $languageNameUtils,
36 ILoadBalancer $loadBalancer
37 ) {
38 parent::__construct();
39 $this->mName = 'Translations';
40 $this->contentLanguage = $contentLanguage;
41 $this->languageNameUtils = $languageNameUtils;
42 $this->loadBalancer = $loadBalancer;
43 }
44
45 protected function getGroupName() {
46 return 'translation';
47 }
48
49 public function getDescription() {
50 return $this->msg( 'translations' );
51 }
52
58 public function execute( $par ) {
59 $this->setHeaders();
60 $this->outputHeader();
61
62 $out = $this->getOutput();
63 $out->addModuleStyles( 'ext.translate.specialpages.styles' );
64
65 $par = (string)$par;
66
67 if ( $this->including() ) {
68 $title = Title::newFromText( $par );
69 if ( !$title ) {
70 $out->addWikiMsg( 'translate-translations-including-no-param' );
71 } else {
72 $this->showTranslations( $title );
73 }
74
75 return;
76 }
77
81 $request = $this->getRequest();
82 $message = $request->getText( 'message' );
83 $namespace = $request->getInt( 'namespace', NS_MAIN );
84
85 if ( $message !== '' ) {
86 $title = Title::newFromText( $message, $namespace );
87 } else {
88 $title = Title::newFromText( $par, $namespace );
89 }
90
91 $out->addHelpLink(
92 'Help:Extension:Translate/Statistics_and_reporting#Translations_in_all_languages'
93 );
94
95 if ( !$title ) {
96 $title = Title::makeTitle( NS_MEDIAWIKI, '' );
97 $this->namespaceMessageForm( $title );
98 } else {
99 $this->namespaceMessageForm( $title );
100 $out->addHTML( '<br />' );
101 $this->showTranslations( $title );
102 }
103 }
104
110 protected function namespaceMessageForm( Title $title = null ): void {
111 $options = [];
112
113 foreach ( $this->getSortedNamespaces() as $text => $index ) {
114 $options[ $text ] = $index;
115 }
116
117 $formDescriptor = [
118 'textbox' => [
119 'type' => 'text',
120 'name' => 'message',
121 'id' => 'message',
122 'label-message' => 'translate-translations-messagename',
123 'size' => 30,
124 'default' => $title->getText(),
125 ],
126 'selector' => [
127 'type' => 'select',
128 'name' => 'namespace',
129 'id' => 'namespace',
130 'label-message' => 'translate-translations-project',
131 'options' => $options,
132 'default' => $title->getNamespace(),
133 ]
134 ];
135
136 $context = new DerivativeContext( $this->getContext() );
137 $context->setTitle( $this->getPageTitle() ); // Remove subpage
138
139 HTMLForm::factory( 'ooui', $formDescriptor, $context )
140 ->setMethod( 'get' )
141 ->setSubmitTextMsg( 'allpagessubmit' )
142 ->setWrapperLegendMsg( 'translate-translations-fieldset-title' )
143 ->prepareForm()
144 ->displayForm( false );
145 }
146
152 public function getSortedNamespaces(): array {
153 global $wgTranslateMessageNamespaces;
154
155 $nslist = [];
156 foreach ( $wgTranslateMessageNamespaces as $ns ) {
157 $nslist[$this->contentLanguage->getFormattedNsText( $ns )] = $ns;
158 }
159 ksort( $nslist );
160
161 return $nslist;
162 }
163
169 protected function showTranslations( Title $title ): void {
170 $handle = new MessageHandle( $title );
171 $namespace = $title->getNamespace();
172 $message = $handle->getKey();
173
174 if ( !$handle->isValid() ) {
175 $this->getOutput()->addWikiMsg( 'translate-translations-no-message', $title->getPrefixedText() );
176
177 return;
178 }
179
180 $dbr = $this->loadBalancer->getConnection( DB_REPLICA );
181 $res = $dbr->newSelectQueryBuilder()
182 ->select( [ 'page_namespace', 'page_title' ] )
183 ->from( 'page' )
184 ->where( [
185 'page_namespace' => $namespace,
186 'page_title ' . $dbr->buildLike( "$message/", $dbr->anyString() ),
187 ] )
188 ->caller( __METHOD__ )
189 ->orderBy( 'page_title' )
190 ->fetchResultSet();
191
192 if ( !$res->numRows() ) {
193 $this->getOutput()->addWikiMsg(
194 'translate-translations-no-message',
195 $title->getPrefixedText()
196 );
197
198 return;
199 } else {
200 $this->getOutput()->addWikiMsg(
201 'translate-translations-count',
202 $this->getLanguage()->formatNum( $res->numRows() )
203 );
204 }
205
206 // Normal output.
207 $titles = [];
208
209 foreach ( $res as $s ) {
210 $titles[] = $s->page_title;
211 }
212
213 $pageInfo = Utilities::getContents( $titles, $namespace );
214
215 $tableheader = Xml::openElement( 'table', [
216 'class' => 'mw-sp-translate-table sortable wikitable'
217 ] );
218
219 $tableheader .= Xml::openElement( 'tr' );
220 $tableheader .= Xml::element( 'th', null, $this->msg( 'allmessagesname' )->text() );
221 $tableheader .= Xml::element( 'th', null, $this->msg( 'allmessagescurrent' )->text() );
222 $tableheader .= Xml::closeElement( 'tr' );
223
224 // Adapted version of Utilities:makeListing() by Nikerabbit.
225 $out = $tableheader;
226
227 $historyText = "\u{00A0}<sup>" .
228 $this->msg( 'translate-translations-history-short' )->escaped() .
229 "</sup>\u{00A0}";
230 $separator = $this->msg( 'word-separator' )->plain();
231
232 $tools = [];
233 foreach ( $res as $s ) {
234 $key = $s->page_title;
235 $tTitle = Title::makeTitle( $s->page_namespace, $key );
236 $tHandle = new MessageHandle( $tTitle );
237
238 $code = $tHandle->getCode();
239
240 $text = Utilities::getLanguageName( $code, $this->getLanguage()->getCode() );
241 $text .= $separator;
242 $text .= $this->msg( 'parentheses' )->params( $code )->plain();
243 $tools['edit'] = Html::element(
244 'a',
245 [ 'href' => Utilities::getEditorUrl( $tHandle ) ],
246 $text
247 );
248
249 $tools['history'] = $this->getLinkRenderer()->makeLink(
250 $tTitle,
251 new HtmlArmor( $historyText ),
252 [
253 'title' => $this->msg( 'history-title', $tTitle->getPrefixedDBkey() )->text()
254 ],
255 [ 'action' => 'history' ]
256 );
257
258 $class = '';
259 if ( MessageHandle::hasFuzzyString( $pageInfo[$key][0] ) || $tHandle->isFuzzy() ) {
260 $class = 'mw-sp-translate-fuzzy';
261 }
262
263 $languageAttributes = [];
264 if ( $this->languageNameUtils->isKnownLanguageTag( $code ) ) {
265 $language = $tHandle->getEffectiveLanguage();
266 $languageAttributes = [
267 'lang' => $language->getHtmlCode(),
268 'dir' => $language->getDir(),
269 ];
270 }
271
272 $formattedContent = Utilities::convertWhiteSpaceToHTML( $pageInfo[$key][0] );
273
274 $leftColumn = $tools['history'] . $tools['edit'];
275 $out .= Xml::tags( 'tr', [ 'class' => $class ],
276 Xml::tags( 'td', null, $leftColumn ) .
277 Xml::tags( 'td', $languageAttributes, $formattedContent )
278 );
279 }
280
281 $out .= Xml::closeElement( 'table' );
282 $this->getOutput()->addHTML( $out );
283 }
284}
Class for pointing to messages, like Title class is for titles.
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.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:31