return $mime ?: 'unknown/unknown';
}
}
-
-/**
- * FileBackendStore helper class for performing asynchronous file operations.
- *
- * For example, calling FileBackendStore::createInternal() with the "async"
- * param flag may result in a StatusValue that contains this object as a value.
- * This class is largely backend-specific and is mostly just "magic" to be
- * passed to FileBackendStore::executeOpHandlesInternal().
- */
-abstract class FileBackendStoreOpHandle {
- /** @var array */
- public $params = []; // params to caller functions
- /** @var FileBackendStore */
- public $backend;
- /** @var array */
- public $resourcesToClose = [];
-
- public $call; // string; name that identifies the function called
-
- /**
- * Close all open file handles
- */
- public function closeResources() {
- array_map( 'fclose', $this->resourcesToClose );
- }
-}
-
-/**
- * FileBackendStore helper function to handle listings that span container shards.
- * Do not use this class from places outside of FileBackendStore.
- *
- * @ingroup FileBackend
- */
-abstract class FileBackendStoreShardListIterator extends FilterIterator {
- /** @var FileBackendStore */
- protected $backend;
-
- /** @var array */
- protected $params;
-
- /** @var string Full container name */
- protected $container;
-
- /** @var string Resolved relative path */
- protected $directory;
-
- /** @var array */
- protected $multiShardPaths = []; // (rel path => 1)
-
- /**
- * @param FileBackendStore $backend
- * @param string $container Full storage container name
- * @param string $dir Storage directory relative to container
- * @param array $suffixes List of container shard suffixes
- * @param array $params
- */
- public function __construct(
- FileBackendStore $backend, $container, $dir, array $suffixes, array $params
- ) {
- $this->backend = $backend;
- $this->container = $container;
- $this->directory = $dir;
- $this->params = $params;
-
- $iter = new AppendIterator();
- foreach ( $suffixes as $suffix ) {
- $iter->append( $this->listFromShard( $this->container . $suffix ) );
- }
-
- parent::__construct( $iter );
- }
-
- public function accept() {
- $rel = $this->getInnerIterator()->current(); // path relative to given directory
- $path = $this->params['dir'] . "/{$rel}"; // full storage path
- if ( $this->backend->isSingleShardPathInternal( $path ) ) {
- return true; // path is only on one shard; no issue with duplicates
- } elseif ( isset( $this->multiShardPaths[$rel] ) ) {
- // Don't keep listing paths that are on multiple shards
- return false;
- } else {
- $this->multiShardPaths[$rel] = 1;
-
- return true;
- }
- }
-
- public function rewind() {
- parent::rewind();
- $this->multiShardPaths = [];
- }
-
- /**
- * Get the list for a given container shard
- *
- * @param string $container Resolved container name
- * @return Iterator
- */
- abstract protected function listFromShard( $container );
-}
-
-/**
- * Iterator for listing directories
- */
-class FileBackendStoreShardDirIterator extends FileBackendStoreShardListIterator {
- protected function listFromShard( $container ) {
- $list = $this->backend->getDirectoryListInternal(
- $container, $this->directory, $this->params );
- if ( $list === null ) {
- return new ArrayIterator( [] );
- } else {
- return is_array( $list ) ? new ArrayIterator( $list ) : $list;
- }
- }
-}
-
-/**
- * Iterator for listing regular files
- */
-class FileBackendStoreShardFileIterator extends FileBackendStoreShardListIterator {
- protected function listFromShard( $container ) {
- $list = $this->backend->getFileListInternal(
- $container, $this->directory, $this->params );
- if ( $list === null ) {
- return new ArrayIterator( [] );
- } else {
- return is_array( $list ) ? new ArrayIterator( $list ) : $list;
- }
- }
-}