9use InvalidArgumentException;
17use Wikimedia\Mime\MimeAnalyzer;
55privateconst MAX_CACHE_SIZE = 500;
77 MimeAnalyzer $mimeAnalyzer
81 $this->cache =
newMapCacheLRU( self::MAX_CACHE_SIZE );
83 $this->mimeAnalyzer = $mimeAnalyzer;
105if ( !is_array( $options ) ) {
107 $options = [
'time' => $options ];
109if ( isset( $options[
'bypassCache'] ) ) {
110 $options[
'latest'] = $options[
'bypassCache'];
// b/c 112if ( isset( $options[
'time'] ) && $options[
'time'] !==
false ) {
113 $options[
'time'] =
wfTimestamp( TS_MW, $options[
'time'] );
115 $options[
'time'] =
false;
118if ( !$this->reposInitialised ) {
122 $title = File::normalizeTitle( $title );
128 $dbkey = $title->getDBkey();
129 $timeKey = is_string( $options[
'time'] ) ? $options[
'time'] :
'';
130if ( empty( $options[
'ignoreRedirect'] )
131 && empty( $options[
'private'] )
132 && empty( $options[
'latest'] )
134if ( $this->cache->hasField( $dbkey, $timeKey, 60 ) ) {
135return $this->cache->getField( $dbkey, $timeKey );
142 # Check the local repo 143 $image = $this->localRepo->findFile( $title, $options );
145 # Check the foreign repos 147foreach ( $this->foreignRepos as $repo ) {
148 $image = $repo->findFile( $title, $options );
155 $image = $image instanceof
File ? $image :
false;
// type check 156 # Cache file existence or non-existence 157if ( $useCache && ( !$image || $image->isCacheable() ) ) {
158 $this->cache->setField( $dbkey, $timeKey, $image );
181publicfunctionfindFiles( array $inputItems, $flags = 0 ) {
182if ( !$this->reposInitialised ) {
187foreach ( $inputItems as $item ) {
188if ( !is_array( $item ) ) {
189 $item = [
'title' => $item ];
191 $item[
'title'] = File::normalizeTitle( $item[
'title'] );
192if ( $item[
'title'] ) {
193 $items[$item[
'title']->getDBkey()] = $item;
197 $images = $this->localRepo->findFiles( $items, $flags );
199foreach ( $this->foreignRepos as $repo ) {
200// Remove found files from $items 201 $items = array_diff_key( $items, $images );
202 $images = array_merge( $images, $repo->findFiles( $items, $flags ) );
214if ( !$this->reposInitialised ) {
218 $title = File::normalizeTitle( $title );
220 $redir = $this->localRepo->checkRedirect( $title );
225foreach ( $this->foreignRepos as $repo ) {
226 $redir = $repo->checkRedirect( $title );
244if ( !$this->reposInitialised ) {
248 $file = $this->localRepo->findFileFromKey( $hash, $options );
250foreach ( $this->foreignRepos as $repo ) {
251 $file = $repo->findFileFromKey( $hash, $options );
268if ( !$this->reposInitialised ) {
272 $result = $this->localRepo->findBySha1( $hash );
273foreach ( $this->foreignRepos as $repo ) {
274 $result = array_merge( $result, $repo->findBySha1( $hash ) );
288if ( !$this->reposInitialised ) {
292 $result = $this->localRepo->findBySha1s( $hashes );
293foreach ( $this->foreignRepos as $repo ) {
294 $result = array_merge_recursive( $result, $repo->findBySha1s( $hashes ) );
296// sort the merged (and presorted) sublist of each hash 297foreach ( $result as $hash => $files ) {
310if ( !$this->reposInitialised ) {
313if ( $index ===
'local' ) {
316return $this->foreignRepos[$index] ??
false;
325if ( !$this->reposInitialised ) {
328foreach ( $this->foreignRepos as $repo ) {
329if ( $repo->name == $name ) {
344// @phan-suppress-next-line PhanTypeMismatchReturnSuperType 345return $this->
getRepo(
'local' );
357if ( !$this->reposInitialised ) {
360foreach ( $this->foreignRepos as $repo ) {
361if ( $callback( $repo, ...$params ) ) {
374if ( !$this->reposInitialised ) {
384if ( $this->reposInitialised ) {
387 $this->reposInitialised =
true;
389 $this->localRepo = $this->
newRepo( $this->localInfo );
390 $this->foreignRepos = [];
391foreach ( $this->foreignInfo as $key => $info ) {
392 $this->foreignRepos[$key] = $this->
newRepo( $info );
403return $this->
newRepo( $info + $this->localInfo );
415 $class = $info[
'class'];
419returnnew $class( $info );
427privatefunction splitVirtualUrl(
$url ) {
428if ( !str_starts_with(
$url,
'mwrepo://' ) ) {
429thrownew InvalidArgumentException( __METHOD__ .
': unknown protocol' );
432 $bits = explode(
'/', substr(
$url, 9 ), 3 );
433if ( count( $bits ) != 3 ) {
434thrownew InvalidArgumentException( __METHOD__ .
": invalid mwrepo URL: $url" );
446 [ $repoName,
/* $zone */,
/* $rel */ ] = $this->splitVirtualUrl( $fileName );
447if ( $repoName ===
'' ) {
450 $repo = $this->
getRepo( $repoName );
452return $repo->getFileProps( $fileName );
456return $mwProps->getPropsFromPath( $fileName,
true );
465if ( $title ==
null ) {
466 $this->cache->clear();
467 } elseif ( is_string( $title ) ) {
468 $this->cache->clear( $title );
470 $this->cache->clear( $title->getDBkey() );
476class_alias( RepoGroup::class,
'RepoGroup' );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
MimeMagic helper wrapper.
Base class for file repositories.
static isVirtualUrl( $url)
Determine if a string is an mwrepo:// URL.
Implements some public methods and some protected utility functions which are required by multiple ch...
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Prioritized list of file repositories.
getRepo( $index)
Get the repo instance with a given key.
forEachForeignRepo( $callback, $params=[])
Call a function for each foreign repo, with the repo object as the first parameter.
clearCache( $title=null)
Clear RepoGroup process cache used for finding a file.
findBySha1s(array $hashes)
Find all instances of files with this keys.
newRepo( $info)
Create a repo class based on an info structure @template T of FileRepo.
findFiles(array $inputItems, $flags=0)
Search repositories for many files at once.
checkRedirect( $title)
Interface for FileRepo::checkRedirect()
findFileFromKey( $hash, $options=[])
Find an instance of the file with this key, created at the specified time Returns false if the file d...
newCustomLocalRepo( $info=[])
Create a local repo with the specified option overrides.
findFile( $title, $options=[])
Search repositories for an image.
initialiseRepos()
Initialise the $repos array.
hasForeignRepos()
Does the installation have any foreign repos set up?
getRepoByName( $name)
Get the repo instance by its name.
getLocalRepo()
Get the local repository, i.e.
findBySha1( $hash)
Find all instances of files with this key.
__construct( $localInfo, $foreignInfo, WANObjectCache $wanCache, MimeAnalyzer $mimeAnalyzer)
Construct a group of file repositories.
Represents a title within MediaWiki.
static compare( $a, $b)
Callback for usort() to do title sorts by (namespace, title)
Base class for all file backend classes (including multi-write backends).
Store key-value entries in a size-limited in-memory LRU cache.
Multi-datacenter aware caching interface.
Represents the target of a wiki link.
Interface for objects (potentially) representing an editable wiki page.