Go to the documentation of this file.
69 parent::__construct( $config );
72 if ( isset( $config[
'basePath'] ) ) {
73 $this->basePath = rtrim( $config[
'basePath'],
'/' );
75 $this->basePath =
null;
78 if ( isset( $config[
'containerPaths'] ) ) {
79 $this->containerPaths = (
array)$config[
'containerPaths'];
80 foreach ( $this->containerPaths
as &
$path ) {
85 $this->fileMode = isset( $config[
'fileMode'] ) ? $config[
'fileMode'] : 0644;
86 if ( isset( $config[
'fileOwner'] ) && function_exists(
'posix_getuid' ) ) {
87 $this->fileOwner = $config[
'fileOwner'];
88 $info = posix_getpwuid( posix_getuid() );
89 $this->currentUser = $info[
'name'];
95 if ( isset( $this->containerPaths[$container] ) || isset( $this->basePath ) ) {
98 return $relStoragePath;
113 if ( preg_match(
'![^/]{256}!',
$path ) ) {
117 return !preg_match(
'![:*?"<>|]!',
$path );
132 if ( isset( $this->containerPaths[$shortCont] ) ) {
133 return $this->containerPaths[$shortCont];
134 } elseif ( isset( $this->basePath ) ) {
135 return "{$this->basePath}/{$fullCont}";
149 if ( $relPath ===
null ) {
154 if ( $relPath !=
'' ) {
155 $fsPath .=
"/{$relPath}";
163 if ( $fsPath ===
null ) {
166 $parentDir = dirname( $fsPath );
168 if ( file_exists( $fsPath ) ) {
169 $ok = is_file( $fsPath ) && is_writable( $fsPath );
171 $ok = is_dir( $parentDir ) && is_writable( $parentDir );
174 if ( $this->fileOwner !==
null && $this->currentUser !== $this->fileOwner ) {
176 trigger_error( __METHOD__ .
": PHP process owner is not '{$this->fileOwner}'." );
186 if ( $dest ===
null ) {
187 $status->fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
192 if ( !empty(
$params[
'async'] ) ) {
195 $status->fatal(
'backend-fail-create',
$params[
'dst'] );
200 $bytes = file_put_contents( $tempFile->getPath(),
$params[
'content'] );
202 if ( $bytes ===
false ) {
203 $status->fatal(
'backend-fail-create',
$params[
'dst'] );
207 $cmd = implode(
' ',
array(
213 $tempFile->bind( $status->value );
216 $bytes = file_put_contents( $dest,
$params[
'content'] );
218 if ( $bytes ===
false ) {
219 $status->fatal(
'backend-fail-create',
$params[
'dst'] );
223 $this->
chmod( $dest );
233 if ( $errors !==
'' && !(
wfIsWindows() && $errors[0] ===
" " ) ) {
234 $status->
fatal(
'backend-fail-create',
$params[
'dst'] );
235 trigger_error(
"$cmd\n$errors", E_USER_WARNING );
243 if ( $dest ===
null ) {
244 $status->
fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
249 if ( !empty(
$params[
'async'] ) ) {
250 $cmd = implode(
' ',
array(
258 $ok =
copy( $params[
'src'], $dest );
261 if ( !
$ok || ( filesize(
$params[
'src'] ) !== filesize( $dest ) ) ) {
264 trigger_error( __METHOD__ .
": copy() failed but returned true." );
270 $this->
chmod( $dest );
280 if ( $errors !==
'' && !(
wfIsWindows() && $errors[0] ===
" " ) ) {
282 trigger_error(
"$cmd\n$errors", E_USER_WARNING );
291 $status->
fatal(
'backend-fail-invalidpath',
$params[
'src'] );
297 if ( $dest ===
null ) {
298 $status->
fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
304 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
311 if ( !empty(
$params[
'async'] ) ) {
312 $cmd = implode(
' ',
array(
323 if ( !
$ok || ( filesize(
$source ) !== filesize( $dest ) ) ) {
328 trigger_error( __METHOD__ .
": copy() failed but returned true." );
334 $this->
chmod( $dest );
344 if ( $errors !==
'' && !(
wfIsWindows() && $errors[0] ===
" " ) ) {
346 trigger_error(
"$cmd\n$errors", E_USER_WARNING );
355 $status->
fatal(
'backend-fail-invalidpath',
$params[
'src'] );
361 if ( $dest ===
null ) {
362 $status->
fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
368 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
375 if ( !empty(
$params[
'async'] ) ) {
376 $cmd = implode(
' ',
array(
401 if ( $errors !==
'' && !(
wfIsWindows() && $errors[0] ===
" " ) ) {
403 trigger_error(
"$cmd\n$errors", E_USER_WARNING );
412 $status->
fatal(
'backend-fail-invalidpath',
$params[
'src'] );
418 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
419 $status->
fatal(
'backend-fail-delete',
$params[
'src'] );
425 if ( !empty(
$params[
'async'] ) ) {
426 $cmd = implode(
' ',
array(
436 $status->
fatal(
'backend-fail-delete',
$params[
'src'] );
449 if ( $errors !==
'' && !(
wfIsWindows() && $errors[0] ===
" " ) ) {
450 $status->
fatal(
'backend-fail-delete',
$params[
'src'] );
451 trigger_error(
"$cmd\n$errors", E_USER_WARNING );
465 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
466 $existed = is_dir(
$dir );
470 $status->
fatal(
'directorycreateerror',
$params[
'dir'] );
471 } elseif ( !is_writable(
$dir ) ) {
472 $status->
fatal(
'directoryreadonlyerror',
$params[
'dir'] );
473 } elseif ( !is_readable(
$dir ) ) {
474 $status->
fatal(
'directorynotreadableerror',
$params[
'dir'] );
478 if ( is_dir(
$dir ) && !$existed ) {
489 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
491 if ( !empty(
$params[
'noListing'] ) && !file_exists(
"{$dir}/index.html" ) ) {
493 $bytes = file_put_contents(
"{$dir}/index.html", $this->
indexHtmlPrivate() );
495 if ( $bytes ===
false ) {
496 $status->
fatal(
'backend-fail-create',
$params[
'dir'] .
'/index.html' );
500 if ( !empty(
$params[
'noAccess'] ) && !file_exists(
"{$contRoot}/.htaccess" ) ) {
502 $bytes = file_put_contents(
"{$contRoot}/.htaccess", $this->
htaccessPrivate() );
504 if ( $bytes ===
false ) {
505 $storeDir =
"mwstore://{$this->name}/{$shortCont}";
506 $status->
fatal(
'backend-fail-create',
"{$storeDir}/.htaccess" );
517 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
519 if ( !empty(
$params[
'listing'] ) && is_file(
"{$dir}/index.html" ) ) {
520 $exists = ( file_get_contents(
"{$dir}/index.html" ) === $this->
indexHtmlPrivate() );
522 if ( $exists && !unlink(
"{$dir}/index.html" ) ) {
523 $status->
fatal(
'backend-fail-delete',
$params[
'dir'] .
'/index.html' );
528 if ( !empty(
$params[
'access'] ) && is_file(
"{$contRoot}/.htaccess" ) ) {
529 $exists = ( file_get_contents(
"{$contRoot}/.htaccess" ) === $this->
htaccessPrivate() );
531 if ( $exists && !unlink(
"{$contRoot}/.htaccess" ) ) {
532 $storeDir =
"mwstore://{$this->name}/{$shortCont}";
533 $status->
fatal(
'backend-fail-delete',
"{$storeDir}/.htaccess" );
545 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
547 if ( is_dir(
$dir ) ) {
568 'size' => $stat[
'size']
570 } elseif ( !$hadError ) {
587 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
590 $exists = is_dir(
$dir );
593 return $hadError ? null : $exists;
606 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
607 $exists = is_dir(
$dir );
609 wfDebug( __METHOD__ .
"() given directory does not exist: '$dir'\n" );
612 } elseif ( !is_readable(
$dir ) ) {
613 wfDebug( __METHOD__ .
"() given directory is unreadable: '$dir'\n" );
631 $dir = ( $dirRel !=
'' ) ?
"{$contRoot}/{$dirRel}" : $contRoot;
632 $exists = is_dir(
$dir );
634 wfDebug( __METHOD__ .
"() given directory does not exist: '$dir'\n" );
637 } elseif ( !is_readable(
$dir ) ) {
638 wfDebug( __METHOD__ .
"() given directory is unreadable: '$dir'\n" );
652 $fsFiles[$src] =
null;
667 $tmpFiles[$src] =
null;
673 $tmpFiles[$src] =
null;
675 $tmpPath = $tmpFile->getPath();
681 $tmpFiles[$src] =
null;
683 $this->
chmod( $tmpPath );
684 $tmpFiles[$src] = $tmpFile;
701 foreach ( $fileOpHandles
as $index => $fileOpHandle ) {
702 $pipes[$index] = popen(
"{$fileOpHandle->cmd} 2>&1",
'r' );
706 foreach ( $pipes
as $index => $pipe ) {
709 $errs[$index] = stream_get_contents( $pipe );
713 foreach ( $fileOpHandles
as $index => $fileOpHandle ) {
715 $function =
'getResponse' . $fileOpHandle->call;
716 $this->$function( $errs[$index], $status, $fileOpHandle->params, $fileOpHandle->cmd );
717 $statuses[$index] = $status;
718 if ( $status->
isOK() && $fileOpHandle->chmodPath ) {
719 $this->
chmod( $fileOpHandle->chmodPath );
756 return "Deny from all\n";
773 $this->hadWarningErrors[] =
false;
774 set_error_handler(
array( $this,
'handleWarning' ), E_WARNING );
783 restore_error_handler();
784 return array_pop( $this->hadWarningErrors );
795 $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] =
true;
852 if (
$path ===
false ) {
855 $this->suffixStart = strlen(
$path ) + 1;
860 }
catch ( UnexpectedValueException
$e ) {
872 if ( !empty( $this->params[
'topOnly'] ) ) {
873 # Get an iterator that will get direct sub-nodes
874 return new DirectoryIterator(
$dir );
876 # Get an iterator that will return leaf nodes (non-directories)
877 # RecursiveDirectoryIterator extends FilesystemIterator.
878 # FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x.
879 $flags = FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::SKIP_DOTS;
881 return new RecursiveIteratorIterator(
883 RecursiveIteratorIterator::CHILD_FIRST
892 public function key() {
901 return $this->
getRelPath( $this->iter->current()->getPathname() );
908 public function next() {
912 }
catch ( UnexpectedValueException
$e ) {
913 throw new FileBackendError(
"File iterator gave UnexpectedValueException." );
922 public function rewind() {
925 $this->iter->rewind();
927 }
catch ( UnexpectedValueException
$e ) {
928 throw new FileBackendError(
"File iterator gave UnexpectedValueException." );
936 public function valid() {
937 return $this->iter && $this->iter->valid();
955 if (
$path ===
false ) {
959 return strtr( substr(
$path, $this->suffixStart ),
'\\',
'/' );
965 while ( $this->iter->valid() ) {
966 if ( $this->iter->current()->isDot() || !$this->iter->current()->isDir() ) {
977 while ( $this->iter->valid() ) {
978 if ( !$this->iter->current()->isFile() ) {
static splitStoragePath( $storagePath)
Split a storage path into a backend name, a container name, and a relative file path.
initIterator( $dir)
Return an appropriate iterator object to wrap.
__construct(array $config)
doCleanInternal( $fullCont, $dirRel, array $params)
filterViaNext()
Filter out items by advancing to the next ones.
doStoreInternal(array $params)
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
doClearCache(array $paths=null)
getResponseStore( $errors, Status $status, array $params, $cmd)
doPublishInternal( $fullCont, $dirRel, array $params)
fatal( $message)
Add an error and set OK to false, indicating that the operation as a whole was fatal.
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
string $currentUser
OS username running this script *.
isOK()
Returns whether the operation completed.
merge( $other, $overwriteValue=false)
Merge another status object into this one.
getResponseCreate( $errors, Status $status, array $params, $cmd)
doPrepareInternal( $fullCont, $dirRel, array $params)
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
File backend exception for checked exceptions (e.g.
wfDebugLog( $logGroup, $text, $dest='all')
Send a line to a supplementary debug log file, if configured, or main debug log if not.
static newGood( $value=null)
Factory function for good results.
copy(array $params, array $opts=array())
Performs a single copy operation.
htaccessPrivate()
Return the text of a .htaccess file to make a directory private.
doGetFileStat(array $params)
directoriesAreVirtual()
Is this a key/value store where directories are just virtual? Virtual directories exists in so much a...
it s the revision text itself In either if gzip is the revision text is gzipped $flags
string $fileOwner
Required OS username to own files *.
getResponseMove( $errors, Status $status, array $params, $cmd)
doGetLocalReferenceMulti(array $params)
string $basePath
Directory holding the container directories *.
filterViaNext()
Filter out items by advancing to the next ones.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
doDirectoryExists( $fullCont, $dirRel, array $params)
getDirectoryListInternal( $fullCont, $dirRel, array $params)
getRelPath( $dir)
Return only the relative path and normalize slashes to FileBackend-style.
containerFSRoot( $shortCont, $fullCont)
Given the short (unresolved) and full (resolved) name of a container, return the file system path of ...
FileBackendStore $backend
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
doSecureInternal( $fullCont, $dirRel, array $params)
Wrapper around RecursiveDirectoryIterator/DirectoryIterator that catches exception or does any custom...
doExecuteOpHandlesInternal(array $fileOpHandles)
getResponseCopy( $errors, Status $status, array $params, $cmd)
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
processing should stop and the error should be shown to the user * false
array $containerPaths
Map of container names to root paths for custom container paths *.
resolveToFSPath( $storagePath)
Get the absolute file system path for a storage path.
doDeleteInternal(array $params)
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
int $fileMode
File permission mode *.
static factory( $prefix, $extension='')
Make a new temporary file on the file system.
resolveContainerPath( $container, $relStoragePath)
Resolve a relative storage path, checking if it's allowed by the backend.
wfIsWindows()
Check if the operating system is Windows.
resolveStoragePathReal( $storagePath)
Like resolveStoragePath() except null values are returned if the container is sharded and the shard c...
wfEscapeShellArg()
Windows-compatible version of escapeshellarg() Windows doesn't recognise single-quotes in the shell,...
Base class for all backends using particular storage medium.
FileBackendStore helper class for performing asynchronous file operations.
Class representing a non-directory file on the file system.
Class for a file system (FS) based file backend.
if(count( $args)==0) $dir
indexHtmlPrivate()
Return the text of an index.html file to hide directory listings.
cleanPathSlashes( $path)
Clean up directory separators for the given OS.
static extensionFromPath( $path)
Get the final extension from a storage or FS path.
__construct(FSFileBackend $backend, array $params, $call, $cmd, $chmodPath=null)
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
doCreateInternal(array $params)
chmod( $path)
Chmod a file, suppressing the warnings.
if(PHP_SAPI !='cli') $source
isLegalRelPath( $path)
Sanity check a relative file system path for validity.
isPathUsableInternal( $storagePath)
Check if a file can be created or changed at a given storage path.
handleWarning( $errno, $errstr)
untrapWarnings()
Stop listening for E_WARNING errors and return true if any happened.
doGetLocalCopyMulti(array $params)
doCopyInternal(array $params)
getFileListInternal( $fullCont, $dirRel, array $params)
trapWarnings()
Listen for E_WARNING errors and track whether any happen.
getResponseDelete( $errors, Status $status, array $params, $cmd)
__construct( $dir, array $params)
doMoveInternal(array $params)
filterViaNext()
Filter out items by advancing to the next ones.