diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
commit | c9aa36da061816dee256a979c2ff8d2ee41824d9 (patch) | |
tree | 29f7002b80ee984b488bd047dbbd80b36bf892e9 /includes/filebackend/FSFileBackend.php | |
parent | b4274e0e33eafb5e9ead9d949ebf031a9fb8363b (diff) | |
parent | d1ba966140d7a60cd5ae4e8667ceb27c1a138592 (diff) |
Merge branch 'archwiki'
# Conflicts:
# skins/ArchLinux.php
# skins/ArchLinux/archlogo.gif
Diffstat (limited to 'includes/filebackend/FSFileBackend.php')
-rw-r--r-- | includes/filebackend/FSFileBackend.php | 201 |
1 files changed, 121 insertions, 80 deletions
diff --git a/includes/filebackend/FSFileBackend.php b/includes/filebackend/FSFileBackend.php index 6d642162..b99ffb62 100644 --- a/includes/filebackend/FSFileBackend.php +++ b/includes/filebackend/FSFileBackend.php @@ -39,14 +39,22 @@ * @since 1.19 */ class FSFileBackend extends FileBackendStore { - protected $basePath; // string; directory holding the container directories - /** @var Array Map of container names to root paths */ - protected $containerPaths = array(); // for custom container paths - protected $fileMode; // integer; file permission mode - protected $fileOwner; // string; required OS username to own files - protected $currentUser; // string; OS username running this script - - /** @var Array */ + /** @var string Directory holding the container directories */ + protected $basePath; + + /** @var array Map of container names to root paths for custom container paths */ + protected $containerPaths = array(); + + /** @var int File permission mode */ + protected $fileMode; + + /** @var string Required OS username to own files */ + protected $fileOwner; + + /** @var string OS username running this script */ + protected $currentUser; + + /** @var array */ protected $hadWarningErrors = array(); /** @@ -82,6 +90,10 @@ class FSFileBackend extends FileBackendStore { } } + public function getFeatures() { + return !wfIsWindows() ? FileBackend::ATTR_UNICODE_PATHS : 0; + } + protected function resolveContainerPath( $container, $relStoragePath ) { // Check that container has a root directory if ( isset( $this->containerPaths[$container] ) || isset( $this->basePath ) ) { @@ -90,6 +102,7 @@ class FSFileBackend extends FileBackendStore { return $relStoragePath; } } + return null; } @@ -125,6 +138,7 @@ class FSFileBackend extends FileBackendStore { } elseif ( isset( $this->basePath ) ) { return "{$this->basePath}/{$fullCont}"; } + return null; // no container base path defined } @@ -144,6 +158,7 @@ class FSFileBackend extends FileBackendStore { if ( $relPath != '' ) { $fsPath .= "/{$relPath}"; } + return $fsPath; } @@ -174,6 +189,7 @@ class FSFileBackend extends FileBackendStore { $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); + return $status; } @@ -181,6 +197,7 @@ class FSFileBackend extends FileBackendStore { $tempFile = TempFSFile::factory( 'create_', 'tmp' ); if ( !$tempFile ) { $status->fatal( 'backend-fail-create', $params['dst'] ); + return $status; } $this->trapWarnings(); @@ -188,6 +205,7 @@ class FSFileBackend extends FileBackendStore { $this->untrapWarnings(); if ( $bytes === false ) { $status->fatal( 'backend-fail-create', $params['dst'] ); + return $status; } $cmd = implode( ' ', array( @@ -195,7 +213,13 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $tempFile->getPath() ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ) ); - $status->value = new FSFileOpHandle( $this, $params, 'Create', $cmd, $dest ); + $handler = function ( $errors, Status $status, array $params, $cmd ) { + if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { + $status->fatal( 'backend-fail-create', $params['dst'] ); + trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output + } + }; + $status->value = new FSFileOpHandle( $this, $params, $handler, $cmd, $dest ); $tempFile->bind( $status->value ); } else { // immediate write $this->trapWarnings(); @@ -203,6 +227,7 @@ class FSFileBackend extends FileBackendStore { $this->untrapWarnings(); if ( $bytes === false ) { $status->fatal( 'backend-fail-create', $params['dst'] ); + return $status; } $this->chmod( $dest ); @@ -211,22 +236,13 @@ class FSFileBackend extends FileBackendStore { return $status; } - /** - * @see FSFileBackend::doExecuteOpHandlesInternal() - */ - protected function _getResponseCreate( $errors, Status $status, array $params, $cmd ) { - if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { - $status->fatal( 'backend-fail-create', $params['dst'] ); - trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output - } - } - protected function doStoreInternal( array $params ) { $status = Status::newGood(); $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); + return $status; } @@ -236,7 +252,13 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $params['src'] ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ) ); - $status->value = new FSFileOpHandle( $this, $params, 'Store', $cmd, $dest ); + $handler = function ( $errors, Status $status, array $params, $cmd ) { + if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { + $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] ); + trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output + } + }; + $status->value = new FSFileOpHandle( $this, $params, $handler, $cmd, $dest ); } else { // immediate write $this->trapWarnings(); $ok = copy( $params['src'], $dest ); @@ -248,6 +270,7 @@ class FSFileBackend extends FileBackendStore { trigger_error( __METHOD__ . ": copy() failed but returned true." ); } $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] ); + return $status; } $this->chmod( $dest ); @@ -256,28 +279,20 @@ class FSFileBackend extends FileBackendStore { return $status; } - /** - * @see FSFileBackend::doExecuteOpHandlesInternal() - */ - protected function _getResponseStore( $errors, Status $status, array $params, $cmd ) { - if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { - $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] ); - trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output - } - } - protected function doCopyInternal( array $params ) { $status = Status::newGood(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { $status->fatal( 'backend-fail-invalidpath', $params['src'] ); + return $status; } $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); + return $status; } @@ -285,6 +300,7 @@ class FSFileBackend extends FileBackendStore { if ( empty( $params['ignoreMissingSource'] ) ) { $status->fatal( 'backend-fail-copy', $params['src'] ); } + return $status; // do nothing; either OK or bad status } @@ -294,7 +310,13 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $source ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ) ); - $status->value = new FSFileOpHandle( $this, $params, 'Copy', $cmd, $dest ); + $handler = function ( $errors, Status $status, array $params, $cmd ) { + if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { + $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] ); + trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output + } + }; + $status->value = new FSFileOpHandle( $this, $params, $handler, $cmd, $dest ); } else { // immediate write $this->trapWarnings(); $ok = ( $source === $dest ) ? true : copy( $source, $dest ); @@ -308,6 +330,7 @@ class FSFileBackend extends FileBackendStore { trigger_error( __METHOD__ . ": copy() failed but returned true." ); } $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] ); + return $status; } $this->chmod( $dest ); @@ -316,28 +339,20 @@ class FSFileBackend extends FileBackendStore { return $status; } - /** - * @see FSFileBackend::doExecuteOpHandlesInternal() - */ - protected function _getResponseCopy( $errors, Status $status, array $params, $cmd ) { - if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { - $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] ); - trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output - } - } - protected function doMoveInternal( array $params ) { $status = Status::newGood(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { $status->fatal( 'backend-fail-invalidpath', $params['src'] ); + return $status; } $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); + return $status; } @@ -345,6 +360,7 @@ class FSFileBackend extends FileBackendStore { if ( empty( $params['ignoreMissingSource'] ) ) { $status->fatal( 'backend-fail-move', $params['src'] ); } + return $status; // do nothing; either OK or bad status } @@ -354,7 +370,13 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $source ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ) ); - $status->value = new FSFileOpHandle( $this, $params, 'Move', $cmd ); + $handler = function ( $errors, Status $status, array $params, $cmd ) { + if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { + $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] ); + trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output + } + }; + $status->value = new FSFileOpHandle( $this, $params, $handler, $cmd ); } else { // immediate write $this->trapWarnings(); $ok = ( $source === $dest ) ? true : rename( $source, $dest ); @@ -362,6 +384,7 @@ class FSFileBackend extends FileBackendStore { clearstatcache(); // file no longer at source if ( !$ok ) { $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] ); + return $status; } } @@ -369,22 +392,13 @@ class FSFileBackend extends FileBackendStore { return $status; } - /** - * @see FSFileBackend::doExecuteOpHandlesInternal() - */ - protected function _getResponseMove( $errors, Status $status, array $params, $cmd ) { - if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { - $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] ); - trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output - } - } - protected function doDeleteInternal( array $params ) { $status = Status::newGood(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { $status->fatal( 'backend-fail-invalidpath', $params['src'] ); + return $status; } @@ -392,6 +406,7 @@ class FSFileBackend extends FileBackendStore { if ( empty( $params['ignoreMissingSource'] ) ) { $status->fatal( 'backend-fail-delete', $params['src'] ); } + return $status; // do nothing; either OK or bad status } @@ -400,13 +415,20 @@ class FSFileBackend extends FileBackendStore { wfIsWindows() ? 'DEL' : 'unlink', wfEscapeShellArg( $this->cleanPathSlashes( $source ) ) ) ); - $status->value = new FSFileOpHandle( $this, $params, 'Copy', $cmd ); + $handler = function ( $errors, Status $status, array $params, $cmd ) { + if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { + $status->fatal( 'backend-fail-delete', $params['src'] ); + trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output + } + }; + $status->value = new FSFileOpHandle( $this, $params, $handler, $cmd ); } else { // immediate write $this->trapWarnings(); $ok = unlink( $source ); $this->untrapWarnings(); if ( !$ok ) { $status->fatal( 'backend-fail-delete', $params['src'] ); + return $status; } } @@ -415,15 +437,11 @@ class FSFileBackend extends FileBackendStore { } /** - * @see FSFileBackend::doExecuteOpHandlesInternal() + * @param string $fullCont + * @param string $dirRel + * @param array $params + * @return Status */ - protected function _getResponseDelete( $errors, Status $status, array $params, $cmd ) { - if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { - $status->fatal( 'backend-fail-delete', $params['src'] ); - trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output - } - } - protected function doPrepareInternal( $fullCont, $dirRel, array $params ) { $status = Status::newGood(); list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); @@ -444,6 +462,7 @@ class FSFileBackend extends FileBackendStore { if ( is_dir( $dir ) && !$existed ) { $status->merge( $this->doSecureInternal( $fullCont, $dirRel, $params ) ); } + return $status; } @@ -471,6 +490,7 @@ class FSFileBackend extends FileBackendStore { $status->fatal( 'backend-fail-create', "{$storeDir}/.htaccess" ); } } + return $status; } @@ -498,6 +518,7 @@ class FSFileBackend extends FileBackendStore { } $this->untrapWarnings(); } + return $status; } @@ -511,6 +532,7 @@ class FSFileBackend extends FileBackendStore { rmdir( $dir ); // remove directory if empty } $this->untrapWarnings(); + return $status; } @@ -557,7 +579,10 @@ class FSFileBackend extends FileBackendStore { /** * @see FileBackendStore::getDirectoryListInternal() - * @return Array|null + * @param string $fullCont + * @param string $dirRel + * @param array $params + * @return array|null */ public function getDirectoryListInternal( $fullCont, $dirRel, array $params ) { list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); @@ -566,17 +591,23 @@ class FSFileBackend extends FileBackendStore { $exists = is_dir( $dir ); if ( !$exists ) { wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" ); + return array(); // nothing under this dir } elseif ( !is_readable( $dir ) ) { wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); + return null; // bad permissions? } + return new FSFileBackendDirList( $dir, $params ); } /** * @see FileBackendStore::getFileListInternal() - * @return Array|FSFileBackendFileList|null + * @param string $fullCont + * @param string $dirRel + * @param array $params + * @return array|FSFileBackendFileList|null */ public function getFileListInternal( $fullCont, $dirRel, array $params ) { list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); @@ -585,11 +616,14 @@ class FSFileBackend extends FileBackendStore { $exists = is_dir( $dir ); if ( !$exists ) { wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" ); + return array(); // nothing under this dir } elseif ( !is_readable( $dir ) ) { wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); + return null; // bad permissions? } + return new FSFileBackendFileList( $dir, $params ); } @@ -662,8 +696,8 @@ class FSFileBackend extends FileBackendStore { foreach ( $fileOpHandles as $index => $fileOpHandle ) { $status = Status::newGood(); - $function = '_getResponse' . $fileOpHandle->call; - $this->$function( $errs[$index], $status, $fileOpHandle->params, $fileOpHandle->cmd ); + $function = $fileOpHandle->call; + $function( $errs[$index], $status, $fileOpHandle->params, $fileOpHandle->cmd ); $statuses[$index] = $status; if ( $status->isOK() && $fileOpHandle->chmodPath ) { $this->chmod( $fileOpHandle->chmodPath ); @@ -718,8 +752,6 @@ class FSFileBackend extends FileBackendStore { /** * Listen for E_WARNING errors and track whether any happen - * - * @return void */ protected function trapWarnings() { $this->hadWarningErrors[] = false; // push to stack @@ -737,7 +769,7 @@ class FSFileBackend extends FileBackendStore { } /** - * @param integer $errno + * @param int $errno * @param string $errstr * @return bool * @access private @@ -745,6 +777,7 @@ class FSFileBackend extends FileBackendStore { public function handleWarning( $errno, $errstr ) { wfDebugLog( 'FSFileBackend', $errstr ); // more detailed error logging $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true; + return true; // suppress from PHP handler } } @@ -759,9 +792,9 @@ class FSFileOpHandle extends FileBackendStoreOpHandle { /** * @param FSFileBackend $backend * @param array $params - * @param string $call + * @param callable $call * @param string $cmd - * @param integer|null $chmodPath + * @param int|null $chmodPath */ public function __construct( FSFileBackend $backend, array $params, $call, $cmd, $chmodPath = null @@ -784,13 +817,18 @@ class FSFileOpHandle extends FileBackendStoreOpHandle { abstract class FSFileBackendList implements Iterator { /** @var Iterator */ protected $iter; - protected $suffixStart; // integer - protected $pos = 0; // integer - /** @var Array */ + + /** @var int */ + protected $suffixStart; + + /** @var int */ + protected $pos = 0; + + /** @var array */ protected $params = array(); /** - * @param string $dir file system directory + * @param string $dir File system directory * @param array $params */ public function __construct( $dir, array $params ) { @@ -811,7 +849,7 @@ abstract class FSFileBackendList implements Iterator { /** * Return an appropriate iterator object to wrap * - * @param string $dir file system directory + * @param string $dir File system directory * @return Iterator */ protected function initIterator( $dir ) { @@ -823,6 +861,7 @@ abstract class FSFileBackendList implements Iterator { # 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 @@ -832,7 +871,7 @@ abstract class FSFileBackendList implements Iterator { /** * @see Iterator::key() - * @return integer + * @return int */ public function key() { return $this->pos; @@ -848,7 +887,7 @@ abstract class FSFileBackendList implements Iterator { /** * @see Iterator::next() - * @return void + * @throws FileBackendError */ public function next() { try { @@ -862,7 +901,7 @@ abstract class FSFileBackendList implements Iterator { /** * @see Iterator::rewind() - * @return void + * @throws FileBackendError */ public function rewind() { $this->pos = 0; @@ -885,13 +924,14 @@ abstract class FSFileBackendList implements Iterator { /** * Filter out items by advancing to the next ones */ - protected function filterViaNext() {} + 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 $path + * @param string $dir * @return string */ protected function getRelPath( $dir ) { @@ -899,6 +939,7 @@ abstract class FSFileBackendList implements Iterator { if ( $path === false ) { $path = $dir; } + return strtr( substr( $path, $this->suffixStart ), '\\', '/' ); } } |