MediaWiki REL1_37
SpecialPageLanguage.php
Go to the documentation of this file.
1<?php
31
41 private $goToUrl;
42
45
48
51
54
61 public function __construct(
66 ) {
67 parent::__construct( 'PageLanguage', 'pagelang' );
68 $this->contentHandlerFactory = $contentHandlerFactory;
69 $this->languageNameUtils = $languageNameUtils;
70 $this->loadBalancer = $loadBalancer;
71 $this->searchEngineFactory = $searchEngineFactory;
72 }
73
74 public function doesWrites() {
75 return true;
76 }
77
78 protected function preText() {
79 $this->getOutput()->addModules( 'mediawiki.misc-authed-ooui' );
80 return parent::preText();
81 }
82
83 protected function getFormFields() {
84 // Get default from the subpage of Special page
85 $defaultName = $this->par;
86 $title = $defaultName ? Title::newFromText( $defaultName ) : null;
87 if ( $title ) {
88 $defaultPageLanguage = $this->contentHandlerFactory->getContentHandler( $title->getContentModel() )
89 ->getPageLanguage( $title );
90
91 $hasCustomLanguageSet = !$defaultPageLanguage->equals( $title->getPageLanguage() );
92 } else {
93 $hasCustomLanguageSet = false;
94 }
95
96 $page = [];
97 $page['pagename'] = [
98 'type' => 'title',
99 'label-message' => 'pagelang-name',
100 'default' => $title ? $title->getPrefixedText() : $defaultName,
101 'autofocus' => $defaultName === null,
102 'exists' => true,
103 ];
104
105 // Options for whether to use the default language or select language
106 $selectoptions = [
107 (string)$this->msg( 'pagelang-use-default' )->escaped() => 1,
108 (string)$this->msg( 'pagelang-select-lang' )->escaped() => 2,
109 ];
110 $page['selectoptions'] = [
111 'id' => 'mw-pl-options',
112 'type' => 'radio',
113 'options' => $selectoptions,
114 'default' => $hasCustomLanguageSet ? 2 : 1
115 ];
116
117 // Building a language selector
118 $userLang = $this->getLanguage()->getCode();
119 $languages = $this->languageNameUtils->getLanguageNames( $userLang, 'mwfile' );
120 $options = [];
121 foreach ( $languages as $code => $name ) {
122 $options["$code - $name"] = $code;
123 }
124
125 $page['language'] = [
126 'id' => 'mw-pl-languageselector',
127 'cssclass' => 'mw-languageselector',
128 'type' => 'select',
129 'options' => $options,
130 'label-message' => 'pagelang-language',
131 'default' => $title ?
132 $title->getPageLanguage()->getCode() :
133 $this->getConfig()->get( 'LanguageCode' ),
134 ];
135
136 // Allow user to enter a comment explaining the change
137 $page['reason'] = [
138 'type' => 'text',
139 'label-message' => 'pagelang-reason'
140 ];
141
142 return $page;
143 }
144
145 protected function postText() {
146 if ( $this->par ) {
147 return $this->showLogFragment( $this->par );
148 }
149 return '';
150 }
151
152 protected function getDisplayFormat() {
153 return 'ooui';
154 }
155
156 public function alterForm( HTMLForm $form ) {
157 $this->getHookRunner()->onLanguageSelector( $this->getOutput(), 'mw-languageselector' );
158 $form->setSubmitTextMsg( 'pagelang-submit' );
159 }
160
165 public function onSubmit( array $data ) {
166 $pageName = $data['pagename'];
167
168 // Check if user wants to use default language
169 if ( $data['selectoptions'] == 1 ) {
170 $newLanguage = 'default';
171 } else {
172 $newLanguage = $data['language'];
173 }
174
175 try {
176 $title = Title::newFromTextThrow( $pageName );
177 } catch ( MalformedTitleException $ex ) {
178 return Status::newFatal( $ex->getMessageObject() );
179 }
180
181 // Check permissions and make sure the user has permission to edit the page
182 $status = PermissionStatus::newEmpty();
183 if ( !$this->getAuthority()->authorizeWrite( 'edit', $title, $status ) ) {
184 $wikitext = $this->getOutput()->formatPermissionStatus( $status );
185 // Hack to get our wikitext parsed
186 return Status::newFatal( new RawMessage( '$1', [ $wikitext ] ) );
187 }
188
189 // Url to redirect to after the operation
190 $this->goToUrl = $title->getFullUrlForRedirect(
191 $title->isRedirect() ? [ 'redirect' => 'no' ] : []
192 );
193
195 $this->getContext(),
196 $title,
197 $newLanguage,
198 $data['reason'] ?? '',
199 [],
200 $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_PRIMARY )
201 );
202 }
203
215 public static function changePageLanguage( IContextSource $context, Title $title,
216 $newLanguage, $reason, array $tags = [], IDatabase $dbw = null ) {
217 // Get the default language for the wiki
218 $defLang = $context->getConfig()->get( 'LanguageCode' );
219
220 $pageId = $title->getArticleID();
221
222 // Check if article exists
223 if ( !$pageId ) {
224 return Status::newFatal(
225 'pagelang-nonexistent-page',
226 wfEscapeWikiText( $title->getPrefixedText() )
227 );
228 }
229
230 // Load the page language from DB
231 $dbw = $dbw ?? wfGetDB( DB_PRIMARY );
232 $oldLanguage = $dbw->selectField(
233 'page',
234 'page_lang',
235 [ 'page_id' => $pageId ],
236 __METHOD__
237 );
238
239 // Check if user wants to use the default language
240 if ( $newLanguage === 'default' ) {
241 $newLanguage = null;
242 }
243
244 // No change in language
245 if ( $newLanguage === $oldLanguage ) {
246 // Check if old language does not exist
247 if ( !$oldLanguage ) {
248 return Status::newFatal( ApiMessage::create(
249 [
250 'pagelang-unchanged-language-default',
251 wfEscapeWikiText( $title->getPrefixedText() )
252 ],
253 'pagelang-unchanged-language'
254 ) );
255 }
256 return Status::newFatal(
257 'pagelang-unchanged-language',
258 wfEscapeWikiText( $title->getPrefixedText() ),
259 $oldLanguage
260 );
261 }
262
263 // Hardcoded [def] if the language is set to null
264 $logOld = $oldLanguage ?: $defLang . '[def]';
265 $logNew = $newLanguage ?: $defLang . '[def]';
266
267 // Writing new page language to database
268 $dbw->update(
269 'page',
270 [ 'page_lang' => $newLanguage ],
271 [
272 'page_id' => $pageId,
273 'page_lang' => $oldLanguage
274 ],
275 __METHOD__
276 );
277
278 if ( !$dbw->affectedRows() ) {
279 return Status::newFatal( 'pagelang-db-failed' );
280 }
281
282 // Logging change of language
283 $logParams = [
284 '4::oldlanguage' => $logOld,
285 '5::newlanguage' => $logNew
286 ];
287 $entry = new ManualLogEntry( 'pagelang', 'pagelang' );
288 $entry->setPerformer( $context->getUser() );
289 $entry->setTarget( $title );
290 $entry->setParameters( $logParams );
291 $entry->setComment( $reason );
292 $entry->addTags( $tags );
293
294 $logid = $entry->insert();
295 $entry->publish( $logid );
296
297 // Force re-render so that language-based content (parser functions etc.) gets updated
298 $title->invalidateCache();
299
300 return Status::newGood( (object)[
301 'oldLanguage' => $logOld,
302 'newLanguage' => $logNew,
303 'logId' => $logid,
304 ] );
305 }
306
307 public function onSuccess() {
308 // Success causes a redirect
309 $this->getOutput()->redirect( $this->goToUrl );
310 }
311
312 private function showLogFragment( $title ) {
313 $moveLogPage = new LogPage( 'pagelang' );
314 $out1 = Xml::element( 'h2', null, $moveLogPage->getName()->text() );
315 $out2 = '';
316 LogEventsList::showLogExtract( $out2, 'pagelang', $title );
317 return $out1 . $out2;
318 }
319
328 public function prefixSearchSubpages( $search, $limit, $offset ) {
329 return $this->prefixSearchString( $search, $limit, $offset, $this->searchEngineFactory );
330 }
331
332 protected function getGroupName() {
333 return 'pagetools';
334 }
335}
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Special page which uses an HTMLForm to handle processing.
string null $par
The sub-page of the special page.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:143
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Class to simplify the use of log pages.
Definition LogPage.php:38
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Class for creating new log entries and inserting them into the database.
A service that provides utilities to do with language names and codes.
A StatusValue for permission errors.
Variant of the Message class.
Factory class for SearchEngine.
Special page for changing the content language of a page.
getFormFields()
Get an HTMLForm descriptor array.
SearchEngineFactory $searchEngineFactory
postText()
Add post-text to the form.
LanguageNameUtils $languageNameUtils
static changePageLanguage(IContextSource $context, Title $title, $newLanguage, $reason, array $tags=[], IDatabase $dbw=null)
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
__construct(IContentHandlerFactory $contentHandlerFactory, LanguageNameUtils $languageNameUtils, ILoadBalancer $loadBalancer, SearchEngineFactory $searchEngineFactory)
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
IContentHandlerFactory $contentHandlerFactory
doesWrites()
Indicates whether this special page may perform database writes.
getDisplayFormat()
Get display format for the form.
string $goToUrl
URL to go to if language change successful.
preText()
Add pre-text to the form.
getOutput()
Get the OutputPage being used for this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getConfig()
Shortcut to get main config object.
prefixSearchString( $search, $limit, $offset, SearchEngineFactory $searchEngineFactory=null)
Perform a regular substring search for prefixSearchSubpages.
getLanguage()
Shortcut to get user's language.
Represents a title within MediaWiki.
Definition Title.php:48
Interface for objects which can provide a MediaWiki context on request.
getConfig()
Get the site configuration.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
Database cluster connection, tracking, load balancing, and transaction manager interface.
const DB_PRIMARY
Definition defines.php:27