eZ Publish  [trunk]
ezobjectrelationtype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZObjectRelationType class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZObjectRelationType ezobjectrelationtype.php
00013   \ingroup eZDatatype
00014   \brief A content datatype which handles object relations
00015 
00016 */
00017 
00018 class eZObjectRelationType extends eZDataType
00019 {
00020     const DATA_TYPE_STRING = "ezobjectrelation";
00021 
00022     /*!
00023      Initializes with a string id and a description.
00024     */
00025     function eZObjectRelationType()
00026     {
00027         $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', "Object relation", 'Datatype name' ),
00028                            array( 'serialize_supported' => true ) );
00029     }
00030 
00031     /*!
00032      Initializes the class attribute with some data.
00033      */
00034     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00035     {
00036         if ( $currentVersion != false )
00037         {
00038             $dataText = $originalContentObjectAttribute->attribute( "data_int" );
00039             $contentObjectAttribute->setAttribute( "data_int", $dataText );
00040         }
00041     }
00042 
00043     /*!
00044      Validates the input and returns true if the input was
00045      valid for this datatype.
00046     */
00047     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00048     {
00049         $postVariableName = $base . "_data_object_relation_id_" . $contentObjectAttribute->attribute( "id" );
00050         if ( $http->hasPostVariable( $postVariableName ) )
00051         {
00052             $relatedObjectID = $http->postVariable( $postVariableName );
00053             $classAttribute = $contentObjectAttribute->contentClassAttribute();
00054 
00055             if ( $contentObjectAttribute->validateIsRequired() and $relatedObjectID == 0 )
00056             {
00057                 $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00058                                                                      'Missing objectrelation input.' ) );
00059                 return eZInputValidator::STATE_INVALID;
00060             }
00061         }
00062         else if ( $contentObjectAttribute->validateIsRequired() )
00063         {
00064             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes', 'Missing objectrelation input.' ) );
00065             return eZInputValidator::STATE_INVALID;
00066         }
00067 
00068         return eZInputValidator::STATE_ACCEPTED;
00069     }
00070 
00071     /*!
00072      Fetches the http post var string input and stores it in the data instance.
00073     */
00074     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00075     {
00076         $postVariableName = $base . "_data_object_relation_id_" . $contentObjectAttribute->attribute( "id" );
00077         $haveData = false;
00078         if ( $http->hasPostVariable( $postVariableName ) )
00079         {
00080             $relatedObjectID = $http->postVariable( $postVariableName );
00081             if ( $relatedObjectID == '' )
00082                 $relatedObjectID = null;
00083             $contentObjectAttribute->setAttribute( 'data_int', $relatedObjectID );
00084             $haveData = true;
00085         }
00086         $fuzzyMatchVariableName = $base . "_data_object_relation_fuzzy_match_" . $contentObjectAttribute->attribute( "id" );
00087         if ( $http->hasPostVariable( $fuzzyMatchVariableName ) )
00088         {
00089             $trans = eZCharTransform::instance();
00090 
00091             $fuzzyMatchText = trim( $http->postVariable( $fuzzyMatchVariableName ) );
00092             if ( $fuzzyMatchText != '' )
00093             {
00094                 $fuzzyMatchText = $trans->transformByGroup( $fuzzyMatchText, 'lowercase' );
00095                 $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
00096                 if ( $classAttribute )
00097                 {
00098                     $classContent = $classAttribute->content();
00099                     if ( $classContent['default_selection_node'] )
00100                     {
00101                         $nodeID = $classContent['default_selection_node'];
00102                         $nodeList = eZContentObjectTreeNode::subTreeByNodeID( array( 'Depth' => 1 ), $nodeID );
00103                         $lastDiff = false;
00104                         $matchObjectID = false;
00105                         foreach ( $nodeList as $node )
00106                         {
00107                             $name = $trans->transformByGroup( trim( $node->attribute( 'name' ) ), 'lowercase' );
00108                             $diff = $this->fuzzyTextMatch( $name, $fuzzyMatchText );
00109                             if ( $diff === false )
00110                                 continue;
00111                             if ( $diff == 0 )
00112                             {
00113                                 $matchObjectID = $node->attribute( 'contentobject_id' );
00114                                 break;
00115                             }
00116                             if ( $lastDiff === false or
00117                                  $diff < $lastDiff )
00118                             {
00119                                 $lastDiff = $diff;
00120                                 $matchObjectID = $node->attribute( 'contentobject_id' );
00121                             }
00122                         }
00123                         if ( $matchObjectID !== false )
00124                         {
00125                             $contentObjectAttribute->setAttribute( 'data_int', $matchObjectID );
00126                             $haveData = true;
00127                         }
00128                     }
00129                 }
00130             }
00131         }
00132         return $haveData;
00133     }
00134 
00135     /*!
00136      \private
00137      \return a number of how near \a $match is to \a $text, the lower the better and 0 is a perfect match.
00138      \return \c false if it does not match
00139     */
00140     function fuzzyTextMatch( $text, $match )
00141     {
00142         $pos = strpos( $text, $match );
00143         if ( $pos !== false )
00144         {
00145             $diff = strlen( $text ) - ( strlen( $match ) + $pos );
00146             $diff += $pos;
00147             return $diff;
00148         }
00149         return false;
00150     }
00151 
00152     /*!
00153      Stores relation to the ezcontentobject_link table
00154     */
00155     function storeObjectAttribute( $contentObjectAttribute )
00156     {
00157         $contentClassAttributeID = $contentObjectAttribute->ContentClassAttributeID;
00158         $contentObjectID = $contentObjectAttribute->ContentObjectID;
00159         $contentObjectVersion = $contentObjectAttribute->Version;
00160 
00161         $obj = $contentObjectAttribute->object();
00162         //get eZContentObjectVersion
00163         $currVerobj = $obj->version( $contentObjectVersion );
00164         // get array of language codes
00165         $transList = $currVerobj->translations( false );
00166         $countTsl = count( $transList );
00167 
00168         if ( ( $countTsl == 1 ) )
00169         {
00170              eZContentObject::fetch( $contentObjectID )->removeContentObjectRelation( false, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
00171         }
00172 
00173         $objectID = $contentObjectAttribute->attribute( "data_int" );
00174 
00175         if ( $objectID )
00176         {
00177             eZContentObject::fetch( $contentObjectID )->addContentObjectRelation( $objectID, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
00178         }
00179     }
00180 
00181     function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
00182     {
00183         $selectionTypeName = 'ContentClass_ezobjectrelation_selection_type_' . $classAttribute->attribute( 'id' );
00184         $state = eZInputValidator::STATE_ACCEPTED;
00185         if ( $http->hasPostVariable( $selectionTypeName ) )
00186         {
00187             $selectionType = $http->postVariable( $selectionTypeName );
00188             if ( $selectionType < 0 and
00189                  $selectionType > 2 )
00190             {
00191                 $state = eZInputValidator::STATE_INVALID;
00192             }
00193         }
00194         return $state;
00195     }
00196 
00197     function fixupClassAttributeHTTPInput( $http, $base, $classAttribute )
00198     {
00199     }
00200 
00201     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00202     {
00203         $selectionTypeName = 'ContentClass_ezobjectrelation_selection_type_' . $classAttribute->attribute( 'id' );
00204         $content = $classAttribute->content();
00205         $hasData = false;
00206         if ( $http->hasPostVariable( $selectionTypeName ) )
00207         {
00208             $selectionType = $http->postVariable( $selectionTypeName );
00209             $content['selection_type'] = $selectionType;
00210             $hasData = true;
00211         }
00212         $helperName = 'ContentClass_ezobjectrelation_selection_fuzzy_match_helper_' . $classAttribute->attribute( 'id' );
00213         if ( $http->hasPostVariable( $helperName ) )
00214         {
00215             $fuzzyMatchName = 'ContentClass_ezobjectrelation_selection_fuzzy_match_' . $classAttribute->attribute( 'id' );
00216             $content['fuzzy_match'] = false;
00217             $hasData = true;
00218             if ( $http->hasPostVariable( $fuzzyMatchName ) )
00219             {
00220                 $content['fuzzy_match'] = true;
00221             }
00222         }
00223         if ( $hasData )
00224         {
00225             $classAttribute->setContent( $content );
00226             return true;
00227         }
00228         return false;
00229     }
00230 
00231     function preStoreClassAttribute( $classAttribute, $version )
00232     {
00233         $content = $classAttribute->content();
00234         $classAttribute->setAttribute( 'data_int1', $content['selection_type'] );
00235         $classAttribute->setAttribute( 'data_int2', $content['default_selection_node'] );
00236         $classAttribute->setAttribute( 'data_int3', $content['fuzzy_match'] );
00237     }
00238 
00239     /*!
00240      \private
00241      Delete the old version from ezcontentobject_link if count of translations > 1
00242     */
00243     function removeContentObjectRelation( $contentObjectAttribute )
00244     {
00245         $obj = $contentObjectAttribute->object();
00246         $atrributeTrans = $contentObjectAttribute->fetchAttributeTranslations( );
00247         // Check if current relation exists in ezcontentobject_link
00248         foreach ( $atrributeTrans as $attrTarns )
00249         {
00250             if ( $attrTarns->attribute( 'id' ) != $contentObjectAttribute->attribute( 'id' ) )
00251                 if ( $attrTarns->attribute( 'data_int' ) == $contentObjectAttribute->attribute( 'data_int' ) )
00252                      return;
00253         }
00254 
00255         //get eZContentObjectVersion
00256         $currVerobj = $obj->currentVersion();
00257         // get array of ezcontentobjecttranslations
00258         $transList = $currVerobj->translations( false );
00259         // get count of LanguageCode in transList
00260         $countTsl = count( $transList );
00261         // Delete the old version from ezcontentobject_link if count of translations > 1
00262         if ( $countTsl > 1 )
00263         {
00264             $objectID = $contentObjectAttribute->attribute( "data_int" );
00265             $contentClassAttributeID = $contentObjectAttribute->ContentClassAttributeID;
00266             $contentObjectID = $contentObjectAttribute->ContentObjectID;
00267             $contentObjectVersion = $contentObjectAttribute->Version;
00268             eZContentObject::fetch( $contentObjectID )->removeContentObjectRelation( $objectID, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
00269         }
00270     }
00271 
00272     function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
00273     {
00274         switch ( $action )
00275         {
00276             case "set_object_relation" :
00277             {
00278                 if ( $http->hasPostVariable( 'BrowseActionName' ) and
00279                           $http->postVariable( 'BrowseActionName' ) == ( 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ) ) and
00280                           $http->hasPostVariable( "SelectedObjectIDArray" ) )
00281                 {
00282                     if ( !$http->hasPostVariable( 'BrowseCancelButton' ) )
00283                     {
00284                         $selectedObjectArray = $http->hasPostVariable( "SelectedObjectIDArray" );
00285                         $selectedObjectIDArray = $http->postVariable( "SelectedObjectIDArray" );
00286 
00287                         // Delete the old version from ezcontentobject_link if count of translations > 1
00288                         $this->removeContentObjectRelation( $contentObjectAttribute );
00289 
00290                         $objectID = $selectedObjectIDArray[0];
00291                         $contentObjectAttribute->setAttribute( 'data_int', $objectID );
00292                         $contentObjectAttribute->store();
00293                     }
00294                 }
00295             } break;
00296 
00297             case "browse_object" :
00298             {
00299                 $module = $parameters['module'];
00300                 $redirectionURI = $parameters['current-redirection-uri'];
00301                 $ini = eZINI::instance( 'content.ini' );
00302 
00303                 $browseParameters = array( 'action_name' => 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ),
00304                                            'type' =>  'AddRelatedObjectToDataType',
00305                                            'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $contentObjectAttribute->attribute( 'id' ) . '_set_object_relation]',
00306                                                                             'value' => $contentObjectAttribute->attribute( 'id' ) ),
00307                                            'persistent_data' => array( 'HasObjectInput' => 0 ),
00308                                            'from_page' => $redirectionURI );
00309                 $browseTypeINIVariable = $ini->variable( 'ObjectRelationDataTypeSettings', 'ClassAttributeStartNode' );
00310                 foreach( $browseTypeINIVariable as $value )
00311                 {
00312                     list( $classAttributeID, $type ) = explode( ';',$value );
00313                     if ( $classAttributeID == $contentObjectAttribute->attribute( 'contentclassattribute_id' ) && strlen( $type ) > 0 )
00314                     {
00315                         $browseParameters['type'] = $type;
00316                         break;
00317                     }
00318                 }
00319 
00320                 $nodePlacementName = $parameters['base_name'] . '_browse_for_object_start_node';
00321                 if ( $http->hasPostVariable( $nodePlacementName ) )
00322                 {
00323                     $nodePlacement = $http->postVariable( $nodePlacementName );
00324                     if ( isset( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ) )
00325                         $browseParameters['start_node'] = eZContentBrowse::nodeAliasID( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] );
00326                 }
00327                 eZContentBrowse::browse( $browseParameters,
00328                                          $module );
00329             } break;
00330 
00331             case "remove_object" :
00332             {
00333                 // Delete the old version from ezcontentobject_link if count of translations > 1
00334                 $this->removeContentObjectRelation( $contentObjectAttribute );
00335 
00336                 $contentObjectAttribute->setAttribute( 'data_int', 0 );
00337                 $contentObjectAttribute->store();
00338             } break;
00339 
00340             default :
00341             {
00342                 eZDebug::writeError( "Unknown custom HTTP action: " . $action, "eZObjectRelationType" );
00343             } break;
00344         }
00345     }
00346 
00347     /*!
00348      Returns the content.
00349     */
00350     function objectAttributeContent( $contentObjectAttribute )
00351     {
00352         $objectID = $contentObjectAttribute->attribute( "data_int" );
00353         if ( $objectID != 0 )
00354             $object = eZContentObject::fetch( $objectID );
00355         else
00356             $object = null;
00357         return $object;
00358     }
00359 
00360     /*!
00361      Sets \c grouped_input to \c true when browse mode is active or
00362      a dropdown with a fuzzy match is used.
00363     */
00364     function objectDisplayInformation( $objectAttribute, $mergeInfo = false )
00365     {
00366         $classAttribute = $objectAttribute->contentClassAttribute();
00367         $content = $this->classAttributeContent( $classAttribute );
00368         $editGrouped = ( $content['selection_type'] == 0 or
00369                          ( $content['selection_type'] == 1 and $content['fuzzy_match'] ) );
00370 
00371         $info = array( 'edit' => array( 'grouped_input' => $editGrouped ),
00372                        'collection' => array( 'grouped_input' => $editGrouped ) );
00373         return eZDataType::objectDisplayInformation( $objectAttribute, $info );
00374     }
00375 
00376     function sortKey( $contentObjectAttribute )
00377     {
00378         return $contentObjectAttribute->attribute( 'data_int' );
00379     }
00380 
00381     function sortKeyType()
00382     {
00383         return 'int';
00384     }
00385 
00386     function classAttributeContent( $classObjectAttribute )
00387     {
00388         $selectionType = $classObjectAttribute->attribute( "data_int1" );
00389         $defaultSelectionNode = $classObjectAttribute->attribute( "data_int2" );
00390         $fuzzyMatch = $classObjectAttribute->attribute( "data_int3" );
00391         return array( 'selection_type' => $selectionType,
00392                       'default_selection_node' => $defaultSelectionNode,
00393                       'fuzzy_match' => $fuzzyMatch );
00394     }
00395 
00396     function customClassAttributeHTTPAction( $http, $action, $classAttribute )
00397     {
00398         switch ( $action )
00399         {
00400             case 'browse_for_selection_node':
00401             {
00402                 $module = $classAttribute->currentModule();
00403                 $customActionName = 'CustomActionButton[' . $classAttribute->attribute( 'id' ) . '_browsed_for_selection_node]';
00404                 eZContentBrowse::browse( array( 'action_name' => 'SelectObjectRelationNode',
00405                                                 'content' => array( 'contentclass_id' => $classAttribute->attribute( 'contentclass_id' ),
00406                                                                     'contentclass_attribute_id' => $classAttribute->attribute( 'id' ),
00407                                                                     'contentclass_version' => $classAttribute->attribute( 'version' ),
00408                                                                     'contentclass_attribute_identifier' => $classAttribute->attribute( 'identifier' ) ),
00409                                                 'persistent_data' => array( $customActionName => '',
00410                                                                             'ContentClassHasInput' => false ),
00411                                                 'description_template' => 'design:class/datatype/browse_objectrelation_placement.tpl',
00412                                                 'from_page' => $module->currentRedirectionURI() ),
00413                                          $module );
00414             } break;
00415             case 'browsed_for_selection_node':
00416             {
00417                 $nodeSelection = eZContentBrowse::result( 'SelectObjectRelationNode' );
00418                 if ( count( $nodeSelection ) > 0 )
00419                 {
00420                     $nodeID = $nodeSelection[0];
00421                     $content = $classAttribute->content();
00422                     $content['default_selection_node'] = $nodeID;
00423                     $classAttribute->setContent( $content );
00424                 }
00425             } break;
00426             case 'disable_selection_node':
00427             {
00428                 $content = $classAttribute->content();
00429                 $content['default_selection_node'] = false;
00430                 $classAttribute->setContent( $content );
00431             } break;
00432             default:
00433             {
00434                 eZDebug::writeError( "Unknown objectrelationlist action '$action'", __METHOD__ );
00435             } break;
00436         }
00437     }
00438 
00439     /*!
00440      Returns the meta data used for storing search indeces.
00441     */
00442     function metaData( $contentObjectAttribute )
00443     {
00444         $object = $this->objectAttributeContent( $contentObjectAttribute );
00445         if ( $object )
00446         {
00447             if ( eZContentObject::recursionProtect( $object->attribute( 'id' ) ) )
00448             {
00449                 // Does the related object exist in the same language as the current content attribute ?
00450                 if ( in_array( $contentObjectAttribute->attribute( 'language_code' ), $object->attribute( 'current' )->translationList( false, false ) ) )
00451                 {
00452                     $attributes = $object->attribute( 'current' )->contentObjectAttributes( $contentObjectAttribute->attribute( 'language_code' ) );
00453                 }
00454                 else
00455                 {
00456                     $attributes = $object->contentObjectAttributes();
00457                 }
00458 
00459                 return eZContentObjectAttribute::metaDataArray( $attributes );
00460             }
00461             else
00462             {
00463                 return array();
00464             }
00465         }
00466         return false;
00467     }
00468     /*!
00469      \return string representation of an contentobjectattribute data for simplified export
00470 
00471     */
00472     function toString( $contentObjectAttribute )
00473     {
00474         return $contentObjectAttribute->attribute( 'data_int' );
00475     }
00476 
00477     function fromString( $contentObjectAttribute, $string )
00478     {
00479         if ( !is_numeric( $string ) || !eZContentObject::fetch( $string ) )
00480             return false;
00481 
00482         $contentObjectAttribute->setAttribute( 'data_int', $string );
00483         return true;
00484     }
00485 
00486     function isIndexable()
00487     {
00488         return true;
00489     }
00490 
00491     /*!
00492      Returns the content of the string for use as a title
00493     */
00494     function title( $contentObjectAttribute, $name = null )
00495     {
00496         $object = $this->objectAttributeContent( $contentObjectAttribute );
00497         if ( $object )
00498         {
00499             return $object->attribute( 'name' );
00500         }
00501         return false;
00502     }
00503 
00504     function hasObjectAttributeContent( $contentObjectAttribute )
00505     {
00506         $object = $this->objectAttributeContent( $contentObjectAttribute );
00507         if ( $object )
00508             return true;
00509         return false;
00510     }
00511 
00512     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00513     {
00514         $content = $classAttribute->content();
00515         $dom = $attributeParametersNode->ownerDocument;
00516         $selectionTypeNode = $dom->createElement( 'selection-type' );
00517         $selectionTypeNode->setAttribute( 'id', $content['selection_type'] );
00518         $attributeParametersNode->appendChild( $selectionTypeNode );
00519         $fuzzyMatchNode = $dom->createElement( 'fuzzy-match' );
00520         $fuzzyMatchNode->setAttribute( 'id', $content['fuzzy_match'] );
00521         $attributeParametersNode->appendChild( $fuzzyMatchNode );
00522         if ( $content['default_selection_node'] )
00523         {
00524             $defaultSelectionNode = $dom->createElement( 'default-selection' );
00525             $defaultSelectionNode->setAttribute( 'node-id', $content['default_selection_node'] );
00526             $attributeParametersNode->appendChild( $defaultSelectionNode );
00527         }
00528     }
00529 
00530     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00531     {
00532         $content = $classAttribute->content();
00533         $selectionTypeNode = $attributeParametersNode->getElementsByTagName( 'selection-type' )->item( 0 );
00534         $content['selection_type'] = 0;
00535         if ( $selectionTypeNode )
00536             $content['selection_type'] = $selectionTypeNode->getAttribute( 'id' );
00537 
00538         $fuzzyMatchNode = $attributeParametersNode->getElementsByTagName( 'fuzzy-match' )->item( 0 );
00539         $content['fuzzy_match'] = false;
00540         if ( $fuzzyMatchNode )
00541             $content['fuzzy_match'] = $fuzzyMatchNode->getAttribute( 'id' );
00542 
00543         $defaultSelectionNode = $attributeParametersNode->getElementsByTagName( 'default-selection' )->item( 0 );
00544         $content['default_selection_node'] = false;
00545         if ( $defaultSelectionNode )
00546             $content['default_selection_node'] = $defaultSelectionNode->getAttribute( 'node-id' );
00547 
00548         $classAttribute->setContent( $content );
00549         $classAttribute->store();
00550     }
00551 
00552     /*!
00553      Export related object's remote_id.
00554     */
00555     function serializeContentObjectAttribute( $package, $objectAttribute )
00556     {
00557         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
00558         $relatedObjectID = $objectAttribute->attribute( 'data_int' );
00559 
00560         if ( $relatedObjectID !== null )
00561         {
00562             $relatedObject = eZContentObject::fetch( $relatedObjectID );
00563             if ( !$relatedObject )
00564             {
00565                 eZDebug::writeNotice( 'Related object with ID: ' . $relatedObjectID . ' does not exist.' );
00566             }
00567             else
00568             {
00569                 $relatedObjectRemoteID = $relatedObject->attribute( 'remote_id' );
00570                 $dom = $node->ownerDocument;
00571                 $relatedObjectRemoteIDNode = $dom->createElement( 'related-object-remote-id' );
00572                 $relatedObjectRemoteIDNode->appendChild( $dom->createTextNode( $relatedObjectRemoteID ) );
00573                 $node->appendChild( $relatedObjectRemoteIDNode );
00574             }
00575         }
00576 
00577         return $node;
00578     }
00579 
00580     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
00581     {
00582         $relatedObjectRemoteIDNode = $attributeNode->getElementsByTagName( 'related-object-remote-id' )->item( 0 );
00583         $relatedObjectID = null;
00584 
00585         if ( $relatedObjectRemoteIDNode )
00586         {
00587             $relatedObjectRemoteID = $relatedObjectRemoteIDNode->textContent;
00588             $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID );
00589             if ( $object )
00590             {
00591                 $relatedObjectID = $object->attribute( 'id' );
00592             }
00593             else
00594             {
00595                 // store remoteID so it can be used in postUnserialize
00596                 $objectAttribute->setAttribute( 'data_text', $relatedObjectRemoteID );
00597             }
00598         }
00599 
00600         $objectAttribute->setAttribute( 'data_int', $relatedObjectID );
00601     }
00602 
00603     function postUnserializeContentObjectAttribute( $package, $objectAttribute )
00604     {
00605         $attributeChanged = false;
00606         $relatedObjectID = $objectAttribute->attribute( 'data_int' );
00607 
00608         if ( !$relatedObjectID )
00609         {
00610             // Restore cross-relations using preserved remoteID
00611             $relatedObjectRemoteID = $objectAttribute->attribute( 'data_text' );
00612             if ( $relatedObjectRemoteID)
00613             {
00614                 $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID );
00615                 $relatedObjectID = ( $object !== null ) ? $object->attribute( 'id' ) : null;
00616 
00617                 if ( $relatedObjectID )
00618                 {
00619                     $objectAttribute->setAttribute( 'data_int', $relatedObjectID );
00620                     $attributeChanged = true;
00621                 }
00622             }
00623         }
00624 
00625         return $attributeChanged;
00626     }
00627 
00628     /*!
00629      Removes objects with given ID from the relations list
00630     */
00631     function removeRelatedObjectItem( $contentObjectAttribute, $objectID )
00632     {
00633         $contentObjectAttribute->setAttribute( "data_int", null );
00634         return true;
00635     }
00636 
00637     function supportsBatchInitializeObjectAttribute()
00638     {
00639         return true;
00640     }
00641 
00642     /// \privatesection
00643 }
00644 
00645 eZDataType::register( eZObjectRelationType::DATA_TYPE_STRING, "eZObjectRelationType" );
00646 
00647 ?>