00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 include_once( 'kernel/classes/ezdatatype.php' );
00046 include_once( 'kernel/classes/ezcontentobject.php' );
00047 include_once( 'lib/ezutils/classes/ezintegervalidator.php' );
00048 include_once( 'lib/ezutils/classes/ezinputvalidator.php' );
00049 include_once( 'lib/ezi18n/classes/eztranslatormanager.php' );
00050 include_once( 'lib/ezxml/classes/ezxml.php' );
00051
00052 define( "EZ_DATATYPESTRING_OBJECT_RELATION_LIST", "ezobjectrelationlist" );
00053
00054 class eZObjectRelationListType extends eZDataType
00055 {
00056
00057
00058
00059 function eZObjectRelationListType()
00060 {
00061 $this->eZDataType( EZ_DATATYPESTRING_OBJECT_RELATION_LIST, ezi18n( 'kernel/classes/datatypes', "Object relations", 'Datatype name' ),
00062 array( 'serialize_supported' => true ) );
00063 }
00064
00065
00066
00067
00068
00069 function validateObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
00070 {
00071 $inputParameters =& $contentObjectAttribute->inputParameters();
00072 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute();
00073 $parameters = $contentObjectAttribute->validationParameters();
00074 if ( isset( $parameters['prefix-name'] ) and
00075 $parameters['prefix-name'] )
00076 $parameters['prefix-name'][] = $contentClassAttribute->attribute( 'name' );
00077 else
00078 $parameters['prefix-name'] = array( $contentClassAttribute->attribute( 'name' ) );
00079
00080 $status = EZ_INPUT_VALIDATOR_STATE_ACCEPTED;
00081 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" );
00082 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute();
00083 $classContent = $contentClassAttribute->content();
00084
00085 if ( $classContent['selection_type'] != 0 )
00086 {
00087 $selectedObjectIDArray = $http->hasPostVariable( $postVariableName ) ? $http->postVariable( $postVariableName ) : false;
00088 if ( $contentObjectAttribute->validateIsRequired() and $selectedObjectIDArray === false )
00089 {
00090 $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00091 'Missing objectrelation list input.' ) );
00092 return EZ_INPUT_VALIDATOR_STATE_INVALID;
00093 }
00094 return $status;
00095 }
00096
00097 $content =& $contentObjectAttribute->content();
00098 if ( $contentObjectAttribute->validateIsRequired() and count( $content['relation_list'] ) == 0 )
00099 {
00100 $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
00101 'Missing objectrelation list input.' ) );
00102 return EZ_INPUT_VALIDATOR_STATE_INVALID;
00103 }
00104
00105 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00106 {
00107 $relationItem = $content['relation_list'][$i];
00108 if ( $relationItem['is_modified'] )
00109 {
00110 $subObjectID = $relationItem['contentobject_id'];
00111 $subObjectVersion = $relationItem['contentobject_version'];
00112 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID;
00113 $object =& eZContentObject::fetch( $subObjectID );
00114 if ( $object )
00115 {
00116 $attributes =& $object->contentObjectAttributes( true, $subObjectVersion );
00117
00118 $validationResult = $object->validateInput( $attributes, $attributeBase,
00119 $inputParameters, $parameters );
00120 $inputValidated = $validationResult['input-validated'];
00121 $content['temp'][$subObjectID]['require-fixup'] = $validationResult['require-fixup'];
00122 $statusMap = $validationResult['status-map'];
00123 foreach ( $statusMap as $statusItem )
00124 {
00125 $statusValue = $statusItem['value'];
00126 $statusAttribute =& $statusItem['attribute'];
00127 if ( $statusValue == EZ_INPUT_VALIDATOR_STATE_INTERMEDIATE and
00128 $status == EZ_INPUT_VALIDATOR_STATE_ACCEPTED )
00129 $status = EZ_INPUT_VALIDATOR_STATE_INTERMEDIATE;
00130 else if ( $statusValue == EZ_INPUT_VALIDATOR_STATE_INVALID )
00131 {
00132 $contentObjectAttribute->setHasValidationError( false );
00133 $status = EZ_INPUT_VALIDATOR_STATE_INVALID;
00134 }
00135 }
00136
00137 $content['temp'][$subObjectID]['attributes'] =& $attributes;
00138 $content['temp'][$subObjectID]['object'] =& $object;
00139 }
00140 }
00141 }
00142 return $status;
00143 }
00144
00145
00146
00147
00148
00149 function fixupObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
00150 {
00151 $content =& $contentObjectAttribute->content();
00152 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00153 {
00154 $relationItem = $content['relation_list'][$i];
00155 if ( $relationItem['is_modified'] )
00156 {
00157 $subObjectID = $relationItem['contentobject_id'];
00158 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID;
00159 $object =& $content['temp'][$subObjectID]['object'];
00160 $requireFixup = $content['temp'][$subObjectID]['require-fixup'];
00161 if ( $object and
00162 $requireFixup )
00163 {
00164 $attributes =& $content['temp'][$subObjectID]['attributes'];
00165 $object->fixupInput( $attributes, $attributeBase );
00166 }
00167 }
00168 }
00169 }
00170
00171
00172
00173
00174 function fetchObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
00175 {
00176 $content =& $contentObjectAttribute->content();
00177
00178 $newObjectPostVariableName = "attribute_" . $contentObjectAttribute->attribute( "id" ) . "_new_object_name";
00179 if ( $http->hasPostVariable( $newObjectPostVariableName ) )
00180 {
00181 $name = $http->postVariable( $newObjectPostVariableName );
00182 if ( !empty( $name ) )
00183 {
00184 $content['new_object'] = $name;
00185 }
00186 }
00187 $singleSelectPostVariableName = "single_select_" . $contentObjectAttribute->attribute( "id" );
00188 if ( $http->hasPostVariable( $singleSelectPostVariableName ) )
00189 $content['singleselect'] = true;
00190
00191 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" );
00192 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute();
00193 $classContent = $contentClassAttribute->content();
00194
00195 if ( $classContent['selection_type'] != 0 )
00196 {
00197 $selectedObjectIDArray = $http->hasPostVariable( $postVariableName ) ? $http->postVariable( $postVariableName ) : false;
00198 $priority = 0;
00199
00200 $content['relation_list'] = array();
00201
00202 if ( $selectedObjectIDArray === false or ( isset( $selectedObjectIDArray[0] ) and $selectedObjectIDArray[0] == 'no_relation' ) )
00203 {
00204 $contentObjectAttribute->setContent( $content );
00205 $contentObjectAttribute->store();
00206 return true;
00207 }
00208
00209 foreach ( $selectedObjectIDArray as $objectID )
00210 {
00211
00212 if ( !is_numeric( $objectID ) )
00213 {
00214 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.",
00215 "eZObjectRelationListType::fetchObjectAttributeHTTPInput" );
00216
00217 continue;
00218 }
00219 ++$priority;
00220 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
00221 $contentObjectAttribute->setContent( $content );
00222 $contentObjectAttribute->store();
00223 }
00224 return true;
00225 }
00226
00227 $contentObjectAttributeID = $contentObjectAttribute->attribute( 'id' );
00228 $priorityBase = $base . '_priority';
00229 $priorities = array();
00230 if ( $http->hasPostVariable( $priorityBase ) )
00231 $priorities = $http->postVariable( $priorityBase );
00232 $reorderedRelationList = array();
00233
00234 $existsPriorities = array();
00235
00236 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00237 {
00238 $priorities[$contentObjectAttributeID][$i] = (int) $priorities[$contentObjectAttributeID][$i];
00239 $existsPriorities[$i] = $priorities[$contentObjectAttributeID][$i];
00240
00241
00242 for ( $j = 0; $j < count( $content['relation_list'] ); ++$j )
00243 {
00244 if ( $i == $j ) continue;
00245 if ( $priorities[$contentObjectAttributeID][$i] == $priorities[$contentObjectAttributeID][$j] )
00246 {
00247 $index = $priorities[$contentObjectAttributeID][$i];
00248 while ( in_array( $index, $existsPriorities ) )
00249 ++$index;
00250 $priorities[$contentObjectAttributeID][$j] = $index;
00251 }
00252 }
00253 $relationItem = $content['relation_list'][$i];
00254 if ( $relationItem['is_modified'] )
00255 {
00256 $subObjectID = $relationItem['contentobject_id'];
00257 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID;
00258 $object =& $content['temp'][$subObjectID]['object'];
00259 if ( $object )
00260 {
00261 $attributes =& $content['temp'][$subObjectID]['attributes'];
00262
00263 $customActionAttributeArray = array();
00264 $fetchResult = $object->fetchInput( $attributes, $attributeBase,
00265 $customActionAttributeArray,
00266 $contentObjectAttribute->inputParameters() );
00267 unset( $attributeInputMap );
00268 $attributeInputMap =& $fetchResult['attribute-input-map'];
00269 $content['temp'][$subObjectID]['attribute-input-map'] =& $attributeInputMap;
00270 $content['temp'][$subObjectID]['attributes'] =& $attributes;
00271 $content['temp'][$subObjectID]['object'] =& $object;
00272 }
00273 }
00274 if ( isset( $priorities[$contentObjectAttributeID][$i] ) )
00275 $relationItem['priority'] = $priorities[$contentObjectAttributeID][$i];
00276 $reorderedRelationList[$relationItem['priority']] = $relationItem;
00277 }
00278 ksort( $reorderedRelationList );
00279 unset( $content['relation_list'] );
00280 $content['relation_list'] = array();
00281 reset( $reorderedRelationList );
00282 $i = 0;
00283 while ( list( $key, $relationItem ) = each( $reorderedRelationList ) )
00284 {
00285 $content['relation_list'][] = $relationItem;
00286 $content['relation_list'][$i]['priority'] = $i + 1;
00287 ++$i;
00288 }
00289 $contentObjectAttribute->setContent( $content );
00290 return true;
00291 }
00292
00293 function createNewObject( &$contentObjectAttribute, $name )
00294 {
00295 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' );
00296 $classContent = $classAttribute->content();
00297 $classID = $classContent['object_class'];
00298 if ( !isset( $classID ) or !is_numeric( $classID ) )
00299 return false;
00300
00301 $defaultPlacementNode = ( is_array( $classContent['default_placement'] ) and isset( $classContent['default_placement']['node_id'] ) ) ? $classContent['default_placement']['node_id'] : false;
00302 if ( !$defaultPlacementNode )
00303 {
00304 eZDebug::writeError( 'Default placement is missing', 'eZObjectRelationListType::createNewObject' );
00305 return false;
00306 }
00307
00308 $node =& eZContentObjectTreeNode::fetch( $defaultPlacementNode );
00309
00310 if ( !$node or !$node->canCreate() )
00311 {
00312 eZDebug::writeError( 'Default placement is wrong or the current user can\'t create a new node as child of this node.', 'eZObjectRelationListType::createNewObject' );
00313 return false;
00314 }
00315
00316 $classList =& $node->canCreateClassList( false );
00317 $canCreate = false;
00318
00319 foreach ( $classList as $class )
00320 {
00321 if ( $class['id'] == $classID )
00322 {
00323 $canCreate = true;
00324 break;
00325 }
00326 }
00327 if ( !$canCreate )
00328 {
00329 eZDebug::writeError( 'The current user is not allowed to create objects of class (ID=' . $classID . ')', 'eZObjectRelationListType::createNewObject' );
00330 return false;
00331 }
00332
00333 $class =& eZContentClass::fetch( $classID );
00334 if ( !$class )
00335 return false;
00336
00337 $currentObject =& $contentObjectAttribute->attribute( 'object' );
00338 $sectionID = $currentObject->attribute( 'section_id' );
00339
00340 $newObjectInstance =& $class->instantiate( false, $sectionID );
00341 $nodeassignment = $newObjectInstance->createNodeAssignment( $defaultPlacementNode, true );
00342 $nodeassignment->store();
00343 $newObjectInstance->sync();
00344 include_once( "lib/ezutils/classes/ezoperationhandler.php" );
00345 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObjectInstance->attribute( 'id' ), 'version' => 1 ) );
00346
00347 $newObjectInstance->rename( $name );
00348
00349 return $newObjectInstance->attribute( 'id' );
00350 }
00351
00352
00353
00354 function storeObjectAttribute( &$attribute )
00355 {
00356 $content = $attribute->content();
00357 if ( isset( $content['new_object'] ) )
00358 {
00359 $newID = $this->createNewObject( $attribute, $content['new_object'] );
00360
00361 if ( $newID )
00362 {
00363 if ( isset( $content['singleselect'] ) )
00364 $content['relation_list'] = array();
00365 $content['relation_list'][] = $this->appendObject( $newID, 0, $attribute );
00366 }
00367 unset( $content['new_object'] );
00368 $attribute->setContent( $content );
00369 $attribute->store();
00370 }
00371
00372 $contentClassAttributeID = $attribute->ContentClassAttributeID;
00373 $contentObjectID = $attribute->ContentObjectID;
00374 $contentObjectVersion = $attribute->Version;
00375
00376 $obj = $attribute->object();
00377
00378 $currVerobj = $obj->version( $contentObjectVersion );
00379
00380
00381
00382 $translationList =& $currVerobj->translations( false );
00383
00384
00385 $langCode = $attribute->attribute( 'language_code' );
00386
00387 $countTsl = count( $translationList );
00388
00389 sort( $translationList );
00390
00391 if ( ( $countTsl == 1 ) or ( $countTsl > 1 and $translationList[0] == $langCode ) )
00392 {
00393 eZContentObject::removeContentObjectRelation( false, $contentObjectVersion, $contentObjectID, $contentClassAttributeID, EZ_CONTENT_OBJECT_RELATION_ATTRIBUTE );
00394 }
00395
00396 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00397 {
00398 $relationItem =& $content['relation_list'][$i];
00399
00400
00401
00402 if ( !$relationItem['contentobject_id'] || !isset( $relationItem['contentobject_id'] ) )
00403 continue;
00404
00405 $subObjectID = $relationItem['contentobject_id'];
00406 $subObjectVersion = $relationItem['contentobject_version'];
00407
00408 eZContentObject::addContentObjectRelation( $subObjectID, $contentObjectVersion, $contentObjectID, $contentClassAttributeID, EZ_CONTENT_OBJECT_RELATION_ATTRIBUTE );
00409
00410 if ( $relationItem['is_modified'] )
00411 {
00412
00413 $object =& $content['temp'][$subObjectID]['object'];
00414 if ( $object )
00415 {
00416 $attributes =& $content['temp'][$subObjectID]['attributes'];
00417 $attributeInputMap =& $content['temp'][$subObjectID]['attribute-input-map'];
00418 $object->storeInput( $attributes,
00419 $attributeInputMap );
00420 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID );
00421 if ( $version )
00422 {
00423 $version->setAttribute( 'modified', time() );
00424 $version->setAttribute( 'status', EZ_VERSION_STATUS_DRAFT );
00425 $version->store();
00426 }
00427
00428 $object->setAttribute( 'status', EZ_CONTENT_OBJECT_STATUS_DRAFT );
00429 $object->store();
00430 }
00431 }
00432 }
00433 return eZObjectRelationListType::storeObjectAttributeContent( $attribute, $content );
00434 }
00435
00436
00437
00438
00439 function onPublish( &$contentObjectAttribute, &$contentObject, &$publishedNodes )
00440 {
00441 $content = $contentObjectAttribute->content();
00442 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00443 {
00444 $relationItem =& $content['relation_list'][$i];
00445 if ( $relationItem['is_modified'] )
00446 {
00447 $subObjectID = $relationItem['contentobject_id'];
00448 $subObjectVersion = $relationItem['contentobject_version'];
00449 $object =& eZContentObject::fetch( $subObjectID );
00450
00451 if ( $object )
00452 {
00453 $class =& $object->contentClass();
00454 $time = time();
00455
00456
00457 $currentVersion =& $object->currentVersion();
00458 $currentVersion->setAttribute( 'status', EZ_VERSION_STATUS_ARCHIVED );
00459 $currentVersion->setAttribute( 'modified', $time );
00460 $currentVersion->store();
00461
00462 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID );
00463 $version->setAttribute( 'modified', $time );
00464 $version->setAttribute( 'status', EZ_VERSION_STATUS_PUBLISHED );
00465 $version->store();
00466 $object->setAttribute( 'status', EZ_CONTENT_OBJECT_STATUS_PUBLISHED );
00467 if ( !$object->attribute( 'published' ) )
00468 $object->setAttribute( 'published', $time );
00469 $object->setAttribute( 'modified', $time );
00470 $object->setAttribute( 'current_version', $version->attribute( 'version' ) );
00471 $object->setAttribute( 'is_published', true );
00472 $objectName = $class->contentObjectName( $object, $version->attribute( 'version' ) );
00473 $object->setName( $objectName, $version->attribute( 'version' ) );
00474 $object->store();
00475 }
00476 if ( $relationItem['parent_node_id'] > 0 )
00477 {
00478 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $relationItem['parent_node_id'], false ) )
00479 {
00480 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ),
00481 'contentobject_version' => $object->attribute( 'current_version' ),
00482 'parent_node' => $relationItem['parent_node_id'],
00483 'sort_field' => 2,
00484 'sort_order' => 0,
00485 'is_main' => 1 ) );
00486 $nodeAssignment->store();
00487 }
00488 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $object->attribute( 'id' ),
00489 'version' => $object->attribute( 'current_version' ) ) );
00490 $objectNodeID = $object->attribute( 'main_node_id' );
00491 $content['relation_list'][$i]['node_id'] = $objectNodeID;
00492 }
00493 else
00494 {
00495 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $contentObject->attribute( 'main_node_id' ), false ) )
00496 {
00497 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ),
00498 'contentobject_version' => $object->attribute( 'current_version' ),
00499 'parent_node' => $contentObject->attribute( 'main_node_id' ),
00500 'sort_field' => 2,
00501 'sort_order' => 0,
00502 'is_main' => 1 ) );
00503 $nodeAssignment->store();
00504 }
00505 }
00506 $content['relation_list'][$i]['is_modified'] = false;
00507 }
00508 }
00509 eZObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content );
00510 $contentObjectAttribute->setContent( $content );
00511 $contentObjectAttribute->store();
00512 }
00513
00514 function initializeObjectAttribute( &$contentObjectAttribute, $currentVersion, &$originalContentObjectAttribute )
00515 {
00516
00517 static $copiedRelatedAccordance;
00518 if ( !isset( $copiedRelatedAccordance ) )
00519 $copiedRelatedAccordance = array();
00520
00521 if ( $currentVersion != false )
00522 {
00523 $dataText = $originalContentObjectAttribute->attribute( 'data_text' );
00524 $contentObjectAttribute->setAttribute( 'data_text', $dataText );
00525 $contentObjectID = $contentObjectAttribute->attribute( 'contentobject_id' );
00526 $originalContentObjectID = $originalContentObjectAttribute->attribute( 'contentobject_id' );
00527
00528 if ( $contentObjectID != $originalContentObjectID )
00529 {
00530 $classContent = eZObjectRelationListType::defaultClassAttributeContent();
00531 if ( !$classContent['default_placement'] )
00532 {
00533 $content = $originalContentObjectAttribute->content();
00534 $contentModified = false;
00535
00536 foreach ( array_keys( $content['relation_list'] ) as $key )
00537 {
00538 $relationItem =& $content['relation_list'][$key];
00539
00540
00541 $object =& eZContentObject::fetch( $relationItem['contentobject_id'] );
00542 $mainNode = $object->attribute( 'main_node' );
00543
00544 if ( is_object( $mainNode ) )
00545 {
00546 $node = ( is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] ) ?
00547 eZContentObjectTreeNode::fetch( $relationItem['node_id'] ) : null;
00548
00549 if ( !$node or $node->attribute( 'contentobject_id' ) != $relationItem['contentobject_id'] )
00550 {
00551 $relationItem['node_id'] = $mainNode->attribute( 'node_id' );
00552 $node = $mainNode;
00553 $contentModified = true;
00554 }
00555
00556 $parentNodeID = $node->attribute( 'parent_node_id' );
00557 if ( $relationItem['parent_node_id'] != $parentNodeID )
00558 {
00559 $relationItem['parent_node_id'] = $parentNodeID;
00560 $contentModified = true;
00561 }
00562 }
00563 else
00564 {
00565 if ( !isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) )
00566 $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] = array();
00567
00568 if ( isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) and
00569 isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] ) )
00570 {
00571 $newObjectID = $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ][ 'to' ];
00572 }
00573 else
00574 {
00575 $newObject =& $object->copy( true );
00576 $newObjectID = $newObject->attribute( 'id' );
00577 $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] = array( 'to' => $newObjectID,
00578 'from' => $originalContentObjectID );
00579 }
00580 $relationItem['contentobject_id'] = $newObjectID;
00581 $contentModified = true;
00582 }
00583 }
00584
00585 if ( $contentModified )
00586 {
00587 $contentObjectAttribute->setContent( $content );
00588 $contentObjectAttribute->store();
00589 }
00590 }
00591 }
00592 }
00593 }
00594
00595
00596
00597
00598 function validateClassAttributeHTTPInput( &$http, $base, &$classAttribute )
00599 {
00600 return EZ_INPUT_VALIDATOR_STATE_ACCEPTED;
00601 }
00602
00603
00604
00605
00606 function fixupClassAttributeHTTPInput( &$http, $base, &$classAttribute )
00607 {
00608 }
00609
00610
00611
00612
00613 function fetchClassAttributeHTTPInput( &$http, $base, &$classAttribute )
00614 {
00615 $content = $classAttribute->content();
00616 $postVariable = 'ContentClass_ezobjectrelationlist_class_list_' . $classAttribute->attribute( 'id' );
00617 if ( $http->hasPostVariable( $postVariable ) )
00618 {
00619 $constrainedList = $http->postVariable( $postVariable );
00620 $constrainedClassList = array();
00621 foreach ( $constrainedList as $constraint )
00622 {
00623 if ( trim( $constraint ) != '' )
00624 $constrainedClassList[] = $constraint;
00625 }
00626 $content['class_constraint_list'] = $constrainedClassList;
00627 }
00628 $typeVariable = 'ContentClass_ezobjectrelationlist_type_' . $classAttribute->attribute( 'id' );
00629 if ( $http->hasPostVariable( $typeVariable ) )
00630 {
00631 $type = $http->postVariable( $typeVariable );
00632 $content['type'] = $type;
00633 }
00634 $selectionTypeVariable = 'ContentClass_ezobjectrelationlist_selection_type_' . $classAttribute->attribute( 'id' );
00635 if ( $http->hasPostVariable( $selectionTypeVariable ) )
00636 {
00637 $selectionType = $http->postVariable( $selectionTypeVariable );
00638 $content['selection_type'] = $selectionType;
00639 }
00640 $objectClassVariable = 'ContentClass_ezobjectrelation_object_class_' . $classAttribute->attribute( 'id' );
00641 if ( $http->hasPostVariable( $objectClassVariable ) )
00642 {
00643 $content['object_class'] = $http->postVariable( $objectClassVariable );
00644 }
00645
00646 $classAttribute->setContent( $content );
00647 $classAttribute->store();
00648 return true;
00649 }
00650
00651
00652
00653
00654 function initializeClassAttribute( &$classAttribute )
00655 {
00656 $xmlText = $classAttribute->attribute( 'data_text5' );
00657 if ( trim( $xmlText ) == '' )
00658 {
00659 $content = eZObjectRelationListType::defaultClassAttributeContent();
00660 return eZObjectRelationListType::storeClassAttributeContent( $classAttribute, $content );
00661 }
00662 }
00663
00664
00665
00666
00667 function preStoreClassAttribute( &$classAttribute, $version )
00668 {
00669 $content = $classAttribute->content();
00670 return eZObjectRelationListType::storeClassAttributeContent( $classAttribute, $content );
00671 }
00672
00673 function storeClassAttributeContent( &$classAttribute, $content )
00674 {
00675 if ( is_array( $content ) )
00676 {
00677 $doc = eZObjectRelationListType::createClassDOMDocument( $content );
00678 eZObjectRelationListType::storeClassDOMDocument( $doc, $classAttribute );
00679 return true;
00680 }
00681 return false;
00682 }
00683
00684 function storeObjectAttributeContent( &$objectAttribute, $content )
00685 {
00686 if ( is_array( $content ) )
00687 {
00688 $doc = eZObjectRelationListType::createObjectDOMDocument( $content );
00689 eZObjectRelationListType::storeObjectDOMDocument( $doc, $objectAttribute );
00690 return true;
00691 }
00692 return false;
00693 }
00694
00695 function storeClassDOMDocument( &$doc, &$classAttribute )
00696 {
00697 $docText = eZObjectRelationListType::domString( $doc );
00698 $classAttribute->setAttribute( 'data_text5', $docText );
00699 }
00700
00701 function storeObjectDOMDocument( &$doc, &$objectAttribute )
00702 {
00703 $docText = eZObjectRelationListType::domString( $doc );
00704 $objectAttribute->setAttribute( 'data_text', $docText );
00705 }
00706
00707
00708
00709
00710
00711
00712
00713 function domString( &$domDocument )
00714 {
00715 $ini =& eZINI::instance();
00716 $xmlCharset = $ini->variable( 'RegionalSettings', 'ContentXMLCharset' );
00717 if ( $xmlCharset == 'enabled' )
00718 {
00719 include_once( 'lib/ezi18n/classes/eztextcodec.php' );
00720 $charset = eZTextCodec::internalCharset();
00721 }
00722 else if ( $xmlCharset == 'disabled' )
00723 $charset = true;
00724 else
00725 $charset = $xmlCharset;
00726 if ( $charset !== true )
00727 {
00728 include_once( 'lib/ezi18n/classes/ezcharsetinfo.php' );
00729 $charset = eZCharsetInfo::realCharsetCode( $charset );
00730 }
00731 $domString = $domDocument->toString( $charset );
00732 return $domString;
00733 }
00734
00735 function createClassDOMDocument( $content )
00736 {
00737 $doc = new eZDOMDocument( 'ObjectRelationList' );
00738 $root = $doc->createElementNode( 'related-objects' );
00739 $constraints = $doc->createElementNode( 'constraints' );
00740 foreach ( $content['class_constraint_list'] as $constraintClassIdentifier )
00741 {
00742 unset( $constraintElement );
00743 $constraintElement = $doc->createElementNode( 'allowed-class',
00744 array( 'contentclass-identifier' => $constraintClassIdentifier ) );
00745 $constraints->appendChild( $constraintElement );
00746 }
00747 $root->appendChild( $constraints );
00748 $constraintType = $doc->createElementNode( 'type', array( 'value' => $content['type'] ) );
00749 $root->appendChild( $constraintType );
00750 $selectionType = $doc->createElementNode( 'selection_type', array( 'value' => $content['selection_type'] ) );
00751 $root->appendChild( $selectionType );
00752 $objectClass = $doc->createElementNode( 'object_class', array( 'value' => $content['object_class'] ) );
00753 $root->appendChild( $objectClass );
00754
00755 $placementAttributes = array();
00756 if ( $content['default_placement'] )
00757 $placementAttributes['node-id'] = $content['default_placement']['node_id'];
00758 $root->appendChild( $doc->createElementNode( 'contentobject-placement',
00759 $placementAttributes ) );
00760 $doc->setRoot( $root );
00761 return $doc;
00762 }
00763
00764 function createObjectDOMDocument( $content )
00765 {
00766 $doc = new eZDOMDocument( 'ObjectRelationList' );
00767 $root = $doc->createElementNode( 'related-objects' );
00768 $relationList = $doc->createElementNode( 'relation-list' );
00769 foreach ( $content['relation_list'] as $relationItem )
00770 {
00771 unset( $relationElement );
00772 $relationElement = $doc->createElementNode( 'relation-item' );
00773 $relationElement->appendAttributes( $relationItem,
00774 eZObjectRelationListType::contentObjectArrayXMLMap() );
00775 $relationList->appendChild( $relationElement );
00776 }
00777 $root->appendChild( $relationList );
00778 $doc->setRoot( $root );
00779 return $doc;
00780 }
00781
00782 function contentObjectArrayXMLMap()
00783 {
00784 return array( 'identifier' => 'identifier',
00785 'priority' => 'priority',
00786 'in-trash' => 'in_trash',
00787 'contentobject-id' => 'contentobject_id',
00788 'contentobject-version' => 'contentobject_version',
00789 'node-id' => 'node_id',
00790 'parent-node-id' => 'parent_node_id',
00791 'contentclass-id' => 'contentclass_id',
00792 'contentclass-identifier' => 'contentclass_identifier',
00793 'is-modified' => 'is_modified',
00794 'contentobject-remote-id' => 'contentobject_remote_id' );
00795 }
00796
00797
00798
00799
00800 function deleteStoredObjectAttribute( &$objectAttribute, $version = null )
00801 {
00802 $content =& $objectAttribute->content();
00803 if ( is_array( $content ) and
00804 is_array( $content['relation_list'] ) )
00805 {
00806 $db =& eZDB::instance();
00807 $db->begin();
00808 foreach ( $content['relation_list'] as $deletionItem )
00809 {
00810 eZObjectRelationListType::removeRelationObject( $objectAttribute, $deletionItem );
00811 }
00812 $db->commit();
00813 }
00814 }
00815
00816
00817
00818
00819 function customObjectAttributeHTTPAction( $http, $action, &$contentObjectAttribute, $parameters )
00820 {
00821 $contentobjectID = false;
00822 if ( eZDataType::fetchActionValue( $action, 'new_class', $classID ) or
00823 $action == 'new_class' )
00824 {
00825 if ( $action == 'new_class' )
00826 {
00827 $base = $parameters['base_name'];
00828 $classVariableName = $base . '_new_class';
00829 if ( $http->hasPostVariable( $classVariableName ) )
00830 {
00831 $classVariable = $http->postVariable( $classVariableName );
00832 $classID = $classVariable[$contentObjectAttribute->attribute( 'id' )];
00833 $class = eZContentClass::fetch( $classID );
00834 }
00835 else
00836 return false;
00837 }
00838 else
00839 $class = eZContentClass::fetch( $classID );
00840 if ( $class )
00841 {
00842 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' );
00843 $class_content = $classAttribute->content();
00844 $content = $contentObjectAttribute->content();
00845 $priority = 0;
00846 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
00847 {
00848 if ( $content['relation_list'][$i]['priority'] > $priority )
00849 $priority = $content['relation_list'][$i]['priority'];
00850 }
00851
00852 $base = $parameters['base_name'];
00853 $nodePlacement = false;
00854 $nodePlacementName = $base . '_object_initial_node_placement';
00855 if ( $http->hasPostVariable( $nodePlacementName ) )
00856 {
00857 $nodePlacementMap = $http->postVariable( $nodePlacementName );
00858 if ( isset( $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )] ) )
00859 $nodePlacement = $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )];
00860 }
00861 $relationItem = eZObjectRelationListType::createInstance( $class,
00862 $priority + 1,
00863 $contentObjectAttribute,
00864 $nodePlacement );
00865 if ( $class_content['default_placement'] )
00866 {
00867 $relationItem['parent_node_id'] = $class_content['default_placement']['node_id'];
00868 }
00869
00870 $content['relation_list'][] = $relationItem;
00871
00872 $hasAttributeInput = false;
00873 $attributeInputVariable = $base . '_has_attribute_input';
00874 if ( $http->hasPostVariable( $attributeInputVariable ) )
00875 {
00876 $attributeInputMap = $http->postVariable( $attributeInputVariable );
00877 if ( isset( $attributeInputMap[$contentObjectAttribute->attribute( 'id' )] ) )
00878 $hasAttributeInput = $attributeInputMap[$contentObjectAttribute->attribute( 'id' )];
00879 }
00880
00881 if ( $hasAttributeInput )
00882 {
00883 $object =& $relationItem['object'];
00884 $attributes =& $object->contentObjectAttributes();
00885 foreach ( array_keys( $attributes ) as $key )
00886 {
00887 $attribute =& $attributes[$key];
00888 $attributeBase = $base . '_ezorl_init_class_' . $object->attribute( 'contentclass_id' ) . '_attr_' . $attribute->attribute( 'contentclassattribute_id' );
00889 $oldAttributeID = $attribute->attribute( 'id' );
00890 $attribute->setAttribute( 'id', false );
00891 if ( $attribute->fetchInput( $http, $attributeBase ) )
00892 {
00893 $attribute->setAttribute( 'id', $oldAttributeID );
00894 $attribute->store();
00895 }
00896 }
00897 }
00898
00899 $contentObjectAttribute->setContent( $content );
00900 $contentObjectAttribute->store();
00901 }
00902 else
00903 eZDebug::writeError( "Unknown class ID $classID, cannot instantiate object",
00904 'eZObjectRelationListType::customObjectAttributeHTTPAction' );
00905 }
00906 else if ( eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) or
00907 $action == 'edit_objects' or
00908 $action == 'remove_objects' )
00909 {
00910 $base = $parameters['base_name'];
00911 $selectionBase = $base . '_selection';
00912 $selections = array();
00913 $http =& eZHTTPTool::instance();
00914 if ( $http->hasPostVariable( $selectionBase ) )
00915 {
00916 $selectionMap = $http->postVariable( $selectionBase );
00917 $selections = $selectionMap[$contentObjectAttribute->attribute( 'id' )];
00918 }
00919 if ( $contentobjectID !== false )
00920 $selections[] = $contentobjectID;
00921 if ( $action == 'edit_objects' or
00922 eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) )
00923 {
00924 $content = $contentObjectAttribute->content();
00925 $relationList =& $content['relation_list'];
00926 for ( $i = 0; $i < count( $relationList ); ++$i )
00927 {
00928 $relationItem =& $relationList[$i];
00929 if ( !$relationItem['is_modified'] and
00930 in_array( $relationItem['contentobject_id'], $selections ) )
00931 {
00932 $object =& eZContentObject::fetch( $relationItem['contentobject_id'] );
00933 if ( $object->attribute( 'can_edit' ) )
00934 {
00935 $relationItem['is_modified'] = true;
00936 $version = $object->createNewVersion();
00937 $relationItem['contentobject_version'] = $version->attribute( 'version' );
00938 }
00939 }
00940 }
00941 $contentObjectAttribute->setContent( $content );
00942 $contentObjectAttribute->store();
00943 }
00944 else if ( $action == 'remove_objects' )
00945 {
00946 $content = $contentObjectAttribute->content();
00947 $relationList =& $content['relation_list'];
00948 $newRelationList = array();
00949 for ( $i = 0; $i < count( $relationList ); ++$i )
00950 {
00951 $relationItem = $relationList[$i];
00952 if ( in_array( $relationItem['contentobject_id'], $selections ) )
00953 {
00954 eZObjectRelationListType::removeRelationObject( $contentObjectAttribute, $relationItem );
00955 }
00956 else
00957 $newRelationList[] = $relationItem;
00958 }
00959 $content['relation_list'] =& $newRelationList;
00960 $contentObjectAttribute->setContent( $content );
00961 $contentObjectAttribute->store();
00962 }
00963 }
00964 else if ( $action == 'browse_objects' )
00965 {
00966 $module =& $parameters['module'];
00967 $redirectionURI = $parameters['current-redirection-uri'];
00968
00969 $ini = eZINI::instance( 'content.ini' );
00970 $browseType = 'AddRelatedObjectListToDataType';
00971 $browseTypeINIVariable = $ini->variable( 'ObjectRelationDataTypeSettings', 'ClassAttributeStartNode' );
00972 foreach ( $browseTypeINIVariable as $value )
00973 {
00974 list( $classAttributeID, $type ) = explode( ';',$value );
00975 if ( is_numeric( $classAttributeID ) and
00976 $classAttributeID == $contentObjectAttribute->attribute( 'contentclassattribute_id' ) and
00977 strlen( $type ) > 0 )
00978 {
00979 $browseType = $type;
00980 break;
00981 }
00982 }
00983
00984
00985
00986 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' );
00987 $classContent =& $classAttribute->content();
00988 if ( isset( $classContent['class_constraint_list'] ) )
00989 $classConstraintList =& $classContent['class_constraint_list'];
00990 else
00991 $classConstraintList = array();
00992
00993 include_once( 'kernel/classes/ezcontentbrowse.php' );
00994 $browseParameters = array( 'action_name' => 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ),
00995 'type' => $browseType,
00996 'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $contentObjectAttribute->attribute( 'id' ) . '_set_object_relation_list]',
00997 'value' => $contentObjectAttribute->attribute( 'id' ) ),
00998 'persistent_data' => array( 'HasObjectInput' => 0 ),
00999 'from_page' => $redirectionURI );
01000 $base = $parameters['base_name'];
01001 $nodePlacementName = $base . '_browse_for_object_start_node';
01002 if ( $http->hasPostVariable( $nodePlacementName ) )
01003 {
01004 $nodePlacement = $http->postVariable( $nodePlacementName );
01005 if ( isset( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ) )
01006 $browseParameters['start_node'] = eZContentBrowse::nodeAliasID( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] );
01007 }
01008 if ( count($classConstraintList) > 0 )
01009 $browseParameters['class_array'] = $classConstraintList;
01010
01011 eZContentBrowse::browse( $browseParameters,
01012 $module );
01013 }
01014 else if ( $action == 'set_object_relation_list' )
01015 {
01016 if ( !$http->hasPostVariable( 'BrowseCancelButton' ) )
01017 {
01018 $selectedObjectIDArray = $http->postVariable( "SelectedObjectIDArray" );
01019 $content = $contentObjectAttribute->content();
01020 $priority = 0;
01021 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
01022 {
01023 if ( $content['relation_list'][$i]['priority'] > $priority )
01024 $priority = $content['relation_list'][$i]['priority'];
01025 }
01026
01027 foreach ( $selectedObjectIDArray as $objectID )
01028 {
01029
01030 if ( !is_numeric( $objectID ) )
01031 {
01032 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.",
01033 "eZObjectRelationListType::customObjectAttributeHTTPAction" );
01034
01035 continue;
01036 }
01037
01038
01039
01040
01041
01042 $found = false;
01043 foreach ( $content['relation_list'] as $i )
01044 {
01045 if ( $i['contentobject_id'] == $objectID )
01046 {
01047 $found = true;
01048 break;
01049 }
01050 }
01051 if ( $found )
01052 continue;
01053
01054 ++$priority;
01055 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
01056 $contentObjectAttribute->setContent( $content );
01057 $contentObjectAttribute->store();
01058 }
01059 }
01060 }
01061 else
01062 {
01063 eZDebug::writeError( "Unknown custom HTTP action: " . $action,
01064 'eZObjectRelationListType' );
01065 }
01066 }
01067
01068
01069
01070
01071 function handleCustomObjectHTTPActions( &$http, $attributeDataBaseName,
01072 $customActionAttributeArray, $customActionParameters )
01073 {
01074 $contentObjectAttribute =& $customActionParameters['contentobject_attribute'];
01075 $content =& $contentObjectAttribute->content();
01076 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
01077 {
01078 $relationItem = $content['relation_list'][$i];
01079 if ( $relationItem['is_modified'] )
01080 {
01081 $subObjectID = $relationItem['contentobject_id'];
01082 $subObjectVersion = $relationItem['contentobject_version'];
01083
01084 $attributeBase = $attributeDataBaseName . '_ezorl_edit_object_' . $subObjectID;
01085 $object =& $content['temp'][$subObjectID]['object'];
01086 if ( eZContentObject::recursionProtect( $subObjectID ) )
01087 {
01088 if ( !$object )
01089 $object =& eZContentObject::fetch( $subObjectID );
01090 if ( $object )
01091 $object->handleAllCustomHTTPActions( $attributeBase,
01092 $customActionAttributeArray,
01093 $customActionParameters,
01094 $subObjectVersion );
01095 }
01096 }
01097 }
01098 }
01099
01100
01101
01102
01103
01104 function isItemPublished( &$relationItem )
01105 {
01106 return is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] > 0;
01107 }
01108
01109
01110
01111
01112
01113
01114 function removeRelationObject( &$contentObjectAttribute, &$deletionItem )
01115 {
01116 if ( eZObjectRelationListType::isItemPublished( $deletionItem ) )
01117 {
01118 return;
01119 }
01120
01121 $hostObject =& $contentObjectAttribute->attribute( 'object' );
01122 $hostObjectVersions =& $hostObject->versions();
01123 $isDeletionAllowed = true;
01124
01125
01126 foreach ( $hostObjectVersions as $version )
01127 {
01128 if ( $isDeletionAllowed and
01129 $version->attribute( 'version' ) != $contentObjectAttribute->attribute( 'version' ) )
01130 {
01131 $relationAttribute = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(),
01132 null,
01133 array( 'version' => $version->attribute( 'version' ),
01134 'contentobject_id' => $hostObject->attribute( 'id' ),
01135 'contentclassattribute_id' => $contentObjectAttribute->attribute( 'contentclassattribute_id' ) ) );
01136
01137 if ( count( $relationAttribute ) > 0 )
01138 {
01139 $relationContent =& $relationAttribute[0]->content();
01140 if ( is_array( $relationContent ) and
01141 is_array( $relationContent['relation_list'] ) )
01142 {
01143 $relationContentCount = count( $relationContent['relation_list'] );
01144 for ( $i = 0; $i < $relationContentCount; ++$i )
01145 {
01146 if ( $deletionItem['contentobject_id'] == $relationContent['relation_list'][$i]['contentobject_id'] &&
01147 $deletionItem['contentobject_version'] == $relationContent['relation_list'][$i]['contentobject_version'] )
01148 {
01149 $isDeletionAllowed = false;
01150 break 2;
01151 }
01152 }
01153 }
01154 }
01155 }
01156 }
01157
01158 if ( $isDeletionAllowed )
01159 {
01160 $subObjectVersion = eZContentObjectVersion::fetchVersion( $deletionItem['contentobject_version'],
01161 $deletionItem['contentobject_id'] );
01162 if ( get_class( $subObjectVersion ) == 'ezcontentobjectversion' )
01163 {
01164 $subObjectVersion->remove();
01165 }
01166 else
01167 {
01168 eZDebug::writeError( 'Cleanup of subobject-version failed. Could not fetch object from relation list.\n' .
01169 'Requested subobject id: ' . $deletionItem['contentobject_id'] . '\n' .
01170 'Requested Subobject version: ' . $deletionItem['contentobject_version'],
01171 'eZObjectRelationListType::removeRelationObject' );
01172 }
01173 }
01174 }
01175
01176
01177 function createInstance( &$class, $priority, &$contentObjectAttribute, $nodePlacement = false )
01178 {
01179 $currentObject =& $contentObjectAttribute->attribute( 'object' );
01180 $sectionID = $currentObject->attribute( 'section_id' );
01181 $object = $class->instantiate( false, $sectionID );
01182 if ( !is_numeric( $nodePlacement ) or $nodePlacement <= 0 )
01183 $nodePlacement = false;
01184 $object->sync();
01185 $relationItem = array( 'identifier' => false,
01186 'priority' => $priority,
01187 'in_trash' => false,
01188 'contentobject_id' => $object->attribute( 'id' ),
01189 'contentobject_version' => $object->attribute( 'current_version' ),
01190 'contentobject_remote_id' => $object->attribute( 'remote_id' ),
01191 'node_id' => false,
01192 'parent_node_id' => $nodePlacement,
01193 'contentclass_id' => $class->attribute( 'id' ),
01194 'contentclass_identifier' => $class->attribute( 'identifier' ),
01195 'is_modified' => true );
01196 $relationItem['object'] =& $object;
01197 return $relationItem;
01198 }
01199
01200 function appendObject( $objectID, $priority, &$contentObjectAttribute )
01201 {
01202 $object =& eZContentObject::fetch( $objectID );
01203 $class =& $object->attribute( 'content_class' );
01204 $sectionID = $object->attribute( 'section_id' );
01205 $relationItem = array( 'identifier' => false,
01206 'priority' => $priority,
01207 'in_trash' => false,
01208 'contentobject_id' => $object->attribute( 'id' ),
01209 'contentobject_version' => $object->attribute( 'current_version' ),
01210 'contentobject_remote_id' => $object->attribute( 'remote_id' ),
01211 'node_id' => $object->attribute( 'main_node_id' ),
01212 'parent_node_id' => $object->attribute( 'main_parent_node_id' ),
01213 'contentclass_id' => $class->attribute( 'id' ),
01214 'contentclass_identifier' => $class->attribute( 'identifier' ),
01215 'is_modified' => false );
01216 $relationItem['object'] =& $object;
01217 return $relationItem;
01218 }
01219
01220
01221 function fixRelatedObjectItem ( &$contentObjectAttribute, $objectID, $mode = false )
01222 {
01223 switch ( $mode )
01224 {
01225 case 'move':
01226 eZObjectRelationListType::fixRelationsMove( $objectID, $contentObjectAttribute );
01227 break;
01228
01229 case 'trash':
01230 eZObjectRelationListType::fixRelationsTrash( $objectID, $contentObjectAttribute );
01231 break;
01232
01233 case 'restore':
01234 eZObjectRelationListType::fixRelationsRestore( $objectID, $contentObjectAttribute );
01235 break;
01236
01237 case 'remove':
01238 eZObjectRelationListType::fixRelationsRemove( $objectID, $contentObjectAttribute );
01239 break;
01240
01241 case 'swap':
01242 eZObjectRelationListType::fixRelationsSwap( $objectID, $contentObjectAttribute );
01243 break;
01244 }
01245 }
01246
01247 function fixRelationsMove ( $objectID, &$contentObjectAttribute )
01248 {
01249 $this->fixRelationsSwap( $objectID, $contentObjectAttribute );
01250 }
01251
01252 function fixRelationsTrash ( $objectID, &$contentObjectAttribute )
01253 {
01254 $content =& $contentObjectAttribute->attribute( 'content' );
01255 foreach ( array_keys( $content['relation_list'] ) as $key )
01256 {
01257 if ( $content['relation_list'][$key]['contentobject_id'] == $objectID )
01258 {
01259 $content['relation_list'][$key]['in_trash'] = true;
01260 $content['relation_list'][$key]['node_id'] = null;
01261 $content['relation_list'][$key]['parent_node_id']= null;
01262 }
01263 }
01264 eZObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content );
01265 $contentObjectAttribute->setContent( $content );
01266 $contentObjectAttribute->storeData();
01267 }
01268
01269 function fixRelationsRestore ( $objectID, &$contentObjectAttribute )
01270 {
01271 $content =& $contentObjectAttribute->content();
01272
01273 foreach ( array_keys( $content['relation_list'] ) as $key )
01274 {
01275 if ( $content['relation_list'][$key]['contentobject_id'] == $objectID )
01276 {
01277 $priority = $content['relation_list'][$key]['priority'];
01278 $content['relation_list'][$key] = $this->appendObject( $objectID, $priority, $contentObjectAttribute);
01279 }
01280 }
01281 eZObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content );
01282 $contentObjectAttribute->setContent( $content );
01283 $contentObjectAttribute->storeData();
01284 }
01285
01286 function fixRelationsRemove ( $objectID, $contentObjectAttribute )
01287 {
01288 $this->removeRelatedObjectItem( $contentObjectAttribute, $objectID );
01289 $contentObjectAttribute->storeData();
01290 }
01291
01292 function fixRelationsSwap ( $objectID, &$contentObjectAttribute )
01293 {
01294 $content =& $contentObjectAttribute->content();
01295
01296 foreach ( array_keys( $content['relation_list'] ) as $key )
01297 {
01298 $relatedObject =& $content['relation_list'][$key];
01299 if ( $relatedObject['contentobject_id'] == $objectID )
01300 {
01301 $priority = $content['relation_list'][$key]['priority'];
01302 $content['relation_list'][$key] = $this->appendObject($objectID, $priority, $contentObjectAttribute );
01303 }
01304 }
01305
01306 eZObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content );
01307 $contentObjectAttribute->setContent( $content );
01308 $contentObjectAttribute->storeData();
01309 }
01310
01311
01312
01313
01314
01315 function &objectAttributeContent( &$contentObjectAttribute )
01316 {
01317 $xmlText = $contentObjectAttribute->attribute( 'data_text' );
01318 if ( trim( $xmlText ) == '' )
01319 {
01320 $objectAttributeContent = eZObjectRelationListType::defaultObjectAttributeContent();
01321 return $objectAttributeContent;
01322 }
01323 $doc =& eZObjectRelationListType::parseXML( $xmlText );
01324 $content = eZObjectRelationListType::createObjectContentStructure( $doc );
01325
01326 return $content;
01327 }
01328
01329
01330
01331
01332 function &classAttributeContent( &$classAttribute )
01333 {
01334 $xmlText = $classAttribute->attribute( 'data_text5' );
01335 if ( trim( $xmlText ) == '' )
01336 {
01337 $classAttributeContent = eZObjectRelationListType::defaultClassAttributeContent();
01338 return $classAttributeContent;
01339 }
01340 $doc =& eZObjectRelationListType::parseXML( $xmlText );
01341 $content = eZObjectRelationListType::createClassContentStructure( $doc );
01342 return $content;
01343 }
01344
01345 function &parseXML( $xmlText )
01346 {
01347 $xml = new eZXML();
01348 $dom =& $xml->domTree( $xmlText );
01349 return $dom;
01350 }
01351
01352 function defaultClassAttributeContent()
01353 {
01354 return array( 'object_class' => '',
01355 'selection_type' => 0,
01356 'type' => 0,
01357 'class_constraint_list' => array(),
01358 'default_placement' => false );
01359 }
01360
01361 function defaultObjectAttributeContent()
01362 {
01363 return array( 'relation_list' => array() );
01364 }
01365
01366 function createClassContentStructure( &$doc )
01367 {
01368 $content = eZObjectRelationListType::defaultClassAttributeContent();
01369 $root =& $doc->root();
01370 $objectPlacement =& $root->elementByName( 'contentobject-placement' );
01371
01372 if ( $objectPlacement and $objectPlacement->hasAttributes() )
01373 {
01374 $nodeID = $objectPlacement->attributeValue( 'node-id' );
01375 $content['default_placement'] = array( 'node_id' => $nodeID );
01376 }
01377 $constraints =& $root->elementByName( 'constraints' );
01378 if ( $constraints )
01379 {
01380 $allowedClassList = $constraints->elementsByName( 'allowed-class' );
01381 foreach( $allowedClassList as $allowedClass )
01382 {
01383 $content['class_constraint_list'][] = $allowedClass->attributeValue( 'contentclass-identifier' );
01384 }
01385 }
01386 $type =& $root->elementByName( 'type' );
01387 if ( $type )
01388 {
01389 $content['type'] = $type->attributeValue( 'value' );
01390 }
01391 $selectionType =& $root->elementByName( 'selection_type' );
01392 if ( $selectionType )
01393 {
01394 $content['selection_type'] = $selectionType->attributeValue( 'value' );
01395 }
01396 $objectClass =& $root->elementByName( 'object_class' );
01397 if ( $objectClass )
01398 {
01399 $content['object_class'] = $objectClass->attributeValue( 'value' );
01400 }
01401
01402 return $content;
01403 }
01404
01405 function createObjectContentStructure( &$doc )
01406 {
01407 $content = eZObjectRelationListType::defaultObjectAttributeContent();
01408 $root =& $doc->root();
01409 $relationList =& $root->elementByName( 'relation-list' );
01410 if ( $relationList )
01411 {
01412 $relationItems = $relationList->elementsByName( 'relation-item' );
01413 foreach( $relationItems as $relationItem )
01414 {
01415 $content['relation_list'][] = $relationItem->attributeValues( eZObjectRelationListType::contentObjectArrayXMLMap(),
01416 false );
01417 }
01418 }
01419 return $content;
01420 }
01421
01422
01423
01424
01425 function customClassAttributeHTTPAction( &$http, $action, &$classAttribute )
01426 {
01427 switch ( $action )
01428 {
01429 case 'browse_for_placement':
01430 {
01431 $module =& $classAttribute->currentModule();
01432 include_once( 'kernel/classes/ezcontentbrowse.php' );
01433 $customActionName = 'CustomActionButton[' . $classAttribute->attribute( 'id' ) . '_browsed_for_placement]';
01434 eZContentBrowse::browse( array( 'action_name' => 'SelectObjectRelationListNode',
01435 'content' => array( 'contentclass_id' => $classAttribute->attribute( 'contentclass_id' ),
01436 'contentclass_attribute_id' => $classAttribute->attribute( 'id' ),
01437 'contentclass_version' => $classAttribute->attribute( 'version' ),
01438 'contentclass_attribute_identifier' => $classAttribute->attribute( 'identifier' ) ),
01439 'persistent_data' => array( $customActionName => '',
01440 'ContentClassHasInput' => false ),
01441 'description_template' => 'design:class/datatype/browse_objectrelationlist_placement.tpl',
01442 'from_page' => $module->currentRedirectionURI() ),
01443 $module );
01444 } break;
01445 case 'browsed_for_placement':
01446 {
01447 include_once( 'kernel/classes/ezcontentbrowse.php' );
01448 $nodeSelection = eZContentBrowse::result( 'SelectObjectRelationListNode' );
01449 if ( $nodeSelection and count( $nodeSelection ) > 0 )
01450 {
01451 $nodeID = $nodeSelection[0];
01452 $content = $classAttribute->content();
01453 $content['default_placement'] = array( 'node_id' => $nodeID );
01454 $classAttribute->setContent( $content );
01455 }
01456 } break;
01457 case 'disable_placement':
01458 {
01459 $content =& $classAttribute->content();
01460 $content['default_placement'] = false;
01461 $classAttribute->setContent( $content );
01462 } break;
01463 default:
01464 {
01465 eZDebug::writeError( "Unknown objectrelationlist action '$action'", 'eZContentObjectRelationListType::customClassAttributeHTTPAction' );
01466 } break;
01467 }
01468 }
01469
01470
01471
01472
01473 function metaData( $contentObjectAttribute )
01474 {
01475 $metaDataArray = array();
01476 $content =& $contentObjectAttribute->content();
01477 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
01478 {
01479 $relationItem = $content['relation_list'][$i];
01480 $subObjectID = $relationItem['contentobject_id'];
01481 if ( !$subObjectID )
01482 continue;
01483
01484 $attributes =& $content['temp'][$subObjectID]['attributes'];
01485 if ( !$attributes )
01486 {
01487 $subObjectVersion = $relationItem['contentobject_version'];
01488 $object =& eZContentObject::fetch( $subObjectID );
01489 if ( eZContentObject::recursionProtect( $subObjectID ) )
01490 {
01491 if ( !$object )
01492 {
01493 continue;
01494 }
01495 $attributes =& $object->contentObjectAttributes( true, $subObjectVersion );
01496 }
01497 }
01498
01499 $metaDataArray = array_merge( $metaDataArray, eZContentObjectAttribute::metaDataArray( $attributes ) );
01500 }
01501
01502 return $metaDataArray;
01503 }
01504
01505
01506
01507
01508
01509 function toString( $contentObjectAttribute )
01510 {
01511 $objectAttributeContent = $contentObjectAttribute->attribute( 'content' );
01512 $objectIDList = array();
01513 foreach( $objectAttributeContent['relation_list'] as $objectInfo )
01514 {
01515 $objectIDList[] = $objectInfo['contentobject_id'];
01516 }
01517 return implode( '-', $objectIDList );
01518 }
01519
01520 function fromString( &$contentObjectAttribute, $string )
01521 {
01522 $objectIDList = explode( '-', $string );
01523
01524 $content = eZObjectRelationListType::defaultObjectAttributeContent();
01525 $priority = 0;
01526 foreach( $objectIDList as $objectID )
01527 {
01528 $object = eZContentObject::fetch( $objectID );
01529 if ( $object )
01530 {
01531 ++$priority;
01532 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
01533 }
01534 else
01535 {
01536 eZDebug::writeWarning( $objectID, "Can not create relation because object is missing" );
01537 }
01538 }
01539 $contentObjectAttribute->setContent( $content );
01540 return true;
01541 }
01542
01543 function hasObjectAttributeContent( &$contentObjectAttribute )
01544 {
01545 $content =& $contentObjectAttribute->content();
01546 return count( $content['relation_list'] ) > 0;
01547 }
01548
01549
01550
01551
01552 function isIndexable()
01553 {
01554 return true;
01555 }
01556
01557
01558
01559
01560
01561 function title( &$contentObjectAttribute )
01562 {
01563 $objectAttributeContent = $this->objectAttributeContent( $contentObjectAttribute );
01564
01565 if ( count( $objectAttributeContent['relation_list'] ) > 0 )
01566 {
01567 $target = $objectAttributeContent['relation_list'][0];
01568 $targetObject =& eZContentObject::fetch( $target['contentobject_id'], false );
01569 return $targetObject['name'];
01570 }
01571 else
01572 {
01573 return false;
01574 }
01575 }
01576
01577
01578
01579
01580 function serializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
01581 {
01582 $content =& $classAttribute->content();
01583 if ( $content['default_placement'] )
01584 $attributeParametersNode->appendChild( eZDOMDocument::createElementNode( 'default-placement',
01585 array( 'node-id' => $content['default_placement']['node_id'] ) ) );
01586 if ( is_numeric( $content['type'] ) )
01587 $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'type', $content['type'] ) );
01588 else
01589 $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'type', '0' ) );
01590 $classConstraintsNode = eZDOMDocument::createElementNode( 'class-constraints' );
01591 $attributeParametersNode->appendChild( $classConstraintsNode );
01592 foreach ( $content['class_constraint_list'] as $classConstraint )
01593 {
01594 $classConstraintIdentifier = $classConstraint;
01595 $classConstraintsNode->appendChild( eZDOMDocument::createElementNode( 'class-constraint',
01596 array( 'class-identifier' => $classConstraintIdentifier ) ) );
01597 }
01598
01599 if ( isset( $content['selection_type'] ) && is_numeric( $content['selection_type'] ) )
01600 {
01601 $selectionTypeNode = eZDOMDocument::createElementTextNode( 'selection-type', $content['selection_type'] );
01602 $attributeParametersNode->appendChild( $selectionTypeNode );
01603 }
01604
01605 if ( isset( $content['object_class'] ) && is_numeric( $content['object_class'] ) )
01606 {
01607 $objectClassNode = eZDOMDocument::createElementTextNode( 'object-class', $content['object_class'] );
01608 $attributeParametersNode->appendChild( $objectClassNode );
01609 }
01610 }
01611
01612
01613
01614
01615 function unserializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
01616 {
01617 $content =& $classAttribute->content();
01618 $defaultPlacementNode = $attributeParametersNode->elementByName( 'default-placement' );
01619 $content['default_placement'] = false;
01620 if ( $defaultPlacementNode )
01621 $content['default_placement'] = array( 'node_id' => $defaultPlacementNode->attributeValue( 'node-id' ) );
01622 $content['type'] = $attributeParametersNode->elementTextContentByName( 'type' );
01623 $classConstraintsNode =& $attributeParametersNode->elementByName( 'class-constraints' );
01624 $classConstraintList = $classConstraintsNode->children();
01625 $content['class_constraint_list'] = array();
01626 foreach ( $classConstraintList as $classConstraintNode )
01627 {
01628 $classIdentifier = $classConstraintNode->attributeValue( 'class-identifier' );
01629 $content['class_constraint_list'][] = $classIdentifier;
01630 }
01631 $objectClassNode = $attributeParametersNode->elementByName( 'object-class' );
01632 if ( $objectClassNode )
01633 {
01634 $content['object_class'] = $objectClassNode->textContent();
01635 }
01636
01637 $selectionTypeNode = $attributeParametersNode->elementByName( 'selection-type' );
01638 if ( $selectionTypeNode )
01639 {
01640 $content['selection_type'] = $selectionTypeNode->textContent();
01641 }
01642
01643 $classAttribute->setContent( $content );
01644 $this->storeClassAttributeContent( $classAttribute, $content );
01645 }
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 function serializeContentObjectAttribute( &$package, &$objectAttribute )
01661 {
01662 $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
01663
01664 $xml = new eZXML();
01665 $domDocument = $xml->domTree( $objectAttribute->attribute( 'data_text' ) );
01666 $rootNode =& $domDocument->root();
01667 $relationList =& $rootNode->elementByName( 'relation-list' );
01668 if ( $relationList )
01669 {
01670 require_once( 'kernel/classes/ezcontentobject.php' );
01671 $relationItems = $relationList->elementsByName( 'relation-item' );
01672 foreach( $relationItems as $i => $relationItem )
01673 {
01674
01675 $relatedObjectID = $relationItem->attributeValue( 'contentobject-id' );
01676 $relatedObject = eZContentObject::fetch( $relatedObjectID );
01677 $relatedObjectRemoteID = $relatedObject->attribute( 'remote_id' );
01678 require_once( 'kernel/classes/ezcontentobject.php' );
01679 $relationItems[$i]->setAttribute( 'contentobject-remote-id', $relatedObjectRemoteID );
01680
01681
01682 foreach ( $relationItem->attributes() as $attribute )
01683 {
01684 $attrName = $attribute->name();
01685 if ( $attrName != 'priority' && $attrName != 'contentobject-remote-id' )
01686 $relationItems[$i]->removeAttribute( $attrName );
01687 }
01688 }
01689 }
01690
01691 $node->appendChild( $rootNode );
01692
01693 return $node;
01694 }
01695
01696
01697
01698
01699 function unserializeContentObjectAttribute( &$package, &$objectAttribute, $attributeNode )
01700 {
01701 $rootNode = $attributeNode->firstChild();
01702
01703 if ( $rootNode->attributeValue( 'local_name' ) == 'data-text' )
01704 $xmlString = '';
01705 else
01706 {
01707 $xmlString = $rootNode->toString( 0 );
01708 }
01709
01710 $objectAttribute->setAttribute( 'data_text', $xmlString );
01711 }
01712
01713 function postUnserializeContentObjectAttribute( &$package, &$objectAttribute )
01714 {
01715 $xmlString = $objectAttribute->attribute( 'data_text' );
01716 $doc =& $this->parseXML( $xmlString );
01717 $rootNode =& $doc->root();
01718
01719 $relationList =& $rootNode->elementByName( 'relation-list' );
01720 if ( !$relationList )
01721 return false;
01722
01723 require_once( 'kernel/classes/ezcontentobject.php' );
01724 $relationItems = $relationList->elementsByName( 'relation-item' );
01725 foreach( $relationItems as $i => $relationItem )
01726 {
01727 $relatedObjectRemoteID = $relationItem->attributeValue( 'contentobject-remote-id' );
01728 $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID );
01729
01730 if ( $object === null )
01731 {
01732 eZDebug::writeWarning( "Object with remote id '$relatedObjectRemoteID' not found: removing the link.",
01733 'eZObjectRelationListType::unserializeContentObjectAttribute()' );
01734 unset( $relationItems[$i] );
01735 continue;
01736 }
01737
01738 $relationItems[$i]->setAttribute( 'contentobject-id', $object->attribute( 'id' ) );
01739 $relationItems[$i]->setAttribute( 'contentobject-version', $object->attribute( 'current_version' ) );
01740 $relationItems[$i]->setAttribute( 'node-id', $object->attribute( 'main_node_id' ) );
01741 $relationItems[$i]->setAttribute( 'parent-node-id', $object->attribute( 'main_parent_node_id' ) );
01742 $relationItems[$i]->setAttribute( 'contentclass-id', $object->attribute( 'contentclass_id' ) );
01743 $relationItems[$i]->setAttribute( 'contentclass-identifier', $object->attribute( 'class_identifier' ) );
01744 }
01745
01746 $newXmlString = $rootNode->toString( 0 );
01747
01748 $objectAttribute->setAttribute( 'data_text', $newXmlString );
01749 return true;
01750 }
01751
01752
01753
01754
01755 function removeRelatedObjectItem( &$contentObjectAttribute, $objectID )
01756 {
01757 $xmlText = $contentObjectAttribute->attribute( 'data_text' );
01758 if ( trim( $xmlText ) == '' ) return;
01759
01760 $doc =& eZObjectRelationListType::parseXML( $xmlText );
01761
01762 $return = false;
01763 $root =& $doc->root();
01764 $relationList =& $root->elementByName( 'relation-list' );
01765 if ( $relationList )
01766 {
01767 $relationItems = $relationList->elementsByName( 'relation-item' );
01768 if ( count( $relationItems ) )
01769 {
01770 foreach( array_keys( $relationItems ) as $key )
01771 {
01772 $relationItem =& $relationItems[$key];
01773 if ( $relationItem->attributeValue( 'contentobject-id' ) == $objectID )
01774 {
01775 $relationList->removeChild( $relationItem );
01776 $return = true;
01777 }
01778 }
01779 }
01780 }
01781 eZObjectRelationListType::storeObjectDOMDocument( $doc, $contentObjectAttribute );
01782 return $return;
01783 }
01784
01785
01786 }
01787
01788 eZDataType::register( EZ_DATATYPESTRING_OBJECT_RELATION_LIST, "ezobjectrelationlisttype" );
01789
01790 ?>