41 protected $reposInitialised =
false;
53 private const MAX_CACHE_SIZE = 500;
56 private $mimeAnalyzer;
74 MimeAnalyzer $mimeAnalyzer
76 $this->localInfo = $localInfo;
77 $this->foreignInfo = $foreignInfo;
78 $this->cache =
new MapCacheLRU( self::MAX_CACHE_SIZE );
79 $this->wanCache = $wanCache;
80 $this->mimeAnalyzer = $mimeAnalyzer;
101 public function findFile( $title, $options = [] ) {
102 if ( !is_array( $options ) ) {
104 $options = [
'time' => $options ];
106 if ( isset( $options[
'bypassCache'] ) ) {
107 $options[
'latest'] = $options[
'bypassCache'];
109 if ( isset( $options[
'time'] ) && $options[
'time'] !==
false ) {
110 $options[
'time'] =
wfTimestamp( TS_MW, $options[
'time'] );
112 $options[
'time'] =
false;
115 if ( !$this->reposInitialised ) {
119 $title = File::normalizeTitle( $title );
125 $dbkey = $title->getDBkey();
126 $timeKey = is_string( $options[
'time'] ) ? $options[
'time'] :
'';
127 if ( empty( $options[
'ignoreRedirect'] )
128 && empty( $options[
'private'] )
129 && empty( $options[
'latest'] )
131 if ( $this->cache->hasField( $dbkey, $timeKey, 60 ) ) {
132 return $this->cache->getField( $dbkey, $timeKey );
139 # Check the local repo
140 $image = $this->localRepo->findFile( $title, $options );
142 # Check the foreign repos
144 foreach ( $this->foreignRepos as $repo ) {
145 $image = $repo->findFile( $title, $options );
152 $image = $image instanceof
File ? $image :
false;
153 # Cache file existence or non-existence
154 if ( $useCache && ( !$image || $image->isCacheable() ) ) {
155 $this->cache->setField( $dbkey, $timeKey, $image );
178 public function findFiles( array $inputItems, $flags = 0 ) {
179 if ( !$this->reposInitialised ) {
184 foreach ( $inputItems as $item ) {
185 if ( !is_array( $item ) ) {
186 $item = [
'title' => $item ];
188 $item[
'title'] = File::normalizeTitle( $item[
'title'] );
189 if ( $item[
'title'] ) {
190 $items[$item[
'title']->getDBkey()] = $item;
194 $images = $this->localRepo->findFiles( $items, $flags );
196 foreach ( $this->foreignRepos as $repo ) {
198 foreach ( $images as $name => $image ) {
199 unset( $items[$name] );
202 $images = array_merge( $images, $repo->findFiles( $items, $flags ) );
214 if ( !$this->reposInitialised ) {
218 $title = File::normalizeTitle( $title );
220 $redir = $this->localRepo->checkRedirect( $title );
225 foreach ( $this->foreignRepos as $repo ) {
226 $redir = $repo->checkRedirect( $title );
244 if ( !$this->reposInitialised ) {
248 $file = $this->localRepo->findFileFromKey( $hash, $options );
250 foreach ( $this->foreignRepos as $repo ) {
251 $file = $repo->findFileFromKey( $hash, $options );
268 if ( !$this->reposInitialised ) {
272 $result = $this->localRepo->findBySha1( $hash );
273 foreach ( $this->foreignRepos as $repo ) {
274 $result = array_merge( $result, $repo->findBySha1( $hash ) );
276 usort( $result, [ File::class,
'compare' ] );
288 if ( !$this->reposInitialised ) {
292 $result = $this->localRepo->findBySha1s( $hashes );
293 foreach ( $this->foreignRepos as $repo ) {
294 $result = array_merge_recursive( $result, $repo->findBySha1s( $hashes ) );
297 foreach ( $result as $hash => $files ) {
298 usort( $result[$hash], [ File::class,
'compare' ] );
310 if ( !$this->reposInitialised ) {
313 if ( $index ===
'local' ) {
314 return $this->localRepo;
316 return $this->foreignRepos[$index] ??
false;
325 if ( !$this->reposInitialised ) {
328 foreach ( $this->foreignRepos as $repo ) {
329 if ( $repo->name == $name ) {
345 return $this->
getRepo(
'local' );
357 if ( !$this->reposInitialised ) {
360 foreach ( $this->foreignRepos as $repo ) {
361 if ( $callback( $repo, ...
$params ) ) {
374 if ( !$this->reposInitialised ) {
377 return (
bool)$this->foreignRepos;
384 if ( $this->reposInitialised ) {
387 $this->reposInitialised =
true;
389 $this->localRepo = $this->
newRepo( $this->localInfo );
390 $this->foreignRepos = [];
391 foreach ( $this->foreignInfo as $key => $info ) {
392 $this->foreignRepos[$key] = $this->
newRepo( $info );
404 return $this->
newRepo( $info + $this->localInfo );
413 $class = $info[
'class'];
415 $info[
'wanCache'] = $this->wanCache;
417 return new $class( $info );
425 private function splitVirtualUrl( $url ) {
426 if ( !str_starts_with( $url,
'mwrepo://' ) ) {
427 throw new InvalidArgumentException( __METHOD__ .
': unknown protocol' );
430 $bits = explode(
'/', substr( $url, 9 ), 3 );
431 if ( count( $bits ) != 3 ) {
432 throw new InvalidArgumentException( __METHOD__ .
": invalid mwrepo URL: $url" );
444 [ $repoName, , ] = $this->splitVirtualUrl( $fileName );
445 if ( $repoName ===
'' ) {
448 $repo = $this->
getRepo( $repoName );
450 return $repo->getFileProps( $fileName );
454 return $mwProps->getPropsFromPath( $fileName,
true );
463 if ( $title ==
null ) {
464 $this->cache->clear();
465 } elseif ( is_string( $title ) ) {
466 $this->cache->clear( $title );
468 $this->cache->clear( $title->getDBkey() );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
array $params
The job parameters.
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...
MimeMagic helper wrapper.
Store key-value entries in a size-limited in-memory LRU cache.
Prioritized list of file repositories.
newCustomLocalRepo( $info=[])
Create a local repo with the specified option overrides.
initialiseRepos()
Initialise the $repos array.
checkRedirect( $title)
Interface for FileRepo::checkRedirect()
getRepoByName( $name)
Get the repo instance by its name.
__construct( $localInfo, $foreignInfo, WANObjectCache $wanCache, MimeAnalyzer $mimeAnalyzer)
Construct a group of file repositories.
hasForeignRepos()
Does the installation have any foreign repos set up?
findFileFromKey( $hash, $options=[])
Find an instance of the file with this key, created at the specified time Returns false if the file d...
findFile( $title, $options=[])
Search repositories for an image.
getLocalRepo()
Get the local repository, i.e.
findBySha1s(array $hashes)
Find all instances of files with this keys.
clearCache( $title=null)
Clear RepoGroup process cache used for finding a file.
getRepo( $index)
Get the repo instance with a given key.
findBySha1( $hash)
Find all instances of files with this key.
findFiles(array $inputItems, $flags=0)
Search repositories for many files at once.
newRepo( $info)
Create a repo class based on an info structure.
forEachForeignRepo( $callback, $params=[])
Call a function for each foreign repo, with the repo object as the first parameter.
Multi-datacenter aware caching interface.
Interface for objects (potentially) representing an editable wiki page.