eZ Publish  [trunk]
ezmimetype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZMimeType class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012   \class eZMimeType ezmimetype.php
00013   \ingroup eZUtils
00014   \brief Detection and management of MIME types.
00015 
00016   The MIME type structure is an array with the following items:
00017   - name     - The name of MIME type, eg. image/jpeg
00018   - suffixes - An array with possible suffixes for the filename, the first entry can be used as when creating filenames of the type.
00019                If no known suffixes exists this value is \a false
00020   - prefixes - An array with possible prefixes for the filename, the first entry can be used as when creating filenames of the type.
00021                If no known prefixes exists this value is \a false
00022   - is_valid - Boolean which tells whether this MIME type is valid or not, usually this is set to \c false if no
00023                match for the file was found in which case the name will also be application/octet-stream
00024   - url      - The original url or file supplied to the matching system, can be \c false if buffer matching was used.
00025   - filename - Just the filename part of the url
00026   - dirpath  - The directory path part of the url
00027   - basename - The basename of the filename without suffix or prefix
00028   - suffix   - The suffix of the file or \c false if none
00029   - prefix   - The prefix of the file or \c false if none
00030 
00031 */
00032 
00033 class eZMimeType
00034 {
00035     /*!
00036      Constructor
00037     */
00038     function eZMimeType()
00039     {
00040         $this->SuffixList = array();
00041         $this->PrefixList = array();
00042         $this->MIMEList = array();
00043 
00044         $ini = eZINI::instance( 'mime.ini' );
00045         $this->QuickMIMETypes = array();
00046         foreach ( $ini->groups() as $extension => $blockValues )
00047         {
00048             foreach ( $blockValues['Types'] as $type )
00049             {
00050                 $this->QuickMIMETypes[] = array( $extension, $type );
00051             }
00052         }
00053 
00054         foreach ( $this->QuickMIMETypes as $quickMIMEType )
00055         {
00056             $mimeEntry =& $this->MIMEList[$quickMIMEType[1]];
00057             if ( !isset( $mimeEntry ) )
00058                 $mimeEntry = array( 'suffixes' => array(),
00059                                     'prefixes' => false );
00060             $mimeEntry['suffixes'][] = $quickMIMEType[0];
00061         }
00062 
00063         eZMimeType::prepareSuffixList( $this->SuffixList, $this->MIMEList );
00064         eZMimeType::preparePrefixList( $this->PrefixList, $this->MIMEList );
00065     }
00066 
00067     /*!
00068      \static
00069      \return the default MIME-Type, this is used for all files that are not recognized.
00070     */
00071     static function defaultMimeType()
00072     {
00073         return array( 'name' => 'application/octet-stream',
00074                       'url' => false,
00075                       'filename' => false,
00076                       'dirpath' => false,
00077                       'basename' => false,
00078                       'suffix' => false,
00079                       'prefix' => false,
00080                       'suffixes' => false,
00081                       'prefixes' => false,
00082                       'is_valid' => true );
00083     }
00084 
00085     /*!
00086      \static
00087      \return the defaultMimeType if \a $returnDefault is \c true, otherwise returns \c false.
00088     */
00089     static function defaultValue( $url, $returnDefault )
00090     {
00091         if ( $returnDefault )
00092         {
00093             $mime = eZMimeType::defaultMimeType();
00094             $mime['url'] = $url;
00095             $suffixPos = strpos( $url, '.' );
00096 
00097             if ( $suffixPos !== false )
00098             {
00099                 $mime['suffix'] = substr( $url, $suffixPos + 1 );
00100                 $mime['dirpath'] = dirname( $url );
00101                 $mime['basename'] = basename( $url, '.' . $mime['suffix'] );
00102                 $mime['filename'] = $mime['basename'] . '.' . $mime['suffix'];
00103             }
00104             else
00105             {
00106                 $mime['basename'] = $url;
00107                 $mime['suffix'] = false;
00108             }
00109             $mime['is_valid'] = false;
00110             return $mime;
00111         }
00112         else
00113             return false;
00114     }
00115 
00116     /*!
00117      Changes the MIME type attribute for the MIME info structure \a $mimeInfo to \a $mimetype,
00118      and recreates all the affected fields.
00119     */
00120     static function changeMIMEType( &$mimeInfo, $mimetype )
00121     {
00122         $mimeInfo['name'] = $mimetype;
00123         $newMimeInfo = eZMimeType::findByName( $mimetype );
00124         $mimeInfo['suffixes'] = $newMimeInfo['suffixes'];
00125         $mimeInfo['prefixes'] = $newMimeInfo['prefixes'];
00126         $mimeInfo['suffix'] = $newMimeInfo['suffix'];
00127         $mimeInfo['prefix'] = $newMimeInfo['prefix'];
00128         $filename = $mimeInfo['filename'];
00129         $dotPosition = strrpos( $filename, '.' );
00130         $basename = $filename;
00131         if ( $dotPosition !== false )
00132             $basename = substr( $filename, 0, $dotPosition );
00133         $mimeInfo['filename'] = $basename . '.' . $mimeInfo['suffix'];
00134         if ( $mimeInfo['dirpath'] )
00135             $mimeInfo['url'] = $mimeInfo['dirpath'] . '/' . $mimeInfo['filename'];
00136         else
00137             $mimeInfo['url'] = $mimeInfo['filename'];
00138     }
00139 
00140     /*!
00141      Changes the basename attribute for the MIME info structure \a $mimeInfo to \a $basename,
00142      and recreates all the affected fields.
00143     */
00144     static function changeBasename( &$mimeInfo, $basename )
00145     {
00146         $mimeInfo['basename'] = $basename;
00147         $mimeInfo['filename'] = $basename . '.' . $mimeInfo['suffix'];
00148         if ( $mimeInfo['dirpath'] )
00149             $mimeInfo['url'] = $mimeInfo['dirpath'] . '/' . $mimeInfo['filename'];
00150         else
00151             $mimeInfo['url'] = $mimeInfo['filename'];
00152     }
00153 
00154     /*!
00155      Changes the basename attribute for the MIME info structure \a $mimeInfo to \a $basename,
00156      and recreates all the affected fields.
00157     */
00158     static function changeDirectoryPath( &$mimeInfo, $dirpath )
00159     {
00160         $mimeInfo['dirpath'] = $dirpath;
00161         if ( $mimeInfo['dirpath'] )
00162             $mimeInfo['url'] = $mimeInfo['dirpath'] . '/' . $mimeInfo['filename'];
00163         else
00164             $mimeInfo['url'] = $mimeInfo['filename'];
00165     }
00166 
00167     /*!
00168      Changes the basename attribute for the MIME info structure \a $mimeInfo to \a $basename,
00169      and recreates all the affected fields.
00170     */
00171     static function changeFileData( &$mimeInfo, $dirpath = false, $basename = false, $suffix = false, $filename = false )
00172     {
00173         if ( $basename !== false )
00174             $mimeInfo['basename'] = $basename;
00175         if ( $suffix !== false )
00176             $mimeInfo['suffix'] = $suffix;
00177         if ( $filename !== false )
00178         {
00179             $mimeInfo['filename'] = $filename;
00180         }
00181         else
00182         {
00183             $mimeInfo['filename'] = $mimeInfo['basename'];
00184             $mimeInfo['filename'] .= '.' . $mimeInfo['suffix'];
00185         }
00186         if ( $dirpath !== false )
00187             $mimeInfo['dirpath'] = $dirpath;
00188 
00189         if ( $mimeInfo['dirpath'] )
00190             $mimeInfo['url'] = $mimeInfo['dirpath'] . '/' . $mimeInfo['filename'];
00191         else
00192             $mimeInfo['url'] = $mimeInfo['filename'];
00193     }
00194 
00195     /*!
00196      \return the MIME structure for the MIME type \a $mimeName.
00197      If \a $returnDefault is set to \c true then it will always return a MIME structure,
00198      if not it will return \c false if none were found.
00199     */
00200     static function findByName( $mimeName, $returnDefault = true )
00201     {
00202         $instance = eZMimeType::instance();
00203         $mimeList =& $instance->MIMEList;
00204         if ( isset( $mimeList[$mimeName] ) )
00205         {
00206             $mime = $mimeList[$mimeName];
00207             $mime['name'] = $mimeName;
00208             $mime['url'] = false;
00209             $mime['filename'] = false;
00210             $mime['dirpath'] = false;
00211             $mime['basename'] = false;
00212             $mime['suffix'] = false;
00213             if ( isset( $mime['suffixes'][0] ) )
00214                 $mime['suffix'] = $mime['suffixes'][0];
00215             $mime['prefix'] = false;
00216             if ( isset( $mime['prefixes'][0] ) )
00217                 $mime['prefix'] = $mime['prefixes'][0];
00218             $mime['is_valid'] = true;
00219             return $mime;
00220         }
00221         return eZMimeType::defaultValue( false, $returnDefault );
00222     }
00223 
00224     /*!
00225      \static
00226      Finds the MIME type for the url \a $url by examining the url itself (not the content) and returns it.
00227      If \a $returnDefault is set to \c true then it will always return a MIME structure,
00228      if not it will return \c false if none were found.
00229     */
00230     static function findByURL( $url, $returnDefault = true )
00231     {
00232         $instance = eZMimeType::instance();
00233 
00234         $file = $url;
00235         $dirPosition = strrpos( $url, '/' );
00236         if ( $dirPosition !== false )
00237             $file = substr( $url, $dirPosition + 1 );
00238         $suffixPosition = strrpos( $file, '.' );
00239         $suffix = false;
00240         $prefix = false;
00241         $mimeName = false;
00242         if ( $suffixPosition !== false )
00243         {
00244             $suffix = strtolower( substr( $file, $suffixPosition + 1 ) );
00245             if ( $suffix )
00246             {
00247                 $subURL = substr( $file, 0, $suffixPosition );
00248                 $suffixList =& $instance->SuffixList;
00249                 if ( array_key_exists( $suffix, $suffixList ) )
00250                 {
00251                     $mimeName = $suffixList[$suffix];
00252                 }
00253             }
00254             if ( !$mimeName )
00255             {
00256                 $prefixPosition = strpos( $file, '.' );
00257                 if ( $prefixPosition !== false )
00258                 {
00259                     $prefix = strtolower( substr( $file, 0, $prefixPosition ) );
00260                 }
00261                 if ( $prefix )
00262                 {
00263                     $subURL = substr( $file, $suffixPosition + 1 );
00264                     $prefixList =& $instance->PrefixList;
00265                     if ( array_key_exists( $prefix, $prefixList ) )
00266                     {
00267                         $mimeName = $prefixList[$prefix];
00268                     }
00269                 }
00270             }
00271             if ( $mimeName )
00272             {
00273                 $mimeList =& $instance->MIMEList;
00274                 if ( array_key_exists( $mimeName, $mimeList ) )
00275                 {
00276                     $lastDirPosition = strrpos( $url, '/' );
00277                     $filename = $url;
00278                     $dirpath = false;
00279                     if ( $lastDirPosition !== false )
00280                     {
00281                         $filename = substr( $url, $lastDirPosition + 1 );
00282                         $dirpath = substr( $url, 0, $lastDirPosition );
00283                     }
00284                     $lastDirPosition = strrpos( $subURL, '/' );
00285                     $basename = $subURL;
00286                     if ( $lastDirPosition !== false )
00287                         $basename = substr( $subURL, $lastDirPosition + 1 );
00288                     $mime = $mimeList[$mimeName];
00289                     $mime['name'] = $mimeName;
00290                     $mime['url'] = $url;
00291                     $mime['filename'] = $filename;
00292                     $mime['dirpath'] = $dirpath;
00293                     $mime['basename'] = $basename;
00294                     $mime['suffix'] = $suffix;
00295                     $mime['prefix'] = $prefix;
00296                     $mime['is_valid'] = true;
00297                     return $mime;
00298                 }
00299             }
00300         }
00301         return eZMimeType::defaultValue( $url, $returnDefault );
00302     }
00303 
00304     /*!
00305      \static
00306      Finds the MIME type for the url \a $url by examining the contents of the url and returns it.
00307      If \a $returnDefault is set to \c true then it will always return a MIME structure,
00308      if not it will return \c false if none were found.
00309      \note Currently it only calls findByURL()
00310     */
00311     static function findByFileContents( $url, $returnDefault = true )
00312     {
00313         return eZMimeType::findByURL( $url, $returnDefault );
00314     }
00315 
00316     /*!
00317      \static
00318      Finds the MIME type for the buffer \a $buffer by examining the contents and returns it.
00319      If \a $returnDefault is set to \c true then it will always return a MIME structure,
00320      if not it will return \c false if none were found.
00321      \param $length If specified it will limit how far the \a $buffer is examined
00322      \param $offset If specified it will set the starting point for the \a $buffer examination
00323      \param $url If specified the url will be used for MIME determination if buffer examination gives no results.
00324      \note Currently it only calls findByURL()
00325     */
00326     static function findByBuffer( $buffer, $length = false, $offset = false, $url = false, $returnDefault = true )
00327     {
00328         return eZMimeType::findByURL( $url, $returnDefault );
00329     }
00330 
00331     /**
00332      * Returns a shared instance of the eZMimeType class.
00333      *
00334      * @return eZMimeType
00335      */
00336     static function instance()
00337     {
00338         $instance =& $GLOBALS['eZMIMETypeInstance'];
00339         if ( !isset( $instance ) )
00340         {
00341             $instance = new eZMimeType();
00342         }
00343         return $instance;
00344     }
00345 
00346     /*!
00347      \deprecated
00348      \static
00349      \return the MIME-Type name for the file \a $file.
00350     */
00351     static function mimeTypeFor( $path, $file )
00352     {
00353         eZDebug::writeWarning( 'eZMimeType::mimeTypeFor() is deprecated, use eZMimeType::findByURL() instead',
00354                                'DEPRECATED FUNCTION eZMimeType::mimeTypeFor' );
00355         $url = $path;
00356         if ( $url )
00357             $url .= '/' . $file;
00358         else
00359             $url = $file;
00360         $match = eZMimeType::findByURL( $url, false );
00361         if ( $match )
00362             return $match['name'];
00363         else
00364             return false;
00365     }
00366 
00367     /*!
00368      \private
00369      Goes trough the mime list and creates a reference to the mime entry using the primary suffix.
00370     */
00371     static function prepareSuffixList( &$suffixList, $mimeList )
00372     {
00373         foreach ( $mimeList as $mimeName => $mimeData )
00374         {
00375             if ( is_array( $mimeData['suffixes'] ) )
00376             {
00377                 foreach ( $mimeData['suffixes'] as $suffix )
00378                 {
00379                     if ( !isset( $suffixList[$suffix] ) )
00380                         $suffixList[$suffix] = $mimeName;
00381                 }
00382             }
00383         }
00384     }
00385 
00386     /*!
00387      \private
00388      Goes trough the mime list and creates a reference to the mime entry using the primary prefix.
00389     */
00390     static function preparePrefixList( &$prefixList, $mimeList )
00391     {
00392         foreach ( $mimeList as $mimeName => $mimeData )
00393         {
00394             if ( is_array( $mimeData['prefixes'] ) )
00395             {
00396                 foreach ( $mimeData['prefixes'] as $prefix )
00397                 {
00398                     if ( !isset( $prefixList[$prefix] ) )
00399                         $prefixList[$prefix] = $mimeName;
00400                 }
00401             }
00402         }
00403     }
00404 
00405     /// \privatesection
00406 
00407     /// An associative array which maps from suffix name to MIME type name.
00408     public $SuffixList;
00409     /// An associative array which maps from prefix name to MIME type name.
00410     public $PrefixList;
00411     /// An associative array which maps MIME type name to MIME structure.
00412     public $MIMEList;
00413 
00414     public $QuickContentMatch = array(
00415         array( array( 0, 'string', 'GIF87a', 'image/gif' ),
00416                array( 0, 'string', 'GIF89a', 'image/gif' ) )
00417         );
00418 
00419     /// A list of suffixes and their MIME types, this is used to quickly initialize the system.
00420     public $QuickMIMETypes = array();
00421 }
00422 ?>