Merge "Cleanup RecentChangeTest, move things out that don't belong"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 21 Sep 2015 14:15:26 +0000 (14:15 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 21 Sep 2015 14:15:26 +0000 (14:15 +0000)
15 files changed:
docs/hooks.txt
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/FileBackendStore.php
includes/filebackend/lockmanager/LockManager.php
includes/page/ImagePage.php
includes/page/WikiPage.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderModule.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialSearch.php
includes/upload/UploadBase.php
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.special/mediawiki.special.preferences.css
resources/src/mediawiki.special/mediawiki.special.search.css

index b7f31cb..f5999a5 100644 (file)
@@ -1272,20 +1272,21 @@ $user: User being checked
 $confirmed: Whether or not the email address is confirmed
 
 'EmailUser': Before sending email from one user to another.
-$to: address of receiving user
-$from: address of sending user
+$to: MailAddress object of receiving user
+$from: MailAddress object of sending user
 $subject: subject of the mail
 $text: text of the mail
+&$error: Out-param for an error
 
 'EmailUserCC': Before sending the copy of the email to the author.
-$to: address of receiving user
-$from: address of sending user
+$to: MailAddress object of receiving user
+$from: MailAddress object of sending user
 $subject: subject of the mail
 $text: text of the mail
 
 'EmailUserComplete': After sending email from one user to another.
-$to: address of receiving user
-$from: address of sending user
+$to: MailAddress object of receiving user
+$from: MailAddress object of sending user
 $subject: subject of the mail
 $text: text of the mail
 
index 6c6a90b..1603d44 100644 (file)
  * Only use this class when transitioning from one storage system to another.
  *
  * Read operations are only done on the 'master' backend for consistency.
- * Write operations are performed on all backends, in the order defined.
- * If an operation fails on one backend it will be rolled back from the others.
+ * Write operations are performed on all backends, starting with the master.
+ * This makes a best-effort to have transactional semantics, but since requests
+ * may sometimes fail, the use of "autoResync" or background scripts to fix
+ * inconsistencies is important.
  *
  * @ingroup FileBackend
  * @since 1.19
@@ -45,6 +47,8 @@ class FileBackendMultiWrite extends FileBackend {
 
        /** @var int Index of master backend */
        protected $masterIndex = -1;
+       /** @var int Index of read affinity backend */
+       protected $readIndex = -1;
 
        /** @var int Bitfield */
        protected $syncChecks = 0;
@@ -52,12 +56,6 @@ class FileBackendMultiWrite extends FileBackend {
        /** @var string|bool */
        protected $autoResync = false;
 
-       /** @var array */
-       protected $noPushDirConts = array();
-
-       /** @var bool */
-       protected $noPushQuickOps = false;
-
        /* Possible internal backend consistency checks */
        const CHECK_SIZE = 1;
        const CHECK_TIME = 2;
@@ -73,6 +71,7 @@ class FileBackendMultiWrite extends FileBackend {
         *                      FileBackendStore class, but with these additional settings:
         *                        - class         : The name of the backend class
         *                        - isMultiMaster : This must be set for one backend.
+        *                        - readAffinity  : Use this for reads without 'latest' set.
         *                        - template:     : If given a backend name, this will use
         *                                          the config of that backend as a template.
         *                                          Values specified here take precedence.
@@ -86,8 +85,6 @@ class FileBackendMultiWrite extends FileBackend {
         *                      Use "conservative" to limit resyncing to copying newer master
         *                      backend files over older (or non-existing) clone backend files.
         *                      Cases that cannot be handled will result in operation abortion.
-        *   - noPushQuickOps : (hack) Only apply doQuickOperations() to the master backend.
-        *   - noPushDirConts : (hack) Only apply directory functions to the master backend.
         *
         * @param array $config
         * @throws FileBackendError
@@ -100,12 +97,6 @@ class FileBackendMultiWrite extends FileBackend {
                $this->autoResync = isset( $config['autoResync'] )
                        ? $config['autoResync']
                        : false;
-               $this->noPushQuickOps = isset( $config['noPushQuickOps'] )
-                       ? $config['noPushQuickOps']
-                       : false;
-               $this->noPushDirConts = isset( $config['noPushDirConts'] )
-                       ? $config['noPushDirConts']
-                       : array();
                // Construct backends here rather than via registration
                // to keep these backends hidden from outside the proxy.
                $namesUsed = array();
@@ -132,6 +123,9 @@ class FileBackendMultiWrite extends FileBackend {
                                $this->masterIndex = $index; // this is the "master"
                                $config['fileJournal'] = $this->fileJournal; // log under proxy backend
                        }
+                       if ( !empty( $config['readAffinity'] ) ) {
+                               $this->readIndex = $index; // prefer this for reads
+                       }
                        // Create sub-backend object
                        if ( !isset( $config['class'] ) ) {
                                throw new FileBackendError( 'No class given for a backend config.' );
@@ -142,6 +136,9 @@ class FileBackendMultiWrite extends FileBackend {
                if ( $this->masterIndex < 0 ) { // need backends and must have a master
                        throw new FileBackendError( 'No master backend defined.' );
                }
+               if ( $this->readIndex < 0 ) {
+                       $this->readIndex = $this->masterIndex; // default
+               }
        }
 
        final protected function doOperationsInternal( array $ops, array $opts ) {
@@ -152,6 +149,7 @@ class FileBackendMultiWrite extends FileBackend {
                // Try to lock those files for the scope of this function...
                if ( empty( $opts['nonLocking'] ) ) {
                        // Try to lock those files for the scope of this function...
+                       /** @noinspection PhpUnusedLocalVariableInspection */
                        $scopeLock = $this->getScopedLocksForOps( $ops, $status );
                        if ( !$status->isOK() ) {
                                return $status; // abort
@@ -458,12 +456,10 @@ class FileBackendMultiWrite extends FileBackend {
                $masterStatus = $this->backends[$this->masterIndex]->doQuickOperations( $realOps );
                $status->merge( $masterStatus );
                // Propagate the operations to the clone backends...
-               if ( !$this->noPushQuickOps ) {
-                       foreach ( $this->backends as $index => $backend ) {
-                               if ( $index !== $this->masterIndex ) { // not done already
-                                       $realOps = $this->substOpBatchPaths( $ops, $backend );
-                                       $status->merge( $backend->doQuickOperations( $realOps ) );
-                               }
+               foreach ( $this->backends as $index => $backend ) {
+                       if ( $index !== $this->masterIndex ) { // not done already
+                               $realOps = $this->substOpBatchPaths( $ops, $backend );
+                               $status->merge( $backend->doQuickOperations( $realOps ) );
                        }
                }
                // Make 'success', 'successCount', and 'failCount' fields reflect
@@ -476,24 +472,11 @@ class FileBackendMultiWrite extends FileBackend {
                return $status;
        }
 
-       /**
-        * @param string $path Storage path
-        * @return bool Path container should have dir changes pushed to all backends
-        */
-       protected function replicateContainerDirChanges( $path ) {
-               list( , $shortCont, ) = self::splitStoragePath( $path );
-
-               return !in_array( $shortCont, $this->noPushDirConts );
-       }
-
        protected function doPrepare( array $params ) {
                $status = Status::newGood();
-               $replicate = $this->replicateContainerDirChanges( $params['dir'] );
                foreach ( $this->backends as $index => $backend ) {
-                       if ( $replicate || $index == $this->masterIndex ) {
-                               $realParams = $this->substOpPaths( $params, $backend );
-                               $status->merge( $backend->doPrepare( $realParams ) );
-                       }
+                       $realParams = $this->substOpPaths( $params, $backend );
+                       $status->merge( $backend->doPrepare( $realParams ) );
                }
 
                return $status;
@@ -501,12 +484,9 @@ class FileBackendMultiWrite extends FileBackend {
 
        protected function doSecure( array $params ) {
                $status = Status::newGood();
-               $replicate = $this->replicateContainerDirChanges( $params['dir'] );
                foreach ( $this->backends as $index => $backend ) {
-                       if ( $replicate || $index == $this->masterIndex ) {
-                               $realParams = $this->substOpPaths( $params, $backend );
-                               $status->merge( $backend->doSecure( $realParams ) );
-                       }
+                       $realParams = $this->substOpPaths( $params, $backend );
+                       $status->merge( $backend->doSecure( $realParams ) );
                }
 
                return $status;
@@ -514,12 +494,9 @@ class FileBackendMultiWrite extends FileBackend {
 
        protected function doPublish( array $params ) {
                $status = Status::newGood();
-               $replicate = $this->replicateContainerDirChanges( $params['dir'] );
                foreach ( $this->backends as $index => $backend ) {
-                       if ( $replicate || $index == $this->masterIndex ) {
-                               $realParams = $this->substOpPaths( $params, $backend );
-                               $status->merge( $backend->doPublish( $realParams ) );
-                       }
+                       $realParams = $this->substOpPaths( $params, $backend );
+                       $status->merge( $backend->doPublish( $realParams ) );
                }
 
                return $status;
@@ -527,12 +504,9 @@ class FileBackendMultiWrite extends FileBackend {
 
        protected function doClean( array $params ) {
                $status = Status::newGood();
-               $replicate = $this->replicateContainerDirChanges( $params['dir'] );
                foreach ( $this->backends as $index => $backend ) {
-                       if ( $replicate || $index == $this->masterIndex ) {
-                               $realParams = $this->substOpPaths( $params, $backend );
-                               $status->merge( $backend->doClean( $realParams ) );
-                       }
+                       $realParams = $this->substOpPaths( $params, $backend );
+                       $status->merge( $backend->doClean( $realParams ) );
                }
 
                return $status;
@@ -540,44 +514,52 @@ class FileBackendMultiWrite extends FileBackend {
 
        public function concatenate( array $params ) {
                // We are writing to an FS file, so we don't need to do this per-backend
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->concatenate( $realParams );
+               return $this->backends[$index]->concatenate( $realParams );
        }
 
        public function fileExists( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->fileExists( $realParams );
+               return $this->backends[$index]->fileExists( $realParams );
        }
 
        public function getFileTimestamp( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams );
+               return $this->backends[$index]->getFileTimestamp( $realParams );
        }
 
        public function getFileSize( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileSize( $realParams );
+               return $this->backends[$index]->getFileSize( $realParams );
        }
 
        public function getFileStat( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileStat( $realParams );
+               return $this->backends[$index]->getFileStat( $realParams );
        }
 
        public function getFileXAttributes( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileXAttributes( $realParams );
+               return $this->backends[$index]->getFileXAttributes( $realParams );
        }
 
        public function getFileContentsMulti( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
-               $contentsM = $this->backends[$this->masterIndex]->getFileContentsMulti( $realParams );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+               $contentsM = $this->backends[$index]->getFileContentsMulti( $realParams );
 
                $contents = array(); // (path => FSFile) mapping using the proxy backend's name
                foreach ( $contentsM as $path => $data ) {
@@ -588,26 +570,31 @@ class FileBackendMultiWrite extends FileBackend {
        }
 
        public function getFileSha1Base36( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileSha1Base36( $realParams );
+               return $this->backends[$index]->getFileSha1Base36( $realParams );
        }
 
        public function getFileProps( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileProps( $realParams );
+               return $this->backends[$index]->getFileProps( $realParams );
        }
 
        public function streamFile( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->streamFile( $realParams );
+               return $this->backends[$index]->streamFile( $realParams );
        }
 
        public function getLocalReferenceMulti( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
-               $fsFilesM = $this->backends[$this->masterIndex]->getLocalReferenceMulti( $realParams );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+               $fsFilesM = $this->backends[$index]->getLocalReferenceMulti( $realParams );
 
                $fsFiles = array(); // (path => FSFile) mapping using the proxy backend's name
                foreach ( $fsFilesM as $path => $fsFile ) {
@@ -618,8 +605,10 @@ class FileBackendMultiWrite extends FileBackend {
        }
 
        public function getLocalCopyMulti( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
-               $tempFilesM = $this->backends[$this->masterIndex]->getLocalCopyMulti( $realParams );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+               $tempFilesM = $this->backends[$index]->getLocalCopyMulti( $realParams );
 
                $tempFiles = array(); // (path => TempFSFile) mapping using the proxy backend's name
                foreach ( $tempFilesM as $path => $tempFile ) {
@@ -630,9 +619,10 @@ class FileBackendMultiWrite extends FileBackend {
        }
 
        public function getFileHttpUrl( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$this->masterIndex]->getFileHttpUrl( $realParams );
+               return $this->backends[$index]->getFileHttpUrl( $realParams );
        }
 
        public function directoryExists( array $params ) {
@@ -665,13 +655,15 @@ class FileBackendMultiWrite extends FileBackend {
        }
 
        public function preloadCache( array $paths ) {
-               $realPaths = $this->substPaths( $paths, $this->backends[$this->masterIndex] );
-               $this->backends[$this->masterIndex]->preloadCache( $realPaths );
+               $realPaths = $this->substPaths( $paths, $this->backends[$this->readIndex] );
+               $this->backends[$this->readIndex]->preloadCache( $realPaths );
        }
 
        public function preloadFileStat( array $params ) {
-               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
-               return $this->backends[$this->masterIndex]->preloadFileStat( $realParams );
+               $index = $this->getReadIndexFromParams( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+               return $this->backends[$index]->preloadFileStat( $realParams );
        }
 
        public function getScopedLocksForOps( array $ops, Status $status ) {
@@ -688,4 +680,12 @@ class FileBackendMultiWrite extends FileBackend {
                // Actually acquire the locks
                return $this->getScopedFileLocks( $pbPaths, 'mixed', $status );
        }
+
+       /**
+        * @param array $params
+        * @return int The master or read affinity backend index, based on $params['latest']
+        */
+       protected function getReadIndexFromParams( array $params ) {
+               return !empty( $params['latest'] ) ? $this->masterIndex : $this->readIndex;
+       }
 }
index 2562f52..9433964 100644 (file)
@@ -1076,6 +1076,7 @@ abstract class FileBackendStore extends FileBackend {
                        // Build up a list of files to lock...
                        $paths = $this->getPathsToLockForOpsInternal( $performOps );
                        // Try to lock those files for the scope of this function...
+
                        $scopeLock = $this->getScopedFileLocks( $paths, 'mixed', $status );
                        if ( !$status->isOK() ) {
                                return $status; // abort
index 615ba77..8115fd4 100644 (file)
@@ -102,7 +102,6 @@ abstract class LockManager {
         * @since 1.22
         */
        final public function lockByType( array $pathsByType, $timeout = 0 ) {
-               $status = Status::newGood();
                $pathsByType = $this->normalizePathsByType( $pathsByType );
                $msleep = array( 0, 50, 100, 300, 500 ); // retry backoff times
                $start = microtime( true );
index 43b12b2..9b9e3cb 100644 (file)
@@ -712,7 +712,7 @@ EOT
                $canUpload = $this->getTitle()->quickUserCan( 'upload', $this->getContext()->getUser() );
                if ( $canUpload && UploadBase::userCanReUpload(
                                $this->getContext()->getUser(),
-                               $this->mPage->getFile()->name )
+                               $this->mPage->getFile() )
                ) {
                        $ulink = Linker::makeExternalLink(
                                $this->getUploadUrl(),
index 69b675b..30590cf 100644 (file)
@@ -1765,7 +1765,6 @@ class WikiPage implements Page, IDBAccessObject {
 
                $dbw = wfGetDB( DB_MASTER );
                $now = wfTimestampNow();
-               $this->mTimestamp = $now;
 
                if ( $flags & EDIT_UPDATE ) {
                        // Update article, but only if changed.
@@ -1844,6 +1843,7 @@ class WikiPage implements Page, IDBAccessObject {
                                $user->incEditCount();
 
                                $dbw->commit( __METHOD__ );
+                               $this->mTimestamp = $now;
                        } else {
                                // Bug 32948: revision ID must be set to page {{REVISIONID}} and
                                // related variables correctly
@@ -1938,6 +1938,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $user->incEditCount();
 
                        $dbw->commit( __METHOD__ );
+                       $this->mTimestamp = $now;
 
                        // Update links, etc.
                        $this->doEditUpdates( $revision, $user, array( 'created' => true ) );
index 1886436..1f48514 100644 (file)
@@ -283,8 +283,8 @@ class ResourceLoader implements LoggerAwareInterface {
                $this->register( include "$IP/resources/Resources.php" );
                $this->register( include "$IP/resources/ResourcesOOUI.php" );
                // Register extension modules
-               Hooks::run( 'ResourceLoaderRegisterModules', array( &$this ) );
                $this->register( $config->get( 'ResourceModules' ) );
+               Hooks::run( 'ResourceLoaderRegisterModules', array( &$this ) );
 
                if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
                        $this->registerTestModules();
@@ -747,18 +747,18 @@ class ResourceLoader implements LoggerAwareInterface {
 
                if ( $context->getImageObj() && $this->errors ) {
                        // We can't show both the error messages and the response when it's an image.
-                       $errorText = '';
-                       foreach ( $this->errors as $error ) {
-                               $errorText .= $error . "\n";
-                       }
-                       $response = $errorText;
+                       $response = implode( "\n\n",  $this->errors );
                } elseif ( $this->errors ) {
-                       // Prepend comments indicating errors
-                       $errorText = '';
-                       foreach ( $this->errors as $error ) {
-                               $errorText .= self::makeComment( $error );
+                       $errorText = implode( "\n\n", $this->errors );
+                       $errorResponse = self::makeComment( $errorText );
+                       if ( $context->shouldIncludeScripts() ) {
+                               $errorResponse .= 'if (window.console && console.error) {'
+                                       . Xml::encodeJsCall( 'console.error', array( $errorText ) )
+                                       . "}\n";
                        }
-                       $response = $errorText . $response;
+
+                       // Prepend error info to the response
+                       $response = $errorResponse . $response;
                }
 
                $this->errors = array();
index 1a4d1f1..1d3ffb5 100644 (file)
@@ -857,14 +857,35 @@ abstract class ResourceLoaderModule {
         * @return string Hash
         */
        protected static function safeFileHash( $filePath ) {
+               static $cache;
+
+               if ( !$cache ) {
+                       $cache = ObjectCache::newAccelerator( CACHE_NONE );
+               }
+
+               MediaWiki\suppressWarnings();
+               $mtime = filemtime( $filePath );
+               MediaWiki\restoreWarnings();
+               if ( !$mtime ) {
+                       return '';
+               }
+
+               $cacheKey = wfGlobalCacheKey( 'resourceloader', __METHOD__, $filePath );
+               $cachedHash = $cache->get( $cacheKey );
+               if ( isset( $cachedHash['mtime'] ) && $cachedHash['mtime'] === $mtime ) {
+                       return $cachedHash['hash'];
+               }
+
                MediaWiki\suppressWarnings();
                $contents = file_get_contents( $filePath );
                MediaWiki\restoreWarnings();
-               if ( $contents !== false ) {
-                       $hash = hash( 'md4', $contents );
-               } else {
-                       $hash = '';
+               if ( !$contents ) {
+                       return '';
                }
+
+               $hash = hash( 'md4', $contents );
+               $cache->set( $cacheKey, array( 'mtime' => $mtime, 'hash' => $hash ), 60 * 60 * 24 );
+
                return $hash;
        }
 }
index 1754471..92cb8bf 100644 (file)
@@ -369,7 +369,10 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        if ( $data['CCMe'] && $to != $from ) {
                                $cc_subject = $context->msg( 'emailccsubject' )->rawParams(
                                        $target->getName(), $subject )->text();
+
+                               // target and sender are equal, because this is the CC for the sender
                                Hooks::run( 'EmailUserCC', array( &$from, &$from, &$cc_subject, &$text ) );
+
                                $ccStatus = UserMailer::send( $from, $from, $cc_subject, $text );
                                $status->merge( $ccStatus );
                        }
index 6606c7f..fd0745f 100644 (file)
@@ -366,14 +366,14 @@ class SpecialSearch extends SpecialPage {
                                $out->wrapWikiMsg( "==$1==\n", 'textmatches' );
                        }
 
-                       // show interwiki results if any
-                       if ( $textMatches->hasInterwikiResults() ) {
-                               $out->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(), $term ) );
-                       }
                        // show results
                        if ( $numTextMatches > 0 ) {
                                $out->addHTML( $this->showMatches( $textMatches ) );
                        }
+                       // show interwiki results if any
+                       if ( $textMatches->hasInterwikiResults() ) {
+                               $out->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(), $term ) );
+                       }
 
                        $textMatches->free();
                }
@@ -388,6 +388,7 @@ class SpecialSearch extends SpecialPage {
                        }
                }
 
+               $out->addHTML( '<div class="visualClear"></div>\n' );
                if ( $prevnext ) {
                        $out->addHTML( "<p class='mw-search-pager-bottom'>{$prevnext}</p>\n" );
                }
index b06b91e..30a85ae 100644 (file)
@@ -1706,24 +1706,21 @@ abstract class UploadBase {
         * Check if a user is the last uploader
         *
         * @param User $user
-        * @param string $img Image name
+        * @param File $img
         * @return bool
         */
-       public static function userCanReUpload( User $user, $img ) {
+       public static function userCanReUpload( User $user, File $img ) {
                if ( $user->isAllowed( 'reupload' ) ) {
                        return true; // non-conditional
-               }
-               if ( !$user->isAllowed( 'reupload-own' ) ) {
+               } elseif ( !$user->isAllowed( 'reupload-own' ) ) {
                        return false;
                }
-               if ( is_string( $img ) ) {
-                       $img = wfLocalFile( $img );
-               }
+
                if ( !( $img instanceof LocalFile ) ) {
                        return false;
                }
 
-               $img->load( File::READ_LATEST );
+               $img->load();
 
                return $user->getId() == $img->getUser( 'id' );
        }
index b0f86e6..66161ed 100644 (file)
@@ -256,14 +256,6 @@ div.htmlform-tip {
        color: #666;
 }
 
-fieldset.prefsection {
-       margin-top: 1em;
-}
-
-fieldset.operaprefsection {
-       margin-left: 15em;
-}
-
 /* emulate center */
 .center {
        width: 100%;
index 9045e4c..961c02b 100644 (file)
@@ -206,18 +206,6 @@ td.mw-label {
        vertical-align: middle;
 }
 
-.prefsection td.mw-label {
-       width: 20%;
-}
-
-.prefsection table {
-       width: 100%;
-}
-
-.prefsection table.mw-htmlform-matrix {
-       width: auto;
-}
-
 td.mw-submit {
        white-space: nowrap;
 }
index 8fb9a47..9e5efd3 100644 (file)
 .mw-preferences-messagebox {
        display: none;
 }
+
+.prefsection td.mw-label {
+       width: 20%;
+}
+
+.prefsection table {
+       width: 100%;
+}
+
+.prefsection table.mw-htmlform-matrix {
+       width: auto;
+}
index 8f845df..b869314 100644 (file)
@@ -27,6 +27,7 @@ div.searchresult {
 }
 .mw-search-results {
        margin-left: 0.4em;
+       float: left;
 }
 .mw-search-results li {
        padding-bottom: 1.2em;