ApiEmailUser.php: fix copyright symbol, spacing and coding style tweaks, spaces ...
[lhc/web/wiklou.git] / includes / EditPage.php
index b4515dd..e92b43b 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;
        var $action;
-       var $mMetaData = '';
        var $isConflict = false;
        var $isCssJsSubpage = false;
        var $isCssSubpage = false;
@@ -72,9 +71,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 +120,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 +129,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 +204,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 );
                                }
                        }
@@ -242,95 +246,6 @@ class EditPage {
                }
        }
 
-       /**
-        * This is the function that extracts metadata from the article body on the first view.
-        * To turn the feature on, set $wgUseMetadataEdit = true ; in LocalSettings
-        *  and set $wgMetadataWhitelist to the *full* title of the template whitelist
-        */
-       function extractMetaDataFromArticle () {
-               global $wgUseMetadataEdit, $wgMetadataWhitelist, $wgContLang;
-               $this->mMetaData = '';
-               if ( !$wgUseMetadataEdit ) return;
-               if ( $wgMetadataWhitelist == '' ) return;
-               $s = '';
-               $t = $this->getContent();
-
-               # MISSING : <nowiki> filtering
-
-               # Categories and language links
-               $t = explode( "\n" , $t );
-               $catlow = strtolower( $wgContLang->getNsText( NS_CATEGORY ) );
-               $cat = $ll = array();
-               foreach ( $t as $key => $x ) {
-                       $y = trim( strtolower ( $x ) );
-                       while ( substr( $y , 0 , 2 ) == '[[' ) {
-                               $y = explode( ']]' , trim ( $x ) );
-                               $first = array_shift( $y );
-                               $first = explode( ':' , $first );
-                               $ns = array_shift( $first );
-                               $ns = trim( str_replace( '[' , '' , $ns ) );
-                               if ( $wgContLang->getLanguageName( $ns ) || strtolower( $ns ) == $catlow ) {
-                                       $add = '[[' . $ns . ':' . implode( ':' , $first ) . ']]';
-                                       if ( strtolower( $ns ) == $catlow ) $cat[] = $add;
-                                       else $ll[] = $add;
-                                       $x = implode( ']]', $y );
-                                       $t[$key] = $x;
-                                       $y = trim( strtolower( $x ) );
-                               } else {
-                                       $x = implode( ']]' , $y );
-                                       $y = trim( strtolower( $x ) );
-                               }
-                       }
-               }
-               if ( count( $cat ) ) $s .= implode( ' ' , $cat ) . "\n";
-               if ( count( $ll ) ) $s .= implode( ' ' , $ll ) . "\n";
-               $t = implode( "\n" , $t );
-
-               # Load whitelist
-               $sat = array () ; # stand-alone-templates; must be lowercase
-               $wl_title = Title::newFromText( $wgMetadataWhitelist );
-               $wl_article = new Article ( $wl_title );
-               $wl = explode ( "\n" , $wl_article->getContent() );
-               foreach ( $wl AS $x ) {
-                       $isentry = false;
-                       $x = trim ( $x );
-                       while ( substr ( $x , 0 , 1 ) == '*' ) {
-                               $isentry = true;
-                               $x = trim ( substr ( $x , 1 ) );
-                       }
-                       if ( $isentry ) {
-                               $sat[] = strtolower ( $x );
-                       }
-
-               }
-
-               # Templates, but only some
-               $t = explode( '{{' , $t );
-               $tl = array() ;
-               foreach ( $t as $key => $x ) {
-                       $y = explode( '}}' , $x , 2 );
-                       if ( count( $y ) == 2 ) {
-                               $z = $y[0];
-                               $z = explode( '|' , $z );
-                               $tn = array_shift( $z );
-                               if ( in_array( strtolower( $tn ) , $sat ) ) {
-                                       $tl[] = '{{' . $y[0] . '}}';
-                                       $t[$key] = $y[1];
-                                       $y = explode( '}}' , $y[1] , 2 );
-                               }
-                               else $t[$key] = '{{' . $x;
-                       }
-                       else if ( $key != 0 ) $t[$key] = '{{' . $x;
-                       else $t[$key] = $x;
-               }
-               if ( count( $tl ) ) $s .= implode( ' ' , $tl );
-               $t = implode( '' , $t );
-
-               $t = str_replace( "\n\n\n", "\n", $t );
-               $this->mArticle->mContent = $t;
-               $this->mMetaData = $s;
-       }
-
        /*
         * Check if a page was deleted while the user was editing it, before submit.
         * Note that we rely on the logging table, which hasn't been always there,
@@ -368,7 +283,7 @@ class EditPage {
         * the newly-edited page.
         */
        function edit() {
-               global $wgOut, $wgRequest;
+               global $wgOut, $wgRequest, $wgUser;
                // Allow extensions to modify/prevent this form or submission
                if ( !wfRunHooks( 'AlternateEdit', array( $this ) ) ) {
                        return;
@@ -396,11 +311,18 @@ class EditPage {
                }
 
                $wgOut->addScriptFile( 'edit.js' );
+               
+               if ( $wgUser->getOption( 'uselivepreview', false ) ) {
+                       $wgOut->includeJQuery();
+                       $wgOut->addScriptFile( 'preview.js' );
+               }
+               // Bug #19334: textarea jumps when editing articles in IE8
+               $wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
 
                $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 {
@@ -415,7 +337,6 @@ class EditPage {
                                if ( $this->previewOnOpen() ) {
                                        $this->formtype = 'preview';
                                } else {
-                                       $this->extractMetaDataFromArticle () ;
                                        $this->formtype = 'initial';
                                }
                        }
@@ -483,6 +404,8 @@ class EditPage {
                        }
                        if ( !$this->mTitle->getArticleId() )
                                wfRunHooks( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
+                       else
+                               wfRunHooks( 'EditFormInitialText', array( $this ) );
                }
 
                $this->showEditForm();
@@ -534,7 +457,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 +470,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 {
@@ -605,7 +531,7 @@ class EditPage {
                                        $this->textbox1 = $textbox1;
                                wfProfileOut( get_class($this)."::importContentFormData" );
                        }
-                       $this->mMetaData = rtrim( $request->getText( 'metadata' ) );
+
                        # Truncate for whole multibyte characters. +5 bytes for ellipsis
                        $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250, '' );
 
@@ -675,7 +601,6 @@ class EditPage {
                        # Not a posted form? Start with nothing.
                        wfDebug( __METHOD__ . ": Not a posted form.\n" );
                        $this->textbox1  = '';
-                       $this->mMetaData = '';
                        $this->summary   = '';
                        $this->edittime  = '';
                        $this->starttime = wfTimestampNow();
@@ -684,7 +609,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 +624,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__ );
 
@@ -754,23 +684,39 @@ class EditPage {
                        $wgOut->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1</div>", 'editinginterface' );
                }
 
-               # Show a warning message when someone creates/edits a user (talk) page but the user does not exists
+               # Show a warning message when someone creates/edits a user (talk) page but the user does not exist
+               # Show log extract when the user is currently blocked
                if ( $namespace == NS_USER || $namespace == NS_USER_TALK ) {
                        $parts = explode( '/', $this->mTitle->getText(), 2 );
                        $username = $parts[0];
-                       $id = User::idFromName( $username );
+                       $user = User::newFromName( $username, false /* allow IP users*/ );
                        $ip = User::isIP( $username );
-                       if ( $id == 0 && !$ip ) {
-                               $wgOut->wrapWikiMsg( '<div class="mw-userpage-userdoesnotexist error">$1</div>',
+                       if ( !$user->isLoggedIn() && !$ip ) { # User does not exist
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1</div>",
                                        array( 'userpage-userdoesnotexist', $username ) );
+                       } else if ( $user->isBlocked() ) { # Show log extract if the user is currently blocked
+                               LogEventsList::showLogExtract(
+                                       $wgOut,
+                                       'block',
+                                       $user->getUserPage()->getPrefixedText(),
+                                       '',
+                                       array(
+                                               'lim' => 1,
+                                               'showIfEmpty' => false,
+                                               'msgKey' => array(
+                                                       'blocked-notice-logextract',
+                                                       $user->getName() # Support GENDER in notice
+                                               )
+                                       )
+                               );
                        }
                }
                # 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...
@@ -816,8 +762,7 @@ class EditPage {
                wfProfileIn( __METHOD__  );
                wfProfileIn( __METHOD__ . '-checks' );
 
-               if ( !wfRunHooks( 'EditPage::attemptSave', array( $this ) ) )
-               {
+               if ( !wfRunHooks( 'EditPage::attemptSave', array( $this ) ) ) {
                        wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
                        return self::AS_HOOK_ERROR;
                }
@@ -833,10 +778,6 @@ class EditPage {
                                }
                }
 
-               # Reintegrate metadata
-               if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
-               $this->mMetaData = '' ;
-
                # Check for spam
                $match = self::matchSummarySpamRegex( $this->summary );
                if ( $match === false ) {
@@ -928,7 +869,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 +1113,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 +1167,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 +1196,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 +1209,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 +1233,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,11 +1267,13 @@ 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 ) );
 
+               $wgOut->addHTML( Xml::hidden( 'oldid', $this->mArticle->getOldID() ) );
+
                if ( $this->section == 'new' ) {
                        $this->showSummaryInput( true, $this->summary );
                        $wgOut->addHTML( $this->getSummaryPreview( true, $this->summary ) );
@@ -1361,10 +1297,6 @@ END
                if ( isset($this->editFormTextAfterWarn) && $this->editFormTextAfterWarn !== '' )
                        $wgOut->addHTML( $this->editFormTextAfterWarn );
 
-               global $wgUseMetadataEdit;
-               if ( $wgUseMetadataEdit )
-                       $this->showMetaData();
-
                $this->showStandardInputs();
 
                $this->showFormAfterText();
@@ -1372,7 +1304,7 @@ END
                $this->showTosSummary();
                $this->showEditTools();
 
-               $wgOut->addHTML( <<<END
+               $wgOut->addHTML( <<<HTML
 {$this->editFormTextAfterTools}
 <div class='templatesUsed'>
 {$formattedtemplates}
@@ -1380,7 +1312,7 @@ END
 <div class='hiddencats'>
 {$formattedhiddencats}
 </div>
-END
+HTML
 );
 
                if ( $this->isConflict )
@@ -1395,8 +1327,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 +1354,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 +1393,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 +1423,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 +1435,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 +1471,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(
+               
+               $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 ) {
@@ -1566,11 +1504,11 @@ END
         * @return string
         */
        protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
-               global $wgOut, $wgContLang, $wgRequest;
+               global $wgOut, $wgContLang;
                # 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 +1617,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,8 +1642,7 @@ INPUTS
                        'id'   => $name,
                        'cols' => $wgUser->getIntOption( 'cols' ), 
                        'rows' => $wgUser->getIntOption( 'rows' ),
-                       'onfocus' => "currentFocused = this;",
-                       'style' => '' // for php notices
+                       'style' => '' // avoid php notices when appending for editwidth preference (appending allows customAttribs['style'] to still work
                );
 
                if ( $wgUser->getOption( 'editwidth' ) )
@@ -1719,15 +1650,6 @@ INPUTS
 
                $wgOut->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
        }
-       
-       protected function showMetaData() {
-               global $wgOut, $wgContLang, $wgUser;
-               $metadata = htmlspecialchars( $wgContLang->recodeForEdit( $this->mMetaData ) );
-               $ew = $wgUser->getOption( 'editwidth' ) ? ' style="width:100%"' : '';
-               $cols = $wgUser->getIntOption( 'cols' );
-               $metadata = wfMsgWikiHtml( 'metadata_help' ) . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>" ;
-               $wgOut->addHTML( $metadata );
-       }
 
        protected function displayPreviewArea( $previewOutput, $isOnTop = false ) {
                global $wgOut;
@@ -1939,10 +1861,10 @@ INPUTS
                        # If we're adding a comment, we need to show the
                        # summary as the headline
                        if ( $this->section == "new" && $this->summary != "" ) {
-                               $toparse="== {$this->summary} ==\n\n" . $toparse;
+                               $toparse = "== {$this->summary} ==\n\n" . $toparse;
                        }
 
-                       if ( $this->mMetaData != "" ) $toparse .= "\n" . $this->mMetaData;
+                       wfRunHooks( 'EditPageGetPreviewText', array( $this, &$toparse ) );
 
                        // Parse mediawiki messages with correct target language
                        if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
@@ -1999,7 +1921,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
@@ -2013,14 +1935,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 );
                }
        }
 
@@ -2053,14 +1970,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 );
        }
 
        /**
@@ -2442,11 +2362,12 @@ INPUTS
 
        public function getCancelLink() {
                global $wgUser, $wgTitle;
+
                $cancelParams = array();
-               if ( !$this->isConflict && isset( $this->mArticle ) &&
-                       isset( $this->mArticle->mRevision ) &&
-                       !$this->mArticle->mRevision->isCurrent() )
-                               $cancelParams['oldid'] = $this->mArticle->mRevision->getId();
+               if ( !$this->isConflict && $this->mArticle->getOldID() > 0 ) {
+                       $cancelParams['oldid'] = $this->mArticle->getOldID();
+               }
+
                return $wgUser->getSkin()->link(
                        $wgTitle,
                        wfMsgExt( 'cancel', array( 'parseinline' ) ),
@@ -2467,6 +2388,9 @@ INPUTS
                $oldtext = $this->mArticle->fetchContent();
                $newtext = $this->mArticle->replaceSection(
                        $this->section, $this->textbox1, $this->summary, $this->edittime );
+
+               wfRunHooks( 'EditPageGetDiffText', array( $this, &$newtext ) );
+
                $newtext = $this->mArticle->preSaveTransform( $newtext );
                $oldtitle = wfMsgExt( 'currentrev', array( 'parseinline' ) );
                $newtitle = wfMsgExt( 'yourtext', array( 'parseinline' ) );
@@ -2616,11 +2540,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 ) {
@@ -2692,5 +2616,5 @@ INPUTS
                } else {
                        return $this->mBaseRevision;
                }
-       }
+       }       
 }