MediaWiki  master
SpecialPageLanguage.php
Go to the documentation of this file.
1 <?php
35  private $goToUrl;
36 
37  public function __construct() {
38  parent::__construct( 'PageLanguage', 'pagelang' );
39  }
40 
41  public function doesWrites() {
42  return true;
43  }
44 
45  protected function preText() {
46  $this->getOutput()->addModules( 'mediawiki.misc-authed-ooui' );
47  return parent::preText();
48  }
49 
50  protected function getFormFields() {
51  // Get default from the subpage of Special page
52  $defaultName = $this->par;
53  $title = $defaultName ? Title::newFromText( $defaultName ) : null;
54  if ( $title ) {
55  $defaultPageLanguage =
56  ContentHandler::getForTitle( $title )->getPageLanguage( $title );
57  $hasCustomLanguageSet = !$defaultPageLanguage->equals( $title->getPageLanguage() );
58  } else {
59  $hasCustomLanguageSet = false;
60  }
61 
62  $page = [];
63  $page['pagename'] = [
64  'type' => 'title',
65  'label-message' => 'pagelang-name',
66  'default' => $title ? $title->getPrefixedText() : $defaultName,
67  'autofocus' => $defaultName === null,
68  'exists' => true,
69  ];
70 
71  // Options for whether to use the default language or select language
72  $selectoptions = [
73  (string)$this->msg( 'pagelang-use-default' )->escaped() => 1,
74  (string)$this->msg( 'pagelang-select-lang' )->escaped() => 2,
75  ];
76  $page['selectoptions'] = [
77  'id' => 'mw-pl-options',
78  'type' => 'radio',
79  'options' => $selectoptions,
80  'default' => $hasCustomLanguageSet ? 2 : 1
81  ];
82 
83  // Building a language selector
84  $userLang = $this->getLanguage()->getCode();
85  $languages = Language::fetchLanguageNames( $userLang, 'mwfile' );
86  $options = [];
87  foreach ( $languages as $code => $name ) {
88  $options["$code - $name"] = $code;
89  }
90 
91  $page['language'] = [
92  'id' => 'mw-pl-languageselector',
93  'cssclass' => 'mw-languageselector',
94  'type' => 'select',
95  'options' => $options,
96  'label-message' => 'pagelang-language',
97  'default' => $title ?
98  $title->getPageLanguage()->getCode() :
99  $this->getConfig()->get( 'LanguageCode' ),
100  ];
101 
102  // Allow user to enter a comment explaining the change
103  $page['reason'] = [
104  'type' => 'text',
105  'label-message' => 'pagelang-reason'
106  ];
107 
108  return $page;
109  }
110 
111  protected function postText() {
112  if ( $this->par ) {
113  return $this->showLogFragment( $this->par );
114  }
115  return '';
116  }
117 
118  protected function getDisplayFormat() {
119  return 'ooui';
120  }
121 
122  public function alterForm( HTMLForm $form ) {
123  Hooks::run( 'LanguageSelector', [ $this->getOutput(), 'mw-languageselector' ] );
124  $form->setSubmitTextMsg( 'pagelang-submit' );
125  }
126 
132  public function onSubmit( array $data ) {
133  $pageName = $data['pagename'];
134 
135  // Check if user wants to use default language
136  if ( $data['selectoptions'] == 1 ) {
137  $newLanguage = 'default';
138  } else {
139  $newLanguage = $data['language'];
140  }
141 
142  try {
143  $title = Title::newFromTextThrow( $pageName );
144  } catch ( MalformedTitleException $ex ) {
145  return Status::newFatal( $ex->getMessageObject() );
146  }
147 
148  // Check permissions and make sure the user has permission to edit the page
149  $errors = $title->getUserPermissionsErrors( 'edit', $this->getUser() );
150 
151  if ( $errors ) {
152  $out = $this->getOutput();
153  $wikitext = $out->formatPermissionsErrorMessage( $errors );
154  // Hack to get our wikitext parsed
155  return Status::newFatal( new RawMessage( '$1', [ $wikitext ] ) );
156  }
157 
158  // Url to redirect to after the operation
159  $this->goToUrl = $title->getFullUrlForRedirect(
160  $title->isRedirect() ? [ 'redirect' => 'no' ] : []
161  );
162 
163  return self::changePageLanguage(
164  $this->getContext(),
165  $title,
166  $newLanguage,
167  $data['reason'] ?? ''
168  );
169  }
170 
180  $newLanguage, $reason, array $tags = [] ) {
181  // Get the default language for the wiki
182  $defLang = $context->getConfig()->get( 'LanguageCode' );
183 
184  $pageId = $title->getArticleID();
185 
186  // Check if article exists
187  if ( !$pageId ) {
188  return Status::newFatal(
189  'pagelang-nonexistent-page',
190  wfEscapeWikiText( $title->getPrefixedText() )
191  );
192  }
193 
194  // Load the page language from DB
195  $dbw = wfGetDB( DB_MASTER );
196  $oldLanguage = $dbw->selectField(
197  'page',
198  'page_lang',
199  [ 'page_id' => $pageId ],
200  __METHOD__
201  );
202 
203  // Check if user wants to use the default language
204  if ( $newLanguage === 'default' ) {
205  $newLanguage = null;
206  }
207 
208  // No change in language
209  if ( $newLanguage === $oldLanguage ) {
210  // Check if old language does not exist
211  if ( !$oldLanguage ) {
213  [
214  'pagelang-unchanged-language-default',
215  wfEscapeWikiText( $title->getPrefixedText() )
216  ],
217  'pagelang-unchanged-language'
218  ) );
219  }
220  return Status::newFatal(
221  'pagelang-unchanged-language',
222  wfEscapeWikiText( $title->getPrefixedText() ),
223  $oldLanguage
224  );
225  }
226 
227  // Hardcoded [def] if the language is set to null
228  $logOld = $oldLanguage ?: $defLang . '[def]';
229  $logNew = $newLanguage ?: $defLang . '[def]';
230 
231  // Writing new page language to database
232  $dbw->update(
233  'page',
234  [ 'page_lang' => $newLanguage ],
235  [
236  'page_id' => $pageId,
237  'page_lang' => $oldLanguage
238  ],
239  __METHOD__
240  );
241 
242  if ( !$dbw->affectedRows() ) {
243  return Status::newFatal( 'pagelang-db-failed' );
244  }
245 
246  // Logging change of language
247  $logParams = [
248  '4::oldlanguage' => $logOld,
249  '5::newlanguage' => $logNew
250  ];
251  $entry = new ManualLogEntry( 'pagelang', 'pagelang' );
252  $entry->setPerformer( $context->getUser() );
253  $entry->setTarget( $title );
254  $entry->setParameters( $logParams );
255  $entry->setComment( $reason );
256  $entry->addTags( $tags );
257 
258  $logid = $entry->insert();
259  $entry->publish( $logid );
260 
261  // Force re-render so that language-based content (parser functions etc.) gets updated
262  $title->invalidateCache();
263 
264  return Status::newGood( (object)[
265  'oldLanguage' => $logOld,
266  'newLanguage' => $logNew,
267  'logId' => $logid,
268  ] );
269  }
270 
271  public function onSuccess() {
272  // Success causes a redirect
273  $this->getOutput()->redirect( $this->goToUrl );
274  }
275 
276  function showLogFragment( $title ) {
277  $moveLogPage = new LogPage( 'pagelang' );
278  $out1 = Xml::element( 'h2', null, $moveLogPage->getName()->text() );
279  $out2 = '';
280  LogEventsList::showLogExtract( $out2, 'pagelang', $title );
281  return $out1 . $out2;
282  }
283 
292  public function prefixSearchSubpages( $search, $limit, $offset ) {
293  return $this->prefixSearchString( $search, $limit, $offset );
294  }
295 
296  protected function getGroupName() {
297  return 'pagetools';
298  }
299 }
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:69
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking, formatting, etc.
invalidateCache( $purgeTime=null)
Updates page_touched for this page; called from LinksUpdate.php.
Definition: Title.php:4344
getArticleID( $flags=0)
Get the article ID for this Title from the link cache, adding it if necessary.
Definition: Title.php:3166
static fetchLanguageNames( $inLanguage=self::AS_AUTONYMS, $include='mw')
Get an array of language names, indexed by code.
Definition: Language.php:814
$context
Definition: load.php:45
getContext()
Gets the context this SpecialPage is executed in.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
static changePageLanguage(IContextSource $context, Title $title, $newLanguage, $reason, array $tags=[])
getOutput()
Get the OutputPage being used for this instance.
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1858
Special page which uses an HTMLForm to handle processing.
const DB_MASTER
Definition: defines.php:26
Special page for changing the content language of a page.
Class to simplify the use of log pages.
Definition: LogPage.php:33
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Get the site configuration.
prefixSearchString( $search, $limit, $offset)
Perform a regular substring search for prefixSearchSubpages.
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
static newFromTextThrow( $text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid, rather than returning null.
Definition: Title.php:354
string null $par
The sub-page of the special page.
Variant of the Message class.
Definition: RawMessage.php:34
getUser()
Shortcut to get the User executing this instance.
getConfig()
Shortcut to get main config object.
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
getLanguage()
Shortcut to get user&#39;s language.
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1392
string $goToUrl
URL to go to if language change successful.
switch( $options['output']) $languages
Definition: transstat.php:76
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
Definition: ApiMessage.php:40
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:319