MediaWiki  master
ExifBitmapHandler.php
Go to the documentation of this file.
1 <?php
2 
27 
37  public const BROKEN_FILE = '-1';
38 
40  public const OLD_BROKEN_FILE = '0';
41 
42  public function convertMetadataVersion( $metadata, $version = 1 ) {
43  // basically flattens arrays.
44  $version = is_int( $version ) ? $version : (int)explode( ';', $version, 2 )[0];
45  if ( $version < 1 || $version >= 2 ) {
46  return $metadata;
47  }
48 
49  if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] !== 2 ) {
50  return $metadata;
51  }
52 
53  // Treat Software as a special case because in can contain
54  // an array of (SoftwareName, Version).
55  if ( isset( $metadata['Software'] )
56  && is_array( $metadata['Software'] )
57  && is_array( $metadata['Software'][0] )
58  && isset( $metadata['Software'][0][0] )
59  && isset( $metadata['Software'][0][1] )
60  ) {
61  $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
62  . $metadata['Software'][0][1] . ')';
63  }
64 
65  $formatter = new FormatMetadata;
66 
67  // ContactInfo also has to be dealt with specially
68  if ( isset( $metadata['Contact'] ) ) {
69  $metadata['Contact'] = $formatter->collapseContactInfo(
70  is_array( $metadata['Contact'] ) ? $metadata['Contact'] : [ $metadata['Contact'] ]
71  );
72  }
73 
74  // Ignore Location shown if it is not a simple string
75  if ( isset( $metadata['LocationShown'] ) && !is_string( $metadata['LocationShown'] ) ) {
76  unset( $metadata['LocationShown'] );
77  }
78 
79  foreach ( $metadata as &$val ) {
80  if ( is_array( $val ) ) {
81  // @phan-suppress-next-line SecurityCheck-DoubleEscaped Ambiguous with the true for nohtml
82  $val = $formatter->flattenArrayReal( $val, 'ul', true );
83  }
84  }
85  unset( $val );
86  $metadata['MEDIAWIKI_EXIF_VERSION'] = 1;
87 
88  return $metadata;
89  }
90 
95  public function isFileMetadataValid( $image ) {
96  $showEXIF = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::ShowEXIF );
97  if ( !$showEXIF ) {
98  # Metadata disabled and so an empty field is expected
99  return self::METADATA_GOOD;
100  }
101  $exif = $image->getMetadataArray();
102  if ( !$exif ) {
103  wfDebug( __METHOD__ . ': error unserializing?' );
104  return self::METADATA_BAD;
105  }
106  if ( $exif === [ '_error' => self::OLD_BROKEN_FILE ] ) {
107  # Old special value indicating that there is no Exif data in the file.
108  # or that there was an error well extracting the metadata.
109  wfDebug( __METHOD__ . ": back-compat version" );
111  }
112 
113  if ( $exif === [ '_error' => self::BROKEN_FILE ] ) {
114  return self::METADATA_GOOD;
115  }
116 
117  if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
118  || $exif['MEDIAWIKI_EXIF_VERSION'] !== Exif::version()
119  ) {
120  if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
121  && $exif['MEDIAWIKI_EXIF_VERSION'] === 1
122  ) {
123  // back-compatible but old
124  wfDebug( __METHOD__ . ": back-compat version" );
125 
127  }
128  # Wrong (non-compatible) version
129  wfDebug( __METHOD__ . ": wrong version" );
130 
131  return self::METADATA_BAD;
132  }
133 
134  return self::METADATA_GOOD;
135  }
136 
142  public function formatMetadata( $image, $context = false ) {
143  $meta = $this->getCommonMetaArray( $image );
144  if ( !$meta ) {
145  return false;
146  }
147 
148  return $this->formatMetadataHelper( $meta, $context );
149  }
150 
151  public function getCommonMetaArray( File $file ) {
152  $exif = $file->getMetadataArray();
153  if ( !$exif ) {
154  return [];
155  }
156  unset( $exif['MEDIAWIKI_EXIF_VERSION'] );
157 
158  return $exif;
159  }
160 
161  public function getMetadataType( $image ) {
162  return 'exif';
163  }
164 
165  protected function applyExifRotation( $info, $metadata ) {
166  if ( $this->autoRotateEnabled() ) {
167  $rotation = $this->getRotationForExifFromOrientation( $metadata['Orientation'] ?? null );
168  } else {
169  $rotation = 0;
170  }
171 
172  if ( $rotation === 90 || $rotation === 270 ) {
173  $width = $info['width'];
174  $info['width'] = $info['height'];
175  $info['height'] = $width;
176  }
177  return $info;
178  }
179 
192  public function getRotation( $file ) {
193  if ( !$this->autoRotateEnabled() ) {
194  return 0;
195  }
196 
197  $orientation = $file->getMetadataItem( 'Orientation' );
198  return $this->getRotationForExifFromOrientation( $orientation );
199  }
200 
209  protected function getRotationForExifFromOrientation( $orientation ) {
210  if ( $orientation === null ) {
211  return 0;
212  }
213  # See http://sylvana.net/jpegcrop/exif_orientation.html
214  switch ( $orientation ) {
215  case 8:
216  return 90;
217  case 3:
218  return 180;
219  case 6:
220  return 270;
221  default:
222  return 0;
223  }
224  }
225 }
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Generic handler for bitmap images.
Stuff specific to JPEG and (built-in) TIFF handler.
getRotationForExifFromOrientation( $orientation)
Given a chunk of serialized Exif metadata, return the orientation as degrees of rotation.
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
applyExifRotation( $info, $metadata)
const OLD_BROKEN_FILE
Outdated error extracting metadata.
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
getRotation( $file)
On supporting image formats, try to read out the low-level orientation of the file and return the ang...
const BROKEN_FILE
Error extracting metadata.
formatMetadata( $image, $context=false)
static version()
#-
Definition: Exif.php:714
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:70
Format Image metadata values into a human readable form.
collapseContactInfo(array $vals)
Format the contact info field into a single value.
const METADATA_COMPATIBLE
const METADATA_BAD
formatMetadataHelper( $metadataArray, $context=false)
sorts the visible/invisible field.
const METADATA_GOOD
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42