00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 include_once( 'lib/ezutils/classes/ezini.php' );
00105
00106 class eZImageManager
00107 {
00108
00109
00110
00111
00112 function eZImageManager()
00113 {
00114
00115 $this->SupportedFormats = array();
00116 $this->SupportedMIMEMap = array();
00117 $this->ImageHandlers = array();
00118 $this->AliasList = array();
00119 $this->Factories = array();
00120 $this->ImageFilters = array();
00121 $this->MIMETypeSettings = array();
00122 $this->MIMETypeSettingsMap = array();
00123 $this->QualityValues = array();
00124 $this->QualityValueMap = array();
00125
00126 $ini =& eZINI::instance( 'image.ini' );
00127 $this->TemporaryImageDirPath = eZSys::cacheDirectory() . '/' . $ini->variable( 'FileSettings', 'TemporaryDir' );
00128 $this->lockTimeout = $ini->hasVariable( 'ImageConverterSettings', 'LockTimeout' ) ? $ini->variable( 'ImageConverterSettings', 'LockTimeout' ) : 60;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 function setSupportedFormats( $mimeList )
00139 {
00140 $this->SupportedFormats = $mimeList;
00141 $this->SupportedMIMEMap = array();
00142 foreach ( $mimeList as $mimeName )
00143 {
00144 $this->SupportedMIMEMap[$mimeName] = true;
00145 }
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 function appendSupportedFormat( $mimeName )
00156 {
00157 $this->SupportedFormats[] = $mimeName;
00158 $this->SupportedMIMEMap[$mimeName] = true;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 function appendImageHandler( &$handler )
00168 {
00169 if ( !$handler )
00170 return false;
00171 if ( !$handler->isAvailable() )
00172 return false;
00173 $this->ImageHandlers[] =& $handler;
00174 $this->ImageFilters = array_merge( $this->ImageFilters, $handler->supportedImageFilters() );
00175 $this->ImageFilters = array_unique( $this->ImageFilters );
00176 return true;
00177 }
00178
00179
00180
00181
00182 function isFilterSupported( $filterName )
00183 {
00184 return in_array( $filterName, $this->ImageFilters );
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 function aliasList()
00198 {
00199 $aliasList = $this->AliasList;
00200 if ( !isset( $aliasList['original'] ) )
00201 {
00202 $alias = array( 'name' => 'original',
00203 'reference' => false,
00204 'mime_type' => false,
00205 'filters' => array() );
00206 $alias['alias_key'] = $this->createImageAliasKey( $alias );
00207 $aliasList['original'] = $alias;
00208 }
00209 return $aliasList;
00210 }
00211
00212
00213
00214
00215 function hasAlias( $aliasName )
00216 {
00217 $aliasList = $this->aliasList();
00218 return array_key_exists( $aliasName, $aliasList );
00219 }
00220
00221
00222
00223
00224 function alias( $aliasName )
00225 {
00226 $aliasList = $this->aliasList();
00227 if ( !array_key_exists( $aliasName, $aliasList ) )
00228 return false;
00229 return $aliasList[$aliasName];
00230 }
00231
00232
00233
00234
00235 function appendImageAlias( $alias )
00236 {
00237 $key = $this->createImageAliasKey( $alias );
00238 $alias['alias_key'] = $key;
00239 $this->AliasList[$alias['name']] = $alias;
00240 return $key;
00241 }
00242
00243
00244
00245
00246
00247 function createImageAliasKey( $alias )
00248 {
00249 $keyData = array( $alias['name'],
00250 $alias['reference'],
00251 $alias['mime_type'] );
00252 if ( $alias['reference'] )
00253 {
00254 $referenceAlias = $this->alias( $alias['reference'] );
00255 if ( $referenceAlias )
00256 $keyData[] = $referenceAlias['alias_key'];
00257 }
00258 foreach ( $alias['filters'] as $filter )
00259 {
00260 $filterData = $filter['name'];
00261 if ( is_array( $filter['data'] ) )
00262 $filterData .= '=' . implode( ',', $filter['data'] );
00263 $keyData[] = $filterData;
00264 }
00265
00266 include_once( 'lib/ezutils/classes/ezsys.php' );
00267 $key = eZSys::ezcrc32( implode( "\n", $keyData ) );
00268
00269 return $key;
00270 }
00271
00272
00273
00274
00275
00276 function isImageAliasValid( $alias )
00277 {
00278 $aliasName = $alias['name'];
00279 if ( isset( $this->AliasList[$aliasName] ) )
00280 {
00281 $aliasKey = $alias['alias_key'];
00282 $aliasInfo = $this->AliasList[$aliasName];
00283 $checkKey = $aliasInfo['alias_key'];
00284 $isValid = ( $aliasKey == $checkKey );
00285 if ( $isValid )
00286 {
00287 $aliasTimestamp = $alias['timestamp'];
00288 $isValid = $this->isImageTimestampValid( $aliasTimestamp );
00289 }
00290 return $isValid;
00291 }
00292 return false;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 function isImageTimestampValid( $timestamp )
00302 {
00303 include_once( 'lib/ezutils/classes/ezexpiryhandler.php' );
00304 $expiryHandler = eZExpiryHandler::instance();
00305 if ( $expiryHandler->hasTimestamp( 'image-manager-alias' ) )
00306 {
00307 $aliasTimestamp = $expiryHandler->timestamp( 'image-manager-alias' );
00308 return ( $timestamp > $aliasTimestamp );
00309 }
00310 return true;
00311 }
00312
00313
00314
00315
00316
00317
00318 function readImageAliasesFromINI( $iniFile = false )
00319 {
00320 if ( !$iniFile )
00321 $iniFile = 'image.ini';
00322 $ini =& eZINI::instance( $iniFile );
00323 if ( !$ini )
00324 return false;
00325 $aliasNames = $ini->variable( 'AliasSettings', 'AliasList' );
00326 foreach ( $aliasNames as $aliasName )
00327 {
00328 $alias = $this->createAliasFromINI( $aliasName );
00329 if ( $alias )
00330 {
00331 $this->appendImageAlias( $alias );
00332 }
00333 else
00334 eZDebug::writeWarning( "Failed reading Image Alias $aliasName from $iniFile",
00335 'eZImageManager::readImageAliasFromINI' );
00336 }
00337 $aliasName = 'original';
00338 if ( !in_array( $aliasName, $aliasNames ) )
00339 {
00340 include_once( 'lib/ezutils/classes/ezini.php' );
00341 $ini =& eZINI::instance( 'image.ini' );
00342 if ( $ini->hasGroup( $aliasName ) )
00343 {
00344 $alias = $this->createAliasFromINI( $aliasName );
00345 if ( $alias )
00346 {
00347 $alias['reference'] = false;
00348 $this->appendImageAlias( $alias );
00349 }
00350 else
00351 eZDebug::writeWarning( "Failed reading Image Alias $aliasName from $iniFile",
00352 'eZImageManager::readImageAliasFromINI' );
00353 }
00354 }
00355 }
00356
00357
00358
00359
00360
00361
00362 function readSupportedFormatsFromINI( $iniFile = false )
00363 {
00364 if ( !$iniFile )
00365 $iniFile = 'image.ini';
00366 $ini =& eZINI::instance( $iniFile );
00367 if ( !$ini )
00368 return false;
00369 $allowedOutputFormats = $ini->variable( 'OutputSettings', 'AllowedOutputFormat' );
00370 foreach ( $allowedOutputFormats as $allowedOutputFormat )
00371 {
00372 $this->appendSupportedFormat( $allowedOutputFormat );
00373 }
00374 }
00375
00376
00377
00378
00379 function hasMIMETypeSetting( $mimeData )
00380 {
00381 return isset( $this->MIMETypeSettingsMap[$mimeData['name']] );
00382 }
00383
00384
00385
00386
00387 function mimeTypeSetting( $mimeData )
00388 {
00389 if ( !isset( $this->MIMETypeSettingsMap[$mimeData['name']] ) )
00390 return false;
00391 $list = $this->MIMETypeSettingsMap[$mimeData['name']];
00392 foreach ( $list as $item )
00393 {
00394 if ( is_array( $item['match'] ) )
00395 {
00396 if ( array_key_exists( 'info', $mimeData ) && is_array( $mimeData['info'] ) )
00397 {
00398 $isMatch = true;
00399 $info =& $mimeData['info'];
00400 foreach ( $item['match'] as $matchKey => $matchValue )
00401 {
00402 if ( !isset( $info[$matchKey] ) or
00403 $info[$matchKey] != $matchValue )
00404 {
00405 $isMatch = false;
00406 break;
00407 }
00408 }
00409 if ( $isMatch )
00410 return $item;
00411 }
00412 }
00413 else
00414 return $item;
00415 }
00416 return false;
00417 }
00418
00419
00420
00421
00422
00423 function wildcardToRegexp( $wildcard, $separatorCharacter = false )
00424 {
00425 return eZImageHandler::wildcardToRegexp( $wildcard, $separatorCharacter );
00426 }
00427
00428
00429
00430
00431 function mimeTypeOverride( $mimeData )
00432 {
00433 if ( $this->hasMIMETypeSetting( $mimeData ) )
00434 {
00435 $settings = $this->mimeTypeSetting( $mimeData );
00436 if ( $settings )
00437 {
00438 return $settings['override_mime_type'];
00439 }
00440 }
00441 return false;
00442 }
00443
00444
00445
00446
00447
00448 function mimeTypeFilters( $mimeData )
00449 {
00450 if ( $this->hasMIMETypeSetting( $mimeData ) )
00451 {
00452 $settings = $this->mimeTypeSetting( $mimeData );
00453 if ( $settings )
00454 {
00455 return $settings['extra_filters'];
00456 }
00457 }
00458 return false;
00459 }
00460
00461
00462
00463
00464 function isFilterAllowed( $filterName, $mimeData )
00465 {
00466 if ( $this->hasMIMETypeSetting( $mimeData ) )
00467 {
00468 $settings = $this->mimeTypeSetting( $mimeData );
00469 if ( $settings )
00470 {
00471 if ( is_array( $settings['disallowed_filters'] ) )
00472 {
00473 foreach ( $settings['disallowed_filters'] as $filter )
00474 {
00475 $regexp = eZImageManager::wildcardToRegexp( $filter );
00476 if ( preg_match( '#' . $regexp . '#', $filterName ) )
00477 {
00478 return false;
00479 }
00480 }
00481 }
00482 if ( is_array( $settings['allowed_filters'] ) )
00483 {
00484 foreach ( $settings['allowed_filters'] as $filter )
00485 {
00486 $regexp = eZImageManager::wildcardToRegexp( $filter );
00487 if ( preg_match( '#' . $regexp . '#', $filterName ) )
00488 {
00489 return true;
00490 }
00491 }
00492 return false;
00493 }
00494 return true;
00495 }
00496 }
00497 return true;
00498 }
00499
00500
00501
00502
00503 function appendQualityValue( $mimeType, $qualityValue )
00504 {
00505 $element = array( 'name' => $mimeType,
00506 'value' => $qualityValue );
00507 $this->QualityValues[] = $element;
00508 $this->QualityValueMap[$mimeType] = $element;
00509 }
00510
00511
00512
00513
00514 function qualityValue( $mimeType )
00515 {
00516 if ( isset( $this->QualityValueMap[$mimeType] ) )
00517 return $this->QualityValueMap[$mimeType]['value'];
00518 return false;
00519 }
00520
00521
00522
00523
00524 function appendMIMETypeSetting( $settings )
00525 {
00526 $this->MIMETypeSettings[] =& $settings;
00527 if ( !isset( $this->MIMETypeSettingsMap[$settings['mime_type']] ) )
00528 $this->MIMETypeSettingsMap[$settings['mime_type']] = array();
00529 $this->MIMETypeSettingsMap[$settings['mime_type']][] =& $settings;
00530 }
00531
00532
00533
00534
00535
00536
00537 function readMIMETypeSettingsFromINI( $iniFile = false )
00538 {
00539 if ( !$iniFile )
00540 $iniFile = 'image.ini';
00541 $ini =& eZINI::instance( $iniFile );
00542 if ( !$ini )
00543 return false;
00544 $overrideList = $ini->variable( 'MIMETypeSettings', 'OverrideList' );
00545 foreach ( $overrideList as $mimeType )
00546 {
00547 $settings = eZImageManager::readMIMETypeSettingFromINI( $mimeType );
00548 if ( $settings )
00549 $this->appendMIMETypeSetting( $settings );
00550 }
00551 }
00552
00553
00554
00555
00556 function readMIMETypeQualitySettingFromINI( $iniFile = false )
00557 {
00558 if ( !$iniFile )
00559 $iniFile = 'image.ini';
00560 $ini =& eZINI::instance( $iniFile );
00561 if ( !$ini )
00562 return false;
00563 if ( !$ini->hasVariable( 'MIMETypeSettings', 'Quality' ) )
00564 return false;
00565 $values = $ini->variable( 'MIMETypeSettings', 'Quality' );
00566 foreach ( $values as $value )
00567 {
00568 $elements = explode( ';', $value );
00569 $mimeType = $elements[0];
00570 $qualityValue = $elements[1];
00571 $this->appendQualityValue( $mimeType, $qualityValue );
00572 }
00573 }
00574
00575
00576
00577
00578 function readConversionRuleSettingsFromINI( $iniFile = false )
00579 {
00580 if ( !$iniFile )
00581 $iniFile = 'image.ini';
00582 $ini =& eZINI::instance( $iniFile );
00583 if ( !$ini )
00584 return false;
00585 if ( $ini->hasVariable( 'MIMETypeSettings', 'ConversionRules' ) )
00586 {
00587 $conversionRules = array();
00588 $rules = $ini->variable( 'MIMETypeSettings', 'ConversionRules' );
00589 foreach ( $rules as $ruleString )
00590 {
00591 $ruleItems = explode( ';', $ruleString );
00592 if ( count( $ruleItems ) >= 2 )
00593 {
00594 $conversionRule = array( 'from' => $ruleItems[0],
00595 'to' => $ruleItems[1] );
00596 $this->appendConversionRule( $conversionRule );
00597 }
00598 }
00599 }
00600 }
00601
00602
00603
00604
00605 function readINISettings()
00606 {
00607 $this->readImageHandlersFromINI();
00608 $this->readSupportedFormatsFromINI();
00609 $this->readImageAliasesFromINI();
00610 $this->readMIMETypeSettingsFromINI();
00611 $this->readMIMETypeQualitySettingFromINI();
00612 $this->readConversionRuleSettingsFromINI();
00613 }
00614
00615
00616
00617
00618 function appendConversionRule( $conversionRule )
00619 {
00620 $this->ConversionRules[] = $conversionRule;
00621 }
00622
00623
00624
00625
00626 function conversionRules()
00627 {
00628 return $this->ConversionRules;
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638 function readMIMETypeSettingFromINI( $mimeGroup, $iniFile = false )
00639 {
00640 if ( !$iniFile )
00641 $iniFile = 'image.ini';
00642 $ini =& eZINI::instance( $iniFile );
00643 if ( !$ini )
00644 return false;
00645 if ( !$ini->hasGroup( $mimeGroup ) )
00646 return false;
00647 if ( !$ini->hasVariable( $mimeGroup, 'MIMEType' ) )
00648 return false;
00649 $settings = array( 'name' => $mimeGroup,
00650 'match' => false,
00651 'mime_type' => false,
00652 'override_mime_type' => false,
00653 'allowed_filters' => false,
00654 'disallowed_filters' => false,
00655 'extra_filters' => false );
00656 $settings['mime_type'] = $ini->variable( $mimeGroup, 'MIMEType' );
00657 $ini->assign( $mimeGroup, 'Match', $settings['match'] );
00658 $ini->assign( $mimeGroup, 'OverrideMIMEType', $settings['override_mime_type'] );
00659 $ini->assign( $mimeGroup, 'AllowedFilters', $settings['allowed_filters'] );
00660 $ini->assign( $mimeGroup, 'DisallowedFilters', $settings['disallowed_filters'] );
00661 if ( $ini->hasVariable( $mimeGroup, 'ExtraFilters' ) )
00662 {
00663 $filters = array();
00664 $filterRawList = $ini->variable( $mimeGroup, 'ExtraFilters' );
00665 foreach ( $filterRawList as $filterRawItem )
00666 {
00667 $filters[] = $this->createFilterDataFromINI( $filterRawItem );
00668 }
00669 if ( count( $filters ) > 0 )
00670 $settings['extra_filters'] = $filters;
00671 }
00672 return $settings;
00673 }
00674
00675
00676
00677
00678
00679
00680 function readImageHandlersFromINI( $iniFile = false )
00681 {
00682 if ( !$iniFile )
00683 $iniFile = 'image.ini';
00684 $ini =& eZINI::instance( $iniFile );
00685 if ( !$ini )
00686 return false;
00687 $handlerList = $ini->variable( 'ImageConverterSettings', 'ImageConverters' );
00688 foreach ( $handlerList as $handlerName )
00689 {
00690 if ( $ini->hasGroup( $handlerName ) )
00691 {
00692 if ( $ini->hasVariable( $handlerName, 'Handler' ) )
00693 {
00694 $factoryName = $ini->variable( $handlerName, 'Handler' );
00695 $factory =& $this->factoryFor( $factoryName, $iniFile );
00696 if ( $factory )
00697 {
00698 $convertHandler =& $factory->produceFromINI( $handlerName, $iniFile );
00699 $this->appendImageHandler( $convertHandler );
00700 }
00701 }
00702 else
00703 {
00704 eZDebug::writeWarning( "INI group $handlerName does not have a Handler setting, cannot instantiate handler without it",
00705 'eZImageManager::readImageHandlersFromINI' );
00706 }
00707 }
00708 else
00709 {
00710 eZDebug::writeWarning( "No INI group $handlerName for Image Handler $handlerName, cannot instantiate",
00711 'eZImageManager::readImageHandlersFromINI' );
00712 }
00713 }
00714 }
00715
00716
00717
00718
00719
00720 function &factoryFor( $factoryName, $iniFile = false )
00721 {
00722 if ( !$iniFile )
00723 $iniFile = 'image.ini';
00724 if ( isset( $this->Factories[$factoryName] ) )
00725 {
00726 return $this->Factories[$factoryName];
00727 }
00728 else
00729 {
00730 include_once( 'lib/ezutils/classes/ezextension.php' );
00731 if ( eZExtension::findExtensionType( array( 'ini-name' => $iniFile,
00732 'repository-group' => 'ImageConverterSettings',
00733 'repository-variable' => 'RepositoryList',
00734 'extension-group' => 'ImageConverterSettings',
00735 'extension-variable' => 'ExtensionList',
00736 'extension-subdir' => 'imagehandler',
00737 'alias-group' => 'ImageConverterSettings',
00738 'alias-variable' => 'ImageHandlerAlias',
00739 'suffix-name' => 'handler.php',
00740 'type-directory' => false,
00741 'type' => $factoryName ),
00742 $result ) )
00743 {
00744 $filepath = $result['found-file-path'];
00745 include_once( $filepath );
00746 $className = $result['type'] . 'factory';
00747 if ( class_exists( $className ) )
00748 {
00749 $factory = new $className();
00750 $this->Factories[$factoryName] =& $factory;
00751 return $factory;
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 $retValue = false;
00766 return $retValue;
00767 }
00768
00769
00770
00771
00772
00773 function createFilterDataFromINI( $filterText )
00774 {
00775 $equalPosition = strpos( $filterText, '=' );
00776 $filterData = false;
00777 if ( $equalPosition !== false )
00778 {
00779 $filterName = substr( $filterText, 0, $equalPosition );
00780 $filterDataText = substr( $filterText, $equalPosition + 1 );
00781 $filterData = explode( ';', $filterDataText );
00782 }
00783 else
00784 $filterName = $filterText;
00785 return array( 'name' => $filterName,
00786 'data' => $filterData );
00787 }
00788
00789
00790
00791
00792
00793 function createAliasFromINI( $iniGroup )
00794 {
00795 include_once( 'lib/ezutils/classes/ezini.php' );
00796 $ini =& eZINI::instance( 'image.ini' );
00797 if ( !$ini->hasGroup( $iniGroup ) )
00798 {
00799 eZDebug::writeError( "No such group $iniGroup in ini file image.ini",
00800 'eZImageManager::createAliasFromINI' );
00801 return false;
00802 }
00803 $alias = array( 'name' => $iniGroup,
00804 'reference' => false,
00805 'mime_type' => false,
00806 'filters' => array() );
00807 if ( $ini->hasVariable( $iniGroup, 'Name' ) )
00808 $alias['name'] = $ini->variable( $iniGroup, 'Name' );
00809 if ( $ini->hasVariable( $iniGroup, 'MIMEType' ) )
00810 $alias['mime_type'] = $ini->variable( $iniGroup, 'MIMEType' );
00811 if ( $ini->hasVariable( $iniGroup, 'Filters' ) )
00812 {
00813 $filters = array();
00814 $filterRawList = $ini->variable( $iniGroup, 'Filters' );
00815 foreach ( $filterRawList as $filterRawItem )
00816 {
00817 $filters[] = $this->createFilterDataFromINI( $filterRawItem );
00818 }
00819 $alias['filters'] = $filters;
00820 }
00821 if ( $ini->hasVariable( $iniGroup, 'Reference' ) )
00822 $alias['reference'] = $ini->variable( $iniGroup, 'Reference' );
00823 return $alias;
00824 }
00825
00826
00827
00828
00829
00830
00831 function createImageAlias( $aliasName, &$existingAliasList, $parameters = array() )
00832 {
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
00854
00855 require_once( 'kernel/classes/ezclusterfilehandler.php' );
00856 $fileHandler = eZClusterFileHandler::instance();
00857 if ( $fileHandler->fileExists( $existingAliasList[$referenceAlias]['url'] ) )
00858 {
00859 $hasReference = true;
00860 }
00861 else
00862 {
00863 eZDebug::writeError( "The reference alias $referenceAlias file " . $existingAliasList[$referenceAlias]['url'] . " does not exist",
00864 'eZImageManager::createImageAlias' );
00865 }
00866 }
00867 if ( !$hasReference )
00868 {
00869 if ( $referenceAlias == 'original' )
00870 {
00871 eZDebug::writeError( "Original alias does not exists, cannot create other aliases without it" );
00872 return false;
00873 }
00874 if ( !$this->createImageAlias( $referenceAlias, $existingAliasList, $parameters ) )
00875 {
00876 eZDebug::writeError( "Failed creating the referenced alias $referenceAlias, cannot create alias $aliasName",
00877 'eZImageManager::createImageAlias' );
00878 return false;
00879 }
00880 }
00881 if ( array_key_exists( $referenceAlias, $existingAliasList ) )
00882 {
00883 $aliasInfo = $existingAliasList[$referenceAlias];
00884 $aliasFilePath = $aliasInfo['url'];
00885 $aliasKey = $currentAliasInfo['alias_key'];
00886
00887
00888 require_once( 'kernel/classes/ezclusterfilehandler.php' );
00889 $aliasFile = eZClusterFileHandler::instance( $aliasFilePath );
00890
00891 if ( $aliasFile->exists() )
00892 {
00893 $aliasFile->fetch();
00894 include_once( 'lib/ezutils/classes/ezmimetype.php' );
00895 $sourceMimeData = eZMimeType::findByFileContents( $aliasFilePath );
00896 $destinationMimeData = $sourceMimeData;
00897 if ( isset( $parameters['basename'] ) )
00898 {
00899 $sourceMimeData['basename'] = $parameters['basename'];
00900 eZMimeType::changeBasename( $destinationMimeData, $parameters['basename'] );
00901 }
00902
00903 if ( !$this->_exclusiveLock( $aliasFilePath, $aliasName ) )
00904 {
00905 return false;
00906 }
00907
00908 $wantImage = $this->imageAliasInfo( $sourceMimeData, $aliasName );
00909 $wantImagePath = $wantImage['url'];
00910
00911 $fileHandler = eZClusterFileHandler::instance( $wantImagePath );
00912 $fileHandler->loadMetaData( true );
00913
00914 if ( $fileHandler->exists() and $this->isImageTimestampValid( $fileHandler->mtime() ) )
00915 {
00916 $destinationMimeData = $wantImage;
00917 $wasLocked = true;
00918 }
00919 else
00920 {
00921 $destinationMimeData['is_valid'] = false;
00922 if ( !$this->convert( $sourceMimeData, $destinationMimeData, $aliasName, $parameters ) )
00923 {
00924 $sourceFile = $sourceMimeData['url'];
00925 $destinationDir = $destinationMimeData['dirpath'];
00926 eZDebug::writeError( "Failed converting $sourceFile to alias '$aliasName' in directory '$destinationDir'",
00927 'eZImageManager::createImageAlias' );
00928
00929 $aliasFile->deleteLocal();
00930 return false;
00931 }
00932 }
00933
00934 $currentAliasData = array( 'url' => $destinationMimeData['url'],
00935 'dirpath' => $destinationMimeData['dirpath'],
00936 'filename' => $destinationMimeData['filename'],
00937 'suffix' => $destinationMimeData['suffix'],
00938 'basename' => $destinationMimeData['basename'],
00939 'alternative_text' => $aliasInfo['alternative_text'],
00940 'name' => $aliasName,
00941 'sub_type' => false,
00942 'timestamp' => time(),
00943 'alias_key' => $aliasKey,
00944 'mime_type' => $destinationMimeData['name'],
00945 'override_mime_type' => false,
00946 'info' => false,
00947 'width' => false,
00948 'height' => false,
00949 'is_valid' => true,
00950 'is_new' => true );
00951 if ( isset( $destinationMimeData['override_mime_type'] ) )
00952 $currentAliasData['override_mime_type'] = $destinationMimeData['override_mime_type'];
00953 if ( isset( $destinationMimeData['info'] ) )
00954 $currentAliasData['info'] = $destinationMimeData['info'];
00955 $currentAliasData['full_path'] =& $currentAliasData['url'];
00956 if ( function_exists( 'getimagesize' ) )
00957 {
00958
00959
00960 $fileHandler = eZClusterFileHandler::instance();
00961 $fileHandler->fileFetch( $destinationMimeData['url'] );
00962
00963 if ( file_exists( $destinationMimeData['url'] ) )
00964 {
00965 $info = getimagesize( $destinationMimeData['url'] );
00966 if ( $info )
00967 {
00968 $width = $info[0];
00969 $height = $info[1];
00970 $currentAliasData['width'] = $width;
00971 $currentAliasData['height'] = $height;
00972 }
00973 else
00974 {
00975 eZDebug::writeError("The size of the generated image " . $destinationMimeData['url'] . " could not be read by getimagesize()", 'eZImageManager::createImageAlias' );
00976 }
00977
00978
00979
00980
00981 if ( !isset( $wasLocked ) )
00982 {
00983 $fileHandler = eZClusterFileHandler::instance( $aliasFilePath );
00984 $fileHandler->fileStore( $destinationMimeData['url'], 'image', true, $destinationMimeData['name'] );
00985 }
00986 }
00987 else
00988 {
00989 eZDebug::writeError( "The destination image " . $destinationMimeData['url'] . " does not exist, cannot figure out image size", 'eZImageManager::createImageAlias' );
00990 }
00991 }
00992 else
00993 eZDebug::writeError( "Unknown function 'getimagesize' cannot get image size", 'eZImageManager::createImageAlias' );
00994 $existingAliasList[$aliasName] = $currentAliasData;
00995
00996 $aliasFile->deleteLocal();
00997
00998 $this->_freeExclusiveLock( $aliasFilePath, $aliasName );
00999
01000 return true;
01001 }
01002 }
01003 return false;
01004 }
01005
01006
01007
01008
01009
01010
01011
01012 function analyzeImage( &$mimeData, $parameters = array() )
01013 {
01014 $file = $mimeData['url'];
01015
01016 if ( !file_exists( $file ) )
01017 return false;
01018 $analyzer = eZImageAnalyzer::createForMIME( $mimeData );
01019 $status = true;
01020 if ( is_object( $analyzer ) )
01021 {
01022 $imageInformation = $analyzer->process( $mimeData, $parameters );
01023 if ( $imageInformation )
01024 {
01025 $mimeData['info'] = $imageInformation;
01026 }
01027 else
01028 $status = false;
01029 }
01030 return $status;
01031 }
01032
01033
01034
01035
01036
01037
01038
01039 function convert( $sourceMimeData, &$destinationMimeData, $aliasName = false, $parameters = array() )
01040 {
01041
01042
01043 require_once( 'kernel/classes/ezclusterfilehandler.php' );
01044 $sourceFile = eZClusterFileHandler::instance( $sourceMimeData['url'] );
01045 $sourceFile->fetch();
01046
01047 include_once( 'lib/ezutils/classes/ezmimetype.php' );
01048 if ( is_string( $sourceMimeData ) )
01049 $sourceMimeData = eZMimeType::findByFileContents( $sourceMimeData );
01050
01051 $this->analyzeImage( $sourceMimeData );
01052 $currentMimeData = $sourceMimeData;
01053 $handlers =& $this->ImageHandlers;
01054 $supportedMIMEMap = $this->SupportedMIMEMap;
01055 if ( is_string( $destinationMimeData ) )
01056 {
01057 $destinationPath = $destinationMimeData;
01058 $destinationMimeData = eZMimeType::findByFileContents( $destinationPath );
01059 }
01060
01061 $filters = array();
01062 $alias = false;
01063 if ( $aliasName )
01064 {
01065 $aliasList = $this->aliasList();
01066 if ( isset( $aliasList[$aliasName] ) )
01067 {
01068 $alias = $aliasList[$aliasName];
01069 $filters = $alias['filters'];
01070 if ( $alias['mime_type'] )
01071 {
01072 eZMimeType::changeMIMEType( $destinationMimeData, $alias['mime_type'] );
01073 }
01074 }
01075 }
01076 $mimeTypeOverride = $this->mimeTypeOverride( $sourceMimeData );
01077 if ( $mimeTypeOverride )
01078 $alias['override_mime_type'] = $mimeTypeOverride;
01079
01080 if ( isset( $parameters['filters'] ) )
01081 {
01082 $filters = array_merge( $filters, $parameters['filters'] );
01083 }
01084
01085 $wantedFilters = $filters;
01086 $mimeTypeFilters = $this->mimeTypeFilters( $sourceMimeData );
01087 if ( is_array( $mimeTypeFilters ) )
01088 $wantedFilters = array_merge( $wantedFilters, $mimeTypeFilters );
01089 $filters = array();
01090 foreach ( array_keys( $wantedFilters ) as $wantedFilterKey )
01091 {
01092 $wantedFilter = $wantedFilters[$wantedFilterKey];
01093 if ( !$this->isFilterSupported( $wantedFilter['name'] ) )
01094 {
01095 eZDebug::writeWarning( "The filter '" . $wantedFilter['name'] . "' is not supported by any of the image handlers, will ignore this filter",
01096 'eZImageManager::convert' );
01097 continue;
01098 }
01099 $filters[] = $wantedFilter;
01100 }
01101 if ( !$destinationMimeData['is_valid'] )
01102 {
01103 $destinationDirPath = $destinationMimeData['dirpath'];
01104 $destinationBasename = $destinationMimeData['basename'];
01105 if ( isset( $supportedMIMEMap[$sourceMimeData['name']] ) )
01106 {
01107 $destinationMimeData = $sourceMimeData;
01108 if ( $alias['mime_type'] )
01109 {
01110 eZMimeType::changeMIMEType( $destinationMimeData, $alias['mime_type'] );
01111 }
01112 eZMimeType::changeFileData( $destinationMimeData, $destinationDirPath, $destinationBasename );
01113 }
01114 else
01115 {
01116 $hasDestination = false;
01117 foreach ( array_keys( $handlers ) as $handlerKey )
01118 {
01119 $handler =& $handlers[$handlerKey];
01120 $gotMimeData = true;
01121 while( $gotMimeData )
01122 {
01123 $gotMimeData = false;
01124 $outputMimeData = $handler->outputMIMEType( $this, $sourceMimeData, false, $this->SupportedFormats, $aliasName );
01125 if ( $outputMimeData and
01126 isset( $supportedMIMEMap[$outputMimeData['name']] ) )
01127 {
01128 $destinationMimeData = $outputMimeData;
01129 eZMimeType::changeFileData( $destinationMimeData, $destinationDirPath, $destinationBasename );
01130 $hasDestination = true;
01131 $gotMimeData = true;
01132 break;
01133 }
01134 }
01135 }
01136 if ( !$hasDestination )
01137 {
01138
01139 $sourceFile->deleteLocal();
01140 return false;
01141 }
01142 }
01143 }
01144
01145 $wantedFilters = $filters;
01146 $filters = array();
01147 foreach ( array_keys( $wantedFilters ) as $wantedFilterKey )
01148 {
01149 $wantedFilter = $wantedFilters[$wantedFilterKey];
01150 if ( !$this->isFilterAllowed( $wantedFilter['name'], $destinationMimeData ) )
01151 {
01152 continue;
01153 }
01154 $filters[] = $wantedFilter;
01155 }
01156 $result = true;
01157 $tempFiles = array();
01158 if ( $currentMimeData['name'] != $destinationMimeData['name'] or
01159 count( $filters ) > 0 )
01160 {
01161 while ( $currentMimeData['name'] != $destinationMimeData['name'] or
01162 count( $filters ) > 0 )
01163 {
01164 $nextMimeData = false;
01165 $nextHandler = false;
01166 foreach ( array_keys( $handlers ) as $handlerKey )
01167 {
01168 $handler =& $handlers[$handlerKey];
01169 if ( !$handler )
01170 continue;
01171 $outputMimeData = $handler->outputMIMEType( $this, $currentMimeData, $destinationMimeData, $this->SupportedFormats, $aliasName );
01172 if ( $outputMimeData['name'] == $destinationMimeData['name'] )
01173 {
01174 $nextMimeData = $outputMimeData;
01175 $nextHandler =& $handler;
01176 break;
01177 }
01178 if ( $outputMimeData and
01179 !$nextMimeData )
01180 {
01181 $nextMimeData = $outputMimeData;
01182 $nextHandler =& $handler;
01183 }
01184 }
01185 if ( !$nextMimeData )
01186 {
01187 eZDebug::writeError( "None of the handlers can convert MIME-Type " . $currentMimeData['name'],
01188 'eZImageManager::convert' );
01189
01190 $sourceFile->deleteLocal();
01191 return false;
01192 }
01193 $handlerFilters = array();
01194 $leftoverFilters = array();
01195 foreach ( $filters as $filter )
01196 {
01197 if ( $nextHandler->isFilterSupported( $filter ) )
01198 $handlerFilters[] = $filter;
01199 else
01200 $leftoverFilters[] = $filter;
01201 }
01202 $useTempImage = false;
01203 if ( $nextMimeData['name'] == $destinationMimeData['name'] and
01204 count( $leftoverFilters ) == 0 )
01205 {
01206 $nextMimeData['dirpath'] = $destinationMimeData['dirpath'];
01207 }
01208 else
01209 {
01210 $useTempImage = true;
01211 $nextMimeData['dirpath'] = $this->temporaryImageDirPath();
01212 }
01213 eZMimeType::changeDirectoryPath( $nextMimeData, $nextMimeData['dirpath'] );
01214
01215 if ( $nextMimeData['dirpath'] and
01216 !file_exists( $nextMimeData['dirpath'] ) )
01217 eZDir::mkdir( $nextMimeData['dirpath'], eZDir::directoryPermission(), true );
01218 if ( $currentMimeData['name'] == $nextMimeData['name'] and
01219 count( $handlerFilters ) == 0 )
01220 {
01221 if ( $currentMimeData['url'] != $nextMimeData['url'] )
01222 {
01223 include_once( 'lib/ezfile/classes/ezfilehandler.php' );
01224 if ( eZFileHandler::copy( $currentMimeData['url'], $nextMimeData['url'] ) )
01225 {
01226 if ( $useTempImage )
01227 $tempFiles[] = $nextMimeData['url'];
01228 }
01229 else
01230 {
01231 $result = false;
01232 break;
01233 }
01234 }
01235 $currentMimeData = $nextMimeData;
01236 }
01237 else
01238 {
01239 if ( $nextHandler->convert( $this, $currentMimeData, $nextMimeData, $handlerFilters ) )
01240 {
01241 if ( $useTempImage )
01242 $tempFiles[] = $nextMimeData['url'];
01243 }
01244 else
01245 {
01246 $result = false;
01247 break;
01248 }
01249 $currentMimeData = $nextMimeData;
01250 }
01251 $filters = $leftoverFilters;
01252 }
01253 }
01254 else
01255 {
01256 $useCopy = false;
01257 if ( $aliasName and
01258 $aliasName != 'original' )
01259 {
01260 $destinationMimeData['filename'] = $destinationMimeData['basename'] . '_' . $aliasName . '.' . $destinationMimeData['suffix'];
01261 if ( $destinationMimeData['dirpath'] )
01262 $destinationMimeData['url'] = $destinationMimeData['dirpath'] . '/' . $destinationMimeData['filename'];
01263 else
01264 $destinationMimeData['url'] = $destinationMimeData['filename'];
01265 }
01266 if ( $sourceMimeData['url'] != $destinationMimeData['url'] )
01267 {
01268 include_once( 'lib/ezfile/classes/ezfilehandler.php' );
01269 if ( $useCopy )
01270 {
01271 eZFileHandler::copy( $sourceMimeData['url'], $destinationMimeData['url'] );
01272 }
01273 else
01274 {
01275 eZFileHandler::linkCopy( $sourceMimeData['url'], $destinationMimeData['url'], false );
01276 }
01277 $currentMimeData = $destinationMimeData;
01278 }
01279 }
01280 foreach ( $tempFiles as $tempFile )
01281 {
01282 if ( !@unlink( $tempFile ) )
01283 {
01284 eZDebug::writeError( "Failed to unlink temporary image file $tempFile",
01285 'eZImageManager::convert' );
01286 }
01287 }
01288 $destinationMimeData = $currentMimeData;
01289
01290
01291
01292 if ( $aliasName && $aliasName != 'original' )
01293 {
01294 if ( $result )
01295 {
01296 $destinationFilePath = $destinationMimeData['url'];
01297 require_once( 'kernel/classes/ezclusterfilehandler.php' );
01298 $fileHandler = eZClusterFileHandler::instance();
01299 $fileHandler->fileStore( $destinationFilePath, 'image', true, $destinationMimeData['name'] );
01300 }
01301
01302 $sourceFile->deleteLocal();
01303 }
01304
01305 return $result;
01306 }
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 function imageAliasInfo( $mimeData, $aliasName )
01318 {
01319 if ( is_string( $mimeData ) )
01320 $mimeData = eZMimeType::findByFileContents( $mimeData );
01321
01322 $this->analyzeImage( $mimeData );
01323 if ( $aliasName )
01324 {
01325 $aliasList = $this->aliasList();
01326 if ( isset( $aliasList[$aliasName] ) )
01327 {
01328 $alias = $aliasList[$aliasName];
01329 if ( $alias['mime_type'] )
01330 {
01331 eZMimeType::changeMIMEType( $mimeData, $alias['mime_type'] );
01332 }
01333 }
01334 }
01335 if ( $aliasName != 'original' )
01336 {
01337 $mimeData['filename'] = $mimeData['basename'] . '_' . $aliasName . '.' . $mimeData['suffix'];
01338 $mimeData['url'] = $mimeData['dirpath'] . '/' . $mimeData['filename'];
01339 }
01340
01341 return $mimeData;
01342 }
01343
01344
01345
01346
01347
01348 function temporaryImageDirPath()
01349 {
01350 return $this->TemporaryImageDirPath;
01351 }
01352
01353
01354
01355
01356 function &instance()
01357 {
01358 $instance =& $GLOBALS["eZImageManager"];
01359 if ( get_class( $instance ) != "ezimagemanager" )
01360 {
01361 $instance = new eZImageManager();
01362 }
01363 return $instance;
01364 }
01365
01366
01367
01368
01369 function _exclusiveLock( $fileName, $aliasName )
01370 {
01371
01372 $mutex =& $this->_mutex( "{$fileName}-{$aliasName}" );
01373 while( true )
01374 {
01375 $timestamp = $mutex->lockTS();
01376 if ( $timestamp === false )
01377 {
01378 if ( !$mutex->lock() )
01379 {
01380 eZDebug::writeWarning( "Failed to acquire lock for file $fileName/$aliasName" );
01381 return false;
01382 }
01383 $mutex->setMeta( 'pid', getmypid() );
01384 return true;
01385 }
01386 if ( $timestamp >= gmmktime() - $this->lockTimeout )
01387 {
01388 sleep( 1 );
01389 continue;
01390 }
01391
01392 $oldPid = $mutex->meta( 'pid' );
01393 if ( is_numeric( $oldPid ) &&
01394 $oldPid != 0 &&
01395 function_exists( 'posix_kill' ) )
01396 {
01397 posix_kill( $oldPid, 9 );
01398 }
01399 if ( !$mutex->steal() )
01400 {
01401 eZDebug::writeWarning( "Failed to steal lock for file $fileName/$aliasName from PID $oldPid" );
01402 return false;
01403 }
01404 $mutex->setMeta( 'pid', getmypid() );
01405 return true;
01406 }
01407 }
01408
01409
01410
01411
01412
01413
01414 function _freeExclusiveLock( $fileName, $aliasName )
01415 {
01416 $mutex =& $this->_mutex( "{$fileName}-{$aliasName}" );
01417 $mutex->unlock();
01418 }
01419
01420
01421
01422
01423 function &_mutex( $fname = false )
01424 {
01425 if ( $this->Mutex !== null )
01426 {
01427 return $this->Mutex;
01428 }
01429 include_once( 'lib/ezutils/classes/ezmutex.php' );
01430 $this->Mutex = new eZMutex( $fname );
01431 return $this->Mutex;
01432 }
01433
01434
01435 var $ImageHandlers;
01436 var $OutputMIME;
01437 var $OutputMIMEMap;
01438 var $Rules;
01439 var $DefaultRule;
01440 var $RuleMap;
01441 var $MIMETypes;
01442 var $Types = array();
01443
01444
01445
01446
01447
01448
01449 var $Mutex;
01450
01451
01452
01453
01454
01455
01456
01457 var $lockTimeout;
01458
01459 }
01460
01461 ?>