MediaWiki  master
SpecialPageLanguage.php
Go to the documentation of this file.
1 <?php
31 
41  private $goToUrl;
42 
45 
48 
50  private $loadBalancer;
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 ) {
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 }
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:911
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:385
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
SpecialPageLanguage\postText
postText()
Add post-text to the form.
Definition: SpecialPageLanguage.php:145
SpecialPageLanguage\$searchEngineFactory
SearchEngineFactory $searchEngineFactory
Definition: SpecialPageLanguage.php:53
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:789
SpecialPageLanguage\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialPageLanguage.php:332
MalformedTitleException\getMessageObject
getMessageObject()
Definition: MalformedTitleException.php:86
SpecialPageLanguage\onSubmit
onSubmit(array $data)
Definition: SpecialPageLanguage.php:165
FormSpecialPage
Special page which uses an HTMLForm to handle processing.
Definition: FormSpecialPage.php:31
SearchEngineFactory
Factory class for SearchEngine.
Definition: SearchEngineFactory.php:12
SpecialPageLanguage\$languageNameUtils
LanguageNameUtils $languageNameUtils
Definition: SpecialPageLanguage.php:47
SpecialPageLanguage\doesWrites
doesWrites()
Indicates whether this special page may perform database writes.
Definition: SpecialPageLanguage.php:74
SpecialPage\getAuthority
getAuthority()
Shortcut to get the Authority executing this instance.
Definition: SpecialPage.php:809
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:829
SpecialPageLanguage\changePageLanguage
static changePageLanguage(IContextSource $context, Title $title, $newLanguage, $reason, array $tags=[], IDatabase $dbw=null)
Definition: SpecialPageLanguage.php:215
SpecialPageLanguage\preText
preText()
Add pre-text to the form.
Definition: SpecialPageLanguage.php:78
SpecialPageLanguage\alterForm
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
Definition: SpecialPageLanguage.php:156
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
MediaWiki\Languages\LanguageNameUtils
A service that provides utilities to do with language names and codes.
Definition: LanguageNameUtils.php:42
SpecialPage\prefixSearchString
prefixSearchString( $search, $limit, $offset, SearchEngineFactory $searchEngineFactory=null)
Perform a regular substring search for prefixSearchSubpages.
Definition: SpecialPage.php:576
SpecialPageLanguage\getDisplayFormat
getDisplayFormat()
Get display format for the form.
Definition: SpecialPageLanguage.php:152
SpecialPage\getHookRunner
getHookRunner()
Definition: SpecialPage.php:1094
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:877
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2306
SpecialPageLanguage\__construct
__construct(IContentHandlerFactory $contentHandlerFactory, LanguageNameUtils $languageNameUtils, ILoadBalancer $loadBalancer, SearchEngineFactory $searchEngineFactory)
Definition: SpecialPageLanguage.php:61
LogPage
Class to simplify the use of log pages.
Definition: LogPage.php:38
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
$title
$title
Definition: testCompression.php:38
LogEventsList\showLogExtract
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Definition: LogEventsList.php:607
SpecialPageLanguage\$loadBalancer
ILoadBalancer $loadBalancer
Definition: SpecialPageLanguage.php:50
ApiMessage\create
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
Definition: ApiMessage.php:43
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:763
FormSpecialPage\$par
string null $par
The sub-page of the special page.
Definition: FormSpecialPage.php:36
Title\newFromTextThrow
static newFromTextThrow( $text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid,...
Definition: Title.php:420
SpecialPageLanguage\$goToUrl
string $goToUrl
URL to go to if language change successful.
Definition: SpecialPageLanguage.php:41
MediaWiki\Content\IContentHandlerFactory
Definition: IContentHandlerFactory.php:10
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
SpecialPageLanguage\showLogFragment
showLogFragment( $title)
Definition: SpecialPageLanguage.php:312
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1456
SpecialPageLanguage\prefixSearchSubpages
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
Definition: SpecialPageLanguage.php:328
IContextSource\getUser
getUser()
SpecialPageLanguage\onSuccess
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
Definition: SpecialPageLanguage.php:307
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
MediaWiki\Permissions\PermissionStatus
A StatusValue for permission errors.
Definition: PermissionStatus.php:34
HTMLForm\setSubmitTextMsg
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1420
Title
Represents a title within MediaWiki.
Definition: Title.php:49
SpecialPageLanguage\$contentHandlerFactory
IContentHandlerFactory $contentHandlerFactory
Definition: SpecialPageLanguage.php:44
MalformedTitleException
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Definition: MalformedTitleException.php:26
SpecialPageLanguage
Special page for changing the content language of a page.
Definition: SpecialPageLanguage.php:37
IContextSource\getConfig
getConfig()
Get the site configuration.
SpecialPageLanguage\getFormFields
getFormFields()
Get an HTMLForm descriptor array.
Definition: SpecialPageLanguage.php:83
ManualLogEntry
Class for creating new log entries and inserting them into the database.
Definition: ManualLogEntry.php:43
RawMessage
Variant of the Message class.
Definition: RawMessage.php:35
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:143