1
<?php
2
/**
3
* Generic (re-usable) class to retrieve information on files / directories
4
*
5
* Class which can retrieve information on files, sub-directories and files within
6
* sub-directories.
7
*
8
* You can retrieve various kinds of lists with filenames as well as retrieve information
9
* about individual files, such as the file-size, file-last-access-date, file-last-modified-date
10
* and more.
11
*
12
* The class defaults to image files only, but based on the parameters you pass,
13
* information on any type of file can be retrieved.
14
*
15
* *********************************************************************<br>
16
* <b>Features</b><br>
17
* *********************************************************************
18
*
19
* - Generate a filelist / directory list as an array
20
* - Include subdirectories / files within subdirectories ($recursion = true)
21
* - Create a selection within the generated filelist based on:<br>
22
* * file extension(s)<br>
23
* * file extension(s) + mimetype check<br>
24
* * last modified date<br>
25
* * last access date
26
* - Create a selection within an earlier made selection
27
* - Sort the filelist
28
* - Find out which is the most recently changed file + the timestamp
29
* - Find out the directory size of<br>
30
* * a directory<br>
31
* * a directory and all subdirectories within it<br>
32
* * a selection of files within a directory<br>
33
* * same but then including selected files in subdirectories
34
* - Check whether the file extension of a file is within an allowed list (defaults to image files)
35
* - Check whether the mime-type of a file is within an allowed list (defaults to image files)
36
* - Combine the above two checks
37
* - Get information on individual files:<br>
38
* * filesize (optionally in a human readable format)<br>
39
* * last modified date (optionally in a - self-defined - human readable format)<br>
40
* * last access date (optionally in a - self-defined - human readable format)<br>
41
* * file permissions in a human readable format<br>
42
* * file owner id<br>
43
* * mime-type
44
* - Change an arbitrary filesize to a human readable format
45
*
46
* *********************************************************************<br>
47
* <b>Basics on how to use the class</b><br>
48
* *********************************************************************
49
*
50
* <i>How to view the results ?</i><br>
51
* You can format the results display yourself, to quickly retrieve and view a filelist, you can use:
52
* <code><?php
53
* // Get a filelist for $pathtodir, $recursion = true,
54
* // don't use a previously made selection (null)
55
* $dirobj->get_filelist( null, $pathtodir, true );
56
* print 'filecount is : ' . $dirobj->filecount;
57
* print '<pre>';
58
* print_r( $dirobj->filelist );
59
* print '</pre>';
60
* ?></code>
61
*
62
* <i>Note</i>: The directory path passed to a methods should be relative to the location
63
* of the calling file and should end with a trailing slash
64
* <code><?php
65
* $pathtodir = 'images/';
66
* ?></code>
67
*
68
* <b>For more extended examples of how to use this class, have a look at the example file which came
69
* with this class. It should be located in /example/example.php</b>
70
*
71
* @package DirInfo
72
* @author Juliette Reinders Folmer, {@link http://www.adviesenzo.nl/ Advies en zo} -
73
* <getdirectorylist@adviesenzo.nl>
74
*
75
* @todo Check whether the $pathtofile checks can be removed
76
*
77
*/
78
class DirInfo_Library {
79
/**
80
* Target directory to traverse
81
*
82
* - Relative path to a directory, i.e. relative to the calling file
83
* - IMPORTANT: end the path with a trailing '/' !!!
84
* - Defaults to the current directory
85
*
86
* @var string $pathtodir
87
*/
88
public $pathtodir = './';
89
90
/**
91
* Only show 'safe' files/directories ?
92
*
93
* - <i>true</i> means: only show 'safe' files (not .htaccess or references to higher directories)
94
* - <i>false</i> means: show all files
95
* - Defaults to <i>true</i>
96
*
97
* @var bool $safe_exts
98
**/
99
public $safe_exts = TRUE;
100
101
/**
102
* Array of file extensions
103
*
104
* The list is used to determine which files should be included in the result array if you want
105
* to make a selection based on file extensions
106
* - Should be an array of file extensions to show only files which comply with these extensions
107
* - Alternatively, the special string-value <i>all</i> will show files independent
108
* of extensions.
109
* - Defaults to typical image file extensions (jpg, gif, jpeg, png)
110
*
111
* @see check_file_extension()
112
* @see check_allowed_file()
113
* @var array|string $exts
114
*/
115
public $exts = array('jpg', 'gif', 'jpeg', 'png', 'php', 'html');
116
117
/**
118
* Array of mime types
119
*
120
* The list is used to determine which files should be included in the result array if you want
121
* to strictly check that the files returned not only comply with the file extensions given, but
122
* are also of the expected mimetype.
123
* - Should be an array of mimetypes to show only files which comply with these mimetypes
124
* - High level mimetypes (content-types such as <i>image</i>) may be used and will be converted
125
* to an array which covers all mimetypes within that content-type.
126
* - If left empty and a strict check is done via the {@link check_allowed_file()} method, the
127
* relevant mimetypes will be guessed based on the passed extensions.
128
* - Defaults to typical image file extensions (jpg, gif, jpeg, png)
129
*
130
* @see check_file_mimetype()
131
* @see check_allowed_file()
132
* @see $exts
133
* @var array $mimetypes
134
*/
135
public $mimetypes = array('image/jpeg', 'image/png', 'image/gif');
136
137
/**
138
* Do a strict file type check ?
139
*
140
* Whether to check whether the files with the correct extension *really* are of the
141
* mime-type you would expect for a file with that extension.
142
* - Defaults to <i>false</i>, i.e. don't do a strict check
143
*
144
* @see $mime_map
145
* @see $valid_mime_types
146
* @var boolean $strict
147
*/
148
public $strict = FALSE;
149
150
/**
151
* Default format string for the human readable last modified and last access date
152
*
153
* - Refer to the {@link http://www.php.net/function.date php documentation} for information
154
* on formatting strings available.
155
* - If set to an empty string, the {@link get_human_readable_lastacc()} and
156
* {@link get_human_readable_lastmod()} methods will return an
157
* unformatted unix timestamp.
158
* - Defaults to <i>Y-m-d H:i:s</i> which should display something like <i>2006-08-31 00:00:00</i>
159
*
160
* @link http://www.php.net/function.date
161
* @var string $date_time_format
162
**/
163
public $datetime_format = 'Y-m-d H:i:s';
164
165
166
/**
167
* Suffixes for use when creating human readable file size string
168
*
169
* @internal ALWAYS (manually) adjust {@link $byte_suffix_count} if suffixes are
170
* added or deleted from this array
171
*
172
* @access private
173
* @var array $byte_suffixes
174
**/
175
public $byte_suffixes = array('b', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
176
177
/**
178
* Number of byte suffixes available
179
*
180
* @internal ALWAYS (manually) adjust this if {@link $byte_suffixes} gets changed
181
*
182
* @access private
183
* @see $byte_suffixes
184
* @var int $byte_suffix_count
185
**/
186
public $byte_suffix_count = 9;
187
188
/**
189
* Filelist result array
190
*
191
* @var array $filelist
192
**/
193
public $filelist = array();
194
195
/**
196
* Filelist selection result array
197
*
198
* @var array $filelist_selection
199
*/
200
public $filelist_selection = array();
201
202
/**
203
* Directory result array
204
*
205
* @var array $dirlist
206
*/
207
public $dirlist = array();
208
209
/**
210
* File count result variable
211
*
212
* Count of number of files in {@link $filelist}
213
* @var int $filecount
214
**/
215
public $filecount = 0;
216
217
/**
218
* File count of selection result variable
219
*
220
* Count of number of files in {@link $filelist_selection}
221
* @var int $fileselection_count
222
**/
223
public $fileselection_count = 0;
224
225
/**
226
* Directory count result variable
227
*
228
* Count of number of directories in {@link $dirlist}
229
* @var int $dircount
230
**/
231
public $dircount = 0;
232
233
/**
234
* Remember last path traversed for efficiency
235
*
236
* @see $pathtodir
237
* @var string $last_path
238
*/
239
public $last_path;
240
241
/**
242
* Remember last recursive setting for efficiency
243
*
244
* - Default for recursion is <i>false</i>
245
*
246
* @var string $last_recursive
247
*/
248
public $last_recursive;
249
250
/**
251
* Remember last passed extensions for efficiency
252
*
253
* @see $exts
254
* @var array|string $last_passed_exts
255
*/
256
public $last_passed_exts;
257
258
/**
259
* Remember last validated extensions for efficiency
260
*
261
* @see $exts
262
* @var array|string $last_exts
263
*/
264
public $last_exts;
265
266
/**
267
* Remember last passed mimetypes for efficiency
268
*
269
* @see $mimetypes
270
* @var array $last_passed_mimetypes
271
*/
272
public $last_passed_mimetypes;
273
274
/**
275
* Remember last validated mimetypes for efficiency
276
*
277
* @see $mimetypes
278
* @var array $last_mimetypes
279
*/
280
public $last_mimetypes;
281
282
283
/**
284
* Constructor - Sets Preferences
285
*
286
*/
287
public function __construct() {}
288
289
/**
290
* Basic validation and parsing of a passed extensions parameter
291
*
292
* - This method does *not* check whether the extensions passed *are* real-life extensions,<br>
293
* i.e. it does not spell check nor check against a list of 'known' extensions.
294
* - If no parameter is passed or the parameter passed is not a string nor an array
295
* it defaults to the class default
296
* - If the passed $exts are the same as the last time this method was used, the check will
297
* be skipped and the results of last time will be used for efficiency
298
*
299
* @access private
300
* @uses $last_passed_exts for efficiency check / sets the variable if the current
301
* passed $exts is different
302
* @uses $last_exts for efficiency if the passed exts were already checked /
303
* sets this variable for same use if the passed $exts was
304
* different
305
* @uses $exts to default to if no valid extensions parameter was passed
306
* @param array|string $exts [optional] extensions parameter to validate
307
* @return array|string array of extensions or the string 'all'
308
*/
309
public function validate_extension_list($exts = NULL) {
310
if ($exts !== $this->last_passed_exts || is_null( $this->last_passed_exts)) {
311
312
$this->last_passed_exts = $exts;
313
314
// If it's a string, check for all, otherwise create an array containing 1 item
315
if (is_string($exts) && $exts !== '') {
316
if ( strtolower($exts) === 'all') {
317
$this->last_exts = strtolower($exts);
318
} else {
319
$this->last_exts = (array(strtolower($exts)));
320
}
321
}
322
323
// If it's an array, make lowercase (which will cast the extension to string automatically)
324
elseif (is_array($exts) && count($exts) > 0) {
325
$ext_array = array();
326
foreach ($exts as $ext) {
327
$ext_array[] = strtolower($ext);
328
}
329
$this->last_exts = $ext_array;
330
}
331
332
// Otherwise return the default
333
else {
334
$this->last_exts = $this->exts;
335
}
336
}
337
338
return $this->last_exts;
339
}
340
341
/**
342
* Validation and parsing of a passed mimetypes parameter
343
*
344
* - This method checks whether a passed array of mimetypes is valid against the official list of
345
* valid types
346
* - Invalid mimetypes will be removed from the array
347
* - If a string is passed, it will be turned into a 1-item array and validated as if it were an
348
* array
349
* - If an array item validates as a content-type mimetype, all subtypes for that content-type will
350
* be added to the array as valid mimetypes
351
* - If no mimetypes were passed or no valid mimetypes were found, the class default will be used
352
* - If the passed $mimetypes are the same as the last time this method was used, the check will
353
* be skipped and the results of last time will be used for efficiency
354
*
355
* @access private
356
* @uses $last_passed_mimetypes for efficiency check / sets the variable if the current
357
* passed $mimetypes is different
358
* @uses $last_mimetypes for efficiency if the passed mimetypes were already checked /
359
* sets this variable for same use if the passed $mimetypes was
360
* different
361
* @uses $mimetypes to default to if no valid mimetypes were found
362
* @uses $valid_mime_types to validate the passed mimetypes and to retrieve subtypes
363
* @param array $mimetypes [optional] mimetypes to validate
364
* @return array validated mimetypes
365
*/
366
public function validate_mime_types($mimetypes = NULL) {
367
if ($mimetypes !== $this->last_passed_mimetypes || is_null($this->last_passed_mimetypes)) {
368
369
$this->last_passed_mimetypes = $mimetypes;
370
371
if (is_string($mimetypes) && $mimetypes !== '') {
372
// Cast to array and pass through
373
$mimetypes = array($mimetypes);
374
}
375
376
if (is_array($mimetypes) && count($mimetypes) > 0) {
377
378
$mime_array = array();
379
380
foreach ($mimetypes as $mimetype) {
381
if (is_string( $mimetype ) && $mimetype !== '') {
382
if (strpos($mimetype, '/') === FALSE) {
383
if (isset($this->valid_mime_types[$mimetype])) {
384
foreach ($this->valid_mime_types[$mimetype] as $subtype) {
385
$mime_array[] = $mimetype . '/' . $subtype;
386
}
387
}
388
} else {
389
$mimeparts = explode( '/', $mimetype, 2 );
390
if (in_array($mimeparts[1], $this->valid_mime_types[$mimeparts[0]], TRUE)) {
391
$mime_array[] = $mimetype;
392
}
393
}
394
}
395
}
396
397
if (count($mime_array) > 0) {
398
$this->last_mimetypes = array_unique($mime_array);
399
}
400
} else {
401
$this->last_mimetypes = $this->mimetypes;
402
}
403
}
404
405
return $this->last_mimetypes;
406
}
407
408
/**
409
* Clears the file stat cache and checks whether the passed $pathtofile is a valid path to a file
410
*
411
* @param string $pathtofile
412
* @return bool
413
*/
414
public static function valid_pathtofile($pathtofile) {
415
clearstatcache();
416
417
// Check if a non empty string has been passed as pathtofile
418
return ((is_string($pathtofile) && $pathtofile !== '') && file_exists($pathtofile));
419
}
420
421
/**
422
* Check whether the file is allowed based on extension and if $strict=true also on mimetype
423
*
424
* - Will use the class defaults for optional parameters which were not passed
425
* - Will try to 'guess' the mimetypes if a strict check is requested, but no mimetypes were
426
* passed
427
* - Returns <i>true</i> is the file passes, <i>false</i> if not.
428
*
429
* @see $exts
430
* @see $strict
431
* @see $mimetypes
432
* @uses $mime_map to 'guess' mimetypes based on $exts if no $mimetypes parameter
433
* was passed and a strict check was requested
434
* @uses validate_extension_list() to validate the passed extension list
435
* @uses check_file_extension() to validate the file against the extension list
436
* @uses check_file_mimetype() to validate the file against the mimetypes
437
* @param string $pathtofile path to the file to check
438
* @param array|string $exts [optional] allowed extensions
439
* @param bool $strict [optional] whether or not to check on mimetype
440
* @param array $mimetypes [optional] allowed mimetypes
441
* @return bool
442
*/
443
public function check_allowed_file($pathtofile, $exts = NULL, $strict = NULL, $mimetypes = NULL) {
444
$strict = (is_bool($strict)) ? $strict : $this->strict;
445
446
if ($strict) {
447
448
/**
449
* We only try to build a mimetype list based on the extensions when exts is not null,
450
* not all nor the default and mimetypes is null.
451
* In all other cases this is not needed as the {@see check_file_extension()}
452
* and the {@see check_file_mimetype()} will validate the passed parameters anyway
453
* and will default to the class default.
454
*/
455
if (is_null($mimetypes) && ! is_null($exts)) {
456
$exts = $this->validate_extension_list($exts);
457
458
if (is_string($exts) && strtolower($exts) === 'all') {
459
// Fall through - mimetype check superfluous
460
return ($this->check_file_extension($pathtofile, $exts));
461
} elseif ($exts === $this->exts && ! is_null($this->mimetypes)) {
462
$mimetypes = $this->mimetypes;
463
} else {
464
$exts = $this->validate_extension_list($exts);
465
$mimetypes = array();
466
foreach ($exts as $ext) {
467
if (isset($this->mime_map[$ext])) {
468
$mimetypes[] = $this->mime_map[$ext];
469
} else {
470
trigger_error('The file extension <em>' . $ext . '</em> does not have a valid mime-type associated with it in the mime_map', E_USER_WARNING);
471
}
472
}
473
$mimetypes = array_unique($mimetypes);
474
}
475
}
476
return ($this->check_file_extension($pathtofile, $exts) && $this->check_file_mimetype($pathtofile, $mimetypes) );
477
} else {
478
return ($this->check_file_extension($pathtofile, $exts));
479
}
480
}
481
482
/**
483
* Check the file extension of a filename against the list of allowed extensions
484
*
485
* - This is a case-insensitive extension check
486
* - Will use the class defaults for optional parameters which were not passed
487
* - Returns <i>true</i> if the filename passes the valid extension check
488
* - Returns <i>false</i> is it fails or if the passed filename parameter is not a string
489
*
490
* @see $exts
491
* @uses validate_extension_list() used to parse the extension list to the expected format
492
* @param string $filename filename to check
493
* @param array|string $exts [optional] array of allowed extensions
494
* @return bool
495
**/
496
public function check_file_extension($filename, $exts = NULL) {
497
// Check if a non empty string has been passed as filename
498
if( ! is_string($filename) || $filename === '') {
499
return FALSE;
500
}
501
502
// Validate the optional parameters and default to the class defaults if not passed or invalid
503
$exts = $this->validate_extension_list( $exts );
504
505
// If all extensions are allowed, return true
506
if($exts === 'all') {
507
return TRUE;
508
}
509
510
// If the function is still running, check the extension against the allowed extension list
511
$pos = strrpos($filename, '.');
512
if($pos !== FALSE) {
513
// Strip the everything before and including the '.'
514
$file_ext = substr($filename, ($pos + 1));
515
return(in_array($file_ext, $exts, TRUE));
516
}
517
518
// No extension found
519
return FALSE;
520
}
521
522
/**
523
* Check the file-mimetype against a list of allowed mimetypes
524
*
525
* - Will use the class defaults for optional parameters which were not passed
526
* - Returns <i>true</i> if the file-mimetype is within the list of allowed mimetypes
527
* - Returns <i>false</i> if not or if the passed filename parameter is not a string
528
*
529
* @see $mimetypes
530
* @uses valid_pathtofile() to check whether the $pathtofile parameter is valid
531
* @uses validate_mime_types() to validate the passed mimetypes
532
* @uses get_mime_content_type() to retrieve the file mimetype
533
* @param string $pathtofile
534
* @param array $mimetypes [optional] array of valid mimetypes
535
* @return bool
536
*/
537
public function check_file_mimetype($pathtofile, $mimetypes = NULL) {
538
if( !$this->valid_pathtofile($pathtofile)) {
539
return FALSE;
540
}
541
$mimetypes = $this->validate_mime_types($mimetypes);
542
$file_mimetype = $this->get_mime_content_type($pathtofile);
543
return (in_array($file_mimetype, $mimetypes));
544
}
545
546
547
/**
548
* Get the filesize of a file
549
*
550
* @static
551
* @link http://www.php.net/function.filesize
552
* @uses valid_pathtofile() to check whether the passed parameter is a file
553
* @param string $pathtofile
554
* @return int|false filesize or false if an invalid $pathtofile was passed
555
*/
556
public function get_filesize($pathtofile) {
557
if( ! self::valid_pathtofile($pathtofile)) {
558
return FALSE;
559
}
560
return filesize($pathtofile);
561
}
562
563
/**
564
* Get the filesize of a file in a human readable format
565
*
566
* @uses get_filesize() to retrieve the filesize
567
* @uses human_readable_filesize() to convert the filesize to a human readable string
568
* @param string $pathtofile
569
* @return string|false human readable filesize string or false if an invalid
570
* $pathtofile was passed
571
*/
572
public function get_human_readable_filesize($pathtofile) {
573
$filesize = $this->get_filesize($pathtofile);
574
return (($filesize !== FALSE) ? $this->human_readable_filesize($filesize) : FALSE);
575
}
576
577
/**
578
* Creates a human readable file size string
579
*
580
* - Rounds bytes and kilobytes to the nearest integer
581
* - Rounds anything else to one digit behind the decimal point
582
* - Returns <i>false</i> is the passed parameter is not an integer or a numeric string
583
*
584
* Examples:<br>
585
* the integer <i>1080</i> becomes the string <i>1 kB</i><br>
586
* the integer <i>3000000</i> becomes the string <i>2.8 MB</i>
587
*
588
* @uses $byte_suffixes for the byte suffixes
589
* @uses $byte_suffix_count
590
* @param int $filesize filesize in bytes
591
* @return string|false human readable filesize string
592
* or false if the passed variable was not an integer
593
**/
594
public function human_readable_filesize($filesize) {
595
if (is_int($filesize) && $filesize > 0) {
596
597
// Get the figure to use in the string
598
for ($i = 0; ($i < $this->byte_suffix_count && $filesize >= 1024 ); $i++) {
599
$filesize = $filesize / 1024;
600
}
601
602
// Return the rounded figure with the appropriate suffix
603
if ($this->byte_suffixes[$i] === 'b' || $this->byte_suffixes[$i] === 'kB') {
604
return (round($filesize, 0) . ' ' . $this->byte_suffixes[$i]);
605
} else {
606
return (round($filesize, 1) . ' ' . $this->byte_suffixes[$i]);
607
}
608
} else {
609
return FALSE;
610
}
611
}
612
613
/**
614
* Get the last modified unix timestamp for a file
615
*
616
* @static
617
* @link http://www.php.net/function.filemtime
618
* @uses valid_pathtofile() to check whether the passed parameter is a file
619
* @param string $pathtofile
620
* @return int|false unix timestamp or false if an invalid $pathtofile was passed
621
*/
622
public function get_lastmod_unixts($pathtofile) {
623
if ( ! self::valid_pathtofile($pathtofile)) {
624
return FALSE;
625
}
626
return filemtime($pathtofile);
627
}
628
629
/**
630
* Get the last modified timestamp of a file in a human readable format
631
*
632
* @uses get_lastmod_unixts() to retrieve the last modified unix timestamp
633
* @uses $datetime_format as a default date/time format if no format was passed
634
* @param string $pathtofile
635
* @param string $datetime_format [optional]
636
* @return string|false human readable date/time string or false if an invalid
637
* $pathtofile was passed
638
*/
639
public function get_human_readable_lastmod($pathtofile, $datetime_format = NULL) {
640
if ( ! is_string($datetime_format) || $datetime_format === '') {
641
$datetime_format = $this->datetime_format;
642
}
643
$uts = $this->get_lastmod_unixts($pathtofile);
644
return (($datetime_format !== '' && $uts !== FALSE) ? date($datetime_format, $uts) : FALSE);
645
}
646
647
/**
648
* Get the last access unix timestamp for a file
649
*
650
* @static
651
* @link http://www.php.net/function.fileatime
652
* @uses valid_pathtofile() to check whether the passed parameter is a file
653
* @param string $pathtofile
654
* @return int|false unix timestamp or false if an invalid $pathtofile was passed
655
*/
656
public function get_lastacc_unixts($pathtofile) {
657
if ( ! self::valid_pathtofile($pathtofile)) {
658
return FALSE;
659
}
660
return fileatime($pathtofile);
661
}
662
663
/**
664
* Get the last access timestamp of a file in a human readable format
665
*
666
* @uses get_lastacc_unixts() to retrieve the last access unix timestamp
667
* @uses $datetime_format as a default date/time format if no format was passed
668
* @param string $pathtofile
669
* @param string $datetime_format [optional]
670
* @return string|false human readable date/time string or false if an invalid
671
* $pathtofile was passed
672
*/
673
public function get_human_readable_lastacc($pathtofile, $datetime_format = NULL) {
674
if ( ! is_string($datetime_format) || $datetime_format === '') {
675
$datetime_format = $this->datetime_format;
676
}
677
$uts = $this->get_lastacc_unixts( $pathtofile );
678
return (($datetime_format !== '' && $uts !== FALSE) ? date($datetime_format, $uts) : FALSE);
679
}
680
681
/**
682
* Get the file owner for a file
683
*
684
* @static
685
* @link http://www.php.net/function.fileowner
686
* @uses valid_pathtofile() to check whether the passed parameter is a file
687
* @param string $pathtofile
688
* @return int|false user id of the file owner or false if an invalid $pathtofile was passed
689
*/
690
public function get_file_owner($pathtofile) {
691
if ( ! self::valid_pathtofile($pathtofile)) {
692
return FALSE;
693
}
694
return fileowner($pathtofile);
695
}
696
697
/**
698
* Get the mime content type of a file
699
*
700
* @static
701
* @author keczerad at poczta dot fm - 30-Aug-2006 10:38
702
* @link http://www.php.net/function.mime-content-type
703
* @uses valid_pathtofile() to check whether the passed parameter is a file
704
* @param string $pathtofile
705
* @return string|false mimetype string or false if an invalid $pathtofile was passed
706
*/
707
public function get_mime_content_type($pathtofile) {
708
if ( ! self::valid_pathtofile($pathtofile)) {
709
return FALSE;
710
}
711
// http://us.php.net/manual/en/function.mime-content-type.php
712
// This function has been deprecated as the PECL extension
713
// Fileinfo provides the same functionality (and more) in a much cleaner way.
714
if (function_exists('mime_content_type')) {
715
return mime_content_type($pathtofile);
716
} else {
717
return exec(trim('file -bi ' . escapeshellarg($pathtofile))) ;
718
}
719
}
720
721
/**
722
* Get a human readable file permission string for a file
723
*
724
* @static
725
* @link http://www.php.net/function.fileperms
726
* @uses valid_pathtofile() to check whether the passed parameter is a file
727
* @param string $pathtofile
728
* @return string|false file permission string or false if an invalid $pathtofile was passed
729
*/
730
public function get_human_readable_file_permissions($pathtofile) {
731
732
if ( ! self::valid_pathtofile($pathtofile)) {
733
return FALSE;
734
}
735
736
$perms = fileperms( $pathtofile );
737
738
if (($perms & 0xC000) == 0xC000) {$info = 's';} // Socket
739
elseif (($perms & 0xA000) == 0xA000) {$info = 'l';} // Symbolic Link
740
elseif (($perms & 0x8000) == 0x8000) {$info = '-';} // Regular
741
elseif (($perms & 0x6000) == 0x6000) {$info = 'b';} // Block special
742
elseif (($perms & 0x4000) == 0x4000) {$info = 'd';} // Directory
743
elseif (($perms & 0x2000) == 0x2000) {$info = 'c';} // Character special
744
elseif (($perms & 0x1000) == 0x1000) {$info = 'p';} // FIFO pipe
745
else { $info = 'u'; } // Unknown
746
747
// Owner
748
$info .= (($perms & 0x0100) ? 'r' : '-');
749
$info .= (($perms & 0x0080) ? 'w' : '-');
750
$info .= (($perms & 0x0040) ?
751
(($perms & 0x0800) ? 's' : 'x' ) :
752
(($perms & 0x0800) ? 'S' : '-' ) );
753
754
// Group
755
$info .= (($perms & 0x0020) ? 'r' : '-');
756
$info .= (($perms & 0x0010) ? 'w' : '-');
757
$info .= (($perms & 0x0008) ?
758
(($perms & 0x0400) ? 's' : 'x') :
759
(($perms & 0x0400) ? 'S' : '-'));
760
761
// World
762
$info .= (($perms & 0x0004) ? 'r' : '-');
763
$info .= (($perms & 0x0002) ? 'w' : '-');
764
$info .= (($perms & 0x0001) ?
765
(($perms & 0x0200) ? 't' : 'x') :
766
(($perms & 0x0200) ? 'T' : '-'));
767
768
return $info;
769
}
770
771
/**
772
* Get list of files in $pathtodir
773
*
774
* - Use this method to retrieve a filelist for a certain directory path
775
* - If a filelist was created before and you want to retrieve this list, you can use this function
776
* without any parameters and it will return the previously created list
777
* - If you created a selection based on the earlier created filelist, you can choose to retrieve
778
* that selection instead by setting $use_selection to <i>true</i>
779
* - If no filelist was created before and no parameters are passed, it will retrieve a filelist
780
* based on the class defaults
781
* - If you call this method as a static method, logically you can not retrieve an earlier
782
* created listing or selection list
783
*
784
* @uses $last_path to check whether the requested list already exists
785
* @uses $last_recursive to check whether the requested list already exists
786
* @uses traverse_directory() to retrieve a new filelist if needed
787
* @uses $filelist to return the list as stored by {@link traverse_directory}
788
* now or earlier
789
* @uses $filecount to check that $filelist contains results if the requested list
790
* already seemed to exist
791
* @uses $pathtodir to default to if no $pathtodir was passed
792
* @uses $fileselection_count to check that $filelist_selection contains results if the
793
* requested list already seemed to exist and the last selection was
794
* requested - if selection was empty, then the complete list will be
795
* returned
796
* @uses $filelist_selection to return the selection list if the selection list was
797
* not empty and the selection was requested
798
*
799
* @param bool $use_selection [optional] whether or not the last made selection should
800
* be returned if available
801
* @param string $pathtodir [optional] path to the directory for which to get the list
802
* @param bool $recursive [optional] whether to retrieve information on files in
803
* subdirectories
804
* @return array array of filenames
805
*/
806
public function get_filelist($use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
807
// If a pathtodir was passed and the path to dir was not the same as the last one used
808
// to get a filelist, build a new filelist
809
if ( ! is_null($pathtodir) && ($pathtodir !== $this->last_path || $recursive !== $this->last_recursive)) {
810
$this->traverse_directory($pathtodir, $recursive);
811
return $this->filelist;
812
} elseif (is_null($pathtodir) && $this->filecount === 0) {
813
$this->traverse_directory($this->pathtodir, $recursive);
814
return $this->filelist;
815
} elseif ($use_selection === TRUE && $this->fileselection_count > 0) {
816
return $this->filelist_selection;
817
} else {
818
return $this->filelist;
819
}
820
}
821
822
/**
823
* Get a list of directories in $pathtodir
824
*
825
* @see get_filelist() for more information on retrieving an earlier created list
826
* @uses $last_path to check whether the requested list already exists
827
* @uses $last_recursive to check whether the requested list already exists
828
* @uses traverse_directory() to retrieve a new dirlist if needed
829
* @uses $dirlist to return the list as stored by {@link traverse_directory}
830
* now or earlier
831
* @param string $pathtodir [optional] path to the directory for which to get the list
832
* @param bool $recursive [optional] whether to retrieve information on directories in
833
* subdirectories
834
* @return array array of filenames
835
*/
836
public function get_dir_list($pathtodir, $recursive = NULL) {
837
if ( ! is_null($pathtodir) && ($pathtodir !== $this->last_path || $recursive !== $this->last_recursive)) {
838
$this->traverse_directory($pathtodir, $recursive);
839
} elseif(is_null($pathtodir ) && $this->dircount === 0) {
840
$this->traverse_directory($this->pathtodir, $recursive);
841
}
842
return $this->dirlist;
843
}
844
845
/**
846
* Function to traverse a directory
847
*
848
* - This is the actual workhorse method which traverses the directory
849
* - This method checks whether something is a file before accepting the file in the filelist
850
* - This method uses the {@link $safe_exts} class setting to determine whether or not to include
851
* 'unsafe' files
852
* - This function can be called recursively for subdirectories, but this has to be explicitely set
853
* Default is non-recursive
854
* - The results of the function are stored in the class variables {@link $filelist},
855
* {@link $filecount}, {@link $dirlist} and {@link $dircount}
856
*
857
* @access private
858
* @link http://www.php.net/function.readdir
859
* @uses $last_path sets this variable
860
* @uses $last_recursive sets this variable
861
* @uses $filelist_selection re-sets this variable
862
* @uses $fileselection_count re-sets this variable
863
* @uses $filelist to store the results
864
* (sorted ascendingly in case-insensitive natural sort order)
865
* @uses $filecount to store a count of $filelist
866
* @uses $dirlist to store the results
867
* (sorted ascendingly in case-insensitive natural sort order)
868
* @uses $dircount to store a count of $dirlist
869
*
870
* @param string $pathtodir [optional] path to the directory for which to get the list
871
* @param bool $recursive [optional] whether to retrieve information on files in
872
* subdirectories
873
* @param string $prefix [optional] gets set internally when this function
874
* is used recursively
875
* @return void sets class variables {@link $filelist} and {@link $filecount}
876
*
877
*/
878
public function traverse_directory($pathtodir, $recursive = FALSE, $prefix = '') {
879
880
if ($prefix === '') {
881
$this->last_path = $pathtodir;
882
$this->last_recursive = $recursive;
883
$this->filelist = array();
884
$this->filelist_selection = array();
885
$this->dirlist = array();
886
$this->filecount = 0;
887
$this->fileselection_count = 0;
888
$this->dircount = 0;
889
}
890
891
if ($handle = @opendir($pathtodir)) {
892
while (($filename = readdir($handle)) !== FALSE) {
893
// Check if the file is an 'unsafe' one such as .htaccess or
894
// higher directory references, if so, skip
895
if ($this->safe_exts === TRUE && strpos($filename, '.') === 0) {
896
// do nothing
897
} else {
898
// If it's a file, check against valid extensions and add to the list
899
if (is_file($pathtodir . $filename) === TRUE) {
900
$this->filelist[] = $prefix . $filename;
901
}
902
903
// If it's a directory and subdirectories should be listed,
904
// add the subdirectory to the list.
905
// If files from subdirs should be listed, run this function on the subdirectory
906
elseif (is_dir($pathtodir . $filename) === TRUE) {
907
$this->dirlist[] = $prefix . $filename . '/';
908
if ($recursive === TRUE) {
909
$this->traverse_directory( $pathtodir . $filename . '/', $recursive, $prefix . $filename . '/' );
910
}
911
}
912
}
913
unset($filename);
914
}
915
closedir($handle);
916
917
$this->filecount = count($this->filelist);
918
$this->dircount = count($this->dirlist);
919
920
921
if ($this->dircount > 1) {
922
natcasesort($this->dirlist);
923
$this->dirlist = array_values($this->dirlist);
924
}
925
if ($this->filecount > 1) {
926
natcasesort($this->filelist);
927
$this->filelist = array_values( $this->filelist );
928
}
929
}
930
}
931
932
933
/**
934
* Retrieve a filelist which only contains files which comply with the allowed extension/mimetypes
935
*
936
* - Creates a selection list of files which comply with the criteria set by
937
* allowed extensions / allowed mimetypes
938
* - $strict determined whether or not to check on mimetype
939
* - $exts, $strict and $mimetypes default to the class defaults if not passed
940
*
941
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
942
* more information on retrieving listings already created
943
* @uses check_allowed_file() to check for each file whether it complies with the criteria
944
* @uses $filelist_selection to store the results
945
* @uses $fileselection_count to store a count of the results
946
*
947
* @param bool $use_selection [optional] whether or not the last made selection should
948
* be returned if available
949
* @param string $pathtodir [optional] path to the directory for which to get the list
950
* @param bool $recursive [optional] whether to retrieve information on files in
951
* subdirectories
952
* @param array|string $exts [optional] allowed extensions
953
* @param bool $strict [optional] whether or not to check on mimetype
954
* @param array $mimetypes [optional] allowed mimetypes
955
* @return array array of filenames of files which pass the test
956
*/
957
public function get_ext_based_filelist($use_selection = NULL, $pathtodir = NULL, $recursive = NULL, $exts = NULL, $strict = NULL, $mimetypes = NULL) {
958
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
959
960
$passed_files = array();
961
962
foreach ($files as $filename) {
963
if ($this->check_allowed_file($this->last_path . $filename, $exts, $strict, $mimetypes)) {
964
$passed_files[] = $filename;
965
}
966
}
967
968
$this->filelist_selection = $passed_files;
969
$this->fileselection_count = count($this->filelist_selection);
970
return $this->filelist_selection;
971
}
972
973
974
/**
975
* Retrieve a sorted filelist
976
*
977
* - Mainly useful for reverse sorting as the normal filelist is already sorted in
978
* ascending order
979
* - Defaults to <i>ascending</i> sort order
980
* - To sort descendingly, set $sort_asc to <i>false</i>
981
* - The list sorting will always use case-insensitive natural sort order
982
* - Retrieving a sorted list will not affect the order of the class 'remembered' filelists
983
*
984
* @link http://www.php.net/function.natcasesort
985
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
986
* more information on retrieving listings already created
987
* @param bool $sort_asc [optional] set to false for reverse / descending sorted list
988
* @param bool $use_selection [optional] whether or not the last made selection should
989
* be returned if available
990
* @param string $pathtodir [optional] path to the directory for which to get the list
991
* @param bool $recursive [optional] whether to retrieve information on files in
992
* subdirectories
993
* @return array sorted array of filenames
994
*/
995
public function get_sorted_filelist($sort_asc = NULL, $use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
996
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
997
998
// Sort the resulting file list
999
if (count( $files ) > 1) {
1000
natcasesort($files);
1001
if ($sort_asc === FALSE) {
1002
$files = array_reverse($files, TRUE);
1003
}
1004
$files = array_values($files);
1005
}
1006
return $files;
1007
}
1008
1009
/**
1010
* Retrieve a sorted (sub-)directory list
1011
*
1012
* - Mainly useful for reverse sorting as the normal dirlist is already sorted in
1013
* ascending order
1014
* - Defaults to <i>ascending</i> sort order
1015
* - To sort descendingly, set $sort_asc to <i>false</i>
1016
* - The list sorting will always use case-insensitive natural sort order
1017
* - Retrieving a sorted list will not affect the order of the class 'remembered' dirlist
1018
*
1019
* @link http://www.php.net/function.natcasesort
1020
* @see get_filelist() for more information on retrieving an earlier created list
1021
* @uses get_dir_list() to retrieve the directory list
1022
* @param bool $sort_asc [optional] set to false for reverse / descending sorted list
1023
* @param string $pathtodir [optional] path to the directory for which to get the list
1024
* @param bool $recursive [optional] whether to retrieve information on directories in
1025
* subdirectories
1026
* @return array sorted array of (sub-)directory names
1027
*/
1028
public function get_sorted_dirlist($sort_asc = NULL, $pathtodir = NULL, $recursive = NULL) {
1029
$dirs = $this->get_dir_list($pathtodir, $recursive);
1030
1031
// Sort the resulting file list
1032
if (count( $dirs ) > 1) {
1033
natcasesort($dirs);
1034
if ($sort_asc === FALSE) {
1035
$dirs = array_reverse($dirs, TRUE);
1036
}
1037
$dirs = array_values($dirs);
1038
}
1039
return $dirs;
1040
}
1041
1042
/**
1043
* Retrieve the filename and last_modified date of the most recently modified file
1044
*
1045
* Inspired by a comment from wookie at at no-way dot org - 14-Sep-2003 11:17
1046
*
1047
* @link http://www.php.net/function.filemtime
1048
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
1049
* more information on retrieving listings already created
1050
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
1051
* @param bool $use_selection [optional] whether or not the last made selection should
1052
* be used if available
1053
* @param string $pathtodir [optional] path to the directory for which to get the list
1054
* @param bool $recursive [optional] whether to retrieve information on files in
1055
* subdirectories
1056
* @return array array with two key-value sets:
1057
* 'filename' => filename of most recent file
1058
* 'last_modified' => last modified unix timestamp of the file
1059
*/
1060
public function get_most_recent_file($use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1061
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1062
1063
// Initialize result
1064
$last_mod_ts = 0;
1065
$last_mod_file = '';
1066
1067
foreach ($files as $filename) {
1068
$file_mod_ts = $this->get_lastmod_unixts($this->last_path . $filename);
1069
if ($file_mod_ts > $last_mod_ts) {
1070
$last_mod_ts = $file_mod_ts;
1071
$last_mod_file = $filename;
1072
}
1073
unset($file_mod_ts);
1074
}
1075
1076
return array('filename' => $last_mod_file, 'last_modified' => $last_mod_ts);
1077
}
1078
1079
1080
/**
1081
* Retrieve a filelist which only contains files modified since the passed unix timestamp
1082
*
1083
* - Creates a selection list of files which comply with the criteria set by $comparets
1084
*
1085
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
1086
*
1087
* @link http://www.php.net/function.filemtime
1088
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
1089
* more information on retrieving listings already created
1090
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
1091
* @uses $filelist_selection to store the results
1092
* @uses $fileselection_count to store a count of the results
1093
*
1094
* @param int $compare_ts Unix timestamp for date/time to compare against
1095
* @param bool $use_selection [optional] whether or not the last made selection should
1096
* be used if available
1097
* @param string $pathtodir [optional] path to the directory for which to get the list
1098
* @param bool $recursive [optional] whether to retrieve information on files in
1099
* subdirectories
1100
* @return array array of filenames of files which pass the test
1101
*/
1102
public function get_files_modified_since($compare_ts, $use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1103
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1104
1105
foreach ($files as $key => $filename) {
1106
$file_mod_ts = $this->get_lastmod_unixts($this->last_path . $filename);
1107
if ($file_mod_ts < $compare_ts) {
1108
unset($files[$key]);
1109
}
1110
}
1111
1112
$this->filelist_selection = $files;
1113
$this->fileselection_count = count($this->filelist_selection);
1114
return $this->filelist_selection;
1115
}
1116
1117
/**
1118
* Retrieve a filelist which only contains files modified before the passed unix timestamp
1119
*
1120
* - Creates a selection list of files which comply with the criteria set by $comparets
1121
*
1122
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
1123
*
1124
* @link http://www.php.net/function.filemtime
1125
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
1126
* more information on retrieving listings already created
1127
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
1128
* @uses $filelist_selection to store the results
1129
* @uses $fileselection_count to store a count of the results
1130
*
1131
* @param int $compare_ts Unix timestamp for date/time to compare against
1132
* @param bool $use_selection [optional] whether or not the last made selection should
1133
* be used if available
1134
* @param string $pathtodir [optional] path to the directory for which to get the list
1135
* @param bool $recursive [optional] whether to retrieve information on files in
1136
* subdirectories
1137
* @return array array of filenames of files which pass the test
1138
*/
1139
public function get_files_modified_before($compare_ts, $use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1140
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1141
1142
foreach ($files as $key => $filename) {
1143
$file_mod_ts = $this->get_lastmod_unixts($this->last_path . $filename);
1144
if ($file_mod_ts > $compare_ts) {
1145
unset($files[$key]);
1146
}
1147
}
1148
1149
$this->filelist_selection = $files;
1150
$this->fileselection_count = count($this->filelist_selection);
1151
return $this->filelist_selection;
1152
}
1153
1154
/**
1155
* Retrieve a filelist which only contains files accessed since the passed unix timestamp
1156
*
1157
* - Creates a selection list of files which comply with the criteria set by $comparets
1158
*
1159
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
1160
*
1161
* @link http://www.php.net/function.fileatime
1162
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
1163
* more information on retrieving listings already created
1164
* @uses get_lastacc_unixts() to get the last access unix timestamp for each file to test
1165
* @uses $filelist_selection to store the results
1166
* @uses $fileselection_count to store a count of the results
1167
*
1168
* @param int $compare_ts Unix timestamp for date/time to compare against
1169
* @param bool $use_selection [optional] whether or not the last made selection should
1170
* be used if available
1171
* @param string $pathtodir [optional] path to the directory for which to get the list
1172
* @param bool $recursive [optional] whether to retrieve information on files in
1173
* subdirectories
1174
* @return array array of filenames of files which pass the test
1175
*/
1176
public function get_files_accessed_since($compare_ts, $use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1177
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1178
1179
foreach ($files as $key => $filename) {
1180
$file_mod_ts = $this->get_lastacc_unixts($this->last_path . $filename);
1181
if ($file_mod_ts < $comparets) {
1182
unset($files[$key]);
1183
}
1184
}
1185
1186
$this->filelist_selection = $files;
1187
$this->fileselection_count = count( $this->filelist_selection );
1188
return $this->filelist_selection;
1189
}
1190
1191
/**
1192
* Retrieve a filelist which only contains files accessed before the passed unix timestamp
1193
*
1194
* - Creates a selection list of files which comply with the criteria set by $comparets
1195
*
1196
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
1197
*
1198
* @link http://www.php.net/function.fileatime
1199
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
1200
* more information on retrieving listings already created
1201
* @uses get_lastacc_unixts() to get the last access unix timestamp for each file to test
1202
* @uses $filelist_selection to store the results
1203
* @uses $fileselection_count to store a count of the results
1204
*
1205
* @param int $compare_ts Unix timestamp for date/time to compare against
1206
* @param bool $use_selection [optional] whether or not the last made selection should
1207
* be used if available
1208
* @param string $pathtodir [optional] path to the directory for which to get the list
1209
* @param bool $recursive [optional] whether to retrieve information on files in
1210
* subdirectories
1211
* @return array array of filenames of files which pass the test
1212
*/
1213
public function get_files_accessed_before($compare_ts, $use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1214
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1215
1216
foreach ($files as $key => $filename) {
1217
$file_mod_ts = $this->get_lastacc_unixts($this->last_path . $filename);
1218
if ($file_mod_ts > $comparets) {
1219
unset($files[$key]);
1220
}
1221
}
1222
1223
$this->filelist_selection = $files;
1224
$this->fileselection_count = count($this->filelist_selection);
1225
return $this->filelist_selection;
1226
}
1227
1228
1229
/**
1230
* Get the total size of all files in $pathtodir
1231
*
1232
* @author marting.dc AT gmail.com - 29-Jan-2006 02:08
1233
* @see http://www.php.net/function.stat
1234
* @uses get_filelist() to retrieve a filelist to use - refer to this method for
1235
* more information on retrieving listings already created
1236
* @uses get_filesize() to retrieve information on the filesize of individual files
1237
*
1238
* @param bool $use_selection [optional] whether or not the last made selection should
1239
* be used if available
1240
* @param string $pathtodir [optional] path to the directory for which to get the size
1241
* @param bool $recursive [optional] whether to include filesize of files in
1242
* subdirectories
1243
* @return int total size of files in directory in bytes
1244
*/
1245
public function get_dirsize($use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1246
$files = $this->get_filelist($use_selection, $pathtodir, $recursive);
1247
1248
// Initialize result
1249
$dirsize = 0;
1250
1251
foreach ($files as $filename) {
1252
$dirsize += $this->get_filesize($this->last_path . $filename);
1253
}
1254
1255
return $dirsize;
1256
}
1257
1258
/**
1259
* Get the total size of all files in a directory in a human readable format
1260
*
1261
* @uses get_dirsize() to retrieve the total size of the files in the directory
1262
* @uses human_readable_filesize() to convert the size to a human readable string
1263
* @param bool $use_selection [optional] whether or not the last made selection should
1264
* be used if available
1265
* @param string $pathtodir [optional] path to the directory for which to get the size
1266
* @param bool $recursive [optional] whether to include filesize of files in
1267
* subdirectories
1268
* @return string human readable directory size string
1269
*/
1270
public function get_human_readable_dirsize($use_selection = NULL, $pathtodir = NULL, $recursive = NULL) {
1271
$dirsize = $this->get_dirsize($use_selection, $pathtodir, $recursive);
1272
return $this->human_readable_filesize($dirsize);
1273
}
1274
1275
/**
1276
* Mapping of file extensions to their expected mime-type
1277
*
1278
* This mapping does not claim to be exhaustive, but is a good listing for a large amount
1279
* of file types.
1280
*
1281
* Last updated: 2006-08-31
1282
*
1283
* @link http://www.duke.edu/websrv/file-extensions.html
1284
* @var array $mime_map key = file extension, value = mime-type
1285
*/
1286
public $mime_map = array(
1287
'ai' => 'application/postscript',
1288
'aif' => 'audio/x-aiff',
1289
'aifc' => 'audio/x-aiff',
1290
'aiff' => 'audio/x-aiff',
1291
'asc' => 'text/plain',
1292
'au' => 'audio/basic',
1293
'avi' => 'video/x-msvideo',
1294
'bcpio' => 'application/x-bcpio',
1295
'bin' => 'application/octet-stream',
1296
'c' => 'text/plain',
1297
'cc' => 'text/plain',
1298
'ccad' => 'application/clariscad',
1299
'cdf' => 'application/x-netcdf',
1300
'class' => 'application/octet-stream',
1301
'cpio' => 'application/x-cpio',
1302
'cpt' => 'application/mac-compactpro',
1303
'csh' => 'application/x-csh',
1304
'css' => 'text/css',
1305
'dcr' => 'application/x-director',
1306
'dir' => 'application/x-director',
1307
'dms' => 'application/octet-stream',
1308
'doc' => 'application/msword',
1309
'drw' => 'application/drafting',
1310
'dvi' => 'application/x-dvi',
1311
'dwg' => 'application/acad',
1312
'dxf' => 'application/dxf',
1313
'dxr' => 'application/x-director',
1314
'eps' => 'application/postscript',
1315
'etx' => 'text/x-setext',
1316
'exe' => 'application/octet-stream',
1317
'ez' => 'application/andrew-inset',
1318
'f' => 'text/plain',
1319
'f90' => 'text/plain',
1320
'fli' => 'video/x-fli',
1321
'gif' => 'image/gif',
1322
'gtar' => 'application/x-gtar',
1323
'gz' => 'application/x-gzip',
1324
'h' => 'text/plain',
1325
'hdf' => 'application/x-hdf',
1326
'hh' => 'text/plain',
1327
'hqx' => 'application/mac-binhex40',
1328
'htm' => 'text/html',
1329
'html' => 'text/html',
1330
'ice' => 'x-conference/x-cooltalk',
1331
'ief' => 'image/ief',
1332
'iges' => 'model/iges',
1333
'igs' => 'model/iges',
1334
'ips' => 'application/x-ipscript',
1335
'ipx' => 'application/x-ipix',
1336
'jpe' => 'image/jpeg',
1337
'jpeg' => 'image/jpeg',
1338
'jpg' => 'image/jpeg',
1339
'js' => 'application/x-javascript',
1340
'kar' => 'audio/midi',
1341
'latex' => 'application/x-latex',
1342
'lha' => 'application/octet-stream',
1343
'lsp' => 'application/x-lisp',
1344
'lzh' => 'application/octet-stream',
1345
'm' => 'text/plain',
1346
'man' => 'application/x-troff-man',
1347
'me' => 'application/x-troff-me',
1348
'mesh' => 'model/mesh',
1349
'mid' => 'audio/midi',
1350
'midi' => 'audio/midi',
1351
'mif' => 'application/vnd.mif',
1352
'mime' => 'www/mime',
1353
'mov' => 'video/quicktime',
1354
'movie' => 'video/x-sgi-movie',
1355
'mp2' => 'audio/mpeg',
1356
'mp3' => 'audio/mpeg',
1357
'mpe' => 'video/mpeg',
1358
'mpeg' => 'video/mpeg',
1359
'mpg' => 'video/mpeg',
1360
'mpga' => 'audio/mpeg',
1361
'ms' => 'application/x-troff-ms',
1362
'msh' => 'model/mesh',
1363
'nc' => 'application/x-netcdf',
1364
'oda' => 'application/oda',
1365
'pbm' => 'image/x-portable-bitmap',
1366
'pdb' => 'chemical/x-pdb',
1367
'pdf' => 'application/pdf',
1368
'pgm' => 'image/x-portable-graymap',
1369
'pgn' => 'application/x-chess-pgn',
1370
'php' => 'text/plain',
1371
'php3' => 'text/plain',
1372
'png' => 'image/png',
1373
'pnm' => 'image/x-portable-anymap',
1374
'pot' => 'application/mspowerpoint',
1375
'ppm' => 'image/x-portable-pixmap',
1376
'pps' => 'application/mspowerpoint',
1377
'ppt' => 'application/mspowerpoint',
1378
'ppz' => 'application/mspowerpoint',
1379
'pre' => 'application/x-freelance',
1380
'prt' => 'application/pro_eng',
1381
'ps' => 'application/postscript',
1382
'qt' => 'video/quicktime',
1383
'ra' => 'audio/x-realaudio',
1384
'ram' => 'audio/x-pn-realaudio',
1385
'ras' => 'image/cmu-raster',
1386
'rgb' => 'image/x-rgb',
1387
'rm' => 'audio/x-pn-realaudio',
1388
'roff' => 'application/x-troff',
1389
'rpm' => 'audio/x-pn-realaudio-plugin',
1390
'rtf' => 'text/rtf',
1391
'rtx' => 'text/richtext',
1392
'scm' => 'application/x-lotusscreencam',
1393
'set' => 'application/set',
1394
'sgm' => 'text/sgml',
1395
'sgml' => 'text/sgml',
1396
'sh' => 'application/x-sh',
1397
'shar' => 'application/x-shar',
1398
'silo' => 'model/mesh',
1399
'sit' => 'application/x-stuffit',
1400
'skd' => 'application/x-koan',
1401
'skm' => 'application/x-koan',
1402
'skp' => 'application/x-koan',
1403
'skt' => 'application/x-koan',
1404
'smi' => 'application/smil',
1405
'smil' => 'application/smil',
1406
'snd' => 'audio/basic',
1407
'sol' => 'application/solids',
1408
'spl' => 'application/x-futuresplash',
1409
'src' => 'application/x-wais-source',
1410
'step' => 'application/STEP',
1411
'stl' => 'application/SLA',
1412
'stp' => 'application/STEP',
1413
'sv4cpio' => 'application/x-sv4cpio',
1414
'sv4crc' => 'application/x-sv4crc',
1415
'swf' => 'application/x-shockwave-flash',
1416
't' => 'application/x-troff',
1417
'tar' => 'application/x-tar',
1418
'tcl' => 'application/x-tcl',
1419
'tex' => 'application/x-tex',
1420
'texi' => 'application/x-texinfo',
1421
'texinfo' => 'application/x-texinfo',
1422
'tif' => 'image/tiff',
1423
'tiff' => 'image/tiff',
1424
'tr' => 'application/x-troff',
1425
'tsi' => 'audio/TSP-audio',
1426
'tsp' => 'application/dsptype',
1427
'tsv' => 'text/tab-separated-values',
1428
'txt' => 'text/plain',
1429
'unv' => 'application/i-deas',
1430
'ustar' => 'application/x-ustar',
1431
'vcd' => 'application/x-cdlink',
1432
'vda' => 'application/vda',
1433
'viv' => 'video/vnd.vivo',
1434
'vivo' => 'video/vnd.vivo',
1435
'vrml' => 'model/vrml',
1436
'wav' => 'audio/x-wav',
1437
'wrl' => 'model/vrml',
1438
'xbm' => 'image/x-xbitmap',
1439
'xlc' => 'application/vnd.ms-excel',
1440
'xll' => 'application/vnd.ms-excel',
1441
'xlm' => 'application/vnd.ms-excel',
1442
'xls' => 'application/vnd.ms-excel',
1443
'xlw' => 'application/vnd.ms-excel',
1444
'xml' => 'text/xml',
1445
'xpm' => 'image/x-xpixmap',
1446
'xwd' => 'image/x-xwindowdump',
1447
'xyz' => 'chemical/x-pdb',
1448
'zip' => 'application/zip'
1449
);
1450
1451
/**
1452
* Valid mime types
1453
*
1454
* Last updated on 2006-08-31
1455
* @link http://www.iana.org/assignments/media-types/
1456
* @var array key = Content-type, value = array of valid subtypes for that content-type
1457
*/
1458
public $valid_mime_types = array(
1459
'application' => array( 'activemessage', 'andrew-inset', 'applefile', 'atom+xml',
1460
'atomicmail', 'batch-SMTP', 'beep+xml', 'cals-1840', 'ccxml+xml', 'cnrp+xml',
1461
'commonground', 'conference-info+xml', 'cpl+xml', 'csta+xml', 'CSTAdata+xml',
1462
'cybercash', 'dca-rft', 'dec-dx', 'dialog-info+xml', 'dicom', 'dns', 'dvcs',
1463
'ecmascript', 'EDI-Consent', 'EDIFACT', 'EDI-X12', 'epp+xml', 'eshop', 'example',
1464
'fastinfoset', 'fastsoap', 'fits', 'font-tdpfr', 'H224', 'http', 'hyperstudio',
1465
'iges', 'im-iscomposing+xml', 'index', 'index.cmd', 'index.obj', 'index.response',
1466
'index.vnd', 'iotp', 'ipp', 'isup', 'javascript', 'json', 'kpml-request+xml',
1467
'kpml-response+xml', 'mac-binhex40', 'macwriteii', 'marc', 'mathematica', 'mbox',
1468
'mikey', 'mpeg4-generic', 'mpeg4-iod', 'mpeg4-iod-xmt', 'mp4', 'msword', 'mxf',
1469
'nasdata', 'news-message-id', 'news-transmission', 'nss', 'ocsp-request',
1470
'ocsp-response', 'octet-stream', 'oda', 'ogg', 'parityfec', 'pdf', 'pgp-encrypted',
1471
'pgp-keys', 'pgp-signature', 'pidf+xml', 'pkcs10', 'pkcs7-mime', 'pkcs7-signature',
1472
'pkix-cert', 'pkixcmp', 'pkix-crl', 'pkix-pkipath', 'pls+xml', 'poc-settings+xml',
1473
'postscript', 'prs.alvestrand.titrax-sheet', 'prs.cww', 'prs.nprend', 'prs.plucker',
1474
'rdf+xml', 'qsig', 'reginfo+xml', 'relax-ng-compact-syntax', 'remote-printing',
1475
'resource-lists+xml', 'riscos', 'rlmi+xml', 'rls-services+xml', 'rtf', 'rtx',
1476
'samlassertion+xml', 'samlmetadata+xml', 'sbml+xml', 'sdp', 'set-payment',
1477
'set-payment-initiation', 'set-registration', 'set-registration-initiation',
1478
'sgml', 'sgml-open-catalog', 'shf+xml', 'sieve', 'simple-filter+xml',
1479
'simple-message-summary', 'slate', 'smil', //OBSOLETE
1480
'smil+xml', 'soap+fastinfoset', 'soap+xml', 'spirits-event+xml', 'srgs',
1481
'srgs+xml', 'ssml+xml', 'timestamp-query', 'timestamp-reply', 'tve-trigger', 'vemmi',
1482
'vnd.3gpp.bsf+xml', 'vnd.3gpp.pic-bw-large', 'vnd.3gpp.pic-bw-small',
1483
'vnd.3gpp.pic-bw-var', 'vnd.3gpp.sms', 'vnd.3gpp2.bcmcsinfo+xml', 'vnd.3gpp2.sms',
1484
'vnd.3M.Post-it-Notes', 'vnd.accpac.simply.aso', 'vnd.accpac.simply.imp',
1485
'vnd.acucobol', 'vnd.acucorp', 'vnd.adobe.xfdf', 'vnd.aether.imp', 'vnd.amiga.ami',
1486
'vnd.anser-web-certificate-issue-initiation', 'vnd.apple.installer+xml',
1487
'vnd.audiograph', 'vnd.autopackage', 'vnd.blueice.multipass', 'vnd.bmi',
1488
'vnd.businessobjects', 'vnd.canon-cpdl', 'vnd.canon-lips', 'vnd.cinderella',
1489
'vnd.chipnuts.karaoke-mmd', 'vnd.claymore', 'vnd.commerce-battelle',
1490
'vnd.commonspace', 'vnd.cosmocaller', 'vnd.contact.cmsg', 'vnd.crick.clicker',
1491
'vnd.crick.clicker.keyboard', 'vnd.crick.clicker.palette',
1492
'vnd.crick.clicker.template', 'vnd.crick.clicker.wordbank',
1493
'vnd.criticaltools.wbs+xml', 'vnd.ctc-posml', 'vnd.cups-pdf', 'vnd.cups-postscript',
1494
'vnd.cups-ppd', 'vnd.cups-raster', 'vnd.cups-raw', 'vnd.curl', 'vnd.cybank',
1495
'vnd.data-vision.rdz', 'vnd.dna', 'vnd.dpgraph', 'vnd.dreamfactory',
1496
'vnd.dvb.esgcontainer', 'vnd.dvb.ipdcesgaccess', 'vnd.dxr', 'vnd.ecdis-update',
1497
'vnd.ecowin.chart', 'vnd.ecowin.filerequest', 'vnd.ecowin.fileupdate',
1498
'vnd.ecowin.series', 'vnd.ecowin.seriesrequest', 'vnd.ecowin.seriesupdate',
1499
'vnd.enliven', 'vnd.epson.esf', 'vnd.epson.msf', 'vnd.epson.quickanime',
1500
'vnd.epson.salt', 'vnd.epson.ssf', 'vnd.ericsson.quickcall', 'vnd.eudora.data',
1501
'vnd.ezpix-album', 'vnd.ezpix-package', 'vnd.fdf', 'vnd.ffsns', 'vnd.fints',
1502
'vnd.FloGraphIt', 'vnd.fluxtime.clip', 'vnd.framemaker', 'vnd.frogans.fnc',
1503
'vnd.frogans.ltf', 'vnd.fsc.weblaunch', 'vnd.fujitsu.oasys', 'vnd.fujitsu.oasys2',
1504
'vnd.fujitsu.oasys3', 'vnd.fujitsu.oasysgp', 'vnd.fujitsu.oasysprs',
1505
'vnd.fujixerox.ART4', 'vnd.fujixerox.ART-EX', 'vnd.fujixerox.ddd',
1506
'vnd.fujixerox.docuworks', 'vnd.fujixerox.docuworks.binder', 'vnd.fujixerox.HBPL',
1507
'vnd.fut-misnet', 'vnd.genomatix.tuxedo', 'vnd.grafeq', 'vnd.groove-account',
1508
'vnd.groove-help', 'vnd.groove-identity-message', 'vnd.groove-injector',
1509
'vnd.groove-tool-message', 'vnd.groove-tool-template', 'vnd.groove-vcard',
1510
'vnd.HandHeld-Entertainment+xml', 'vnd.hbci', 'vnd.hcl-bireports',
1511
'vnd.hhe.lesson-player', 'vnd.hp-HPGL', 'vnd.hp-hpid', 'vnd.hp-hps',
1512
'vnd.hp-jlyt', 'vnd.hp-PCL', 'vnd.hp-PCLXL', 'vnd.httphone', 'vnd.hzn-3d-crossword',
1513
'vnd.ibm.afplinedata', 'vnd.ibm.electronic-media', 'vnd.ibm.MiniPay',
1514
'vnd.ibm.modcap', 'vnd.ibm.rights-management', 'vnd.ibm.secure-container',
1515
'vnd.igloader', 'vnd.informix-visionary', 'vnd.intercon.formnet',
1516
'vnd.intertrust.digibox', 'vnd.intertrust.nncp', 'vnd.intu.qbo', 'vnd.intu.qfx',
1517
'vnd.ipunplugged.rcprofile', 'vnd.irepository.package+xml', 'vnd.is-xpr',
1518
'vnd.japannet-directory-service', 'vnd.japannet-jpnstore-wakeup',
1519
'vnd.japannet-payment-wakeup', 'vnd.japannet-registration',
1520
'vnd.japannet-registration-wakeup', 'vnd.japannet-setstore-wakeup',
1521
'vnd.japannet-verification', 'vnd.japannet-verification-wakeup',
1522
'vnd.jisp', 'vnd.kahootz', 'vnd.kde.karbon', 'vnd.kde.kchart', 'vnd.kde.kformula',
1523
'vnd.kde.kivio', 'vnd.kde.kontour', 'vnd.kde.kpresenter', 'vnd.kde.kspread',
1524
'vnd.kde.kword', 'vnd.kenameaapp', 'vnd.kidspiration', 'vnd.Kinar',
1525
'vnd.koan', 'vnd.liberty-request+xml', 'vnd.llamagraphics.life-balance.desktop',
1526
'vnd.llamagraphics.life-balance.exchange+xml', 'vnd.lotus-1-2-3',
1527
'vnd.lotus-approach', 'vnd.lotus-freelance', 'vnd.lotus-notes',
1528
'vnd.lotus-organizer', 'vnd.lotus-screencam', 'vnd.lotus-wordpro',
1529
'vnd.marlin.drm.mdcf', 'vnd.mcd', 'vnd.medcalcdata', 'vnd.mediastation.cdkey',
1530
'vnd.meridian-slingshot', 'vnd.mfmp', 'vnd.micrografx.flo', 'vnd.micrografx.igx',
1531
'vnd.mif', 'vnd.minisoft-hp3000-save', 'vnd.mitsubishi.misty-guard.trustweb',
1532
'vnd.Mobius.DAF', 'vnd.Mobius.DIS', 'vnd.Mobius.MBK', 'vnd.Mobius.MQY',
1533
'vnd.Mobius.MSL', 'vnd.Mobius.PLC', 'vnd.Mobius.TXF', 'vnd.mophun.application',
1534
'vnd.mophun.certificate', 'vnd.motorola.flexsuite', 'vnd.motorola.flexsuite.adsi',
1535
'vnd.motorola.flexsuite.fis', 'vnd.motorola.flexsuite.gotap',
1536
'vnd.motorola.flexsuite.kmr', 'vnd.motorola.flexsuite.ttc',
1537
'vnd.motorola.flexsuite.wem', 'vnd.mozilla.xul+xml', 'vnd.ms-artgalry',
1538
'vnd.ms-asf', 'vnd.ms-cab-compressed', 'vnd.mseq', 'vnd.ms-excel',
1539
'vnd.ms-fontobject', 'vnd.ms-htmlhelp', 'vnd.msign', 'vnd.ms-ims', 'vnd.ms-lrm',
1540
'vnd.ms-powerpoint', 'vnd.ms-project', 'vnd.ms-tnef', 'vnd.ms-wmdrm.lic-chlg-req',
1541
'vnd.ms-wmdrm.lic-resp', 'vnd.ms-works', 'vnd.ms-wpl', 'vnd.ms-xpsdocument',
1542
'vnd.musician', 'vnd.music-niff', 'vnd.nervana', 'vnd.netfpx',
1543
'vnd.noblenet-directory', 'vnd.noblenet-sealer', 'vnd.noblenet-web',
1544
'vnd.nokia.catalogs', 'vnd.nokia.conml+wbxml', 'vnd.nokia.conml+xml',
1545
'vnd.nokia.iptv.config+xml', 'vnd.nokia.landmark+wbxml', 'vnd.nokia.landmark+xml',
1546
'vnd.nokia.landmarkcollection+xml', 'vnd.nokia.pcd+wbxml', 'vnd.nokia.pcd+xml',
1547
'vnd.nokia.radio-preset', 'vnd.nokia.radio-presets', 'vnd.novadigm.EDM',
1548
'vnd.novadigm.EDX', 'vnd.novadigm.EXT', 'vnd.oasis.opendocument.chart',
1549
'vnd.oasis.opendocument.chart-template', 'vnd.oasis.opendocument.formula',
1550
'vnd.oasis.opendocument.formula-template', 'vnd.oasis.opendocument.graphics',
1551
'vnd.oasis.opendocument.graphics-template', 'vnd.oasis.opendocument.image',
1552
'vnd.oasis.opendocument.image-template', 'vnd.oasis.opendocument.presentation',
1553
'vnd.oasis.opendocument.presentation-template', 'vnd.oasis.opendocument.spreadsheet',
1554
'vnd.oasis.opendocument.spreadsheet-template', 'vnd.oasis.opendocument.text',
1555
'vnd.oasis.opendocument.text-master', 'vnd.oasis.opendocument.text-template',
1556
'vnd.oasis.opendocument.text-web', 'vnd.obn', 'vnd.oma.dd2+xml',
1557
'vnd.omads-email+xml', 'vnd.omads-file+xml', 'vnd.omads-folder+xml',
1558
'vnd.omaloc-supl-init', 'vnd.osa.netdeploy', 'vnd.osgi.dp', 'vnd.otps.ct-kip+xml',
1559
'vnd.palm', 'vnd.paos.xml', 'vnd.pg.format', 'vnd.pg.osasli',
1560
'vnd.piaccess.application-licence', 'vnd.picsel', 'vnd.pocketlearn',
1561
'vnd.powerbuilder6', 'vnd.powerbuilder6-s', 'vnd.powerbuilder7',
1562
'vnd.powerbuilder75', 'vnd.powerbuilder75-s', 'vnd.powerbuilder7-s',
1563
'vnd.preminet', 'vnd.previewsystems.box', 'vnd.proteus.magazine',
1564
'vnd.publishare-delta-tree', 'vnd.pvi.ptid1', 'vnd.pwg-multiplexed',
1565
'vnd.pwg-xhtml-print+xml', 'vnd.qualcomm.brew-app-res', 'vnd.Quark.QuarkXPress',
1566
'vnd.rapid', 'vnd.RenLearn.rlprint', 'vnd.ruckus.download', 'vnd.s3sms',
1567
'vnd.scribus', 'vnd.sealed.3df', 'vnd.sealed.csf', 'vnd.sealed.doc',
1568
'vnd.sealed.eml', 'vnd.sealed.mht', 'vnd.sealed.net', 'vnd.sealed.ppt',
1569
'vnd.sealed.tiff', 'vnd.sealed.xls', 'vnd.sealedmedia.softseal.html',
1570
'vnd.sealedmedia.softseal.pdf', 'vnd.seemail', 'vnd.sema',
1571
'vnd.shana.informed.formdata', 'vnd.shana.informed.formtemplate',
1572
'vnd.shana.informed.interchange', 'vnd.shana.informed.package',
1573
'vnd.smaf', 'vnd.solent.sdkm+xml', 'vnd.sss-cod', 'vnd.sss-dtf', 'vnd.sss-ntf',
1574
'vnd.street-stream', 'vnd.sun.wadl+xml', 'vnd.sus-calendar', 'vnd.svd',
1575
'vnd.swiftview-ics', 'vnd.syncml.dm+wbxml', 'vnd.syncml.ds.notification',
1576
'vnd.syncml.+xml', 'vnd.triscape.mxs', 'vnd.trueapp', 'vnd.truedoc',
1577
'vnd.ufdl', 'vnd.uiq.theme', 'vnd.umajin', 'vnd.uoml+xml', 'vnd.uplanet.alert',
1578
'vnd.uplanet.alert-wbxml', 'vnd.uplanet.bearer-choice',
1579
'vnd.uplanet.bearer-choice-wbxml', 'vnd.uplanet.cacheop', 'vnd.uplanet.cacheop-wbxml',
1580
'vnd.uplanet.channel', 'vnd.uplanet.channel-wbxml', 'vnd.uplanet.list',
1581
'vnd.uplanet.listcmd', 'vnd.uplanet.listcmd-wbxml', 'vnd.uplanet.list-wbxml',
1582
'vnd.uplanet.signal', 'vnd.vcx', 'vnd.vectorworks', 'vnd.vd-study',
1583
'vnd.vidsoft.vidconference', 'vnd.visio', 'vnd.visionary',
1584
'vnd.vividence.scriptfile', 'vnd.vsf', 'vnd.wap.sic', 'vnd.wap.slc', 'vnd.wap.wbxml',
1585
'vnd.wap.wmlc', 'vnd.wap.wmlscriptc', 'vnd.webturbo', 'vnd.wfa.wsc',
1586
'vnd.wordperfect', 'vnd.wqd', 'vnd.wrq-hp3000-labelled', 'vnd.wt.stf',
1587
'vnd.wv.csp+xml', 'vnd.wv.csp+wbxml', 'vnd.wv.ssp+xml', 'vnd.xara', 'vnd.xfdl',
1588
'vnd.yamaha.hv-dic', 'vnd.yamaha.hv-script', 'vnd.yamaha.hv-voice',
1589
'vnd.yamaha.smaf-audio', 'vnd.yamaha.smaf-phrase', 'vnd.yellowriver-custom-menu',
1590
'vnd.zzazz.deck+xml', 'voicexml+xml', 'watcherinfo+xml', 'whoispp-query',
1591
'whoispp-response', 'wita', 'wordperfect5.1', 'x400-bp', 'xcap-att+xml',
1592
'xcap-caps+xml', 'xcap-el+xml', 'xcap-error+xml', 'xenc+xml',
1593
'xhtml-voice+xml', // OBSOLETE
1594
'xhtml+xml', 'xml', 'xml-dtd', 'xml-external-parsed-entity', 'xmpp+xml',
1595
'xop+xml', 'xv+xml', 'zip',
1596
),
1597
'audio' => array(
1598
'32kadpcm', '3gpp', '3gpp2', 'ac3', 'AMR', 'AMR-WB', 'amr-wb+', 'asc',
1599
'basic', 'BV16', 'BV32', 'clearmode', 'CN', 'DAT12', 'dls', 'dsr-es201108',
1600
'dsr-es202050', 'dsr-es202211', 'dsr-es202212', 'eac3', 'DVI4', 'EVRC',
1601
'EVRC0', 'EVRC-QCP', 'example', 'G722', 'G7221', 'G723', 'G726-16',
1602
'G726-24', 'G726-32', 'G726-40', 'G728', 'G729', 'G729D', 'G729E', 'GSM',
1603
'GSM-EFR', 'iLBC', 'L8', 'L16', 'L20', 'L24', 'LPC', 'MPA', 'mp4', 'MP4A-LATM',
1604
'mpa-robust', 'mpeg', 'mpeg4-generic', 'parityfec', 'PCMA', 'PCMU', 'prs.sid',
1605
'QCELP', 'RED', 'rtp-midi', 'rtx', 'SMV', 'SMV0', 'SMV-QCP', 't140c', 't38',
1606
'telephone-event', 'tone', 'VDVI', 'VMR-WB', 'vnd.3gpp.iufp', 'vnd.4SB',
1607
'vnd.audiokoz', 'vnd.CELP', 'vnd.cisco.nse', 'vnd.cmles.radio-events',
1608
'vnd.cns.anp1', 'vnd.cns.inf1', 'vnd.digital-winds', 'vnd.dlna.adts',
1609
'vnd.everad.plj', 'vnd.hns.audio', 'vnd.lucent.voice', 'vnd.nokia.mobile-xmf',
1610
'vnd.nortel.vbk', 'vnd.nuera.ecelp4800', 'vnd.nuera.ecelp7470',
1611
'vnd.nuera.ecelp9600', 'vnd.octel.sbc',
1612
'vnd.qcelp', // DEPRECATED - Please use audio/qcelp
1613
'vnd.rhetorex.32kadpcm', 'vnd.sealedmedia.softseal.mpeg', 'vnd.vmx.cvsd'
1614
),
1615
'example' => array(),
1616
'image ' => array(
1617
'cgm', 'example', 'fits', 'g3fax', 'gif', 'ief', 'jp2', 'jpeg', 'jpm', 'jpx',
1618
'naplps', 'png', 'prs.btif', 'prs.pti', 't38', 'tiff', 'tiff-fx',
1619
'vnd.adobe.photoshop', 'vnd.cns.inf2', 'vnd.djvu', 'vnd.dwg', 'vnd.dxf',
1620
'vnd.fastbidsheet', 'vnd.fpx', 'vnd.fst', 'vnd.fujixerox.edmics-mmr',
1621
'vnd.fujixerox.edmics-rlc', 'vnd.globalgraphics.pgb', 'vnd.microsoft.icon',
1622
'vnd.mix', 'vnd.ms-modi', 'vnd.net-fpx', 'vnd.sealed.png',
1623
'vnd.sealedmedia.softseal.gif', 'vnd.sealedmedia.softseal.jpg', 'vnd.svf',
1624
'vnd.wap.wbmp', 'vnd.xiff'
1625
),
1626
'message' => array(
1627
'CPIM', 'delivery-status', 'disposition-notification', 'example',
1628
'external-body', 'http', 'news', 'partial', 'rfc822', 's-http', 'sip',
1629
'sipfrag', 'tracking-status'
1630
),
1631
'model' => array(
1632
'example', 'iges', 'mesh', 'vnd.dwf', 'vnd.flatland.3dml', 'vnd.gdl',
1633
'vnd.gs-gdl', 'vnd.gtw', 'vnd.moml+xml', 'vnd.mts', 'vnd.parasolid.transmit.binary',
1634
'vnd.parasolid.transmit.text', 'vnd.vtu', 'vrml'
1635
),
1636
'multipart' => array(
1637
'alternative', 'appledouble', 'byteranges', 'digest', 'encrypted', 'example',
1638
'form-data', 'header-set', 'mixed', 'parallel', 'related', 'report', 'signed',
1639
'voice-message'
1640
),
1641
'text' => array(
1642
'calendar', 'css', 'csv', 'directory', 'dns', 'ecmascript', // OBSOLETE
1643
'enriched', 'example', 'html', 'javascript', // OBSOLETE
1644
'parityfec', 'plain', 'prs.fallenstein.rst', 'prs.lines.tag', 'RED',
1645
'rfc822-headers', 'richtext', 'rtf', 'rtx', 'sgml', 't140',
1646
'tab-separated-values', 'troff', 'uri-list', 'vnd.abc', 'vnd.curl',
1647
'vnd.DMClientScript', 'vnd.esmertec.theme-descriptor', 'vnd.fly',
1648
'vnd.fmi.flexstor', 'vnd.in3d.3dml', 'vnd.in3d.spot', 'vnd.IPTC.NewsML',
1649
'vnd.IPTC.NITF', 'vnd.latex-z', 'vnd.motorola.reflex', 'vnd.ms-mediapackage',
1650
'vnd.net2phone.commcenter.command', 'vnd.sun.j2me.app-descriptor', 'vnd.wap.si',
1651
'vnd.wap.sl', 'vnd.wap.wml', 'vnd.wap.wmlscript', 'xml', 'xml-external-parsed-entity'
1652
),
1653
'video' => array(
1654
'3gpp', '3gpp2', '3gpp-tt', 'BMPEG', 'BT656', 'CelB', 'DV', 'example', 'H261',
1655
'H263', 'H263-1998', 'H263-2000', 'H264', 'JPEG', 'MJ2', 'MP1S', 'MP2P', 'MP2T',
1656
'mp4', 'MP4V-ES', 'MPV', 'mpeg', 'mpeg4-generic', 'nv', 'parityfec', 'pointer',
1657
'quicktime', 'raw', 'rtx', 'SMPTE292M', 'vc1', 'vnd.dlna.mpeg-tts', 'vnd.fvt',
1658
'vnd.hns.video', 'vnd.motorola.video', 'vnd.motorola.videop', 'vnd.mpegurl',
1659
'vnd.nokia.interleaved-multimedia', 'vnd.objectvideo', 'vnd.sealed.mpeg1',
1660
'vnd.sealed.mpeg4', 'vnd.sealed.swf', 'vnd.sealedmedia.softseal.mov',
1661
'vnd.vivo'
1662
)
1663
);
1664
1665
/**
1666
* Get Directory File Information
1667
*
1668
* Reads the specified directory and builds an array containing the filenames,
1669
* filesize, dates, and permissions
1670
*
1671
* Any sub-folders contained within the specified path are read as well.
1672
*
1673
* @access public
1674
* @param string path to source
1675
* @param bool Look only at the top level directory specified?
1676
* @param bool internal variable to determine recursion status - do not use in calls
1677
* @return array
1678
*/
1679
public static function dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE) {
1680
static $_filedata = array();
1681
$relative_path = $source_dir;
1682
1683
if ($fp = @opendir($source_dir)) {
1684
// reset the array and make sure $source_dir has a trailing slash on the initial call
1685
if ($_recursion === FALSE) {
1686
$_filedata = array();
1687
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1688
}
1689
1690
// foreach (scandir($source_dir, 1) as $file) // In addition to being PHP5+, scandir() is simply not as fast
1691
while (FALSE !== ($file = readdir($fp))) {
1692
if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0 && $top_level_only === FALSE) {
1693
self::dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE);
1694
} elseif (strncmp($file, '.', 1) !== 0) {
1695
$_filedata[$file] = self::get_file_info($source_dir.$file);
1696
$_filedata[$file]['relative_path'] = $relative_path;
1697
}
1698
}
1699
1700
return $_filedata;
1701
} else {
1702
return FALSE;
1703
}
1704
}
1705
1706
1707
/**
1708
* Get File Info
1709
*
1710
* Given a file and path, returns the name, path, size, date modified
1711
* Second parameter allows you to explicitly declare what information you want returned
1712
* Options are: name, server_path, size, date, readable, writable, executable, fileperms
1713
* Returns FALSE if the file cannot be found.
1714
*
1715
* @access public
1716
* @param string path to file
1717
* @param mixed array or comma separated string of information returned
1718
* @return array
1719
*/
1720
public static function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) {
1721
if ( ! file_exists($file)) {
1722
return FALSE;
1723
}
1724
1725
if (is_string($returned_values)) {
1726
$returned_values = explode(',', $returned_values);
1727
}
1728
1729
foreach ($returned_values as $key) {
1730
switch ($key) {
1731
case 'name':
1732
$fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1);
1733
break;
1734
case 'server_path':
1735
$fileinfo['server_path'] = $file;
1736
break;
1737
case 'size':
1738
$fileinfo['size'] = filesize($file);
1739
break;
1740
case 'date':
1741
$fileinfo['date'] = filemtime($file);
1742
break;
1743
case 'readable':
1744
$fileinfo['readable'] = is_readable($file);
1745
break;
1746
case 'writable':
1747
// There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms()
1748
$fileinfo['writable'] = is_writable($file);
1749
break;
1750
case 'executable':
1751
$fileinfo['executable'] = is_executable($file);
1752
break;
1753
case 'fileperms':
1754
$fileinfo['fileperms'] = fileperms($file);
1755
break;
1756
}
1757
}
1758
1759
return $fileinfo;
1760
}
1761
1762
1763
/**
1764
* Create a Directory Map
1765
*
1766
* Reads the specified directory and builds an array
1767
* representation of it. Sub-folders contained with the
1768
* directory will be mapped as well.
1769
*
1770
* @access public
1771
* @param string path to source
1772
* @param int depth of directories to traverse (0 = fully recursive, 1 = current dir, etc)
1773
* @return array
1774
*/
1775
public static function directory_map($target_dir, $directory_depth = 0, $hidden = FALSE) {
1776
if ($fp = @opendir($target_dir)) {
1777
$filedata = array();
1778
$new_depth = $directory_depth - 1;
1779
$target_dir = rtrim($target_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1780
1781
while (FALSE !== ($file = readdir($fp))) {
1782
// Remove '.', '..', and hidden files [optional]
1783
if ( ! trim($file, '.') || ($hidden == FALSE && $file[0] == '.')) {
1784
continue;
1785
}
1786
1787
if (($directory_depth < 1 || $new_depth > 0) && @is_dir($target_dir.$file)) {
1788
$filedata[$file] = self::directory_map($target_dir.$file.DIRECTORY_SEPARATOR, $new_depth, $hidden);
1789
} else {
1790
$filedata[] = $file;
1791
}
1792
}
1793
1794
closedir($fp);
1795
return $filedata;
1796
}
1797
1798
return FALSE;
1799
}
1800
1801
1802
}
1803
1804
1805
/* End of file: ./system/libraries/dirinfo_library.php */
Page URI: http://www.infopotato.com/index.php/code/library/dirinfo/
