Add $wgDiffEngine
[lhc/web/wiklou.git] / includes / diff / DifferenceEngine.php
index b8697e5..af01ca1 100644 (file)
@@ -544,7 +544,7 @@ class DifferenceEngine extends ContextSource {
                        if ( $samePage && $this->mNewPage && $permissionManager->quickUserCan(
                                'edit', $user, $this->mNewPage
                        ) ) {
-                               if ( $this->mNewRev->isCurrent() && $permissionManager->userCan(
+                               if ( $this->mNewRev->isCurrent() && $permissionManager->quickUserCan(
                                        'rollback', $user, $this->mNewPage
                                ) ) {
                                        $rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext(),
@@ -869,7 +869,7 @@ class DifferenceEngine extends ContextSource {
                        $out->setArticleFlag( true );
 
                        if ( !Hooks::run( 'ArticleRevisionViewCustom',
-                               [ $this->mNewRev->getRevisionRecord(), $this->mNewPage, $out ] )
+                               [ $this->mNewRev->getRevisionRecord(), $this->mNewPage, $this->mOldid, $out ] )
                        ) {
                                // Handled by extension
                                // NOTE: sync with hooks called in Article::view()
@@ -1178,7 +1178,7 @@ class DifferenceEngine extends ContextSource {
                $engine = $this->getEngine();
                $params = [
                        'diff',
-                       $engine,
+                       $engine === 'php' ? false : $engine, // Back compat
                        self::DIFF_VERSION,
                        "old-{$this->mOldid}",
                        "rev-{$this->mNewid}"
@@ -1288,35 +1288,59 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
-        * Process $wgExternalDiffEngine and get a sane, usable engine
+        * Process DiffEngine config and get a sane, usable engine
         *
-        * @return bool|string 'wikidiff2', path to an executable, or false
+        * @return string 'wikidiff2', 'php', or path to an executable
         * @internal For use by this class and TextSlotDiffRenderer only.
         */
        public static function getEngine() {
-               global $wgExternalDiffEngine;
-               // We use the global here instead of Config because we write to the value,
-               // and Config is not mutable.
-               if ( $wgExternalDiffEngine == 'wikidiff' || $wgExternalDiffEngine == 'wikidiff3' ) {
-                       wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27' );
-                       $wgExternalDiffEngine = false;
-               } elseif ( $wgExternalDiffEngine == 'wikidiff2' ) {
-                       wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.32' );
-                       $wgExternalDiffEngine = false;
-               } elseif ( !is_string( $wgExternalDiffEngine ) && $wgExternalDiffEngine !== false ) {
-                       // And prevent people from shooting themselves in the foot...
-                       wfWarn( '$wgExternalDiffEngine is set to a non-string value, forcing it to false' );
-                       $wgExternalDiffEngine = false;
-               }
-
-               if ( is_string( $wgExternalDiffEngine ) && is_executable( $wgExternalDiffEngine ) ) {
-                       return $wgExternalDiffEngine;
-               } elseif ( $wgExternalDiffEngine === false && function_exists( 'wikidiff2_do_diff' ) ) {
-                       return 'wikidiff2';
+               $diffEngine = MediaWikiServices::getInstance()->getMainConfig()
+                       ->get( 'DiffEngine' );
+               $externalDiffEngine = MediaWikiServices::getInstance()->getMainConfig()
+                       ->get( 'ExternalDiffEngine' );
+
+               if ( $diffEngine === null ) {
+                       $engines = [ 'external', 'wikidiff2', 'php' ];
                } else {
-                       // Native PHP
-                       return false;
+                       $engines = [ $diffEngine ];
+               }
+
+               $failureReason = null;
+               foreach ( $engines as $engine ) {
+                       switch ( $engine ) {
+                               case 'external':
+                                       if ( is_string( $externalDiffEngine ) ) {
+                                               if ( is_executable( $externalDiffEngine ) ) {
+                                                       return $externalDiffEngine;
+                                               }
+                                               $failureReason = 'ExternalDiffEngine config points to a non-executable';
+                                               if ( $diffEngine === null ) {
+                                                       wfDebug( "$failureReason, ignoring" );
+                                               }
+                                       } else {
+                                               $failureReason = 'ExternalDiffEngine config is set to a non-string value';
+                                               if ( $diffEngine === null && $externalDiffEngine ) {
+                                                       wfWarn( "$failureReason, ignoring" );
+                                               }
+                                       }
+                                       break;
+
+                               case 'wikidiff2':
+                                       if ( function_exists( 'wikidiff2_do_diff' ) ) {
+                                               return 'wikidiff2';
+                                       }
+                                       $failureReason = 'wikidiff2 is not available';
+                                       break;
+
+                               case 'php':
+                                       // Always available.
+                                       return 'php';
+
+                               default:
+                                       throw new DomainException( 'Invalid value for $wgDiffEngine: ' . $engine );
+                       }
                }
+               throw new UnexpectedValueException( "Cannot use diff engine '$engine': $failureReason" );
        }
 
        /**
@@ -1370,7 +1394,7 @@ class DifferenceEngine extends ContextSource {
                $engine = self::getEngine();
                if ( $engine === 'wikidiff2' ) {
                        return $this->debug( 'wikidiff2' );
-               } elseif ( $engine === false ) {
+               } elseif ( $engine === 'php' ) {
                        return $this->debug( 'native PHP' );
                } else {
                        return $this->debug( "external $engine" );
@@ -1511,10 +1535,6 @@ class DifferenceEngine extends ContextSource {
        private function userCanEdit( Revision $rev ) {
                $user = $this->getUser();
 
-               if ( !$rev->getContentHandler()->supportsDirectEditing() ) {
-                       return false;
-               }
-
                if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        return false;
                }
@@ -1717,14 +1737,29 @@ class DifferenceEngine extends ContextSource {
         *     false signifies that there is no previous/next revision ($old is the oldest/newest one).
         */
        public function mapDiffPrevNext( $old, $new ) {
+               $rl = MediaWikiServices::getInstance()->getRevisionLookup();
                if ( $new === 'prev' ) {
                        // Show diff between revision $old and the previous one. Get previous one from DB.
                        $newid = intval( $old );
-                       $oldid = $this->getTitle()->getPreviousRevisionID( $newid );
+                       $oldid = false;
+                       $newRev = $rl->getRevisionById( $newid );
+                       if ( $newRev ) {
+                               $oldRev = $rl->getPreviousRevision( $newRev );
+                               if ( $oldRev ) {
+                                       $oldid = $oldRev->getId();
+                               }
+                       }
                } elseif ( $new === 'next' ) {
                        // Show diff between revision $old and the next one. Get next one from DB.
                        $oldid = intval( $old );
-                       $newid = $this->getTitle()->getNextRevisionID( $oldid );
+                       $newid = false;
+                       $oldRev = $rl->getRevisionById( $oldid );
+                       if ( $oldRev ) {
+                               $newRev = $rl->getNextRevision( $oldRev );
+                               if ( $newRev ) {
+                                       $newid = $newRev->getId();
+                               }
+                       }
                } else {
                        $oldid = intval( $old );
                        $newid = intval( $new );