summaryrefslogtreecommitdiff
path: root/includes/filerepo/FileRepo.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/filerepo/FileRepo.php')
-rw-r--r--includes/filerepo/FileRepo.php175
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 );
}
}