<?php
/**
* File: getdirectorylist.inc.php
* @package directory_info
*/
/**
* Generic (re-usable) class to retrieve information on files / directories
*
* Class which can retrieve information on files, sub-directories and files within
* sub-directories.
*
* You can retrieve various kinds of lists with filenames as well as retrieve information
* about individual files, such as the file-size, file-last-access-date, file-last-modified-date
* and more.
*
* The class defaults to image files only, but based on the parameters you pass,
* information on any type of file can be retrieved.
*
* *********************************************************************<br>
* <b>Features</b><br>
* *********************************************************************
*
* - Generate a filelist / directory list as an array
* - Include subdirectories / files within subdirectories ($recursion = true)
* - Create a selection within the generated filelist based on:<br>
* * file extension(s)<br>
* * file extension(s) + mimetype check<br>
* * last modified date<br>
* * last access date
* - Create a selection within an earlier made selection
* - Sort the filelist
* - Find out which is the most recently changed file + the timestamp
* - Find out the directory size of<br>
* * a directory<br>
* * a directory and all subdirectories within it<br>
* * a selection of files within a directory<br>
* * same but then including selected files in subdirectories
* - Check whether the file extension of a file is within an allowed list (defaults to image files)
* - Check whether the mime-type of a file is within an allowed list (defaults to image files)
* - Combine the above two checks
* - Get information on individual files:<br>
* * filesize (optionally in a human readable format)<br>
* * last modified date (optionally in a - self-defined - human readable format)<br>
* * last access date (optionally in a - self-defined - human readable format)<br>
* * file permissions in a human readable format<br>
* * file owner id<br>
* * mime-type
* - Change an arbitrary filesize to a human readable format
*
* *********************************************************************<br>
* <b>Basics on how to use the class</b><br>
* *********************************************************************
*
* <i>How to instantiate ?</i>
* <code><?php
* $dirobj = new directory_info( );
* ?></code>
*
* <i>How to view the results ?</i><br>
* You can format the results display yourself, to quickly retrieve and view a filelist, you can use:
* <code><?php
* // Get a filelist for $pathtodir, $recursion = true,
* // don't use a previously made selection (null)
* $dirobj->get_filelist( null, $pathtodir, true );
* print 'filecount is : ' . $dirobj->filecount;
* print '<pre>';
* print_r( $dirobj->filelist );
* print '</pre>';
* ?></code>
*
* <i>Note</i>: The directory path passed to a methods should be relative to the location
* of the calling file and should end with a trailing slash
* <code><?php
* $pathtodir = 'images/';
* ?></code>
*
* <b>For more extended examples of how to use this class, have a look at the example file which came
* with this class. It should be located in /example/example.php</b>
*
* *********************************************************************<br>
* <b>Version management information</b><br>
* *********************************************************************
*
* + v1.5 2006-09-02<br>
* - Improved inline documentation to work with {@link http://www.phpdoc.org/ phpDocumentor}
* and updated the example file<br>
* - Created separate methods to set the class variables and moved the main filelist get
* functionality out of the class instantiation<br>
* - Created various methods for retrieving selections of a filelist
* - Adjusted the methods to auto-re-use or auto-destroy the previous retrieved
* results so you can keep re-using the (instantiated) class<br>
* - Made a lot of file related methods static, i.e. callable without instantiating
* the class<br>
* - Added lots of new methods
* + v1.4 2006-07-04<br>
* - Added filecount variable
* + v1.3 2005-12-24<br>
* - Added support for uppercase filenames and uppercase extensions passed
* + v1.2 2005-12-05<br>
* - Rewrite of function to class to improve re-usability<br>
* - Added filesize option
* + v1.0 2004-07-15<br>
* - Originally posted as a function to the comments section
* of {@link http://www.php.net/function.readdir}
*
* *********************************************************************
*
* @package directory_info
* @author Juliette Reinders Folmer, {@link http://www.adviesenzo.nl/ Advies en zo} -
* <hide@address.com>
*
* @todo Check whether the $pathtofile checks can be removed
*
* @version 1.5
* @since 2006-09-02 // Last changed: by Juliette Reinders Folmer
* @copyright Advies en zo, Meedenken en -doen ©2004-2006
* @license http://www.opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
* @license http://opensource.org/licenses/academic Academic Free License Version 1.2
* @example example/example.php
*
*/
class directory_info {
/**********************************************************************
* INITIATION OF THE DEFAULT VARIABLES USED IN THE CLASS
*********************************************************************/
/**
* Directory to traverse
*
* - Relative path to a directory, i.e. relative to the calling file
* - IMPORTANT: end the path with a trailing '/' !!!
* - Defaults to the current directory
*
* @var string $pathtodir
*/
var $pathtodir = './';
/**
* Only show 'safe' files/directories ?
*
* - <i>true</i> means: only show 'safe' files (not .htaccess or references to higher
* directories)
* - <i>false</i> means: show all files
* - Defaults to <i>true</i>
*
* @var bool $safe_exts
**/
var $safe_exts = true;
/**
* Array of file extensions
*
* The list is used to determine which files should be included in the result array if you want
* to make a selection based on file extensions
* - Should be an array of file extensions to show only files which comply with these extensions
* - Alternatively, the special string-value <i>all</i> will show files independent
* of extensions.
* - Defaults to typical image file extensions (jpg, gif, jpeg, png)
*
* @see check_file_extension()
* @see check_allowed_file()
* @var array|string $exts
*/
var $exts = array( 'jpg', 'gif', 'jpeg', 'png' );
/**
* Array of mime types
*
* The list is used to determine which files should be included in the result array if you want
* to strictly check that the files returned not only comply with the file extensions given, but
* are also of the expected mimetype.
* - Should be an array of mimetypes to show only files which comply with these mimetypes
* - High level mimetypes (content-types such as <i>image</i>) may be used and will be converted
* to an array which covers all mimetypes within that content-type.
* - If left empty and a strict check is done via the {@link check_allowed_file()} method, the
* relevant mimetypes will be guessed based on the passed extensions.
* - Defaults to typical image file extensions (jpg, gif, jpeg, png)
*
* @see check_file_mimetype()
* @see check_allowed_file()
* @see $exts
* @var array $mimetypes
*/
var $mimetypes = array( 'image/jpeg', 'image/png', 'image/gif' );
/**
* Do a strict file type check ?
*
* Whether to check whether the files with the correct extension *really* are of the
* mime-type you would expect for a file with that extension.
* - Defaults to <i>false</i>, i.e. don't do a strict check
*
* @see $mime_map
* @see $valid_mime_types
* @var boolean $strict
*/
var $strict = false;
/**
* Default format string for the human readable last modified and last access date
*
* - Refer to the {@link http://www.php.net/function.date php documentation} for information
* on formatting strings available.
* - If set to an empty string, the {@link get_human_readable_lastacc()} and
* {@link get_human_readable_lastmod()} methods will return an
* unformatted unix timestamp.
* - Defaults to <i>Y-m-d H:i:s</i> which should display something like <i>2006-08-31 00:00:00</i>
*
* @link http://www.php.net/function.date
* @var string $date_time_format
**/
var $datetime_format = 'Y-m-d H:i:s';
/**
* Suffixes for use when creating human readable file size string
*
* @internal ALWAYS (manually) adjust {@link $byte_suffix_count} if suffixes are
* added or deleted from this array
*
* @access private
* @var array $byte_suffixes
**/
var $byte_suffixes = array( 'b', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
/**
* Number of byte suffixes available
*
* @internal ALWAYS (manually) adjust this if {@link $byte_suffixes} gets changed
*
* @access private
* @see $byte_suffixes
* @var int $byte_suffix_count
**/
var $byte_suffix_count = 9;
/**********************************************************************
* INITIATION OF THE RESULT VARIABLES USED IN THE CLASS
*********************************************************************/
/**
* Filelist result array
*
* @var array $filelist
**/
var $filelist = array();
/**
* Filelist selection result array
*
* @var array $filelist_selection
*/
var $filelist_selection = array();
/**
* Directory result array
*
* @var array $dirlist
*/
var $dirlist = array();
/**
* File count result variable
*
* Count of number of files in {@link $filelist}
* @var int $filecount
**/
var $filecount = 0;
/**
* File count of selection result variable
*
* Count of number of files in {@link $filelist_selection}
* @var int $fileselection_count
**/
var $fileselection_count = 0;
/**
* Directory count result variable
*
* Count of number of directories in {@link $dirlist}
* @var int $dircount
**/
var $dircount = 0;
/**
* Remember last path traversed for efficiency
*
* @see $pathtodir
* @var string $last_path
*/
var $last_path;
/**
* Remember last recursive setting for efficiency
*
* - Default for recursion is <i>false</i>
*
* @var string $last_recursive
*/
var $last_recursive;
/**
* Remember last passed extensions for efficiency
*
* @see $exts
* @var array|string $last_passed_exts
*/
var $last_passed_exts;
/**
* Remember last validated extensions for efficiency
*
* @see $exts
* @var array|string $last_exts
*/
var $last_exts;
/**
* Remember last passed mimetypes for efficiency
*
* @see $mimetypes
* @var array $last_passed_mimetypes
*/
var $last_passed_mimetypes;
/**
* Remember last validated mimetypes for efficiency
*
* @see $mimetypes
* @var array $last_mimetypes
*/
var $last_mimetypes;
/**********************************************************************
* METHODS TO CHANGE THE CLASS DEFAULTS
*********************************************************************/
/**
* Change the {@link $pathtodir} default
*
* - Refer to {@link $pathtodir} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $pathtodir to store new default
* @param string $pathtodir
* @return bool
*/
function set_default_path( $pathtodir ) {
if( ( is_string( $pathtodir ) && $pathtodir !== '' ) && is_dir( $pathtodir ) ) {
$this->pathtodir = $pathtodir;
return true;
}
return false;
}
/**
* Change the {@link $safe_exts} default
*
* - Refer to {@link $safe_exts} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $safe_exts to store new default
* @param bool $safe_exts
* @return bool
*/
function set_safe_exts( $safe_exts ) {
if( is_bool( $safe_exts ) ) {
$this->safe_exts = $safe_exts;
return true;
}
return false;
}
/**
* Change the {@link $exts} default
*
* - Refer to {@link $exts} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $exts to store new default
* @param array|string $exts
* @return bool
*/
function set_default_exts( $exts ) {
$exts = $this->validate_extension_list( $exts );
if( $exts !== $this->exts ) {
$this->exts = $exts;
return true;
}
return false;
}
/**
* Change the {@link $mimetypes} default
*
* - Refer to {@link $mimetypes} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $mimetypes to store new default
* @param array $mimetypes
* @return bool
*/
function set_default_mimetypes( $mimetypes ) {
$mimetypes = validate_mime_types( $mimetypes );
if( $mimetypes !== $this->mimetypes ) {
$this->mimetypes = $mimetypes;
return true;
}
return false;
}
/**
* Change the {@link $strict} default
*
* - Refer to {@link $strict} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $strict to store new default
* @param bool $strict
* @return bool
*/
function set_strict( $strict ) {
if( is_bool( $strict ) ) {
$this->strict = $strict;
return true;
}
return false;
}
/**
* Change the {@link $datetime_format} default
*
* - Refer to {@link $datetime_format} for information on valid formats for the variable
* - Returns boolean true / false to indicate whether the default was changed succesfully
* @uses $datetime_format to store new default
* @param string $datetime_format
* @return bool
*/
function set_datetime_format( $datetime_format ) {
if( is_string( $datetime_format ) && $datetime_format !== '' ) {
$this->datetime_format = $datetime_format;
return true;
}
return false;
}
/**********************************************************************
* METHODS TO VALIDATE SOME PASSED PARAMETERS
*********************************************************************/
/**
* Basic validation and parsing of a passed extensions parameter
*
* - This method does *not* check whether the extensions passed *are* real-life extensions,<br>
* i.e. it does not spell check nor check against a list of 'known' extensions.
* - If no parameter is passed or the parameter passed is not a string nor an array
* it defaults to the class default
* - If the passed $exts are the same as the last time this method was used, the check will
* be skipped and the results of last time will be used for efficiency
*
* @access private
* @uses $last_passed_exts for efficiency check / sets the variable if the current
* passed $exts is different
* @uses $last_exts for efficiency if the passed exts were already checked /
* sets this variable for same use if the passed $exts was
* different
* @uses $exts to default to if no valid extensions parameter was passed
* @param array|string $exts [optional] extensions parameter to validate
* @return array|string array of extensions or the string 'all'
*/
function validate_extension_list( $exts = null ) {
if( $exts !== $this->last_passed_exts || is_null( $this->last_passed_exts ) ) {
$this->last_passed_exts = $exts;
// If it's a string, check for all, otherwise create an array containing 1 item
if( is_string( $exts ) && $exts !== '' ) {
if( strtolower( $exts ) === 'all' ) {
$this->last_exts = strtolower( $exts );
}
else {
$this->last_exts = ( array( strtolower( $exts ) ) );
}
}
// If it's an array, make lowercase (which will cast the extension to string automatically)
elseif( is_array( $exts ) && count( $exts ) > 0 ) {
$ext_array = array();
foreach( $exts as $ext ) {
$ext_array[] = strtolower( $ext );
}
$this->last_exts = $ext_array;
}
// Otherwise return the default
else {
$this->last_exts = $this->exts;
}
}
return $this->last_exts;
}
/**
* Validation and parsing of a passed mimetypes parameter
*
* - This method checks whether a passed array of mimetypes is valid against the official list of
* valid types
* - Invalid mimetypes will be removed from the array
* - If a string is passed, it will be turned into a 1-item array and validated as if it were an
* array
* - If an array item validates as a content-type mimetype, all subtypes for that content-type will
* be added to the array as valid mimetypes
* - If no mimetypes were passed or no valid mimetypes were found, the class default will be used
* - If the passed $mimetypes are the same as the last time this method was used, the check will
* be skipped and the results of last time will be used for efficiency
*
* @access private
* @uses $last_passed_mimetypes for efficiency check / sets the variable if the current
* passed $mimetypes is different
* @uses $last_mimetypes for efficiency if the passed mimetypes were already checked /
* sets this variable for same use if the passed $mimetypes was
* different
* @uses $mimetypes to default to if no valid mimetypes were found
* @uses $valid_mime_types to validate the passed mimetypes and to retrieve subtypes
* @param array $mimetypes [optional] mimetypes to validate
* @return array validated mimetypes
*/
function validate_mime_types( $mimetypes = null ) {
if( $mimetypes !== $this->last_passed_mimetypes || is_null( $this->last_passed_mimetypes ) ) {
$this->last_passed_mimetypes = $mimetypes;
if( is_string( $mimetypes ) && $mimetypes !== '' ) {
// Cast to array and pass through
$mimetypes = array( $mimetypes );
}
if( is_array( $mimetypes ) && count( $mimetypes ) > 0 ) {
$mime_array = array();
foreach( $mimetypes as $mimetype ) {
if( is_string( $mimetype ) && $mimetype !== '' ) {
if( strpos( $mimetype, '/') === false ) {
if( isset( $this->valid_mime_types[$mimetype] ) ) {
foreach( $this->valid_mime_types[$mimetype] as $subtype ) {
$mime_array[] = $mimetype . '/' . $subtype;
}
}
}
else {
$mimeparts = explode( '/', $mimetype, 2 );
if( in_array( $mimeparts[1], $this->valid_mime_types[$mimeparts[0]], true) ) {
$mime_array[] = $mimetype;
}
}
}
}
if( count( $mime_array ) > 0 ) {
$this->last_mimetypes = array_unique( $mime_array );
}
}
else {
$this->last_mimetypes = $this->mimetypes;
}
}
return $this->last_mimetypes;
}
/**
* Clears the file stat cache and checks whether the passed $pathtofile is a valid path to a file
*
* @param string $pathtofile
* @return bool
*/
function valid_pathtofile( $pathtofile ) {
clearstatcache();
// Check if a non empty string has been passed as pathtofile
return ( ( is_string( $pathtofile ) && $pathtofile !== '' ) && file_exists( $pathtofile ) );
}
/**********************************************************************
* METHODS TO RETRIEVE INFORMATION ON INDIVIDUAL FILES
*********************************************************************/
/**
* Check whether the file is allowed based on extension and if $strict=true also on mimetype
*
* - Will use the class defaults for optional parameters which were not passed
* - Will try to 'guess' the mimetypes if a strict check is requested, but no mimetypes were
* passed
* - Returns <i>true</i> is the file passes, <i>false</i> if not.
*
* @see $exts
* @see $strict
* @see $mimetypes
* @uses $mime_map to 'guess' mimetypes based on $exts if no $mimetypes parameter
* was passed and a strict check was requested
* @uses validate_extension_list() to validate the passed extension list
* @uses check_file_extension() to validate the file against the extension list
* @uses check_file_mimetype() to validate the file against the mimetypes
* @param string $pathtofile path to the file to check
* @param array|string $exts [optional] allowed extensions
* @param bool $strict [optional] whether or not to check on mimetype
* @param array $mimetypes [optional] allowed mimetypes
* @return bool
*/
function check_allowed_file( $pathtofile, $exts = null, $strict = null, $mimetypes = null ) {
$strict = ( is_bool( $strict ) ) ? $strict : $this->strict;
if( $strict ) {
/**
* We only try to build a mimetype list based on the extensions when exts is not null,
* not all nor the default and mimetypes is null.
* In all other cases this is not needed as the {@see check_file_extension()}
* and the {@see check_file_mimetype()} will validate the passed parameters anyway
* and will default to the class default.
*/
if( is_null( $mimetypes ) && !is_null( $exts ) ) {
$exts = $this->validate_extension_list( $exts );
if( is_string( $exts) && strtolower( $exts ) === 'all' ) {
// Fall through - mimetype check superfluous
return ( $this->check_file_extension( $pathtofile, $exts ) );
}
elseif( $exts === $this->exts && !is_null( $this->mimetypes ) ) {
$mimetypes = $this->mimetypes;
}
else {
$exts = $this->validate_extension_list( $exts );
$mimetypes = array();
foreach( $exts as $ext ) {
if( isset( $this->mime_map[$ext] ) ) {
$mimetypes[] = $this->mime_map[$ext];
}
else {
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 );
}
}
$mimetypes = array_unique( $mimetypes );
}
}
return ( $this->check_file_extension( $pathtofile, $exts ) && $this->check_file_mimetype( $pathtofile, $mimetypes ) );
}
else {
return ( $this->check_file_extension( $pathtofile, $exts ) );
}
}
/**
* Check the file extension of a filename against the list of allowed extensions
*
* - This is a case-insensitive extension check
* - Will use the class defaults for optional parameters which were not passed
* - Returns <i>true</i> if the filename passes the valid extension check
* - Returns <i>false</i> is it fails or if the passed filename parameter is not a string
*
* @see $exts
* @uses validate_extension_list() used to parse the extension list to the expected format
* @param string $filename filename to check
* @param array|string $exts [optional] array of allowed extensions
* @return bool
**/
function check_file_extension( $filename, $exts = null ) {
// Check if a non empty string has been passed as filename
if( !is_string( $filename ) || $filename === '' ) {
return false;
}
// Validate the optional parameters and default to the class defaults if not passed or invalid
$exts = $this->validate_extension_list( $exts );
// If all extensions are allowed, return true
if( $exts === 'all') {
return true;
}
// If the function is still running, check the extension against the allowed extension list
$pos = strrpos( $filename, '.' );
if( $pos !== false ) {
// Strip the everything before and including the '.'
$file_ext = substr( $filename, ( $pos + 1 ) );
return( in_array( $file_ext, $exts, true ) );
}
// No extension found
return false;
}
/**
* Check the file-mimetype against a list of allowed mimetypes
*
* - Will use the class defaults for optional parameters which were not passed
* - Returns <i>true</i> if the file-mimetype is within the list of allowed mimetypes
* - Returns <i>false</i> if not or if the passed filename parameter is not a string
*
* @see $mimetypes
* @uses valid_pathtofile() to check whether the $pathtofile parameter is valid
* @uses validate_mime_types() to validate the passed mimetypes
* @uses get_mime_content_type() to retrieve the file mimetype
* @param string $pathtofile
* @param array $mimetypes [optional] array of valid mimetypes
* @return bool
*/
function check_file_mimetype( $pathtofile, $mimetypes = null ) {
if( !$this->valid_pathtofile( $pathtofile ) ) {
return false;
}
$mimetypes = $this->validate_mime_types( $mimetypes );
$file_mimetype = $this->get_mime_content_type( $pathtofile );
return ( in_array( $file_mimetype, $mimetypes ) );
}
/**
* Get the filesize of a file
*
* @static
* @link http://www.php.net/function.filesize
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return int|false filesize or false if an invalid $pathtofile was passed
*/
function get_filesize( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
return filesize( $pathtofile );
}
/**
* Get the filesize of a file in a human readable format
*
* @uses get_filesize() to retrieve the filesize
* @uses human_readable_filesize() to convert the filesize to a human readable string
* @param string $pathtofile
* @return string|false human readable filesize string or false if an invalid
* $pathtofile was passed
*/
function get_human_readable_filesize( $pathtofile ) {
$filesize = $this->get_filesize( $pathtofile );
return ( ( $filesize !== false ) ? $this->human_readable_filesize( $filesize ) : false );
}
/**
* Creates a human readable file size string
*
* - Rounds bytes and kilobytes to the nearest integer
* - Rounds anything else to one digit behind the decimal point
* - Returns <i>false</i> is the passed parameter is not an integer or a numeric string
*
* Examples:<br>
* the integer <i>1080</i> becomes the string <i>1 kB</i><br>
* the integer <i>3000000</i> becomes the string <i>2.8 MB</i>
*
* @uses $byte_suffixes for the byte suffixes
* @uses $byte_suffix_count
* @param int $filesize filesize in bytes
* @return string|false human readable filesize string
* or false if the passed variable was not an integer
**/
function human_readable_filesize( $filesize ) {
if( is_int( $filesize ) && $filesize > 0 ) {
// Get the figure to use in the string
for( $i = 0; ( $i < $this->byte_suffix_count && $filesize >= 1024 ); $i++ ) {
$filesize = $filesize / 1024;
}
// Return the rounded figure with the appropriate suffix
if( $this->byte_suffixes[$i] === 'b' || $this->byte_suffixes[$i] === 'kB' ) {
return( round( $filesize, 0 ) . ' ' . $this->byte_suffixes[$i] );
}
else {
return( round( $filesize, 1 ) . ' ' . $this->byte_suffixes[$i] );
}
}
else {
return false;
}
}
/**
* Get the last modified unix timestamp for a file
*
* @static
* @link http://www.php.net/function.filemtime
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return int|false unix timestamp or false if an invalid $pathtofile was passed
*/
function get_lastmod_unixts( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
return filemtime( $pathtofile );
}
/**
* Get the last modified timestamp of a file in a human readable format
*
* @uses get_lastmod_unixts() to retrieve the last modified unix timestamp
* @uses $datetime_format as a default date/time format if no format was passed
* @param string $pathtofile
* @param string $datetime_format [optional]
* @return string|false human readable date/time string or false if an invalid
* $pathtofile was passed
*/
function get_human_readable_lastmod( $pathtofile, $datetime_format = null ) {
if( !is_string( $datetime_format ) || $datetime_format === '' ) {
$datetime_format = $this->datetime_format;
}
$uts = $this->get_lastmod_unixts( $pathtofile );
return ( ( $datetime_format !== '' && $uts !== false ) ? date( $datetime_format, $uts ) : false );
}
/**
* Get the last access unix timestamp for a file
*
* @static
* @link http://www.php.net/function.fileatime
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return int|false unix timestamp or false if an invalid $pathtofile was passed
*/
function get_lastacc_unixts( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
return fileatime( $pathtofile );
}
/**
* Get the last access timestamp of a file in a human readable format
*
* @uses get_lastacc_unixts() to retrieve the last access unix timestamp
* @uses $datetime_format as a default date/time format if no format was passed
* @param string $pathtofile
* @param string $datetime_format [optional]
* @return string|false human readable date/time string or false if an invalid
* $pathtofile was passed
*/
function get_human_readable_lastacc( $pathtofile, $datetime_format = null ) {
if( !is_string( $datetime_format ) || $datetime_format === '' ) {
$datetime_format = $this->datetime_format;
}
$uts = $this->get_lastacc_unixts( $pathtofile );
return ( ( $datetime_format !== '' && $uts !== false ) ? date( $datetime_format, $uts ) : false );
}
/**
* Get the file owner for a file
*
* @static
* @link http://www.php.net/function.fileowner
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return int|false user id of the file owner or false if an invalid $pathtofile was passed
*/
function get_file_owner( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
return fileowner( $pathtofile );
}
/**
* Get the mime content type of a file
*
* @static
* @author keczerad at poczta dot fm - 30-Aug-2006 10:38
* @link http://www.php.net/function.mime-content-type
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return string|false mimetype string or false if an invalid $pathtofile was passed
*/
function get_mime_content_type( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
if( function_exists( 'mime_content_type' ) ) {
return mime_content_type( $pathtofile );
}
else {
return exec( trim( 'file -bi ' . escapeshellarg( $pathtofile ) ) ) ;
}
}
/**
* Get a human readable file permission string for a file
*
* @static
* @link http://www.php.net/function.fileperms
* @uses valid_pathtofile() to check whether the passed parameter is a file
* @param string $pathtofile
* @return string|false file permission string or false if an invalid $pathtofile was passed
*/
function get_human_readable_file_permissions( $pathtofile ) {
if( !directory_info::valid_pathtofile( $pathtofile ) ) {
return false;
}
$perms = fileperms( $pathtofile );
if( ( $perms & 0xC000 ) == 0xC000 ) { $info = 's'; } // Socket
elseif( ( $perms & 0xA000 ) == 0xA000 ) { $info = 'l'; } // Symbolic Link
elseif( ( $perms & 0x8000 ) == 0x8000 ) { $info = '-'; } // Regular
elseif( ( $perms & 0x6000 ) == 0x6000 ) { $info = 'b'; } // Block special
elseif( ( $perms & 0x4000 ) == 0x4000 ) { $info = 'd'; } // Directory
elseif( ( $perms & 0x2000 ) == 0x2000 ) { $info = 'c'; } // Character special
elseif( ( $perms & 0x1000 ) == 0x1000 ) { $info = 'p'; } // FIFO pipe
else { $info = 'u'; } // Unknown
// Owner
$info .= ( ( $perms & 0x0100 ) ? 'r' : '-' );
$info .= ( ( $perms & 0x0080 ) ? 'w' : '-' );
$info .= ( ( $perms & 0x0040 ) ?
( ( $perms & 0x0800 ) ? 's' : 'x' ) :
( ( $perms & 0x0800 ) ? 'S' : '-' ) );
// Group
$info .= ( ( $perms & 0x0020 ) ? 'r' : '-' );
$info .= ( ( $perms & 0x0010 ) ? 'w' : '-' );
$info .= ( ( $perms & 0x0008 ) ?
( ( $perms & 0x0400 ) ? 's' : 'x' ) :
( ( $perms & 0x0400 ) ? 'S' : '-' ) );
// World
$info .= ( ( $perms & 0x0004 ) ? 'r' : '-' );
$info .= ( ( $perms & 0x0002 ) ? 'w' : '-' );
$info .= ( ( $perms & 0x0001 ) ?
( ( $perms & 0x0200 ) ? 't' : 'x' ) :
( ( $perms & 0x0200 ) ? 'T' : '-' ) );
return $info;
}
/**********************************************************************
* METHODS TO RETRIEVE FILE LISTS
*********************************************************************/
/**
* Get list of files in $pathtodir
*
* - Use this method to retrieve a filelist for a certain directory path
* - If a filelist was created before and you want to retrieve this list, you can use this function
* without any parameters and it will return the previously created list
* - If you created a selection based on the earlier created filelist, you can choose to retrieve
* that selection instead by setting $use_selection to <i>true</i>
* - If no filelist was created before and no parameters are passed, it will retrieve a filelist
* based on the class defaults
* - If you call this method as a static method, logically you can not retrieve an earlier
* created listing or selection list
*
* @uses $last_path to check whether the requested list already exists
* @uses $last_recursive to check whether the requested list already exists
* @uses traverse_directory() to retrieve a new filelist if needed
* @uses $filelist to return the list as stored by {@link traverse_directory}
* now or earlier
* @uses $filecount to check that $filelist contains results if the requested list
* already seemed to exist
* @uses $pathtodir to default to if no $pathtodir was passed
* @uses $fileselection_count to check that $filelist_selection contains results if the
* requested list already seemed to exist and the last selection was
* requested - if selection was empty, then the complete list will be
* returned
* @uses $filelist_selection to return the selection list if the selection list was
* not empty and the selection was requested
*
* @param bool $use_selection [optional] whether or not the last made selection should
* be returned if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array of filenames
*/
function get_filelist( $use_selection = null, $pathtodir = null, $recursive = null ) {
// If a pathtodir was passed and the path to dir was not the same as the last one used
// to get a filelist, build a new filelist
if( !is_null( $pathtodir ) && ( $pathtodir !== $this->last_path || $recursive !== $this->last_recursive ) ) {
$this->traverse_directory( $pathtodir, $recursive );
return $this->filelist;
}
elseif( is_null( $pathtodir ) && $this->filecount === 0 ) {
$this->traverse_directory( $this->pathtodir, $recursive );
return $this->filelist;
}
elseif( $use_selection === true && $this->fileselection_count > 0 ) {
return $this->filelist_selection;
}
else {
return $this->filelist;
}
}
/**
* Get a list of directories in $pathtodir
*
* @see get_filelist() for more information on retrieving an earlier created list
* @uses $last_path to check whether the requested list already exists
* @uses $last_recursive to check whether the requested list already exists
* @uses traverse_directory() to retrieve a new dirlist if needed
* @uses $dirlist to return the list as stored by {@link traverse_directory}
* now or earlier
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on directories in
* subdirectories
* @return array array of filenames
*/
function get_dir_list( $pathtodir, $recursive = null ) {
if( !is_null( $pathtodir ) && ( $pathtodir !== $this->last_path || $recursive !== $this->last_recursive ) ) {
$this->traverse_directory( $pathtodir, $recursive );
}
elseif( is_null( $pathtodir ) && $this->dircount === 0 ) {
$this->traverse_directory( $this->pathtodir, $recursive );
}
return $this->dirlist;
}
/**
* Function to traverse a directory
*
* - This is the actual workhorse method which traverses the directory
* - This method checks whether something is a file before accepting the file in the filelist
* - This method uses the {@link $safe_exts} class setting to determine whether or not to include
* 'unsafe' files
* - This function can be called recursively for subdirectories, but this has to be explicitely set
* Default is non-recursive
* - The results of the function are stored in the class variables {@link $filelist},
* {@link $filecount}, {@link $dirlist} and {@link $dircount}
*
* @access private
* @link http://www.php.net/function.readdir
* @uses $last_path sets this variable
* @uses $last_recursive sets this variable
* @uses $filelist_selection re-sets this variable
* @uses $fileselection_count re-sets this variable
* @uses $filelist to store the results
* (sorted ascendingly in case-insensitive natural sort order)
* @uses $filecount to store a count of $filelist
* @uses $dirlist to store the results
* (sorted ascendingly in case-insensitive natural sort order)
* @uses $dircount to store a count of $dirlist
*
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @param string $prefix [optional] gets set internally when this function
* is used recursively
* @return void sets class variables {@link $filelist} and {@link $filecount}
*
*/
function traverse_directory( $pathtodir, $recursive = false, $prefix = '' ) {
if( $prefix === '' ) {
$this->last_path = $pathtodir;
$this->last_recursive = $recursive;
$this->filelist = array();
$this->filelist_selection = array();
$this->dirlist = array();
$this->filecount = 0;
$this->fileselection_count = 0;
$this->dircount = 0;
}
if( $handle = @opendir( $pathtodir ) ) {
while( ( $filename = readdir( $handle ) ) !== false ) {
// Check if the file is an 'unsafe' one such as .htaccess or
// higher directory references, if so, skip
if( $this->safe_exts === true && strpos( $filename, '.' ) === 0 ) {
// do nothing
}
else {
// If it's a file, check against valid extensions and add to the list
if( is_file( $pathtodir . $filename ) === true ) {
$this->filelist[] = $prefix . $filename;
}
// If it's a directory and subdirectories should be listed,
// add the subdirectory to the list.
// If files from subdirs should be listed, run this function on the subdirectory
elseif( is_dir( $pathtodir . $filename ) === true ) {
$this->dirlist[] = $prefix . $filename . '/';
if( $recursive === true) {
$this->traverse_directory( $pathtodir . $filename . '/', $recursive, $prefix . $filename . '/' );
}
}
}
unset( $filename );
}
closedir( $handle );
$this->filecount = count( $this->filelist );
$this->dircount = count( $this->dirlist );
if( $this->dircount > 1 ) {
natcasesort( $this->dirlist );
$this->dirlist = array_values( $this->dirlist );
}
if( $this->filecount > 1 ) {
natcasesort( $this->filelist );
$this->filelist = array_values( $this->filelist );
}
}
}
/**
* Retrieve a filelist which only contains files which comply with the allowed extension/mimetypes
*
* - Creates a selection list of files which comply with the criteria set by
* allowed extensions / allowed mimetypes
* - $strict determined whether or not to check on mimetype
* - $exts, $strict and $mimetypes default to the class defaults if not passed
*
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses check_allowed_file() to check for each file whether it complies with the criteria
* @uses $filelist_selection to store the results
* @uses $fileselection_count to store a count of the results
*
* @param bool $use_selection [optional] whether or not the last made selection should
* be returned if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @param array|string $exts [optional] allowed extensions
* @param bool $strict [optional] whether or not to check on mimetype
* @param array $mimetypes [optional] allowed mimetypes
* @return array array of filenames of files which pass the test
*/
function get_ext_based_filelist( $use_selection = null, $pathtodir = null, $recursive = null, $exts = null, $strict = null, $mimetypes = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
$passed_files = array();
foreach( $files as $filename ) {
if( $this->check_allowed_file( $this->last_path . $filename, $exts, $strict, $mimetypes ) ) {
$passed_files[] = $filename;
}
}
$this->filelist_selection = $passed_files;
$this->fileselection_count = count( $this->filelist_selection );
return $this->filelist_selection;
}
/**
* Retrieve a sorted filelist
*
* - Mainly useful for reverse sorting as the normal filelist is already sorted in
* ascending order
* - Defaults to <i>ascending</i> sort order
* - To sort descendingly, set $sort_asc to <i>false</i>
* - The list sorting will always use case-insensitive natural sort order
* - Retrieving a sorted list will not affect the order of the class 'remembered' filelists
*
* @link http://www.php.net/function.natcasesort
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @param bool $sort_asc [optional] set to false for reverse / descending sorted list
* @param bool $use_selection [optional] whether or not the last made selection should
* be returned if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array sorted array of filenames
*/
function get_sorted_filelist( $sort_asc = null, $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
// Sort the resulting file list
if( count( $files ) > 1 ) {
natcasesort( $files );
if( $sort_asc === false ) {
$files = array_reverse( $files, true );
}
$files = array_values( $files );
}
return $files;
}
/**
* Retrieve a sorted (sub-)directory list
*
* - Mainly useful for reverse sorting as the normal dirlist is already sorted in
* ascending order
* - Defaults to <i>ascending</i> sort order
* - To sort descendingly, set $sort_asc to <i>false</i>
* - The list sorting will always use case-insensitive natural sort order
* - Retrieving a sorted list will not affect the order of the class 'remembered' dirlist
*
* @link http://www.php.net/function.natcasesort
* @see get_filelist() for more information on retrieving an earlier created list
* @uses get_dir_list() to retrieve the directory list
* @param bool $sort_asc [optional] set to false for reverse / descending sorted list
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on directories in
* subdirectories
* @return array sorted array of (sub-)directory names
*/
function get_sorted_dirlist( $sort_asc = null, $pathtodir = null, $recursive = null ) {
$dirs = $this->get_dir_list( $pathtodir, $recursive );
// Sort the resulting file list
if( count( $dirs ) > 1 ) {
natcasesort( $dirs );
if( $sort_asc === false ) {
$dirs = array_reverse( $dirs, true );
}
$dirs = array_values( $dirs );
}
return $dirs;
}
/**
* Retrieve the filename and last_modified date of the most recently modified file
*
* Inspired by a comment from wookie at at no-way dot org - 14-Sep-2003 11:17
*
* @link http://www.php.net/function.filemtime
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array with two key-value sets:
* 'filename' => filename of most recent file
* 'last_modified' => last modified unix timestamp of the file
*/
function get_most_recent_file( $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
// Initialize result
$last_mod_ts = 0;
$last_mod_file = '';
foreach( $files as $filename ) {
$file_mod_ts = $this->get_lastmod_unixts( $this->last_path . $filename);
if( $file_mod_ts > $last_mod_ts ) {
$last_mod_ts = $file_mod_ts;
$last_mod_file = $filename;
}
unset( $file_mod_ts );
}
return array( 'filename' => $last_mod_file, 'last_modified' => $last_mod_ts );
}
/**
* Retrieve a filelist which only contains files modified since the passed unix timestamp
*
* - Creates a selection list of files which comply with the criteria set by $comparets
*
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
*
* @link http://www.php.net/function.filemtime
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
* @uses $filelist_selection to store the results
* @uses $fileselection_count to store a count of the results
*
* @param int $compare_ts Unix timestamp for date/time to compare against
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array of filenames of files which pass the test
*/
function get_files_modified_since( $compare_ts, $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
foreach( $files as $key => $filename ) {
$file_mod_ts = $this->get_lastmod_unixts( $this->last_path . $filename);
if( $file_mod_ts < $compare_ts ) {
unset( $files[$key] );
}
}
$this->filelist_selection = $files;
$this->fileselection_count = count( $this->filelist_selection );
return $this->filelist_selection;
}
/**
* Retrieve a filelist which only contains files modified before the passed unix timestamp
*
* - Creates a selection list of files which comply with the criteria set by $comparets
*
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
*
* @link http://www.php.net/function.filemtime
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses get_lastmod_unixts() to get the last modified unix timestamp for each file to test
* @uses $filelist_selection to store the results
* @uses $fileselection_count to store a count of the results
*
* @param int $compare_ts Unix timestamp for date/time to compare against
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array of filenames of files which pass the test
*/
function get_files_modified_before( $compare_ts, $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
foreach( $files as $key => $filename ) {
$file_mod_ts = $this->get_lastmod_unixts( $this->last_path . $filename);
if( $file_mod_ts > $compare_ts ) {
unset( $files[$key] );
}
}
$this->filelist_selection = $files;
$this->fileselection_count = count( $this->filelist_selection );
return $this->filelist_selection;
}
/**
* Retrieve a filelist which only contains files accessed since the passed unix timestamp
*
* - Creates a selection list of files which comply with the criteria set by $comparets
*
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
*
* @link http://www.php.net/function.fileatime
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses get_lastacc_unixts() to get the last access unix timestamp for each file to test
* @uses $filelist_selection to store the results
* @uses $fileselection_count to store a count of the results
*
* @param int $compare_ts Unix timestamp for date/time to compare against
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array of filenames of files which pass the test
*/
function get_files_accessed_since( $compare_ts, $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
foreach( $files as $key => $filename ) {
$file_mod_ts = $this->get_lastacc_unixts( $this->last_path . $filename);
if( $file_mod_ts < $comparets ) {
unset( $files[$key] );
}
}
$this->filelist_selection = $files;
$this->fileselection_count = count( $this->filelist_selection );
return $this->filelist_selection;
}
/**
* Retrieve a filelist which only contains files accessed before the passed unix timestamp
*
* - Creates a selection list of files which comply with the criteria set by $comparets
*
* Inspired by a comment from Benan Tumkaya (benantumkaya at yahoo) - 14-Aug-2006 11:11
*
* @link http://www.php.net/function.fileatime
* @uses get_filelist() to retrieve the requested filelist - refer to this method for
* more information on retrieving listings already created
* @uses get_lastacc_unixts() to get the last access unix timestamp for each file to test
* @uses $filelist_selection to store the results
* @uses $fileselection_count to store a count of the results
*
* @param int $compare_ts Unix timestamp for date/time to compare against
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the list
* @param bool $recursive [optional] whether to retrieve information on files in
* subdirectories
* @return array array of filenames of files which pass the test
*/
function get_files_accessed_before( $compare_ts, $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
foreach( $files as $key => $filename ) {
$file_mod_ts = $this->get_lastacc_unixts( $this->last_path . $filename);
if( $file_mod_ts > $comparets ) {
unset( $files[$key] );
}
}
$this->filelist_selection = $files;
$this->fileselection_count = count( $this->filelist_selection );
return $this->filelist_selection;
}
/**
* Get the total size of all files in $pathtodir
*
* @author marting.dc AT gmail.com - 29-Jan-2006 02:08
* @see http://www.php.net/function.stat
* @uses get_filelist() to retrieve a filelist to use - refer to this method for
* more information on retrieving listings already created
* @uses get_filesize() to retrieve information on the filesize of individual files
*
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the size
* @param bool $recursive [optional] whether to include filesize of files in
* subdirectories
* @return int total size of files in directory in bytes
*/
function get_dirsize( $use_selection = null, $pathtodir = null, $recursive = null ) {
$files = $this->get_filelist( $use_selection, $pathtodir, $recursive );
// Initialize result
$dirsize = 0;
foreach( $files as $filename ) {
$dirsize += $this->get_filesize( $this->last_path . $filename );
}
return $dirsize;
}
/**
* Get the total size of all files in a directory in a human readable format
*
* @uses get_dirsize() to retrieve the total size of the files in the directory
* @uses human_readable_filesize() to convert the size to a human readable string
* @param bool $use_selection [optional] whether or not the last made selection should
* be used if available
* @param string $pathtodir [optional] path to the directory for which to get the size
* @param bool $recursive [optional] whether to include filesize of files in
* subdirectories
* @return string human readable directory size string
*/
function get_human_readable_dirsize( $use_selection = null, $pathtodir = null, $recursive = null ) {
$dirsize = $this->get_dirsize( $use_selection, $pathtodir, $recursive );
return $this->human_readable_filesize( $dirsize );
}
/**
* Mapping of file extensions to their expected mime-type
*
* This mapping does not claim to be exhaustive, but is a good listing for a large amount
* of file types.
*
* Last updated: 2006-08-31
*
* @link http://www.duke.edu/websrv/file-extensions.html
* @var array $mime_map key = file extension, value = mime-type
*/
var $mime_map = array(
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'asc' => 'text/plain',
'au' => 'audio/basic',
'avi' => 'video/x-msvideo',
'bcpio' => 'application/x-bcpio',
'bin' => 'application/octet-stream',
'c' => 'text/plain',
'cc' => 'text/plain',
'ccad' => 'application/clariscad',
'cdf' => 'application/x-netcdf',
'class' => 'application/octet-stream',
'cpio' => 'application/x-cpio',
'cpt' => 'application/mac-compactpro',
'csh' => 'application/x-csh',
'css' => 'text/css',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dms' => 'application/octet-stream',
'doc' => 'application/msword',
'drw' => 'application/drafting',
'dvi' => 'application/x-dvi',
'dwg' => 'application/acad',
'dxf' => 'application/dxf',
'dxr' => 'application/x-director',
'eps' => 'application/postscript',
'etx' => 'text/x-setext',
'exe' => 'application/octet-stream',
'ez' => 'application/andrew-inset',
'f' => 'text/plain',
'f90' => 'text/plain',
'fli' => 'video/x-fli',
'gif' => 'image/gif',
'gtar' => 'application/x-gtar',
'gz' => 'application/x-gzip',
'h' => 'text/plain',
'hdf' => 'application/x-hdf',
'hh' => 'text/plain',
'hqx' => 'application/mac-binhex40',
'htm' => 'text/html',
'html' => 'text/html',
'ice' => 'x-conference/x-cooltalk',
'ief' => 'image/ief',
'iges' => 'model/iges',
'igs' => 'model/iges',
'ips' => 'application/x-ipscript',
'ipx' => 'application/x-ipix',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'application/x-javascript',
'kar' => 'audio/midi',
'latex' => 'application/x-latex',
'lha' => 'application/octet-stream',
'lsp' => 'application/x-lisp',
'lzh' => 'application/octet-stream',
'm' => 'text/plain',
'man' => 'application/x-troff-man',
'me' => 'application/x-troff-me',
'mesh' => 'model/mesh',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mif' => 'application/vnd.mif',
'mime' => 'www/mime',
'mov' => 'video/quicktime',
'movie' => 'video/x-sgi-movie',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpga' => 'audio/mpeg',
'ms' => 'application/x-troff-ms',
'msh' => 'model/mesh',
'nc' => 'application/x-netcdf',
'oda' => 'application/oda',
'pbm' => 'image/x-portable-bitmap',
'pdb' => 'chemical/x-pdb',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'pgn' => 'application/x-chess-pgn',
'php' => 'text/plain',
'php3' => 'text/plain',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'pot' => 'application/mspowerpoint',
'ppm' => 'image/x-portable-pixmap',
'pps' => 'application/mspowerpoint',
'ppt' => 'application/mspowerpoint',
'ppz' => 'application/mspowerpoint',
'pre' => 'application/x-freelance',
'prt' => 'application/pro_eng',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'ra' => 'audio/x-realaudio',
'ram' => 'audio/x-pn-realaudio',
'ras' => 'image/cmu-raster',
'rgb' => 'image/x-rgb',
'rm' => 'audio/x-pn-realaudio',
'roff' => 'application/x-troff',
'rpm' => 'audio/x-pn-realaudio-plugin',
'rtf' => 'text/rtf',
'rtx' => 'text/richtext',
'scm' => 'application/x-lotusscreencam',
'set' => 'application/set',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'sh' => 'application/x-sh',
'shar' => 'application/x-shar',
'silo' => 'model/mesh',
'sit' => 'application/x-stuffit',
'skd' => 'application/x-koan',
'skm' => 'application/x-koan',
'skp' => 'application/x-koan',
'skt' => 'application/x-koan',
'smi' => 'application/smil',
'smil' => 'application/smil',
'snd' => 'audio/basic',
'sol' => 'application/solids',
'spl' => 'application/x-futuresplash',
'src' => 'application/x-wais-source',
'step' => 'application/STEP',
'stl' => 'application/SLA',
'stp' => 'application/STEP',
'sv4cpio' => 'application/x-sv4cpio',
'sv4crc' => 'application/x-sv4crc',
'swf' => 'application/x-shockwave-flash',
't' => 'application/x-troff',
'tar' => 'application/x-tar',
'tcl' => 'application/x-tcl',
'tex' => 'application/x-tex',
'texi' => 'application/x-texinfo',
'texinfo' => 'application/x-texinfo',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'tr' => 'application/x-troff',
'tsi' => 'audio/TSP-audio',
'tsp' => 'application/dsptype',
'tsv' => 'text/tab-separated-values',
'txt' => 'text/plain',
'unv' => 'application/i-deas',
'ustar' => 'application/x-ustar',
'vcd' => 'application/x-cdlink',
'vda' => 'application/vda',
'viv' => 'video/vnd.vivo',
'vivo' => 'video/vnd.vivo',
'vrml' => 'model/vrml',
'wav' => 'audio/x-wav',
'wrl' => 'model/vrml',
'xbm' => 'image/x-xbitmap',
'xlc' => 'application/vnd.ms-excel',
'xll' => 'application/vnd.ms-excel',
'xlm' => 'application/vnd.ms-excel',
'xls' => 'application/vnd.ms-excel',
'xlw' => 'application/vnd.ms-excel',
'xml' => 'text/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'xyz' => 'chemical/x-pdb',
'zip' => 'application/zip'
);
/**
* Valid mime types
*
* Last updated on 2006-08-31
* @link http://www.iana.org/assignments/media-types/
* @var array key = Content-type, value = array of valid subtypes for that content-type
*/
var $valid_mime_types = array(
'application' => array( 'activemessage', 'andrew-inset', 'applefile', 'atom+xml',
'atomicmail', 'batch-SMTP', 'beep+xml', 'cals-1840', 'ccxml+xml', 'cnrp+xml',
'commonground', 'conference-info+xml', 'cpl+xml', 'csta+xml', 'CSTAdata+xml',
'cybercash', 'dca-rft', 'dec-dx', 'dialog-info+xml', 'dicom', 'dns', 'dvcs',
'ecmascript', 'EDI-Consent', 'EDIFACT', 'EDI-X12', 'epp+xml', 'eshop', 'example',
'fastinfoset', 'fastsoap', 'fits', 'font-tdpfr', 'H224', 'http', 'hyperstudio',
'iges', 'im-iscomposing+xml', 'index', 'index.cmd', 'index.obj', 'index.response',
'index.vnd', 'iotp', 'ipp', 'isup', 'javascript', 'json', 'kpml-request+xml',
'kpml-response+xml', 'mac-binhex40', 'macwriteii', 'marc', 'mathematica', 'mbox',
'mikey', 'mpeg4-generic', 'mpeg4-iod', 'mpeg4-iod-xmt', 'mp4', 'msword', 'mxf',
'nasdata', 'news-message-id', 'news-transmission', 'nss', 'ocsp-request',
'ocsp-response', 'octet-stream', 'oda', 'ogg', 'parityfec', 'pdf', 'pgp-encrypted',
'pgp-keys', 'pgp-signature', 'pidf+xml', 'pkcs10', 'pkcs7-mime', 'pkcs7-signature',
'pkix-cert', 'pkixcmp', 'pkix-crl', 'pkix-pkipath', 'pls+xml', 'poc-settings+xml',
'postscript', 'prs.alvestrand.titrax-sheet', 'prs.cww', 'prs.nprend', 'prs.plucker',
'rdf+xml', 'qsig', 'reginfo+xml', 'relax-ng-compact-syntax', 'remote-printing',
'resource-lists+xml', 'riscos', 'rlmi+xml', 'rls-services+xml', 'rtf', 'rtx',
'samlassertion+xml', 'samlmetadata+xml', 'sbml+xml', 'sdp', 'set-payment',
'set-payment-initiation', 'set-registration', 'set-registration-initiation',
'sgml', 'sgml-open-catalog', 'shf+xml', 'sieve', 'simple-filter+xml',
'simple-message-summary', 'slate', 'smil', //OBSOLETE
'smil+xml', 'soap+fastinfoset', 'soap+xml', 'spirits-event+xml', 'srgs',
'srgs+xml', 'ssml+xml', 'timestamp-query', 'timestamp-reply', 'tve-trigger', 'vemmi',
'vnd.3gpp.bsf+xml', 'vnd.3gpp.pic-bw-large', 'vnd.3gpp.pic-bw-small',
'vnd.3gpp.pic-bw-var', 'vnd.3gpp.sms', 'vnd.3gpp2.bcmcsinfo+xml', 'vnd.3gpp2.sms',
'vnd.3M.Post-it-Notes', 'vnd.accpac.simply.aso', 'vnd.accpac.simply.imp',
'vnd.acucobol', 'vnd.acucorp', 'vnd.adobe.xfdf', 'vnd.aether.imp', 'vnd.amiga.ami',
'vnd.anser-web-certificate-issue-initiation', 'vnd.apple.installer+xml',
'vnd.audiograph', 'vnd.autopackage', 'vnd.blueice.multipass', 'vnd.bmi',
'vnd.businessobjects', 'vnd.canon-cpdl', 'vnd.canon-lips', 'vnd.cinderella',
'vnd.chipnuts.karaoke-mmd', 'vnd.claymore', 'vnd.commerce-battelle',
'vnd.commonspace', 'vnd.cosmocaller', 'vnd.contact.cmsg', 'vnd.crick.clicker',
'vnd.crick.clicker.keyboard', 'vnd.crick.clicker.palette',
'vnd.crick.clicker.template', 'vnd.crick.clicker.wordbank',
'vnd.criticaltools.wbs+xml', 'vnd.ctc-posml', 'vnd.cups-pdf', 'vnd.cups-postscript',
'vnd.cups-ppd', 'vnd.cups-raster', 'vnd.cups-raw', 'vnd.curl', 'vnd.cybank',
'vnd.data-vision.rdz', 'vnd.dna', 'vnd.dpgraph', 'vnd.dreamfactory',
'vnd.dvb.esgcontainer', 'vnd.dvb.ipdcesgaccess', 'vnd.dxr', 'vnd.ecdis-update',
'vnd.ecowin.chart', 'vnd.ecowin.filerequest', 'vnd.ecowin.fileupdate',
'vnd.ecowin.series', 'vnd.ecowin.seriesrequest', 'vnd.ecowin.seriesupdate',
'vnd.enliven', 'vnd.epson.esf', 'vnd.epson.msf', 'vnd.epson.quickanime',
'vnd.epson.salt', 'vnd.epson.ssf', 'vnd.ericsson.quickcall', 'vnd.eudora.data',
'vnd.ezpix-album', 'vnd.ezpix-package', 'vnd.fdf', 'vnd.ffsns', 'vnd.fints',
'vnd.FloGraphIt', 'vnd.fluxtime.clip', 'vnd.framemaker', 'vnd.frogans.fnc',
'vnd.frogans.ltf', 'vnd.fsc.weblaunch', 'vnd.fujitsu.oasys', 'vnd.fujitsu.oasys2',
'vnd.fujitsu.oasys3', 'vnd.fujitsu.oasysgp', 'vnd.fujitsu.oasysprs',
'vnd.fujixerox.ART4', 'vnd.fujixerox.ART-EX', 'vnd.fujixerox.ddd',
'vnd.fujixerox.docuworks', 'vnd.fujixerox.docuworks.binder', 'vnd.fujixerox.HBPL',
'vnd.fut-misnet', 'vnd.genomatix.tuxedo', 'vnd.grafeq', 'vnd.groove-account',
'vnd.groove-help', 'vnd.groove-identity-message', 'vnd.groove-injector',
'vnd.groove-tool-message', 'vnd.groove-tool-template', 'vnd.groove-vcard',
'vnd.HandHeld-Entertainment+xml', 'vnd.hbci', 'vnd.hcl-bireports',
'vnd.hhe.lesson-player', 'vnd.hp-HPGL', 'vnd.hp-hpid', 'vnd.hp-hps',
'vnd.hp-jlyt', 'vnd.hp-PCL', 'vnd.hp-PCLXL', 'vnd.httphone', 'vnd.hzn-3d-crossword',
'vnd.ibm.afplinedata', 'vnd.ibm.electronic-media', 'vnd.ibm.MiniPay',
'vnd.ibm.modcap', 'vnd.ibm.rights-management', 'vnd.ibm.secure-container',
'vnd.igloader', 'vnd.informix-visionary', 'vnd.intercon.formnet',
'vnd.intertrust.digibox', 'vnd.intertrust.nncp', 'vnd.intu.qbo', 'vnd.intu.qfx',
'vnd.ipunplugged.rcprofile', 'vnd.irepository.package+xml', 'vnd.is-xpr',
'vnd.japannet-directory-service', 'vnd.japannet-jpnstore-wakeup',
'vnd.japannet-payment-wakeup', 'vnd.japannet-registration',
'vnd.japannet-registration-wakeup', 'vnd.japannet-setstore-wakeup',
'vnd.japannet-verification', 'vnd.japannet-verification-wakeup',
'vnd.jisp', 'vnd.kahootz', 'vnd.kde.karbon', 'vnd.kde.kchart', 'vnd.kde.kformula',
'vnd.kde.kivio', 'vnd.kde.kontour', 'vnd.kde.kpresenter', 'vnd.kde.kspread',
'vnd.kde.kword', 'vnd.kenameaapp', 'vnd.kidspiration', 'vnd.Kinar',
'vnd.koan', 'vnd.liberty-request+xml', 'vnd.llamagraphics.life-balance.desktop',
'vnd.llamagraphics.life-balance.exchange+xml', 'vnd.lotus-1-2-3',
'vnd.lotus-approach', 'vnd.lotus-freelance', 'vnd.lotus-notes',
'vnd.lotus-organizer', 'vnd.lotus-screencam', 'vnd.lotus-wordpro',
'vnd.marlin.drm.mdcf', 'vnd.mcd', 'vnd.medcalcdata', 'vnd.mediastation.cdkey',
'vnd.meridian-slingshot', 'vnd.mfmp', 'vnd.micrografx.flo', 'vnd.micrografx.igx',
'vnd.mif', 'vnd.minisoft-hp3000-save', 'vnd.mitsubishi.misty-guard.trustweb',
'vnd.Mobius.DAF', 'vnd.Mobius.DIS', 'vnd.Mobius.MBK', 'vnd.Mobius.MQY',
'vnd.Mobius.MSL', 'vnd.Mobius.PLC', 'vnd.Mobius.TXF', 'vnd.mophun.application',
'vnd.mophun.certificate', 'vnd.motorola.flexsuite', 'vnd.motorola.flexsuite.adsi',
'vnd.motorola.flexsuite.fis', 'vnd.motorola.flexsuite.gotap',
'vnd.motorola.flexsuite.kmr', 'vnd.motorola.flexsuite.ttc',
'vnd.motorola.flexsuite.wem', 'vnd.mozilla.xul+xml', 'vnd.ms-artgalry',
'vnd.ms-asf', 'vnd.ms-cab-compressed', 'vnd.mseq', 'vnd.ms-excel',
'vnd.ms-fontobject', 'vnd.ms-htmlhelp', 'vnd.msign', 'vnd.ms-ims', 'vnd.ms-lrm',
'vnd.ms-powerpoint', 'vnd.ms-project', 'vnd.ms-tnef', 'vnd.ms-wmdrm.lic-chlg-req',
'vnd.ms-wmdrm.lic-resp', 'vnd.ms-works', 'vnd.ms-wpl', 'vnd.ms-xpsdocument',
'vnd.musician', 'vnd.music-niff', 'vnd.nervana', 'vnd.netfpx',
'vnd.noblenet-directory', 'vnd.noblenet-sealer', 'vnd.noblenet-web',
'vnd.nokia.catalogs', 'vnd.nokia.conml+wbxml', 'vnd.nokia.conml+xml',
'vnd.nokia.iptv.config+xml', 'vnd.nokia.landmark+wbxml', 'vnd.nokia.landmark+xml',
'vnd.nokia.landmarkcollection+xml', 'vnd.nokia.pcd+wbxml', 'vnd.nokia.pcd+xml',
'vnd.nokia.radio-preset', 'vnd.nokia.radio-presets', 'vnd.novadigm.EDM',
'vnd.novadigm.EDX', 'vnd.novadigm.EXT', 'vnd.oasis.opendocument.chart',
'vnd.oasis.opendocument.chart-template', 'vnd.oasis.opendocument.formula',
'vnd.oasis.opendocument.formula-template', 'vnd.oasis.opendocument.graphics',
'vnd.oasis.opendocument.graphics-template', 'vnd.oasis.opendocument.image',
'vnd.oasis.opendocument.image-template', 'vnd.oasis.opendocument.presentation',
'vnd.oasis.opendocument.presentation-template', 'vnd.oasis.opendocument.spreadsheet',
'vnd.oasis.opendocument.spreadsheet-template', 'vnd.oasis.opendocument.text',
'vnd.oasis.opendocument.text-master', 'vnd.oasis.opendocument.text-template',
'vnd.oasis.opendocument.text-web', 'vnd.obn', 'vnd.oma.dd2+xml',
'vnd.omads-email+xml', 'vnd.omads-file+xml', 'vnd.omads-folder+xml',
'vnd.omaloc-supl-init', 'vnd.osa.netdeploy', 'vnd.osgi.dp', 'vnd.otps.ct-kip+xml',
'vnd.palm', 'vnd.paos.xml', 'vnd.pg.format', 'vnd.pg.osasli',
'vnd.piaccess.application-licence', 'vnd.picsel', 'vnd.pocketlearn',
'vnd.powerbuilder6', 'vnd.powerbuilder6-s', 'vnd.powerbuilder7',
'vnd.powerbuilder75', 'vnd.powerbuilder75-s', 'vnd.powerbuilder7-s',
'vnd.preminet', 'vnd.previewsystems.box', 'vnd.proteus.magazine',
'vnd.publishare-delta-tree', 'vnd.pvi.ptid1', 'vnd.pwg-multiplexed',
'vnd.pwg-xhtml-print+xml', 'vnd.qualcomm.brew-app-res', 'vnd.Quark.QuarkXPress',
'vnd.rapid', 'vnd.RenLearn.rlprint', 'vnd.ruckus.download', 'vnd.s3sms',
'vnd.scribus', 'vnd.sealed.3df', 'vnd.sealed.csf', 'vnd.sealed.doc',
'vnd.sealed.eml', 'vnd.sealed.mht', 'vnd.sealed.net', 'vnd.sealed.ppt',
'vnd.sealed.tiff', 'vnd.sealed.xls', 'vnd.sealedmedia.softseal.html',
'vnd.sealedmedia.softseal.pdf', 'vnd.seemail', 'vnd.sema',
'vnd.shana.informed.formdata', 'vnd.shana.informed.formtemplate',
'vnd.shana.informed.interchange', 'vnd.shana.informed.package',
'vnd.smaf', 'vnd.solent.sdkm+xml', 'vnd.sss-cod', 'vnd.sss-dtf', 'vnd.sss-ntf',
'vnd.street-stream', 'vnd.sun.wadl+xml', 'vnd.sus-calendar', 'vnd.svd',
'vnd.swiftview-ics', 'vnd.syncml.dm+wbxml', 'vnd.syncml.ds.notification',
'vnd.syncml.+xml', 'vnd.triscape.mxs', 'vnd.trueapp', 'vnd.truedoc',
'vnd.ufdl', 'vnd.uiq.theme', 'vnd.umajin', 'vnd.uoml+xml', 'vnd.uplanet.alert',
'vnd.uplanet.alert-wbxml', 'vnd.uplanet.bearer-choice',
'vnd.uplanet.bearer-choice-wbxml', 'vnd.uplanet.cacheop', 'vnd.uplanet.cacheop-wbxml',
'vnd.uplanet.channel', 'vnd.uplanet.channel-wbxml', 'vnd.uplanet.list',
'vnd.uplanet.listcmd', 'vnd.uplanet.listcmd-wbxml', 'vnd.uplanet.list-wbxml',
'vnd.uplanet.signal', 'vnd.vcx', 'vnd.vectorworks', 'vnd.vd-study',
'vnd.vidsoft.vidconference', 'vnd.visio', 'vnd.visionary',
'vnd.vividence.scriptfile', 'vnd.vsf', 'vnd.wap.sic', 'vnd.wap.slc', 'vnd.wap.wbxml',
'vnd.wap.wmlc', 'vnd.wap.wmlscriptc', 'vnd.webturbo', 'vnd.wfa.wsc',
'vnd.wordperfect', 'vnd.wqd', 'vnd.wrq-hp3000-labelled', 'vnd.wt.stf',
'vnd.wv.csp+xml', 'vnd.wv.csp+wbxml', 'vnd.wv.ssp+xml', 'vnd.xara', 'vnd.xfdl',
'vnd.yamaha.hv-dic', 'vnd.yamaha.hv-script', 'vnd.yamaha.hv-voice',
'vnd.yamaha.smaf-audio', 'vnd.yamaha.smaf-phrase', 'vnd.yellowriver-custom-menu',
'vnd.zzazz.deck+xml', 'voicexml+xml', 'watcherinfo+xml', 'whoispp-query',
'whoispp-response', 'wita', 'wordperfect5.1', 'x400-bp', 'xcap-att+xml',
'xcap-caps+xml', 'xcap-el+xml', 'xcap-error+xml', 'xenc+xml',
'xhtml-voice+xml', // OBSOLETE
'xhtml+xml', 'xml', 'xml-dtd', 'xml-external-parsed-entity', 'xmpp+xml',
'xop+xml', 'xv+xml', 'zip',
),
'audio' => array(
'32kadpcm', '3gpp', '3gpp2', 'ac3', 'AMR', 'AMR-WB', 'amr-wb+', 'asc',
'basic', 'BV16', 'BV32', 'clearmode', 'CN', 'DAT12', 'dls', 'dsr-es201108',
'dsr-es202050', 'dsr-es202211', 'dsr-es202212', 'eac3', 'DVI4', 'EVRC',
'EVRC0', 'EVRC-QCP', 'example', 'G722', 'G7221', 'G723', 'G726-16',
'G726-24', 'G726-32', 'G726-40', 'G728', 'G729', 'G729D', 'G729E', 'GSM',
'GSM-EFR', 'iLBC', 'L8', 'L16', 'L20', 'L24', 'LPC', 'MPA', 'mp4', 'MP4A-LATM',
'mpa-robust', 'mpeg', 'mpeg4-generic', 'parityfec', 'PCMA', 'PCMU', 'prs.sid',
'QCELP', 'RED', 'rtp-midi', 'rtx', 'SMV', 'SMV0', 'SMV-QCP', 't140c', 't38',
'telephone-event', 'tone', 'VDVI', 'VMR-WB', 'vnd.3gpp.iufp', 'vnd.4SB',
'vnd.audiokoz', 'vnd.CELP', 'vnd.cisco.nse', 'vnd.cmles.radio-events',
'vnd.cns.anp1', 'vnd.cns.inf1', 'vnd.digital-winds', 'vnd.dlna.adts',
'vnd.everad.plj', 'vnd.hns.audio', 'vnd.lucent.voice', 'vnd.nokia.mobile-xmf',
'vnd.nortel.vbk', 'vnd.nuera.ecelp4800', 'vnd.nuera.ecelp7470',
'vnd.nuera.ecelp9600', 'vnd.octel.sbc',
'vnd.qcelp', // DEPRECATED - Please use audio/qcelp
'vnd.rhetorex.32kadpcm', 'vnd.sealedmedia.softseal.mpeg', 'vnd.vmx.cvsd'
),
'example' => array(),
'image ' => array(
'cgm', 'example', 'fits', 'g3fax', 'gif', 'ief', 'jp2', 'jpeg', 'jpm', 'jpx',
'naplps', 'png', 'prs.btif', 'prs.pti', 't38', 'tiff', 'tiff-fx',
'vnd.adobe.photoshop', 'vnd.cns.inf2', 'vnd.djvu', 'vnd.dwg', 'vnd.dxf',
'vnd.fastbidsheet', 'vnd.fpx', 'vnd.fst', 'vnd.fujixerox.edmics-mmr',
'vnd.fujixerox.edmics-rlc', 'vnd.globalgraphics.pgb', 'vnd.microsoft.icon',
'vnd.mix', 'vnd.ms-modi', 'vnd.net-fpx', 'vnd.sealed.png',
'vnd.sealedmedia.softseal.gif', 'vnd.sealedmedia.softseal.jpg', 'vnd.svf',
'vnd.wap.wbmp', 'vnd.xiff'
),
'message' => array(
'CPIM', 'delivery-status', 'disposition-notification', 'example',
'external-body', 'http', 'news', 'partial', 'rfc822', 's-http', 'sip',
'sipfrag', 'tracking-status'
),
'model' => array(
'example', 'iges', 'mesh', 'vnd.dwf', 'vnd.flatland.3dml', 'vnd.gdl',
'vnd.gs-gdl', 'vnd.gtw', 'vnd.moml+xml', 'vnd.mts', 'vnd.parasolid.transmit.binary',
'vnd.parasolid.transmit.text', 'vnd.vtu', 'vrml'
),
'multipart' => array(
'alternative', 'appledouble', 'byteranges', 'digest', 'encrypted', 'example',
'form-data', 'header-set', 'mixed', 'parallel', 'related', 'report', 'signed',
'voice-message'
),
'text' => array(
'calendar', 'css', 'csv', 'directory', 'dns', 'ecmascript', // OBSOLETE
'enriched', 'example', 'html', 'javascript', // OBSOLETE
'parityfec', 'plain', 'prs.fallenstein.rst', 'prs.lines.tag', 'RED',
'rfc822-headers', 'richtext', 'rtf', 'rtx', 'sgml', 't140',
'tab-separated-values', 'troff', 'uri-list', 'vnd.abc', 'vnd.curl',
'vnd.DMClientScript', 'vnd.esmertec.theme-descriptor', 'vnd.fly',
'vnd.fmi.flexstor', 'vnd.in3d.3dml', 'vnd.in3d.spot', 'vnd.IPTC.NewsML',
'vnd.IPTC.NITF', 'vnd.latex-z', 'vnd.motorola.reflex', 'vnd.ms-mediapackage',
'vnd.net2phone.commcenter.command', 'vnd.sun.j2me.app-descriptor', 'vnd.wap.si',
'vnd.wap.sl', 'vnd.wap.wml', 'vnd.wap.wmlscript', 'xml', 'xml-external-parsed-entity'
),
'video' => array(
'3gpp', '3gpp2', '3gpp-tt', 'BMPEG', 'BT656', 'CelB', 'DV', 'example', 'H261',
'H263', 'H263-1998', 'H263-2000', 'H264', 'JPEG', 'MJ2', 'MP1S', 'MP2P', 'MP2T',
'mp4', 'MP4V-ES', 'MPV', 'mpeg', 'mpeg4-generic', 'nv', 'parityfec', 'pointer',
'quicktime', 'raw', 'rtx', 'SMPTE292M', 'vc1', 'vnd.dlna.mpeg-tts', 'vnd.fvt',
'vnd.hns.video', 'vnd.motorola.video', 'vnd.motorola.videop', 'vnd.mpegurl',
'vnd.nokia.interleaved-multimedia', 'vnd.objectvideo', 'vnd.sealed.mpeg1',
'vnd.sealed.mpeg4', 'vnd.sealed.swf', 'vnd.sealedmedia.softseal.mov',
'vnd.vivo'
)
);
}// End of class
//****** END OF FILE ******/
?>