|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZImageManager class 00004 // 00005 // Created on: <01-Mar-2002 14:23:49 amos> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! \defgroup eZImage Image conversion and scaling */ 00032 00033 /*! 00034 \class eZImageManager ezimagemanager.php 00035 \ingroup eZImage 00036 \brief Manages image operations using delegates to do the work 00037 00038 The manager allows for transparent conversion of one image format 00039 to another. The conversion may be done in one step if the required 00040 conversion type is available or it may build a tree of conversion 00041 rules which is needed to reach the desired end format. 00042 00043 It's also possible to run operations on images. It's up to each conversion 00044 rule to report whether or not the operation is supported, the manager will 00045 then distribute the operations on the available rules which can handle them. 00046 Examples of operations are scaling and grayscale. 00047 00048 The scale operation is special and is known to the manager directly while 00049 the other operations must be recognized by the converter. 00050 00051 In determing what image rules to be used the manager must first know 00052 which output types are allowed, this is set with setOutputTypes(). 00053 It takes an array of mimetypes which are allowed. 00054 00055 The manager must then be fed conversion rules, these tell which conversion 00056 type is used for converting from the source mimetype to the destination 00057 mimetype. The rules are set with setRules() which accepts an array of 00058 rules and a default rule as paremeter. The default rule is used when no 00059 other mimetype match is found. 00060 To create a rule you should use the createRule() function, it takes the source 00061 and destination mimetype as well as the conversion type name. Optionally 00062 it can specified whether the rule can scale or run operations. 00063 00064 The last thing that needs to be done is to specify the mimetypes. The manager 00065 uses mimetypes internally to know what type of image it's working on. 00066 To go from a filename to a mimetype a set of matches must be setup. The matches 00067 are created with createMIMEType() which takes the mimetype, regex filename match 00068 and suffix as parameter. The mimetypes are then registered with setMIMETypes(). 00069 00070 See <a href="http://www.iana.org/">www.iana.org</a> for information on MIME types. 00071 00072 Now the manager is ready and you can convert images with convert(). 00073 00074 Example: 00075 \code 00076 $img = eZImageManager::instance(); 00077 $img->registerType( "convert", new eZImageShell( '', "convert", array(), array(), 00078 array( eZImageShell::createRule( "-geometry %wx%h>", // Scale rule 00079 "modify/scale" ), 00080 eZImageShell::createRule( "-colorspace GRAY", // Grayscale rule 00081 "colorspace/gray" ) ) ) ); // Register shell program convert 00082 $img->registerType( "gd", new eZImageGD() ); // Register PHP converter GD 00083 00084 $img->setOutputTypes( array( "image/jpeg", 00085 "image/png" ) ); // We only want jpeg and png, gif is not recommended due to licencing issues. 00086 $rules = array( $img->createRule( "image/jpeg", "image/jpeg", "GD", true, false ), // Required for scaling jpeg images 00087 $img->createRule( "image/gif", "image/png", "convert", true, false ) ); // Convert GIF to png 00088 $img->setRules( $rules, $img->createRule( "*", "image/png", "convert", true, false ) ); // Convert all other images to PNG with convert 00089 00090 $mime_rules = array( $img->createMIMEType( "image/jpeg", "\.jpe?g$", "jpg" ), 00091 $img->createMIMEType( "image/png", "\.png$", "png" ), 00092 $img->createMIMEType( "image/gif", "\.gif$", "gif" ) ); 00093 $img->setMIMETypes( $mime_rules ); // Register mimetypes 00094 00095 $img1 = $img->convert( "image1.gif", "cache/" ); // Convert GIF and places it in cache dir 00096 $img1 = $img->convert( "image1.png", "cache/", // Scale PNG image and place in cache dir 00097 array( "width" => 200, "height" => 200 ), // Scale parameter 00098 array( array( "rule-type" => "colorspace/gray" ) ) ); // Gray scale conversion 00099 \endcode 00100 00101 00102 */ 00103 00104 //include_once( 'lib/ezutils/classes/ezini.php' ); 00105 00106 class eZImageManager 00107 { 00108 /*! 00109 Initializes the manager by registering a application/octet-stream mimetype 00110 which is applied for all unknown files. 00111 */ 00112 function eZImageManager() 00113 { 00114 $this->SupportedFormats = array(); 00115 $this->SupportedMIMEMap = array(); 00116 $this->ImageHandlers = array(); 00117 $this->AliasList = array(); 00118 $this->Factories = array(); 00119 $this->ImageFilters = array(); 00120 $this->MIMETypeSettings = array(); 00121 $this->MIMETypeSettingsMap = array(); 00122 $this->QualityValues = array(); 00123 $this->QualityValueMap = array(); 00124 00125 $ini = eZINI::instance( 'image.ini' ); 00126 $this->TemporaryImageDirPath = eZSys::cacheDirectory() . '/' . $ini->variable( 'FileSettings', 'TemporaryDir' ); 00127 $this->lockTimeout = $ini->hasVariable( 'ImageConverterSettings', 'LockTimeout' ) ? $ini->variable( 'ImageConverterSettings', 'LockTimeout' ) : 60; 00128 } 00129 00130 /*! 00131 Sets which MIME-Types are allowed to use for destination format, this is an array of MIME-Type names. 00132 e.g. 00133 \code 00134 $manager->setOutputTypes( array( 'image/jpeg', 'image/gif' ) ); 00135 \endcode 00136 */ 00137 function setSupportedFormats( $mimeList ) 00138 { 00139 $this->SupportedFormats = $mimeList; 00140 $this->SupportedMIMEMap = array(); 00141 foreach ( $mimeList as $mimeName ) 00142 { 00143 $this->SupportedMIMEMap[$mimeName] = true; 00144 } 00145 } 00146 00147 /*! 00148 Sets which MIME-Types are allowed to use for destination format, this is an array of MIME-Type names. 00149 e.g. 00150 \code 00151 $manager->setOutputTypes( array( 'image/jpeg', 'image/gif' ) ); 00152 \endcode 00153 */ 00154 function appendSupportedFormat( $mimeName ) 00155 { 00156 $this->SupportedFormats[] = $mimeName; 00157 $this->SupportedMIMEMap[$mimeName] = true; 00158 } 00159 00160 /*! 00161 Appends the image handler \a $handler to the list of known handlers in the image system. 00162 Onces it is added the supported image filters for that handler is extracted. 00163 00164 \note If the handler is not available (isAvailable()) it will not be added. 00165 */ 00166 function appendImageHandler( $handler ) 00167 { 00168 if ( !$handler ) 00169 return false; 00170 if ( !$handler->isAvailable() ) 00171 return false; 00172 $this->ImageHandlers[] = $handler; 00173 $this->ImageFilters = array_merge( $this->ImageFilters, $handler->supportedImageFilters() ); 00174 $this->ImageFilters = array_unique( $this->ImageFilters ); 00175 return true; 00176 } 00177 00178 /*! 00179 \return \c true if the filtername \a $filtername is supported by any of the image handlers. 00180 */ 00181 function isFilterSupported( $filterName ) 00182 { 00183 return in_array( $filterName, $this->ImageFilters ); 00184 } 00185 00186 /*! 00187 Returns a list of defined image aliases in the image system. 00188 Each entry in the list is an associative array with the following keys: 00189 - name - The name of the alias 00190 - reference - The name of the alias it refers to or \c false if no reference 00191 - mime_type - Controls which MIME-Type the alias will be in, or \c false if not defined. 00192 - filters - An array with filters which applies to this alias 00193 - alias_key - The CRC key for this alias, it is created from the current values of the alias 00194 and will change each time the alias values changes 00195 */ 00196 function aliasList() 00197 { 00198 $aliasList = $this->AliasList; 00199 if ( !isset( $aliasList['original'] ) ) 00200 { 00201 $alias = array( 'name' => 'original', 00202 'reference' => false, 00203 'mime_type' => false, 00204 'filters' => array() ); 00205 $alias['alias_key'] = $this->createImageAliasKey( $alias ); 00206 $aliasList['original'] = $alias; 00207 } 00208 return $aliasList; 00209 } 00210 00211 /*! 00212 \return \c true if the image alias \a $aliasName exists. 00213 */ 00214 function hasAlias( $aliasName ) 00215 { 00216 $aliasList = $this->aliasList(); 00217 return array_key_exists( $aliasName, $aliasList ); 00218 } 00219 00220 /*! 00221 \return the definition for the Image Alias named \a $aliasName. 00222 */ 00223 function alias( $aliasName ) 00224 { 00225 $aliasList = $this->aliasList(); 00226 if ( !array_key_exists( $aliasName, $aliasList ) ) 00227 return false; 00228 return $aliasList[$aliasName]; 00229 } 00230 00231 /*! 00232 Appends the image alias \a $alias to the list of defined aliases. 00233 */ 00234 function appendImageAlias( $alias ) 00235 { 00236 $key = $this->createImageAliasKey( $alias ); 00237 $alias['alias_key'] = $key; 00238 $this->AliasList[$alias['name']] = $alias; 00239 return $key; 00240 } 00241 00242 /*! 00243 Creates a unique key for the image alias and returns it. 00244 \note The key is an MD5 of the alias settings and is used to determine if alias settings has changed. 00245 */ 00246 function createImageAliasKey( $alias ) 00247 { 00248 $keyData = array( $alias['name'], 00249 $alias['reference'], 00250 $alias['mime_type'] ); 00251 if ( $alias['reference'] ) 00252 { 00253 $referenceAlias = $this->alias( $alias['reference'] ); 00254 if ( $referenceAlias ) 00255 $keyData[] = $referenceAlias['alias_key']; 00256 } 00257 foreach ( $alias['filters'] as $filter ) 00258 { 00259 $filterData = $filter['name']; 00260 if ( is_array( $filter['data'] ) ) 00261 $filterData .= '=' . implode( ',', $filter['data'] ); 00262 $keyData[] = $filterData; 00263 } 00264 00265 //include_once( 'lib/ezutils/classes/ezsys.php' ); 00266 $key = eZSys::ezcrc32( implode( "\n", $keyData ) ); 00267 00268 return $key; 00269 } 00270 00271 /*! 00272 \return \c true if the Image Alias \a $alias is valid for use. 00273 This is tested by checking the key against the key for current Image Alias settings. 00274 */ 00275 function isImageAliasValid( $alias ) 00276 { 00277 $aliasName = $alias['name']; 00278 if ( isset( $this->AliasList[$aliasName] ) ) 00279 { 00280 $aliasKey = $alias['alias_key']; 00281 $aliasInfo = $this->AliasList[$aliasName]; 00282 $checkKey = $aliasInfo['alias_key']; 00283 $isValid = ( $aliasKey == $checkKey ); 00284 if ( $isValid ) 00285 { 00286 $aliasTimestamp = $alias['timestamp']; 00287 $isValid = $this->isImageTimestampValid( $aliasTimestamp ); 00288 } 00289 return $isValid; 00290 } 00291 return false; 00292 } 00293 00294 /*! 00295 \return \c true if the timestamp \a $timestamp is newer than the image alias expiry timestamp. 00296 The image alias expiry timestamp will be set whenever the image aliases must be recreated. 00297 00298 \note Normally the expiry timestamp is not set. 00299 */ 00300 function isImageTimestampValid( $timestamp ) 00301 { 00302 eZExpiryHandler::registerShutdownFunction(); 00303 $expiryHandler = eZExpiryHandler::instance(); 00304 if ( $expiryHandler->hasTimestamp( 'image-manager-alias' ) ) 00305 { 00306 $aliasTimestamp = $expiryHandler->timestamp( 'image-manager-alias' ); 00307 return ( $timestamp > $aliasTimestamp ); 00308 } 00309 return true; 00310 } 00311 00312 /*! 00313 Reads all image aliases from the INI file 'image.ini' 00314 and appends them to the image system. 00315 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00316 */ 00317 function readImageAliasesFromINI( $iniFile = false ) 00318 { 00319 if ( !$iniFile ) 00320 $iniFile = 'image.ini'; 00321 $ini = eZINI::instance( $iniFile ); 00322 if ( !$ini ) 00323 return false; 00324 $aliasNames = $ini->variable( 'AliasSettings', 'AliasList' ); 00325 foreach ( $aliasNames as $aliasName ) 00326 { 00327 $alias = $this->createAliasFromINI( $aliasName ); 00328 if ( $alias ) 00329 { 00330 $this->appendImageAlias( $alias ); 00331 } 00332 else 00333 eZDebug::writeWarning( "Failed reading Image Alias $aliasName from $iniFile", 00334 'eZImageManager::readImageAliasFromINI' ); 00335 } 00336 $aliasName = 'original'; 00337 if ( !in_array( $aliasName, $aliasNames ) ) 00338 { 00339 //include_once( 'lib/ezutils/classes/ezini.php' ); 00340 $ini = eZINI::instance( 'image.ini' ); 00341 if ( $ini->hasGroup( $aliasName ) ) 00342 { 00343 $alias = $this->createAliasFromINI( $aliasName ); 00344 if ( $alias ) 00345 { 00346 $alias['reference'] = false; 00347 $this->appendImageAlias( $alias ); 00348 } 00349 else 00350 { 00351 eZDebug::writeWarning( "Failed reading Image Alias $aliasName from $iniFile", 00352 'eZImageManager::readImageAliasFromINI' ); 00353 } 00354 } 00355 } 00356 } 00357 00358 /*! 00359 Reads all supported image formats from the INI file 'image.ini' 00360 and appends them to the image system. 00361 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00362 */ 00363 function readSupportedFormatsFromINI( $iniFile = false ) 00364 { 00365 if ( !$iniFile ) 00366 $iniFile = 'image.ini'; 00367 $ini = eZINI::instance( $iniFile ); 00368 if ( !$ini ) 00369 return false; 00370 $allowedOutputFormats = $ini->variable( 'OutputSettings', 'AllowedOutputFormat' ); 00371 foreach ( $allowedOutputFormats as $allowedOutputFormat ) 00372 { 00373 $this->appendSupportedFormat( $allowedOutputFormat ); 00374 } 00375 } 00376 00377 /*! 00378 \return \c true if the MIME-Type defined in \a $mimeData exists in the image system. 00379 */ 00380 function hasMIMETypeSetting( $mimeData ) 00381 { 00382 return isset( $this->MIMETypeSettingsMap[$mimeData['name']] ); 00383 } 00384 00385 /*! 00386 \return The setting for the MIME-Type defined in \a $mimeData. 00387 */ 00388 function mimeTypeSetting( $mimeData ) 00389 { 00390 if ( !isset( $this->MIMETypeSettingsMap[$mimeData['name']] ) ) 00391 return false; 00392 $list = $this->MIMETypeSettingsMap[$mimeData['name']]; 00393 foreach ( $list as $item ) 00394 { 00395 if ( is_array( $item['match'] ) ) 00396 { 00397 if ( array_key_exists( 'info', $mimeData ) && is_array( $mimeData['info'] ) ) 00398 { 00399 $isMatch = true; 00400 $info = $mimeData['info']; 00401 foreach ( $item['match'] as $matchKey => $matchValue ) 00402 { 00403 if ( !isset( $info[$matchKey] ) or 00404 $info[$matchKey] != $matchValue ) 00405 { 00406 $isMatch = false; 00407 break; 00408 } 00409 } 00410 if ( $isMatch ) 00411 return $item; 00412 } 00413 } 00414 else 00415 return $item; 00416 } 00417 return false; 00418 } 00419 00420 /*! 00421 Calls eZImageHandler::wildcardToRegexp() to generate 00422 a regular expression out of the wilcard and return it. 00423 */ 00424 static function wildcardToRegexp( $wildcard, $separatorCharacter = false ) 00425 { 00426 return eZImageHandler::wildcardToRegexp( $wildcard, $separatorCharacter ); 00427 } 00428 00429 /*! 00430 \return The override MIME-Type for the MIME structure \a $mimeData or \c false if no override. 00431 */ 00432 function mimeTypeOverride( $mimeData ) 00433 { 00434 if ( $this->hasMIMETypeSetting( $mimeData ) ) 00435 { 00436 $settings = $this->mimeTypeSetting( $mimeData ); 00437 if ( $settings ) 00438 { 00439 return $settings['override_mime_type']; 00440 } 00441 } 00442 return false; 00443 } 00444 00445 /*! 00446 \return An array with extra filters for the MIME-Type defined in \a $mimeData 00447 or \c false if no filters. 00448 */ 00449 function mimeTypeFilters( $mimeData ) 00450 { 00451 if ( $this->hasMIMETypeSetting( $mimeData ) ) 00452 { 00453 $settings = $this->mimeTypeSetting( $mimeData ); 00454 if ( $settings ) 00455 { 00456 return $settings['extra_filters']; 00457 } 00458 } 00459 return false; 00460 } 00461 00462 /*! 00463 \return \c true if the filtername \a $filtername is allowed to be used on the type defined in \a $mimeData. 00464 */ 00465 function isFilterAllowed( $filterName, $mimeData ) 00466 { 00467 if ( $this->hasMIMETypeSetting( $mimeData ) ) 00468 { 00469 $settings = $this->mimeTypeSetting( $mimeData ); 00470 if ( $settings ) 00471 { 00472 if ( is_array( $settings['disallowed_filters'] ) ) 00473 { 00474 foreach ( $settings['disallowed_filters'] as $filter ) 00475 { 00476 $regexp = eZImageManager::wildcardToRegexp( $filter ); 00477 if ( preg_match( '#' . $regexp . '#', $filterName ) ) 00478 { 00479 return false; 00480 } 00481 } 00482 } 00483 if ( is_array( $settings['allowed_filters'] ) ) 00484 { 00485 foreach ( $settings['allowed_filters'] as $filter ) 00486 { 00487 $regexp = eZImageManager::wildcardToRegexp( $filter ); 00488 if ( preg_match( '#' . $regexp . '#', $filterName ) ) 00489 { 00490 return true; 00491 } 00492 } 00493 return false; 00494 } 00495 return true; 00496 } 00497 } 00498 return true; 00499 } 00500 00501 /*! 00502 Binds the quality value \a $qualityValue to the MIME-Type \a $mimeType. 00503 */ 00504 function appendQualityValue( $mimeType, $qualityValue ) 00505 { 00506 $element = array( 'name' => $mimeType, 00507 'value' => $qualityValue ); 00508 $this->QualityValues[] = $element; 00509 $this->QualityValueMap[$mimeType] = $element; 00510 } 00511 00512 /*! 00513 \return the quality value for MIME-Type \a $mimeType or \c false if none exists. 00514 */ 00515 function qualityValue( $mimeType ) 00516 { 00517 if ( isset( $this->QualityValueMap[$mimeType] ) ) 00518 return $this->QualityValueMap[$mimeType]['value']; 00519 return false; 00520 } 00521 00522 /*! 00523 Appends the MIME-Type setting \a $settings to the image system. 00524 */ 00525 function appendMIMETypeSetting( $settings ) 00526 { 00527 $this->MIMETypeSettings[] = $settings; 00528 if ( !isset( $this->MIMETypeSettingsMap[$settings['mime_type']] ) ) 00529 $this->MIMETypeSettingsMap[$settings['mime_type']] = array(); 00530 $this->MIMETypeSettingsMap[$settings['mime_type']][] = $settings; 00531 } 00532 00533 /*! 00534 Reads all MIME-Type settings from the INI file 'image.ini' 00535 and appends them to the image system. 00536 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00537 */ 00538 function readMIMETypeSettingsFromINI( $iniFile = false ) 00539 { 00540 if ( !$iniFile ) 00541 $iniFile = 'image.ini'; 00542 $ini = eZINI::instance( $iniFile ); 00543 if ( !$ini ) 00544 return false; 00545 $overrideList = $ini->variable( 'MIMETypeSettings', 'OverrideList' ); 00546 foreach ( $overrideList as $mimeType ) 00547 { 00548 $settings = eZImageManager::readMIMETypeSettingFromINI( $mimeType ); 00549 if ( $settings ) 00550 $this->appendMIMETypeSetting( $settings ); 00551 } 00552 } 00553 00554 /*! 00555 Reads MIME-Type quality settings and appends them. 00556 */ 00557 function readMIMETypeQualitySettingFromINI( $iniFile = false ) 00558 { 00559 if ( !$iniFile ) 00560 $iniFile = 'image.ini'; 00561 $ini = eZINI::instance( $iniFile ); 00562 if ( !$ini ) 00563 return false; 00564 if ( !$ini->hasVariable( 'MIMETypeSettings', 'Quality' ) ) 00565 return false; 00566 $values = $ini->variable( 'MIMETypeSettings', 'Quality' ); 00567 foreach ( $values as $value ) 00568 { 00569 $elements = explode( ';', $value ); 00570 $mimeType = $elements[0]; 00571 $qualityValue = $elements[1]; 00572 $this->appendQualityValue( $mimeType, $qualityValue ); 00573 } 00574 } 00575 00576 /*! 00577 Reads in global conversion rules from INI file. 00578 */ 00579 function readConversionRuleSettingsFromINI( $iniFile = false ) 00580 { 00581 if ( !$iniFile ) 00582 $iniFile = 'image.ini'; 00583 $ini = eZINI::instance( $iniFile ); 00584 if ( !$ini ) 00585 return false; 00586 if ( $ini->hasVariable( 'MIMETypeSettings', 'ConversionRules' ) ) 00587 { 00588 $conversionRules = array(); 00589 $rules = $ini->variable( 'MIMETypeSettings', 'ConversionRules' ); 00590 foreach ( $rules as $ruleString ) 00591 { 00592 $ruleItems = explode( ';', $ruleString ); 00593 if ( count( $ruleItems ) >= 2 ) 00594 { 00595 $conversionRule = array( 'from' => $ruleItems[0], 00596 'to' => $ruleItems[1] ); 00597 $this->appendConversionRule( $conversionRule ); 00598 } 00599 } 00600 } 00601 } 00602 00603 /*! 00604 Will read in all required INI settings. 00605 */ 00606 function readINISettings() 00607 { 00608 $this->readImageHandlersFromINI(); 00609 $this->readSupportedFormatsFromINI(); 00610 $this->readImageAliasesFromINI(); 00611 $this->readMIMETypeSettingsFromINI(); 00612 $this->readMIMETypeQualitySettingFromINI(); 00613 $this->readConversionRuleSettingsFromINI(); 00614 } 00615 00616 /*! 00617 Appends a new global conversion rule. 00618 */ 00619 function appendConversionRule( $conversionRule ) 00620 { 00621 $this->ConversionRules[] = $conversionRule; 00622 } 00623 00624 /*! 00625 \return The global conversion rules. 00626 */ 00627 function conversionRules() 00628 { 00629 return $this->ConversionRules; 00630 } 00631 00632 /*! 00633 Reads a single MIME-Type setting from the INI file 'image.ini' 00634 and appends them to the image system. 00635 \param $mimeGroup Which INI group to read settings from. 00636 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00637 \return The settings that were read. 00638 */ 00639 function readMIMETypeSettingFromINI( $mimeGroup, $iniFile = false ) 00640 { 00641 if ( !$iniFile ) 00642 $iniFile = 'image.ini'; 00643 $ini = eZINI::instance( $iniFile ); 00644 if ( !$ini ) 00645 return false; 00646 if ( !$ini->hasGroup( $mimeGroup ) ) 00647 return false; 00648 if ( !$ini->hasVariable( $mimeGroup, 'MIMEType' ) ) 00649 return false; 00650 $settings = array( 'name' => $mimeGroup, 00651 'match' => false, 00652 'mime_type' => false, 00653 'override_mime_type' => false, 00654 'allowed_filters' => false, 00655 'disallowed_filters' => false, 00656 'extra_filters' => false ); 00657 $settings['mime_type'] = $ini->variable( $mimeGroup, 'MIMEType' ); 00658 $ini->assign( $mimeGroup, 'Match', $settings['match'] ); 00659 $ini->assign( $mimeGroup, 'OverrideMIMEType', $settings['override_mime_type'] ); 00660 $ini->assign( $mimeGroup, 'AllowedFilters', $settings['allowed_filters'] ); 00661 $ini->assign( $mimeGroup, 'DisallowedFilters', $settings['disallowed_filters'] ); 00662 if ( $ini->hasVariable( $mimeGroup, 'ExtraFilters' ) ) 00663 { 00664 $filters = array(); 00665 $filterRawList = $ini->variable( $mimeGroup, 'ExtraFilters' ); 00666 foreach ( $filterRawList as $filterRawItem ) 00667 { 00668 $filters[] = $this->createFilterDataFromINI( $filterRawItem ); 00669 } 00670 if ( count( $filters ) > 0 ) 00671 $settings['extra_filters'] = $filters; 00672 } 00673 return $settings; 00674 } 00675 00676 /*! 00677 Reads all settings for image handlers from the INI file 'image.ini' 00678 and appends them to the image system. 00679 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00680 */ 00681 function readImageHandlersFromINI( $iniFile = false ) 00682 { 00683 if ( !$iniFile ) 00684 $iniFile = 'image.ini'; 00685 $ini = eZINI::instance( $iniFile ); 00686 if ( !$ini ) 00687 return false; 00688 $handlerList = $ini->variable( 'ImageConverterSettings', 'ImageConverters' ); 00689 foreach ( $handlerList as $handlerName ) 00690 { 00691 if ( $ini->hasGroup( $handlerName ) ) 00692 { 00693 if ( $ini->hasVariable( $handlerName, 'Handler' ) ) 00694 { 00695 $factoryName = $ini->variable( $handlerName, 'Handler' ); 00696 $factory = $this->factoryFor( $factoryName, $iniFile ); 00697 if ( $factory ) 00698 { 00699 $convertHandler = $factory->produceFromINI( $handlerName, $iniFile ); 00700 $this->appendImageHandler( $convertHandler ); 00701 } 00702 } 00703 else 00704 { 00705 eZDebug::writeWarning( "INI group $handlerName does not have a Handler setting, cannot instantiate handler without it", 00706 'eZImageManager::readImageHandlersFromINI' ); 00707 } 00708 } 00709 else 00710 { 00711 eZDebug::writeWarning( "No INI group $handlerName for Image Handler $handlerName, cannot instantiate", 00712 'eZImageManager::readImageHandlersFromINI' ); 00713 } 00714 } 00715 } 00716 00717 /*! 00718 Finds the image handler factory with the name \a $factoryName and returns it. 00719 \param $iniFile The INI file to read from or if \c false use 'image.ini' 00720 */ 00721 function factoryFor( $factoryName, $iniFile = false ) 00722 { 00723 if ( !$iniFile ) 00724 $iniFile = 'image.ini'; 00725 if ( isset( $this->Factories[$factoryName] ) ) 00726 { 00727 return $this->Factories[$factoryName]; 00728 } 00729 else 00730 { 00731 //include_once( 'lib/ezutils/classes/ezextension.php' ); 00732 if ( eZExtension::findExtensionType( array( 'ini-name' => $iniFile, 00733 'repository-group' => 'ImageConverterSettings', 00734 'repository-variable' => 'RepositoryList', 00735 'extension-group' => 'ImageConverterSettings', 00736 'extension-variable' => 'ExtensionList', 00737 'extension-subdir' => 'imagehandler', 00738 'alias-group' => 'ImageConverterSettings', 00739 'alias-variable' => 'ImageHandlerAlias', 00740 'suffix-name' => 'handler.php', 00741 'type-directory' => false, 00742 'type' => $factoryName ), 00743 $result ) ) 00744 { 00745 $filepath = $result['found-file-path']; 00746 include_once( $filepath ); 00747 $className = $result['type'] . 'factory'; 00748 include_once( $result['found-file-dir'] . '/' . $className . '.php' ); 00749 if ( class_exists( $className ) ) 00750 { 00751 return $this->Factories[$factoryName] = new $className(); 00752 } 00753 else 00754 { 00755 eZDebug::writeWarning( "The Image Factory class $className was not found, cannot create factory", 00756 'eZImageManager::factoryFor' ); 00757 } 00758 } 00759 else 00760 { 00761 eZDebug::writeWarning( "Could not locate Image Factory for $factoryName", 00762 'eZImageManager::factoryFor' ); 00763 } 00764 } 00765 return false; 00766 } 00767 00768 /*! 00769 Parses the filter text \a $filterText which is taken from an INI file 00770 and returns a filter data structure for it. 00771 */ 00772 function createFilterDataFromINI( $filterText ) 00773 { 00774 $equalPosition = strpos( $filterText, '=' ); 00775 $filterData = false; 00776 if ( $equalPosition !== false ) 00777 { 00778 $filterName = substr( $filterText, 0, $equalPosition ); 00779 $filterDataText = substr( $filterText, $equalPosition + 1 ); 00780 $filterData = explode( ';', $filterDataText ); 00781 } 00782 else 00783 $filterName = $filterText; 00784 return array( 'name' => $filterName, 00785 'data' => $filterData ); 00786 } 00787 00788 /*! 00789 Parses the INI group \a $iniGroup and creates an Image Alias from it. 00790 \return the Image Alias structure. 00791 */ 00792 function createAliasFromINI( $iniGroup ) 00793 { 00794 //include_once( 'lib/ezutils/classes/ezini.php' ); 00795 $ini = eZINI::instance( 'image.ini' ); 00796 if ( !$ini->hasGroup( $iniGroup ) ) 00797 { 00798 eZDebug::writeError( "No such group $iniGroup in ini file image.ini", 00799 'eZImageManager::createAliasFromINI' ); 00800 return false; 00801 } 00802 $alias = array( 'name' => $iniGroup, 00803 'reference' => false, 00804 'mime_type' => false, 00805 'filters' => array() ); 00806 if ( $ini->hasVariable( $iniGroup, 'Name' ) ) 00807 $alias['name'] = $ini->variable( $iniGroup, 'Name' ); 00808 if ( $ini->hasVariable( $iniGroup, 'MIMEType' ) ) 00809 $alias['mime_type'] = $ini->variable( $iniGroup, 'MIMEType' ); 00810 if ( $ini->hasVariable( $iniGroup, 'Filters' ) ) 00811 { 00812 $filters = array(); 00813 $filterRawList = $ini->variable( $iniGroup, 'Filters' ); 00814 foreach ( $filterRawList as $filterRawItem ) 00815 { 00816 $filters[] = $this->createFilterDataFromINI( $filterRawItem ); 00817 } 00818 $alias['filters'] = $filters; 00819 } 00820 if ( $ini->hasVariable( $iniGroup, 'Reference' ) ) 00821 $alias['reference'] = $ini->variable( $iniGroup, 'Reference' ); 00822 return $alias; 00823 } 00824 00825 /*! 00826 Makes sure the Image Alias \a $aliasName is created. It will check if referenced 00827 image aliases exists and if not create those also. 00828 \return \c true if successful 00829 */ 00830 function createImageAlias( $aliasName, &$existingAliasList, $parameters = array() ) 00831 { 00832 //eZDebug::writeDebug( $existingAliasList, 'eZImageManager::createImageAlias existing alias list' ); 00833 $aliasList = $this->aliasList(); 00834 if ( !isset( $aliasList[$aliasName] ) ) 00835 { 00836 eZDebug::writeWarning( "Alias name $aliasName does not exist, cannot create it" ); 00837 return false; 00838 } 00839 $currentAliasInfo = $aliasList[$aliasName]; 00840 $referenceAlias = $currentAliasInfo['reference']; 00841 if ( $referenceAlias and !$this->hasAlias( $referenceAlias ) ) 00842 { 00843 eZDebug::writeError( "The referenced alias '$referenceAlias' for image alias '$aliasName' does not exist, cannot use it for reference.\n" . 00844 "Will use 'original' alias instead.", 00845 'eZImageManager::createImageAlias' ); 00846 $referenceAlias = false; 00847 } 00848 if ( !$referenceAlias ) 00849 $referenceAlias = 'original'; 00850 $hasReference = false; 00851 if ( array_key_exists( $referenceAlias, $existingAliasList ) ) 00852 { 00853 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00854 $fileHandler = eZClusterFileHandler::instance(); 00855 if ( $fileHandler->fileExists( $existingAliasList[$referenceAlias]['url'] ) ) 00856 { 00857 $hasReference = true; 00858 } 00859 else 00860 { 00861 eZDebug::writeDebug( 'cluster file handler could not find ' . $existingAliasList[$referenceAlias]['url'], 'eZImageManager::createImageAlias' ); 00862 eZDebug::writeError( "The reference alias $referenceAlias file " . $existingAliasList[$referenceAlias]['url'] . " does not exist", 00863 'eZImageManager::createImageAlias' ); 00864 } 00865 } 00866 if ( !$hasReference ) 00867 { 00868 if ( $referenceAlias == 'original' ) 00869 { 00870 eZDebug::writeError( "Original alias does not exists, cannot create other aliases without it" ); 00871 return false; 00872 } 00873 if ( !$this->createImageAlias( $referenceAlias, $existingAliasList, $parameters ) ) 00874 { 00875 eZDebug::writeError( "Failed creating the referenced alias $referenceAlias, cannot create alias $aliasName", 00876 'eZImageManager::createImageAlias' ); 00877 return false; 00878 } 00879 } 00880 if ( array_key_exists( $referenceAlias, $existingAliasList ) ) 00881 { 00882 $aliasInfo = $existingAliasList[$referenceAlias]; 00883 $aliasFilePath = $aliasInfo['url']; 00884 $aliasKey = $currentAliasInfo['alias_key']; 00885 00886 $aliasFile = eZClusterFileHandler::instance( $aliasFilePath ); 00887 00888 if ( $aliasFile->exists() ) 00889 { 00890 $aliasFile->fetch(); 00891 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 00892 $sourceMimeData = eZMimeType::findByFileContents( $aliasFilePath ); 00893 $destinationMimeData = $sourceMimeData; 00894 if ( isset( $parameters['basename'] ) ) 00895 { 00896 $sourceMimeData['basename'] = $parameters['basename']; 00897 eZMimeType::changeBasename( $destinationMimeData, $parameters['basename'] ); 00898 } 00899 00900 if ( !$this->_exclusiveLock( $aliasFilePath, $aliasName ) ) 00901 { 00902 return false; 00903 } 00904 00905 $wantImage = $this->imageAliasInfo( $sourceMimeData, $aliasName ); 00906 $wantImagePath = $wantImage['url']; 00907 00908 $fileHandler = eZClusterFileHandler::instance( $wantImagePath ); 00909 $fileHandler->loadMetaData( true ); 00910 00911 if ( $fileHandler->exists() and $this->isImageTimestampValid( $fileHandler->mtime() ) ) 00912 { 00913 $destinationMimeData = $wantImage; 00914 $wasLocked = true; 00915 } 00916 else 00917 { 00918 $destinationMimeData['is_valid'] = false; 00919 if ( !$this->convert( $sourceMimeData, $destinationMimeData, $aliasName, $parameters ) ) 00920 { 00921 $sourceFile = $sourceMimeData['url']; 00922 $destinationDir = $destinationMimeData['dirpath']; 00923 eZDebug::writeError( "Failed converting $sourceFile to alias '$aliasName' in directory '$destinationDir'", 00924 'eZImageManager::createImageAlias' ); 00925 $aliasFile->deleteLocal(); 00926 return false; 00927 } 00928 } 00929 00930 $currentAliasData = array( 'url' => $destinationMimeData['url'], 00931 'dirpath' => $destinationMimeData['dirpath'], 00932 'filename' => $destinationMimeData['filename'], 00933 'suffix' => $destinationMimeData['suffix'], 00934 'basename' => $destinationMimeData['basename'], 00935 'alternative_text' => $aliasInfo['alternative_text'], 00936 'name' => $aliasName, 00937 'sub_type' => false, 00938 'timestamp' => time(), 00939 'alias_key' => $aliasKey, 00940 'mime_type' => $destinationMimeData['name'], 00941 'override_mime_type' => false, 00942 'info' => false, 00943 'width' => false, 00944 'height' => false, 00945 'is_valid' => true, 00946 'is_new' => true ); 00947 if ( isset( $destinationMimeData['override_mime_type'] ) ) 00948 $currentAliasData['override_mime_type'] = $destinationMimeData['override_mime_type']; 00949 if ( isset( $destinationMimeData['info'] ) ) 00950 $currentAliasData['info'] = $destinationMimeData['info']; 00951 $currentAliasData['full_path'] =& $currentAliasData['url']; 00952 if ( function_exists( 'getimagesize' ) ) 00953 { 00954 $fileHandler = eZClusterFileHandler::instance(); 00955 $fileHandler->fileFetch( $destinationMimeData['url'] ); 00956 00957 if ( file_exists( $destinationMimeData['url'] ) ) 00958 { 00959 $info = getimagesize( $destinationMimeData['url'] ); 00960 if ( $info ) 00961 { 00962 $width = $info[0]; 00963 $height = $info[1]; 00964 $currentAliasData['width'] = $width; 00965 $currentAliasData['height'] = $height; 00966 } 00967 else 00968 { 00969 eZDebug::writeError("The size of the generated image " . $destinationMimeData['url'] . " could not be read by getimagesize()", 'eZImageManager::createImageAlias' ); 00970 } 00971 00972 // The file is not written to the database if it was already written due to a lock situation 00973 if ( !isset( $wasLocked ) ) 00974 { 00975 $fileHandler = eZClusterFileHandler::instance( $aliasFilePath ); 00976 $fileHandler->fileStore( $destinationMimeData['url'], 'image', true, $destinationMimeData['name'] ); 00977 } 00978 } 00979 else 00980 { 00981 eZDebug::writeError( "The destination image " . $destinationMimeData['url'] . " does not exist, cannot figure out image size", 'eZImageManager::createImageAlias' ); 00982 } 00983 } 00984 else 00985 eZDebug::writeError( "Unknown function 'getimagesize' cannot get image size", 'eZImageManager::createImageAlias' ); 00986 $existingAliasList[$aliasName] = $currentAliasData; 00987 $aliasFile->deleteLocal(); 00988 00989 $this->_freeExclusiveLock( $aliasFilePath, $aliasName ); 00990 00991 return true; 00992 } 00993 } 00994 return false; 00995 } 00996 00997 /*! 00998 \static 00999 Analyzes the image in the MIME structure \a $mimeData and fills in extra information if found. 01000 \return \c true if the image was succesfully analyzed, \c false otherwise. 01001 \note It will return \c true if there is no analyzer for the image type. 01002 */ 01003 static function analyzeImage( &$mimeData, $parameters = array() ) 01004 { 01005 $file = $mimeData['url']; 01006 01007 if ( !file_exists( $file ) ) 01008 return false; 01009 $analyzer = eZImageAnalyzer::createForMIME( $mimeData ); 01010 $status = true; 01011 if ( is_object( $analyzer ) ) 01012 { 01013 $imageInformation = $analyzer->process( $mimeData, $parameters ); 01014 if ( $imageInformation ) 01015 { 01016 $mimeData['info'] = $imageInformation; 01017 } 01018 else 01019 $status = false; 01020 } 01021 return $status; 01022 } 01023 01024 /*! 01025 Converts the source image \a $sourceMimeData into the destination image \a $destinationMimeData. 01026 The source image can be supplied with the full path to the image instead of the MIME structure. 01027 The destination image can be supplied with full path or dirpath to the destination image instead of the MIME structure. 01028 \param $aliasName determines the Image Alias to use for conversion, this usually adds some filters to the conversion. 01029 */ 01030 function convert( $sourceMimeData, &$destinationMimeData, $aliasName = false, $parameters = array() ) 01031 { 01032 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01033 $sourceFile = eZClusterFileHandler::instance( $sourceMimeData['url'] ); 01034 $sourceFile->fetch(); 01035 01036 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 01037 if ( is_string( $sourceMimeData ) ) 01038 $sourceMimeData = eZMimeType::findByFileContents( $sourceMimeData ); 01039 01040 $this->analyzeImage( $sourceMimeData ); 01041 $currentMimeData = $sourceMimeData; 01042 $handlers = $this->ImageHandlers; 01043 $supportedMIMEMap = $this->SupportedMIMEMap; 01044 if ( is_string( $destinationMimeData ) ) 01045 { 01046 $destinationPath = $destinationMimeData; 01047 $destinationMimeData = eZMimeType::findByFileContents( $destinationPath ); 01048 } 01049 01050 $filters = array(); 01051 $alias = false; 01052 if ( $aliasName ) 01053 { 01054 $aliasList = $this->aliasList(); 01055 if ( isset( $aliasList[$aliasName] ) ) 01056 { 01057 $alias = $aliasList[$aliasName]; 01058 $filters = $alias['filters']; 01059 if ( $alias['mime_type'] ) 01060 { 01061 eZMimeType::changeMIMEType( $destinationMimeData, $alias['mime_type'] ); 01062 } 01063 } 01064 } 01065 $mimeTypeOverride = $this->mimeTypeOverride( $sourceMimeData ); 01066 if ( $mimeTypeOverride ) 01067 $alias['override_mime_type'] = $mimeTypeOverride; 01068 01069 if ( isset( $parameters['filters'] ) ) 01070 { 01071 $filters = array_merge( $filters, $parameters['filters'] ); 01072 } 01073 01074 $wantedFilters = $filters; 01075 $mimeTypeFilters = $this->mimeTypeFilters( $sourceMimeData ); 01076 if ( is_array( $mimeTypeFilters ) ) 01077 $wantedFilters = array_merge( $wantedFilters, $mimeTypeFilters ); 01078 $filters = array(); 01079 foreach ( array_keys( $wantedFilters ) as $wantedFilterKey ) 01080 { 01081 $wantedFilter = $wantedFilters[$wantedFilterKey]; 01082 if ( !$this->isFilterSupported( $wantedFilter['name'] ) ) 01083 { 01084 eZDebug::writeWarning( "The filter '" . $wantedFilter['name'] . "' is not supported by any of the image handlers, will ignore this filter", 01085 'eZImageManager::convert' ); 01086 continue; 01087 } 01088 $filters[] = $wantedFilter; 01089 } 01090 if ( !$destinationMimeData['is_valid'] ) 01091 { 01092 $destinationDirPath = $destinationMimeData['dirpath']; 01093 $destinationBasename = $destinationMimeData['basename']; 01094 if ( isset( $supportedMIMEMap[$sourceMimeData['name']] ) ) 01095 { 01096 $destinationMimeData = $sourceMimeData; 01097 if ( $alias['mime_type'] ) 01098 { 01099 eZMimeType::changeMIMEType( $destinationMimeData, $alias['mime_type'] ); 01100 } 01101 eZMimeType::changeFileData( $destinationMimeData, $destinationDirPath, $destinationBasename ); 01102 } 01103 else 01104 { 01105 $hasDestination = false; 01106 foreach ( $handlers as $handler ) 01107 { 01108 $gotMimeData = true; 01109 while( $gotMimeData ) 01110 { 01111 $gotMimeData = false; 01112 $outputMimeData = $handler->outputMIMEType( $this, $sourceMimeData, false, $this->SupportedFormats, $aliasName ); 01113 if ( $outputMimeData and 01114 isset( $supportedMIMEMap[$outputMimeData['name']] ) ) 01115 { 01116 $destinationMimeData = $outputMimeData; 01117 eZMimeType::changeFileData( $destinationMimeData, $destinationDirPath, $destinationBasename ); 01118 $hasDestination = true; 01119 $gotMimeData = true; 01120 break; 01121 } 01122 } 01123 } 01124 if ( !$hasDestination ) 01125 { 01126 $sourceFile->deleteLocal(); 01127 return false; 01128 } 01129 } 01130 } 01131 01132 $wantedFilters = $filters; 01133 $filters = array(); 01134 foreach ( array_keys( $wantedFilters ) as $wantedFilterKey ) 01135 { 01136 $wantedFilter = $wantedFilters[$wantedFilterKey]; 01137 if ( !$this->isFilterAllowed( $wantedFilter['name'], $destinationMimeData ) ) 01138 { 01139 continue; 01140 } 01141 $filters[] = $wantedFilter; 01142 } 01143 $result = true; 01144 $tempFiles = array(); 01145 if ( $currentMimeData['name'] != $destinationMimeData['name'] or 01146 count( $filters ) > 0 ) 01147 { 01148 while ( $currentMimeData['name'] != $destinationMimeData['name'] or 01149 count( $filters ) > 0 ) 01150 { 01151 $nextMimeData = false; 01152 $nextHandler = false; 01153 foreach ( $handlers as $handler ) 01154 { 01155 if ( !$handler ) 01156 continue; 01157 $outputMimeData = $handler->outputMIMEType( $this, $currentMimeData, $destinationMimeData, $this->SupportedFormats, $aliasName ); 01158 if ( $outputMimeData['name'] == $destinationMimeData['name'] ) 01159 { 01160 $nextMimeData = $outputMimeData; 01161 $nextHandler = $handler; 01162 break; 01163 } 01164 if ( $outputMimeData and 01165 !$nextMimeData ) 01166 { 01167 $nextMimeData = $outputMimeData; 01168 $nextHandler = $handler; 01169 } 01170 } 01171 if ( !$nextMimeData ) 01172 { 01173 eZDebug::writeError( "None of the handlers can convert MIME-Type " . $currentMimeData['name'], 01174 'eZImageManager::convert' ); 01175 $sourceFile->deleteLocal(); 01176 return false; 01177 } 01178 $handlerFilters = array(); 01179 $leftoverFilters = array(); 01180 foreach ( $filters as $filter ) 01181 { 01182 if ( $nextHandler->isFilterSupported( $filter ) ) 01183 $handlerFilters[] = $filter; 01184 else 01185 $leftoverFilters[] = $filter; 01186 } 01187 $useTempImage = false; 01188 if ( $nextMimeData['name'] == $destinationMimeData['name'] and 01189 count( $leftoverFilters ) == 0 ) 01190 { 01191 $nextMimeData['dirpath'] = $destinationMimeData['dirpath']; 01192 } 01193 else 01194 { 01195 $useTempImage = true; 01196 $nextMimeData['dirpath'] = $this->temporaryImageDirPath(); 01197 } 01198 eZMimeType::changeDirectoryPath( $nextMimeData, $nextMimeData['dirpath'] ); 01199 01200 if ( $nextMimeData['dirpath'] and 01201 !file_exists( $nextMimeData['dirpath'] ) ) 01202 eZDir::mkdir( $nextMimeData['dirpath'], false, true ); 01203 if ( $currentMimeData['name'] == $nextMimeData['name'] and 01204 count( $handlerFilters ) == 0 ) 01205 { 01206 if ( $currentMimeData['url'] != $nextMimeData['url'] ) 01207 { 01208 //include_once( 'lib/ezfile/classes/ezfilehandler.php' ); 01209 if ( eZFileHandler::copy( $currentMimeData['url'], $nextMimeData['url'] ) ) 01210 { 01211 if ( $useTempImage ) 01212 $tempFiles[] = $nextMimeData['url']; 01213 } 01214 else 01215 { 01216 $result = false; 01217 break; 01218 } 01219 } 01220 $currentMimeData = $nextMimeData; 01221 } 01222 else 01223 { 01224 if ( $nextHandler->convert( $this, $currentMimeData, $nextMimeData, $handlerFilters ) ) 01225 { 01226 if ( $useTempImage ) 01227 $tempFiles[] = $nextMimeData['url']; 01228 } 01229 else 01230 { 01231 $result = false; 01232 break; 01233 } 01234 $currentMimeData = $nextMimeData; 01235 } 01236 $filters = $leftoverFilters; 01237 } 01238 } 01239 else 01240 { 01241 $useCopy = false; 01242 if ( $aliasName and 01243 $aliasName != 'original' ) 01244 { 01245 $destinationMimeData['filename'] = $destinationMimeData['basename'] . '_' . $aliasName . '.' . $destinationMimeData['suffix']; 01246 if ( $destinationMimeData['dirpath'] ) 01247 $destinationMimeData['url'] = $destinationMimeData['dirpath'] . '/' . $destinationMimeData['filename']; 01248 else 01249 $destinationMimeData['url'] = $destinationMimeData['filename']; 01250 } 01251 if ( $sourceMimeData['url'] != $destinationMimeData['url'] ) 01252 { 01253 //include_once( 'lib/ezfile/classes/ezfilehandler.php' ); 01254 if ( $useCopy ) 01255 { 01256 eZFileHandler::copy( $sourceMimeData['url'], $destinationMimeData['url'] ); 01257 } 01258 else 01259 { 01260 eZFileHandler::linkCopy( $sourceMimeData['url'], $destinationMimeData['url'], false ); 01261 } 01262 $currentMimeData = $destinationMimeData; 01263 } 01264 } 01265 foreach ( $tempFiles as $tempFile ) 01266 { 01267 if ( !@unlink( $tempFile ) ) 01268 { 01269 eZDebug::writeError( "Failed to unlink temporary image file $tempFile", 01270 'eZImageManager::convert' ); 01271 } 01272 } 01273 $destinationMimeData = $currentMimeData; 01274 01275 if ( $aliasName && $aliasName != 'original' ) 01276 { 01277 if ( $result ) 01278 { 01279 $destinationFilePath = $destinationMimeData['url']; 01280 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01281 $fileHandler = eZClusterFileHandler::instance(); 01282 $fileHandler->fileStore( $destinationFilePath, 'image', true, $destinationMimeData['name'] ); 01283 } 01284 01285 $sourceFile->deleteLocal(); 01286 } 01287 01288 return $result; 01289 } 01290 01291 /** 01292 * Image information for $aliasName. This is the information which normally 01293 * would be provided during generation of aliasName. This so that requests 01294 * not holding the lock will provide meaningful information. 01295 * 01296 * @param mixed $mimeData 01297 * @param string $aliasName 01298 * @return mixed 01299 */ 01300 function imageAliasInfo( $mimeData, $aliasName ) 01301 { 01302 if ( is_string( $mimeData ) ) 01303 $mimeData = eZMimeType::findByFileContents( $mimeData ); 01304 01305 $this->analyzeImage( $mimeData ); 01306 if ( $aliasName ) 01307 { 01308 $aliasList = $this->aliasList(); 01309 if ( isset( $aliasList[$aliasName] ) ) 01310 { 01311 $alias = $aliasList[$aliasName]; 01312 if ( $alias['mime_type'] ) 01313 { 01314 eZMimeType::changeMIMEType( $mimeData, $alias['mime_type'] ); 01315 } 01316 } 01317 } 01318 if ( $aliasName != 'original' ) 01319 { 01320 $mimeData['filename'] = $mimeData['basename'] . '_' . $aliasName . '.' . $mimeData['suffix']; 01321 $mimeData['url'] = $mimeData['dirpath'] . '/' . $mimeData['filename']; 01322 } 01323 // eZDebug::writeDebug( $mimeData, 'return from eZImageManager::imageAliasInfo' ); 01324 return $mimeData; 01325 } 01326 01327 /*! 01328 \return the path for temporary images. 01329 \note The default value uses the temporary directory setting from site.ini. 01330 */ 01331 function temporaryImageDirPath() 01332 { 01333 return $this->TemporaryImageDirPath; 01334 } 01335 01336 /*! 01337 Returns the only instance of the image manager. 01338 */ 01339 static function instance() 01340 { 01341 if ( !isset( $GLOBALS["eZImageManager"] ) ) 01342 { 01343 $GLOBALS["eZImageManager"] = new eZImageManager(); 01344 } 01345 return $GLOBALS["eZImageManager"]; 01346 } 01347 01348 /*! 01349 Acquires an exclusive lock for the currently generated alias 01350 */ 01351 private function _exclusiveLock( $fileName, $aliasName ) 01352 { 01353 // mutex w/ exclusive lock: convert(targetFileName) 01354 $mutex = $this->_mutex( "{$fileName}-{$aliasName}" ); 01355 while( true ) 01356 { 01357 $timestamp = $mutex->lockTS(); // Note: This does not lock, only checks what the timestamp is. 01358 if ( $timestamp === false ) 01359 { 01360 if ( !$mutex->lock() ) 01361 { 01362 eZDebug::writeWarning( "Failed to acquire lock for file $fileName/$aliasName" ); 01363 return false; 01364 } 01365 $mutex->setMeta( 'pid', getmypid() ); 01366 return true; 01367 } 01368 if ( $timestamp >= time() - $this->lockTimeout ) 01369 { 01370 sleep( 1 ); // Sleep 1 second 01371 continue; 01372 } 01373 01374 $oldPid = $mutex->meta( 'pid' ); 01375 if ( is_numeric( $oldPid ) && 01376 $oldPid != 0 && 01377 function_exists( 'posix_kill' ) ) 01378 { 01379 posix_kill( $oldPid, 9 ); 01380 } 01381 if ( !$mutex->steal() ) 01382 { 01383 eZDebug::writeWarning( "Failed to steal lock for file $fileName/$aliasName from PID $oldPid" ); 01384 return false; 01385 } 01386 $mutex->setMeta( 'pid', getmypid() ); 01387 return true; 01388 } // while 01389 } 01390 01391 /*! 01392 Frees the current exclusive lock in use. 01393 01394 \param $fname Name of the calling code (usually function name). 01395 */ 01396 private function _freeExclusiveLock( $fileName, $aliasName ) 01397 { 01398 $this->_mutex( "{$fileName}-{$aliasName}" )->unlock(); 01399 } 01400 01401 /*! 01402 Returns the mutex object for the current file. 01403 */ 01404 private function _mutex( $fname = false ) 01405 { 01406 if ( $this->Mutex !== null ) 01407 { 01408 return $this->Mutex; 01409 } 01410 $this->Mutex = new eZMutex( $fname ); 01411 return $this->Mutex; 01412 } 01413 01414 /// \privatesection 01415 public $ImageHandlers; 01416 public $OutputMIME; 01417 public $OutputMIMEMap; 01418 public $Rules; 01419 public $DefaultRule; 01420 public $RuleMap; 01421 public $MIMETypes; 01422 public $Types = array(); 01423 01424 /** 01425 * Holds the mutex for image alias file. 01426 * 01427 * @var eZMutex 01428 */ 01429 private $Mutex; 01430 01431 /** 01432 * The time spent waiting before an existing eZMutex lock is cancelled and reused. 01433 * Default value is 60 seconds, which is set in constructor. 01434 * 01435 * @var int 01436 */ 01437 private $lockTimeout; 01438 01439 } 01440 01441 ?>