eZ Publish  [trunk]
ezimagehandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZImageHandler 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 eZImageHandler ezimagehandler.php
00013   \ingroup eZImage
00014   \brief The class eZImageHandler does
00015 
00016 */
00017 
00018 class eZImageHandler
00019 {
00020     const KEEP_SUFFIX = 1;
00021     const REPLACE_SUFFIX = 2;
00022     const PREPEND_TAG_REPLACE_SUFFIX = 3;
00023 
00024     /*!
00025      Initializes the image handler with data sent from the inheriting class.
00026      \param $handlerName The name of the current handler
00027      \param $isEnabled A boolean which tells whether the handler can be used or not
00028      \param $outputRewriteType Defines how output filenames are rewritten
00029      \param $supportedInputMIMETypes A list of MIME-Types the handler supports as input or \c false if no type as defined
00030      \param $supportedOutputMIMETypes A list of MIME-Types the handler supports as output or \c false if no type as defined
00031      \param $conversionRules A list of conversion rules specific for this handler, is combined with the global rules
00032      \param $filters A list of filters this handler supports
00033      \param $mimeTagMap A mapping table which maps from a MIME-Type to a specific tag, this tag can be used when rewriting the filename.
00034     */
00035     function eZImageHandler( $handlerName, $isEnabled = true, $outputRewriteType = self::REPLACE_SUFFIX,
00036                              $supportedInputMIMETypes = false, $supportedOutputMIMETypes,
00037                              $conversionRules = false, $filters = false, $mimeTagMap = false )
00038     {
00039         $this->HandlerName = $handlerName;
00040         $this->SupportedInputMIMETypes = $supportedInputMIMETypes;
00041         $this->SupportedOutputMIMETypes = $supportedOutputMIMETypes;
00042         $this->ConversionRules = $conversionRules;
00043         $this->OutputRewriteType = $outputRewriteType;
00044         $this->Filters = $filters;
00045         $this->FilterMap = array();
00046         $this->SupportImageFilters = array();
00047         $this->MIMETagMap = array();
00048         if ( $mimeTagMap )
00049             $this->MIMETagMap = $mimeTagMap;
00050         if ( $this->Filters)
00051         {
00052             foreach ( array_keys( $this->Filters ) as $filterKey )
00053             {
00054                 $filter =& $this->Filters[$filterKey];
00055                 $this->FilterMap[$filter['name']] =& $filter;
00056                 $this->SupportImageFilters[] = $filter['name'];
00057             }
00058         }
00059         $this->SupportImageFilters = array_unique( $this->SupportImageFilters );
00060         $this->IsEnabled = $isEnabled;
00061     }
00062 
00063     /*!
00064      \return whether this handler can be used or not.
00065 
00066      Implementors of image handlers should implement this to return true if
00067      the image conversion system to be used is available, for instance to check
00068      for a PHP extension.
00069      \note default is to return \c true.
00070     */
00071     function isAvailable()
00072     {
00073         return $this->IsEnabled;
00074     }
00075 
00076     /*!
00077      \return the tag for the MIME type named \a $mimeName.
00078      This is a helper function for some shell based handlers, it will create a
00079      proper name from the MIME type \a $mimeData.
00080      \note The default returns the type part of the MIME type.
00081     */
00082     function tagForMIMEType( $mimeData )
00083     {
00084         $name = $mimeData['name'];
00085         if ( isset( $this->MIMETagMap[$name] ) )
00086             return $this->MIMETagMap[$name];
00087         $position = strpos( $name, '/' );
00088         if ( $position !== false )
00089             return substr( $name, $position + 1 );
00090         else
00091             return false;
00092     }
00093 
00094     /*!
00095      \return an array with the names of the filters this handler can work with.
00096     */
00097     function supportedImageFilters()
00098     {
00099         return $this->SupportImageFilters;
00100     }
00101 
00102     /*!
00103      \return The conversion rules for this handler.
00104     */
00105     function conversionRules()
00106     {
00107         return $this->ConversionRules;
00108      }
00109 
00110     /*!
00111      Parses the filter text \a $filterText which is taken from an INI file
00112      and returns a filter definition structure for it.
00113     */
00114     static function createFilterDefinitionFromINI( $filterText )
00115     {
00116         $equalPosition = strpos( $filterText, '=' );
00117         $filterData = false;
00118         if ( $equalPosition !== false )
00119         {
00120             $filterName = substr( $filterText, 0, $equalPosition );
00121             $filterData = substr( $filterText, $equalPosition + 1 );
00122         }
00123         else
00124             $filterName = $filterText;
00125         return array( 'name' => $filterName,
00126                       'text' => $filterData );
00127     }
00128 
00129     /*!
00130      Converts a filter definition and filter data into a text string.
00131      This string is usually the commandline parameter.
00132     */
00133     static function convertFilterToText( $filterDefinition, $filterData )
00134     {
00135         $replaceList = array();
00136         if ( $filterData['data'] )
00137         {
00138             $counter = 1;
00139             foreach ( $filterData['data'] as $data )
00140             {
00141                 $replaceList['%' . $counter] = $data;
00142                 ++$counter;
00143             }
00144         }
00145         $argumentText = $filterDefinition['text'];
00146         $text = eZSys::createShellArgument( $argumentText, $replaceList );
00147         return $text;
00148     }
00149 
00150     /*!
00151      Calls convertFilterToText with the correct filter definition and returns the text.
00152     */
00153     function textForFilter( $filterData )
00154     {
00155         $text = false;
00156         if ( isset( $this->FilterMap[$filterData['name']] ) )
00157         {
00158             $filterDefinition =& $this->FilterMap[$filterData['name']];
00159             $text = $this->convertFilterToText( $filterDefinition, $filterData );
00160         }
00161         return $text;
00162     }
00163 
00164     /*!
00165      Rewrites the URL in \a $originalMimeData to become a url for \a $destinationMimeData.
00166      The type of rewrite is determined by \a $rewriteType which can be one of:
00167      - self::KEEP_SUFFIX - Does nothing to the url
00168      - self::REPLACE_SUFFIX - Replaces the suffix or the url
00169      - self::PREPEND_TAG_REPLACE_SUFFIX - Prepends the tag name and replaces the suffix of the url
00170      The new url is placed in the \a $destinationMimeData.
00171     */
00172     function rewriteURL( $originalMimeData, &$destinationMimeData, $rewriteType, $aliasName = false )
00173     {
00174         $extraText = false;
00175         if ( $aliasName and
00176              $aliasName != 'original' )
00177             $extraText = '_' . $aliasName;
00178         switch ( $rewriteType )
00179         {
00180             case self::KEEP_SUFFIX:
00181             {
00182                 $destinationMimeData['basename'] = $originalMimeData['basename'];
00183                 $destinationMimeData['filename'] = $originalMimeData['basename'] . $extraText . '.' . $originalMimeData['suffix'];
00184                 $destinationMimeData['dirpath'] = $originalMimeData['dirpath'];
00185                 if ( $originalMimeData['dirpath'] )
00186                     $destinationMimeData['url'] = $originalMimeData['dirpath'] . '/' . $destinationMimeData['filename'];
00187                 else
00188                     $destinationMimeData['url'] = $destinationMimeData['filename'];
00189             } break;
00190             case self::REPLACE_SUFFIX:
00191             {
00192                 $destinationMimeData['basename'] = $originalMimeData['basename'];
00193                 $destinationMimeData['filename'] = $originalMimeData['basename'] . $extraText . '.' . $destinationMimeData['suffixes'][0];
00194                 $destinationMimeData['dirpath'] = $originalMimeData['dirpath'];
00195                 if ( $originalMimeData['dirpath'] )
00196                     $destinationMimeData['url'] = $originalMimeData['dirpath'] . '/' . $destinationMimeData['filename'];
00197                 else
00198                     $destinationMimeData['url'] = $destinationMimeData['filename'];
00199             } break;
00200             case self::PREPEND_TAG_REPLACE_SUFFIX:
00201             {
00202                 $tagName = $this->tagForMIMEType( $destinationMimeData );
00203                 $destinationMimeData['basename'] = $originalMimeData['basename'];
00204                 $destinationMimeData['filename'] = $originalMimeData['basename'] . $extraText . '.' . $destinationMimeData['suffixes'][0];
00205                 $destinationMimeData['dirpath'] = $originalMimeData['dirpath'];
00206                 if ( $originalMimeData['dirpath'] )
00207                     $destinationMimeData['url'] = $originalMimeData['dirpath'] . '/' . $destinationMimeData['filename'];
00208                 else
00209                     $destinationMimeData['url'] = $destinationMimeData['filename'];
00210                 $destinationMimeData['url'] = $tagName . ':' . $destinationMimeData['url'];
00211             } break;
00212         }
00213     }
00214 
00215     /*!
00216      \return an array with MIME type names that the handler supports as input.
00217              MIME type names can also be specified with wildcards, for instance
00218              image/* to say that all image types are supported.
00219      \note The default implementation returns the MIME types specified in the constructor
00220     */
00221     function supportedInputMIMETypes()
00222     {
00223         return $this->SupportedInputMIMETypes;
00224     }
00225 
00226     /*!
00227      \return an array with MIME type names that the handler supports as output.
00228              MIME type names can also be specified with wildcards, for instance
00229              image/* to say that all image types are supported.
00230      \note The default implementation returns the MIME types specified in the constructor
00231     */
00232     function supportedOutputMIMETypes()
00233     {
00234         return $this->SupportedOutputMIMETypes;
00235     }
00236 
00237     /*!
00238      \static
00239      Changes the file permissions for image file \a $filepath to the ones
00240      defines in image.ini. It uses the group FileSettings and variable ImagePermissions.
00241      \return \c true on success, \c false otherwise
00242     */
00243     static function changeFilePermissions( $filepath )
00244     {
00245         if ( !file_exists( $filepath ) )
00246             return false;
00247         $ini = eZINI::instance( 'image.ini' );
00248         $perm = $ini->variable( "FileSettings", "ImagePermissions" );
00249         $success = false;
00250         $oldmask = umask( 0 );
00251         if ( !chmod( $filepath, octdec( $perm ) ) )
00252             eZDebug::writeError( "Chmod $perm $filepath failed", __METHOD__ );
00253         else
00254             $success = true;
00255         umask( $oldmask );
00256         return $success;
00257     }
00258 
00259     /*!
00260      \static
00261      Creats a regexp string out of the wildcard \a $wilcard and returns it.
00262     */
00263     static function wildcardToRegexp( $wildcard, $separatorCharacter = false )
00264     {
00265         if ( !$separatorCharacter )
00266             $separatorCharacter = '#';
00267         $wildcardArray = preg_split( "#[*]#", $wildcard, -1, PREG_SPLIT_DELIM_CAPTURE );
00268         $wildcardList = array();
00269         $i = 0;
00270         foreach ( $wildcardArray as $wildcardElement )
00271         {
00272             if ( ( $i % 2 ) == 1 )
00273                 $wildcardList[] = '(.+)';
00274             else
00275                 $wildcardList[] = preg_quote( $wildcardElement, $separatorCharacter );
00276             ++$i;
00277         }
00278         $wildcardString = implode( '', $wildcardList );
00279         return $wildcardString;
00280     }
00281 
00282     /*!
00283      \return \c true if the MIME-Type defined in \a $mimeData is supported as output by this handler.
00284     */
00285     function isOutputMIMETypeSupported( $mimeData )
00286     {
00287         $mimeTypes = $this->supportedOutputMIMETypes();
00288         $mimeName = $mimeData;
00289         if ( is_array( $mimeData ) )
00290             $mimeName = $mimeData['name'];
00291         foreach ( $mimeTypes as $mimeType )
00292         {
00293             if ( strpos( $mimeType, '*' ) !== false )
00294             {
00295                 $matchString = eZImageHandler::wildcardToRegexp( $mimeType );
00296                 if ( preg_match( "#^" . $matchString . "$#", $mimeName ) )
00297                 {
00298                     return true;
00299                 }
00300             }
00301             else if ( $mimeType == $mimeName )
00302             {
00303                 return true;
00304             }
00305         }
00306         return false;
00307     }
00308 
00309     /*!
00310      \return \c true if the MIME-Type defined in \a $mimeData is supported as input by this handler.
00311     */
00312     function isInputMIMETypeSupported( $mimeData )
00313     {
00314         $mimeTypes = $this->supportedInputMIMETypes();
00315         $mimeName = $mimeData;
00316         if ( is_array( $mimeData ) )
00317             $mimeName = $mimeData['name'];
00318         foreach ( $mimeTypes as $mimeType )
00319         {
00320             if ( strpos( $mimeType, '*' ) !== false )
00321             {
00322                 $matchString = eZImageHandler::wildcardToRegexp( $mimeType );
00323                 if ( preg_match( "#^" . $matchString . "$#", $mimeName ) )
00324                 {
00325                     return true;
00326                 }
00327             }
00328             else if ( $mimeType == $mimeName )
00329             {
00330                 return true;
00331             }
00332         }
00333         return false;
00334     }
00335 
00336     /*!
00337      Figures out the output MIME type for the \a $currentMimeData. It goes trough
00338      all conversion rules for this handler and returns a MIME structure for the
00339      possible output. The returned structure also contains the correct url for the output.
00340      \param $wantedMimeData an optional MIME structure for the wanted output type,
00341                             if a direct conversion rule exists from \a $currentMimeData to \a $wantedMimeData
00342                             then this is used.
00343      \param $aliasName An optional name for the current alias being used, if supplied
00344                        the output MIME structure will have the alias name in the filename.
00345     */
00346     function outputMIMEType( &$manager, $currentMimeData, $wantedMimeData, $supportedFormatsOriginal, $aliasName = false )
00347     {
00348         if ( is_array( $this->conversionRules() ) )
00349         {
00350             $conversionRules = array_merge( $manager->conversionRules(), $this->conversionRules() );
00351         }
00352         else
00353         {
00354             $conversionRules = $manager->conversionRules();
00355         }
00356         $mimeData = false;
00357         $mimeType = false;
00358         if ( !$this->isInputMIMETypeSupported( $currentMimeData ) )
00359             return false;
00360 
00361         if ( $wantedMimeData )
00362         {
00363             $conversionRules = array_merge( array( array( 'from' => $currentMimeData['name'],
00364                                                           'to' => $wantedMimeData['name'] ) ),
00365                                             $conversionRules );
00366         }
00367 
00368         $supportedFormats = array();
00369         foreach ( $supportedFormatsOriginal as $supportedFormat )
00370         {
00371             if ( $this->isOutputMIMETypeSupported( $supportedFormat ) )
00372             {
00373                 $supportedFormats[] = $supportedFormat;
00374                 $conversionRules[] = array( 'from' => $supportedFormat,
00375                                             'to' => $supportedFormat );
00376             }
00377         }
00378 
00379         if ( $wantedMimeData and
00380              in_array( $wantedMimeData['name'], $supportedFormats ) )
00381         {
00382             $mimeType = $wantedMimeData['name'];
00383         }
00384         else if ( is_array( $conversionRules ) )
00385         {
00386             foreach ( $conversionRules as $rule )
00387             {
00388                 if ( !$this->isOutputMIMETypeSupported( $rule['to'] ) or
00389                      !in_array( $rule['to'], $supportedFormats ) )
00390                     continue;
00391 
00392                 $matchRule = false;
00393                 if ( strpos( $rule['from'], '*' ) !== false )
00394                 {
00395                     $matchString = eZImageHandler::wildcardToRegexp( $rule['from'] );
00396                     if ( preg_match( "#^" . $matchString . "$#", $currentMimeData['name'] ) )
00397                     {
00398                         $matchRule = $rule;
00399                     }
00400                 }
00401                 else if ( $rule['from'] == $currentMimeData['name'] )
00402                 {
00403                     $matchRule = $rule;
00404                 }
00405                 if ( $matchRule )
00406                 {
00407                     if ( $mimeType )
00408                     {
00409                         if ( $wantedMimeData and
00410                              $matchRule['to'] == $wantedMimeData['name'] )
00411                             $mimeType = $matchRule['to'];
00412                     }
00413                     else
00414                         $mimeType = $matchRule['to'];
00415                 }
00416             }
00417         }
00418         if ( $mimeType )
00419         {
00420             $mimeData = eZMimeType::findByName( $mimeType );
00421             $this->rewriteURL( $currentMimeData, $mimeData, $this->outputRewriteType(), $aliasName );
00422         }
00423         return $mimeData;
00424     }
00425 
00426     /*!
00427      \return the type of filename rewrite this handler uses for output.
00428     */
00429     function outputRewriteType()
00430     {
00431         return $this->OutputRewriteType;
00432     }
00433 
00434     /*!
00435      \return \c true if the filter \a $filter is supported by this handler.
00436     */
00437     function isFilterSupported( $filter )
00438     {
00439         return isset( $this->FilterMap[$filter['name']] );
00440     }
00441 
00442     /*!
00443      \pure
00444      Converts the source file \a $sourceMimeData to the destination file \a $destinationMimeData.
00445      If \a $filters is supplied then the filters will be applied to the conversion.
00446     */
00447     function convert( $manager, $sourceMimeData, &$destinationMimeData, $filters = false )
00448     {
00449     }
00450 
00451 }
00452 
00453 ?>