|
eZ Publish
[trunk]
|
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 ?>