Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslationsSpecialPage.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorInterface;
5
6use HtmlArmor;
9use MediaWiki\Html\Html;
10use MediaWiki\HTMLForm\HTMLForm;
11use MediaWiki\Language\Language;
12use MediaWiki\Languages\LanguageNameUtils;
13use MediaWiki\Message\Message;
14use MediaWiki\SpecialPage\IncludableSpecialPage;
15use MediaWiki\Title\Title;
16use SearchEngineFactory;
17use Wikimedia\Rdbms\ILoadBalancer;
18
28class TranslationsSpecialPage extends IncludableSpecialPage {
29 private Language $contentLanguage;
30 private LanguageNameUtils $languageNameUtils;
31 private ILoadBalancer $loadBalancer;
32 private SearchEngineFactory $searchEngineFactory;
33
34 public function __construct(
35 Language $contentLanguage,
36 LanguageNameUtils $languageNameUtils,
37 ILoadBalancer $loadBalancer,
38 SearchEngineFactory $searchEngineFactory
39 ) {
40 parent::__construct( 'Translations' );
41 $this->contentLanguage = $contentLanguage;
42 $this->languageNameUtils = $languageNameUtils;
43 $this->loadBalancer = $loadBalancer;
44 $this->searchEngineFactory = $searchEngineFactory;
45 }
46
47 protected function getGroupName(): string {
48 return 'translation';
49 }
50
52 public function getDescription() {
53 return $this->msg( 'translations' );
54 }
55
57 public function prefixSearchSubpages( $search, $limit, $offset ) {
58 return $this->prefixSearchString( $search, $limit, $offset, $this->searchEngineFactory );
59 }
60
66 public function execute( $par ) {
67 $this->setHeaders();
68 $this->outputHeader();
69
70 $out = $this->getOutput();
71 $out->addModuleStyles( 'ext.translate.specialpages.styles' );
72
73 $par = (string)$par;
74
75 if ( $this->including() ) {
76 $title = Title::newFromText( $par );
77 if ( !$title ) {
78 $out->addWikiMsg( 'translate-translations-including-no-param' );
79 } else {
80 $this->showTranslations( $title );
81 }
82
83 return;
84 }
85
89 $request = $this->getRequest();
90 $message = $request->getText( 'message', $par );
91 $namespace = $request->getInt( 'namespace', NS_MAIN );
92
93 $title = Title::newFromText( $message, $namespace );
94
95 $out->addHelpLink(
96 'Help:Extension:Translate/Statistics_and_reporting#Translations_in_all_languages'
97 );
98
99 if ( !$title ) {
100 $title = Title::makeTitle( NS_MEDIAWIKI, '' );
101 $this->namespaceMessageForm( $title );
102 } else {
103 $this->namespaceMessageForm( $title );
104 $out->addHTML( '<br />' );
105 $this->showTranslations( $title );
106 }
107 }
108
112 private function namespaceMessageForm( Title $title ): void {
113 $formDescriptor = [
114 'textbox' => [
115 'type' => 'text',
116 'name' => 'message',
117 'id' => 'message',
118 'label-message' => 'translate-translations-messagename',
119 'size' => 30,
120 'default' => $title->getText(),
121 ],
122 'selector' => [
123 'type' => 'select',
124 'name' => 'namespace',
125 'id' => 'namespace',
126 'label-message' => 'translate-translations-project',
127 'options' => $this->getSortedNamespaces(),
128 'default' => $title->getNamespace(),
129 ]
130 ];
131
132 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
133 ->setMethod( 'get' )
134 ->setTitle( $this->getPageTitle() ) // Remove subpage
135 ->setSubmitTextMsg( 'allpagessubmit' )
136 ->setWrapperLegendMsg( 'translate-translations-fieldset-title' )
137 ->prepareForm()
138 ->displayForm( false );
139 }
140
146 private function getSortedNamespaces(): array {
147 $nslist = [];
148 foreach ( $this->getConfig()->get( 'TranslateMessageNamespaces' ) as $ns ) {
149 $nslist[$this->contentLanguage->getFormattedNsText( $ns )] = $ns;
150 }
151 ksort( $nslist );
152
153 return $nslist;
154 }
155
159 private function showTranslations( Title $title ): void {
160 $handle = new MessageHandle( $title );
161 $namespace = $title->getNamespace();
162 $message = $handle->getKey();
163
164 if ( !$handle->isValid() ) {
165 $this->getOutput()->addWikiMsg( 'translate-translations-no-message', $title->getPrefixedText() );
166
167 return;
168 }
169
170 $dbr = $this->loadBalancer->getConnection( DB_REPLICA );
172 $titles = $dbr->newSelectQueryBuilder()
173 ->select( 'page_title' )
174 ->from( 'page' )
175 ->where( [
176 'page_namespace' => $namespace,
177 'page_title ' . $dbr->buildLike( "$message/", $dbr->anyString() ),
178 ] )
179 ->caller( __METHOD__ )
180 ->orderBy( 'page_title' )
181 ->fetchFieldValues();
182
183 if ( !$titles ) {
184 $this->getOutput()->addWikiMsg(
185 'translate-translations-no-message',
186 $title->getPrefixedText()
187 );
188
189 return;
190 } else {
191 $this->getOutput()->addWikiMsg(
192 'translate-translations-count',
193 Message::numParam( count( $titles ) )
194 );
195 }
196
197 $pageInfo = Utilities::getContents( $titles, $namespace );
198
199 $rows = [
200 Html::rawElement(
201 'tr',
202 [],
203 Html::element( 'th', [], $this->msg( 'allmessagesname' )->text() ) .
204 Html::element( 'th', [], $this->msg( 'allmessagescurrent' )->text() )
205 ),
206 ];
207
208 $historyText = "\u{00A0}<sup>" .
209 $this->msg( 'translate-translations-history-short' )->escaped() .
210 "</sup>\u{00A0}";
211 $separator = $this->msg( 'word-separator' )->plain();
212
213 foreach ( $titles as $key ) {
214 $tTitle = Title::makeTitle( $namespace, $key );
215 $tHandle = new MessageHandle( $tTitle );
216
217 $code = $tHandle->getCode();
218
219 $text = Utilities::getLanguageName( $code, $this->getLanguage()->getCode() );
220 $text .= $separator;
221 $text .= $this->msg( 'parentheses' )->params( $code )->plain();
222 $tools = [
223 'edit' => Html::element(
224 'a',
225 [ 'href' => Utilities::getEditorUrl( $tHandle ) ],
226 $text
227 ),
228 'history' => $this->getLinkRenderer()->makeLink(
229 $tTitle,
230 new HtmlArmor( $historyText ),
231 [
232 'title' => $this->msg( 'history-title', $tTitle->getPrefixedDBkey() )->text()
233 ],
234 [ 'action' => 'history' ]
235 ),
236 ];
237
238 $class = '';
239 if ( MessageHandle::hasFuzzyString( $pageInfo[$key][0] ) || $tHandle->isFuzzy() ) {
240 $class = 'mw-sp-translate-fuzzy';
241 }
242
243 $languageAttributes = [];
244 if ( $this->languageNameUtils->isKnownLanguageTag( $code ) ) {
245 $language = $tHandle->getEffectiveLanguage();
246 $languageAttributes = [
247 'lang' => $language->getHtmlCode(),
248 'dir' => $language->getDir(),
249 ];
250 }
251
252 $formattedContent = Utilities::convertWhiteSpaceToHTML( $pageInfo[$key][0] );
253
254 $rows[] = Html::rawElement(
255 'tr',
256 [ 'class' => $class ],
257 Html::rawElement( 'td', [], $tools['history'] . $tools['edit'] ) .
258 Html::rawElement( 'td', $languageAttributes, $formattedContent )
259 );
260 }
261
262 $out = Html::rawElement(
263 'table',
264 [ 'class' => 'mw-sp-translate-table sortable wikitable' ],
265 "\n" . implode( "\n", $rows ) . "\n"
266 );
267 $this->getOutput()->addHTML( $out );
268 }
269}
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.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:29