SpecialPageLanguage: Redirect to redirect by adding redirect=no
[lhc/web/wiklou.git] / includes / specials / SpecialPageLanguage.php
index 38093be..db05ebe 100644 (file)
@@ -50,44 +50,50 @@ class SpecialPageLanguage extends FormSpecialPage {
                // Get default from the subpage of Special page
                $defaultName = $this->par;
 
-               $page = array();
-               $page['pagename'] = array(
+               $page = [];
+               $page['pagename'] = [
                        'type' => 'title',
                        'label-message' => 'pagelang-name',
                        'default' => $defaultName,
                        'autofocus' => $defaultName === null,
                        'exists' => true,
-               );
+               ];
 
                // Options for whether to use the default language or select language
-               $selectoptions = array(
+               $selectoptions = [
                        (string)$this->msg( 'pagelang-use-default' )->escaped() => 1,
                        (string)$this->msg( 'pagelang-select-lang' )->escaped() => 2,
-               );
-               $page['selectoptions'] = array(
+               ];
+               $page['selectoptions'] = [
                        'id' => 'mw-pl-options',
                        'type' => 'radio',
                        'options' => $selectoptions,
                        'default' => 1
-               );
+               ];
 
                // Building a language selector
                $userLang = $this->getLanguage()->getCode();
                $languages = Language::fetchLanguageNames( $userLang, 'mwfile' );
                ksort( $languages );
-               $options = array();
+               $options = [];
                foreach ( $languages as $code => $name ) {
                        $options["$code - $name"] = $code;
                }
 
-               $page['language'] = array(
+               $page['language'] = [
                        'id' => 'mw-pl-languageselector',
                        'cssclass' => 'mw-languageselector',
                        'type' => 'select',
                        'options' => $options,
                        'label-message' => 'pagelang-language',
                        'default' => $this->getConfig()->get( 'LanguageCode' ),
-               );
+               ];
+
+               // Allow user to enter a comment explaining the change
+               $page['reason'] = [
+                       'type' => 'text',
+                       'label-message' => 'pagelang-reason'
+               ];
 
                return $page;
        }
