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