52 parent::__construct( $info );
55 && $info[
'storageLayout'] ===
'sha1';
59 'backend' => $this->backend,
60 'repoName' => $this->name,
72 if ( isset( $row->img_name ) ) {
73 return call_user_func( $this->fileFromRowFactory, $row, $this );
74 } elseif ( isset( $row->oi_name ) ) {
75 return call_user_func( $this->oldFileFromRowFactory, $row, $this );
77 throw new MWException( __METHOD__ .
': invalid row' );
102 wfDebug( __METHOD__ .
": skipped because storage uses sha1 paths\n" );
103 return Status::newGood();
110 $storageKeys = array_unique( $storageKeys );
111 foreach ( $storageKeys as $key ) {
113 $path =
"$root/$hashPath$key";
114 $dbw->startAtomic( __METHOD__ );
119 if ( !$deleted && !$hidden ) {
120 wfDebug( __METHOD__ .
": deleting $key\n" );
121 $op = [
'op' =>
'delete',
'src' =>
$path ];
123 $status->error(
'undelete-cleanup-error',
$path );
124 $status->failCount++;
127 wfDebug( __METHOD__ .
": $key still in use\n" );
128 $status->successCount++;
130 $dbw->endAtomic( __METHOD__ );
144 $options = ( $lock ===
'lock' ) ? [
'FOR UPDATE' ] : [];
148 return (
bool)$dbw->selectField(
'filearchive',
'1',
149 [
'fa_storage_group' =>
'deleted',
'fa_storage_key' => $key ],
162 $options = ( $lock ===
'lock' ) ? [
'FOR UPDATE' ] : [];
169 return (
bool)$dbw->selectField(
'oldimage',
'1',
170 [
'oi_sha1' => $sha1,
171 'oi_archive_name ' . $dbw->buildLike( $dbw->anyString(),
".$ext" ),
184 $sha1 = strtok( $key,
'.' );
185 if ( is_string( $sha1 ) && strlen( $sha1 ) === 32 && $sha1[0] ===
'0' ) {
186 $sha1 = substr( $sha1, 1 );
201 if ( $memcKey ===
false ) {
208 $method = __METHOD__;
209 $redirDbKey = $this->wanCache->getWithSetCallback(
212 function ( $oldValue, &$ttl, array &$setOpts ) use ( $method,
$title ) {
215 $setOpts += Database::getCacheSetOptions(
$dbr );
217 $row =
$dbr->selectRow(
218 [
'page',
'redirect' ],
219 [
'rd_namespace',
'rd_title' ],
221 'page_namespace' =>
$title->getNamespace(),
222 'page_title' =>
$title->getDBkey(),
228 return ( $row && $row->rd_namespace ==
NS_FILE )
229 ? Title::makeTitle( $row->rd_namespace, $row->rd_title )->getDBkey()
232 [
'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
236 if ( $redirDbKey !==
' ' && strval( $redirDbKey ) !==
'' ) {
238 return Title::newFromText( $redirDbKey,
NS_FILE );
248 foreach ( $items as $item ) {
249 if ( is_array( $item ) ) {
252 $searchSet[
$title->getDBkey()] = $item;
257 $searchSet[
$title->getDBkey()] = [];
262 $fileMatchesSearch =
function (
File $file, array $search ) {
264 $user = ( !empty( $search[
'private'] ) && $search[
'private'] instanceof
User )
271 ( empty( $search[
'time'] ) && !
$file->isOld() ) ||
272 ( !empty( $search[
'time'] ) && $search[
'time'] ===
$file->getTimestamp() )
280 use ( $fileMatchesSearch, $flags )
282 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
284 foreach ( $res as $row ) {
288 $dbKeysLook = [ strtr(
$file->getName(),
' ',
'_' ) ];
289 if ( !empty( $info[
'initialCapital'] ) ) {
291 $dbKeysLook[] = $contLang->lcfirst(
$file->getName() );
293 foreach ( $dbKeysLook as $dbKey ) {
294 if ( isset( $searchSet[$dbKey] )
295 && $fileMatchesSearch(
$file, $searchSet[$dbKey] )
298 ? [
'title' => $dbKey,
'timestamp' =>
$file->getTimestamp() ]
300 unset( $searchSet[$dbKey] );
310 foreach ( array_keys( $searchSet ) as $dbKey ) {
314 if ( count( $imgNames ) ) {
316 $res =
$dbr->select( $fileQuery[
'tables'], $fileQuery[
'fields'], [
'img_name' => $imgNames ],
317 __METHOD__, [], $fileQuery[
'joins'] );
318 $applyMatchingFiles(
$res, $searchSet, $finalFiles );
323 foreach ( $searchSet as $dbKey => $search ) {
324 if ( isset( $search[
'time'] ) ) {
325 $oiConds[] =
$dbr->makeList(
328 'oi_timestamp' =>
$dbr->timestamp( $search[
'time'] )
335 if ( count( $oiConds ) ) {
337 $res =
$dbr->select( $fileQuery[
'tables'], $fileQuery[
'fields'],
339 __METHOD__, [], $fileQuery[
'joins'] );
340 $applyMatchingFiles(
$res, $searchSet, $finalFiles );
344 foreach ( $searchSet as $dbKey => $search ) {
345 if ( !empty( $search[
'ignoreRedirect'] ) ) {
352 if ( $redir && $redir->getNamespace() ==
NS_FILE ) {
354 if (
$file && $fileMatchesSearch(
$file, $search ) ) {
357 $finalFiles[$dbKey] = [
358 'title' =>
$file->getTitle()->getDBkey(),
359 'timestamp' =>
$file->getTimestamp()
362 $finalFiles[$dbKey] =
$file;
382 $fileQuery[
'tables'],
383 $fileQuery[
'fields'],
384 [
'img_sha1' => $hash ],
386 [
'ORDER BY' =>
'img_name' ],
391 foreach (
$res as $row ) {
416 $fileQuery[
'tables'],
417 $fileQuery[
'fields'],
420 [
'ORDER BY' =>
'img_name' ],
425 foreach (
$res as $row ) {
442 $selectOptions = [
'ORDER BY' =>
'img_name',
'LIMIT' => intval( $limit ) ];
448 $fileQuery[
'tables'],
449 $fileQuery[
'fields'],
450 'img_name ' .
$dbr->buildLike( $prefix,
$dbr->anyString() ),
458 foreach (
$res as $row ) {
496 return function ( $index ) {
509 $args = func_get_args();
511 return $this->wanCache->makeKey( ...
$args );
523 $this->
getMasterDB()->onTransactionPreCommitOrIdle(
524 function () use ( $key ) {
525 $this->wanCache->delete( $key );
541 return array_merge( parent::getInfo(), [
546 public function store( $srcPath, $dstZone, $dstRel, $flags = 0 ) {
572 public function delete( $srcRel, $archiveRel ) {
591 wfDebug( __METHOD__ .
": skipped because storage uses sha1 paths\n" );
592 return Status::newGood();
594 return parent::$function( ...
$args );
$wgFavicon
The URL path of the shortcut icon.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Proxy backend that manages file layout rewriting for FileRepo.
doOperation(array $op, array $opts=[])
Same as doOperations() except it takes a single operation.
Base class for file repositories.
getLocalCacheKey()
Get a key for this repo in the local cache domain.
assertWritableRepo()
Throw an exception if this repo is read-only by design.
newGood( $value=null)
Create a new good result.
hasSha1Storage()
Returns whether or not storage is SHA-1 based.
getZonePath( $zone)
Get the storage path corresponding to one of the zones.
getDeletedHashPath( $key)
Get a relative path for a deletion archive key, e.g.
newFile( $title, $time=false)
Create a new File object from the local repository.
getNameFromTitle(Title $title)
Get the name of a file from its title object.
Implements some public methods and some protected utility functions which are required by multiple ch...
static normalizeTitle( $title, $exception=false)
Given a string or Title object return either a valid Title object with namespace NS_FILE or null.
static normalizeExtension( $extension)
Normalize a file extension to the common form, making it lowercase and checking some synonyms,...
static getQueryInfo(array $options=[])
Return the tables, fields, and join conditions to be selected to create a new localfile object.
A repository that stores files in the local filesystem and registers them in the wiki's own database.
skipWriteOperationIfSha1( $function, array $args)
Skips the write operation if storage is sha1-based, executes it normally otherwise.
getDBFactory()
Get a callback to get a DB handle given an index (DB_REPLICA/DB_MASTER)
getInfo()
Return information about the repository.
deletedFileHasKey( $key, $lock=null)
Check if a deleted (filearchive) file has this sha1 key.
callable $oldFileFactoryKey
cleanupBatch(array $files, $flags=0)
Deletes a batch of files.
publishBatch(array $ntuples, $flags=0)
Publish a batch of files.
findFiles(array $items, $flags=0)
Find many files at once.
findFilesByPrefix( $prefix, $limit)
Return an array of files where the name starts with $prefix.
findBySha1s(array $hashes)
Get an array of arrays or iterators of file objects for files that have the given SHA-1 content hashe...
callable $oldFileFromRowFactory
cleanupDeletedBatch(array $storageKeys)
Delete files in the deleted directory if they are not referenced in the filearchive table.
invalidateImageRedirect(Title $title)
Invalidates image redirect cache related to that image.
checkRedirect(Title $title)
Checks if there is a redirect named as $title.
getReplicaDB()
Get a connection to the replica DB.
store( $srcPath, $dstZone, $dstRel, $flags=0)
Store a file to a given destination.
publish( $src, $dstRel, $archiveRel, $flags=0, array $options=[])
Copy or move a file either from a storage path, virtual URL, or file system path, into this repositor...
getMasterDB()
Get a connection to the master DB.
getSlaveDB()
Alias for getReplicaDB()
storeBatch(array $triplets, $flags=0)
Store a batch of files.
callable $fileFromRowFactory
__construct(array $info=null)
deleteBatch(array $sourceDestPairs)
Move a group of files to the deletion archive.
hiddenFileHasKey( $key, $lock=null)
Check if a hidden (revision delete) file has this sha1 key.
getSharedCacheKey()
Get a key on the primary cache for this repository.
static getHashFromKey( $key)
Gets the SHA1 hash from a storage key.
newFromArchiveName( $title, $archiveName)
findBySha1( $hash)
Get an array or iterator of file objects for files that have a given SHA-1 content hash.
static newFromArchiveName( $title, $repo, $archiveName)
static getQueryInfo(array $options=[])
Return the tables, fields, and join conditions to be selected to create a new oldlocalfile object.
Represents a title within MediaWiki.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!is_readable( $file)) $ext