@@ -104,92 +110,142 @@ class SpecialPageLanguage extends FormSpecialPage {
        }
 
        public function alterForm( HTMLForm $form ) {
-               Hooks::run( 'LanguageSelector', array( $this->getOutput(), 'mw-languageselector' ) );
+               Hooks::run( 'LanguageSelector', [ $this->getOutput(), 'mw-languageselector' ] );
                $form->setSubmitTextMsg( 'pagelang-submit' );
        }
 
        /**
         *
         * @param array $data
-        * @return bool
+        * @return Status
         */
        public function onSubmit( array $data ) {
-               $title = Title::newFromText( $data['pagename'] );
+               $pageName = $data['pagename'];
+
+               // Check if user wants to use default language
+               if ( $data['selectoptions'] == 1 ) {
+                       $newLanguage = 'default';
+               } else {
+                       $newLanguage = $data['language'];
+               }
 
-               // Check if title is valid
-               if ( !$title ) {
-                       return false;
+               try {
+                       $title = Title::newFromTextThrow( $pageName );
+               } catch ( MalformedTitleException $ex ) {
+                       return Status::newFatal( $ex->getMessageObject() );
                }
 
+               // Url to redirect to after the operation
+               $this->goToUrl = $title->getFullURL(
+                       $title->isRedirect() ? [ 'redirect' => 'no' ] : []
+               );
+
+               return self::changePageLanguage(
+                       $this->getContext(),
+                       $title,
+                       $newLanguage,
+                       $data['reason'] === null ? '' : $data['reason']
+               );
+       }
+
+       /**
+        * @param IContextSource $context
+        * @param Title $title
+        * @param string $newLanguage Language code
+        * @param string $reason Reason for the change
+        * @param array $tags Change tags to apply to the log entry
+        * @return Status
+        */
+       public static function changePageLanguage( IContextSource $context, Title $title,
+               $newLanguage, $reason, array $tags = [] ) {
                // Get the default language for the wiki
-               // Returns the default since the page is not loaded from DB
-               $defLang = $title->getPageLanguage()->getCode();
+               $defLang = $context->getConfig()->get( 'LanguageCode' );
 
                $pageId = $title->getArticleID();
 
                // Check if article exists
                if ( !$pageId ) {
-                       return false;
+                       return Status::newFatal(
+                               'pagelang-nonexistent-page',
+                               wfEscapeWikiText( $title->getPrefixedText() )
+                       );
                }
 
                // Load the page language from DB
                $dbw = wfGetDB( DB_MASTER );
-               $langOld = $dbw->selectField(
+               $oldLanguage = $dbw->selectField(
                        'page',
                        'page_lang',
-                       array( 'page_id' => $pageId ),
+                       [ 'page_id' => $pageId ],
                        __METHOD__
                );
 
-               // Url to redirect to after the operation
-               $this->goToUrl = $title->getFullURL();
-
-               // Check if user wants to use default language
-               if ( $data['selectoptions'] == 1 ) {
-                       $langNew = null;
-               } else {
-                       $langNew = $data['language'];
+               // Check if user wants to use the default language
+               if ( $newLanguage === 'default' ) {
+                       $newLanguage = null;
                }
 
                // No change in language
-               if ( $langNew === $langOld ) {
-                       return false;
+               if ( $newLanguage === $oldLanguage ) {
+                       // Check if old language does not exist
+                       if ( !$oldLanguage ) {
+                               return Status::newFatal( ApiMessage::create(
+                                       [
+                                               'pagelang-unchanged-language-default',
+                                               wfEscapeWikiText( $title->getPrefixedText() )
+                                       ],
+                                       'pagelang-unchanged-language'
+                               ) );
+                       }
+                       return Status::newFatal(
+                               'pagelang-unchanged-language',
+                               wfEscapeWikiText( $title->getPrefixedText() ),
+                               $oldLanguage
+                       );
                }
 
                // Hardcoded [def] if the language is set to null
-               $logOld = $langOld ? $langOld : $defLang . '[def]';
-               $logNew = $langNew ? $langNew : $defLang . '[def]';
+               $logOld = $oldLanguage ? $oldLanguage : $defLang . '[def]';
+               $logNew = $newLanguage ? $newLanguage : $defLang . '[def]';
 
                // Writing new page language to database
-               $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'page',
-                       array( 'page_lang' => $langNew ),
-                       array(
+                       [ 'page_lang' => $newLanguage ],
+                       [
                                'page_id' => $pageId,
-                               'page_lang' => $langOld
-                       ),
+                               'page_lang' => $oldLanguage
+                       ],
                        __METHOD__
                );
 
                if ( !$dbw->affectedRows() ) {
-                       return false;
+                       return Status::newFatal( 'pagelang-db-failed' );
                }
 
                // Logging change of language
-               $logParams = array(
+               $logParams = [
                        '4::oldlanguage' => $logOld,
                        '5::newlanguage' => $logNew
-               );
+               ];
                $entry = new ManualLogEntry( 'pagelang', 'pagelang' );
-               $entry->setPerformer( $this->getUser() );
+               $entry->setPerformer( $context->getUser() );
                $entry->setTarget( $title );
                $entry->setParameters( $logParams );
+               $entry->setComment( $reason );
+               $entry->setTags( $tags );
 
                $logid = $entry->insert();
                $entry->publish( $logid );
 
-               return true;
+               // Force re-render so that language-based content (parser functions etc.) gets updated
+               $title->invalidateCache();
+
+               return Status::newGood( (object)[
+                       'oldLanguage' => $logOld,
+                       'newLanguage' => $logNew,
+                       'logId' => $logid,
+               ] );
        }
 
        public function onSuccess() {