24use Wikimedia\Mime\MimeAnalyzer;
43 protected $reposInitialised =
false;
55 private const MAX_CACHE_SIZE = 500;
58 private $mimeAnalyzer;
76 MimeAnalyzer $mimeAnalyzer
78 $this->localInfo = $localInfo;
79 $this->foreignInfo = $foreignInfo;
80 $this->cache =
new MapCacheLRU( self::MAX_CACHE_SIZE );
81 $this->wanCache = $wanCache;
82 $this->mimeAnalyzer = $mimeAnalyzer;
103 public function findFile( $title, $options = [] ) {
104 if ( !is_array( $options ) ) {
106 $options = [
'time' => $options ];
108 if ( isset( $options[
'bypassCache'] ) ) {
109 $options[
'latest'] = $options[
'bypassCache'];
111 if ( isset( $options[
'time'] ) && $options[
'time'] !==
false ) {
112 $options[
'time'] =
wfTimestamp( TS_MW, $options[
'time'] );
114 $options[
'time'] =
false;
117 if ( !$this->reposInitialised ) {
121 $title = File::normalizeTitle( $title );
127 $dbkey = $title->getDBkey();
128 $timeKey = is_string( $options[
'time'] ) ? $options[
'time'] :
'';
129 if ( empty( $options[
'ignoreRedirect'] )
130 && empty( $options[
'private'] )
131 && empty( $options[
'latest'] )
133 if ( $this->cache->hasField( $dbkey, $timeKey, 60 ) ) {
134 return $this->cache->getField( $dbkey, $timeKey );
141 # Check the local repo
142 $image = $this->localRepo->findFile( $title, $options );
144 # Check the foreign repos
146 foreach ( $this->foreignRepos as $repo ) {
147 $image = $repo->findFile( $title, $options );
154 $image = $image instanceof
File ? $image :
false;
155 # Cache file existence or non-existence
156 if ( $useCache && ( !$image || $image->isCacheable() ) ) {
157 $this->cache->setField( $dbkey, $timeKey, $image );
180 public function findFiles( array $inputItems, $flags = 0 ) {
181 if ( !$this->reposInitialised ) {
186 foreach ( $inputItems as $item ) {
187 if ( !is_array( $item ) ) {
188 $item = [
'title' => $item ];
190 $item[
'title'] = File::normalizeTitle( $item[
'title'] );
191 if ( $item[
'title'] ) {
192 $items[$item[
'title']->getDBkey()] = $item;
196 $images = $this->localRepo->findFiles( $items, $flags );
198 foreach ( $this->foreignRepos as $repo ) {
200 foreach ( $images as $name => $image ) {
201 unset( $items[$name] );
204 $images = array_merge( $images, $repo->findFiles( $items, $flags ) );
216 if ( !$this->reposInitialised ) {
220 $title = File::normalizeTitle( $title );
222 $redir = $this->localRepo->checkRedirect( $title );
227 foreach ( $this->foreignRepos as $repo ) {
228 $redir = $repo->checkRedirect( $title );
246 if ( !$this->reposInitialised ) {
250 $file = $this->localRepo->findFileFromKey( $hash, $options );
252 foreach ( $this->foreignRepos as $repo ) {
253 $file = $repo->findFileFromKey( $hash, $options );
270 if ( !$this->reposInitialised ) {
274 $result = $this->localRepo->findBySha1( $hash );
275 foreach ( $this->foreignRepos as $repo ) {
276 $result = array_merge( $result, $repo->findBySha1( $hash ) );
278 usort( $result, [ File::class,
'compare' ] );
290 if ( !$this->reposInitialised ) {
294 $result = $this->localRepo->findBySha1s( $hashes );
295 foreach ( $this->foreignRepos as $repo ) {
296 $result = array_merge_recursive( $result, $repo->findBySha1s( $hashes ) );
299 foreach ( $result as $hash => $files ) {
300 usort( $result[$hash], [ File::class,
'compare' ] );
312 if ( !$this->reposInitialised ) {
315 if ( $index ===
'local' ) {
316 return $this->localRepo;
318 return $this->foreignRepos[$index] ??
false;
327 if ( !$this->reposInitialised ) {
330 foreach ( $this->foreignRepos as $repo ) {
331 if ( $repo->name == $name ) {
347 return $this->
getRepo(
'local' );
359 if ( !$this->reposInitialised ) {
362 foreach ( $this->foreignRepos as $repo ) {
363 if ( $callback( $repo, ...
$params ) ) {
376 if ( !$this->reposInitialised ) {
379 return (
bool)$this->foreignRepos;
386 if ( $this->reposInitialised ) {
389 $this->reposInitialised =
true;
391 $this->localRepo = $this->
newRepo( $this->localInfo );
392 $this->foreignRepos = [];
393 foreach ( $this->foreignInfo as $key => $info ) {
394 $this->foreignRepos[$key] = $this->
newRepo( $info );
406 return $this->
newRepo( $info + $this->localInfo );
415 $class = $info[
'class'];
417 $info[
'wanCache'] = $this->wanCache;
419 return new $class( $info );
427 private function splitVirtualUrl(
$url ) {
428 if ( !str_starts_with(
$url,
'mwrepo://' ) ) {
429 throw new InvalidArgumentException( __METHOD__ .
': unknown protocol' );
432 $bits = explode(
'/', substr(
$url, 9 ), 3 );
433 if ( count( $bits ) != 3 ) {
434 throw new InvalidArgumentException( __METHOD__ .
": invalid mwrepo URL: $url" );
446 [ $repoName, , ] = $this->splitVirtualUrl( $fileName );
447 if ( $repoName ===
'' ) {
450 $repo = $this->
getRepo( $repoName );
452 return $repo->getFileProps( $fileName );
456 return $mwProps->getPropsFromPath( $fileName,
true );
465 if ( $title ==
null ) {
466 $this->cache->clear();
467 } elseif ( is_string( $title ) ) {
468 $this->cache->clear( $title );
470 $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.
Interface for objects (potentially) representing an editable wiki page.