Skip to content

Commit e04c3b8

Browse files
committed
#87 - Detect file extension based on the detected content type
1 parent 5e3b7af commit e04c3b8

File tree

2 files changed

+274
-2
lines changed

2 files changed

+274
-2
lines changed

src/FileConverter.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace FileConverter;
1717
use FileConverter\Configuration\ConfigurationDefaults;
1818
use FileConverter\Configuration\ConfigurationOverride;
19+
use FileConverter\Util\FileInfo;
1920

2021
/**
2122
* The controlling FileConverter class.
@@ -150,8 +151,12 @@ public function convert($type = 'string', $convert_path = 'null->null', $source
150151

151152
public function convertFile($source, $destination, $convert_path = NULL) {
152153
if (!isset($convert_path)) {
153-
$convert_path = pathinfo($source, PATHINFO_EXTENSION) . '->'
154-
. pathinfo($destination, PATHINFO_EXTENSION);
154+
$source_ext = strtolower(trim(pathinfo($source, PATHINFO_EXTENSION)));
155+
if ($source_ext === '' && is_file($source)) {
156+
$source_ext = FileInfo::detectNormalExtension($source);
157+
}
158+
$destination_ext = pathinfo($destination, PATHINFO_EXTENSION);
159+
$convert_path = $source_ext . '->' . $destination_ext;
155160
}
156161
$this->convert('file', $convert_path, $source, $destination);
157162
return $this;

src/Util/FileInfo.php

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
<?php
2+
/*
3+
* This file is part of the FileConverter package.
4+
*
5+
* (c) Greg Payne
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace FileConverter\Util;
12+
13+
class FileInfo {
14+
/**
15+
* When multiple extensions have the same mime type, this array
16+
* determines which extension is preferred.
17+
* @var array
18+
*/
19+
static public $preferred = array(
20+
'jpg',
21+
);
22+
/**
23+
* Map file extensions to content types.
24+
* @var array
25+
*/
26+
static public $types = array(
27+
'' => 'application/octet-stream',
28+
'323' => 'text/h323',
29+
'acx' => 'application/internet-property-stream',
30+
'ai' => 'application/postscript',
31+
'aif' => 'audio/x-aiff',
32+
'aifc' => 'audio/x-aiff',
33+
'aiff' => 'audio/x-aiff',
34+
'asf' => 'video/x-ms-asf',
35+
'asr' => 'video/x-ms-asf',
36+
'asx' => 'video/x-ms-asf',
37+
'au' => 'audio/basic',
38+
'avi' => 'video/x-msvideo',
39+
'axs' => 'application/olescript',
40+
'bas' => 'text/plain',
41+
'bcpio' => 'application/x-bcpio',
42+
'bin' => 'application/octet-stream',
43+
'bmp' => 'image/bmp',
44+
'c' => 'text/plain',
45+
'cat' => 'application/vnd.ms-pkiseccat',
46+
'cdf' => 'application/x-cdf',
47+
'cer' => 'application/x-x509-ca-cert',
48+
'class' => 'application/octet-stream',
49+
'clp' => 'application/x-msclip',
50+
'cmx' => 'image/x-cmx',
51+
'cod' => 'image/cis-cod',
52+
'cpio' => 'application/x-cpio',
53+
'crd' => 'application/x-mscardfile',
54+
'crl' => 'application/pkix-crl',
55+
'crt' => 'application/x-x509-ca-cert',
56+
'csh' => 'application/x-csh',
57+
'css' => 'text/css',
58+
'csv' => 'text/csv',
59+
'dcr' => 'application/x-director',
60+
'der' => 'application/x-x509-ca-cert',
61+
'dir' => 'application/x-director',
62+
'dll' => 'application/x-msdownload',
63+
'dms' => 'application/octet-stream',
64+
'doc' => 'application/msword',
65+
'dot' => 'application/msword',
66+
'dvi' => 'application/x-dvi',
67+
'dxr' => 'application/x-director',
68+
'eps' => 'application/postscript',
69+
'etx' => 'text/x-setext',
70+
'evy' => 'application/envoy',
71+
'exe' => 'application/octet-stream',
72+
'fif' => 'application/fractals',
73+
'flr' => 'x-world/x-vrml',
74+
'gif' => 'image/gif',
75+
'gtar' => 'application/x-gtar',
76+
'gz' => 'application/x-gzip',
77+
'h' => 'text/plain',
78+
'hdf' => 'application/x-hdf',
79+
'hlp' => 'application/winhlp',
80+
'hqx' => 'application/mac-binhex40',
81+
'hta' => 'application/hta',
82+
'htc' => 'text/x-component',
83+
'htm' => 'text/html',
84+
'html' => 'text/html',
85+
'htt' => 'text/webviewhtml',
86+
'ico' => 'image/x-icon',
87+
'ief' => 'image/ief',
88+
'iii' => 'application/x-iphone',
89+
'ins' => 'application/x-internet-signup',
90+
'isp' => 'application/x-internet-signup',
91+
'jfif' => 'image/pipeg',
92+
'jpe' => 'image/jpeg',
93+
'jpeg' => 'image/jpeg',
94+
'jpg' => 'image/jpeg',
95+
'js' => 'application/x-javascript',
96+
'latex' => 'application/x-latex',
97+
'lha' => 'application/octet-stream',
98+
'lsf' => 'video/x-la-asf',
99+
'lsx' => 'video/x-la-asf',
100+
'lzh' => 'application/octet-stream',
101+
'm13' => 'application/x-msmediaview',
102+
'm14' => 'application/x-msmediaview',
103+
'm3u' => 'audio/x-mpegurl',
104+
'man' => 'application/x-troff-man',
105+
'mdb' => 'application/x-msaccess',
106+
'me' => 'application/x-troff-me',
107+
'mht' => 'message/rfc822',
108+
'mhtml' => 'message/rfc822',
109+
'mid' => 'audio/mid',
110+
'mny' => 'application/x-msmoney',
111+
'mov' => 'video/quicktime',
112+
'movie' => 'video/x-sgi-movie',
113+
'mp2' => 'video/mpeg',
114+
'mp3' => 'audio/mpeg',
115+
'mp4' => 'video/mp4',
116+
'mpa' => 'video/mpeg',
117+
'mpe' => 'video/mpeg',
118+
'mpeg' => 'video/mpeg',
119+
'mpg' => 'video/mpeg',
120+
'mpp' => 'application/vnd.ms-project',
121+
'mpv2' => 'video/mpeg',
122+
'ms' => 'application/x-troff-ms',
123+
'mvb' => 'application/x-msmediaview',
124+
'nws' => 'message/rfc822',
125+
'oda' => 'application/oda',
126+
'p10' => 'application/pkcs10',
127+
'p12' => 'application/x-pkcs12',
128+
'p7b' => 'application/x-pkcs7-certificates',
129+
'p7c' => 'application/x-pkcs7-mime',
130+
'p7m' => 'application/x-pkcs7-mime',
131+
'p7r' => 'application/x-pkcs7-certreqresp',
132+
'p7s' => 'application/x-pkcs7-signature',
133+
'pbm' => 'image/x-portable-bitmap',
134+
'pdf' => 'application/pdf',
135+
'pfx' => 'application/x-pkcs12',
136+
'pgm' => 'image/x-portable-graymap',
137+
'pko' => 'application/ynd.ms-pkipko',
138+
'pma' => 'application/x-perfmon',
139+
'pmc' => 'application/x-perfmon',
140+
'pml' => 'application/x-perfmon',
141+
'pmr' => 'application/x-perfmon',
142+
'pmw' => 'application/x-perfmon',
143+
'png' => 'image/png',
144+
'pnm' => 'image/x-portable-anymap',
145+
'pot,' => 'application/vnd.ms-powerpoint',
146+
'ppm' => 'image/x-portable-pixmap',
147+
'pps' => 'application/vnd.ms-powerpoint',
148+
'ppt' => 'application/vnd.ms-powerpoint',
149+
'prf' => 'application/pics-rules',
150+
'ps' => 'application/postscript',
151+
'psd' => 'application/octet-stream',
152+
'pub' => 'application/x-mspublisher',
153+
'qt' => 'video/quicktime',
154+
'ra' => 'audio/x-pn-realaudio',
155+
'ram' => 'audio/x-pn-realaudio',
156+
'ras' => 'image/x-cmu-raster',
157+
'rgb' => 'image/x-rgb',
158+
'rmi' => 'audio/mid',
159+
'roff' => 'application/x-troff',
160+
'rss' => 'text/xml',
161+
'rtf' => 'application/rtf',
162+
'rtx' => 'text/richtext',
163+
'scd' => 'application/x-msschedule',
164+
'sct' => 'text/scriptlet',
165+
'setpay' => 'application/set-payment-initiation',
166+
'setreg' => 'application/set-registration-initiation',
167+
'sh' => 'application/x-sh',
168+
'shar' => 'application/x-shar',
169+
'sit' => 'application/x-stuffit',
170+
'snd' => 'audio/basic',
171+
'spc' => 'application/x-pkcs7-certificates',
172+
'spl' => 'application/futuresplash',
173+
'src' => 'application/x-wais-source',
174+
'sst' => 'application/vnd.ms-pkicertstore',
175+
'stl' => 'application/vnd.ms-pkistl',
176+
'stm' => 'text/html',
177+
'sv4cpio' => 'application/x-sv4cpio',
178+
'sv4crc' => 'application/x-sv4crc',
179+
'swf' => 'application/x-shockwave-flash',
180+
't' => 'application/x-troff',
181+
'tar' => 'application/x-tar',
182+
'tcl' => 'application/x-tcl',
183+
'tex' => 'application/x-tex',
184+
'texi' => 'application/x-texinfo',
185+
'texinfo' => 'application/x-texinfo',
186+
'tgz' => 'application/x-compressed',
187+
'tif' => 'image/tiff',
188+
'tiff' => 'image/tiff',
189+
'tr' => 'application/x-troff',
190+
'trm' => 'application/x-msterminal',
191+
'tsv' => 'text/tab-separated-values',
192+
'txt' => 'text/plain',
193+
'uls' => 'text/iuls',
194+
'ustar' => 'application/x-ustar',
195+
'vcf' => 'text/x-vcard',
196+
'vrml' => 'x-world/x-vrml',
197+
'wav' => 'audio/x-wav',
198+
'wcm' => 'application/vnd.ms-works',
199+
'wdb' => 'application/vnd.ms-works',
200+
'wks' => 'application/vnd.ms-works',
201+
'wmf' => 'application/x-msmetafile',
202+
'wps' => 'application/vnd.ms-works',
203+
'wri' => 'application/x-mswrite',
204+
'wrl' => 'x-world/x-vrml',
205+
'wrz' => 'x-world/x-vrml',
206+
'xaf' => 'x-world/x-vrml',
207+
'xbm' => 'image/x-xbitmap',
208+
'xla' => 'application/vnd.ms-excel',
209+
'xlc' => 'application/vnd.ms-excel',
210+
'xlm' => 'application/vnd.ms-excel',
211+
'xls' => 'application/vnd.ms-excel',
212+
'xlt' => 'application/vnd.ms-excel',
213+
'xlw' => 'application/vnd.ms-excel',
214+
'xml' => 'text/xml',
215+
'xof' => 'x-world/x-vrml',
216+
'xpm' => 'image/x-xpixmap',
217+
'xwd' => 'image/x-xwindowdump',
218+
'z' => 'application/x-compress',
219+
'zip' => 'application/zip',
220+
// Office 2007 formats
221+
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
222+
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
223+
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
224+
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
225+
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
226+
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
227+
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
228+
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
229+
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
230+
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
231+
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
232+
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
233+
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
234+
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
235+
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
236+
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
237+
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
238+
);
239+
240+
static public function detectNormalExtension($path) {
241+
// Since FILEINFO_EXTENSION is not available until php7.2.0, convert type to extension.
242+
$type = array(
243+
self::detectContentType($path),
244+
);
245+
$extensions = array_intersect(self::$types, $type);
246+
if (sizeof($extensions) > 1) {
247+
$extensions = array_keys($extensions);
248+
$test = array_intersect($extensions, self::$preferred);
249+
if (!empty($test)) {
250+
return current($test);
251+
}
252+
return current($extensions);
253+
}
254+
return 'unknown';
255+
}
256+
257+
static public function detectContentType($path) {
258+
if (!is_file($path)) {
259+
throw new \InvalidArgumentException("Unable to detect content type of non-existent file.");
260+
}
261+
$finfo = finfo_open(FILEINFO_MIME_TYPE);
262+
$tmp = finfo_file($finfo, $path);
263+
finfo_close($finfo);
264+
return $tmp;
265+
}
266+
267+
}

0 commit comments

Comments
 (0)