var $oldFileFactory = false;
var $fileFactoryKey = false, $oldFileFactoryKey = false;
- function __construct( array $info = null ) {
+ /**
+ * @param $info array|null
+ * @throws MWException
+ */
+ public function __construct( array $info = null ) {
// Verify required settings presence
if(
$info === null
: array();
// Give defaults for the basic zones...
foreach ( array( 'public', 'thumb', 'temp', 'deleted' ) as $zone ) {
- if ( !isset( $this->zones[$zone] ) ) {
- $this->zones[$zone] = array(
- 'container' => "{$this->name}-{$zone}",
- 'directory' => '' // container root
- );
+ if ( !isset( $this->zones[$zone]['container'] ) ) {
+ $this->zones[$zone]['container'] = "{$this->name}-{$zone}";
+ }
+ if ( !isset( $this->zones[$zone]['directory'] ) ) {
+ $this->zones[$zone]['directory'] = '';
}
}
}
* Check if a single zone or list of zones is defined for usage
*
* @param $doZones Array Only do a particular zones
+ * @throws MWException
* @return Status
*/
protected function initZones( $doZones = array() ) {
return $status;
}
- /**
- * Take all available measures to prevent web accessibility of new deleted
- * directories, in case the user has not configured offline storage
- *
- * @param $dir string
- * @return void
- */
- protected function initDeletedDir( $dir ) {
- $this->backend->secure( // prevent web access & dir listings
- array( 'dir' => $dir, 'noAccess' => true, 'noListing' => true ) );
- }
-
/**
* Determine if a string is an mwrepo:// URL
*
* The suffix, if supplied, is considered to be unencoded, and will be
* URL-encoded before being returned.
*
- * @param $suffix string
+ * @param $suffix string|bool
* @return string
*/
public function getVirtualUrl( $suffix = false ) {
* @return String or false
*/
public function getZoneUrl( $zone ) {
+ if ( isset( $this->zones[$zone]['url'] )
+ && in_array( $zone, array( 'public', 'temp', 'thumb' ) ) )
+ {
+ return $this->zones[$zone]['url']; // custom URL
+ }
switch ( $zone ) {
case 'public':
return $this->url;
* Use this function wisely.
*
* @param $url string
+ * @throws MWException
* @return string
*/
public function resolveVirtualUrl( $url ) {
* SHA-1 content hash.
*
* STUB
+ * @param $hash
* @return array
*/
public function findBySha1( $hash ) {
return array();
}
+ /**
+ * Get an array of arrays or iterators of file objects for files that
+ * have the given SHA-1 content hashes.
+ *
+ * @param $hashes array An array of hashes
+ * @return array An Array of arrays or iterators of file objects and the hash as key
+ */
+ public function findBySha1s( array $hashes ) {
+ $result = array();
+ foreach ( $hashes as $hash ) {
+ $files = $this->findBySha1( $hash );
+ if ( count( $files ) ) {
+ $result[$hash] = $files;
+ }
+ }
+ return $result;
+ }
+
/**
* Get the public root URL of the repository
*
+ * @deprecated since 1.20
* @return string
*/
public function getRootUrl() {
- return $this->url;
+ return $this->getZoneUrl( 'public' );
}
/**
* self::OVERWRITE_SAME Overwrite the file if the destination exists and has the
* same contents as the source
* self::SKIP_LOCKING Skip any file locking when doing the store
+ * @throws MWException
* @return FileRepoStatus
*/
public function storeBatch( array $triplets, $flags = 0 ) {
$dstPath = "$root/$dstRel";
$dstDir = dirname( $dstPath );
// Create destination directories for this triplet
- if ( !$backend->prepare( array( 'dir' => $dstDir ) )->isOK() ) {
+ if ( !$this->initDirectory( $dstDir )->isOK() ) {
return $this->newFatal( 'directorycreateerror', $dstDir );
}
- if ( $dstZone == 'deleted' ) {
- $this->initDeletedDir( $dstDir );
- }
-
// Resolve source to a storage path if virtual
$srcPath = $this->resolveToStoragePath( $srcPath );
* Each file can be a (zone, rel) pair, virtual url, storage path.
* It will try to delete each file, but ignores any errors that may occur.
*
- * @param $pairs array List of files to delete
+ * @param $files array List of files to delete
* @param $flags Integer: bitwise combination of the following flags:
* self::SKIP_LOCKING Skip any file locking when doing the deletions
* @return FileRepoStatus
* This function can be used to write to otherwise read-only foreign repos.
* This is intended for copying generated thumbnails into the repo.
*
- * @param $src Array List of tuples (file system path, virtual URL or storage path)
+ * @param $pairs Array List of tuples (file system path, virtual URL or storage path)
* @return FileRepoStatus
*/
public function quickImportBatch( array $pairs ) {
$operations = array();
foreach ( $pairs as $pair ) {
list ( $src, $dst ) = $pair;
+ $dst = $this->resolveToStoragePath( $dst );
$operations[] = array(
'op' => 'store',
'src' => $src,
- 'dst' => $this->resolveToStoragePath( $dst ),
- 'overwrite' => true
+ 'dst' => $dst
);
- $this->backend->prepare( array( 'dir' => dirname( $dst ) ) );
+ $status->merge( $this->initDirectory( dirname( $dst ) ) );
}
- $status->merge( $this->backend->doOperations( $operations,
- array( 'force' => 1, 'nonLocking' => 1, 'allowStale' => 1, 'nonJournaled' => 1 )
- ) );
+ $status->merge( $this->backend->doQuickOperations( $operations ) );
return $status;
}
* This function can be used to write to otherwise read-only foreign repos.
* This does no locking nor journaling and is intended for purging thumbnails.
*
- * @param $path Array List of virtual URLs or storage paths
+ * @param $paths Array List of virtual URLs or storage paths
* @return FileRepoStatus
*/
public function quickPurgeBatch( array $paths ) {
'ignoreMissingSource' => true
);
}
- $status->merge( $this->backend->doOperations( $operations,
- array( 'force' => 1, 'nonLocking' => 1, 'allowStale' => 1, 'nonJournaled' => 1 )
- ) );
+ $status->merge( $this->backend->doQuickOperations( $operations ) );
return $status;
}
* @param $triplets Array: (source, dest, archive) triplets as per publish()
* @param $flags Integer: bitfield, may be FileRepo::DELETE_SOURCE to indicate
* that the source files should be deleted if possible
+ * @throws MWException
* @return FileRepoStatus
*/
public function publishBatch( array $triplets, $flags = 0 ) {
$dstDir = dirname( $dstPath );
$archiveDir = dirname( $archivePath );
// Abort immediately on directory creation errors since they're likely to be repetitive
- if ( !$backend->prepare( array( 'dir' => $dstDir ) )->isOK() ) {
+ if ( !$this->initDirectory( $dstDir )->isOK() ) {
return $this->newFatal( 'directorycreateerror', $dstDir );
}
- if ( !$backend->prepare( array( 'dir' => $archiveDir ) )->isOK() ) {
+ if ( !$this->initDirectory($archiveDir )->isOK() ) {
return $this->newFatal( 'directorycreateerror', $archiveDir );
}
return $status;
}
+ /**
+ * Creates a directory with the appropriate zone permissions.
+ * Callers are responsible for doing read-only and "writable repo" checks.
+ *
+ * @param $dir string Virtual URL (or storage path) of directory to clean
+ * @return Status
+ */
+ protected function initDirectory( $dir ) {
+ $path = $this->resolveToStoragePath( $dir );
+ list( $b, $container, $r ) = FileBackend::splitStoragePath( $path );
+
+ $params = array( 'dir' => $path );
+ if ( $container === $this->zones['deleted']['container'] ) {
+ # Take all available measures to prevent web accessibility of new deleted
+ # directories, in case the user has not configured offline storage
+ $params = array( 'noAccess' => true, 'noListing' => true ) + $params;
+ }
+
+ return $this->backend->prepare( $params );
+ }
+
/**
* Deletes a directory if empty.
*
* is a two-element array containing the source file path relative to the
* public root in the first element, and the archive file path relative
* to the deleted zone root in the second element.
+ * @throws MWException
* @return FileRepoStatus
*/
public function deleteBatch( array $sourceDestPairs ) {
$archiveDir = dirname( $archivePath ); // does not touch FS
// Create destination directories
- if ( !$backend->prepare( array( 'dir' => $archiveDir ) )->isOK() ) {
+ if ( !$this->initDirectory( $archiveDir )->isOK() ) {
return $this->newFatal( 'directorycreateerror', $archiveDir );
}
- $this->initDeletedDir( $archiveDir );
$operations[] = array(
'op' => 'move',
* Get a relative path for a deletion archive key,
* e.g. s/z/a/ for sza251lrxrc1jad41h5mgilp8nysje52.jpg
*
+ * @param $key string
* @return string
*/
public function getDeletedHashPath( $key ) {
/**
* Create a new good result
*
+ * @param $value null|string
* @return FileRepoStatus
*/
public function newGood( $value = null ) {