MediaWiki  master
BadFileLookup.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki;
4 
5 use BagOStuff;
6 use Hooks;
9 use RepoGroup;
10 use TitleParser;
11 
15 
17  private $cache;
18 
20  private $repoGroup;
21 
23  private $titleParser;
24 
26  private $badFiles;
27 
36  public function __construct(
37  callable $blacklistCallback,
39  RepoGroup $repoGroup,
40  TitleParser $titleParser
41  ) {
42  $this->blacklistCallback = $blacklistCallback;
43  $this->cache = $cache;
44  $this->repoGroup = $repoGroup;
45  $this->titleParser = $titleParser;
46  }
47 
61  public function isBadFile( $name, LinkTarget $contextTitle = null ) {
62  // Handle redirects; callers almost always hit wfFindFile() anyway, so just use that method
63  // 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 ( !Hooks::run( 'BadImage', [ $name, &$bad ] ) ) {
74  return (bool)$bad;
75  }
76 
77  if ( $this->badFiles === null ) {
78  // Not used before in this request, try the cache
79  $blacklist = ( $this->blacklistCallback )();
80  $key = $this->cache->makeKey( 'bad-image-list', sha1( $blacklist ) );
81  $this->badFiles = $this->cache->get( $key ) ?: null;
82  }
83 
84  if ( $this->badFiles === null ) {
85  // Cache miss, build the list now
86  $this->badFiles = [];
87  $lines = explode( "\n", $blacklist );
88  foreach ( $lines as $line ) {
89  // List items only
90  if ( substr( $line, 0, 1 ) !== '*' ) {
91  continue;
92  }
93 
94  // Find all links
95  $m = [];
96  // XXX What is the ':?' doing in the regex? Why not let the TitleParser strip it?
97  if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
98  continue;
99  }
100 
101  $fileDBkey = null;
102  $exceptions = [];
103  foreach ( $m[1] as $i => $titleText ) {
104  try {
105  $title = $this->titleParser->parseTitle( $titleText );
106  } catch ( MalformedTitleException $e ) {
107  continue;
108  }
109  if ( $i == 0 ) {
110  $fileDBkey = $title->getDBkey();
111  } else {
112  $exceptions[$title->getNamespace()][$title->getDBkey()] = true;
113  }
114  }
115 
116  if ( $fileDBkey !== null ) {
117  $this->badFiles[$fileDBkey] = $exceptions;
118  }
119  }
120  $this->cache->set( $key, $this->badFiles, 24 * 60 * 60 );
121  }
122 
123  return isset( $this->badFiles[$name] ) && ( !$contextTitle ||
124  !isset( $this->badFiles[$name][$contextTitle->getNamespace()]
125  [$contextTitle->getDBkey()] ) );
126  }
127 }
array null $badFiles
Parsed blacklist.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
BagOStuff $cache
Cache of parsed bad image list.
__construct(callable $blacklistCallback, BagOStuff $cache, RepoGroup $repoGroup, TitleParser $titleParser)
Do not call directly.
isBadFile( $name, LinkTarget $contextTitle=null)
Determine if a file exists on the &#39;bad image list&#39;.
A helper class for throttling authentication attempts.
$cache
Definition: mcc.php:33
callable $blacklistCallback
Returns contents of blacklist (see comment for isBadFile())
$lines
Definition: router.php:61
$line
Definition: cdb.php:59
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200