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 $items = array_diff_key( $items, $images );
201 $images = array_merge( $images, $repo->findFiles( $items, $flags ) );
213 if ( !$this->reposInitialised ) {
217 $title = File::normalizeTitle( $title );
219 $redir = $this->localRepo->checkRedirect( $title );
224 foreach ( $this->foreignRepos as $repo ) {
225 $redir = $repo->checkRedirect( $title );
243 if ( !$this->reposInitialised ) {
247 $file = $this->localRepo->findFileFromKey( $hash, $options );
249 foreach ( $this->foreignRepos as $repo ) {
250 $file = $repo->findFileFromKey( $hash, $options );
267 if ( !$this->reposInitialised ) {
271 $result = $this->localRepo->findBySha1( $hash );
272 foreach ( $this->foreignRepos as $repo ) {
273 $result = array_merge( $result, $repo->findBySha1( $hash ) );
275 usort( $result, [ File::class,
'compare' ] );
287 if ( !$this->reposInitialised ) {
291 $result = $this->localRepo->findBySha1s( $hashes );
292 foreach ( $this->foreignRepos as $repo ) {
293 $result = array_merge_recursive( $result, $repo->findBySha1s( $hashes ) );
296 foreach ( $result as $hash => $files ) {
297 usort( $result[$hash], [ File::class,
'compare' ] );
309 if ( !$this->reposInitialised ) {
312 if ( $index ===
'local' ) {
313 return $this->localRepo;
315 return $this->foreignRepos[$index] ??
false;
324 if ( !$this->reposInitialised ) {
327 foreach ( $this->foreignRepos as $repo ) {
328 if ( $repo->name == $name ) {
344 return $this->
getRepo(
'local' );
356 if ( !$this->reposInitialised ) {
359 foreach ( $this->foreignRepos as $repo ) {
360 if ( $callback( $repo, ...
$params ) ) {
373 if ( !$this->reposInitialised ) {
376 return (
bool)$this->foreignRepos;
383 if ( $this->reposInitialised ) {
386 $this->reposInitialised =
true;
388 $this->localRepo = $this->
newRepo( $this->localInfo );
389 $this->foreignRepos = [];
390 foreach ( $this->foreignInfo as $key => $info ) {
391 $this->foreignRepos[$key] = $this->
newRepo( $info );
403 return $this->
newRepo( $info + $this->localInfo );
412 $class = $info[
'class'];
414 $info[
'wanCache'] = $this->wanCache;
416 return new $class( $info );
424 private function splitVirtualUrl(
$url ) {
425 if ( !str_starts_with(
$url,
'mwrepo://' ) ) {
426 throw new InvalidArgumentException( __METHOD__ .
': unknown protocol' );
429 $bits = explode(
'/', substr(
$url, 9 ), 3 );
430 if ( count( $bits ) != 3 ) {
431 throw new InvalidArgumentException( __METHOD__ .
": invalid mwrepo URL: $url" );
443 [ $repoName, , ] = $this->splitVirtualUrl( $fileName );
444 if ( $repoName ===
'' ) {
447 $repo = $this->
getRepo( $repoName );
449 return $repo->getFileProps( $fileName );
453 return $mwProps->getPropsFromPath( $fileName,
true );
462 if ( $title ==
null ) {
463 $this->cache->clear();
464 } elseif ( is_string( $title ) ) {
465 $this->cache->clear( $title );
467 $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.