9 * Class representing a non-directory file on the file system
12 * @ingroup FileBackend
15 protected $path; // path to file
18 * Sets up the file object
20 * @param String $path Path to temporary file on local disk
22 public function __construct( $path ) {
23 if ( FileBackend
::isStoragePath( $path ) ) {
24 throw new MWException( __METHOD__
. " given storage path `$path`." );
30 * Returns the file system path
34 public function getPath() {
39 * Checks if the file exists
43 public function exists() {
44 return is_file( $this->path
);
48 * Get the file size in bytes
52 public function getSize() {
53 return filesize( $this->path
);
57 * Get the file's last-modified timestamp
59 * @return string|false TS_MW timestamp or false on failure
61 public function getTimestamp() {
63 $timestamp = filemtime( $this->path
);
65 if ( $timestamp !== false ) {
66 $timestamp = wfTimestamp( TS_MW
, $timestamp );
72 * Get an associative array containing information about
73 * a file with the given storage path.
75 * @param $ext Mixed: the file extension, or true to extract it from the filename.
76 * Set it to false to ignore the extension.
80 public function getProps( $ext = true ) {
81 wfProfileIn( __METHOD__
);
82 wfDebug( __METHOD__
.": Getting file info for $this->path\n" );
84 $info = self
::placeholderProps();
85 $info['fileExists'] = $this->exists();
87 if ( $info['fileExists'] ) {
88 $magic = MimeMagic
::singleton();
90 # get the file extension
91 if ( $ext === true ) {
92 $i = strrpos( $this->path
, '.' );
93 $ext = strtolower( $i ?
substr( $this->path
, $i +
1 ) : '' );
96 # mime type according to file contents
97 $info['file-mime'] = $magic->guessMimeType( $this->path
, false );
99 $info['mime'] = $magic->improveTypeFromExtension( $info['file-mime'], $ext );
101 list( $info['major_mime'], $info['minor_mime'] ) = File
::splitMime( $info['mime'] );
102 $info['media_type'] = $magic->getMediaType( $this->path
, $info['mime'] );
105 $info['size'] = $this->getSize();
107 # Height, width and metadata
108 $handler = MediaHandler
::getHandler( $info['mime'] );
110 $tempImage = (object)array();
111 $info['metadata'] = $handler->getMetadata( $tempImage, $this->path
);
112 $gis = $handler->getImageSize( $tempImage, $this->path
, $info['metadata'] );
113 if ( is_array( $gis ) ) {
114 $info = $this->extractImageSizeInfo( $gis ) +
$info;
117 $info['sha1'] = $this->getSha1Base36();
119 wfDebug(__METHOD__
.": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n");
121 wfDebug(__METHOD__
.": $this->path NOT FOUND!\n");
124 wfProfileOut( __METHOD__
);
129 * Placeholder file properties to use for files that don't exist
133 public static function placeholderProps() {
135 $info['fileExists'] = false;
136 $info['mime'] = null;
137 $info['media_type'] = MEDIATYPE_UNKNOWN
;
138 $info['metadata'] = '';
146 protected function extractImageSizeInfo( array $gis ) {
148 # NOTE: $gis[2] contains a code for the image type. This is no longer used.
149 $info['width'] = $gis[0];
150 $info['height'] = $gis[1];
151 if ( isset( $gis['bits'] ) ) {
152 $info['bits'] = $gis['bits'];
160 * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
161 * encoding, zero padded to 31 digits.
163 * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
166 * @return false|string False on failure
168 public function getSha1Base36() {
169 wfProfileIn( __METHOD__
);
171 wfSuppressWarnings();
172 $hash = sha1_file( $this->path
);
174 if ( $hash !== false ) {
175 $hash = wfBaseConvert( $hash, 16, 36, 31 );
178 wfProfileOut( __METHOD__
);
183 * Get an associative array containing information about a file in the local filesystem.
185 * @param $path String: absolute local filesystem path
186 * @param $ext Mixed: the file extension, or true to extract it from the filename.
187 * Set it to false to ignore the extension.
191 static function getPropsFromPath( $path, $ext = true ) {
192 $fsFile = new self( $path );
193 return $fsFile->getProps( $ext );
197 * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
198 * encoding, zero padded to 31 digits.
200 * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
203 * @param $path string
205 * @return false|string False on failure
207 static function getSha1Base36FromPath( $path ) {
208 $fsFile = new self( $path );
209 return $fsFile->getSha1Base36();