diff options
Diffstat (limited to 'includes/filerepo/FileRepo.php')
-rw-r--r-- | includes/filerepo/FileRepo.php | 175 |
1 files changed, 129 insertions, 46 deletions
diff --git a/includes/filerepo/FileRepo.php b/includes/filerepo/FileRepo.php index c9d34377..f94709b3 100644 --- a/includes/filerepo/FileRepo.php +++ b/includes/filerepo/FileRepo.php @@ -6,16 +6,15 @@ * @ingroup FileRepo */ abstract class FileRepo { + const FILES_ONLY = 1; const DELETE_SOURCE = 1; - const FIND_PRIVATE = 1; - const FIND_IGNORE_REDIRECT = 2; const OVERWRITE = 2; const OVERWRITE_SAME = 4; var $thumbScriptUrl, $transformVia404; var $descBaseUrl, $scriptDirUrl, $articleUrl, $fetchDescription, $initialCapital; var $pathDisclosureProtection = 'paranoid'; - var $descriptionCacheExpiry, $apiThumbCacheExpiry, $hashLevels; + var $descriptionCacheExpiry, $hashLevels, $url, $thumbUrl; /** * Factory functions for creating new files @@ -29,10 +28,10 @@ abstract class FileRepo { $this->name = $info['name']; // Optional settings - $this->initialCapital = true; // by default + $this->initialCapital = MWNamespace::isCapitalized( NS_FILE ); foreach ( array( 'descBaseUrl', 'scriptDirUrl', 'articleUrl', 'fetchDescription', - 'thumbScriptUrl', 'initialCapital', 'pathDisclosureProtection', - 'descriptionCacheExpiry', 'apiThumbCacheExpiry', 'hashLevels' ) as $var ) + 'thumbScriptUrl', 'initialCapital', 'pathDisclosureProtection', + 'descriptionCacheExpiry', 'hashLevels', 'url', 'thumbUrl' ) as $var ) { if ( isset( $info[$var] ) ) { $this->$var = $info[$var]; @@ -81,9 +80,24 @@ abstract class FileRepo { * version control should return false if the time is specified. * * @param mixed $title Title object or string - * @param mixed $time 14-character timestamp, or false for the current version - */ - function findFile( $title, $time = false, $flags = 0 ) { + * @param $options Associative array of options: + * time: requested time for an archived image, or false for the + * current version. An image object will be returned which was + * created at the specified time. + * + * ignoreRedirect: If true, do not follow file redirects + * + * private: If true, return restricted (deleted) files if the current + * user is allowed to view them. Otherwise, such files will not + * be found. + */ + function findFile( $title, $options = array() ) { + if ( !is_array( $options ) ) { + // MW 1.15 compat + $time = $options; + } else { + $time = isset( $options['time'] ) ? $options['time'] : false; + } if ( !($title instanceof Title) ) { $title = Title::makeTitleSafe( NS_FILE, $title ); if ( !is_object( $title ) ) { @@ -104,17 +118,17 @@ abstract class FileRepo { if ( $img && $img->exists() ) { if ( !$img->isDeleted(File::DELETED_FILE) ) { return $img; - } else if ( ($flags & FileRepo::FIND_PRIVATE) && $img->userCan(File::DELETED_FILE) ) { + } else if ( !empty( $options['private'] ) && $img->userCan(File::DELETED_FILE) ) { return $img; } } } - + # Now try redirects - if ( $flags & FileRepo::FIND_IGNORE_REDIRECT ) { + if ( !empty( $options['ignoreRedirect'] ) ) { return false; } - $redir = $this->checkRedirect( $title ); + $redir = $this->checkRedirect( $title ); if( $redir && $redir->getNamespace() == NS_FILE) { $img = $this->newFile( $redir ); if( !$img ) { @@ -127,22 +141,34 @@ abstract class FileRepo { } return false; } - + /* - * Find many files at once. - * @param array $titles, an array of titles - * @todo Think of a good way to optionally pass timestamps to this function. + * Find many files at once. + * @param array $items, an array of titles, or an array of findFile() options with + * the "title" option giving the title. Example: + * + * $findItem = array( 'title' => $title, 'private' => true ); + * $findBatch = array( $findItem ); + * $repo->findFiles( $findBatch ); */ - function findFiles( $titles ) { + function findFiles( $items ) { $result = array(); - foreach ( $titles as $index => $title ) { - $file = $this->findFile( $title ); + foreach ( $items as $index => $item ) { + if ( is_array( $item ) ) { + $title = $item['title']; + $options = $item; + unset( $options['title'] ); + } else { + $title = $item; + $options = array(); + } + $file = $this->findFile( $title, $options ); if ( $file ) $result[$file->getTitle()->getDBkey()] = $file; } return $result; } - + /** * Create a new File object from the local repository * @param mixed $sha1 SHA-1 key @@ -163,16 +189,23 @@ abstract class FileRepo { return call_user_func( $this->fileFactoryKey, $sha1, $this ); } } - + /** * Find an instance of the file with this key, created at the specified time * Returns false if the file does not exist. Repositories not supporting * version control should return false if the time is specified. * * @param string $sha1 string - * @param mixed $time 14-character timestamp, or false for the current version + * @param array $options Option array, same as findFile(). */ - function findFileFromKey( $sha1, $time = false, $flags = 0 ) { + function findFileFromKey( $sha1, $options = array() ) { + if ( !is_array( $options ) ) { + # MW 1.15 compat + $time = $options; + } else { + $time = isset( $options['time'] ) ? $options['time'] : false; + } + # First try the current version of the file to see if it precedes the timestamp $img = $this->newFileFromKey( $sha1 ); if ( !$img ) { @@ -187,7 +220,7 @@ abstract class FileRepo { if ( $img->exists() ) { if ( !$img->isDeleted(File::DELETED_FILE) ) { return $img; - } else if ( ($flags & FileRepo::FIND_PRIVATE) && $img->userCan(File::DELETED_FILE) ) { + } else if ( !empty( $options['private'] ) && $img->userCan(File::DELETED_FILE) ) { return $img; } } @@ -203,6 +236,15 @@ abstract class FileRepo { } /** + * Get the URL corresponding to one of the four basic zones + * @param String $zone One of: public, deleted, temp, thumb + * @return String or false + */ + function getZoneUrl( $zone ) { + return false; + } + + /** * Returns true if the repository can transform files via a 404 handler */ function canTransformVia404() { @@ -214,7 +256,7 @@ abstract class FileRepo { */ function getNameFromTitle( $title ) { global $wgCapitalLinks; - if ( $this->initialCapital != $wgCapitalLinks ) { + if ( $this->initialCapital != MWNamespace::isCapitalized( NS_FILE ) ) { global $wgContLang; $name = $title->getUserCaseDBKey(); if ( $this->initialCapital ) { @@ -238,7 +280,7 @@ abstract class FileRepo { return $path; } } - + /** * Get a relative path including trailing slash, e.g. f/fa/ * If the repo is not hashed, returns an empty string @@ -355,6 +397,17 @@ abstract class FileRepo { */ abstract function storeTemp( $originalName, $srcPath ); + + /** + * Append the contents of the source path to the given file. + * @param $srcPath string location of the source file + * @param $toAppendPath string path to append to. + * @param $flags Bitfield, may be FileRepo::DELETE_SOURCE to indicate + * that the source file should be deleted if possible + * @return mixed Status or false + */ + abstract function append( $srcPath, $toAppendPath, $flags = 0 ); + /** * Remove a temporary file or mark it for garbage collection * @param string $virtualUrl The virtual URL returned by storeTemp @@ -400,6 +453,21 @@ abstract class FileRepo { */ abstract function publishBatch( $triplets, $flags = 0 ); + function fileExists( $file, $flags = 0 ) { + $result = $this->fileExistsBatch( array( $file ), $flags ); + return $result[0]; + } + + /** + * Checks existence of an array of files. + * + * @param array $files URLs (or paths) of files to check + * @param integer $flags Bitwise combination of the following flags: + * self::FILES_ONLY Mark file as existing only if it is a file (not directory) + * @return Either array of files and existence flags, or false + */ + abstract function fileExistsBatch( $files, $flags = 0 ); + /** * Move a group of files to the deletion archive. * @@ -529,21 +597,25 @@ abstract class FileRepo { /** * Invalidates image redirect cache related to that image + * Doesn't do anything for repositories that don't support image redirects. * + * STUB * @param Title $title Title of image - */ - function invalidateImageRedirect( $title ) { - global $wgMemc; - $memcKey = $this->getMemcKey( "image_redirect:" . md5( $title->getPrefixedDBkey() ) ); - $wgMemc->delete( $memcKey ); - } - + */ + function invalidateImageRedirect( $title ) {} + + /** + * Get an array or iterator of file objects for files that have a given + * SHA-1 content hash. + * + * STUB + */ function findBySha1( $hash ) { return array(); } - + /** - * Get the human-readable name of the repo. + * Get the human-readable name of the repo. * @return string */ public function getDisplayName() { @@ -551,22 +623,33 @@ abstract class FileRepo { if ( $this->name == 'local' ) { return null; } + // 'shared-repo-name-wikimediacommons' is used when $wgUseInstantCommons = true $repoName = wfMsg( 'shared-repo-name-' . $this->name ); if ( !wfEmptyMsg( 'shared-repo-name-' . $this->name, $repoName ) ) { return $repoName; } - return wfMsg( 'shared-repo' ); - } - - function getSlaveDB() { - return wfGetDB( DB_SLAVE ); + return wfMsg( 'shared-repo' ); } - function getMasterDB() { - return wfGetDB( DB_MASTER ); + /** + * Get a key on the primary cache for this repository. + * Returns false if the repository's cache is not accessible at this site. + * The parameters are the parts of the key, as for wfMemcKey(). + * + * STUB + */ + function getSharedCacheKey( /*...*/ ) { + return false; } - - function getMemcKey( $key ) { - return wfWikiID( $this->getSlaveDB() ) . ":{$key}"; + + /** + * Get a key for this repo in the local cache domain. These cache keys are + * not shared with remote instances of the repo. + * The parameters are the parts of the key, as for wfMemcKey(). + */ + function getLocalCacheKey( /*...*/ ) { + $args = func_get_args(); + array_unshift( $args, 'filerepo', $this->getName() ); + return call_user_func_array( 'wfMemcKey', $args ); } } |