MediaWiki  master
FileBackend.php
Go to the documentation of this file.
1 <?php
31 use Psr\Log\LoggerAwareInterface;
32 use Psr\Log\LoggerInterface;
33 use Psr\Log\NullLogger;
34 use Wikimedia\ScopedCallback;
35 
96 abstract class FileBackend implements LoggerAwareInterface {
98  protected $name;
99 
101  protected $domainId;
102 
104  protected $readOnly;
105 
107  protected $parallelize;
108 
110  protected $concurrency;
111 
113  protected $tmpFileFactory;
114 
116  protected $lockManager;
118  protected $fileJournal;
120  protected $logger;
122  protected $profiler;
123 
125  protected $obResetFunc;
127  protected $streamMimeFunc;
129  protected $statusWrapper;
130 
132  public const ATTR_HEADERS = 1; // files can be tagged with standard HTTP headers
133  public const ATTR_METADATA = 2; // files can be stored with metadata key/values
134  public const ATTR_UNICODE_PATHS = 4; // files can have Unicode paths (not just ASCII)
135 
137  protected const STAT_ABSENT = false;
138 
140  public const STAT_ERROR = null;
142  public const LIST_ERROR = null;
144  public const TEMPURL_ERROR = null;
146  public const EXISTENCE_ERROR = null;
147 
149  public const TIMESTAMP_FAIL = false;
151  public const CONTENT_FAIL = false;
153  public const XATTRS_FAIL = false;
155  public const SIZE_FAIL = false;
157  public const SHA1_FAIL = false;
158 
193  public function __construct( array $config ) {
194  if ( !array_key_exists( 'name', $config ) ) {
195  throw new InvalidArgumentException( 'Backend name not specified.' );
196  }
197  $this->name = $config['name'];
198  $this->domainId = $config['domainId'] // e.g. "my_wiki-en_"
199  ?? $config['wikiId'] // b/c alias
200  ?? null;
201  if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
202  throw new InvalidArgumentException( "Backend name '{$this->name}' is invalid." );
203  }
204  if ( !is_string( $this->domainId ) ) {
205  throw new InvalidArgumentException(
206  "Backend domain ID not provided for '{$this->name}'." );
207  }
208  $this->lockManager = $config['lockManager'] ?? new NullLockManager( [] );
209  $this->fileJournal = $config['fileJournal'] ?? new NullFileJournal;
210  $this->readOnly = isset( $config['readOnly'] )
211  ? (string)$config['readOnly']
212  : '';
213  $this->parallelize = isset( $config['parallelize'] )
214  ? (string)$config['parallelize']
215  : 'off';
216  $this->concurrency = isset( $config['concurrency'] )
217  ? (int)$config['concurrency']
218  : 50;
219  $this->obResetFunc = $config['obResetFunc'] ?? [ $this, 'resetOutputBuffer' ];
220  $this->streamMimeFunc = $config['streamMimeFunc'] ?? null;
221 
222  $this->profiler = $config['profiler'] ?? null;
223  if ( !is_callable( $this->profiler ) ) {
224  $this->profiler = null;
225  }
226  $this->logger = $config['logger'] ?? new NullLogger();
227  $this->statusWrapper = $config['statusWrapper'] ?? null;
228  // tmpDirectory gets precedence for backward compatibility
229  if ( isset( $config['tmpDirectory'] ) ) {
230  $this->tmpFileFactory = new TempFSFileFactory( $config['tmpDirectory'] );
231  } else {
232  $this->tmpFileFactory = $config['tmpFileFactory'] ?? new TempFSFileFactory();
233  }
234  }
235 
236  public function setLogger( LoggerInterface $logger ) {
237  $this->logger = $logger;
238  }
239 
248  final public function getName() {
249  return $this->name;
250  }
251 
258  final public function getDomainId() {
259  return $this->domainId;
260  }
261 
269  final public function getWikiId() {
270  return $this->getDomainId();
271  }
272 
278  final public function isReadOnly() {
279  return ( $this->readOnly != '' );
280  }
281 
287  final public function getReadOnlyReason() {
288  return ( $this->readOnly != '' ) ? $this->readOnly : false;
289  }
290 
297  public function getFeatures() {
299  }
300 
308  final public function hasFeatures( $bitfield ) {
309  return ( $this->getFeatures() & $bitfield ) === $bitfield;
310  }
311 
464  final public function doOperations( array $ops, array $opts = [] ) {
465  if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
466  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
467  }
468  if ( $ops === [] ) {
469  return $this->newStatus(); // nothing to do
470  }
471 
472  $ops = $this->resolveFSFileObjects( $ops );
473  if ( empty( $opts['force'] ) ) { // sanity
474  unset( $opts['nonLocking'] );
475  }
476 
478  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
479 
480  return $this->doOperationsInternal( $ops, $opts );
481  }
482 
489  abstract protected function doOperationsInternal( array $ops, array $opts );
490 
502  final public function doOperation( array $op, array $opts = [] ) {
503  return $this->doOperations( [ $op ], $opts );
504  }
505 
516  final public function create( array $params, array $opts = [] ) {
517  return $this->doOperation( [ 'op' => 'create' ] + $params, $opts );
518  }
519 
530  final public function store( array $params, array $opts = [] ) {
531  return $this->doOperation( [ 'op' => 'store' ] + $params, $opts );
532  }
533 
544  final public function copy( array $params, array $opts = [] ) {
545  return $this->doOperation( [ 'op' => 'copy' ] + $params, $opts );
546  }
547 
558  final public function move( array $params, array $opts = [] ) {
559  return $this->doOperation( [ 'op' => 'move' ] + $params, $opts );
560  }
561 
572  final public function delete( array $params, array $opts = [] ) {
573  return $this->doOperation( [ 'op' => 'delete' ] + $params, $opts );
574  }
575 
587  final public function describe( array $params, array $opts = [] ) {
588  return $this->doOperation( [ 'op' => 'describe' ] + $params, $opts );
589  }
590 
707  final public function doQuickOperations( array $ops, array $opts = [] ) {
708  if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
709  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
710  }
711  if ( $ops === [] ) {
712  return $this->newStatus(); // nothing to do
713  }
714 
715  $ops = $this->resolveFSFileObjects( $ops );
716  foreach ( $ops as &$op ) {
717  $op['overwrite'] = true; // avoids RTTs in key/value stores
718  }
719 
721  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
722 
723  return $this->doQuickOperationsInternal( $ops, $opts );
724  }
725 
733  abstract protected function doQuickOperationsInternal( array $ops, array $opts );
734 
746  final public function doQuickOperation( array $op, array $opts = [] ) {
747  return $this->doQuickOperations( [ $op ], $opts );
748  }
749 
761  final public function quickCreate( array $params, array $opts = [] ) {
762  return $this->doQuickOperation( [ 'op' => 'create' ] + $params, $opts );
763  }
764 
776  final public function quickStore( array $params, array $opts = [] ) {
777  return $this->doQuickOperation( [ 'op' => 'store' ] + $params, $opts );
778  }
779 
791  final public function quickCopy( array $params, array $opts = [] ) {
792  return $this->doQuickOperation( [ 'op' => 'copy' ] + $params, $opts );
793  }
794 
806  final public function quickMove( array $params, array $opts = [] ) {
807  return $this->doQuickOperation( [ 'op' => 'move' ] + $params, $opts );
808  }
809 
821  final public function quickDelete( array $params, array $opts = [] ) {
822  return $this->doQuickOperation( [ 'op' => 'delete' ] + $params, $opts );
823  }
824 
836  final public function quickDescribe( array $params, array $opts = [] ) {
837  return $this->doQuickOperation( [ 'op' => 'describe' ] + $params, $opts );
838  }
839 
852  abstract public function concatenate( array $params );
853 
872  final public function prepare( array $params ) {
873  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
874  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
875  }
877  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
878  return $this->doPrepare( $params );
879  }
880 
886  abstract protected function doPrepare( array $params );
887 
904  final public function secure( array $params ) {
905  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
906  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
907  }
909  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
910  return $this->doSecure( $params );
911  }
912 
918  abstract protected function doSecure( array $params );
919 
938  final public function publish( array $params ) {
939  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
940  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
941  }
943  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
944  return $this->doPublish( $params );
945  }
946 
952  abstract protected function doPublish( array $params );
953 
965  final public function clean( array $params ) {
966  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
967  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
968  }
970  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
971  return $this->doClean( $params );
972  }
973 
979  abstract protected function doClean( array $params );
980 
997  abstract public function fileExists( array $params );
998 
1009  abstract public function getFileTimestamp( array $params );
1010 
1022  final public function getFileContents( array $params ) {
1023  $contents = $this->getFileContentsMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1024 
1025  return $contents[$params['src']];
1026  }
1027 
1041  abstract public function getFileContentsMulti( array $params );
1042 
1063  abstract public function getFileXAttributes( array $params );
1064 
1075  abstract public function getFileSize( array $params );
1076 
1093  abstract public function getFileStat( array $params );
1094 
1105  abstract public function getFileSha1Base36( array $params );
1106 
1116  abstract public function getFileProps( array $params );
1117 
1137  abstract public function streamFile( array $params );
1138 
1157  final public function getLocalReference( array $params ) {
1158  $fsFiles = $this->getLocalReferenceMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1159 
1160  return $fsFiles[$params['src']];
1161  }
1162 
1180  abstract public function getLocalReferenceMulti( array $params );
1181 
1194  final public function getLocalCopy( array $params ) {
1195  $tmpFiles = $this->getLocalCopyMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1196 
1197  return $tmpFiles[$params['src']];
1198  }
1199 
1215  abstract public function getLocalCopyMulti( array $params );
1216 
1235  abstract public function getFileHttpUrl( array $params );
1236 
1262  abstract public function directoryExists( array $params );
1263 
1286  abstract public function getDirectoryList( array $params );
1287 
1304  final public function getTopDirectoryList( array $params ) {
1305  return $this->getDirectoryList( [ 'topOnly' => true ] + $params );
1306  }
1307 
1328  abstract public function getFileList( array $params );
1329 
1346  final public function getTopFileList( array $params ) {
1347  return $this->getFileList( [ 'topOnly' => true ] + $params );
1348  }
1349 
1358  abstract public function preloadCache( array $paths );
1359 
1368  abstract public function clearCache( array $paths = null );
1369 
1384  abstract public function preloadFileStat( array $params );
1385 
1397  final public function lockFiles( array $paths, $type, $timeout = 0 ) {
1398  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1399 
1400  return $this->wrapStatus( $this->lockManager->lock( $paths, $type, $timeout ) );
1401  }
1402 
1410  final public function unlockFiles( array $paths, $type ) {
1411  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1412 
1413  return $this->wrapStatus( $this->lockManager->unlock( $paths, $type ) );
1414  }
1415 
1432  final public function getScopedFileLocks(
1433  array $paths, $type, StatusValue $status, $timeout = 0
1434  ) {
1435  if ( $type === 'mixed' ) {
1436  foreach ( $paths as &$typePaths ) {
1437  $typePaths = array_map( 'FileBackend::normalizeStoragePath', $typePaths );
1438  }
1439  } else {
1440  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1441  }
1442 
1443  return ScopedLock::factory( $this->lockManager, $paths, $type, $status, $timeout );
1444  }
1445 
1462  abstract public function getScopedLocksForOps( array $ops, StatusValue $status );
1463 
1471  final public function getRootStoragePath() {
1472  return "mwstore://{$this->name}";
1473  }
1474 
1482  final public function getContainerStoragePath( $container ) {
1483  return $this->getRootStoragePath() . "/{$container}";
1484  }
1485 
1491  final public function getJournal() {
1492  return $this->fileJournal;
1493  }
1494 
1504  protected function resolveFSFileObjects( array $ops ) {
1505  foreach ( $ops as &$op ) {
1506  $src = $op['src'] ?? null;
1507  if ( $src instanceof FSFile ) {
1508  $op['srcRef'] = $src;
1509  $op['src'] = $src->getPath();
1510  }
1511  }
1512  unset( $op );
1513 
1514  return $ops;
1515  }
1516 
1524  final public static function isStoragePath( $path ) {
1525  return ( strpos( $path, 'mwstore://' ) === 0 );
1526  }
1527 
1536  final public static function splitStoragePath( $storagePath ) {
1537  if ( self::isStoragePath( $storagePath ) ) {
1538  // Remove the "mwstore://" prefix and split the path
1539  $parts = explode( '/', substr( $storagePath, 10 ), 3 );
1540  if ( count( $parts ) >= 2 && $parts[0] != '' && $parts[1] != '' ) {
1541  if ( count( $parts ) == 3 ) {
1542  return $parts; // e.g. "backend/container/path"
1543  } else {
1544  return [ $parts[0], $parts[1], '' ]; // e.g. "backend/container"
1545  }
1546  }
1547  }
1548 
1549  return [ null, null, null ];
1550  }
1551 
1559  final public static function normalizeStoragePath( $storagePath ) {
1560  list( $backend, $container, $relPath ) = self::splitStoragePath( $storagePath );
1561  if ( $relPath !== null ) { // must be for this backend
1562  $relPath = self::normalizeContainerPath( $relPath );
1563  if ( $relPath !== null ) {
1564  return ( $relPath != '' )
1565  ? "mwstore://{$backend}/{$container}/{$relPath}"
1566  : "mwstore://{$backend}/{$container}";
1567  }
1568  }
1569 
1570  return null;
1571  }
1572 
1581  final public static function parentStoragePath( $storagePath ) {
1582  // XXX dirname() depends on platform and locale! If nothing enforces that the storage path
1583  // doesn't contain characters like '\', behavior can vary by platform. We should use
1584  // explode() instead.
1585  $storagePath = dirname( $storagePath );
1586  list( , , $rel ) = self::splitStoragePath( $storagePath );
1587 
1588  return ( $rel === null ) ? null : $storagePath;
1589  }
1590 
1598  final public static function extensionFromPath( $path, $case = 'lowercase' ) {
1599  // This will treat a string starting with . as not having an extension, but store paths have
1600  // to start with 'mwstore://', so "garbage in, garbage out".
1601  $i = strrpos( $path, '.' );
1602  $ext = $i ? substr( $path, $i + 1 ) : '';
1603 
1604  if ( $case === 'lowercase' ) {
1605  $ext = strtolower( $ext );
1606  } elseif ( $case === 'uppercase' ) {
1607  $ext = strtoupper( $ext );
1608  }
1609 
1610  return $ext;
1611  }
1612 
1620  final public static function isPathTraversalFree( $path ) {
1621  return ( self::normalizeContainerPath( $path ) !== null );
1622  }
1623 
1633  final public static function makeContentDisposition( $type, $filename = '' ) {
1634  $parts = [];
1635 
1636  $type = strtolower( $type );
1637  if ( !in_array( $type, [ 'inline', 'attachment' ] ) ) {
1638  throw new InvalidArgumentException( "Invalid Content-Disposition type '$type'." );
1639  }
1640  $parts[] = $type;
1641 
1642  if ( strlen( $filename ) ) {
1643  $parts[] = "filename*=UTF-8''" . rawurlencode( basename( $filename ) );
1644  }
1645 
1646  return implode( ';', $parts );
1647  }
1648 
1659  final protected static function normalizeContainerPath( $path ) {
1660  // Normalize directory separators
1661  $path = strtr( $path, '\\', '/' );
1662  // Collapse any consecutive directory separators
1663  $path = preg_replace( '![/]{2,}!', '/', $path );
1664  // Remove any leading directory separator
1665  $path = ltrim( $path, '/' );
1666  // Use the same traversal protection as Title::secureAndSplit()
1667  if ( strpos( $path, '.' ) !== false ) {
1668  if (
1669  $path === '.' ||
1670  $path === '..' ||
1671  strpos( $path, './' ) === 0 ||
1672  strpos( $path, '../' ) === 0 ||
1673  strpos( $path, '/./' ) !== false ||
1674  strpos( $path, '/../' ) !== false
1675  ) {
1676  return null;
1677  }
1678  }
1679 
1680  return $path;
1681  }
1682 
1691  final protected function newStatus( ...$args ) {
1692  if ( count( $args ) ) {
1693  $sv = StatusValue::newFatal( ...$args );
1694  } else {
1695  $sv = StatusValue::newGood();
1696  }
1697 
1698  return $this->wrapStatus( $sv );
1699  }
1700 
1705  final protected function wrapStatus( StatusValue $sv ) {
1706  return $this->statusWrapper ? call_user_func( $this->statusWrapper, $sv ) : $sv;
1707  }
1708 
1713  protected function scopedProfileSection( $section ) {
1714  return $this->profiler ? ( $this->profiler )( $section ) : null;
1715  }
1716 
1720  protected function resetOutputBuffer() {
1721  // XXX According to documentation, ob_get_status() always returns a non-empty array and this
1722  // condition will always be true
1723  while ( ob_get_status() ) {
1724  if ( !ob_end_clean() ) {
1725  // Could not remove output buffer handler; abort now
1726  // to avoid getting in some kind of infinite loop.
1727  break;
1728  }
1729  }
1730  }
1731 }
FileBackend\streamFile
streamFile(array $params)
Stream the content of the file at a storage path in the backend.
FileBackend\splitStoragePath
static splitStoragePath( $storagePath)
Split a storage path into a backend name, a container name, and a relative file path.
Definition: FileBackend.php:1536
LockManager
Class for handling resource locking.
Definition: LockManager.php:47
FileBackend\$tmpFileFactory
TempFSFileFactory $tmpFileFactory
Definition: FileBackend.php:113
FileBackend\doPrepare
doPrepare(array $params)
FileBackend\doOperations
doOperations(array $ops, array $opts=[])
This is the main entry point into the backend for write operations.
Definition: FileBackend.php:464
FileBackend\$lockManager
LockManager $lockManager
Definition: FileBackend.php:116
StatusValue
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: StatusValue.php:42
FileBackend\normalizeContainerPath
static normalizeContainerPath( $path)
Validate and normalize a relative storage path.
Definition: FileBackend.php:1659
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:69
FileBackend\quickStore
quickStore(array $params, array $opts=[])
Performs a single quick store operation.
Definition: FileBackend.php:776
FileBackend\preloadFileStat
preloadFileStat(array $params)
Preload file stat information (concurrently if possible) into in-process cache.
FileBackend
Base class for all file backend classes (including multi-write backends).
Definition: FileBackend.php:96
FileBackend\describe
describe(array $params, array $opts=[])
Performs a single describe operation.
Definition: FileBackend.php:587
FileBackend\unlockFiles
unlockFiles(array $paths, $type)
Unlock the files at the given storage paths in the backend.
Definition: FileBackend.php:1410
FileBackend\doPublish
doPublish(array $params)
FileBackend\ATTR_HEADERS
const ATTR_HEADERS
Bitfield flags for supported features.
Definition: FileBackend.php:132
FileBackend\directoryExists
directoryExists(array $params)
Check if a directory exists at a given storage path.
FileBackend\getLocalReferenceMulti
getLocalReferenceMulti(array $params)
Like getLocalReference() except it takes an array of storage paths and yields an order-preserved map ...
FileBackend\getFileStat
getFileStat(array $params)
Get quick information about a file at a storage path in the backend.
FileBackend\getFileXAttributes
getFileXAttributes(array $params)
Get metadata about a file at a storage path in the backend.
FileBackend\$statusWrapper
callable $statusWrapper
Definition: FileBackend.php:129
FileBackend\publish
publish(array $params)
Remove measures to block web access to a storage directory and the container it belongs to.
Definition: FileBackend.php:938
FileBackend\wrapStatus
wrapStatus(StatusValue $sv)
Definition: FileBackend.php:1705
FileBackend\resolveFSFileObjects
resolveFSFileObjects(array $ops)
Convert FSFile 'src' paths to string paths (with an 'srcRef' field set to the FSFile)
Definition: FileBackend.php:1504
FileBackend\getName
getName()
Get the unique backend name.
Definition: FileBackend.php:248
FileBackend\getDirectoryList
getDirectoryList(array $params)
Get an iterator to list all directories under a storage directory.
NullFileJournal
Simple version of FileJournal that does nothing.
Definition: NullFileJournal.php:6
FileBackend\getScopedFileLocks
getScopedFileLocks(array $paths, $type, StatusValue $status, $timeout=0)
Lock the files at the given storage paths in the backend.
Definition: FileBackend.php:1432
FileBackend\getDomainId
getDomainId()
Get the domain identifier used for this backend (possibly empty).
Definition: FileBackend.php:258
FileBackend\doQuickOperationsInternal
doQuickOperationsInternal(array $ops, array $opts)
FileBackend\$readOnly
string $readOnly
Read-only explanation message.
Definition: FileBackend.php:104
FileBackend\extensionFromPath
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
Definition: FileBackend.php:1598
FileBackend\normalizeStoragePath
static normalizeStoragePath( $storagePath)
Normalize a storage path by cleaning up directory separators.
Definition: FileBackend.php:1559
FileBackend\getReadOnlyReason
getReadOnlyReason()
Get an explanatory message if this backend is read-only.
Definition: FileBackend.php:287
FileBackend\getFileHttpUrl
getFileHttpUrl(array $params)
Return an HTTP URL to a given file that requires no authentication to use.
FileBackend\doQuickOperation
doQuickOperation(array $op, array $opts=[])
Same as doQuickOperations() except it takes a single operation.
Definition: FileBackend.php:746
ScopedLock\factory
static factory(LockManager $manager, array $paths, $type, StatusValue $status, $timeout=0)
Get a ScopedLock object representing a lock on resource paths.
Definition: ScopedLock.php:70
FileBackend\setLogger
setLogger(LoggerInterface $logger)
Definition: FileBackend.php:236
FileBackend\move
move(array $params, array $opts=[])
Performs a single move operation.
Definition: FileBackend.php:558
FileBackend\store
store(array $params, array $opts=[])
Performs a single store operation.
Definition: FileBackend.php:530
FileBackend\getFileContentsMulti
getFileContentsMulti(array $params)
Like getFileContents() except it takes an array of storage paths and returns an order preserved map o...
FileBackend\doOperation
doOperation(array $op, array $opts=[])
Same as doOperations() except it takes a single operation.
Definition: FileBackend.php:502
NullLockManager
Simple version of LockManager that only does lock reference counting.
Definition: NullLockManager.php:28
FileBackend\getFileTimestamp
getFileTimestamp(array $params)
Get the last-modified timestamp of the file at a storage path.
FileBackend\getFileSize
getFileSize(array $params)
Get the size (bytes) of a file at a storage path in the backend.
FileBackend\doClean
doClean(array $params)
FileBackend\isStoragePath
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
Definition: FileBackend.php:1524
FileBackend\$concurrency
int $concurrency
How many operations can be done in parallel.
Definition: FileBackend.php:110
FileBackend\create
create(array $params, array $opts=[])
Performs a single create operation.
Definition: FileBackend.php:516
FileJournal
Class for handling file operation journaling.
Definition: FileJournal.php:40
FileBackend\getFileSha1Base36
getFileSha1Base36(array $params)
Get a SHA-1 hash of the content of the file at a storage path in the backend.
FileBackend\ATTR_UNICODE_PATHS
const ATTR_UNICODE_PATHS
Definition: FileBackend.php:134
$args
if( $line===false) $args
Definition: mcc.php:124
FileBackend\getTopFileList
getTopFileList(array $params)
Same as FileBackend::getFileList() except only lists files that are immediately under the given direc...
Definition: FileBackend.php:1346
FileBackend\__construct
__construct(array $config)
Create a new backend instance from configuration.
Definition: FileBackend.php:193
FileBackend\hasFeatures
hasFeatures( $bitfield)
Check if the backend medium supports a field of extra features.
Definition: FileBackend.php:308
FileBackend\doQuickOperations
doQuickOperations(array $ops, array $opts=[])
Perform a set of independent file operations on some files.
Definition: FileBackend.php:707
FileBackend\quickCopy
quickCopy(array $params, array $opts=[])
Performs a single quick copy operation.
Definition: FileBackend.php:791
FileBackend\quickMove
quickMove(array $params, array $opts=[])
Performs a single quick move operation.
Definition: FileBackend.php:806
FileBackend\resetOutputBuffer
resetOutputBuffer()
Let's not reset output buffering during tests.
Definition: FileBackend.php:1720
MediaWiki\FileBackend\FSFile\TempFSFileFactory
Definition: TempFSFileFactory.php:10
FileBackend\$obResetFunc
callable $obResetFunc
Definition: FileBackend.php:125
FileBackend\lockFiles
lockFiles(array $paths, $type, $timeout=0)
Lock the files at the given storage paths in the backend.
Definition: FileBackend.php:1397
FileBackend\ATTR_METADATA
const ATTR_METADATA
Definition: FileBackend.php:133
FileBackend\quickDescribe
quickDescribe(array $params, array $opts=[])
Performs a single quick describe operation.
Definition: FileBackend.php:836
FileBackend\$streamMimeFunc
callable $streamMimeFunc
Definition: FileBackend.php:127
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
FileBackend\getLocalCopyMulti
getLocalCopyMulti(array $params)
Like getLocalCopy() except it takes an array of storage paths and yields an order preserved-map of st...
FileBackend\fileExists
fileExists(array $params)
Check if a file exists at a storage path in the backend.
FileBackend\preloadCache
preloadCache(array $paths)
Preload persistent file stat cache and property cache into in-process cache.
FileBackend\$parallelize
string $parallelize
When to do operations in parallel.
Definition: FileBackend.php:107
FileBackend\quickCreate
quickCreate(array $params, array $opts=[])
Performs a single quick create operation.
Definition: FileBackend.php:761
FileBackend\prepare
prepare(array $params)
Prepare a storage directory for usage.
Definition: FileBackend.php:872
FileBackend\$logger
LoggerInterface $logger
Definition: FileBackend.php:120
FileBackend\doSecure
doSecure(array $params)
FSFile
Class representing a non-directory file on the file system.
Definition: FSFile.php:32
FileBackend\doOperationsInternal
doOperationsInternal(array $ops, array $opts)
FileBackend\newStatus
newStatus(... $args)
Yields the result of the status wrapper callback on either:
Definition: FileBackend.php:1691
FileBackend\clearCache
clearCache(array $paths=null)
Invalidate any in-process file stat and property cache.
FileBackend\getFileList
getFileList(array $params)
Get an iterator to list all stored files under a storage directory.
FileBackend\getRootStoragePath
getRootStoragePath()
Get the root storage path of this backend.
Definition: FileBackend.php:1471
FileBackend\getScopedLocksForOps
getScopedLocksForOps(array $ops, StatusValue $status)
Get an array of scoped locks needed for a batch of file operations.
FileBackend\$name
string $name
Unique backend name.
Definition: FileBackend.php:98
FileBackend\clean
clean(array $params)
Delete a storage directory if it is empty.
Definition: FileBackend.php:965
FileBackend\getLocalCopy
getLocalCopy(array $params)
Get a local copy on disk of the file at a storage path in the backend.
Definition: FileBackend.php:1194
$path
$path
Definition: NoLocalSettings.php:25
FileBackend\getFileProps
getFileProps(array $params)
Get the properties of the content of the file at a storage path in the backend.
FileBackend\quickDelete
quickDelete(array $params, array $opts=[])
Performs a single quick delete operation.
Definition: FileBackend.php:821
FileBackend\isPathTraversalFree
static isPathTraversalFree( $path)
Check if a relative path has no directory traversals.
Definition: FileBackend.php:1620
FileBackend\getJournal
getJournal()
Get the file journal object for this backend.
Definition: FileBackend.php:1491
FileBackend\concatenate
concatenate(array $params)
Concatenate a list of storage files into a single file system file.
FileBackend\getTopDirectoryList
getTopDirectoryList(array $params)
Same as FileBackend::getDirectoryList() except only lists directories that are immediately under the ...
Definition: FileBackend.php:1304
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
FileBackend\$profiler
callable null $profiler
Definition: FileBackend.php:122
FileBackend\getLocalReference
getLocalReference(array $params)
Returns a file system file, identical in content to the file at a storage path.
Definition: FileBackend.php:1157
FileBackend\copy
copy(array $params, array $opts=[])
Performs a single copy operation.
Definition: FileBackend.php:544
FileBackend\$fileJournal
FileJournal $fileJournal
Definition: FileBackend.php:118
FileBackend\getFeatures
getFeatures()
Get the a bitfield of extra features supported by the backend medium.
Definition: FileBackend.php:297
FileBackend\getContainerStoragePath
getContainerStoragePath( $container)
Get the storage path for the given container for this backend.
Definition: FileBackend.php:1482
FileBackend\getFileContents
getFileContents(array $params)
Get the contents of a file at a storage path in the backend.
Definition: FileBackend.php:1022
FileBackend\getWikiId
getWikiId()
Alias to getDomainId()
Definition: FileBackend.php:269
FileBackend\scopedProfileSection
scopedProfileSection( $section)
Definition: FileBackend.php:1713
FileBackend\secure
secure(array $params)
Take measures to block web access to a storage directory and the container it belongs to.
Definition: FileBackend.php:904
FileBackend\parentStoragePath
static parentStoragePath( $storagePath)
Get the parent storage directory of a storage path.
Definition: FileBackend.php:1581
FileBackend\$domainId
string $domainId
Unique domain name.
Definition: FileBackend.php:101
FileBackend\isReadOnly
isReadOnly()
Check if this backend is read-only.
Definition: FileBackend.php:278
$type
$type
Definition: testCompression.php:52
FileBackend\makeContentDisposition
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
Definition: FileBackend.php:1633