From: Reedy Date: Sun, 14 Apr 2019 02:35:00 +0000 (+0100) Subject: Split filebackend files to class per file X-Git-Tag: 1.34.0-rc.0~1980^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=7f04a47d68462be2c8418e2ae4d9b4eaa8991518 Split filebackend files to class per file Change-Id: Idf9f4177fb9a523ce41227bda2af923bf418396b --- diff --git a/.phpcs.xml b/.phpcs.xml index b4503a631d..228c650680 100644 --- a/.phpcs.xml +++ b/.phpcs.xml @@ -194,9 +194,6 @@ --> */includes/api/ApiErrorFormatter\.php */includes/diff/DairikiDiff\.php - */includes/libs/filebackend/FileBackendStore\.php - */includes/libs/filebackend/FSFileBackend\.php - */includes/libs/filebackend/SwiftFileBackend\.php */includes/parser/Preprocessor_DOM\.php */includes/parser/Preprocessor_Hash\.php */includes/parser/Preprocessor\.php diff --git a/autoload.php b/autoload.php index fe5e7cfa33..9b8ec043d4 100644 --- a/autoload.php +++ b/autoload.php @@ -487,10 +487,10 @@ $wgAutoloadLocalClasses = [ 'ExternalUserNames' => __DIR__ . '/includes/user/ExternalUserNames.php', 'FSFile' => __DIR__ . '/includes/libs/filebackend/fsfile/FSFile.php', 'FSFileBackend' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php', - 'FSFileBackendDirList' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php', - 'FSFileBackendFileList' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php', - 'FSFileBackendList' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php', - 'FSFileOpHandle' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php', + 'FSFileBackendDirList' => __DIR__ . '/includes/libs/filebackend/FSFileBackendDirList.php', + 'FSFileBackendFileList' => __DIR__ . '/includes/libs/filebackend/FSFileBackendFileList.php', + 'FSFileBackendList' => __DIR__ . '/includes/libs/filebackend/FSFileBackendList.php', + 'FSFileOpHandle' => __DIR__ . '/includes/libs/filebackend/FSFileOpHandle.php', 'FSLockManager' => __DIR__ . '/includes/libs/lockmanager/FSLockManager.php', 'FakeConverter' => __DIR__ . '/languages/FakeConverter.php', 'FakeMaintenance' => __DIR__ . '/maintenance/Maintenance.php', @@ -511,10 +511,10 @@ $wgAutoloadLocalClasses = [ 'FileBackendGroup' => __DIR__ . '/includes/filebackend/FileBackendGroup.php', 'FileBackendMultiWrite' => __DIR__ . '/includes/libs/filebackend/FileBackendMultiWrite.php', 'FileBackendStore' => __DIR__ . '/includes/libs/filebackend/FileBackendStore.php', - 'FileBackendStoreOpHandle' => __DIR__ . '/includes/libs/filebackend/FileBackendStore.php', - 'FileBackendStoreShardDirIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStore.php', - 'FileBackendStoreShardFileIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStore.php', - 'FileBackendStoreShardListIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStore.php', + 'FileBackendStoreOpHandle' => __DIR__ . '/includes/libs/filebackend/FileBackendStoreOpHandle.php', + 'FileBackendStoreShardDirIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStoreShardDirIterator.php', + 'FileBackendStoreShardFileIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStoreShardFileIterator.php', + 'FileBackendStoreShardListIterator' => __DIR__ . '/includes/libs/filebackend/FileBackendStoreShardListIterator.php', 'FileBasedSiteLookup' => __DIR__ . '/includes/site/FileBasedSiteLookup.php', 'FileCacheBase' => __DIR__ . '/includes/cache/FileCacheBase.php', 'FileContentHandler' => __DIR__ . '/includes/content/FileContentHandler.php', @@ -1455,10 +1455,10 @@ $wgAutoloadLocalClasses = [ 'SubpageImportTitleFactory' => __DIR__ . '/includes/title/SubpageImportTitleFactory.php', 'SvgHandler' => __DIR__ . '/includes/media/SvgHandler.php', 'SwiftFileBackend' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackend.php', - 'SwiftFileBackendDirList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackend.php', - 'SwiftFileBackendFileList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackend.php', - 'SwiftFileBackendList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackend.php', - 'SwiftFileOpHandle' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackend.php', + 'SwiftFileBackendDirList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackendDirList.php', + 'SwiftFileBackendFileList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackendFileList.php', + 'SwiftFileBackendList' => __DIR__ . '/includes/libs/filebackend/SwiftFileBackendList.php', + 'SwiftFileOpHandle' => __DIR__ . '/includes/libs/filebackend/SwiftFileOpHandle.php', 'SwiftVirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/SwiftVirtualRESTService.php', 'SyncFileBackend' => __DIR__ . '/maintenance/syncFileBackend.php', 'TableCleanup' => __DIR__ . '/maintenance/cleanupTable.inc', diff --git a/includes/libs/filebackend/FSFileBackend.php b/includes/libs/filebackend/FSFileBackend.php index b8aa951fd5..593e617fe6 100644 --- a/includes/libs/filebackend/FSFileBackend.php +++ b/includes/libs/filebackend/FSFileBackend.php @@ -1,4 +1,24 @@ backend = $backend; - $this->params = $params; - $this->call = $call; - $this->cmd = $cmd; - $this->chmodPath = $chmodPath; - } -} - -/** - * Wrapper around RecursiveDirectoryIterator/DirectoryIterator that - * catches exception or does any custom behavoir that we may want. - * Do not use this class from places outside FSFileBackend. - * - * @ingroup FileBackend - */ -abstract class FSFileBackendList implements Iterator { - /** @var Iterator */ - protected $iter; - - /** @var int */ - protected $suffixStart; - - /** @var int */ - protected $pos = 0; - - /** @var array */ - protected $params = []; - - /** - * @param string $dir File system directory - * @param array $params - */ - public function __construct( $dir, array $params ) { - $path = realpath( $dir ); // normalize - if ( $path === false ) { - $path = $dir; - } - $this->suffixStart = strlen( $path ) + 1; // size of "path/to/dir/" - $this->params = $params; - - try { - $this->iter = $this->initIterator( $path ); - } catch ( UnexpectedValueException $e ) { - $this->iter = null; // bad permissions? deleted? - } - } - - /** - * Return an appropriate iterator object to wrap - * - * @param string $dir File system directory - * @return Iterator - */ - protected function initIterator( $dir ) { - if ( !empty( $this->params['topOnly'] ) ) { // non-recursive - # Get an iterator that will get direct sub-nodes - return new DirectoryIterator( $dir ); - } else { // recursive - # Get an iterator that will return leaf nodes (non-directories) - # RecursiveDirectoryIterator extends FilesystemIterator. - # FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x. - $flags = FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::SKIP_DOTS; - - return new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( $dir, $flags ), - RecursiveIteratorIterator::CHILD_FIRST // include dirs - ); - } - } - - /** - * @see Iterator::key() - * @return int - */ - public function key() { - return $this->pos; - } - - /** - * @see Iterator::current() - * @return string|bool String or false - */ - public function current() { - return $this->getRelPath( $this->iter->current()->getPathname() ); - } - - /** - * @see Iterator::next() - * @throws FileBackendError - */ - public function next() { - try { - $this->iter->next(); - $this->filterViaNext(); - } catch ( UnexpectedValueException $e ) { // bad permissions? deleted? - throw new FileBackendError( "File iterator gave UnexpectedValueException." ); - } - ++$this->pos; - } - - /** - * @see Iterator::rewind() - * @throws FileBackendError - */ - public function rewind() { - $this->pos = 0; - try { - $this->iter->rewind(); - $this->filterViaNext(); - } catch ( UnexpectedValueException $e ) { // bad permissions? deleted? - throw new FileBackendError( "File iterator gave UnexpectedValueException." ); - } - } - - /** - * @see Iterator::valid() - * @return bool - */ - public function valid() { - return $this->iter && $this->iter->valid(); - } - - /** - * Filter out items by advancing to the next ones - */ - protected function filterViaNext() { - } - - /** - * Return only the relative path and normalize slashes to FileBackend-style. - * Uses the "real path" since the suffix is based upon that. - * - * @param string $dir - * @return string - */ - protected function getRelPath( $dir ) { - $path = realpath( $dir ); - if ( $path === false ) { - $path = $dir; - } - - return strtr( substr( $path, $this->suffixStart ), '\\', '/' ); - } -} - -class FSFileBackendDirList extends FSFileBackendList { - protected function filterViaNext() { - while ( $this->iter->valid() ) { - if ( $this->iter->current()->isDot() || !$this->iter->current()->isDir() ) { - $this->iter->next(); // skip non-directories and dot files - } else { - break; - } - } - } -} - -class FSFileBackendFileList extends FSFileBackendList { - protected function filterViaNext() { - while ( $this->iter->valid() ) { - if ( !$this->iter->current()->isFile() ) { - $this->iter->next(); // skip non-files and dot files - } else { - break; - } - } - } -} diff --git a/includes/libs/filebackend/FSFileBackendDirList.php b/includes/libs/filebackend/FSFileBackendDirList.php new file mode 100644 index 0000000000..0545d9ff25 --- /dev/null +++ b/includes/libs/filebackend/FSFileBackendDirList.php @@ -0,0 +1,32 @@ +iter->valid() ) { + if ( $this->iter->current()->isDot() || !$this->iter->current()->isDir() ) { + $this->iter->next(); // skip non-directories and dot files + } else { + break; + } + } + } +} diff --git a/includes/libs/filebackend/FSFileBackendFileList.php b/includes/libs/filebackend/FSFileBackendFileList.php new file mode 100644 index 0000000000..980e9999f9 --- /dev/null +++ b/includes/libs/filebackend/FSFileBackendFileList.php @@ -0,0 +1,32 @@ +iter->valid() ) { + if ( !$this->iter->current()->isFile() ) { + $this->iter->next(); // skip non-files and dot files + } else { + break; + } + } + } +} diff --git a/includes/libs/filebackend/FSFileBackendList.php b/includes/libs/filebackend/FSFileBackendList.php new file mode 100644 index 0000000000..9194efe131 --- /dev/null +++ b/includes/libs/filebackend/FSFileBackendList.php @@ -0,0 +1,157 @@ +suffixStart = strlen( $path ) + 1; // size of "path/to/dir/" + $this->params = $params; + + try { + $this->iter = $this->initIterator( $path ); + } catch ( UnexpectedValueException $e ) { + $this->iter = null; // bad permissions? deleted? + } + } + + /** + * Return an appropriate iterator object to wrap + * + * @param string $dir File system directory + * @return Iterator + */ + protected function initIterator( $dir ) { + if ( !empty( $this->params['topOnly'] ) ) { // non-recursive + # Get an iterator that will get direct sub-nodes + return new DirectoryIterator( $dir ); + } else { // recursive + # Get an iterator that will return leaf nodes (non-directories) + # RecursiveDirectoryIterator extends FilesystemIterator. + # FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x. + $flags = FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::SKIP_DOTS; + + return new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( $dir, $flags ), + RecursiveIteratorIterator::CHILD_FIRST // include dirs + ); + } + } + + /** + * @see Iterator::key() + * @return int + */ + public function key() { + return $this->pos; + } + + /** + * @see Iterator::current() + * @return string|bool String or false + */ + public function current() { + return $this->getRelPath( $this->iter->current()->getPathname() ); + } + + /** + * @see Iterator::next() + * @throws FileBackendError + */ + public function next() { + try { + $this->iter->next(); + $this->filterViaNext(); + } catch ( UnexpectedValueException $e ) { // bad permissions? deleted? + throw new FileBackendError( "File iterator gave UnexpectedValueException." ); + } + ++$this->pos; + } + + /** + * @see Iterator::rewind() + * @throws FileBackendError + */ + public function rewind() { + $this->pos = 0; + try { + $this->iter->rewind(); + $this->filterViaNext(); + } catch ( UnexpectedValueException $e ) { // bad permissions? deleted? + throw new FileBackendError( "File iterator gave UnexpectedValueException." ); + } + } + + /** + * @see Iterator::valid() + * @return bool + */ + public function valid() { + return $this->iter && $this->iter->valid(); + } + + /** + * Filter out items by advancing to the next ones + */ + protected function filterViaNext() { + } + + /** + * Return only the relative path and normalize slashes to FileBackend-style. + * Uses the "real path" since the suffix is based upon that. + * + * @param string $dir + * @return string + */ + protected function getRelPath( $dir ) { + $path = realpath( $dir ); + if ( $path === false ) { + $path = $dir; + } + + return strtr( substr( $path, $this->suffixStart ), '\\', '/' ); + } +} diff --git a/includes/libs/filebackend/FSFileOpHandle.php b/includes/libs/filebackend/FSFileOpHandle.php new file mode 100644 index 0000000000..2d65c434a1 --- /dev/null +++ b/includes/libs/filebackend/FSFileOpHandle.php @@ -0,0 +1,45 @@ +backend = $backend; + $this->params = $params; + $this->call = $call; + $this->cmd = $cmd; + $this->chmodPath = $chmodPath; + } +} diff --git a/includes/libs/filebackend/FileBackendStore.php b/includes/libs/filebackend/FileBackendStore.php index 97da5572fd..3663637747 100644 --- a/includes/libs/filebackend/FileBackendStore.php +++ b/includes/libs/filebackend/FileBackendStore.php @@ -1866,133 +1866,3 @@ abstract class FileBackendStore extends FileBackend { 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; - } - } -} diff --git a/includes/libs/filebackend/FileBackendStoreOpHandle.php b/includes/libs/filebackend/FileBackendStoreOpHandle.php new file mode 100644 index 0000000000..c366a0fff7 --- /dev/null +++ b/includes/libs/filebackend/FileBackendStoreOpHandle.php @@ -0,0 +1,46 @@ +resourcesToClose ); + } +} diff --git a/includes/libs/filebackend/FileBackendStoreShardDirIterator.php b/includes/libs/filebackend/FileBackendStoreShardDirIterator.php new file mode 100644 index 0000000000..cd8ebff06c --- /dev/null +++ b/includes/libs/filebackend/FileBackendStoreShardDirIterator.php @@ -0,0 +1,35 @@ +backend->getDirectoryListInternal( + $container, $this->directory, $this->params ); + if ( $list === null ) { + return new ArrayIterator( [] ); + } else { + return is_array( $list ) ? new ArrayIterator( $list ) : $list; + } + } +} diff --git a/includes/libs/filebackend/FileBackendStoreShardFileIterator.php b/includes/libs/filebackend/FileBackendStoreShardFileIterator.php new file mode 100644 index 0000000000..d65a5d71a0 --- /dev/null +++ b/includes/libs/filebackend/FileBackendStoreShardFileIterator.php @@ -0,0 +1,35 @@ +backend->getFileListInternal( + $container, $this->directory, $this->params ); + if ( $list === null ) { + return new ArrayIterator( [] ); + } else { + return is_array( $list ) ? new ArrayIterator( $list ) : $list; + } + } +} diff --git a/includes/libs/filebackend/FileBackendStoreShardListIterator.php b/includes/libs/filebackend/FileBackendStoreShardListIterator.php new file mode 100644 index 0000000000..5f6b762426 --- /dev/null +++ b/includes/libs/filebackend/FileBackendStoreShardListIterator.php @@ -0,0 +1,94 @@ + 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 ); +} diff --git a/includes/libs/filebackend/SwiftFileBackend.php b/includes/libs/filebackend/SwiftFileBackend.php index 61b4d69c58..4ba1e1c4ee 100644 --- a/includes/libs/filebackend/SwiftFileBackend.php +++ b/includes/libs/filebackend/SwiftFileBackend.php @@ -1803,180 +1803,3 @@ class SwiftFileBackend extends FileBackendStore { $this->logger->error( $msg, $msgParams ); } } - -/** - * @see FileBackendStoreOpHandle - */ -class SwiftFileOpHandle extends FileBackendStoreOpHandle { - /** @var array List of Requests for MultiHttpClient */ - public $httpOp; - /** @var Closure */ - public $callback; - - /** - * @param SwiftFileBackend $backend - * @param Closure $callback Function that takes (HTTP request array, status) - * @param array $httpOp MultiHttpClient op - */ - public function __construct( SwiftFileBackend $backend, Closure $callback, array $httpOp ) { - $this->backend = $backend; - $this->callback = $callback; - $this->httpOp = $httpOp; - } -} - -/** - * SwiftFileBackend helper class to page through listings. - * Swift also has a listing limit of 10,000 objects for sanity. - * Do not use this class from places outside SwiftFileBackend. - * - * @ingroup FileBackend - */ -abstract class SwiftFileBackendList implements Iterator { - /** @var array List of path or (path,stat array) entries */ - protected $bufferIter = []; - - /** @var string List items *after* this path */ - protected $bufferAfter = null; - - /** @var int */ - protected $pos = 0; - - /** @var array */ - protected $params = []; - - /** @var SwiftFileBackend */ - protected $backend; - - /** @var string Container name */ - protected $container; - - /** @var string Storage directory */ - protected $dir; - - /** @var int */ - protected $suffixStart; - - const PAGE_SIZE = 9000; // file listing buffer size - - /** - * @param SwiftFileBackend $backend - * @param string $fullCont Resolved container name - * @param string $dir Resolved directory relative to container - * @param array $params - */ - public function __construct( SwiftFileBackend $backend, $fullCont, $dir, array $params ) { - $this->backend = $backend; - $this->container = $fullCont; - $this->dir = $dir; - if ( substr( $this->dir, -1 ) === '/' ) { - $this->dir = substr( $this->dir, 0, -1 ); // remove trailing slash - } - if ( $this->dir == '' ) { // whole container - $this->suffixStart = 0; - } else { // dir within container - $this->suffixStart = strlen( $this->dir ) + 1; // size of "path/to/dir/" - } - $this->params = $params; - } - - /** - * @see Iterator::key() - * @return int - */ - public function key() { - return $this->pos; - } - - /** - * @see Iterator::next() - */ - public function next() { - // Advance to the next file in the page - next( $this->bufferIter ); - ++$this->pos; - // Check if there are no files left in this page and - // advance to the next page if this page was not empty. - if ( !$this->valid() && count( $this->bufferIter ) ) { - $this->bufferIter = $this->pageFromList( - $this->container, $this->dir, $this->bufferAfter, self::PAGE_SIZE, $this->params - ); // updates $this->bufferAfter - } - } - - /** - * @see Iterator::rewind() - */ - public function rewind() { - $this->pos = 0; - $this->bufferAfter = null; - $this->bufferIter = $this->pageFromList( - $this->container, $this->dir, $this->bufferAfter, self::PAGE_SIZE, $this->params - ); // updates $this->bufferAfter - } - - /** - * @see Iterator::valid() - * @return bool - */ - public function valid() { - if ( $this->bufferIter === null ) { - return false; // some failure? - } else { - return ( current( $this->bufferIter ) !== false ); // no paths can have this value - } - } - - /** - * Get the given list portion (page) - * - * @param string $container Resolved container name - * @param string $dir Resolved path relative to container - * @param string &$after - * @param int $limit - * @param array $params - * @return Traversable|array - */ - abstract protected function pageFromList( $container, $dir, &$after, $limit, array $params ); -} - -/** - * Iterator for listing directories - */ -class SwiftFileBackendDirList extends SwiftFileBackendList { - /** - * @see Iterator::current() - * @return string|bool String (relative path) or false - */ - public function current() { - return substr( current( $this->bufferIter ), $this->suffixStart, -1 ); - } - - protected function pageFromList( $container, $dir, &$after, $limit, array $params ) { - return $this->backend->getDirListPageInternal( $container, $dir, $after, $limit, $params ); - } -} - -/** - * Iterator for listing regular files - */ -class SwiftFileBackendFileList extends SwiftFileBackendList { - /** - * @see Iterator::current() - * @return string|bool String (relative path) or false - */ - public function current() { - list( $path, $stat ) = current( $this->bufferIter ); - $relPath = substr( $path, $this->suffixStart ); - if ( is_array( $stat ) ) { - $storageDir = rtrim( $this->params['dir'], '/' ); - $this->backend->loadListingStatInternal( "$storageDir/$relPath", $stat ); - } - - return $relPath; - } - - protected function pageFromList( $container, $dir, &$after, $limit, array $params ) { - return $this->backend->getFileListPageInternal( $container, $dir, $after, $limit, $params ); - } -} diff --git a/includes/libs/filebackend/SwiftFileBackendDirList.php b/includes/libs/filebackend/SwiftFileBackendDirList.php new file mode 100644 index 0000000000..b0b784d389 --- /dev/null +++ b/includes/libs/filebackend/SwiftFileBackendDirList.php @@ -0,0 +1,40 @@ +bufferIter ), $this->suffixStart, -1 ); + } + + protected function pageFromList( $container, $dir, &$after, $limit, array $params ) { + return $this->backend->getDirListPageInternal( $container, $dir, $after, $limit, $params ); + } +} diff --git a/includes/libs/filebackend/SwiftFileBackendFileList.php b/includes/libs/filebackend/SwiftFileBackendFileList.php new file mode 100644 index 0000000000..045b8f878c --- /dev/null +++ b/includes/libs/filebackend/SwiftFileBackendFileList.php @@ -0,0 +1,47 @@ +bufferIter ); + $relPath = substr( $path, $this->suffixStart ); + if ( is_array( $stat ) ) { + $storageDir = rtrim( $this->params['dir'], '/' ); + $this->backend->loadListingStatInternal( "$storageDir/$relPath", $stat ); + } + + return $relPath; + } + + protected function pageFromList( $container, $dir, &$after, $limit, array $params ) { + return $this->backend->getFileListPageInternal( $container, $dir, $after, $limit, $params ); + } +} diff --git a/includes/libs/filebackend/SwiftFileBackendList.php b/includes/libs/filebackend/SwiftFileBackendList.php new file mode 100644 index 0000000000..bcde8d90a9 --- /dev/null +++ b/includes/libs/filebackend/SwiftFileBackendList.php @@ -0,0 +1,138 @@ +backend = $backend; + $this->container = $fullCont; + $this->dir = $dir; + if ( substr( $this->dir, -1 ) === '/' ) { + $this->dir = substr( $this->dir, 0, -1 ); // remove trailing slash + } + if ( $this->dir == '' ) { // whole container + $this->suffixStart = 0; + } else { // dir within container + $this->suffixStart = strlen( $this->dir ) + 1; // size of "path/to/dir/" + } + $this->params = $params; + } + + /** + * @see Iterator::key() + * @return int + */ + public function key() { + return $this->pos; + } + + /** + * @see Iterator::next() + */ + public function next() { + // Advance to the next file in the page + next( $this->bufferIter ); + ++$this->pos; + // Check if there are no files left in this page and + // advance to the next page if this page was not empty. + if ( !$this->valid() && count( $this->bufferIter ) ) { + $this->bufferIter = $this->pageFromList( + $this->container, $this->dir, $this->bufferAfter, self::PAGE_SIZE, $this->params + ); // updates $this->bufferAfter + } + } + + /** + * @see Iterator::rewind() + */ + public function rewind() { + $this->pos = 0; + $this->bufferAfter = null; + $this->bufferIter = $this->pageFromList( + $this->container, $this->dir, $this->bufferAfter, self::PAGE_SIZE, $this->params + ); // updates $this->bufferAfter + } + + /** + * @see Iterator::valid() + * @return bool + */ + public function valid() { + if ( $this->bufferIter === null ) { + return false; // some failure? + } else { + return ( current( $this->bufferIter ) !== false ); // no paths can have this value + } + } + + /** + * Get the given list portion (page) + * + * @param string $container Resolved container name + * @param string $dir Resolved path relative to container + * @param string &$after + * @param int $limit + * @param array $params + * @return Traversable|array + */ + abstract protected function pageFromList( $container, $dir, &$after, $limit, array $params ); +} diff --git a/includes/libs/filebackend/SwiftFileOpHandle.php b/includes/libs/filebackend/SwiftFileOpHandle.php new file mode 100644 index 0000000000..1119867800 --- /dev/null +++ b/includes/libs/filebackend/SwiftFileOpHandle.php @@ -0,0 +1,44 @@ +backend = $backend; + $this->callback = $callback; + $this->httpOp = $httpOp; + } +}