MediaWiki fundraising/REL1_35
SpecialPageLanguage.php
Go to the documentation of this file.
1<?php
27
37 private $goToUrl;
38
39 public function __construct() {
40 parent::__construct( 'PageLanguage', 'pagelang' );
41 }
42
43 public function doesWrites() {
44 return true;
45 }
46
47 protected function preText() {
48 $this->getOutput()->addModules( 'mediawiki.misc-authed-ooui' );
49 return parent::preText();
50 }
51
52 protected function getFormFields() {
53 // Get default from the subpage of Special page
54 $defaultName = $this->par;
55 $title = $defaultName ? Title::newFromText( $defaultName ) : null;
56 if ( $title ) {
57 $defaultPageLanguage = MediaWikiServices::getInstance()
58 ->getContentHandlerFactory()
59 ->getContentHandler( $title->getContentModel() )
60 ->getPageLanguage( $title );
61
62 $hasCustomLanguageSet = !$defaultPageLanguage->equals( $title->getPageLanguage() );
63 } else {
64 $hasCustomLanguageSet = false;
65 }
66
67 $page = [];
68 $page['pagename'] = [
69 'type' => 'title',
70 'label-message' => 'pagelang-name',
71 'default' => $title ? $title->getPrefixedText() : $defaultName,
72 'autofocus' => $defaultName === null,
73 'exists' => true,
74 ];
75
76 // Options for whether to use the default language or select language
77 $selectoptions = [
78 (string)$this->msg( 'pagelang-use-default' )->escaped() => 1,
79 (string)$this->msg( 'pagelang-select-lang' )->escaped() => 2,
80 ];
81 $page['selectoptions'] = [
82 'id' => 'mw-pl-options',
83 'type' => 'radio',
84 'options' => $selectoptions,
85 'default' => $hasCustomLanguageSet ? 2 : 1
86 ];
87
88 // Building a language selector
89 $userLang = $this->getLanguage()->getCode();
90 $languages = MediaWikiServices::getInstance()
91 ->getLanguageNameUtils()
92 ->getLanguageNames( $userLang, 'mwfile' );
93 $options = [];
94 foreach ( $languages as $code => $name ) {
95 $options["$code - $name"] = $code;
96 }
97
98 $page['language'] = [
99 'id' => 'mw-pl-languageselector',
100 'cssclass' => 'mw-languageselector',
101 'type' => 'select',
102 'options' => $options,
103 'label-message' => 'pagelang-language',
104 'default' => $title ?
105 $title->getPageLanguage()->getCode() :
106 $this->getConfig()->get( 'LanguageCode' ),
107 ];
108
109 // Allow user to enter a comment explaining the change
110 $page['reason'] = [
111 'type' => 'text',
112 'label-message' => 'pagelang-reason'
113 ];
114
115 return $page;
116 }
117
118 protected function postText() {
119 if ( $this->par ) {
120 return $this->showLogFragment( $this->par );
121 }
122 return '';
123 }
124
125 protected function getDisplayFormat() {
126 return 'ooui';
127 }
128
129 public function alterForm( HTMLForm $form ) {
130 $this->getHookRunner()->onLanguageSelector( $this->getOutput(), 'mw-languageselector' );
131 $form->setSubmitTextMsg( 'pagelang-submit' );
132 }
133
138 public function onSubmit( array $data ) {
139 $pageName = $data['pagename'];
140
141 // Check if user wants to use default language
142 if ( $data['selectoptions'] == 1 ) {
143 $newLanguage = 'default';
144 } else {
145 $newLanguage = $data['language'];
146 }
147
148 try {
149 $title = Title::newFromTextThrow( $pageName );
150 } catch ( MalformedTitleException $ex ) {
151 return Status::newFatal( $ex->getMessageObject() );
152 }
153
154 // Check permissions and make sure the user has permission to edit the page
155 $errors = MediaWikiServices::getInstance()->getPermissionManager()
156 ->getPermissionErrors( 'edit', $this->getUser(), $title );
157
158 if ( $errors ) {
159 $out = $this->getOutput();
160 $wikitext = $out->formatPermissionsErrorMessage( $errors );
161 // Hack to get our wikitext parsed
162 return Status::newFatal( new RawMessage( '$1', [ $wikitext ] ) );
163 }
164
165 // Url to redirect to after the operation
166 $this->goToUrl = $title->getFullUrlForRedirect(
167 $title->isRedirect() ? [ 'redirect' => 'no' ] : []
168 );
169
171 $this->getContext(),
172 $title,
173 $newLanguage,
174 $data['reason'] ?? ''
175 );
176 }
177
186 public static function changePageLanguage( IContextSource $context, Title $title,
187 $newLanguage, $reason, array $tags = [] ) {
188 // Get the default language for the wiki
189 $defLang = $context->getConfig()->get( 'LanguageCode' );
190
191 $pageId = $title->getArticleID();
192
193 // Check if article exists
194 if ( !$pageId ) {
195 return Status::newFatal(
196 'pagelang-nonexistent-page',
197 wfEscapeWikiText( $title->getPrefixedText() )
198 );
199 }
200
201 // Load the page language from DB
202 $dbw = wfGetDB( DB_MASTER );
203 $oldLanguage = $dbw->selectField(
204 'page',
205 'page_lang',
206 [ 'page_id' => $pageId ],
207 __METHOD__
208 );
209
210 // Check if user wants to use the default language
211 if ( $newLanguage === 'default' ) {
212 $newLanguage = null;
213 }
214
215 // No change in language
216 if ( $newLanguage === $oldLanguage ) {
217 // Check if old language does not exist
218 if ( !$oldLanguage ) {
219 return Status::newFatal( ApiMessage::create(
220 [
221 'pagelang-unchanged-language-default',
222 wfEscapeWikiText( $title->getPrefixedText() )
223 ],
224 'pagelang-unchanged-language'
225 ) );
226 }
227 return Status::newFatal(
228 'pagelang-unchanged-language',
229 wfEscapeWikiText( $title->getPrefixedText() ),
230 $oldLanguage
231 );
232 }
233
234 // Hardcoded [def] if the language is set to null
235 $logOld = $oldLanguage ?: $defLang . '[def]';
236 $logNew = $newLanguage ?: $defLang . '[def]';
237
238 // Writing new page language to database
239 $dbw->update(
240 'page',
241 [ 'page_lang' => $newLanguage ],
242 [
243 'page_id' => $pageId,
244 'page_lang' => $oldLanguage
245 ],
246 __METHOD__
247 );
248
249 if ( !$dbw->affectedRows() ) {
250 return Status::newFatal( 'pagelang-db-failed' );
251 }
252
253 // Logging change of language
254 $logParams = [
255 '4::oldlanguage' => $logOld,
256 '5::newlanguage' => $logNew
257 ];
258 $entry = new ManualLogEntry( 'pagelang', 'pagelang' );
259 $entry->setPerformer( $context->getUser() );
260 $entry->setTarget( $title );
261 $entry->setParameters( $logParams );
262 $entry->setComment( $reason );
263 $entry->addTags( $tags );
264
265 $logid = $entry->insert();
266 $entry->publish( $logid );
267
268 // Force re-render so that language-based content (parser functions etc.) gets updated
269 $title->invalidateCache();
270
271 return Status::newGood( (object)[
272 'oldLanguage' => $logOld,
273 'newLanguage' => $logNew,
274 'logId' => $logid,
275 ] );
276 }
277
278 public function onSuccess() {
279 // Success causes a redirect
280 $this->getOutput()->redirect( $this->goToUrl );
281 }
282
283 private function showLogFragment( $title ) {
284 $moveLogPage = new LogPage( 'pagelang' );
285 $out1 = Xml::element( 'h2', null, $moveLogPage->getName()->text() );
286 $out2 = '';
287 LogEventsList::showLogExtract( $out2, 'pagelang', $title );
288 return $out1 . $out2;
289 }
290
299 public function prefixSearchSubpages( $search, $limit, $offset ) {
300 return $this->prefixSearchString( $search, $limit, $offset );
301 }
302
303 protected function getGroupName() {
304 return 'pagetools';
305 }
306}
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:135
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Class to simplify the use of log pages.
Definition LogPage.php:37
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.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Variant of the Message class.
Special page for changing the content language of a page.
getFormFields()
Get an HTMLForm descriptor array.
postText()
Add post-text to the form.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
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...
static changePageLanguage(IContextSource $context, Title $title, $newLanguage, $reason, array $tags=[])
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
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.
getUser()
Shortcut to get the User executing this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getLanguage()
Shortcut to get user's language.
prefixSearchString( $search, $limit, $offset)
Perform a regular substring search for prefixSearchSubpages.
Represents a title within MediaWiki.
Definition Title.php:42
Interface for objects which can provide a MediaWiki context on request.
getConfig()
Get the site configuration.
const DB_MASTER
Definition defines.php:29