MediaWiki master
BadFileLookup.php
Go to the documentation of this file.
1<?php
2
4
10use RepoGroup;
12
15 private $listCallback;
16
17 private BagOStuff $cache;
18 private RepoGroup $repoGroup;
19 private TitleParser $titleParser;
20 private HookRunner $hookRunner;
21
23 private $badFiles;
24
34 public function __construct(
35 callable $listCallback,
36 BagOStuff $cache,
37 RepoGroup $repoGroup,
38 TitleParser $titleParser,
39 HookContainer $hookContainer
40 ) {
41 $this->listCallback = $listCallback;
42 $this->cache = $cache;
43 $this->repoGroup = $repoGroup;
44 $this->titleParser = $titleParser;
45 $this->hookRunner = new HookRunner( $hookContainer );
46 }
47
61 public function isBadFile( $name, LinkTarget $contextTitle = null ) {
62 // Handle redirects; callers almost always hit RepoGroup::findFile() anyway,
63 // so just use that method because it has a fast process cache.
64 $file = $this->repoGroup->findFile( $name );
65 // XXX If we don't find the file we also don't replace spaces by underscores or otherwise
66 // validate or normalize the title, is this right?
67 if ( $file ) {
68 $name = $file->getTitle()->getDBkey();
69 }
70
71 // Run the extension hook
72 $bad = false;
73 if ( !$this->hookRunner->onBadImage( $name, $bad ) ) {
74 return (bool)$bad;
75 }
76
77 if ( $this->badFiles === null ) {
78 $list = ( $this->listCallback )();
79 $key = $this->cache->makeKey( 'bad-image-list', sha1( $list ) );
80 $this->badFiles = $this->cache->getWithSetCallback(
81 $key,
82 BagOStuff::TTL_DAY,
83 function () use ( $list ) {
84 return $this->buildBadFilesList( $list );
85 }
86 );
87 }
88
89 return isset( $this->badFiles[$name] ) && ( !$contextTitle ||
90 !isset( $this->badFiles[$name][$contextTitle->getNamespace()][$contextTitle->getDBkey()] ) );
91 }
92
97 private function buildBadFilesList( string $list ): array {
98 $ret = [];
99 $lines = explode( "\n", $list );
100 foreach ( $lines as $line ) {
101 // List items only
102 if ( substr( $line, 0, 1 ) !== '*' ) {
103 continue;
104 }
105
106 // Find all links
107 $m = [];
108 // XXX What is the ':?' doing in the regex? Why not let the TitleParser strip it?
109 if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
110 continue;
111 }
112
113 $fileDBkey = null;
114 $exceptions = [];
115 foreach ( $m[1] as $i => $titleText ) {
116 try {
117 $title = $this->titleParser->parseTitle( $titleText );
118 } catch ( MalformedTitleException $e ) {
119 continue;
120 }
121 if ( $i == 0 ) {
122 $fileDBkey = $title->getDBkey();
123 } else {
124 $exceptions[$title->getNamespace()][$title->getDBkey()] = true;
125 }
126 }
127
128 if ( $fileDBkey !== null ) {
129 $ret[$fileDBkey] = $exceptions;
130 }
131 }
132 return $ret;
133 }
134}
135
137class_alias( BadFileLookup::class, 'MediaWiki\\BadFileLookup' );
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
isBadFile( $name, LinkTarget $contextTitle=null)
Determine if a file exists on the 'bad image list'.
__construct(callable $listCallback, BagOStuff $cache, RepoGroup $repoGroup, TitleParser $titleParser, HookContainer $hookContainer)
Do not call directly.
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Prioritized list of file repositories.
Definition RepoGroup.php:30
Class representing a cache/ephemeral data store.
Definition BagOStuff.php:88
Represents the target of a wiki link.
A title parser service for MediaWiki.
if(!file_exists( $CREDITS)) $lines