eZ Publish  [4.0]
ezimagetype.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZImageType class
00004 //
00005 // Created on: <30-Apr-2002 13:06:21 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 eZImageType ezimagetype.php
00033   \ingroup eZDatatype
00034   \brief The class eZImageType handles image accounts and association with content objects
00035 
00036   \note The method initializeObjectAttribute was removed in 3.8, the new
00037         storage technique removes the need to have it.
00038 */
00039 
00040 //include_once( "kernel/classes/ezdatatype.php" );
00041 //include_once( "lib/ezfile/classes/ezdir.php" );
00042 //include_once( "lib/ezutils/classes/ezhttpfile.php" );
00043 
00044 class eZImageType extends eZDataType
00045 {
00046     const FILESIZE_FIELD = 'data_int1';
00047     const FILESIZE_VARIABLE = '_ezimage_max_filesize_';
00048     const DATA_TYPE_STRING = "ezimage";
00049 
00050     function eZImageType()
00051     {
00052         $this->eZDataType( self::DATA_TYPE_STRING, ezi18n( 'kernel/classes/datatypes', "Image", 'Datatype name' ),
00053                            array( 'serialize_supported' => true ) );
00054     }
00055 
00056     function repairContentObjectAttribute( $contentObjectAttribute )
00057     {
00058         //include_once( "kernel/classes/datatypes/ezimage/ezimage.php" );
00059         $image = eZImage::fetch( $contentObjectAttribute->attribute( 'id' ),
00060                                   $contentObjectAttribute->attribute( 'version' ) );
00061         if ( !is_object( $image ) )
00062         {
00063             $list = eZContentObjectAttribute::fetchSameClassAttributeIDList( $contentObjectAttribute->attribute( 'contentclassattribute_id' ),
00064                                                                               true,
00065                                                                               $contentObjectAttribute->attribute( 'version' ) );
00066             $language = eZContentObject::defaultLanguage();
00067             $attribute = false;
00068             foreach ( $list as $listItem )
00069             {
00070                 if ( $listItem->attribute( 'language_code' ) == $language )
00071                 {
00072                     $attribute = $listItem;
00073                     break;
00074                 }
00075             }
00076             if ( $attribute === false )
00077             {
00078                 $attribute = $list[0];
00079             }
00080             if ( $attribute )
00081             {
00082                 $originalImage = eZImage::fetch( $attribute->attribute( 'id' ),
00083                                                   $attribute->attribute( 'version' ) );
00084                 if ( is_object( $originalImage ) )
00085                 {
00086                     $originalImage->setAttribute( 'contentobject_attribute_id', $contentObjectAttribute->attribute( 'id' ) );
00087                     $originalImage->store();
00088                     return true;
00089                 }
00090             }
00091         }
00092         return false;
00093     }
00094 
00095     /*!
00096      \reimp
00097     */
00098     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00099     {
00100         if ( $currentVersion != false )
00101         {
00102             $dataText = $originalContentObjectAttribute->attribute( "data_text" );
00103             $contentObjectAttribute->setAttribute( "data_text", $dataText );
00104         }
00105     }
00106 
00107     /*!
00108      The object is being moved to trash, do any necessary changes to the attribute.
00109      Rename file and update db row with new name, so that access to the file using old links no longer works.
00110     */
00111     function trashStoredObjectAttribute( $contentObjectAttribute, $version = null )
00112     {
00113         $contentObjectAttributeID = $contentObjectAttribute->attribute( "id" );
00114         $imageHandler = $contentObjectAttribute->attribute( 'content' );
00115         $imageFiles = eZImageFile::fetchForContentObjectAttribute( $contentObjectAttributeID );
00116 
00117         foreach ( $imageFiles as $imageFile )
00118         {
00119             if ( $imageFile == null )
00120                 continue;
00121             $existingFilepath = $imageFile;
00122 
00123             // Check if there are any other records in ezimagefile that point to that filename.
00124             $imageObjectsWithSameFileName = eZImageFile::fetchByFilepath( false, $existingFilepath );
00125 
00126             $file = eZClusterFileHandler::instance( $existingFilepath );
00127 
00128             if ( $file->exists() and count( $imageObjectsWithSameFileName ) <= 1 )
00129             {
00130                 $orig_dir = dirname( $existingFilepath ) . '/trashed';
00131                 $fileName = basename( $existingFilepath );
00132 
00133                 // create dest filename in the same manner as eZHTTPFile::store()
00134                 // grab file's suffix
00135                 $fileSuffix = eZFile::suffix( $fileName );
00136                 // prepend dot
00137                 if ( $fileSuffix )
00138                     $fileSuffix = '.' . $fileSuffix;
00139                 // grab filename without suffix
00140                 $fileBaseName = basename( $fileName, $fileSuffix );
00141                 // create dest filename
00142                 $newFileBaseName = md5( $fileBaseName . microtime() . mt_rand() );
00143                 $newFileName = $newFileBaseName . $fileSuffix;
00144                 $newFilepath = $orig_dir . '/' . $newFileName;
00145 
00146                 // rename the file, and update the database data
00147                 $imageHandler->updateAliasPath( $orig_dir, $newFileBaseName );
00148                 if ( $imageHandler->isStorageRequired() )
00149                 {
00150                     $imageHandler->store( $contentObjectAttribute );
00151                     $contentObjectAttribute->store();
00152                 }
00153             }
00154         }
00155     }
00156 
00157     /*!
00158      \reimp
00159     */
00160     function deleteStoredObjectAttribute( $contentObjectAttribute, $version = null )
00161     {
00162         if ( $version === null )
00163         {
00164             //include_once( "kernel/classes/datatypes/ezimage/ezimagealiashandler.php" );
00165             eZImageAliasHandler::removeAllAliases( $contentObjectAttribute );
00166         }
00167         else
00168         {
00169             $imageHandler = $contentObjectAttribute->attribute( 'content' );
00170             if ( $imageHandler )
00171                 $imageHandler->removeAliases( $contentObjectAttribute );
00172         }
00173     }
00174 
00175     /*!
00176      \reimp
00177     */
00178     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00179     {
00180         $classAttribute = $contentObjectAttribute->contentClassAttribute();
00181         $httpFileName = $base . "_data_imagename_" . $contentObjectAttribute->attribute( "id" );
00182         $maxSize = 1024 * 1024 * $classAttribute->attribute( self::FILESIZE_FIELD );
00183         $mustUpload = false;
00184 
00185         if( $contentObjectAttribute->validateIsRequired() )
00186         {
00187             $tmpImgObj = $contentObjectAttribute->attribute( 'content' );
00188             $original = $tmpImgObj->attribute( 'original' );
00189             if ( !$original['is_valid'] )
00190             {
00191                 $mustUpload = true;
00192             }
00193         }
00194 
00195         $canFetchResult = eZHTTPFile::canFetch( $httpFileName, $maxSize );
00196         if ( isset( $_FILES[$httpFileName] ) and  $_FILES[$httpFileName]["tmp_name"] != "" )
00197         {
00198              $imagefile = $_FILES[$httpFileName]['tmp_name'];
00199              if ( !$_FILES[$httpFileName]["size"] )
00200              {
00201                 $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00202                                                                      'The image file must have non-zero size.' ) );
00203                 return eZInputValidator::STATE_INVALID;
00204              }
00205              if ( function_exists( 'getimagesize' ) )
00206              {
00207                 $info = getimagesize( $imagefile );
00208                 if ( !$info )
00209                 {
00210                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00211                                                                          'A valid image file is required.' ) );
00212                     return eZInputValidator::STATE_INVALID;
00213                 }
00214              }
00215              else
00216              {
00217                  //include_once( 'lib/ezutils/classes/ezmimetype.php' );
00218                  $mimeType = eZMimeType::findByURL( $_FILES[$httpFileName]['name'] );
00219                  $nameMimeType = $mimeType['name'];
00220                  $nameMimeTypes = explode("/", $nameMimeType);
00221                  if ( $nameMimeTypes[0] != 'image' )
00222                  {
00223                      $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00224                                                                           'A valid image file is required.' ) );
00225                      return eZInputValidator::STATE_INVALID;
00226                  }
00227              }
00228         }
00229         if ( $mustUpload && $canFetchResult == eZHTTPFile::UPLOADEDFILE_DOES_NOT_EXIST )
00230         {
00231             $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00232                 'A valid image file is required.' ) );
00233             return eZInputValidator::STATE_INVALID;
00234         }
00235         if ( $canFetchResult == eZHTTPFile::UPLOADEDFILE_EXCEEDS_PHP_LIMIT )
00236         {
00237             $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00238                 'The size of the uploaded image exceeds limit set by upload_max_filesize directive in php.ini. Please contact the site administrator.' ) );
00239             return eZInputValidator::STATE_INVALID;
00240         }
00241         if ( $canFetchResult == eZHTTPFile::UPLOADEDFILE_EXCEEDS_MAX_SIZE )
00242         {
00243             $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00244                 'The size of the uploaded file exceeds the limit set for this site: %1 bytes.' ), $maxSize );
00245             return eZInputValidator::STATE_INVALID;
00246         }
00247         return eZInputValidator::STATE_ACCEPTED;
00248     }
00249 
00250     /*!
00251      \reimp
00252     */
00253     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00254     {
00255         $result = false;
00256         $imageAltText = false;
00257         $hasImageAltText = false;
00258         if ( $http->hasPostVariable( $base . "_data_imagealttext_" . $contentObjectAttribute->attribute( "id" ) ) )
00259         {
00260             $imageAltText = $http->postVariable( $base . "_data_imagealttext_" . $contentObjectAttribute->attribute( "id" ) );
00261             $hasImageAltText = true;
00262         }
00263 
00264         $content = $contentObjectAttribute->attribute( 'content' );
00265         $httpFileName = $base . "_data_imagename_" . $contentObjectAttribute->attribute( "id" );
00266 
00267         if ( eZHTTPFile::canFetch( $httpFileName ) )
00268         {
00269             $httpFile = eZHTTPFile::fetch( $httpFileName );
00270             if ( $httpFile )
00271             {
00272                 if ( $content )
00273                 {
00274                     $content->setHTTPFile( $httpFile );
00275                     $result = true;
00276                 }
00277             }
00278         }
00279 
00280         if ( $content )
00281         {
00282             if ( $hasImageAltText )
00283                 $content->setAttribute( 'alternative_text', $imageAltText );
00284             $result = true;
00285         }
00286 
00287         return $result;
00288     }
00289 
00290     /*!
00291      \reimp
00292     */
00293     function storeObjectAttribute( $contentObjectAttribute )
00294     {
00295         $imageHandler = $contentObjectAttribute->attribute( 'content' );
00296         if ( $imageHandler )
00297         {
00298             $httpFile = $imageHandler->httpFile( true );
00299             if ( $httpFile )
00300             {
00301                 $imageAltText = $imageHandler->attribute( 'alternative_text' );
00302 
00303                 $imageHandler->initializeFromHTTPFile( $httpFile, $imageAltText );
00304             }
00305             if ( $imageHandler->isStorageRequired() )
00306             {
00307                 $imageHandler->store( $contentObjectAttribute );
00308             }
00309         }
00310     }
00311 
00312     /*!
00313      \reimp
00314      HTTP file insertion is supported.
00315     */
00316     function isHTTPFileInsertionSupported()
00317     {
00318         return true;
00319     }
00320 
00321     /*!
00322      \reimp
00323      Regular file insertion is supported.
00324     */
00325     function isRegularFileInsertionSupported()
00326     {
00327         return true;
00328     }
00329 
00330     /*!
00331      \reimp
00332      Inserts the file using the Image Handler eZImageAliasHandler.
00333     */
00334     function insertHTTPFile( $object, $objectVersion, $objectLanguage,
00335                              $objectAttribute, $httpFile, $mimeData,
00336                              &$result )
00337     {
00338         $result = array( 'errors' => array(),
00339                          'require_storage' => false );
00340 
00341         $handler = $objectAttribute->content();
00342         if ( !$handler )
00343         {
00344             $result['errors'][] = array( 'description' => ezi18n( 'kernel/classes/datatypes/ezimage',
00345                                                                   'Failed to fetch Image Handler. Please contact the site administrator.' ) );
00346             return false;
00347         }
00348 
00349         $status = $handler->initializeFromHTTPFile( $httpFile );
00350         $result['require_storage'] = $handler->isStorageRequired();
00351         return $status;
00352     }
00353 
00354     /*!
00355      \reimp
00356      Inserts the file using the Image Handler eZImageAliasHandler.
00357     */
00358     function insertRegularFile( $object, $objectVersion, $objectLanguage,
00359                                 $objectAttribute, $filePath,
00360                                 &$result )
00361     {
00362         $result = array( 'errors' => array(),
00363                          'require_storage' => false );
00364 
00365         $handler = $objectAttribute->content();
00366         if ( !$handler )
00367         {
00368             $result['errors'][] = array( 'description' => ezi18n( 'kernel/classes/datatypes/ezimage',
00369                                                                   'Failed to fetch Image Handler. Please contact the site administrator.' ) );
00370             return false;
00371         }
00372 
00373         $status = $handler->initializeFromFile( $filePath, false, basename( $filePath ) );
00374         $result['require_storage'] = $handler->isStorageRequired();
00375         return $status;
00376     }
00377 
00378     /*!
00379       \reimp
00380       We support file information
00381     */
00382     function hasStoredFileInformation( $object, $objectVersion, $objectLanguage,
00383                                        $objectAttribute )
00384     {
00385         return true;
00386     }
00387 
00388     /*!
00389       \reimp
00390       Extracts file information for the image entry.
00391     */
00392     function storedFileInformation( $object, $objectVersion, $objectLanguage,
00393                                     $objectAttribute )
00394     {
00395         $content = $objectAttribute->content();
00396         if ( $content )
00397         {
00398             $original = $content->attribute( 'original' );
00399             $fileName = $original['filename'];
00400             $filePath = $original['full_path'];
00401             $mimeType = $original['mime_type'];
00402             $originalFileName = $original['original_filename'];
00403 
00404             return array( 'filename' => $fileName,
00405                           'original_filename' => $originalFileName,
00406                           'filepath' => $filePath,
00407                           'mime_type' => $mimeType );
00408         }
00409         return false;
00410     }
00411 
00412     /*!
00413      \reimp
00414     */
00415     function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes )
00416     {
00417         $hasContent = $contentObjectAttribute->hasContent();
00418         if ( $hasContent )
00419         {
00420             $imageHandler = $contentObjectAttribute->attribute( 'content' );
00421             $mainNode = false;
00422             foreach ( array_keys( $publishedNodes ) as $publishedNodeKey )
00423             {
00424                 $publishedNode = $publishedNodes[$publishedNodeKey];
00425                 if ( $publishedNode->attribute( 'main_node_id' ) )
00426                 {
00427                     $mainNode = $publishedNode;
00428                     break;
00429                 }
00430             }
00431             if ( $mainNode )
00432             {
00433                 $dirpath = $imageHandler->imagePathByNode( $contentObjectAttribute, $mainNode );
00434                 $oldDirpath = $imageHandler->directoryPath();
00435                 if ( $oldDirpath != $dirpath )
00436                 {
00437                     $name = $imageHandler->imageNameByNode( $contentObjectAttribute, $mainNode );
00438                     $imageHandler->updateAliasPath( $dirpath, $name );
00439                 }
00440             }
00441             if ( $imageHandler->isStorageRequired() )
00442             {
00443                 $imageHandler->store( $contentObjectAttribute );
00444                 $contentObjectAttribute->store();
00445             }
00446         }
00447     }
00448 
00449     /*!
00450      \reimp
00451     */
00452     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00453     {
00454         $filesizeName = $base . self::FILESIZE_VARIABLE . $classAttribute->attribute( 'id' );
00455         if ( $http->hasPostVariable( $filesizeName ) )
00456         {
00457             $filesizeValue = $http->postVariable( $filesizeName );
00458             $classAttribute->setAttribute( self::FILESIZE_FIELD, $filesizeValue );
00459             return true;
00460         }
00461         return false;
00462     }
00463 
00464     /*!
00465      \reimp
00466     */
00467     function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
00468     {
00469         if( $action == "delete_image" )
00470         {
00471             $content = $contentObjectAttribute->attribute( 'content' );
00472             if ( $content )
00473             {
00474                 $content->removeAliases( $contentObjectAttribute );
00475             }
00476         }
00477     }
00478 
00479     /*!
00480      \reimp
00481      Will return one of the following items from the original alias.
00482      - alternative_text - If it's not empty
00483      - Default paramater in \a $name if it exists
00484      - original_filename, this is the default fallback.
00485     */
00486     function title( $contentObjectAttribute, $name = 'original_filename' )
00487     {
00488         $content = $contentObjectAttribute->content();
00489         $original = $content->attribute( 'original' );
00490         $value = $original['alternative_text'];
00491         if ( trim( $value ) == '' )
00492         {
00493             if ( array_key_exists( $name, $original ) )
00494                 $value = $original[$name];
00495             else
00496                 $value = $original['original_filename'];
00497         }
00498 
00499         return $value;
00500     }
00501 
00502     function hasObjectAttributeContent( $contentObjectAttribute )
00503     {
00504         $handler = $contentObjectAttribute->content();
00505         if ( !$handler )
00506             return false;
00507         return $handler->attribute( 'is_valid' );
00508     }
00509 
00510     /*!
00511      \reimp
00512     */
00513     function objectAttributeContent( $contentObjectAttribute )
00514     {
00515         //include_once( "kernel/classes/datatypes/ezimage/ezimagealiashandler.php" );
00516         $imageHandler = new eZImageAliasHandler( $contentObjectAttribute );
00517 
00518         return $imageHandler;
00519     }
00520 
00521     /*!
00522      \reimp
00523     */
00524     function metaData( $contentObjectAttribute )
00525     {
00526         $content = $contentObjectAttribute->content();
00527         $original = $content->attribute( 'original' );
00528         $value = $original['alternative_text'];
00529         return $value;
00530     }
00531 
00532     /*!
00533      \reimp
00534     */
00535     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00536     {
00537         $maxSize = $classAttribute->attribute( self::FILESIZE_FIELD );
00538         $dom = $attributeParametersNode->ownerDocument;
00539 
00540         $maxSizeNode = $dom->createElement( 'max-size' );
00541         $maxSizeNode->appendChild( $dom->createTextNode( $maxSize ) );
00542         $maxSizeNode->setAttribute( 'unit-size', 'mega' );
00543         $attributeParametersNode->appendChild( $maxSizeNode );
00544     }
00545 
00546     /*!
00547      \reimp
00548     */
00549     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00550     {
00551         $sizeNode = $attributeParametersNode->getElementsByTagName( 'max-size' )->item( 0 );
00552         $maxSize = $sizeNode->textContent;
00553         $unitSize = $sizeNode->getAttribute( 'unit-size' );
00554         $classAttribute->setAttribute( self::FILESIZE_FIELD, $maxSize );
00555     }
00556 
00557 
00558     /*!
00559      \reimp
00560      \return a DOM representation of the content object attribute
00561     */
00562     function serializeContentObjectAttribute( $package, $objectAttribute )
00563     {
00564         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
00565 
00566         $content = $objectAttribute->content();
00567         $original = $content->attribute( 'original' );
00568 
00569         if ( $original['url'] )
00570         {
00571             $imageKey = md5( mt_rand() );
00572 
00573             $package->appendSimpleFile( $imageKey, $original['url'] );
00574             $node->setAttribute( 'image-file-key', $imageKey );
00575         }
00576 
00577         $node->setAttribute( 'alternative-text', $original['alternative_text'] );
00578 
00579         return $node;
00580     }
00581 
00582     /*!
00583      \reimp
00584      \param package
00585      \param contentobject attribute object
00586      \param domnode object
00587     */
00588     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
00589     {
00590         // Remove all existing image data for the case this is a translated attribute,
00591         // so initial language's image alias will not be removed in 'initializeFromFile'
00592         $objectAttribute->setAttribute( 'data_text', '' );
00593 
00594         $alternativeText = $attributeNode->getAttribute( 'alternative-text' );
00595         // Backwards compatability with older node name
00596         if ( $alternativeText === false )
00597             $alternativeText = $attributeNode->getAttribute( 'alternativ-text' );
00598         $content = $objectAttribute->attribute( 'content' );
00599         $imageFileKey = $attributeNode->getAttribute( 'image-file-key' );
00600         if ( $imageFileKey )
00601         {
00602             $content->initializeFromFile( $package->simpleFilePath( $imageFileKey ), $alternativeText );
00603         }
00604         else
00605         {
00606             $content->setAttribute( 'alternative_text', $alternativeText );
00607         }
00608         $content->store( $objectAttribute );
00609     }
00610 
00611     /*!
00612      \return string representation of an contentobjectattribute data for simplified export
00613 
00614     */
00615     function toString( $objectAttribute )
00616     {
00617         $content = $objectAttribute->content();
00618         $original = $content->attribute( 'original' );
00619         return $original['url'];
00620     }
00621 
00622     function fromString( $objectAttribute, $string )
00623     {
00624         $delimiterPos = strpos( $string, '|' );
00625 
00626         $content = $objectAttribute->attribute( 'content' );
00627         if ( $delimiterPos === false )
00628         {
00629             $content->initializeFromFile( $string, '' );
00630         }
00631         else
00632         {
00633             $content->initializeFromFile( substr( $string, 0, $delimiterPos ), '' );
00634             $content->setAttribute( 'alternative_text', substr( $string, $delimiterPos + 1 ) );
00635         }
00636         $content->store( $objectAttribute );
00637         return true;
00638     }
00639 
00640 }
00641 
00642 eZDataType::register( eZImageType::DATA_TYPE_STRING, "eZImageType" );
00643 
00644 ?>