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 
98 abstract class FileBackend implements LoggerAwareInterface {
100  protected $name;
101 
103  protected $domainId;
104 
106  protected $readOnly;
107 
109  protected $parallelize;
110 
112  protected $concurrency;
113 
115  protected $tmpFileFactory;
116 
118  protected $lockManager;
120  protected $fileJournal;
122  protected $logger;
124  protected $profiler;
125 
127  protected $obResetFunc;
129  protected $streamMimeFunc;
131  protected $statusWrapper;
132 
134  public const ATTR_HEADERS = 1; // files can be tagged with standard HTTP headers
135  public const ATTR_METADATA = 2; // files can be stored with metadata key/values
136  public const ATTR_UNICODE_PATHS = 4; // files can have Unicode paths (not just ASCII)
137 
139  protected const STAT_ABSENT = false;
140 
142  public const STAT_ERROR = null;
144  public const LIST_ERROR = null;
146  public const TEMPURL_ERROR = null;
148  public const EXISTENCE_ERROR = null;
149 
151  public const TIMESTAMP_FAIL = false;
153  public const CONTENT_FAIL = false;
155  public const XATTRS_FAIL = false;
157  public const SIZE_FAIL = false;
159  public const SHA1_FAIL = false;
160 
196  public function __construct( array $config ) {
197  if ( !array_key_exists( 'name', $config ) ) {
198  throw new InvalidArgumentException( 'Backend name not specified.' );
199  }
200  $this->name = $config['name'];
201  $this->domainId = $config['domainId'] // e.g. "my_wiki-en_"
202  ?? $config['wikiId'] // b/c alias
203  ?? null;
204  if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
205  throw new InvalidArgumentException( "Backend name '{$this->name}' is invalid." );
206  }
207  if ( !is_string( $this->domainId ) ) {
208  throw new InvalidArgumentException(
209  "Backend domain ID not provided for '{$this->name}'." );
210  }
211  $this->lockManager = $config['lockManager'] ?? new NullLockManager( [] );
212  $this->fileJournal = $config['fileJournal'] ?? new NullFileJournal;
213  $this->readOnly = isset( $config['readOnly'] )
214  ? (string)$config['readOnly']
215  : '';
216  $this->parallelize = isset( $config['parallelize'] )
217  ? (string)$config['parallelize']
218  : 'off';
219  $this->concurrency = isset( $config['concurrency'] )
220  ? (int)$config['concurrency']
221  : 50;
222  $this->obResetFunc = $config['obResetFunc'] ?? [ $this, 'resetOutputBuffer' ];
223  $this->streamMimeFunc = $config['streamMimeFunc'] ?? null;
224 
225  $this->profiler = $config['profiler'] ?? null;
226  if ( !is_callable( $this->profiler ) ) {
227  $this->profiler = null;
228  }
229  $this->logger = $config['logger'] ?? new NullLogger();
230  $this->statusWrapper = $config['statusWrapper'] ?? null;
231  // tmpDirectory gets precedence for backward compatibility
232  if ( isset( $config['tmpDirectory'] ) ) {
233  $this->tmpFileFactory = new TempFSFileFactory( $config['tmpDirectory'] );
234  } else {
235  $this->tmpFileFactory = $config['tmpFileFactory'] ?? new TempFSFileFactory();
236  }
237  }
238 
239  public function setLogger( LoggerInterface $logger ) {
240  $this->logger = $logger;
241  }
242 
251  final public function getName() {
252  return $this->name;
253  }
254 
261  final public function getDomainId() {
262  return $this->domainId;
263  }
264 
272  final public function getWikiId() {
273  return $this->getDomainId();
274  }
275 
281  final public function isReadOnly() {
282  return ( $this->readOnly != '' );
283  }
284 
290  final public function getReadOnlyReason() {
291  return ( $this->readOnly != '' ) ? $this->readOnly : false;
292  }
293 
301  public function getFeatures() {
303  }
304 
312  final public function hasFeatures( $bitfield ) {
313  return ( $this->getFeatures() & $bitfield ) === $bitfield;
314  }
315 
468  final public function doOperations( array $ops, array $opts = [] ) {
469  if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
470  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
471  }
472  if ( $ops === [] ) {
473  return $this->newStatus(); // nothing to do
474  }
475 
476  $ops = $this->resolveFSFileObjects( $ops );
477  if ( empty( $opts['force'] ) ) { // sanity
478  unset( $opts['nonLocking'] );
479  }
480 
482  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
483 
484  return $this->doOperationsInternal( $ops, $opts );
485  }
486 
493  abstract protected function doOperationsInternal( array $ops, array $opts );
494 
506  final public function doOperation( array $op, array $opts = [] ) {
507  return $this->doOperations( [ $op ], $opts );
508  }
509 
520  final public function create( array $params, array $opts = [] ) {
521  return $this->doOperation( [ 'op' => 'create' ] + $params, $opts );
522  }
523 
534  final public function store( array $params, array $opts = [] ) {
535  return $this->doOperation( [ 'op' => 'store' ] + $params, $opts );
536  }
537 
548  final public function copy( array $params, array $opts = [] ) {
549  return $this->doOperation( [ 'op' => 'copy' ] + $params, $opts );
550  }
551 
562  final public function move( array $params, array $opts = [] ) {
563  return $this->doOperation( [ 'op' => 'move' ] + $params, $opts );
564  }
565 
576  final public function delete( array $params, array $opts = [] ) {
577  return $this->doOperation( [ 'op' => 'delete' ] + $params, $opts );
578  }
579 
591  final public function describe( array $params, array $opts = [] ) {
592  return $this->doOperation( [ 'op' => 'describe' ] + $params, $opts );
593  }
594 
711  final public function doQuickOperations( array $ops, array $opts = [] ) {
712  if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
713  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
714  }
715  if ( $ops === [] ) {
716  return $this->newStatus(); // nothing to do
717  }
718 
719  $ops = $this->resolveFSFileObjects( $ops );
720  foreach ( $ops as &$op ) {
721  $op['overwrite'] = true; // avoids RTTs in key/value stores
722  }
723 
725  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
726 
727  return $this->doQuickOperationsInternal( $ops, $opts );
728  }
729 
737  abstract protected function doQuickOperationsInternal( array $ops, array $opts );
738 
750  final public function doQuickOperation( array $op, array $opts = [] ) {
751  return $this->doQuickOperations( [ $op ], $opts );
752  }
753 
765  final public function quickCreate( array $params, array $opts = [] ) {
766  return $this->doQuickOperation( [ 'op' => 'create' ] + $params, $opts );
767  }
768 
780  final public function quickStore( array $params, array $opts = [] ) {
781  return $this->doQuickOperation( [ 'op' => 'store' ] + $params, $opts );
782  }
783 
795  final public function quickCopy( array $params, array $opts = [] ) {
796  return $this->doQuickOperation( [ 'op' => 'copy' ] + $params, $opts );
797  }
798 
810  final public function quickMove( array $params, array $opts = [] ) {
811  return $this->doQuickOperation( [ 'op' => 'move' ] + $params, $opts );
812  }
813 
825  final public function quickDelete( array $params, array $opts = [] ) {
826  return $this->doQuickOperation( [ 'op' => 'delete' ] + $params, $opts );
827  }
828 
840  final public function quickDescribe( array $params, array $opts = [] ) {
841  return $this->doQuickOperation( [ 'op' => 'describe' ] + $params, $opts );
842  }
843 
856  abstract public function concatenate( array $params );
857 
876  final public function prepare( array $params ) {
877  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
878  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
879  }
881  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
882  return $this->doPrepare( $params );
883  }
884 
890  abstract protected function doPrepare( array $params );
891 
908  final public function secure( array $params ) {
909  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
910  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
911  }
913  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
914  return $this->doSecure( $params );
915  }
916 
922  abstract protected function doSecure( array $params );
923 
942  final public function publish( array $params ) {
943  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
944  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
945  }
947  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
948  return $this->doPublish( $params );
949  }
950 
956  abstract protected function doPublish( array $params );
957 
969  final public function clean( array $params ) {
970  if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
971  return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly );
972  }
974  $scope = ScopedCallback::newScopedIgnoreUserAbort(); // try to ignore client aborts
975  return $this->doClean( $params );
976  }
977 
983  abstract protected function doClean( array $params );
984 
1001  abstract public function fileExists( array $params );
1002 
1013  abstract public function getFileTimestamp( array $params );
1014 
1026  final public function getFileContents( array $params ) {
1027  $contents = $this->getFileContentsMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1028 
1029  return $contents[$params['src']];
1030  }
1031 
1045  abstract public function getFileContentsMulti( array $params );
1046 
1067  abstract public function getFileXAttributes( array $params );
1068 
1079  abstract public function getFileSize( array $params );
1080 
1097  abstract public function getFileStat( array $params );
1098 
1109  abstract public function getFileSha1Base36( array $params );
1110 
1120  abstract public function getFileProps( array $params );
1121 
1141  abstract public function streamFile( array $params );
1142 
1161  final public function getLocalReference( array $params ) {
1162  $fsFiles = $this->getLocalReferenceMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1163 
1164  return $fsFiles[$params['src']];
1165  }
1166 
1184  abstract public function getLocalReferenceMulti( array $params );
1185 
1198  final public function getLocalCopy( array $params ) {
1199  $tmpFiles = $this->getLocalCopyMulti( [ 'srcs' => [ $params['src'] ] ] + $params );
1200 
1201  return $tmpFiles[$params['src']];
1202  }
1203 
1219  abstract public function getLocalCopyMulti( array $params );
1220 
1239  abstract public function getFileHttpUrl( array $params );
1240 
1266  abstract public function directoryExists( array $params );
1267 
1290  abstract public function getDirectoryList( array $params );
1291 
1308  final public function getTopDirectoryList( array $params ) {
1309  return $this->getDirectoryList( [ 'topOnly' => true ] + $params );
1310  }
1311 
1332  abstract public function getFileList( array $params );
1333 
1350  final public function getTopFileList( array $params ) {
1351  return $this->getFileList( [ 'topOnly' => true ] + $params );
1352  }
1353 
1362  abstract public function preloadCache( array $paths );
1363 
1372  abstract public function clearCache( array $paths = null );
1373 
1388  abstract public function preloadFileStat( array $params );
1389 
1401  final public function lockFiles( array $paths, $type, $timeout = 0 ) {
1402  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1403 
1404  return $this->wrapStatus( $this->lockManager->lock( $paths, $type, $timeout ) );
1405  }
1406 
1414  final public function unlockFiles( array $paths, $type ) {
1415  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1416 
1417  return $this->wrapStatus( $this->lockManager->unlock( $paths, $type ) );
1418  }
1419 
1436  final public function getScopedFileLocks(
1437  array $paths, $type, StatusValue $status, $timeout = 0
1438  ) {
1439  if ( $type === 'mixed' ) {
1440  foreach ( $paths as &$typePaths ) {
1441  $typePaths = array_map( 'FileBackend::normalizeStoragePath', $typePaths );
1442  }
1443  } else {
1444  $paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
1445  }
1446 
1447  return ScopedLock::factory( $this->lockManager, $paths, $type, $status, $timeout );
1448  }
1449 
1466  abstract public function getScopedLocksForOps( array $ops, StatusValue $status );
1467 
1475  final public function getRootStoragePath() {
1476  return "mwstore://{$this->name}";
1477  }
1478 
1486  final public function getContainerStoragePath( $container ) {
1487  return $this->getRootStoragePath() . "/{$container}";
1488  }
1489 
1495  final public function getJournal() {
1496  return $this->fileJournal;
1497  }
1498 
1508  protected function resolveFSFileObjects( array $ops ) {
1509  foreach ( $ops as &$op ) {
1510  $src = $op['src'] ?? null;
1511  if ( $src instanceof FSFile ) {
1512  $op['srcRef'] = $src;
1513  $op['src'] = $src->getPath();
1514  }
1515  }
1516  unset( $op );
1517 
1518  return $ops;
1519  }
1520 
1528  final public static function isStoragePath( $path ) {
1529  return ( strpos( $path, 'mwstore://' ) === 0 );
1530  }
1531 
1540  final public static function splitStoragePath( $storagePath ) {
1541  if ( self::isStoragePath( $storagePath ) ) {
1542  // Remove the "mwstore://" prefix and split the path
1543  $parts = explode( '/', substr( $storagePath, 10 ), 3 );
1544  if ( count( $parts ) >= 2 && $parts[0] != '' && $parts[1] != '' ) {
1545  if ( count( $parts ) == 3 ) {
1546  return $parts; // e.g. "backend/container/path"
1547  } else {
1548  return [ $parts[0], $parts[1], '' ]; // e.g. "backend/container"
1549  }
1550  }
1551  }
1552 
1553  return [ null, null, null ];
1554  }
1555 
1563  final public static function normalizeStoragePath( $storagePath ) {
1564  list( $backend, $container, $relPath ) = self::splitStoragePath( $storagePath );
1565  if ( $relPath !== null ) { // must be for this backend
1566  $relPath = self::normalizeContainerPath( $relPath );
1567  if ( $relPath !== null ) {
1568  return ( $relPath != '' )
1569  ? "mwstore://{$backend}/{$container}/{$relPath}"
1570  : "mwstore://{$backend}/{$container}";
1571  }
1572  }
1573 
1574  return null;
1575  }
1576 
1585  final public static function parentStoragePath( $storagePath ) {
1586  // XXX dirname() depends on platform and locale! If nothing enforces that the storage path
1587  // doesn't contain characters like '\', behavior can vary by platform. We should use
1588  // explode() instead.
1589  $storagePath = dirname( $storagePath );
1590  list( , , $rel ) = self::splitStoragePath( $storagePath );
1591 
1592  return ( $rel === null ) ? null : $storagePath;
1593  }
1594 
1602  final public static function extensionFromPath( $path, $case = 'lowercase' ) {
1603  // This will treat a string starting with . as not having an extension, but store paths have
1604  // to start with 'mwstore://', so "garbage in, garbage out".
1605  $i = strrpos( $path, '.' );
1606  $ext = $i ? substr( $path, $i + 1 ) : '';
1607 
1608  if ( $case === 'lowercase' ) {
1609  $ext = strtolower( $ext );
1610  } elseif ( $case === 'uppercase' ) {
1611  $ext = strtoupper( $ext );
1612  }
1613 
1614  return $ext;
1615  }
1616 
1624  final public static function isPathTraversalFree( $path ) {
1625  return ( self::normalizeContainerPath( $path ) !== null );
1626  }
1627 
1637  final public static function makeContentDisposition( $type, $filename = '' ) {
1638  $parts = [];
1639 
1640  $type = strtolower( $type );
1641  if ( !in_array( $type, [ 'inline', 'attachment' ] ) ) {
1642  throw new InvalidArgumentException( "Invalid Content-Disposition type '$type'." );
1643  }
1644  $parts[] = $type;
1645 
1646  if ( strlen( $filename ) ) {
1647  $parts[] = "filename*=UTF-8''" . rawurlencode( basename( $filename ) );
1648  }
1649 
1650  return implode( ';', $parts );
1651  }
1652 
1663  final protected static function normalizeContainerPath( $path ) {
1664  // Normalize directory separators
1665  $path = strtr( $path, '\\', '/' );
1666  // Collapse any consecutive directory separators
1667  $path = preg_replace( '![/]{2,}!', '/', $path );
1668  // Remove any leading directory separator
1669  $path = ltrim( $path, '/' );
1670  // Use the same traversal protection as Title::secureAndSplit()
1671  if ( strpos( $path, '.' ) !== false ) {
1672  if (
1673  $path === '.' ||
1674  $path === '..' ||
1675  strpos( $path, './' ) === 0 ||
1676  strpos( $path, '../' ) === 0 ||
1677  strpos( $path, '/./' ) !== false ||
1678  strpos( $path, '/../' ) !== false
1679  ) {
1680  return null;
1681  }
1682  }
1683 
1684  return $path;
1685  }
1686 
1695  final protected function newStatus( ...$args ) {
1696  if ( count( $args ) ) {
1697  $sv = StatusValue::newFatal( ...$args );
1698  } else {
1699  $sv = StatusValue::newGood();
1700  }
1701 
1702  return $this->wrapStatus( $sv );
1703  }
1704 
1709  final protected function wrapStatus( StatusValue $sv ) {
1710  return $this->statusWrapper ? call_user_func( $this->statusWrapper, $sv ) : $sv;
1711  }
1712 
1717  protected function scopedProfileSection( $section ) {
1718  return $this->profiler ? ( $this->profiler )( $section ) : null;
1719  }
1720 
1724  protected function resetOutputBuffer() {
1725  // XXX According to documentation, ob_get_status() always returns a non-empty array and this
1726  // condition will always be true
1727  while ( ob_get_status() ) {
1728  if ( !ob_end_clean() ) {
1729  // Could not remove output buffer handler; abort now
1730  // to avoid getting in some kind of infinite loop.
1731  break;
1732  }
1733  }
1734  }
1735 }
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:1540
LockManager
Class for handling resource locking.
Definition: LockManager.php:48
FileBackend\$tmpFileFactory
TempFSFileFactory $tmpFileFactory
Definition: FileBackend.php:115
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:468
FileBackend\$lockManager
LockManager $lockManager
Definition: FileBackend.php:118
StatusValue
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: StatusValue.php:43
FileBackend\normalizeContainerPath
static normalizeContainerPath( $path)
Validate and normalize a relative storage path.
Definition: FileBackend.php:1663
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
FileBackend\quickStore
quickStore(array $params, array $opts=[])
Performs a single quick store operation.
Definition: FileBackend.php:780
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:98
FileBackend\describe
describe(array $params, array $opts=[])
Performs a single describe operation.
Definition: FileBackend.php:591
FileBackend\unlockFiles
unlockFiles(array $paths, $type)
Unlock the files at the given storage paths in the backend.
Definition: FileBackend.php:1414
FileBackend\doPublish
doPublish(array $params)
FileBackend\ATTR_HEADERS
const ATTR_HEADERS
Bitfield flags for supported features.
Definition: FileBackend.php:134
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:131
FileBackend\publish
publish(array $params)
Remove measures to block web access to a storage directory and the container it belongs to.
Definition: FileBackend.php:942
FileBackend\wrapStatus
wrapStatus(StatusValue $sv)
Definition: FileBackend.php:1709
FileBackend\resolveFSFileObjects
resolveFSFileObjects(array $ops)
Convert FSFile 'src' paths to string paths (with an 'srcRef' field set to the FSFile)
Definition: FileBackend.php:1508
FileBackend\getName
getName()
Get the unique backend name.
Definition: FileBackend.php:251
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:1436
FileBackend\getDomainId
getDomainId()
Get the domain identifier used for this backend (possibly empty).
Definition: FileBackend.php:261
FileBackend\doQuickOperationsInternal
doQuickOperationsInternal(array $ops, array $opts)
FileBackend\$readOnly
string $readOnly
Read-only explanation message.
Definition: FileBackend.php:106
FileBackend\extensionFromPath
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
Definition: FileBackend.php:1602
FileBackend\normalizeStoragePath
static normalizeStoragePath( $storagePath)
Normalize a storage path by cleaning up directory separators.
Definition: FileBackend.php:1563
FileBackend\getReadOnlyReason
getReadOnlyReason()
Get an explanatory message if this backend is read-only.
Definition: FileBackend.php:290
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:750
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:239
FileBackend\move
move(array $params, array $opts=[])
Performs a single move operation.
Definition: FileBackend.php:562
FileBackend\store
store(array $params, array $opts=[])
Performs a single store operation.
Definition: FileBackend.php:534
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:506
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:1528
FileBackend\$concurrency
int $concurrency
How many operations can be done in parallel.
Definition: FileBackend.php:112
FileBackend\create
create(array $params, array $opts=[])
Performs a single create operation.
Definition: FileBackend.php:520
FileJournal
Class for handling file operation journaling.
Definition: FileJournal.php:41
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:136
$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:1350
FileBackend\__construct
__construct(array $config)
Create a new backend instance from configuration.
Definition: FileBackend.php:196
FileBackend\hasFeatures
hasFeatures( $bitfield)
Check if the backend medium supports a field of extra features.
Definition: FileBackend.php:312
FileBackend\doQuickOperations
doQuickOperations(array $ops, array $opts=[])
Perform a set of independent file operations on some files.
Definition: FileBackend.php:711
FileBackend\quickCopy
quickCopy(array $params, array $opts=[])
Performs a single quick copy operation.
Definition: FileBackend.php:795
FileBackend\quickMove
quickMove(array $params, array $opts=[])
Performs a single quick move operation.
Definition: FileBackend.php:810
FileBackend\resetOutputBuffer
resetOutputBuffer()
Let's not reset output buffering during tests.
Definition: FileBackend.php:1724
MediaWiki\FileBackend\FSFile\TempFSFileFactory
Definition: TempFSFileFactory.php:10
FileBackend\$obResetFunc
callable $obResetFunc
Definition: FileBackend.php:127
FileBackend\lockFiles
lockFiles(array $paths, $type, $timeout=0)
Lock the files at the given storage paths in the backend.
Definition: FileBackend.php:1401
FileBackend\ATTR_METADATA
const ATTR_METADATA
Definition: FileBackend.php:135
FileBackend\quickDescribe
quickDescribe(array $params, array $opts=[])
Performs a single quick describe operation.
Definition: FileBackend.php:840
FileBackend\$streamMimeFunc
callable $streamMimeFunc
Definition: FileBackend.php:129
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
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:109
FileBackend\quickCreate
quickCreate(array $params, array $opts=[])
Performs a single quick create operation.
Definition: FileBackend.php:765
FileBackend\prepare
prepare(array $params)
Prepare a storage directory for usage.
Definition: FileBackend.php:876
FileBackend\$logger
LoggerInterface $logger
Definition: FileBackend.php:122
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:1695
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:1475
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:100
FileBackend\clean
clean(array $params)
Delete a storage directory if it is empty.
Definition: FileBackend.php:969
FileBackend\getLocalCopy
getLocalCopy(array $params)
Get a local copy on disk of the file at a storage path in the backend.
Definition: FileBackend.php:1198
$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:825
FileBackend\isPathTraversalFree
static isPathTraversalFree( $path)
Check if a relative path has no directory traversals.
Definition: FileBackend.php:1624
FileBackend\getJournal
getJournal()
Get the file journal object for this backend.
Definition: FileBackend.php:1495
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:1308
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
FileBackend\$profiler
callable null $profiler
Definition: FileBackend.php:124
FileBackend\getLocalReference
getLocalReference(array $params)
Returns a file system file, identical in content to the file at a storage path.
Definition: FileBackend.php:1161
FileBackend\copy
copy(array $params, array $opts=[])
Performs a single copy operation.
Definition: FileBackend.php:548
FileBackend\$fileJournal
FileJournal $fileJournal
Definition: FileBackend.php:120
FileBackend\getFeatures
getFeatures()
Get the a bitfield of extra features supported by the backend medium Stable to override.
Definition: FileBackend.php:301
FileBackend\getContainerStoragePath
getContainerStoragePath( $container)
Get the storage path for the given container for this backend.
Definition: FileBackend.php:1486
FileBackend\getFileContents
getFileContents(array $params)
Get the contents of a file at a storage path in the backend.
Definition: FileBackend.php:1026
FileBackend\getWikiId
getWikiId()
Alias to getDomainId()
Definition: FileBackend.php:272
FileBackend\scopedProfileSection
scopedProfileSection( $section)
Definition: FileBackend.php:1717
FileBackend\secure
secure(array $params)
Take measures to block web access to a storage directory and the container it belongs to.
Definition: FileBackend.php:908
FileBackend\parentStoragePath
static parentStoragePath( $storagePath)
Get the parent storage directory of a storage path.
Definition: FileBackend.php:1585
FileBackend\$domainId
string $domainId
Unique domain name.
Definition: FileBackend.php:103
FileBackend\isReadOnly
isReadOnly()
Check if this backend is read-only.
Definition: FileBackend.php:281
$type
$type
Definition: testCompression.php:52
FileBackend\makeContentDisposition
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
Definition: FileBackend.php:1637