messing with wfMerge
[lhc/web/wiklou.git] / includes / EditPage.php
index c895048..91d2be4 100644 (file)
  * headaches, which may be fatal.
  */
 class EditPage {
+
+       /**
+        * Status: Article successfully updated
+        */
        const AS_SUCCESS_UPDATE            = 200;
+
+       /**
+        * Status: Article successfully created
+        */
        const AS_SUCCESS_NEW_ARTICLE       = 201;
+
+       /**
+        * Status: Article update aborted by a hook function
+        */
        const AS_HOOK_ERROR                = 210;
+
+       /**
+        * Status: The filter function set in $wgFilterCallback returned true (= block it) 
+        */
        const AS_FILTERING                 = 211;
+
+       /**
+        * Status: A hook function returned an error
+        */
        const AS_HOOK_ERROR_EXPECTED       = 212;
+
+       /**
+        * Status: User is blocked from editting this page
+        */
        const AS_BLOCKED_PAGE_FOR_USER     = 215;
+
+       /**
+        * Status: Content too big (> $wgMaxArticleSize)
+        */
        const AS_CONTENT_TOO_BIG           = 216;
+
+       /**
+        * Status: User cannot edit? (not used)
+        */
        const AS_USER_CANNOT_EDIT          = 217;
+
+       /**
+        * Status: this anonymous user is not allowed to edit this page
+        */
        const AS_READ_ONLY_PAGE_ANON       = 218;
+
+       /**
+        * Status: this logged in user is not allowed to edit this page
+        */
        const AS_READ_ONLY_PAGE_LOGGED     = 219;
+
+       /**
+        * Status: wiki is in readonly mode (wfReadOnly() == true)
+        */
        const AS_READ_ONLY_PAGE            = 220;
+
+       /**
+        * Status: rate limiter for action 'edit' was tripped
+        */
        const AS_RATE_LIMITED              = 221;
+
+       /**
+        * Status: article was deleted while editting and param wpRecreate == false or form
+        * was not posted
+        */
        const AS_ARTICLE_WAS_DELETED       = 222;
+
+       /**
+        * Status: user tried to create this page, but is not allowed to do that
+        * ( Title->usercan('create') == false )
+        */
        const AS_NO_CREATE_PERMISSION      = 223;
+
+       /**
+        * Status: user tried to create a blank page
+        */
        const AS_BLANK_ARTICLE             = 224;
+
+       /**
+        * Status: (non-resolvable) edit conflict
+        */
        const AS_CONFLICT_DETECTED         = 225;
+
+       /**
+        * Status: no edit summary given and the user has forceeditsummary set and the user is not
+        * editting in his own userspace or talkspace and wpIgnoreBlankSummary == false
+        */
        const AS_SUMMARY_NEEDED            = 226;
+
+       /**
+        * Status: user tried to create a new section without content
+        */
        const AS_TEXTBOX_EMPTY             = 228;
+
+       /**
+        * Status: article is too big (> $wgMaxArticleSize), after merging in the new section
+        */
        const AS_MAX_ARTICLE_SIZE_EXCEEDED = 229;
+
+       /**
+        * not used
+        */
        const AS_OK                        = 230;
+
+       /**
+        * Status: WikiPage::doEdit() was unsuccessfull
+        */
        const AS_END                       = 231;
+
+       /**
+        * Status: summary contained spam according to one of the regexes in $wgSummarySpamRegex
+        */
        const AS_SPAM_ERROR                = 232;
+
+       /**
+        * Status: anonymous user is not allowed to upload (User::isAllowed('upload') == false)
+        */
        const AS_IMAGE_REDIRECT_ANON       = 233;
+
+       /**
+        * Status: logged in user is not allowed to upload (User::isAllowed('upload') == false)
+        */
        const AS_IMAGE_REDIRECT_LOGGED     = 234;
 
        /**
@@ -113,10 +212,9 @@ class EditPage {
        public $suppressIntro = false;
 
        /**
-        * @todo document
         * @param $article Article
         */
-       public function __construct( $article ) {
+       public function __construct( Article $article ) {
                $this->mArticle = $article;
                $this->mTitle = $article->getTitle();
        }
@@ -235,14 +333,6 @@ class EditPage {
                        return;
                }
 
-               $wgOut->addModules( array( 'mediawiki.action.edit' ) );
-
-               if ( $wgUser->getOption( 'uselivepreview', false ) ) {
-                       $wgOut->addModules( 'mediawiki.legacy.preview' );
-               }
-               // Bug #19334: textarea jumps when editing articles in IE8
-               $wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
-
                wfProfileIn( __METHOD__."-business-end" );
 
                $this->isConflict = false;
@@ -254,36 +344,8 @@ class EditPage {
                $this->isNew                = !$this->mTitle->exists() || $this->section == 'new';
 
                # Show applicable editing introductions
-               if ( $this->formtype == 'initial' || $this->firsttime )
+               if ( $this->formtype == 'initial' || $this->firsttime ) {
                        $this->showIntro();
-
-               if ( $this->mTitle->isTalkPage() ) {
-                       $wgOut->addWikiMsg( 'talkpagetext' );
-               }
-
-               # Optional notices on a per-namespace and per-page basis
-               $editnotice_ns   = 'editnotice-'.$this->mTitle->getNamespace();
-               $editnotice_ns_message = wfMessage( $editnotice_ns )->inContentLanguage();
-               if ( $editnotice_ns_message->exists() ) {
-                       $wgOut->addWikiText( $editnotice_ns_message->plain() );
-               }
-               if ( MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) {
-                       $parts = explode( '/', $this->mTitle->getDBkey() );
-                       $editnotice_base = $editnotice_ns;
-                       while ( count( $parts ) > 0 ) {
-                               $editnotice_base .= '-'.array_shift( $parts );
-                               $editnotice_base_msg = wfMessage( $editnotice_base )->inContentLanguage();
-                               if ( $editnotice_base_msg->exists() ) {
-                                       $wgOut->addWikiText( $editnotice_base_msg->plain()  );
-                               }
-                       }
-               } else {
-                       # Even if there are no subpages in namespace, we still don't want / in MW ns.
-                       $editnoticeText = $editnotice_ns . '-' . str_replace( '/', '-', $this->mTitle->getDBkey() );
-                       $editnoticeMsg = wfMessage( $editnoticeText )->inContentLanguage();
-                       if ( $editnoticeMsg->exists() ) {
-                               $wgOut->addWikiText( $editnoticeMsg->plain() );
-                       }
                }
 
                # Attempt submission here.  This will check for edit conflicts,
@@ -346,7 +408,7 @@ class EditPage {
        /**
         * Display a permissions error page, like OutputPage::showPermissionsErrorPage(),
         * but with the following differences:
-        * - If redlink=1, the user will be redirect to the page
+        * - If redlink=1, the user will be redirected to the page
         * - If there is content to display or the error occurs while either saving,
         *   previewing or showing the difference, it will be a
         *   "View source for ..." page displaying the source code after the error message.
@@ -802,7 +864,9 @@ class EditPage {
                if ( $revision === null ) {
                        return '';
                }
-               return $this->mArticle->getContent();
+
+        $content = $this->mArticle->getContentObject();
+               return $content->getRawData(); # this editor is for editing the raw text. so use the raw text.
        }
 
        /**
@@ -838,7 +902,7 @@ class EditPage {
         * @param $preload String: representing the title to preload from.
         * @return String
         */
-       protected function getPreloadedText( $preload ) {
+       protected function getPreloadedText( $preload ) { #FIXME: change to getPreloadedContent()
                global $wgUser, $wgParser;
 
                if ( !empty( $this->mPreloadText ) ) {
@@ -866,7 +930,7 @@ class EditPage {
                }
 
                $parserOptions = ParserOptions::newFromUser( $wgUser );
-               return $wgParser->getPreloadText( $page->getRawText(), $title, $parserOptions );
+               return $wgParser->getPreloadText( $page->getRawText(), $title, $parserOptions ); #FIXME: create Content::getPreloadCopy
        }
 
        /**
@@ -1235,10 +1299,12 @@ class EditPage {
                        
                        if ( $this->isConflict ) {
                                wfDebug( __METHOD__ . ": conflict! getting section '$this->section' for time '$this->edittime' (article time '{$timestamp}')\n" );
-                               $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $sectionTitle, $this->edittime );
+                               $cnt = $this->mArticle->replaceSection( $this->section, $this->textbox1, $sectionTitle, $this->edittime );
+                $text = ContentHandler::getContentText($cnt); #FIXME: use Content object throughout, make edit form aware of content model and serialization format
                        } else {
                                wfDebug( __METHOD__ . ": getting section '$this->section'\n" );
-                               $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $sectionTitle );
+                $cnt = $this->mArticle->replaceSection( $this->section, $this->textbox1, $sectionTitle );
+                $text = ContentHandler::getContentText($cnt); #FIXME: use Content object throughout, make edit form aware of content model and serialization format
                        }
                        if ( is_null( $text ) ) {
                                wfDebug( __METHOD__ . ": activating conflict; section replace failed.\n" );
@@ -1246,7 +1312,7 @@ class EditPage {
                                $text = $this->textbox1; // do not try to merge here!
                        } elseif ( $this->isConflict ) {
                                # Attempt merge
-                               if ( $this->mergeChangesInto( $text ) ) {
+                               if ( $this->mergeChangesInto( $text ) ) { #FIXME: passe/receive Content object
                                        // Successful merge! Maybe we should tell the user the good news?
                                        $this->isConflict = false;
                                        wfDebug( __METHOD__ . ": Suppressing edit conflict, successful merge.\n" );
@@ -1449,7 +1515,7 @@ class EditPage {
                        wfProfileOut( __METHOD__ );
                        return false;
                }
-               $baseText = $baseRevision->getText();
+               $baseContent = $baseRevision->getContent();
 
                // The current state, we want to merge updates into it
                $currentRevision = Revision::loadFromTitle( $db, $this->mTitle );
@@ -1457,11 +1523,14 @@ class EditPage {
                        wfProfileOut( __METHOD__ );
                        return false;
                }
-               $currentText = $currentRevision->getText();
+               $currentContent = $currentRevision->getContent();
+
+        $handler = ContentHandler::getForModelName( $baseContent->getModelName() );
+        $editContent = $handler->unserialize( $editText ); #FIXME: supply serialization fomrat from edit form!
 
-               $result = '';
-               if ( wfMerge( $baseText, $editText, $currentText, $result ) ) {
-                       $editText = $result;
+               $result = $handler->merge3( $baseContent, $editContent, $currentContent );
+               if ( $result ) {
+                       $editText = ContentHandler::getContentText($result);  #FIXME: supply serialization fomrat from edit form!
                        wfProfileOut( __METHOD__ );
                        return true;
                } else {
@@ -1527,8 +1596,21 @@ class EditPage {
        }
 
        function setHeaders() {
-               global $wgOut;
+               global $wgOut, $wgUser;
+
+               $wgOut->addModules( 'mediawiki.action.edit' );
+
+               if ( $wgUser->getOption( 'uselivepreview', false ) ) {
+                       $wgOut->addModules( 'mediawiki.legacy.preview' );
+               }
+               // Bug #19334: textarea jumps when editing articles in IE8
+               $wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
+
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
+
+               # Enabled article-related sidebar, toplinks, etc.
+               $wgOut->setArticleRelated( true );
+
                if ( $this->isConflict ) {
                        $wgOut->setPageTitle( wfMessage( 'editconflict', $this->getContextTitle()->getPrefixedText() ) );
                } elseif ( $this->section != '' ) {
@@ -1652,9 +1734,6 @@ class EditPage {
 
                $this->setHeaders();
 
-               # Enabled article-related sidebar, toplinks, etc.
-               $wgOut->setArticleRelated( true );
-
                if ( $this->showHeader() === false ) {
                        wfProfileOut( __METHOD__ );
                        return;
@@ -1805,6 +1884,36 @@ class EditPage {
 
        protected function showHeader() {
                global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
+
+               if ( $this->mTitle->isTalkPage() ) {
+                       $wgOut->addWikiMsg( 'talkpagetext' );
+               }
+
+               # Optional notices on a per-namespace and per-page basis
+               $editnotice_ns   = 'editnotice-'.$this->mTitle->getNamespace();
+               $editnotice_ns_message = wfMessage( $editnotice_ns )->inContentLanguage();
+               if ( $editnotice_ns_message->exists() ) {
+                       $wgOut->addWikiText( $editnotice_ns_message->plain() );
+               }
+               if ( MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) {
+                       $parts = explode( '/', $this->mTitle->getDBkey() );
+                       $editnotice_base = $editnotice_ns;
+                       while ( count( $parts ) > 0 ) {
+                               $editnotice_base .= '-'.array_shift( $parts );
+                               $editnotice_base_msg = wfMessage( $editnotice_base )->inContentLanguage();
+                               if ( $editnotice_base_msg->exists() ) {
+                                       $wgOut->addWikiText( $editnotice_base_msg->plain()  );
+                               }
+                       }
+               } else {
+                       # Even if there are no subpages in namespace, we still don't want / in MW ns.
+                       $editnoticeText = $editnotice_ns . '-' . str_replace( '/', '-', $this->mTitle->getDBkey() );
+                       $editnoticeMsg = wfMessage( $editnoticeText )->inContentLanguage();
+                       if ( $editnoticeMsg->exists() ) {
+                               $wgOut->addWikiText( $editnoticeMsg->plain() );
+                       }
+               }
+
                if ( $this->isConflict ) {
                        $wgOut->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
                        $this->edittime = $this->mArticle->getTimestamp();
@@ -2138,6 +2247,7 @@ HTML
                $attribs = $customAttribs + array(
                        'accesskey' => ',',
                        'id'   => $name,
+                       'cols' => $wgUser->getIntOption( 'cols' ),
                        'rows' => $wgUser->getIntOption( 'rows' ),
                        'style' => '' // avoid php notices when appending preferences (appending allows customAttribs['style'] to still work
                );
@@ -2449,6 +2559,7 @@ HTML
                # don't parse non-wikitext pages, show message about preview
                # XXX: stupid php bug won't let us use $this->getContextTitle()->isCssJsSubpage() here -- This note has been there since r3530. Sure the bug was fixed time ago?
 
+        #FIXME: get appropriate content handler!
                if ( $this->isCssJsSubpage || !$this->mTitle->isWikitextPage() ) {
                        if( $this->mTitle->isCssJsSubpage() ) {
                                $level = 'user';
@@ -2461,6 +2572,7 @@ HTML
                        # Used messages to make sure grep find them:
                        # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview
                        if( $level ) {
+                           #FIXME: move this crud into ContentHandler class!
                                if (preg_match( "/\\.css$/", $this->mTitle->getText() ) ) {
                                        $previewtext = "<div id='mw-{$level}csspreview'>\n" . wfMsg( "{$level}csspreview" ) . "\n</div>";
                                        $class = "mw-code mw-css";
@@ -2672,7 +2784,7 @@ HTML
                        )
                );
 
-               $script = '';
+               $script = 'mw.loader.using("mediawiki.action.edit", function() {';
                foreach ( $toolarray as $tool ) {
                        if ( !$tool ) {
                                continue;
@@ -2693,6 +2805,14 @@ HTML
 
                        $script .= Xml::encodeJsCall( 'mw.toolbar.addButton', $params );
                }
+               
+               // This used to be called on DOMReady from mediawiki.action.edit, which
+               // ended up causing race conditions with the setup code above.
+               $script .= "\n" .
+                       "// Create button bar\n" .
+                       "$(function() { mw.toolbar.init(); } );\n";
+
+               $script .= '});';
                $wgOut->addScript( Html::inlineScript( ResourceLoader::makeLoaderConditionalScript( $script ) ) );
 
                $toolbar = '<div id="toolbar"></div>';