And while I'm at it: removed unused global declarations of $wgFeedClasses
[lhc/web/wiklou.git] / includes / EditPage.php
index e8867a5..db32c4b 100644 (file)
  * usually the same, but they are now allowed to be different.
  */
 class EditPage {
-       const AS_SUCCESS_UPDATE                 = 200;
-       const AS_SUCCESS_NEW_ARTICLE            = 201;
-       const AS_HOOK_ERROR                     = 210;
-       const AS_FILTERING                      = 211;
-       const AS_HOOK_ERROR_EXPECTED            = 212;
-       const AS_BLOCKED_PAGE_FOR_USER          = 215;
-       const AS_CONTENT_TOO_BIG                = 216;
-       const AS_USER_CANNOT_EDIT               = 217;
-       const AS_READ_ONLY_PAGE_ANON            = 218;
-       const AS_READ_ONLY_PAGE_LOGGED          = 219;
-       const AS_READ_ONLY_PAGE                 = 220;
-       const AS_RATE_LIMITED                   = 221;
-       const AS_ARTICLE_WAS_DELETED            = 222;
-       const AS_NO_CREATE_PERMISSION           = 223;
-       const AS_BLANK_ARTICLE                  = 224;
-       const AS_CONFLICT_DETECTED              = 225;
-       const AS_SUMMARY_NEEDED                 = 226;
-       const AS_TEXTBOX_EMPTY                  = 228;
-       const AS_MAX_ARTICLE_SIZE_EXCEEDED      = 229;
-       const AS_OK                             = 230;
-       const AS_END                            = 231;
-       const AS_SPAM_ERROR                     = 232;
-       const AS_IMAGE_REDIRECT_ANON            = 233;
-       const AS_IMAGE_REDIRECT_LOGGED          = 234;
+       const AS_SUCCESS_UPDATE            = 200;
+       const AS_SUCCESS_NEW_ARTICLE       = 201;
+       const AS_HOOK_ERROR                = 210;
+       const AS_FILTERING                 = 211;
+       const AS_HOOK_ERROR_EXPECTED       = 212;
+       const AS_BLOCKED_PAGE_FOR_USER     = 215;
+       const AS_CONTENT_TOO_BIG           = 216;
+       const AS_USER_CANNOT_EDIT          = 217;
+       const AS_READ_ONLY_PAGE_ANON       = 218;
+       const AS_READ_ONLY_PAGE_LOGGED     = 219;
+       const AS_READ_ONLY_PAGE            = 220;
+       const AS_RATE_LIMITED              = 221;
+       const AS_ARTICLE_WAS_DELETED       = 222;
+       const AS_NO_CREATE_PERMISSION      = 223;
+       const AS_BLANK_ARTICLE             = 224;
+       const AS_CONFLICT_DETECTED         = 225;
+       const AS_SUMMARY_NEEDED            = 226;
+       const AS_TEXTBOX_EMPTY             = 228;
+       const AS_MAX_ARTICLE_SIZE_EXCEEDED = 229;
+       const AS_OK                        = 230;
+       const AS_END                       = 231;
+       const AS_SPAM_ERROR                = 232;
+       const AS_IMAGE_REDIRECT_ANON       = 233;
+       const AS_IMAGE_REDIRECT_LOGGED     = 234;
 
        var $mArticle;
        var $mTitle;
@@ -72,9 +72,9 @@ class EditPage {
        # Form values
        var $save = false, $preview = false, $diff = false;
        var $minoredit = false, $watchthis = false, $recreate = false;
-       var $textbox1 = '', $textbox2 = '', $summary = '';
+       var $textbox1 = '', $textbox2 = '', $summary = '', $nosummary = false;
        var $edittime = '', $section = '', $starttime = '';
-       var $oldid = 0, $editintro = '', $scrolltop = null;
+       var $oldid = 0, $editintro = '', $scrolltop = null, $bot = true;
 
        # Placeholders for text injection by hooks (must be HTML)
        # extensions should take care to _append_ to the present value
@@ -121,6 +121,7 @@ class EditPage {
 
        /**
         * Fetch initial editing page content.
+        * @returns mixed string on success, $def_text for invalid sections
         * @private
         */
        function getContent( $def_text = '' ) {
@@ -129,7 +130,10 @@ class EditPage {
                wfProfileIn( __METHOD__ );
                # Get variables from query string :P
                $section = $wgRequest->getVal( 'section' );
-               $preload = $wgRequest->getVal( 'preload' );
+                       
+               $preload = $wgRequest->getVal( 'preload', 
+                       // Custom preload text for new sections
+                       $section === 'new' ? 'MediaWiki:addsection-preload' : '' );
                $undoafter = $wgRequest->getVal( 'undoafter' );
                $undo = $wgRequest->getVal( 'undo' );
 
@@ -201,6 +205,7 @@ class EditPage {
                                if ( $section == 'new' ) {
                                        $text = $this->getPreloadedText( $preload );
                                } else {
+                                       // Get section edit text (returns $def_text for invalid sections)
                                        $text = $wgParser->getSection( $text, $section, $def_text );
                                }
                        }
@@ -400,7 +405,7 @@ class EditPage {
                $permErrors = $this->getEditPermissionErrors();
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
-                       $this->readOnlyPage( $this->getContent(), true, $permErrors, 'edit' );
+                       $this->readOnlyPage( $this->getContent( false ), true, $permErrors, 'edit' );
                        wfProfileOut( __METHOD__ );
                        return;
                } else {
@@ -534,7 +539,7 @@ class EditPage {
         * @return bool
         */
        protected function previewOnOpen() {
-               global $wgRequest, $wgUser;
+               global $wgRequest, $wgUser, $wgPreviewOnOpenNamespaces;
                if ( $wgRequest->getVal( 'preview' ) == 'yes' ) {
                        // Explicit override from request
                        return true;
@@ -547,7 +552,10 @@ class EditPage {
                } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() ) && $wgUser->getOption( 'previewonfirst' ) ) {
                        // Standard preference behaviour
                        return true;
-               } elseif ( !$this->mTitle->exists() && $this->mTitle->getNamespace() == NS_CATEGORY ) {
+               } elseif ( !$this->mTitle->exists() &&
+                 isset($wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()]) &&
+                 $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
+               {
                        // Categories are special
                        return true;
                } else {
@@ -684,7 +692,7 @@ class EditPage {
                        $this->save      = false;
                        $this->diff      = false;
                        $this->minoredit = false;
-                       $this->watchthis = false;
+                       $this->watchthis = $request->getBool( 'watchthis', false ); // Watch may be overriden by request parameters
                        $this->recreate  = false;
 
                        if ( $this->section == 'new' && $request->getVal( 'preloadtitle' ) ) {
@@ -699,11 +707,16 @@ class EditPage {
                        }
                }
 
+               $this->bot = $request->getBool( 'bot', true );
+               $this->nosummary = $request->getBool( 'nosummary' );
+
                // FIXME: unused variable?
                $this->oldid = $request->getInt( 'oldid' );
 
                $this->live = $request->getCheck( 'live' );
-               $this->editintro = $request->getText( 'editintro' );
+               $this->editintro = $request->getText( 'editintro',
+                       // Custom edit intro for new sections
+                       $this->section === 'new' ? 'MediaWiki:addsection-editintro' : '' );
 
                wfProfileOut( __METHOD__ );
 
@@ -761,16 +774,16 @@ class EditPage {
                        $id = User::idFromName( $username );
                        $ip = User::isIP( $username );
                        if ( $id == 0 && !$ip ) {
-                               $wgOut->wrapWikiMsg( '<div class="mw-userpage-userdoesnotexist error">$1</div>',
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1</div>",
                                        array( 'userpage-userdoesnotexist', $username ) );
                        }
                }
                # Try to add a custom edit intro, or use the standard one if this is not possible.
                if ( !$this->showCustomIntro() && !$this->mTitle->exists() ) {
                        if ( $wgUser->isLoggedIn() ) {
-                               $wgOut->wrapWikiMsg( '<div class="mw-newarticletext">$1</div>', 'newarticletext' );
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-newarticletext\">\n$1</div>", 'newarticletext' );
                        } else {
-                               $wgOut->wrapWikiMsg( '<div class="mw-newarticletextanon">$1</div>', 'newarticletextanon' );
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-newarticletextanon\">\n$1</div>", 'newarticletextanon' );
                        }
                }
                # Give a notice if the user is editing a deleted/moved page...
@@ -928,7 +941,7 @@ class EditPage {
                        }
 
                        # Don't save a new article if it's blank.
-                       if ( '' == $this->textbox1 ) {
+                       if ( $this->textbox1 == '' ) {
                                wfProfileOut( __METHOD__ );
                                return self::AS_BLANK_ARTICLE;
                        }
@@ -1172,10 +1185,25 @@ class EditPage {
        /**
         * Initialise form fields in the object
         * Called on the first invocation, e.g. when a user clicks an edit link
+        * @returns bool -- if the requested section is valid
         */
        function initialiseForm() {
+               global $wgUser;
                $this->edittime = $this->mArticle->getTimestamp();
                $this->textbox1 = $this->getContent( false );
+               // activate checkboxes if user wants them to be always active
+               # Sort out the "watch" checkbox
+               if ( $wgUser->getOption( 'watchdefault' ) ) {
+                       # Watch all edits
+                       $this->watchthis = true;
+               } elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
+                       # Watch creations
+                       $this->watchthis = true;
+               } elseif ( $this->mTitle->userIsWatching() ) {
+                       # Already watched
+                       $this->watchthis = true;
+               }
+               if ( $wgUser->getOption( 'minordefault' ) ) $this->minoredit = true;
                if ( $this->textbox1 === false ) return false;
                wfProxyCheck();
                return true;
@@ -1211,7 +1239,7 @@ class EditPage {
         *                      near the top, for captchas and the like.
         */
        function showEditForm( $formCallback=null ) {
-               global $wgOut, $wgUser, $wgTitle, $wgRequest;
+               global $wgOut, $wgUser, $wgTitle;
 
                # If $wgTitle is null, that means we're in API mode.
                # Some hook probably called this function  without checking
@@ -1240,7 +1268,7 @@ class EditPage {
                # Enabled article-related sidebar, toplinks, etc.
                $wgOut->setArticleRelated( true );
 
-               if ( $this->editFormHeadInit() === false )
+               if ( $this->showHeader() === false )
                        return;
 
                $action = htmlspecialchars($this->getActionURL($wgTitle));
@@ -1253,28 +1281,6 @@ class EditPage {
                }
 
 
-               // activate checkboxes if user wants them to be always active
-               if ( !$this->preview && !$this->diff ) {
-                       # Sort out the "watch" checkbox
-                       if ( $wgUser->getOption( 'watchdefault' ) ) {
-                               # Watch all edits
-                               $this->watchthis = true;
-                       } elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
-                               # Watch creations
-                               $this->watchthis = true;
-                       } elseif ( $this->mTitle->userIsWatching() ) {
-                               # Already watched
-                               $this->watchthis = true;
-                       }
-
-                       # May be overriden by request parameters
-                       if( $wgRequest->getBool( 'watchthis' ) ) {
-                               $this->watchthis = true;
-                       }
-
-                       if ( $wgUser->getOption( 'minordefault' ) ) $this->minoredit = true;
-               }
-
                $wgOut->addHTML( $this->editFormPageTop );
 
                if ( $wgUser->getOption( 'previewontop' ) ) {
@@ -1299,10 +1305,10 @@ class EditPage {
                        $toolbar = '';
                        // @todo move this to a cleaner conditional instead of blanking a variable
                }
-               $wgOut->addHTML( <<<END
+               $wgOut->addHTML( <<<HTML
 {$toolbar}
 <form id="editform" name="editform" method="post" action="$action" enctype="multipart/form-data">
-END
+HTML
 );
 
                if ( is_callable( $formCallback ) ) {
@@ -1333,7 +1339,7 @@ END
                # For a bit more sophisticated detection of blank summaries, hash the
                # automatic one and pass that in the hidden field wpAutoSummary.
                if ( $this->missingSummary ||
-                       ( $this->section == 'new' && $wgRequest->getBool( 'nosummary' ) ) )
+                       ( $this->section == 'new' && $this->nosummary ) )
                                $wgOut->addHTML( Xml::hidden( 'wpIgnoreBlankSummary', true ) );
                $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
                $wgOut->addHTML( Xml::hidden( 'wpAutoSummary', $autosumm ) );
@@ -1372,7 +1378,7 @@ END
                $this->showTosSummary();
                $this->showEditTools();
 
-               $wgOut->addHTML( <<<END
+               $wgOut->addHTML( <<<HTML
 {$this->editFormTextAfterTools}
 <div class='templatesUsed'>
 {$formattedtemplates}
@@ -1380,7 +1386,7 @@ END
 <div class='hiddencats'>
 {$formattedhiddencats}
 </div>
-END
+HTML
 );
 
                if ( $this->isConflict )
@@ -1395,8 +1401,8 @@ END
                wfProfileOut( __METHOD__ );
        }
        
-       protected function editFormHeadInit() {
-               global $wgOut, $wgParser, $wgUser, $wgMaxArticleSize, $wgLang;
+       protected function showHeader() {
+               global $wgOut, $wgUser, $wgTitle, $wgMaxArticleSize, $wgLang;
                if ( $this->isConflict ) {
                        $wgOut->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1</div>", 'explainconflict' );
                        $this->edittime = $this->mArticle->getTimestamp();
@@ -1422,20 +1428,25 @@ END
                                }
                        }
 
-                       if ( $this->missingComment )
-                               $wgOut->wrapWikiMsg( '<div id="mw-missingcommenttext">$1</div>', 'missingcommenttext' );
+                       if ( $this->missingComment ) {
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1</div>", 'missingcommenttext' );
+                       }
 
-                       if ( $this->missingSummary && $this->section != 'new' )
-                               $wgOut->wrapWikiMsg( '<div id="mw-missingsummary">$1</div>', 'missingsummary' );
+                       if ( $this->missingSummary && $this->section != 'new' ) {
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingsummary'>\n$1</div>", 'missingsummary' );
+                       }
 
-                       if ( $this->missingSummary && $this->section == 'new' )
-                               $wgOut->wrapWikiMsg( '<div id="mw-missingcommentheader">$1</div>', 'missingcommentheader' );
+                       if ( $this->missingSummary && $this->section == 'new' ) {
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1</div>", 'missingcommentheader' );
+                       }
 
-                       if ( $this->hookError !== '' )
+                       if ( $this->hookError !== '' ) {
                                $wgOut->addWikiText( $this->hookError );
+                       }
 
-                       if ( !$this->checkUnicodeCompliantBrowser() )
+                       if ( !$this->checkUnicodeCompliantBrowser() ) {
                                $wgOut->addWikiMsg( 'nonunicodebrowser' );
+                       }
 
                        if ( isset( $this->mArticle ) && isset( $this->mArticle->mRevision ) ) {
                        // Let sysop know that this will make private content public if saved
@@ -1456,7 +1467,7 @@ END
                if ( wfReadOnly() ) {
                        $wgOut->wrapWikiMsg( "<div id=\"mw-read-only-warning\">\n$1\n</div>", array( 'readonlywarning', wfReadOnlyReason() ) );
                } elseif ( $wgUser->isAnon() && $this->formtype != 'preview' ) {
-                       $wgOut->wrapWikiMsg( '<div id="mw-anon-edit-warning">$1</div>', 'anoneditwarning' );
+                       $wgOut->wrapWikiMsg( "<div id=\"mw-anon-edit-warning\">\n$1</div>", 'anoneditwarning' );
                } else {
                        if ( $this->isCssJsSubpage ) {
                                # Check the skin exists
@@ -1486,7 +1497,7 @@ END
                if ( $this->mTitle->isCascadeProtected() ) {
                        # Is this page under cascading protection from some source pages?
                        list($cascadeSources, /* $restrictions */) = $this->mTitle->getCascadeProtectionSources();
-                       $notice = "<div class='mw-cascadeprotectedwarning'>$1\n";
+                       $notice = "<div class='mw-cascadeprotectedwarning'>\n$1\n";
                        $cascadeSourcesCount = count( $cascadeSources );
                        if ( $cascadeSourcesCount > 0 ) {
                                # Explain, and list the titles responsible
@@ -1498,11 +1509,16 @@ END
                        $wgOut->wrapWikiMsg( $notice, array( 'cascadeprotectedwarning', $cascadeSourcesCount ) );
                }
                if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
-                       $wgOut->wrapWikiMsg( '<div class="mw-titleprotectedwarning">$1</div>', 'titleprotectedwarning' );
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle->getPrefixedText(), '',
+                               array(  'lim' => 1,
+                                       'showIfEmpty' => false,
+                                       'msgKey' => array( 'titleprotectedwarning' ),
+                                       'wrap' => "<div class=\"mw-titleprotectedwarning\">\n$1</div>" ) );
                }
 
-               if ( $this->kblength === false )
+               if ( $this->kblength === false ) {
                        $this->kblength = (int)( strlen( $this->textbox1 ) / 1024 );
+               }
 
                if ( $this->tooBig || $this->kblength > $wgMaxArticleSize ) {
                        $wgOut->addHTML( "<div class='error' id='mw-edit-longpageerror'>\n" );
@@ -1529,23 +1545,19 @@ END
         * 
         * @return array An array in the format array( $label, $input )
         */
-       function getSummaryInput($summary = "", $labelText = null, $userInputAttrs = null, $userSpanLabelAttrs = null) {
-               $inputAttrs = array(
+       function getSummaryInput($summary = "", $labelText = null, $inputAttrs = null, $spanLabelAttrs = null) {
+               $inputAttrs = ( is_array($inputAttrs) ? $inputAttrs : array() ) + array(
                        'id' => 'wpSummary',
                        'maxlength' => '200',
                        'tabindex' => '1',
                        'size' => 60,
                        'spellcheck' => 'true',
-                       'onfocus' => "currentFocused = this;",
                );
-               if ( $userInputAttrs )
-                       $inputAttrs += $userInputAttrs;
-               $spanLabelAttrs = array(
-                       'class' => $summaryClass,
+               
+               $spanLabelAttrs = ( is_array($spanLabelAttrs) ? $spanLabelAttrs : array() ) + array(
+                       'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
                        'id' => "wpSummaryLabel"
                );
-               if ( is_array($userSpanLabelAttrs) )
-                       $spanLabelAttrs += $userSpanLabelAttrs;
 
                $label = null;
                if ( $labelText ) {
@@ -1570,7 +1582,7 @@ END
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                if ( $isSubjectPreview ) {
-                       if ( $wgRequest->getBool( 'nosummary' ) )
+                       if ( $this->nosummary )
                                return;
                } else {
                        if ( !$this->mShowSummaryField )
@@ -1679,12 +1691,6 @@ INPUTS
                                $classes[] = $attribs['class'];
                        $attribs['class'] = implode( ' ', $classes );
                }
-
-               # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
-               if ( !$this->preview && !$this->diff ) {
-                       global $wgOut;
-                       $wgOut->setOnloadHandler( 'document.editform.wpTextbox1.focus();' );
-               }
                
                $this->showTextbox( isset($textoverride) ? $textoverride : $this->textbox1, 'wpTextbox1', $attribs );
        }
@@ -1710,7 +1716,7 @@ INPUTS
                        'id'   => $name,
                        'cols' => $wgUser->getIntOption( 'cols' ), 
                        'rows' => $wgUser->getIntOption( 'rows' ),
-                       'onfocus' => "currentFocused = this;",
+                       'style' => '' // avoid php notices when appending for editwidth preference (appending allows customAttribs['style'] to still work
                );
 
                if ( $wgUser->getOption( 'editwidth' ) )
@@ -1998,7 +2004,7 @@ INPUTS
         * Call the stock "user is blocked" page
         */
        function blockedPage() {
-               global $wgOut, $wgUser;
+               global $wgOut;
                $wgOut->blockedPage( false ); # Standard block notice on the top, don't 'return'
 
                # If the user made changes, preserve them when showing the markup
@@ -2012,14 +2018,9 @@ INPUTS
 
                # Spit out the source or the user's modified version
                if ( $source !== false ) {
-                       $rows = $wgUser->getIntOption( 'rows' );
-                       $cols = $wgUser->getIntOption( 'cols' );
-                       $attribs = array( 'id' => 'wpTextbox1', 'name' => 'wpTextbox1', 'cols' => $cols, 'rows' => $rows, 'readonly' => 'readonly' );
                        $wgOut->addHTML( '<hr />' );
                        $wgOut->addWikiMsg( $first ? 'blockedoriginalsource' : 'blockededitsource', $this->mTitle->getPrefixedText() );
-                       # Why we don't use Xml::element here?
-                       # Is it because if $source is '', it returns <textarea />?
-                       $wgOut->addHTML( Xml::openElement( 'textarea', $attribs ) . htmlspecialchars( $source ) . Xml::closeElement( 'textarea' ) );
+                       $this->showTextbox1( array( 'readonly' ), $source );
                }
        }
 
@@ -2052,14 +2053,17 @@ INPUTS
         * they have attempted to edit a nonexistent section.
         */
        function noSuchSectionPage() {
-               global $wgOut, $wgTitle;
+               global $wgOut;
 
                $wgOut->setPageTitle( wfMsg( 'nosuchsectiontitle' ) );
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
                $wgOut->setArticleRelated( false );
 
-               $wgOut->addWikiMsg( 'nosuchsectiontext', $this->section );
-               $wgOut->returnToMain( false, $wgTitle );
+               $res = wfMsgExt( 'nosuchsectiontext', 'parse', $this->section );
+               wfRunHooks( 'EditPageNoSuchSection', array( &$this, &$res ) );
+               $wgOut->addHTML( $res );
+
+               $wgOut->returnToMain( false, $this->mTitle );
        }
 
        /**
@@ -2615,11 +2619,11 @@ INPUTS
         * @return bool false if output is done, true if the rest of the form should be displayed
         */
        function attemptSave() {
-               global $wgUser, $wgOut, $wgTitle, $wgRequest;
+               global $wgUser, $wgOut, $wgTitle;
 
                $resultDetails = false;
                # Allow bots to exempt some edits from bot flagging
-               $bot = $wgUser->isAllowed( 'bot' ) && $wgRequest->getBool( 'bot', true );
+               $bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
                $value = $this->internalAttemptSave( $resultDetails, $bot );
 
                if ( $value == self::AS_SUCCESS_UPDATE || $value == self::AS_SUCCESS_NEW_ARTICLE ) {
@@ -2691,5 +2695,5 @@ INPUTS
                } else {
                        return $this->mBaseRevision;
                }
-       }
+       }       
 }