]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/specials/SpecialPageLanguage.php
MediaWiki 1.30.2 renames
[autoinstallsdev/mediawiki.git] / includes / specials / SpecialPageLanguage.php
1 <?php
2 /**
3  * Implements Special:PageLanguage
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  * @ingroup SpecialPage
22  * @author Kunal Grover
23  * @since 1.24
24  */
25
26 /**
27  * Special page for changing the content language of a page
28  *
29  * @ingroup SpecialPage
30  */
31 class SpecialPageLanguage extends FormSpecialPage {
32         /**
33          * @var string URL to go to if language change successful
34          */
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.special.pageLanguage' );
47         }
48
49         protected function getFormFields() {
50                 // Get default from the subpage of Special page
51                 $defaultName = $this->par;
52                 $title = $defaultName ? Title::newFromText( $defaultName ) : null;
53                 if ( $title ) {
54                         $defaultPageLanguage =
55                                 ContentHandler::getForTitle( $title )->getPageLanguage( $title );
56                         $hasCustomLanguageSet = !$defaultPageLanguage->equals( $title->getPageLanguage() );
57                 } else {
58                         $hasCustomLanguageSet = false;
59                 }
60
61                 $page = [];
62                 $page['pagename'] = [
63                         'type' => 'title',
64                         'label-message' => 'pagelang-name',
65                         'default' => $title ? $title->getPrefixedText() : $defaultName,
66                         'autofocus' => $defaultName === null,
67                         'exists' => true,
68                 ];
69
70                 // Options for whether to use the default language or select language
71                 $selectoptions = [
72                         (string)$this->msg( 'pagelang-use-default' )->escaped() => 1,
73                         (string)$this->msg( 'pagelang-select-lang' )->escaped() => 2,
74                 ];
75                 $page['selectoptions'] = [
76                         'id' => 'mw-pl-options',
77                         'type' => 'radio',
78                         'options' => $selectoptions,
79                         'default' => $hasCustomLanguageSet ? 2 : 1
80                 ];
81
82                 // Building a language selector
83                 $userLang = $this->getLanguage()->getCode();
84                 $languages = Language::fetchLanguageNames( $userLang, 'mwfile' );
85                 ksort( $languages );
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
127         /**
128          *
129          * @param array $data
130          * @return Status
131          */
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'] === null ? '' : $data['reason']
168                 );
169         }
170
171         /**
172          * @param IContextSource $context
173          * @param Title $title
174          * @param string $newLanguage Language code
175          * @param string $reason Reason for the change
176          * @param array $tags Change tags to apply to the log entry
177          * @return Status
178          */
179         public static function changePageLanguage( IContextSource $context, Title $title,
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 ) {
212                                 return Status::newFatal( ApiMessage::create(
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 ? $oldLanguage : $defLang . '[def]';
229                 $logNew = $newLanguage ? $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->setTags( $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
284         /**
285          * Return an array of subpages beginning with $search that this special page will accept.
286          *
287          * @param string $search Prefix to search for
288          * @param int $limit Maximum number of results to return (usually 10)
289          * @param int $offset Number of results to skip (usually 0)
290          * @return string[] Matching subpages
291          */
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 }