|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZImageAliasHandler class 00004 // 00005 // Created on: <16-Oct-2003 09:34:25 bf> 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 /*! 00032 \class eZImageAliasHandler ezimagealiashandler.php 00033 \ingroup eZDatatype 00034 \brief Internal manager for the eZImage datatype 00035 00036 Takes care of image conversion and serialization from and to 00037 the internal XML format. 00038 00039 \note This handler was introduced in eZ Publish 3.3 and will detect older 00040 eZImage structures and convert them on the fly. 00041 00042 \note The XML storage was improved in 3.8, from then it always stores the 00043 attribute ID, version and language in the <original> tag. 00044 This was required to get the new multi-language features to work. 00045 */ 00046 00047 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00048 //include_once( 'lib/ezfile/classes/ezfilehandler.php' ); 00049 //include_once( "kernel/classes/datatypes/ezimage/ezimagefile.php" ); 00050 00051 class eZImageAliasHandler 00052 { 00053 /*! 00054 Creates the handler and creates a reference to the contentobject attribute that created it. 00055 */ 00056 function eZImageAliasHandler( $contentObjectAttribute ) 00057 { 00058 $this->ContentObjectAttributeData = array(); 00059 if ( is_object( $contentObjectAttribute ) ) 00060 { 00061 $this->ContentObjectAttributeData['id'] = $contentObjectAttribute->attribute( 'id' ); 00062 $this->ContentObjectAttributeData['contentobject_id'] = $contentObjectAttribute->attribute( 'contentobject_id' ); 00063 $this->ContentObjectAttributeData['version'] = $contentObjectAttribute->attribute( 'version' ); 00064 $this->ContentObjectAttributeData['language_code'] = $contentObjectAttribute->attribute( 'language_code' ); 00065 $this->ContentObjectAttributeData['can_translate'] = $contentObjectAttribute->attribute( 'can_translate' ); 00066 $this->ContentObjectAttributeData['data_text'] = $contentObjectAttribute->attribute( 'data_text' ); 00067 $this->ContentObjectAttributeData['DataTypeCustom'] = $contentObjectAttribute->DataTypeCustom; 00068 if ( !is_array( $this->ContentObjectAttributeData['DataTypeCustom'] ) ) 00069 { 00070 $this->ContentObjectAttributeData['DataTypeCustom'] = array(); 00071 } 00072 } 00073 else 00074 { 00075 eZDebug::writeWarning( 'Invalid eZContentObjectAttribute', 'eZImageAliasHandler::eZImageAliasHandler' ); 00076 } 00077 } 00078 00079 /*! 00080 Lists all available image aliases as attributes as well as: 00081 - alternative_text - The alternative text input by the user, can be empty 00082 - original_filename - The name of image which it had on the users disk before it was uploaded 00083 - is_valid - A boolean which says if there is an image here or not. 00084 */ 00085 function attributes() 00086 { 00087 require_once( 'kernel/common/image.php' ); 00088 $imageManager = imageInit(); 00089 $aliasList = $imageManager->aliasList(); 00090 return array_merge( array( 'alternative_text', 00091 'original_filename', 00092 'is_valid' ), 00093 array_keys( $aliasList ) ); 00094 } 00095 00096 /*! 00097 \return true if the attribute named \a $attributeName exists. 00098 See eZImageAliasHandler::attributes() for which attributes are available. 00099 */ 00100 function hasAttribute( $attributeName ) 00101 { 00102 if ( in_array( $attributeName, 00103 array( 'alternative_text', 00104 'original_filename', 00105 'is_valid' ) ) ) 00106 return true; 00107 require_once( 'kernel/common/image.php' ); 00108 $imageManager = imageInit(); 00109 if ( $imageManager->hasAlias( $attributeName ) ) 00110 return true; 00111 return false; 00112 } 00113 00114 /*! 00115 \return the value of the attribute named \a $attributeName. 00116 See eZImageAliasHandler::attributes() for which attributes are available. 00117 */ 00118 function attribute( $attributeName ) 00119 { 00120 if ( in_array( $attributeName, 00121 array( 'alternative_text', 00122 'original_filename', 00123 'is_valid' ) ) ) 00124 { 00125 return $this->attributeFromOriginal( $attributeName ); 00126 } 00127 $aliasName = $attributeName; 00128 return $this->imageAlias( $aliasName ); 00129 } 00130 00131 /*! 00132 \return The value of the attribute named \a $attributeName from the 'original' image alias. 00133 00134 This is a quick way for extracting information from the 'original' image alias. 00135 */ 00136 function &attributeFromOriginal( $attributeName ) 00137 { 00138 $originalAlias = $this->attribute( 'original' ); 00139 if ( $originalAlias ) 00140 return $originalAlias[$attributeName]; 00141 $retValue = null; 00142 return $retValue; 00143 } 00144 00145 /*! 00146 Sets the attribute named \a $attributeName to have the value \a $attributeValue. 00147 00148 The following attributes can be set: 00149 - alternative text 00150 - original_filename 00151 */ 00152 function setAttribute( $attributeName, $attributeValue ) 00153 { 00154 if ( in_array( $attributeName, 00155 array( 'alternative_text', 00156 'original_filename' ) ) ) 00157 { 00158 $aliasList = $this->aliasList(); 00159 foreach ( array_keys( $aliasList ) as $aliasName ) 00160 { 00161 $this->setAliasAttribute( $aliasName, $attributeName, $attributeValue ); 00162 } 00163 if ( $attributeName == 'alternative_text' ) 00164 { 00165 $text = $this->displayText( $attributeValue ); 00166 foreach ( array_keys( $aliasList ) as $aliasName ) 00167 { 00168 $this->setAliasAttribute( $aliasName, 'text', $text ); 00169 } 00170 } 00171 $this->recreateDOMTree(); 00172 $this->setStorageRequired(); 00173 return true; 00174 } 00175 return false; 00176 } 00177 00178 /*! 00179 \return \c true if this is considered to be owner of the image. 00180 00181 It will be considered an owner if attribute data is not a copy 00182 of another attribute. For instance each time a new image is uploaded 00183 this will return \c true. 00184 */ 00185 function isImageOwner() 00186 { 00187 $originalData = $this->originalAttributeData(); 00188 return ( $originalData['attribute_id'] == false || 00189 ( $originalData['attribute_id'] == $this->ContentObjectAttributeData['id'] && 00190 $originalData['attribute_version'] == $this->ContentObjectAttributeData['version'] && 00191 $originalData['attribute_language'] == $this->ContentObjectAttributeData['language_code'] ) ); 00192 } 00193 00194 /*! 00195 \return The current serial number, the value will be 1 or higher. 00196 00197 The serial number is used to create unique filenames for uploaded images, 00198 it will be increased each time an image is uploaded. 00199 00200 00201 \note This was required to get around the problem where browsers 00202 caches image information, if two images were uploaded in one version (e.g. a draft) 00203 the browser would not load the new image since it thought it had not changed. 00204 */ 00205 function imageSerialNumber() 00206 { 00207 $serialNumber = $this->imageSerialNumberRaw(); 00208 if ( $serialNumber < 1 ) 00209 { 00210 $serialNumber = 1; 00211 } 00212 return $serialNumber; 00213 } 00214 00215 /*! 00216 Increases the serial by one. 00217 */ 00218 function increaseImageSerialNumber() 00219 { 00220 $this->setImageSerialNumber( $this->imageSerialNumberRaw() + 1 ); 00221 } 00222 00223 /*! 00224 Resets the serial number to zero. 00225 */ 00226 function resetImageSerialNumber() 00227 { 00228 $this->setImageSerialNumber( 0 ); 00229 } 00230 00231 /*! 00232 \return A text string which can be used as display for the image. 00233 00234 The text string will either contain the alternative text from the attribute 00235 or the parameter \a $alternativeText if it is set. 00236 */ 00237 function displayText( $alternativeText = null ) 00238 { 00239 if ( $alternativeText === null ) 00240 $text = $this->attribute( 'alternative_text' ); 00241 else 00242 $text = $alternativeText; 00243 00244 return $text; 00245 } 00246 00247 /*! 00248 \return The full directory path to the image, this includes the var and storage directory. 00249 */ 00250 function directoryPath() 00251 { 00252 $aliasList = $this->aliasList(); 00253 if ( isset( $aliasList['original'] ) ) 00254 { 00255 return $aliasList['original']['dirpath']; 00256 } 00257 return false; 00258 } 00259 00260 /*! 00261 \return A normalized name for the image. 00262 00263 The image name will generated from the name of the current version. 00264 If this is empty it will use the object name or the alternative text. 00265 00266 This ensures that the image has a name which corresponds to the object it belongs to. 00267 00268 The normalization ensures that the name only contains filename and URL friendly characters. 00269 */ 00270 function imageName( $contentObjectAttribute, $contentVersion, $language = false ) 00271 { 00272 if ( $language === false ) 00273 { 00274 if ( is_object( $contentObjectAttribute ) ) // for backward compatibility when eZImageAliasHandler used $this->contentObjectAttribute 00275 { 00276 $language = $contentObjectAttribute->attribute( 'language_code' ); 00277 } 00278 else 00279 { 00280 $language = $contentObjectAttribute['language_code']; 00281 } 00282 } 00283 $objectName = $contentVersion->versionName( $language ); 00284 if ( !$objectName ) 00285 { 00286 $objectName = $contentVersion->name( $language ); 00287 if ( !$objectName ) 00288 { 00289 $objectName = $this->attribute( 'alternative_text' ); 00290 if ( !$objectName ) 00291 { 00292 $objectName = ezi18n( 'kernel/classes/datatypes', 'image', 'Default image name' ); 00293 } 00294 } 00295 } 00296 $objectName = eZImageAliasHandler::normalizeImageName( $objectName ); 00297 $objectName .= $this->imageSerialNumber(); 00298 00299 return $objectName; 00300 } 00301 00302 /*! 00303 \return A normalized name for the image based on a node. 00304 00305 Similar to \a imageName() but fetches name information from the node \a $mainNode. 00306 00307 The normalization ensures that the name only contains filename and URL friendly characters. 00308 */ 00309 function imageNameByNode( $contentObjectAttribute, $mainNode, $language = false ) 00310 { 00311 if ( $language === false ) 00312 { 00313 if ( is_object( $contentObjectAttribute ) ) // for backward compatibility when eZImageAliasHandler used $this->contentObjectAttribute 00314 { 00315 $language = $contentObjectAttribute->attribute( 'language_code' ); 00316 } 00317 else 00318 { 00319 $language = $contentObjectAttribute['language_code']; 00320 } 00321 } 00322 $objectName = $mainNode->getName( $language ); 00323 if ( !$objectName ) 00324 { 00325 $objectName = $this->attribute( 'alternative_text' ); 00326 if ( !$objectName ) 00327 { 00328 $objectName = ezi18n( 'kernel/classes/datatypes', 'image', 'Default image name' ); 00329 } 00330 } 00331 $objectName = eZImageAliasHandler::normalizeImageName( $objectName ); 00332 return $objectName; 00333 } 00334 00335 /*! 00336 \return The storage path for the image. 00337 00338 The path is calculated by using information from the current object and version. 00339 If the object is in the node tree it will contain a path that matches the node path, 00340 if not it will be placed in the versioned storage repository. 00341 */ 00342 function imagePath( $contentObjectAttribute, $contentVersion, $isImageOwner = null ) 00343 { 00344 $useVersion = false; 00345 if ( $isImageOwner === null ) 00346 $isImageOwner = $this->isImageOwner(); 00347 if ( $contentVersion->attribute( 'status' ) == eZContentObjectVersion::STATUS_PUBLISHED or 00348 !$isImageOwner ) 00349 { 00350 $contentObject = $contentVersion->attribute( 'contentobject' ); 00351 $mainNode = $contentObject->attribute( 'main_node' ); 00352 if ( !$mainNode ) 00353 { 00354 $ini = eZINI::instance( 'image.ini' ); 00355 $contentImageSubtree = $ini->variable( 'FileSettings', 'VersionedImages' ); 00356 $pathString = $contentImageSubtree; 00357 $useVersion = true; 00358 } 00359 else 00360 { 00361 $ini = eZINI::instance( 'image.ini' ); 00362 $contentImageSubtree = $ini->variable( 'FileSettings', 'PublishedImages' ); 00363 $pathString = $mainNode->pathWithNames(); 00364 $pathString = function_exists( 'mb_strtolower' ) ? mb_strtolower( $pathString ) : strtolower( $pathString ); 00365 $pathString = $contentImageSubtree . '/' . $pathString; 00366 } 00367 } 00368 else 00369 { 00370 $ini = eZINI::instance( 'image.ini' ); 00371 $contentImageSubtree = $ini->variable( 'FileSettings', 'VersionedImages' ); 00372 $pathString = $contentImageSubtree; 00373 $useVersion = true; 00374 } 00375 $attributeData = $this->originalAttributeData(); 00376 $attributeID = $attributeData['attribute_id']; 00377 $attributeVersion = $attributeData['attribute_version']; 00378 $attributeLanguage = $attributeData['attribute_language']; 00379 if ( $useVersion ) 00380 $identifierString = $attributeID . '/' . $attributeVersion . '-' . $attributeLanguage; 00381 else 00382 $identifierString = $attributeID . '-' . $attributeVersion . '-' . $attributeLanguage; 00383 $imagePath = eZSys::storageDirectory() . '/' . $pathString . '/' . $identifierString; 00384 return $imagePath; 00385 } 00386 00387 /*! 00388 \return The storage path for the image based on a node. 00389 00390 Similar to \a imagePath() but fetches name information from the node \a $mainNode. 00391 */ 00392 function imagePathByNode( $contentObjectAttribute, $mainNode ) 00393 { 00394 $pathString = $mainNode->pathWithNames(); 00395 $pathString = function_exists( 'mb_strtolower' ) ? mb_strtolower( $pathString ) : strtolower( $pathString ); 00396 00397 $ini = eZINI::instance( 'image.ini' ); 00398 $contentImageSubtree = $ini->variable( 'FileSettings', 'PublishedImages' ); 00399 $attributeData = $this->originalAttributeData(); 00400 $attributeID = $attributeData['attribute_id']; 00401 $attributeVersion = $attributeData['attribute_version']; 00402 $attributeLanguage = $attributeData['attribute_language']; 00403 $pathParts = array( eZSys::storageDirectory(), $contentImageSubtree ); 00404 if ( $pathString != '' ) 00405 { 00406 $pathParts[] = $pathString; 00407 } 00408 $pathParts[] = $attributeID . '-' . $attributeVersion . '-' . $attributeLanguage; 00409 $imagePath = implode( '/', $pathParts ); 00410 return $imagePath; 00411 } 00412 00413 /*! 00414 \return The image alias structure for the alias named \a $aliasName. 00415 00416 This will create the image alias if it does not exist yet, this can involve 00417 running image operations to for instance scale the image. 00418 */ 00419 function imageAlias( $aliasName ) 00420 { 00421 require_once( 'kernel/common/image.php' ); 00422 $imageManager = imageInit(); 00423 if ( !$imageManager->hasAlias( $aliasName ) ) 00424 { 00425 return null; 00426 } 00427 00428 $aliasList = $this->aliasList(); 00429 if ( array_key_exists( $aliasName, $aliasList ) ) 00430 { 00431 return $aliasList[$aliasName]; 00432 } 00433 else 00434 { 00435 $imageManager = imageInit(); 00436 if ( $imageManager->hasAlias( $aliasName ) ) 00437 { 00438 $original = $aliasList['original']; 00439 $basename = $original['basename']; 00440 if ( $imageManager->createImageAlias( $aliasName, $aliasList, 00441 array( 'basename' => $basename ) ) ) 00442 { 00443 $text = $this->displayText( $original['alternative_text'] ); 00444 $originalFilename = $original['original_filename']; 00445 foreach ( $aliasList as $aliasKey => $alias ) 00446 { 00447 $alias['original_filename'] = $originalFilename; 00448 $alias['text'] = $text; 00449 if ( $alias['url'] ) 00450 { 00451 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00452 $aliasFile = eZClusterFileHandler::instance( $alias['url'] ); 00453 if( $aliasFile->exists() ) 00454 $alias['filesize'] = $aliasFile->size(); 00455 } 00456 if ( $alias['is_new'] ) 00457 { 00458 eZImageFile::appendFilepath( $this->ContentObjectAttributeData['id'], $alias['url'] ); 00459 } 00460 $aliasList[$aliasKey] = $alias; 00461 } 00462 $this->setAliasList( $aliasList ); 00463 $this->addImageAliases( $aliasList ); 00464 $aliasList = $this->aliasList(); 00465 return $aliasList[$aliasName]; 00466 } 00467 } 00468 } 00469 00470 return null; 00471 } 00472 00473 /*! 00474 Set alias list. Set alias list to current object 00475 00476 \param alias list 00477 */ 00478 protected function setAliasList( $aliasList ) 00479 { 00480 $this->ContentObjectAttributeData['DataTypeCustom']['alias_list'] = $aliasList; 00481 } 00482 00483 /* 00484 Set alias variation 00485 00486 \param alias name 00487 \param variation array 00488 */ 00489 protected function setAliasVariation( $aliasName, $variation ) 00490 { 00491 $this->ContentObjectAttributeData['DataTypeCustom']['alias_list'][$aliasName] = $variation; 00492 } 00493 00494 /*! 00495 Set alias value. 00496 00497 \param alias name 00498 \param attribute name 00499 \param attribute value 00500 */ 00501 protected function setAliasAttribute( $aliasName, $attributeName, $value ) 00502 { 00503 $this->ContentObjectAttributeData['DataTypeCustom']['alias_list'][$aliasName][$attributeName] = $value; 00504 } 00505 00506 /*! 00507 \private 00508 \return A list of aliases structures for the current attribute.ezxml 00509 00510 The first this is called the XML data will be parsed into the internal 00511 structures. Subsequent calls will simply return the internal structure. 00512 */ 00513 function aliasList() 00514 { 00515 if ( isset( $this->ContentObjectAttributeData['DataTypeCustom']['alias_list'] ) ) 00516 { 00517 return $this->ContentObjectAttributeData['DataTypeCustom']['alias_list']; 00518 } 00519 00520 eZDebug::accumulatorStart('imageparse', 'XML', 'Image XML parsing' ); 00521 00522 $domTree = new DOMDocument( '1.0', 'utf-8' ); 00523 00524 $xmlString = $this->ContentObjectAttributeData['data_text']; 00525 00526 $success = false; 00527 if ( $xmlString != '' ) 00528 { 00529 $success = $domTree->loadXML( $xmlString ); 00530 } 00531 00532 if ( !$success ) 00533 { 00534 $this->generateXMLData(); 00535 $xmlString = $this->ContentObjectAttributeData['data_text']; 00536 $success = $domTree->loadXML( $xmlString ); 00537 } 00538 00539 $this->ContentObjectAttributeData['DataTypeCustom']['dom_tree'] = $domTree; 00540 $imageNodeArray = $domTree->getElementsByTagName( "ezimage" ); 00541 00542 $aliasList = array(); 00543 00544 // I think this is a bug in the plain package or related to the bug I filed 00545 // about the image datatype serialization 00546 // http://ez.no/bugs/view/8821 ezpm Error: (eZFileHandler::copy) Unable to open source file in read mode 00547 if ( $imageNodeArray->length == 0 ) 00548 { 00549 return $aliasList; 00550 } 00551 00552 $imageNode = $imageNodeArray->item( 0 ); 00553 00554 $imageInfoNodeArray = $imageNode->getElementsByTagName( "information" ); 00555 $imageVariationNodeArray = $imageNode->getElementsByTagName( "alias" ); 00556 $imageOriginalArray = $imageNode->getElementsByTagName( "original" ); 00557 00558 $aliasEntry = array(); 00559 00560 $alternativeText = $imageNode->getAttribute( 'alternative_text' ); 00561 $originalFilename = $imageNode->getAttribute( 'original_filename' ); 00562 $basename = $imageNode->getAttribute( 'basename' ); 00563 $displayText = $this->displayText( $alternativeText ); 00564 00565 $originalData = array( 'attribute_id' => '', 00566 'attribute_version' => '', 00567 'attribute_language' => '' ); 00568 if ( $imageOriginalArray->length > 0 ) 00569 { 00570 $imageOriginalNode = $imageOriginalArray->item( 0 ); 00571 $originalData = array( 'attribute_id' => $imageOriginalNode->getAttribute( 'attribute_id' ), 00572 'attribute_version' => $imageOriginalNode->getAttribute( 'attribute_version' ), 00573 'attribute_language' => $imageOriginalNode->getAttribute( 'attribute_language' ) ); 00574 } 00575 if ( strlen( $originalData['attribute_id'] ) == 0 || 00576 strlen( $originalData['attribute_version'] ) == 0 || 00577 strlen( $originalData['attribute_language'] ) == 0 ) 00578 { 00579 $originalData = array( 'attribute_id' => $this->ContentObjectAttributeData['id'], 00580 'attribute_version' => $this->ContentObjectAttributeData['version'], 00581 'attribute_language' => $this->ContentObjectAttributeData['language_code'] ); 00582 } 00583 $this->setOriginalAttributeData( $originalData ); 00584 00585 $aliasEntry['name'] = 'original'; 00586 $aliasEntry['width'] = $imageNode->getAttribute( 'width' ); 00587 $aliasEntry['height'] = $imageNode->getAttribute( 'height' ); 00588 $aliasEntry['mime_type'] = $imageNode->getAttribute( 'mime_type' ); 00589 $aliasEntry['filename'] = $imageNode->getAttribute( 'filename' ); 00590 $aliasEntry['suffix'] = $imageNode->getAttribute( 'suffix' ); 00591 $aliasEntry['dirpath'] = $imageNode->getAttribute( 'dirpath' ); 00592 $aliasEntry['basename'] = $basename; 00593 $aliasEntry['alternative_text'] = $alternativeText; 00594 $aliasEntry['text'] = $displayText; 00595 $aliasEntry['original_filename'] = $originalFilename; 00596 $aliasEntry['url'] = $imageNode->getAttribute( 'url' ); 00597 $aliasEntry['alias_key'] = $imageNode->getAttribute( 'alias_key' ); 00598 $aliasEntry['timestamp'] = $imageNode->getAttribute( 'timestamp' ); 00599 $aliasEntry['full_path'] = $aliasEntry['url']; 00600 $aliasEntry['is_valid'] = $imageNode->getAttribute( 'is_valid' ); 00601 $aliasEntry['is_new'] = false; 00602 $aliasEntry['filesize'] = false; 00603 00604 if ( $aliasEntry['url'] ) 00605 { 00606 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00607 $aliasFile = eZClusterFileHandler::instance( $aliasEntry['url'] ); 00608 00609 if ( $aliasFile->exists() ) 00610 $aliasEntry['filesize'] = $aliasFile->size(); 00611 } 00612 00613 $imageInformation = false; 00614 if ( $imageInfoNodeArray->length > 0 ) 00615 { 00616 $imageInfoNode = $imageInfoNodeArray->item( 0 ); 00617 $imageInformation = $this->parseInformationNode( $imageInfoNode ); 00618 } 00619 $aliasEntry['info'] = $imageInformation; 00620 00621 $serialNumber = $imageNode->getAttribute( 'serial_number' ); 00622 if ( $serialNumber ) 00623 { 00624 $this->setImageSerialNumber( $serialNumber ); 00625 } 00626 00627 $aliasList['original'] = $aliasEntry; 00628 00629 if ( $imageVariationNodeArray->length > 0 ) 00630 { 00631 foreach ( $imageVariationNodeArray as $imageVariation ) 00632 { 00633 $aliasEntry = array(); 00634 $aliasEntry['name'] = $imageVariation->getAttribute( 'name' ); 00635 $aliasEntry['width'] = $imageVariation->getAttribute( 'width' ); 00636 $aliasEntry['height'] = $imageVariation->getAttribute( 'height' ); 00637 $aliasEntry['mime_type'] = $imageVariation->getAttribute( 'mime_type' ); 00638 $aliasEntry['filename'] = $imageVariation->getAttribute( 'filename' ); 00639 $aliasEntry['suffix'] = $imageVariation->getAttribute( 'suffix' ); 00640 $aliasEntry['dirpath'] = $imageVariation->getAttribute( 'dirpath' ); 00641 $aliasEntry['alias_key'] = $imageVariation->getAttribute( 'alias_key' ); 00642 $aliasEntry['timestamp'] = $imageVariation->getAttribute( 'timestamp' ); 00643 $aliasEntry['is_valid'] = $imageVariation->getAttribute( 'is_valid' ); 00644 $aliasEntry['url'] = $imageVariation->getAttribute( 'url' ); 00645 $aliasEntry['basename'] = $basename; 00646 $aliasEntry['alternative_text'] = $alternativeText; 00647 $aliasEntry['text'] = $displayText; 00648 $aliasEntry['original_filename'] = $originalFilename; 00649 $aliasEntry['full_path'] = $aliasEntry['url']; 00650 $aliasEntry['is_new'] = false; 00651 $aliasEntry['info'] = $imageInformation; 00652 00653 if ( $aliasEntry['url'] ) 00654 { 00655 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00656 $aliasFile = eZClusterFileHandler::instance( $aliasEntry['url'] ); 00657 00658 if ( $aliasFile->exists() ) 00659 $aliasEntry['filesize'] = $aliasFile->size(); 00660 } 00661 00662 require_once( 'kernel/common/image.php' ); 00663 $imageManager = imageInit(); 00664 if ( $imageManager->isImageAliasValid( $aliasEntry ) ) 00665 { 00666 $aliasList[$aliasEntry['name']] = $aliasEntry; 00667 } 00668 } 00669 } 00670 $this->setAliasList( $aliasList ); 00671 eZDebug::accumulatorStop( 'imageparse' ); 00672 return $aliasList; 00673 } 00674 00675 /** 00676 * Removes all image alias files which the attribute refers to. 00677 * 00678 * @param eZContentObjectAttribute 00679 * @note If you want to remove the alias information use removeAliases(). 00680 **/ 00681 static function removeAllAliases( $contentObjectAttribute ) 00682 { 00683 $handler = $contentObjectAttribute->attribute( 'content' ); 00684 if ( !$handler->isImageOwner() ) 00685 { 00686 return; 00687 } 00688 $attributeData = $handler->originalAttributeData(); 00689 $files = eZImageFile::fetchForContentObjectAttribute( $attributeData['attribute_id'], false ); 00690 $dirs = array(); 00691 00692 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00693 foreach ( $files as $filepath ) 00694 { 00695 $file = eZClusterFileHandler::instance( $filepath ); 00696 if ( $file->exists() ) 00697 { 00698 // FIXME: optimize not to use recursive delete 00699 $file->delete(); 00700 $dirs[] = eZDir::dirpath( $filepath ); 00701 } 00702 } 00703 $dirs = array_unique( $dirs ); 00704 foreach ( $dirs as $dirpath ) 00705 { 00706 eZDir::cleanupEmptyDirectories( $dirpath ); 00707 } 00708 eZImageFile::removeForContentObjectAttribute( $attributeData['attribute_id'] ); 00709 } 00710 00711 /** 00712 * Removes all the image aliases and their information. 00713 * The stored images will also be removed if the attribute is the owner 00714 * of the images. 00715 * 00716 * After the images are removed the attribute will containe an internal 00717 * structure with empty data 00718 * 00719 * @param eZContentObjectAttribute $contentObjectAttribute 00720 * Content object attribute to remove aliases for 00721 * 00722 * @return void 00723 **/ 00724 function removeAliases( $contentObjectAttribute ) 00725 { 00726 $aliasList = $this->aliasList(); 00727 $alternativeText = false; 00728 00729 $contentObjectAttributeVersion = $this->ContentObjectAttributeData['version']; 00730 $contentObjectAttributeID = $this->ContentObjectAttributeData['id']; 00731 00732 $isImageOwner = $this->isImageOwner(); 00733 00734 // We loop over each image alias, and look up the file in ezcontentobject_attribute 00735 // Only images referenced by one version will be removed 00736 foreach ( $aliasList as $aliasName => $alias ) 00737 { 00738 $dirpath = $alias['dirpath']; 00739 $doNotDelete = false; // Do not delete files from storage 00740 00741 if ( $aliasName == 'original' ) 00742 $alternativeText = $alias['alternative_text']; 00743 if ( $alias['is_valid'] ) 00744 { 00745 $filepath = $alias['url']; 00746 00747 // Fetch ezimage attributes that use $filepath 00748 // Always returns current attribute (array of $contentObjectAttributeID and $contentObjectAttributeVersion) 00749 $dbResult = eZImageFile::fetchImageAttributesByFilepath( $filepath, $contentObjectAttributeID ); 00750 $dbResultCount = count( $dbResult ); 00751 // Check if there are the attributes. 00752 if ( $dbResultCount > 0 ) 00753 { 00754 $doNotDelete = true; 00755 foreach ( $dbResult as $res ) 00756 { 00757 // We only look results where the version matches 00758 if ( $res['version'] == $contentObjectAttributeVersion ) 00759 { 00760 // If more than one result has been returned, it means 00761 // that another version is using the same image, 00762 // and we should not delete this file 00763 if ( $dbResultCount > 1 ) 00764 { 00765 continue; 00766 } 00767 // Only one result means that the current attribute 00768 // & version are the only ones using this image, 00769 // and it can be removed 00770 else 00771 { 00772 $doNotDelete = false; 00773 } 00774 } 00775 00776 eZImageFile::appendFilepath( $res['id'], $filepath, true ); 00777 } 00778 } 00779 00780 if ( !$doNotDelete ) 00781 { 00782 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00783 $file = eZClusterFileHandler::instance( $filepath ); 00784 if ( $file->exists() ) 00785 { 00786 $file->delete(); 00787 eZImageFile::removeFilepath( $contentObjectAttributeID, $filepath ); 00788 eZDir::cleanupEmptyDirectories( $dirpath ); 00789 } 00790 else 00791 { 00792 eZDebug::writeError( "Image file $filepath for alias $aliasName does not exist, could not remove from disk", 00793 'eZImageAliasHandler::removeAliases' ); 00794 } 00795 } 00796 } 00797 } 00798 00799 $doc = new DOMDocument( '1.0', 'utf-8' ); 00800 $imageNode = $doc->createElement( "ezimage" ); 00801 $doc->appendChild( $imageNode ); 00802 00803 $imageNode->setAttribute( 'serial_number', false ); 00804 $imageNode->setAttribute( 'is_valid', false ); 00805 $imageNode->setAttribute( 'filename', false ); 00806 $imageNode->setAttribute( 'suffix', false ); 00807 $imageNode->setAttribute( 'basename', false ); 00808 $imageNode->setAttribute( 'dirpath', false ); 00809 $imageNode->setAttribute( 'url', false ); 00810 $imageNode->setAttribute( 'original_filename', false ); 00811 $imageNode->setAttribute( 'mime_type', false ); 00812 $imageNode->setAttribute( 'width', false ); 00813 $imageNode->setAttribute( 'height', false ); 00814 $imageNode->setAttribute( 'alternative_text', $alternativeText ); 00815 $imageNode->setAttribute( 'alias_key', false ); 00816 $imageNode->setAttribute( 'timestamp', false ); 00817 00818 $this->ContentObjectAttributeData['DataTypeCustom']['dom_tree'] = $doc; 00819 unset( $this->ContentObjectAttributeData['DataTypeCustom']['alias_list'] ); 00820 00821 $this->storeDOMTree( $doc, true, $contentObjectAttribute ); 00822 } 00823 00824 /*! 00825 Will update the path for images to point to the new path \a $dirpath and filename \a $name. 00826 00827 This is usually called when the object contain the image attribute is moved in the tree. 00828 */ 00829 function updateAliasPath( $dirpath, $name ) 00830 { 00831 if ( !file_exists( $dirpath ) ) 00832 { 00833 eZDir::mkdir( $dirpath, false, true ); 00834 } 00835 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 00836 $aliasList = $this->aliasList(); 00837 $this->resetImageSerialNumber(); 00838 00839 foreach ( $aliasList as $aliasName => $alias ) 00840 { 00841 if ( $alias['dirpath'] != $dirpath ) 00842 { 00843 $oldDirpath = $alias['url']; 00844 $oldURL = $alias['url']; 00845 $basename = $name; 00846 if ( $aliasName != 'original' ) 00847 $basename .= '_' . $aliasName; 00848 eZMimeType::changeFileData( $alias, $dirpath, $basename ); 00849 $alias['full_path'] = $alias['url']; 00850 if ( $this->isImageOwner() ) 00851 { 00852 if ( $oldURL == '' ) 00853 { 00854 continue; 00855 } 00856 00857 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00858 $fileHandler = eZClusterFileHandler::instance(); 00859 $fileHandler->fileMove( $oldURL, $alias['url'] ); 00860 00861 eZDir::cleanupEmptyDirectories( $oldDirpath ); 00862 eZImageFile::moveFilepath( $this->ContentObjectAttributeData['id'], $oldURL, $alias['url'] ); 00863 } 00864 else 00865 { 00866 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00867 $fileHandler = eZClusterFileHandler::instance(); 00868 $fileHandler->fileLinkCopy( $oldURL, $alias['url'], false ); 00869 eZImageFile::appendFilepath( $this->ContentObjectAttributeData['id'], $alias['url'] ); 00870 } 00871 $this->setAliasVariation( $aliasName, $alias ); 00872 } 00873 } 00874 00875 $this->recreateDOMTree(); 00876 $this->setStorageRequired(); 00877 } 00878 00879 /*! 00880 \private 00881 Creates XML attributes containing information on the original image attribute. 00882 00883 The new attributes will be appended to \a $originalNode. 00884 */ 00885 function createOriginalAttributeXMLData( $originalNode, $originalData ) 00886 { 00887 $originalNode->setAttribute( 'attribute_id', $originalData['attribute_id'] ); 00888 $originalNode->setAttribute( 'attribute_version', $originalData['attribute_version'] ); 00889 $originalNode->setAttribute( 'attribute_language', $originalData['attribute_language'] ); 00890 } 00891 00892 /*! 00893 \private 00894 Recreates the DOM tree from the internal array structures and stores the DOM tree 00895 in the 'data_text' field of the attribute. 00896 */ 00897 function recreateDOMTree() 00898 { 00899 $aliasList = $this->aliasList(); 00900 $doc = new DOMDocument( '1.0', 'utf-8' ); 00901 $imageNode = $doc->createElement( "ezimage" ); 00902 $doc->appendChild( $imageNode ); 00903 00904 $originalNode = $doc->createElement( "original" ); 00905 $imageNode->appendChild( $originalNode ); 00906 00907 require_once( 'kernel/common/image.php' ); 00908 $imageManager = imageInit(); 00909 00910 $aliasName = 'original'; 00911 00912 $originalData = $this->originalAttributeData(); 00913 $this->createOriginalAttributeXMLData( $originalNode, $originalData ); 00914 00915 $imageNode->setAttribute( 'serial_number', $this->imageSerialNumber() ); 00916 $imageNode->setAttribute( 'is_valid', $aliasList[$aliasName]['is_valid'] ); 00917 $imageNode->setAttribute( 'filename', $aliasList[$aliasName]['filename'] ); 00918 $imageNode->setAttribute( 'suffix', $aliasList[$aliasName]['suffix'] ); 00919 $imageNode->setAttribute( 'basename', $aliasList[$aliasName]['basename'] ); 00920 $imageNode->setAttribute( 'dirpath', $aliasList[$aliasName]['dirpath'] ); 00921 $imageNode->setAttribute( 'url', $aliasList[$aliasName]['url'] ); 00922 $imageNode->setAttribute( 'original_filename', $aliasList[$aliasName]['original_filename'] ); 00923 $imageNode->setAttribute( 'mime_type', $aliasList[$aliasName]['mime_type'] ); 00924 $imageNode->setAttribute( 'width', $aliasList[$aliasName]['width'] ); 00925 $imageNode->setAttribute( 'height', $aliasList[$aliasName]['height'] ); 00926 $imageNode->setAttribute( 'alternative_text', $aliasList[$aliasName]['alternative_text'] ); 00927 $imageNode->setAttribute( 'alias_key', $imageManager->createImageAliasKey( $imageManager->alias( $aliasName ) ) ); 00928 $imageNode->setAttribute( 'timestamp', $aliasList[$aliasName]['timestamp'] ); 00929 00930 $filename = $aliasList[$aliasName]['url']; 00931 if ( $filename ) 00932 { 00933 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00934 $imageFile = eZClusterFileHandler::instance( $filename ); 00935 00936 $fetchedFilePath = $imageFile->fetchUnique(); 00937 00938 //(Cluster) Get mime data of real file, and fetch info by image analizer. 00939 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 00940 $mimeDataTemp = eZMimeType::findByFileContents( $fetchedFilePath ); 00941 $imageManager->analyzeImage( $mimeDataTemp ); 00942 00943 //(Cluster) Get mime data of a file which does not really exist on file system. We need this to build correct imageInformationNode. 00944 $mimeData = eZMimeType::findByURL( $filename ); 00945 if ( isset( $mimeDataTemp['info'] ) ) 00946 $mimeData['info'] = $mimeDataTemp['info']; 00947 00948 $this->createImageInformationNode( $imageNode, $mimeData ); 00949 $imageFile->fileDeleteLocal( $fetchedFilePath ); 00950 } 00951 00952 foreach ( $aliasList as $aliasName => $alias ) 00953 { 00954 if ( $aliasName == 'original' ) 00955 continue; 00956 $this->addImageAliasToXML( $doc, $alias ); 00957 } 00958 00959 $this->setDOMTree( $doc ); 00960 } 00961 00962 /*! 00963 \return the DOM tree for the current content object attribute. 00964 \note It will cache the result in the DataTypeCustom member variable of the 00965 content object attribute in the 'dom_tree' key. 00966 */ 00967 function domTree() 00968 { 00969 $contentObjectAttributeData = $this->ContentObjectAttributeData; 00970 if ( isset( $contentObjectAttributeData['DataTypeCustom']['dom_tree'] ) ) 00971 { 00972 return $contentObjectAttributeData['DataTypeCustom']['dom_tree']; 00973 } 00974 00975 $dom = new DOMDocument( '1.0', 'utf-8' ); 00976 $xmlString = $contentObjectAttributeData['data_text']; 00977 $success = $xmlString == '' ? false : $dom->loadXML( $xmlString ); 00978 if ( !$success ) 00979 { 00980 $this->generateXMLData(); 00981 $xmlString = $this->ContentObjectAttributeData['data_text']; 00982 $success = $dom->loadXML( $xmlString ); 00983 } 00984 00985 $contentObjectAttributeData['DataTypeCustom']['dom_tree'] = $dom; 00986 00987 return $dom; 00988 } 00989 00990 /*! 00991 \private 00992 Parses the information node and generates the internal information structures. 00993 00994 The information node contains information from the image itself, for instance 00995 EXIF data from a JPEG or TIFF image. 00996 00997 \param $imageInfoNode 00998 00999 \return $imageInformation array 01000 */ 01001 function parseInformationNode( $imageInfoNode ) 01002 { 01003 $imageInformation = array(); 01004 01005 $attributes = $imageInfoNode->attributes; 01006 foreach ( $attributes as $attribute ) 01007 { 01008 $imageInformation[$attribute->name] = $attribute->value; 01009 } 01010 01011 $children = $imageInfoNode->childNodes; 01012 foreach ( $children as $child ) 01013 { 01014 if ( $child->nodeType != XML_ELEMENT_NODE ) 01015 { 01016 continue; 01017 } 01018 01019 $childName = false; 01020 if ( isset ( $child->localName ) ) 01021 { 01022 $childName = $child->localName; 01023 } 01024 01025 if ( $childName == 'array' ) 01026 { 01027 $name = $child->getAttribute( 'name' ); 01028 $items = $child->getElementsByTagName( 'item' ); 01029 $array = array(); 01030 foreach ( $items as $item ) 01031 { 01032 $itemValue = $item->textContent; 01033 if ( $item->getAttribute( 'base64' ) == '1' ) 01034 { 01035 $array[$item->getAttribute( 'key' )] = base64_decode( $itemValue ); 01036 } 01037 else 01038 { 01039 $array[$item->getAttribute( 'key' )] = $itemValue; 01040 } 01041 } 01042 ksort( $array ); 01043 $imageInformation[$name] = $array; 01044 } 01045 else if ( $childName == 'serialized' ) 01046 { 01047 $name = $child->getAttribute( 'name' ); 01048 $data = $child->getAttribute( 'data' ); 01049 $imageInformation[$name] = unserialize( $data ); 01050 } 01051 } 01052 01053 return $imageInformation; 01054 } 01055 01056 /*! 01057 \static 01058 Normalized the image name \a $imageName by removing all characters that are not considered 01059 filename or URL friendly. 01060 The filename will also be in non-capital letters. 01061 */ 01062 function normalizeImageName( $imageName ) 01063 { 01064 // Initialize transformation system 01065 //include_once( 'lib/ezi18n/classes/ezchartransform.php' ); 01066 $trans = eZCharTransform::instance(); 01067 01068 $imageName = eZURLAliasML::convertToAlias( $imageName ); 01069 return $imageName; 01070 } 01071 01072 /*! 01073 Sets the uploaded HTTP file object to \a $httpFile. 01074 This object is used to store information about the image file until the content object attribute is to be stored. 01075 \sa httpFile 01076 */ 01077 function setHTTPFile( $httpFile ) 01078 { 01079 $this->ContentObjectAttributeData['DataTypeCustom']['http_file'] = $httpFile; 01080 } 01081 01082 /*! 01083 \return the stored HTTP file object or \c false if no object is previously stored. 01084 \sa setHTTPFile 01085 */ 01086 function httpFile( $release = false ) 01087 { 01088 if ( isset( $this->ContentObjectAttributeData['DataTypeCustom']['http_file'] ) ) 01089 { 01090 $httpFile = $this->ContentObjectAttributeData['DataTypeCustom']['http_file']; 01091 if ( $release ) 01092 { 01093 unset( $this->ContentObjectAttributeData['DataTypeCustom']['http_file'] ); 01094 } 01095 return $httpFile; 01096 } 01097 01098 return false; 01099 } 01100 01101 /*! 01102 Initializes the content object attribute \a $contentObjectAttribute with the uploaded HTTP file \a $httpFile. 01103 Optionally you may also specify the alternative text in the parameter \a $imageAltText. 01104 */ 01105 function initializeFromHTTPFile( $httpFile, $imageAltText = false ) 01106 { 01107 $this->increaseImageSerialNumber(); 01108 01109 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 01110 $mimeData = eZMimeType::findByFileContents( $httpFile->attribute( 'filename' ) ); 01111 if ( !$mimeData['is_valid'] ) 01112 { 01113 $mimeData = eZMimeType::findByName( $httpFile->attribute( 'mime_type' ) ); 01114 if ( !$mimeData['is_valid'] ) 01115 { 01116 $mimeData = eZMimeType::findByURL( $httpFile->attribute( 'original_filename' ) ); 01117 } 01118 } 01119 $attr = false; 01120 $this->removeAliases( $attr ); 01121 $this->setOriginalAttributeDataValues( $this->ContentObjectAttributeData['id'], 01122 $this->ContentObjectAttributeData['version'], 01123 $this->ContentObjectAttributeData['language_code'] ); 01124 $contentVersion = eZContentObjectVersion::fetchVersion( $this->ContentObjectAttributeData['version'], 01125 $this->ContentObjectAttributeData['contentobject_id'] ); 01126 $objectName = $this->imageName( $this->ContentObjectAttributeData, $contentVersion ); 01127 $objectPathString = $this->imagePath( $this->ContentObjectAttributeData, $contentVersion, true ); 01128 01129 eZMimeType::changeBaseName( $mimeData, $objectName ); 01130 eZMimeType::changeDirectoryPath( $mimeData, $objectPathString ); 01131 01132 $httpFile->store( false, false, $mimeData ); 01133 01134 $originalFilename = $httpFile->attribute( 'original_filename' ); 01135 return $this->initialize( $mimeData, $originalFilename, $imageAltText ); 01136 } 01137 01138 /*! 01139 Initializes the content object attribute \a $contentObjectAttribute with the filename \a $filename. 01140 Optionally you may also specify the alternative text in the parameter \a $imageAltText. 01141 \sa initialize 01142 */ 01143 function initializeFromFile( $filename, $imageAltText = false, $originalFilename = false ) 01144 { 01145 if ( !file_exists( $filename ) ) 01146 { 01147 eZDebug::writeError( "The image '$filename' does not exist, cannot initialize image attribute with it", 01148 'eZImageAliasHandler::initializeFromFile' ); 01149 return false; 01150 } 01151 01152 $this->increaseImageSerialNumber(); 01153 01154 if ( !$originalFilename ) 01155 $originalFilename = basename( $filename ); 01156 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 01157 $mimeData = eZMimeType::findByFileContents( $filename ); 01158 if ( !$mimeData['is_valid'] and 01159 $originalFilename != $filename ) 01160 { 01161 $mimeData = eZMimeType::findByFileContents( $originalFilename ); 01162 } 01163 01164 $attr = false; 01165 $this->removeAliases( $attr ); 01166 $this->setOriginalAttributeDataValues( $this->ContentObjectAttributeData['id'], 01167 $this->ContentObjectAttributeData['version'], 01168 $this->ContentObjectAttributeData['language_code'] ); 01169 $contentVersion = eZContentObjectVersion::fetchVersion( $this->ContentObjectAttributeData['version'], 01170 $this->ContentObjectAttributeData['contentobject_id'] ); 01171 $objectName = $this->imageName( $this->ContentObjectAttributeData, $contentVersion ); 01172 $objectPathString = $this->imagePath( $this->ContentObjectAttributeData, $contentVersion, true ); 01173 01174 eZMimeType::changeBaseName( $mimeData, $objectName ); 01175 eZMimeType::changeDirectoryPath( $mimeData, $objectPathString ); 01176 if ( !file_exists( $mimeData['dirpath'] ) ) 01177 { 01178 eZDir::mkdir( $mimeData['dirpath'], false, true ); 01179 } 01180 01181 eZFileHandler::copy( $filename, $mimeData['url'] ); 01182 01183 return $this->initialize( $mimeData, $originalFilename, $imageAltText ); 01184 } 01185 01186 /*! 01187 Makes sure the attribute contains the image file mentioned in \a $mimeData. 01188 This involves removing any previous image (and image aliases), increasing 01189 the image name counter, figuring out the image size and creating 01190 the internal XML structure. 01191 \return \c true on success. 01192 */ 01193 function initialize( $mimeData, $originalFilename, $imageAltText = false ) 01194 { 01195 require_once( 'kernel/common/image.php' ); 01196 $imageManager = imageInit(); 01197 01198 $this->setOriginalAttributeDataValues( $this->ContentObjectAttributeData['id'], 01199 $this->ContentObjectAttributeData['version'], 01200 $this->ContentObjectAttributeData['language_code'] ); 01201 01202 $aliasList = array( 'original' => $mimeData ); 01203 $aliasList['original']['alternative_text'] = $imageAltText; 01204 $aliasList['original']['original_filename'] = $originalFilename; 01205 01206 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01207 $fileHandler = eZClusterFileHandler::instance(); 01208 $filePath = $mimeData['url']; 01209 $fileHandler->fileStore( $filePath, 'image', false, $mimeData['name'] ); 01210 01211 if ( $imageManager->createImageAlias( 'original', $aliasList, array( 'basename' => $mimeData['basename'] ) ) ) 01212 { 01213 $mimeData = $aliasList['original']; 01214 $mimeData['name'] = $mimeData['mime_type']; 01215 $aliasList['original']['original_filename'] = $originalFilename; 01216 } 01217 01218 if ( $aliasList['original']['url'] ) 01219 { 01220 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01221 $aliasFile = eZClusterFileHandler::instance( $aliasList['original']['url'] ); 01222 if( $aliasFile->exists() ) 01223 $aliasList['original']['filesize'] = $aliasFile->size(); 01224 } 01225 01226 // refetch the original image 01227 $fileHandler->fileFetch( $filePath ); 01228 01229 $imageManager->analyzeImage( $mimeData ); 01230 01231 $doc = new DOMDocument( '1.0', 'utf-8' ); 01232 $imageNode = $doc->createElement( "ezimage" ); 01233 $doc->appendChild( $imageNode ); 01234 01235 $width = false; 01236 $height = false; 01237 $info = getimagesize( $mimeData['url'] ); 01238 if ( $info ) 01239 { 01240 $width = $info[0]; 01241 $height = $info[1]; 01242 } 01243 01244 $originalNode = $doc->createElement( "original" ); 01245 $imageNode->appendChild( $originalNode ); 01246 $attributeData = $this->originalAttributeData(); 01247 $this->createOriginalAttributeXMLData( $originalNode, $attributeData ); 01248 01249 $imageNode->setAttribute( 'serial_number', $this->imageSerialNumber() ); 01250 $imageNode->setAttribute( 'is_valid', true ); 01251 $imageNode->setAttribute( 'filename', $mimeData['filename'] ); 01252 $imageNode->setAttribute( 'suffix', $mimeData['suffix'] ); 01253 $imageNode->setAttribute( 'basename', $mimeData['basename'] ); 01254 $imageNode->setAttribute( 'dirpath', $mimeData['dirpath'] ); 01255 $imageNode->setAttribute( 'url', $mimeData['url'] ); 01256 $imageNode->setAttribute( 'original_filename', $originalFilename ); 01257 $imageNode->setAttribute( 'mime_type', $mimeData['name'] ); 01258 $imageNode->setAttribute( 'width', $width ); 01259 $imageNode->setAttribute( 'height', $height ); 01260 $imageNode->setAttribute( 'alternative_text', $imageAltText ); 01261 $imageNode->setAttribute( 'alias_key', $imageManager->createImageAliasKey( $imageManager->alias( 'original' ) ) ); 01262 $imageNode->setAttribute( 'timestamp', time() ); 01263 01264 $this->createImageInformationNode( $imageNode, $mimeData ); 01265 01266 $this->setDOMTree( $doc ); 01267 01268 $this->setAliasList( $aliasList ); 01269 01270 eZImageFile::appendFilepath( $this->ContentObjectAttributeData['id'], $mimeData['url'] ); 01271 01272 $fileHandler->fileDeleteLocal( $filePath ); 01273 01274 return true; 01275 } 01276 01277 function createImageInformationNode( $imageNode, $mimeData ) 01278 { 01279 $dom = $imageNode->ownerDocument; 01280 if ( isset( $mimeData['info'] ) and 01281 $mimeData['info'] ) 01282 { 01283 $imageInfoNode = $dom->createElement( 'information' ); 01284 $info = $mimeData['info']; 01285 foreach ( $info as $infoItemName => $infoItem ) 01286 { 01287 if ( is_array( $infoItem ) ) 01288 { 01289 $hasScalarValues = true; 01290 foreach ( $infoItem as $infoArrayItem ) 01291 { 01292 if ( is_array( $infoArrayItem ) ) 01293 { 01294 $hasScalarValues = false; 01295 break; 01296 } 01297 } 01298 if ( !$hasScalarValues ) 01299 { 01300 $toRemove = array(); 01301 foreach ( $infoItem as $key => $value ) 01302 { 01303 if ( is_string( $value ) && !ctype_print( $value ) ) 01304 { 01305 $toRemove[] = $key; 01306 } 01307 } 01308 01309 if ( count( $toRemove ) > 0 ) 01310 { 01311 eZDebug::writeDebug( 'removing image information items containing non-printable characters: ' . implode( ', ', $toRemove ) ); 01312 01313 foreach ( $toRemove as $remove ) 01314 { 01315 unset( $infoItem[$remove] ); 01316 } 01317 } 01318 01319 unset( $serializedNode ); 01320 $serializedNode = $dom->createElement( 'serialized' ); 01321 $serializedNode->setAttribute( 'name', $infoItemName ); 01322 $serializedNode->setAttribute( 'data', serialize( $infoItem ) ); 01323 01324 $imageInfoNode->appendChild( $serializedNode ); 01325 } 01326 else 01327 { 01328 unset( $arrayNode ); 01329 $arrayNode = $dom->createElement( 'array' ); 01330 $arrayNode->setAttribute( 'name', $infoItemName ); 01331 01332 $imageInfoNode->appendChild( $arrayNode ); 01333 foreach ( $infoItem as $infoArrayKey => $infoArrayItem ) 01334 { 01335 unset( $arrayItemNode ); 01336 $arrayItemNode = $dom->createElement( 'item' ); 01337 $arrayItemNode->appendChild( $dom->createTextNode( base64_encode( $infoArrayItem ) ) ); 01338 $arrayItemNode->setAttribute( 'key', $infoArrayKey ); 01339 $arrayItemNode->setAttribute( 'base64', 1 ); 01340 01341 $arrayNode->appendChild( $arrayItemNode ); 01342 } 01343 } 01344 } 01345 else 01346 { 01347 $infoItem = iconv( mb_detect_encoding( $infoItem ), 'UTF-8//IGNORE', $infoItem ); 01348 $imageInfoNode->setAttribute( $infoItemName, $infoItem ); 01349 } 01350 } 01351 $imageNode->appendChild( $imageInfoNode ); 01352 } 01353 } 01354 01355 /*! 01356 Adds all the new image alias structures in \a $imageAliasList to the content object attribute. 01357 */ 01358 function addImageAliases( $imageAliasList ) 01359 { 01360 $domTree = $this->domTree(); 01361 foreach ( $imageAliasList as $imageAliasName => $imageAlias ) 01362 { 01363 if ( $imageAlias['is_new'] ) 01364 { 01365 $this->addImageAliasToXML( $domTree, $imageAlias ); 01366 $this->setAliasAttribute( $imageAliasName, 'is_new', false ); 01367 } 01368 } 01369 $attr = false; 01370 $this->storeDOMTree( $domTree, true, $attr ); 01371 } 01372 01373 /*! 01374 Adds the image alias structure \a $imageAlias to the content object attribute. 01375 */ 01376 function addImageAlias( $imageAlias ) 01377 { 01378 $domTree = $this->domTree(); 01379 $this->addImageAliasToXML( $domTree, $imageAlias ); 01380 $attr = false; 01381 $this->storeDOMTree( $domTree, true, $attr ); 01382 01383 } 01384 01385 /*! 01386 Adds the image alias structure \a $imageAlias to the XML DOM document \a $domTree. 01387 */ 01388 function addImageAliasToXML( $domTree, $imageAlias ) 01389 { 01390 $imageVariationNodeArray = $domTree->getElementsByTagName( 'alias' ); 01391 $imageNode = false; 01392 foreach ( $imageVariationNodeArray as $imageVariation ) 01393 { 01394 $aliasEntryName = $imageVariation->getAttribute( 'name' ); 01395 if ( $aliasEntryName == $imageAlias['name'] ) 01396 { 01397 $imageNode = $imageVariation; 01398 break; 01399 } 01400 } 01401 if ( !$imageNode ) 01402 { 01403 $rootNode = $domTree->documentElement; 01404 01405 $imageNode = $domTree->createElement( "alias" ); 01406 $rootNode->appendChild( $imageNode ); 01407 } 01408 else 01409 { 01410 $imageNode->removeAttribute( 'name' ); 01411 $imageNode->removeAttribute( 'filename' ); 01412 $imageNode->removeAttribute( 'suffix' ); 01413 $imageNode->removeAttribute( 'dirpath' ); 01414 $imageNode->removeAttribute( 'url' ); 01415 $imageNode->removeAttribute( 'mime_type' ); 01416 $imageNode->removeAttribute( 'width' ); 01417 $imageNode->removeAttribute( 'height' ); 01418 $imageNode->removeAttribute( 'alias_key' ); 01419 $imageNode->removeAttribute( 'timestamp' ); 01420 $imageNode->removeAttribute( 'is_valid' ); 01421 } 01422 $imageNode->setAttribute( 'name', $imageAlias['name'] ); 01423 $imageNode->setAttribute( 'filename', $imageAlias['filename'] ); 01424 $imageNode->setAttribute( 'suffix', $imageAlias['suffix'] ); 01425 $imageNode->setAttribute( 'dirpath', $imageAlias['dirpath'] ); 01426 $imageNode->setAttribute( 'url', $imageAlias['url'] ); 01427 $imageNode->setAttribute( 'mime_type', $imageAlias['mime_type'] ); 01428 $imageNode->setAttribute( 'width', $imageAlias['width'] ); 01429 $imageNode->setAttribute( 'height', $imageAlias['height'] ); 01430 $imageNode->setAttribute( 'alias_key', $imageAlias['alias_key'] ); 01431 $imageNode->setAttribute( 'timestamp', $imageAlias['timestamp'] ); 01432 $imageNode->setAttribute( 'is_valid', $imageAlias['is_valid'] ); 01433 } 01434 01435 /*! 01436 Sets the XML DOM document \a $domTree as the current DOM document. 01437 */ 01438 function setDOMTree( $domTree ) 01439 { 01440 $this->ContentObjectAttributeData['DataTypeCustom']['dom_tree'] = $domTree; 01441 $this->ContentObjectAttributeData['DataTypeCustom']['is_storage_required'] = true; 01442 } 01443 01444 /*! 01445 Stores the XML DOM document \a $domTree to the content object attribute. 01446 */ 01447 function storeDOMTree( $domTree, $storeAttribute, $contentObjectAttributeRef ) 01448 { 01449 if ( !$domTree ) 01450 return false; 01451 $this->ContentObjectAttributeData['DataTypeCustom']['dom_tree'] = $domTree; 01452 $this->ContentObjectAttributeData['DataTypeCustom']['is_storage_required'] = false; 01453 $xmlString = $domTree->saveXML(); 01454 $this->ContentObjectAttributeData['data_text'] = $xmlString; 01455 01456 if ( $storeAttribute ) 01457 { 01458 if ( is_object( $contentObjectAttributeRef ) ) 01459 { 01460 $contentObjectAttribute = $contentObjectAttributeRef; 01461 } 01462 else 01463 { 01464 $contentObjectAttribute = eZContentObjectAttribute::fetch( $this->ContentObjectAttributeData['id'], 01465 $this->ContentObjectAttributeData['version'] ); 01466 } 01467 01468 if ( is_object( $contentObjectAttribute ) ) 01469 { 01470 $contentObjectAttribute->setAttribute( 'data_text', $xmlString ); 01471 $contentObjectAttribute->storeData(); 01472 } 01473 else 01474 { 01475 eZDebug::writeError( "Invalid objectAttribute: id = " . $this->ContentObjectAttributeData['id'] . 01476 " version = " . $this->ContentObjectAttributeData['version'] , 01477 "eZImageAliasHandler::storeDOMTree" ); 01478 } 01479 } 01480 01481 return true; 01482 } 01483 01484 /*! 01485 Stores the data in the image alias handler to the content object attribute. 01486 \sa isStorageRequired, setStorageRequired 01487 */ 01488 function store( $contentObjectAttribute ) 01489 { 01490 $domTree = $this->domTree(); 01491 if ( $domTree ) 01492 { 01493 if ( is_object( $contentObjectAttribute ) ) 01494 { 01495 $this->storeDOMTree( $domTree, false, $contentObjectAttribute ); 01496 01497 $contentObjectAttribute->setAttribute( 'data_text', $this->ContentObjectAttributeData['data_text'] ); 01498 $contentObjectAttribute->storeData(); 01499 } 01500 else 01501 { 01502 $this->storeDOMTree( $domTree, true, $contentObjectAttribute ); 01503 01504 } 01505 } 01506 01507 $this->setStorageRequired( false ); 01508 } 01509 01510 /*! 01511 \return \c true if the image alias handler is required to store it's contents. 01512 \sa setStorageRequired, store 01513 */ 01514 function isStorageRequired() 01515 { 01516 return isset( $this->ContentObjectAttributeData['DataTypeCustom']['is_storage_required'] ) ? 01517 $this->ContentObjectAttributeData['DataTypeCustom']['is_storage_required'] : 01518 false; 01519 } 01520 01521 /*! 01522 Sets whether storage of the image alias data is required or not. 01523 \sa isStorageRequired, store 01524 */ 01525 function setStorageRequired( $require = true ) 01526 { 01527 $this->ContentObjectAttributeData['DataTypeCustom']['is_storage_required'] = $require; 01528 } 01529 01530 /*! 01531 \return An array structure with information on which attribute 01532 originally created the current data. 01533 01534 This will only contain data if the attribute is a copy of 01535 another attribute, e.g in the case of a new version without an new image upload. 01536 */ 01537 function originalAttributeData() 01538 { 01539 $contentObjectAttributeData = $this->ContentObjectAttributeData; 01540 if ( isset( $contentObjectAttributeData['DataTypeCustom']['original_data'] ) ) 01541 return $contentObjectAttributeData['DataTypeCustom']['original_data']; 01542 01543 $originalData = array( 'attribute_id' => $contentObjectAttributeData['id'], 01544 'attribute_version' => $contentObjectAttributeData['version'], 01545 'attribute_language' => $contentObjectAttributeData['language_code'] ); 01546 $this->setOriginalAttributeData( $originalData ); 01547 return $originalData; 01548 } 01549 01550 /*! 01551 Sets the information on which attribute the data was fetched from. 01552 See eZImageAliasHandler::originalAttributeData() for more information. 01553 */ 01554 function setOriginalAttributeData( $originalData ) 01555 { 01556 $this->ContentObjectAttributeData['DataTypeCustom']['original_data'] = $originalData; 01557 01558 $domTree = $this->domTree(); 01559 $imageOriginalArray = $domTree->getElementsByTagName( "original" ); 01560 if ( $imageOriginalArray->length > 0 ) 01561 { 01562 $imageOriginalNode = $imageOriginalArray->item( 0 ); 01563 $this->createOriginalAttributeXMLData( $imageOriginalNode, $originalData ); 01564 } 01565 } 01566 01567 /*! 01568 Sets the information on which attribute the data was fetched from. 01569 01570 Fetches data from the contentobject attribute \a $contentObjectAttribute and 01571 sets it using setOriginalAttributeData(). 01572 */ 01573 function setOriginalAttributeDataFromAttribute( $contentObjectAttribute ) 01574 { 01575 $originalImageHandler = $contentObjectAttribute->attribute( 'content' ); 01576 $originalAttributeData = $originalImageHandler->originalAttributeData(); 01577 $domTree = $originalImageHandler->domTree(); 01578 $this->setDOMTree( $domTree ); 01579 if ( $originalAttributeData['attribute_id'] ) 01580 { 01581 $this->setOriginalAttributeData( $originalAttributeData ); 01582 } 01583 else 01584 { 01585 $this->setOriginalAttributeDataValues( $contentObjectAttribute->attribute( 'id' ), 01586 $contentObjectAttribute->attribute( 'version' ), 01587 $contentObjectAttribute->attribute( 'language_code' ), 01588 false ); 01589 } 01590 } 01591 01592 /*! 01593 Sets the information on which attribute the data was fetched from. 01594 01595 Fetches data from the parameters and sets it using setOriginalAttributeData(). 01596 */ 01597 function setOriginalAttributeDataValues( $attributeID, $attributeVersion, $attributeLanguage ) 01598 { 01599 $this->setOriginalAttributeData( array( 'attribute_id' => $attributeID, 01600 'attribute_version' => $attributeVersion, 01601 'attribute_language' => $attributeLanguage ) ); 01602 } 01603 01604 /*! 01605 Set internal serial number 01606 01607 \param value 01608 */ 01609 function setImageSerialNumber( $val ) 01610 { 01611 $this->ContentObjectAttributeData['DataTypeCustom']['serial_number'] = $val; 01612 } 01613 01614 /*! 01615 \private 01616 \return The internal serial number. 01617 01618 It will check if a serial number exists and return that, if not a new one will be created and returned. 01619 */ 01620 private function imageSerialNumberRaw() 01621 { 01622 return isset( $this->ContentObjectAttributeData['DataTypeCustom']['serial_number'] ) ? 01623 $this->ContentObjectAttributeData['DataTypeCustom']['serial_number'] : 01624 0; 01625 } 01626 01627 /*! 01628 Fetches image information from the old 3.2 image system and creates new information. 01629 */ 01630 function generateXMLData() 01631 { 01632 // VS-DBFILE 01633 // VS: I feel we don't need clustering support for the old image system. 01634 01635 //include_once( "lib/ezdb/classes/ezdb.php" ); 01636 01637 $db = eZDB::instance(); 01638 01639 $contentObjectAttributeData = $this->ContentObjectAttributeData; 01640 $attributeID = $contentObjectAttributeData['id']; 01641 $attributeVersion = $contentObjectAttributeData['version']; 01642 01643 if ( is_numeric( $attributeID ) ) 01644 { 01645 $imageRow = $db->arrayQuery( "SELECT * FROM ezimage 01646 WHERE contentobject_attribute_id=$attributeID AND 01647 version=$attributeVersion" ); 01648 } 01649 01650 $doc = new DOMDocument( '1.0', 'utf-8' ); 01651 $imageNode = $doc->createElement( "ezimage" ); 01652 $doc->appendChild( $imageNode ); 01653 01654 $isValid = false; 01655 $fileName = false; 01656 $suffix = false; 01657 $baseName = false; 01658 $dirPath = false; 01659 $filePath = false; 01660 $originalFileName = false; 01661 $mimeType = false; 01662 $width = false; 01663 $height = false; 01664 $altText = false; 01665 01666 //include_once( 'lib/ezutils/classes/ezmimetype.php' ); 01667 if ( count( $imageRow ) == 1 ) 01668 { 01669 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01670 $fileHandler = eZClusterFileHandler::instance(); 01671 01672 $fileName = $imageRow[0]['filename']; 01673 $originalFileName = $imageRow[0]['original_filename']; 01674 $mimeType = $imageRow[0]['mime_type']; 01675 $altText = $imageRow[0]['alternative_text']; 01676 01677 $dirPath = eZSys::storageDirectory() . '/original/image'; 01678 $filePath = $dirPath . '/' . $fileName; 01679 01680 // VS-DBFILE : TODO checked 01681 01682 $baseName = $fileName; 01683 $dotPosition = strrpos( $fileName, '.' ); 01684 if ( $dotPosition !== false ) 01685 { 01686 $baseName = substr( $fileName, 0, $dotPosition ); 01687 $suffix = substr( $fileName, $dotPosition + 1 ); 01688 } 01689 01690 $width = false; 01691 $height = false; 01692 if ( !file_exists( $filePath ) ) 01693 { 01694 $referenceDirPath = eZSys::storageDirectory() . '/reference/image'; 01695 $suffixList = array( 'jpg', 'png', 'gif' ); 01696 foreach ( $suffixList as $suffix ) 01697 { 01698 // VS-DBFILE : TODO checked 01699 01700 $referenceFilePath = $referenceDirPath . '/' . $baseName . '.' . $suffix; 01701 if ( file_exists( $referenceFilePath ) ) 01702 { 01703 $filePath = $referenceFilePath; 01704 $dirPath = $referenceDirPath; 01705 break; 01706 } 01707 } 01708 } 01709 01710 // VS-DBFILE : TODO checked 01711 01712 if ( file_exists( $filePath ) ) 01713 { 01714 $isValid = true; 01715 $info = getimagesize( $filePath ); 01716 if ( $info ) 01717 { 01718 $width = $info[0]; 01719 $height = $info[1]; 01720 } 01721 $mimeInfo = eZMimeType::findByFileContents( $filePath ); 01722 $mimeType = $mimeInfo['name']; 01723 01724 $newFilePath = $filePath; 01725 $newSuffix = $suffix; 01726 $contentVersion = eZContentObjectVersion::fetchVersion( $contentObjectAttributeData['version'], 01727 $contentObjectAttributeData['contentobject_id'] ); 01728 if ( $contentVersion ) 01729 { 01730 $objectName = $this->imageName( $contentObjectAttributeData, $contentVersion ); 01731 $objectPathString = $this->imagePath( $contentObjectAttributeData, $contentVersion ); 01732 01733 $newDirPath = $objectPathString; 01734 $newFileName = $objectName . '.' . $mimeInfo['suffix']; 01735 $newSuffix = $mimeInfo['suffix']; 01736 $newFilePath = $newDirPath . '/' . $newFileName; 01737 $newBaseName = $objectName; 01738 } 01739 01740 // VS-DBFILE : TODO checked 01741 01742 if ( $newFilePath != $filePath ) 01743 { 01744 if ( !file_exists( $newDirPath ) ) 01745 { 01746 //include_once( 'lib/ezfile/classes/ezdir.php' ); 01747 eZDir::mkdir( $newDirPath, eZDir::directoryPermission(), true ); 01748 } 01749 eZFileHandler::copy( $filePath, $newFilePath ); 01750 01751 // VS-DBFILE : TODO checked 01752 01753 //require_once( 'kernel/classes/ezclusterfilehandler.php' ); 01754 //$fileHandler = eZClusterFileHandler::instance(); 01755 //$fileHandler->fileCopy( $filePath, $newFilePath ); 01756 01757 $filePath = $newFilePath; 01758 $fileName = $newFileName; 01759 $suffix = $newSuffix; 01760 $dirPath = $newDirPath; 01761 $baseName = $newBaseName; 01762 } 01763 } 01764 } 01765 require_once( 'kernel/common/image.php' ); 01766 $imageManager = imageInit(); 01767 01768 $mimeData = eZMimeType::findByFileContents( $fileName ); 01769 01770 $imageManager->analyzeImage( $mimeData ); 01771 01772 $imageNode->setAttribute( 'serial_number', false ); 01773 $imageNode->setAttribute( 'is_valid', $isValid ); 01774 $imageNode->setAttribute( 'filename', $fileName ); 01775 $imageNode->setAttribute( 'suffix', $suffix ); 01776 $imageNode->setAttribute( 'basename', $baseName ); 01777 $imageNode->setAttribute( 'dirpath', $dirPath ); 01778 $imageNode->setAttribute( 'url', $filePath ); 01779 $imageNode->setAttribute( 'original_filename', $originalFileName ); 01780 $imageNode->setAttribute( 'mime_type', $mimeType ); 01781 $imageNode->setAttribute( 'width', $width ); 01782 $imageNode->setAttribute( 'height', $height ); 01783 $imageNode->setAttribute( 'alternative_text', $altText ); 01784 $imageNode->setAttribute( 'alias_key', $imageManager->createImageAliasKey( $imageManager->alias( 'original' ) ) ); 01785 $imageNode->setAttribute( 'timestamp', time() ); 01786 01787 $this->createImageInformationNode( $imageNode, $mimeData ); 01788 01789 $attr = false; 01790 $this->storeDOMTree( $doc, true, $attr ); 01791 01792 01793 eZImageFile::appendFilepath( $contentObjectAttributeData['id'], $filePath ); 01794 } 01795 01796 /// \privatesection 01797 /// Contains a some eZContentObjectAttribute's attributes. 01798 public $ContentObjectAttributeData; 01799 /// Deprecated. Contains a reference to the object attribute 01800 public $ContentObjectAttribute; 01801 01802 } 01803 ?>