MediaWiki  master
ArchivedFile.php
Go to the documentation of this file.
1 <?php
25 
31 class ArchivedFile {
33  private $id;
34 
36  private $name;
37 
39  private $group;
40 
42  private $key;
43 
45  private $size;
46 
48  private $bits;
49 
51  private $width;
52 
54  private $height;
55 
57  private $metadata;
58 
60  private $mime;
61 
63  private $media_type;
64 
66  private $description;
67 
69  private $user;
70 
72  private $timestamp;
73 
75  private $dataLoaded;
76 
78  private $deleted;
79 
81  private $sha1;
82 
86  private $pageCount;
87 
89  private $archive_name;
90 
92  protected $handler;
93 
95  protected $title; # image title
96 
104  function __construct( $title, $id = 0, $key = '', $sha1 = '' ) {
105  $this->id = -1;
106  $this->title = false;
107  $this->name = false;
108  $this->group = 'deleted'; // needed for direct use of constructor
109  $this->key = '';
110  $this->size = 0;
111  $this->bits = 0;
112  $this->width = 0;
113  $this->height = 0;
114  $this->metadata = '';
115  $this->mime = "unknown/unknown";
116  $this->media_type = '';
117  $this->description = '';
118  $this->user = null;
119  $this->timestamp = null;
120  $this->deleted = 0;
121  $this->dataLoaded = false;
122  $this->exists = false;
123  $this->sha1 = '';
124 
125  if ( $title instanceof Title ) {
126  $this->title = File::normalizeTitle( $title, 'exception' );
127  $this->name = $title->getDBkey();
128  }
129 
130  if ( $id ) {
131  $this->id = $id;
132  }
133 
134  if ( $key ) {
135  $this->key = $key;
136  }
137 
138  if ( $sha1 ) {
139  $this->sha1 = $sha1;
140  }
141 
142  if ( !$id && !$key && !( $title instanceof Title ) && !$sha1 ) {
143  throw new MWException( "No specifications provided to ArchivedFile constructor." );
144  }
145  }
146 
152  public function load() {
153  if ( $this->dataLoaded ) {
154  return true;
155  }
156  $conds = [];
157 
158  if ( $this->id > 0 ) {
159  $conds['fa_id'] = $this->id;
160  }
161  if ( $this->key ) {
162  $conds['fa_storage_group'] = $this->group;
163  $conds['fa_storage_key'] = $this->key;
164  }
165  if ( $this->title ) {
166  $conds['fa_name'] = $this->title->getDBkey();
167  }
168  if ( $this->sha1 ) {
169  $conds['fa_sha1'] = $this->sha1;
170  }
171 
172  if ( $conds === [] ) {
173  throw new MWException( "No specific information for retrieving archived file" );
174  }
175 
176  if ( !$this->title || $this->title->getNamespace() == NS_FILE ) {
177  $this->dataLoaded = true; // set it here, to have also true on miss
178  $dbr = wfGetDB( DB_REPLICA );
179  $fileQuery = self::getQueryInfo();
180  $row = $dbr->selectRow(
181  $fileQuery['tables'],
182  $fileQuery['fields'],
183  $conds,
184  __METHOD__,
185  [ 'ORDER BY' => 'fa_timestamp DESC' ],
186  $fileQuery['joins']
187  );
188  if ( !$row ) {
189  // this revision does not exist?
190  return null;
191  }
192 
193  // initialize fields for filestore image object
194  $this->loadFromRow( $row );
195  } else {
196  throw new MWException( 'This title does not correspond to an image page.' );
197  }
198  $this->exists = true;
199 
200  return true;
201  }
202 
209  public static function newFromRow( $row ) {
210  $file = new ArchivedFile( Title::makeTitle( NS_FILE, $row->fa_name ) );
211  $file->loadFromRow( $row );
212 
213  return $file;
214  }
215 
221  static function selectFields() {
223 
224  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
225  // If code is using this instead of self::getQueryInfo(), there's a
226  // decent chance it's going to try to directly access
227  // $row->fa_user or $row->fa_user_text and we can't give it
228  // useful values here once those aren't being used anymore.
229  throw new BadMethodCallException(
230  'Cannot use ' . __METHOD__
231  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
232  );
233  }
234 
235  wfDeprecated( __METHOD__, '1.31' );
236  return [
237  'fa_id',
238  'fa_name',
239  'fa_archive_name',
240  'fa_storage_key',
241  'fa_storage_group',
242  'fa_size',
243  'fa_bits',
244  'fa_width',
245  'fa_height',
246  'fa_metadata',
247  'fa_media_type',
248  'fa_major_mime',
249  'fa_minor_mime',
250  'fa_user',
251  'fa_user_text',
252  'fa_actor' => 'NULL',
253  'fa_timestamp',
254  'fa_deleted',
255  'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
256  'fa_sha1',
257  ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'fa_description' );
258  }
259 
269  public static function getQueryInfo() {
270  $commentQuery = MediaWikiServices::getInstance()->getCommentStore()->getJoin( 'fa_description' );
271  $actorQuery = ActorMigration::newMigration()->getJoin( 'fa_user' );
272  return [
273  'tables' => [ 'filearchive' ] + $commentQuery['tables'] + $actorQuery['tables'],
274  'fields' => [
275  'fa_id',
276  'fa_name',
277  'fa_archive_name',
278  'fa_storage_key',
279  'fa_storage_group',
280  'fa_size',
281  'fa_bits',
282  'fa_width',
283  'fa_height',
284  'fa_metadata',
285  'fa_media_type',
286  'fa_major_mime',
287  'fa_minor_mime',
288  'fa_timestamp',
289  'fa_deleted',
290  'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
291  'fa_sha1',
292  ] + $commentQuery['fields'] + $actorQuery['fields'],
293  'joins' => $commentQuery['joins'] + $actorQuery['joins'],
294  ];
295  }
296 
303  public function loadFromRow( $row ) {
304  $this->id = intval( $row->fa_id );
305  $this->name = $row->fa_name;
306  $this->archive_name = $row->fa_archive_name;
307  $this->group = $row->fa_storage_group;
308  $this->key = $row->fa_storage_key;
309  $this->size = $row->fa_size;
310  $this->bits = $row->fa_bits;
311  $this->width = $row->fa_width;
312  $this->height = $row->fa_height;
313  $this->metadata = $row->fa_metadata;
314  $this->mime = "$row->fa_major_mime/$row->fa_minor_mime";
315  $this->media_type = $row->fa_media_type;
316  $this->description = MediaWikiServices::getInstance()->getCommentStore()
317  // Legacy because $row may have come from self::selectFields()
318  ->getCommentLegacy( wfGetDB( DB_REPLICA ), 'fa_description', $row )->text;
319  $this->user = User::newFromAnyId( $row->fa_user, $row->fa_user_text, $row->fa_actor );
320  $this->timestamp = $row->fa_timestamp;
321  $this->deleted = $row->fa_deleted;
322  if ( isset( $row->fa_sha1 ) ) {
323  $this->sha1 = $row->fa_sha1;
324  } else {
325  // old row, populate from key
326  $this->sha1 = LocalRepo::getHashFromKey( $this->key );
327  }
328  if ( !$this->title ) {
329  $this->title = Title::makeTitleSafe( NS_FILE, $row->fa_name );
330  }
331  }
332 
338  public function getTitle() {
339  if ( !$this->title ) {
340  $this->load();
341  }
342  return $this->title;
343  }
344 
350  public function getName() {
351  if ( $this->name === false ) {
352  $this->load();
353  }
354 
355  return $this->name;
356  }
357 
361  public function getID() {
362  $this->load();
363 
364  return $this->id;
365  }
366 
370  public function exists() {
371  $this->load();
372 
373  return $this->exists;
374  }
375 
380  public function getKey() {
381  $this->load();
382 
383  return $this->key;
384  }
385 
390  public function getStorageKey() {
391  return $this->getKey();
392  }
393 
398  public function getGroup() {
399  return $this->group;
400  }
401 
406  public function getWidth() {
407  $this->load();
408 
409  return $this->width;
410  }
411 
416  public function getHeight() {
417  $this->load();
418 
419  return $this->height;
420  }
421 
426  public function getMetadata() {
427  $this->load();
428 
429  return $this->metadata;
430  }
431 
436  public function getSize() {
437  $this->load();
438 
439  return $this->size;
440  }
441 
446  public function getBits() {
447  $this->load();
448 
449  return $this->bits;
450  }
451 
456  public function getMimeType() {
457  $this->load();
458 
459  return $this->mime;
460  }
461 
466  function getHandler() {
467  if ( !isset( $this->handler ) ) {
468  $this->handler = MediaHandler::getHandler( $this->getMimeType() );
469  }
470 
471  return $this->handler;
472  }
473 
479  function pageCount() {
480  if ( !isset( $this->pageCount ) ) {
481  // @FIXME: callers expect File objects
482  if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
483  $this->pageCount = $this->handler->pageCount( $this );
484  } else {
485  $this->pageCount = false;
486  }
487  }
488 
489  return $this->pageCount;
490  }
491 
497  public function getMediaType() {
498  $this->load();
499 
500  return $this->media_type;
501  }
502 
508  public function getTimestamp() {
509  $this->load();
510 
511  return wfTimestamp( TS_MW, $this->timestamp );
512  }
513 
520  function getSha1() {
521  $this->load();
522 
523  return $this->sha1;
524  }
525 
537  public function getUser( $type = 'text' ) {
538  $this->load();
539 
540  if ( $type === 'object' ) {
541  return $this->user;
542  } elseif ( $type === 'text' ) {
543  return $this->user ? $this->user->getName() : '';
544  } elseif ( $type === 'id' ) {
545  return $this->user ? $this->user->getId() : 0;
546  }
547 
548  throw new MWException( "Unknown type '$type'." );
549  }
550 
556  public function getDescription() {
557  $this->load();
558  if ( $this->isDeleted( File::DELETED_COMMENT ) ) {
559  return 0;
560  } else {
561  return $this->description;
562  }
563  }
564 
570  public function getRawUser() {
571  return $this->getUser( 'id' );
572  }
573 
579  public function getRawUserText() {
580  return $this->getUser( 'text' );
581  }
582 
588  public function getRawDescription() {
589  $this->load();
590 
591  return $this->description;
592  }
593 
598  public function getVisibility() {
599  $this->load();
600 
601  return $this->deleted;
602  }
603 
610  public function isDeleted( $field ) {
611  $this->load();
612 
613  return ( $this->deleted & $field ) == $field;
614  }
615 
623  public function userCan( $field, User $user = null ) {
624  $this->load();
625 
626  $title = $this->getTitle();
627  return Revision::userCanBitfield( $this->deleted, $field, $user, $title ?: null );
628  }
629 }
MediaHandler $handler
getDescription()
Return upload description.
string $media_type
Media type.
static newFromRow( $row)
Loads a file object from the filearchive table.
const DELETED_COMMENT
Definition: File.php:55
getRawUser()
Return the user ID of the uploader.
int false $pageCount
Number of pages of a multipage document, or false for documents which aren&#39;t multipage documents...
static getQueryInfo()
Return the tables, fields, and join conditions to be selected to create a new archivedfile object...
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Definition: router.php:42
int $deleted
Bitfield akin to rev_deleted.
int $wgActorTableSchemaMigrationStage
Actor table schema migration stage.
width
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
getRawUserText()
Return the user name of the uploader.
int $bits
Size in bytes.
const SCHEMA_COMPAT_READ_NEW
Definition: Defines.php:287
getStorageKey()
Return the FileStore key (overriding base File class)
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation use $formDescriptor instead default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message key
Definition: hooks.txt:2151
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
bool $dataLoaded
Whether or not all this has been loaded from the database (loadFromXxx)
string $group
FileStore storage group.
getSha1()
Get the SHA-1 base 36 hash of the file.
getHeight()
Return the height of the image.
getMetadata()
Get handler-specific metadata.
getHandler()
Get a MediaHandler instance for this file.
string $timestamp
Time of upload.
User null $user
Uploader.
title
getName()
Return the file name.
getGroup()
Return the FileStore storage group.
string $description
Upload description.
getWidth()
Return the width of the image.
isDeleted( $field)
for file or revision rows
and how to run hooks for an and one after Each event has a name
Definition: hooks.txt:6
pageCount()
Returns the number of pages of a multipage document, or false for documents which aren&#39;t multipage do...
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:48
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
string $mime
MIME type.
Class representing a row of the &#39;filearchive&#39; table.
getTitle()
Return the associated title object.
static newMigration()
Static constructor.
getSize()
Return the size of the image file, in bytes.
getDBkey()
Get the main part with underscores.
Definition: Title.php:1001
static selectFields()
Fields in the filearchive table.
static userCanBitfield( $bitfield, $field, User $user=null, Title $title=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
Definition: Revision.php:1244
userCan( $field, User $user=null)
Determine if the current user is allowed to view a particular field of this FileStore image file...
getMediaType()
Return the type of the media in the file.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such and we might be restricted by PHP settings such as safe mode or open_basedir We cannot assume that the software even has read access anywhere useful Many shared hosts run all users web applications under the same user
Wikitext formatted, in the key only.
Definition: distributors.txt:9
loadFromRow( $row)
Load ArchivedFile object fields from a DB row.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
const NS_FILE
Definition: Defines.php:70
string $sha1
SHA-1 hash of file content.
getKey()
Return the FileStore key.
int $size
File size in bytes.
__construct( $title, $id=0, $key='', $sha1='')
int $width
Width.
static getHashFromKey( $key)
Gets the SHA1 hash from a storage key.
Definition: LocalRepo.php:182
string $metadata
Metadata string.
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:617
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:589
string $key
FileStore SHA-1 key.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
static newFromAnyId( $userId, $userName, $actorId)
Static factory method for creation from an ID, name, and/or actor ID.
Definition: User.php:678
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check set to true or false to override the $wgMaxImageArea check result gives extension the possibility to transform it themselves set to a MediaTransformOutput the error message to be returned in an array you should do so by altering $wgNamespaceProtection and $wgNamespaceContentModels outside the handler
Definition: hooks.txt:780
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
string $archive_name
Original base filename.
int $height
Height.
string $name
File name.
getUser( $type='text')
Returns ID or name of user who uploaded the file.
const DB_REPLICA
Definition: defines.php:25
int $id
Filearchive row ID.
load()
Loads a file object from the filearchive table.
getRawDescription()
Return upload description.
static getHandler( $type)
Get a MediaHandler for a given MIME type from the instance cache.
getTimestamp()
Return upload timestamp.
static normalizeTitle( $title, $exception=false)
Given a string or Title object return either a valid Title object with namespace NS_FILE or null...
Definition: File.php:185
getMimeType()
Returns the MIME type of the file.
getBits()
Return the bits of the image file, in bytes.
getVisibility()
Returns the deletion bitfield.