| [ Index ] |
|
Code source de eZ Publish 3.9.0 |
1 <?php 2 // 3 // Definition of eZObjectRelationListType class 4 // 5 // Created on: <16-Apr-2002 11:08:14 amos> 6 // 7 // SOFTWARE NAME: eZ publish 8 // SOFTWARE RELEASE: 3.9.0 9 // BUILD VERSION: 17785 10 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS 11 // SOFTWARE LICENSE: GNU General Public License v2.0 12 // NOTICE: > 13 // This program is free software; you can redistribute it and/or 14 // modify it under the terms of version 2.0 of the GNU General 15 // Public License as published by the Free Software Foundation. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of version 2.0 of the GNU General 23 // Public License along with this program; if not, write to the Free 24 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 25 // MA 02110-1301, USA. 26 // 27 // 28 29 /*! 30 \class eZObjectRelationListType ezobjectrelationlisttype.php 31 \ingroup eZDatatype 32 \brief A content datatype which handles object relations 33 34 Bugs/missing features: 35 - No identifier support yet 36 - Validation and fixup for "Add new object" functionality 37 - Proper embed views for admin classes 38 - No translation page support yet (maybe?) 39 40 */ 41 42 include_once ( 'kernel/classes/ezdatatype.php' ); 43 include_once ( 'kernel/classes/ezcontentobject.php' ); 44 include_once ( 'lib/ezutils/classes/ezintegervalidator.php' ); 45 include_once ( 'lib/ezutils/classes/ezinputvalidator.php' ); 46 include_once ( 'lib/ezi18n/classes/eztranslatormanager.php' ); 47 include_once ( 'lib/ezxml/classes/ezxml.php' ); 48 49 define( "EZ_DATATYPESTRING_OBJECT_RELATION_LIST", "ezobjectrelationlist" ); 50 51 class eZObjectRelationListType extends eZDataType 52 { 53 /*! 54 Initializes with a string id and a description. 55 */ 56 function eZObjectRelationListType() 57 { 58 $this->eZDataType( EZ_DATATYPESTRING_OBJECT_RELATION_LIST, ezi18n( 'kernel/classes/datatypes', "Object relations", 'Datatype name' ), 59 array( 'serialize_supported' => true ) ); 60 } 61 62 /*! 63 Validates the input and returns true if the input was 64 valid for this datatype. 65 */ 66 function validateObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute ) 67 { 68 $inputParameters =& $contentObjectAttribute->inputParameters(); 69 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute(); 70 $parameters = $contentObjectAttribute->validationParameters(); 71 if ( isset( $parameters['prefix-name'] ) and 72 $parameters['prefix-name'] ) 73 $parameters['prefix-name'][] = $contentClassAttribute->attribute( 'name' ); 74 else 75 $parameters['prefix-name'] = array( $contentClassAttribute->attribute( 'name' ) ); 76 77 $status = EZ_INPUT_VALIDATOR_STATE_ACCEPTED; 78 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" ); 79 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute(); 80 $classContent = $contentClassAttribute->content(); 81 // Check if selection type is not browse 82 if ( $classContent['selection_type'] != 0 ) 83 { 84 $selectedObjectIDArray = $http->hasPostVariable( $postVariableName ) ? $http->postVariable( $postVariableName ) : false; 85 if ( $contentObjectAttribute->validateIsRequired() and $selectedObjectIDArray === false ) 86 { 87 $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes', 88 'Missing objectrelation list input.' ) ); 89 return EZ_INPUT_VALIDATOR_STATE_INVALID; 90 } 91 return $status; 92 } 93 94 $content =& $contentObjectAttribute->content(); 95 if ( $contentObjectAttribute->validateIsRequired() and count( $content['relation_list'] ) == 0 ) 96 { 97 $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes', 98 'Missing objectrelation list input.' ) ); 99 return EZ_INPUT_VALIDATOR_STATE_INVALID; 100 } 101 102 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 103 { 104 $relationItem = $content['relation_list'][$i]; 105 if ( $relationItem['is_modified'] ) 106 { 107 $subObjectID = $relationItem['contentobject_id']; 108 $subObjectVersion = $relationItem['contentobject_version']; 109 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID; 110 $object =& eZContentObject::fetch( $subObjectID ); 111 if ( $object ) 112 { 113 $attributes =& $object->contentObjectAttributes( true, $subObjectVersion ); 114 115 $validationResult = $object->validateInput( $attributes, $attributeBase, 116 $inputParameters, $parameters ); 117 $inputValidated = $validationResult['input-validated']; 118 $content['temp'][$subObjectID]['require-fixup'] = $validationResult['require-fixup']; 119 $statusMap = $validationResult['status-map']; 120 foreach ( $statusMap as $statusItem ) 121 { 122 $statusValue = $statusItem['value']; 123 $statusAttribute =& $statusItem['attribute']; 124 if ( $statusValue == EZ_INPUT_VALIDATOR_STATE_INTERMEDIATE and 125 $status == EZ_INPUT_VALIDATOR_STATE_ACCEPTED ) 126 $status = EZ_INPUT_VALIDATOR_STATE_INTERMEDIATE; 127 else if ( $statusValue == EZ_INPUT_VALIDATOR_STATE_INVALID ) 128 { 129 $contentObjectAttribute->setHasValidationError( false ); 130 $status = EZ_INPUT_VALIDATOR_STATE_INVALID; 131 } 132 } 133 134 $content['temp'][$subObjectID]['attributes'] =& $attributes; 135 $content['temp'][$subObjectID]['object'] =& $object; 136 } 137 } 138 } 139 return $status; 140 } 141 142 /*! 143 Validates the input and returns true if the input was 144 valid for this datatype. 145 */ 146 function fixupObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute ) 147 { 148 $content =& $contentObjectAttribute->content(); 149 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 150 { 151 $relationItem = $content['relation_list'][$i]; 152 if ( $relationItem['is_modified'] ) 153 { 154 $subObjectID = $relationItem['contentobject_id']; 155 $subObjectVersion = $relationItem['contentobject_version']; 156 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID; 157 $object =& $content['temp'][$subObjectID]['object']; 158 $requireFixup = $content['temp'][$subObjectID]['require-fixup']; 159 if ( $object and 160 $requireFixup ) 161 { 162 $attributes =& $content['temp'][$subObjectID]['attributes']; 163 $object->fixupInput( $contentObjectAttributes, $attributeBase ); 164 } 165 } 166 } 167 } 168 169 /*! 170 Fetches the http post var string input and stores it in the data instance. 171 */ 172 function fetchObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute ) 173 { 174 $content =& $contentObjectAttribute->content(); 175 // new object creation 176 $newObjectPostVariableName = "attribute_" . $contentObjectAttribute->attribute( "id" ) . "_new_object_name"; 177 if ( $http->hasPostVariable( $newObjectPostVariableName ) ) 178 { 179 $name = $http->postVariable( $newObjectPostVariableName ); 180 if ( !empty( $name ) ) 181 { 182 $content['new_object'] = $name; 183 } 184 } 185 $singleSelectPostVariableName = "single_select_" . $contentObjectAttribute->attribute( "id" ); 186 if ( $http->hasPostVariable( $singleSelectPostVariableName ) ) 187 $content['singleselect'] = true; 188 189 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" ); 190 $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute(); 191 $classContent = $contentClassAttribute->content(); 192 // Check if selection type is not browse 193 if ( $classContent['selection_type'] != 0 ) 194 { 195 $selectedObjectIDArray = $http->hasPostVariable( $postVariableName ) ? $http->postVariable( $postVariableName ) : false; 196 $priority = 0; 197 // We should clear content 198 $content['relation_list'] = array(); 199 // If we got an empty object id list 200 if ( $selectedObjectIDArray === false or ( isset( $selectedObjectIDArray[0] ) and $selectedObjectIDArray[0] == 'no_relation' ) ) 201 { 202 $contentObjectAttribute->setContent( $content ); 203 $contentObjectAttribute->store(); 204 return true; 205 } 206 207 foreach ( $selectedObjectIDArray as $objectID ) 208 { 209 // Check if the given object ID has a numeric value, if not go to the next object. 210 if ( !is_numeric( $objectID ) ) 211 { 212 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", 213 "eZObjectRelationListType::fetchObjectAttributeHTTPInput" ); 214 215 continue; 216 } 217 ++$priority; 218 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute ); 219 $contentObjectAttribute->setContent( $content ); 220 $contentObjectAttribute->store(); 221 } 222 return true; 223 } 224 225 $contentObjectAttributeID = $contentObjectAttribute->attribute( 'id' ); 226 $priorityBase = $base . '_priority'; 227 $priorities = array(); 228 if ( $http->hasPostVariable( $priorityBase ) ) 229 $priorities = $http->postVariable( $priorityBase ); 230 $reorderedRelationList = array(); 231 // Contains existing priorities 232 $existsPriorities = array(); 233 234 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 235 { 236 $priorities[$contentObjectAttributeID][$i] = (int) $priorities[$contentObjectAttributeID][$i]; 237 $existsPriorities[$i] = $priorities[$contentObjectAttributeID][$i]; 238 239 // Change objects' priorities providing their uniqueness. 240 for ( $j = 0; $j < count( $content['relation_list'] ); ++$j ) 241 { 242 if ( $i == $j ) continue; 243 if ( $priorities[$contentObjectAttributeID][$i] == $priorities[$contentObjectAttributeID][$j] ) 244 { 245 $index = $priorities[$contentObjectAttributeID][$i]; 246 while ( in_array( $index, $existsPriorities ) ) 247 ++$index; 248 $priorities[$contentObjectAttributeID][$j] = $index; 249 } 250 } 251 $relationItem = $content['relation_list'][$i]; 252 if ( $relationItem['is_modified'] ) 253 { 254 $subObjectID = $relationItem['contentobject_id']; 255 $subObjectVersion = $relationItem['contentobject_version']; 256 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID; 257 $object =& $content['temp'][$subObjectID]['object']; 258 if ( $object ) 259 { 260 $attributes =& $content['temp'][$subObjectID]['attributes']; 261 262 $customActionAttributeArray = array(); 263 $fetchResult = $object->fetchInput( $attributes, $attributeBase, 264 $customActionAttributeArray, 265 $contentObjectAttribute->inputParameters() ); 266 unset( $attributeInputMap ); 267 $attributeInputMap =& $fetchResult['attribute-input-map']; 268 $content['temp'][$subObjectID]['attribute-input-map'] =& $attributeInputMap; 269 $content['temp'][$subObjectID]['attributes'] =& $attributes; 270 $content['temp'][$subObjectID]['object'] =& $object; 271 } 272 } 273 if ( isset( $priorities[$contentObjectAttributeID][$i] ) ) 274 $relationItem['priority'] = $priorities[$contentObjectAttributeID][$i]; 275 $reorderedRelationList[$relationItem['priority']] = $relationItem; 276 } 277 ksort( $reorderedRelationList ); 278 unset( $content['relation_list'] ); 279 $content['relation_list'] = array(); 280 reset( $reorderedRelationList ); 281 $i = 0; 282 while ( list( $key, $relationItem ) = each( $reorderedRelationList ) ) 283 { 284 $content['relation_list'][] = $relationItem; 285 $content['relation_list'][$i]['priority'] = $i + 1; 286 ++$i; 287 } 288 $contentObjectAttribute->setContent( $content ); 289 return true; 290 } 291 292 function createNewObject( &$contentObjectAttribute, $name ) 293 { 294 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' ); 295 $classContent = $classAttribute->content(); 296 $classID = $classContent['object_class']; 297 if ( !isset( $classID ) or !is_numeric( $classID ) ) 298 return false; 299 300 $defaultPlacementNode = ( is_array( $classContent['default_placement'] ) and isset( $classContent['default_placement']['node_id'] ) ) ? $classContent['default_placement']['node_id'] : false; 301 if ( !$defaultPlacementNode ) 302 { 303 eZDebug::writeError( 'Default placement is missing', 'eZObjectRelationListType::createNewObject' ); 304 return false; 305 } 306 307 $node =& eZContentObjectTreeNode::fetch( $defaultPlacementNode ); 308 // Check if current user can create a new node as child of this node. 309 if ( !$node or !$node->canCreate() ) 310 { 311 eZDebug::writeError( 'Default placement is wrong or the current user can\'t create a new node as child of this node.', 'eZObjectRelationListType::createNewObject' ); 312 return false; 313 } 314 315 $classList =& $node->canCreateClassList( false ); 316 $canCreate = false; 317 // Check if current user can create object of class (with $classID) 318 foreach ( $classList as $class ) 319 { 320 if ( $class['id'] == $classID ) 321 { 322 $canCreate = true; 323 break; 324 } 325 } 326 if ( !$canCreate ) 327 { 328 eZDebug::writeError( 'The current user is not allowed to create objects of class (ID=' . $classID . ')', 'eZObjectRelationListType::createNewObject' ); 329 return false; 330 } 331 332 $class =& eZContentClass::fetch( $classID ); 333 if ( !$class ) 334 return false; 335 336 $currentObject =& $contentObjectAttribute->attribute( 'object' ); 337 $sectionID = $currentObject->attribute( 'section_id' ); 338 //instantiate object, same section, currentuser as owner (i.e. provide false as param) 339 $newObjectInstance =& $class->instantiate( false, $sectionID ); 340 $nodeassignment = $newObjectInstance->createNodeAssignment( $defaultPlacementNode, true ); 341 $nodeassignment->store(); 342 $newObjectInstance->sync(); 343 include_once ( "lib/ezutils/classes/ezoperationhandler.php" ); 344 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObjectInstance->attribute( 'id' ), 'version' => 1 ) ); 345 // so it updates the attributes 346 $newObjectInstance->rename( $name ); 347 348 return $newObjectInstance->attribute( 'id' ); 349 } 350 351 /*! 352 */ 353 function storeObjectAttribute( &$attribute ) 354 { 355 $content = $attribute->content(); 356 if ( isset( $content['new_object'] ) ) 357 { 358 $newID = $this->createNewObject( $attribute, $content['new_object'] ); 359 // if this is a single element selection mode (radio or dropdown), then the newly created item is the only one selected 360 if ( $newID ) 361 { 362 if ( isset( $content['singleselect'] ) ) 363 $content['relation_list'] = array(); 364 $content['relation_list'][] = $this->appendObject( $newID, 0, $attribute ); 365 } 366 unset( $content['new_object'] ); 367 $attribute->setContent( $content ); 368 $attribute->store(); 369 } 370 371 $contentClassAttributeID = $attribute->ContentClassAttributeID; 372 $contentObjectID = $attribute->ContentObjectID; 373 $contentObjectVersion = $attribute->Version; 374 375 $obj = $attribute->object(); 376 //get eZContentObjectVersion 377 $currVerobj = $obj->version( $contentObjectVersion ); 378 379 // create translation List 380 // $translationList will contain for example eng-GB, ita-IT etc. 381 $translationList =& $currVerobj->translations( false ); 382 383 // get current language_code 384 $langCode = $attribute->attribute( 'language_code' ); 385 // get count of LanguageCode in translationList 386 $countTsl = count( $translationList ); 387 // order by asc 388 sort( $translationList ); 389 390 if ( ( $countTsl == 1 ) or ( $countTsl > 1 and $translationList[0] == $langCode ) ) 391 { 392 eZContentObject::removeContentObjectRelation( false, $contentObjectVersion, $contentObjectID, $contentClassAttributeID, EZ_CONTENT_OBJECT_RELATION_ATTRIBUTE ); 393 } 394 395 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 396 { 397 $relationItem =& $content['relation_list'][$i]; 398 399 // Installing content object, postUnserialize is not called yet, 400 // so object's ID is unknown. 401 if ( !$relationItem['contentobject_id'] || !isset( $relationItem['contentobject_id'] ) ) 402 continue; 403 404 $subObjectID = $relationItem['contentobject_id']; 405 $subObjectVersion = $relationItem['contentobject_version']; 406 407 eZContentObject::addContentObjectRelation( $subObjectID, $contentObjectVersion, $contentObjectID, $contentClassAttributeID, EZ_CONTENT_OBJECT_RELATION_ATTRIBUTE ); 408 409 if ( $relationItem['is_modified'] ) 410 { 411 // handling sub-objects 412 $object =& $content['temp'][$subObjectID]['object']; 413 if ( $object ) 414 { 415 $attributes =& $content['temp'][$subObjectID]['attributes']; 416 $attributeInputMap =& $content['temp'][$subObjectID]['attribute-input-map']; 417 $object->storeInput( $attributes, 418 $attributeInputMap ); 419 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID ); 420 if ( $version ) 421 { 422 $version->setAttribute( 'modified', time() ); 423 $version->setAttribute( 'status', EZ_VERSION_STATUS_DRAFT ); 424 $version->store(); 425 } 426 427 $object->setAttribute( 'status', EZ_CONTENT_OBJECT_STATUS_DRAFT ); 428 $object->store(); 429 } 430 } 431 } 432 return eZObjectRelationListType::storeObjectAttributeContent( $attribute, $content ); 433 } 434 435 /*! 436 \reimp 437 */ 438 function onPublish( &$contentObjectAttribute, &$contentObject, &$publishedNodes ) 439 { 440 $content = $contentObjectAttribute->content(); 441 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 442 { 443 $relationItem =& $content['relation_list'][$i]; 444 if ( $relationItem['is_modified'] ) 445 { 446 $subObjectID = $relationItem['contentobject_id']; 447 $subObjectVersion = $relationItem['contentobject_version']; 448 $object =& eZContentObject::fetch( $subObjectID ); 449 450 if ( $object ) 451 { 452 $class =& $object->contentClass(); 453 $time = time(); 454 455 // Make the previous version archived 456 $currentVersion =& $object->currentVersion(); 457 $currentVersion->setAttribute( 'status', EZ_VERSION_STATUS_ARCHIVED ); 458 $currentVersion->setAttribute( 'modified', $time ); 459 $currentVersion->store(); 460 461 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID ); 462 $version->setAttribute( 'modified', $time ); 463 $version->setAttribute( 'status', EZ_VERSION_STATUS_PUBLISHED ); 464 $version->store(); 465 $object->setAttribute( 'status', EZ_CONTENT_OBJECT_STATUS_PUBLISHED ); 466 if ( !$object->attribute( 'published' ) ) 467 $object->setAttribute( 'published', $time ); 468 $object->setAttribute( 'modified', $time ); 469 $object->setAttribute( 'current_version', $version->attribute( 'version' ) ); 470 $object->setAttribute( 'is_published', true ); 471 $objectName = $class->contentObjectName( $object, $version->attribute( 'version' ) ); 472 $object->setName( $objectName, $version->attribute( 'version' ) ); 473 $object->store(); 474 } 475 if ( $relationItem['parent_node_id'] > 0 ) 476 { 477 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $relationItem['parent_node_id'], false ) ) 478 { 479 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ), 480 'contentobject_version' => $object->attribute( 'current_version' ), 481 'parent_node' => $relationItem['parent_node_id'], 482 'sort_field' => 2, 483 'sort_order' => 0, 484 'is_main' => 1 ) ); 485 $nodeAssignment->store(); 486 } 487 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $object->attribute( 'id' ), 488 'version' => $object->attribute( 'current_version' ) ) ); 489 $objectNodeID = $object->attribute( 'main_node_id' ); 490 $content['relation_list'][$i]['node_id'] = $objectNodeID; 491 } 492 else 493 { 494 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $contentObject->attribute( 'main_node_id' ), false ) ) 495 { 496 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ), 497 'contentobject_version' => $object->attribute( 'current_version' ), 498 'parent_node' => $contentObject->attribute( 'main_node_id' ), 499 'sort_field' => 2, 500 'sort_order' => 0, 501 'is_main' => 1 ) ); 502 $nodeAssignment->store(); 503 } 504 } 505 $content['relation_list'][$i]['is_modified'] = false; 506 } 507 } 508 eZObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content ); 509 $contentObjectAttribute->setContent( $content ); 510 $contentObjectAttribute->store(); 511 } 512 513 function initializeObjectAttribute( &$contentObjectAttribute, $currentVersion, &$originalContentObjectAttribute ) 514 { 515 if ( $currentVersion != false ) 516 { 517 $dataText = $originalContentObjectAttribute->attribute( 'data_text' ); 518 $contentObjectAttribute->setAttribute( 'data_text', $dataText ); 519 520 if ( $contentObjectAttribute->attribute( 'contentobject_id' ) != $originalContentObjectAttribute->attribute( 'contentobject_id' ) ) 521 { 522 $classContent = eZObjectRelationListType::defaultClassAttributeContent(); 523 if ( !$classContent['default_placement'] ) 524 { 525 $content = $originalContentObjectAttribute->content(); 526 for ( $i = 0; $i < count( $content['relation_list'] ); $i++ ) 527 { 528 $relationItem =& $content['relation_list'][$i]; 529 530 // create related object copies only if they are subobjects 531 if ( !isset( $relationItem['node_id'] ) ) 532 { 533 $object =& eZContentObject::fetch( $relationItem['contentobject_id'] ); 534 $newObject =& $object->copy( true ); 535 $relationItem['contentobject_id'] = $newObject->attribute( 'id' ); 536 } 537 } 538 $contentObjectAttribute->setContent( $content ); 539 $contentObjectAttribute->store(); 540 } 541 } 542 } 543 } 544 545 /*! 546 \reimp 547 */ 548 function validateClassAttributeHTTPInput( &$http, $base, &$classAttribute ) 549 { 550 return EZ_INPUT_VALIDATOR_STATE_ACCEPTED; 551 } 552 553 /*! 554 \reimp 555 */ 556 function fixupClassAttributeHTTPInput( &$http, $base, &$classAttribute ) 557 { 558 } 559 560 /*! 561 \reimp 562 */ 563 function fetchClassAttributeHTTPInput( &$http, $base, &$classAttribute ) 564 { 565 $content = $classAttribute->content(); 566 $postVariable = 'ContentClass_ezobjectrelationlist_class_list_' . $classAttribute->attribute( 'id' ); 567 if ( $http->hasPostVariable( $postVariable ) ) 568 { 569 $constrainedList = $http->postVariable( $postVariable ); 570 $constrainedClassList = array(); 571 foreach ( $constrainedList as $constraint ) 572 { 573 if ( trim( $constraint ) != '' ) 574 $constrainedClassList[] = $constraint; 575 } 576 $content['class_constraint_list'] = $constrainedClassList; 577 } 578 $typeVariable = 'ContentClass_ezobjectrelationlist_type_' . $classAttribute->attribute( 'id' ); 579 if ( $http->hasPostVariable( $typeVariable ) ) 580 { 581 $type = $http->postVariable( $typeVariable ); 582 $content['type'] = $type; 583 } 584 $selectionTypeVariable = 'ContentClass_ezobjectrelationlist_selection_type_' . $classAttribute->attribute( 'id' ); 585 if ( $http->hasPostVariable( $selectionTypeVariable ) ) 586 { 587 $selectionType = $http->postVariable( $selectionTypeVariable ); 588 $content['selection_type'] = $selectionType; 589 } 590 $objectClassVariable = 'ContentClass_ezobjectrelation_object_class_' . $classAttribute->attribute( 'id' ); 591 if ( $http->hasPostVariable( $objectClassVariable ) ) 592 { 593 $content['object_class'] = $http->postVariable( $objectClassVariable ); 594 } 595 596 $classAttribute->setContent( $content ); 597 $classAttribute->store(); 598 return true; 599 } 600 601 /*! 602 \reimp 603 */ 604 function initializeClassAttribute( &$classAttribute ) 605 { 606 $xmlText = $classAttribute->attribute( 'data_text5' ); 607 if ( trim( $xmlText ) == '' ) 608 { 609 $content = eZObjectRelationListType::defaultClassAttributeContent(); 610 return eZObjectRelationListType::storeClassAttributeContent( $classAttribute, $content ); 611 } 612 } 613 614 /*! 615 \reimp 616 */ 617 function preStoreClassAttribute( &$classAttribute, $version ) 618 { 619 $content = $classAttribute->content(); 620 return eZObjectRelationListType::storeClassAttributeContent( $classAttribute, $content ); 621 } 622 623 function storeClassAttributeContent( &$classAttribute, $content ) 624 { 625 if ( is_array( $content ) ) 626 { 627 $doc = eZObjectRelationListType::createClassDOMDocument( $content ); 628 eZObjectRelationListType::storeClassDOMDocument( $doc, $classAttribute ); 629 return true; 630 } 631 return false; 632 } 633 634 function storeObjectAttributeContent( &$objectAttribute, $content ) 635 { 636 if ( is_array( $content ) ) 637 { 638 $doc = eZObjectRelationListType::createObjectDOMDocument( $content ); 639 eZObjectRelationListType::storeObjectDOMDocument( $doc, $objectAttribute ); 640 return true; 641 } 642 return false; 643 } 644 645 function storeClassDOMDocument( &$doc, &$classAttribute ) 646 { 647 $docText = eZObjectRelationListType::domString( $doc ); 648 $classAttribute->setAttribute( 'data_text5', $docText ); 649 } 650 651 function storeObjectDOMDocument( &$doc, &$objectAttribute ) 652 { 653 $docText = eZObjectRelationListType::domString( $doc ); 654 $objectAttribute->setAttribute( 'data_text', $docText ); 655 } 656 657 /*! 658 \static 659 \return the XML structure in \a $domDocument as text. 660 It will take of care of the necessary charset conversions 661 for content storage. 662 */ 663 function domString( &$domDocument ) 664 { 665 $ini =& eZINI::instance(); 666 $xmlCharset = $ini->variable( 'RegionalSettings', 'ContentXMLCharset' ); 667 if ( $xmlCharset == 'enabled' ) 668 { 669 include_once ( 'lib/ezi18n/classes/eztextcodec.php' ); 670 $charset = eZTextCodec::internalCharset(); 671 } 672 else if ( $xmlCharset == 'disabled' ) 673 $charset = true; 674 else 675 $charset = $xmlCharset; 676 if ( $charset !== true ) 677 { 678 include_once ( 'lib/ezi18n/classes/ezcharsetinfo.php' ); 679 $charset = eZCharsetInfo::realCharsetCode( $charset ); 680 } 681 $domString = $domDocument->toString( $charset ); 682 return $domString; 683 } 684 685 function createClassDOMDocument( $content ) 686 { 687 $doc = new eZDOMDocument( 'ObjectRelationList' ); 688 $root = $doc->createElementNode( 'related-objects' ); 689 $constraints = $doc->createElementNode( 'constraints' ); 690 foreach ( $content['class_constraint_list'] as $constraintClassIdentifier ) 691 { 692 unset( $constraintElement ); 693 $constraintElement = $doc->createElementNode( 'allowed-class', 694 array( 'contentclass-identifier' => $constraintClassIdentifier ) ); 695 $constraints->appendChild( $constraintElement ); 696 } 697 $root->appendChild( $constraints ); 698 $constraintType = $doc->createElementNode( 'type', array( 'value' => $content['type'] ) ); 699 $root->appendChild( $constraintType ); 700 $selectionType = $doc->createElementNode( 'selection_type', array( 'value' => $content['selection_type'] ) ); 701 $root->appendChild( $selectionType ); 702 $objectClass = $doc->createElementNode( 'object_class', array( 'value' => $content['object_class'] ) ); 703 $root->appendChild( $objectClass ); 704 705 $placementAttributes = array(); 706 if ( $content['default_placement'] ) 707 $placementAttributes['node-id'] = $content['default_placement']['node_id']; 708 $root->appendChild( $doc->createElementNode( 'contentobject-placement', 709 $placementAttributes ) ); 710 $doc->setRoot( $root ); 711 return $doc; 712 } 713 714 function createObjectDOMDocument( $content ) 715 { 716 $doc = new eZDOMDocument( 'ObjectRelationList' ); 717 $root = $doc->createElementNode( 'related-objects' ); 718 $relationList = $doc->createElementNode( 'relation-list' ); 719 foreach ( $content['relation_list'] as $relationItem ) 720 { 721 unset( $relationElement ); 722 $relationElement = $doc->createElementNode( 'relation-item' ); 723 $relationElement->appendAttributes( $relationItem, 724 eZObjectRelationListType::contentObjectArrayXMLMap() ); 725 $relationList->appendChild( $relationElement ); 726 } 727 $root->appendChild( $relationList ); 728 $doc->setRoot( $root ); 729 return $doc; 730 } 731 732 function contentObjectArrayXMLMap() 733 { 734 return array( 'identifier' => 'identifier', 735 'priority' => 'priority', 736 'contentobject-id' => 'contentobject_id', 737 'contentobject-version' => 'contentobject_version', 738 'node-id' => 'node_id', 739 'parent-node-id' => 'parent_node_id', 740 'contentclass-id' => 'contentclass_id', 741 'contentclass-identifier' => 'contentclass_identifier', 742 'is-modified' => 'is_modified', 743 'contentobject-remote-id' => 'contentobject_remote_id' ); 744 } 745 746 /*! 747 \reimp 748 */ 749 function deleteStoredObjectAttribute( &$objectAttribute, $version = null ) 750 { 751 $content =& $objectAttribute->content(); 752 if ( is_array( $content ) and 753 is_array( $content['relation_list'] ) ) 754 { 755 $db =& eZDB::instance(); 756 $db->begin(); 757 foreach ( $content['relation_list'] as $deletionItem ) 758 { 759 eZObjectRelationListType::removeRelationObject( $objectAttribute, $deletionItem ); 760 } 761 $db->commit(); 762 } 763 } 764 765 /*! 766 \reimp 767 */ 768 function customObjectAttributeHTTPAction( $http, $action, &$contentObjectAttribute, $parameters ) 769 { 770 $contentobjectID = false; 771 if ( eZDataType::fetchActionValue( $action, 'new_class', $classID ) or 772 $action == 'new_class' ) 773 { 774 if ( $action == 'new_class' ) 775 { 776 $base = $parameters['base_name']; 777 $classVariableName = $base . '_new_class'; 778 if ( $http->hasPostVariable( $classVariableName ) ) 779 { 780 $classVariable = $http->postVariable( $classVariableName ); 781 $classID = $classVariable[$contentObjectAttribute->attribute( 'id' )]; 782 $class = eZContentClass::fetch( $classID ); 783 } 784 else 785 return false; 786 } 787 else 788 $class = eZContentClass::fetch( $classID ); 789 if ( $class ) 790 { 791 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' ); 792 $class_content = $classAttribute->content(); 793 $content = $contentObjectAttribute->content(); 794 $priority = 0; 795 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 796 { 797 if ( $content['relation_list'][$i]['priority'] > $priority ) 798 $priority = $content['relation_list'][$i]['priority']; 799 } 800 801 $base = $parameters['base_name']; 802 $nodePlacement = false; 803 $nodePlacementName = $base . '_object_initial_node_placement'; 804 if ( $http->hasPostVariable( $nodePlacementName ) ) 805 { 806 $nodePlacementMap = $http->postVariable( $nodePlacementName ); 807 if ( isset( $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )] ) ) 808 $nodePlacement = $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )]; 809 } 810 $relationItem = eZObjectRelationListType::createInstance( $class, 811 $priority + 1, 812 $contentObjectAttribute, 813 $nodePlacement ); 814 if ( $class_content['default_placement'] ) 815 { 816 $relationItem['parent_node_id'] = $class_content['default_placement']['node_id']; 817 } 818 819 $content['relation_list'][] = $relationItem; 820 821 $hasAttributeInput = false; 822 $attributeInputVariable = $base . '_has_attribute_input'; 823 if ( $http->hasPostVariable( $attributeInputVariable ) ) 824 { 825 $attributeInputMap = $http->postVariable( $attributeInputVariable ); 826 if ( isset( $attributeInputMap[$contentObjectAttribute->attribute( 'id' )] ) ) 827 $hasAttributeInput = $attributeInputMap[$contentObjectAttribute->attribute( 'id' )]; 828 } 829 830 if ( $hasAttributeInput ) 831 { 832 $object =& $relationItem['object']; 833 $attributes =& $object->contentObjectAttributes(); 834 foreach ( array_keys( $attributes ) as $key ) 835 { 836 $attribute =& $attributes[$key]; 837 $attributeBase = $base . '_ezorl_init_class_' . $object->attribute( 'contentclass_id' ) . '_attr_' . $attribute->attribute( 'contentclassattribute_id' ); 838 $oldAttributeID = $attribute->attribute( 'id' ); 839 $attribute->setAttribute( 'id', false ); 840 if ( $attribute->fetchInput( $http, $attributeBase ) ) 841 { 842 $attribute->setAttribute( 'id', $oldAttributeID ); 843 $attribute->store(); 844 } 845 } 846 } 847 848 $contentObjectAttribute->setContent( $content ); 849 $contentObjectAttribute->store(); 850 } 851 else 852 eZDebug::writeError( "Unknown class ID $classID, cannot instantiate object", 853 'eZObjectRelationListType::customObjectAttributeHTTPAction' ); 854 } 855 else if ( eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) or 856 $action == 'edit_objects' or 857 $action == 'remove_objects' ) 858 { 859 $base = $parameters['base_name']; 860 $selectionBase = $base . '_selection'; 861 $selections = array(); 862 $http =& eZHTTPTool::instance(); 863 if ( $http->hasPostVariable( $selectionBase ) ) 864 { 865 $selectionMap = $http->postVariable( $selectionBase ); 866 $selections = $selectionMap[$contentObjectAttribute->attribute( 'id' )]; 867 } 868 if ( $contentobjectID !== false ) 869 $selections[] = $contentobjectID; 870 if ( $action == 'edit_objects' or 871 eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) ) 872 { 873 $content = $contentObjectAttribute->content(); 874 $relationList =& $content['relation_list']; 875 for ( $i = 0; $i < count( $relationList ); ++$i ) 876 { 877 $relationItem =& $relationList[$i]; 878 if ( !$relationItem['is_modified'] and 879 in_array( $relationItem['contentobject_id'], $selections ) ) 880 { 881 $object =& eZContentObject::fetch( $relationItem['contentobject_id'] ); 882 if ( $object->attribute( 'can_edit' ) ) 883 { 884 $relationItem['is_modified'] = true; 885 $version = $object->createNewVersion( $relationItem['contentobject_version'] ); 886 $relationItem['contentobject_version'] = $version->attribute( 'version' ); 887 } 888 } 889 } 890 $contentObjectAttribute->setContent( $content ); 891 $contentObjectAttribute->store(); 892 } 893 else if ( $action == 'remove_objects' ) 894 { 895 $content = $contentObjectAttribute->content(); 896 $relationList =& $content['relation_list']; 897 $newRelationList = array(); 898 for ( $i = 0; $i < count( $relationList ); ++$i ) 899 { 900 $relationItem = $relationList[$i]; 901 if ( in_array( $relationItem['contentobject_id'], $selections ) ) 902 { 903 eZObjectRelationListType::removeRelationObject( $contentObjectAttribute, $relationItem ); 904 } 905 else 906 $newRelationList[] = $relationItem; 907 } 908 $content['relation_list'] =& $newRelationList; 909 $contentObjectAttribute->setContent( $content ); 910 $contentObjectAttribute->store(); 911 } 912 } 913 else if ( $action == 'browse_objects' ) 914 { 915 $module =& $parameters['module']; 916 $redirectionURI = $parameters['current-redirection-uri']; 917 918 $ini = eZINI::instance( 'content.ini' ); 919 $browseType = 'AddRelatedObjectListToDataType'; 920 $browseTypeINIVariable = $ini->variable( 'ObjectRelationDataTypeSettings', 'ClassAttributeStartNode' ); 921 foreach ( $browseTypeINIVariable as $value ) 922 { 923 list( $classAttributeID, $type ) = explode( ';',$value ); 924 if ( is_numeric( $classAttributeID ) and 925 $classAttributeID == $contentObjectAttribute->attribute( 'contentclassattribute_id' ) and 926 strlen( $type ) > 0 ) 927 { 928 $browseType = $type; 929 break; 930 } 931 } 932 933 // Fetch the list of "allowed" classes . 934 // A user can select objects of only those allowed classes when browsing. 935 $classAttribute =& $contentObjectAttribute->attribute( 'contentclass_attribute' ); 936 $classContent =& $classAttribute->content(); 937 if ( isset( $classContent['class_constraint_list'] ) ) 938 $classConstraintList =& $classContent['class_constraint_list']; 939 else 940 $classConstraintList = array(); 941 942 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 943 $browseParameters = array( 'action_name' => 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ), 944 'type' => $browseType, 945 'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $contentObjectAttribute->attribute( 'id' ) . '_set_object_relation_list]', 946 'value' => $contentObjectAttribute->attribute( 'id' ) ), 947 'persistent_data' => array( 'HasObjectInput' => 0 ), 948 'from_page' => $redirectionURI ); 949 $base = $parameters['base_name']; 950 $nodePlacementName = $base . '_browse_for_object_start_node'; 951 if ( $http->hasPostVariable( $nodePlacementName ) ) 952 { 953 $nodePlacement = $http->postVariable( $nodePlacementName ); 954 if ( isset( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ) ) 955 $browseParameters['start_node'] = eZContentBrowse::nodeAliasID( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ); 956 } 957 if ( count($classConstraintList) > 0 ) 958 $browseParameters['class_array'] = $classConstraintList; 959 960 eZContentBrowse::browse( $browseParameters, 961 $module ); 962 } 963 else if ( $action == 'set_object_relation_list' ) 964 { 965 if ( !$http->hasPostVariable( 'BrowseCancelButton' ) ) 966 { 967 $selectedObjectIDArray = $http->postVariable( "SelectedObjectIDArray" ); 968 $content = $contentObjectAttribute->content(); 969 $priority = 0; 970 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 971 { 972 if ( $content['relation_list'][$i]['priority'] > $priority ) 973 $priority = $content['relation_list'][$i]['priority']; 974 } 975 976 foreach ( $selectedObjectIDArray as $objectID ) 977 { 978 // Check if the given object ID has a numeric value, if not go to the next object. 979 if ( !is_numeric( $objectID ) ) 980 { 981 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", 982 "eZObjectRelationListType::customObjectAttributeHTTPAction" ); 983 984 continue; 985 } 986 987 /* Here we check if current object is already in the related objects list. 988 * If so, we don't add it again. 989 * FIXME: Stupid linear search. Maybe there's some better way? 990 */ 991 $found = false; 992 foreach ( $content['relation_list'] as $i ) 993 { 994 if ( $i['contentobject_id'] == $objectID ) 995 { 996 $found = true; 997 break; 998 } 999 } 1000 if ( $found ) 1001 continue; 1002 1003 ++$priority; 1004 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute ); 1005 $contentObjectAttribute->setContent( $content ); 1006 $contentObjectAttribute->store(); 1007 } 1008 } 1009 } 1010 else 1011 { 1012 eZDebug::writeError( "Unknown custom HTTP action: " . $action, 1013 'eZObjectRelationListType' ); 1014 } 1015 } 1016 1017 /*! 1018 \reimp 1019 */ 1020 function handleCustomObjectHTTPActions( &$http, $attributeDataBaseName, 1021 $customActionAttributeArray, $customActionParameters ) 1022 { 1023 $contentObjectAttribute =& $customActionParameters['contentobject_attribute']; 1024 $content =& $contentObjectAttribute->content(); 1025 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 1026 { 1027 $relationItem = $content['relation_list'][$i]; 1028 $subObjectID = $relationItem['contentobject_id']; 1029 $subObjectVersion = $relationItem['contentobject_version']; 1030 1031 $attributeBase = $attributeDataBaseName . '_ezorl_edit_object_' . $subObjectID; 1032 $object =& $content['temp'][$subObjectID]['object']; 1033 if ( eZContentObject::recursionProtect( $subObjectID ) ) 1034 { 1035 if ( !$object ) 1036 $object =& eZContentObject::fetch( $subObjectID ); 1037 if ( $object ) 1038 $object->handleAllCustomHTTPActions( $attributeBase, 1039 $customActionAttributeArray, 1040 $customActionParameters, 1041 $subObjectVersion ); 1042 } 1043 } 1044 } 1045 1046 /*! 1047 \static 1048 \return \c true if the relation item \a $relationItem exist in the content tree. 1049 */ 1050 function isItemPublished( &$relationItem ) 1051 { 1052 return is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] > 0; 1053 } 1054 1055 /*! 1056 \private 1057 Removes the relation object \a $deletionItem if the item is owned solely by this 1058 version and is not published in the content tree. 1059 */ 1060 function removeRelationObject( &$contentObjectAttribute, &$deletionItem ) 1061 { 1062 if ( eZObjectRelationListType::isItemPublished( $deletionItem ) ) 1063 { 1064 return; 1065 } 1066 1067 $hostObject =& $contentObjectAttribute->attribute( 'object' ); 1068 $hostObjectVersions =& $hostObject->versions(); 1069 $isDeletionAllowed = true; 1070 1071 // check if the relation item to be deleted is unique in the domain of all host-object versions 1072 foreach ( $hostObjectVersions as $version ) 1073 { 1074 if ( $isDeletionAllowed and 1075 $version->attribute( 'version' ) != $contentObjectAttribute->attribute( 'version' ) ) 1076 { 1077 $relationAttribute = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), 1078 null, 1079 array( 'version' => $version->attribute( 'version' ), 1080 'contentobject_id' => $hostObject->attribute( 'id' ), 1081 'contentclassattribute_id' => $contentObjectAttribute->attribute( 'contentclassattribute_id' ) ) ); 1082 1083 if ( count( $relationAttribute ) > 0 ) 1084 { 1085 $relationContent =& $relationAttribute[0]->content(); 1086 if ( is_array( $relationContent ) and 1087 is_array( $relationContent['relation_list'] ) ) 1088 { 1089 $relationContentCount = count( $relationContent['relation_list'] ); 1090 for ( $i = 0; $i < $relationContentCount; ++$i ) 1091 { 1092 if ( $deletionItem['contentobject_id'] == $relationContent['relation_list'][$i]['contentobject_id'] && 1093 $deletionItem['contentobject_version'] == $relationContent['relation_list'][$i]['contentobject_version'] ) 1094 { 1095 $isDeletionAllowed = false; 1096 break 2; 1097 } 1098 } 1099 } 1100 } 1101 } 1102 } 1103 1104 if ( $isDeletionAllowed ) 1105 { 1106 $subObjectVersion = eZContentObjectVersion::fetchVersion( $deletionItem['contentobject_version'], 1107 $deletionItem['contentobject_id'] ); 1108 if ( get_class( $subObjectVersion ) == 'ezcontentobjectversion' ) 1109 { 1110 $subObjectVersion->remove(); 1111 } 1112 else 1113 { 1114 eZDebug::writeError( 'Cleanup of subobject-version failed. Could not fetch object from relation list.\n' . 1115 'Requested subobject id: ' . $relationItem['contentobject_id'] . '\n' . 1116 'Requested Subobject version: ' . $relationItem['contentobject_version'], 1117 'eZObjectRelationListType::removeRelationObject' ); 1118 } 1119 } 1120 } 1121 1122 1123 function createInstance( &$class, $priority, &$contentObjectAttribute, $nodePlacement = false ) 1124 { 1125 $currentObject =& $contentObjectAttribute->attribute( 'object' ); 1126 $sectionID = $currentObject->attribute( 'section_id' ); 1127 $object = $class->instantiate( false, $sectionID ); 1128 if ( !is_numeric( $nodePlacement ) or $nodePlacement <= 0 ) 1129 $nodePlacement = false; 1130 $object->sync(); 1131 $relationItem = array( 'identifier' => false, 1132 'priority' => $priority, 1133 'contentobject_id' => $object->attribute( 'id' ), 1134 'contentobject_version' => $object->attribute( 'current_version' ), 1135 'node_id' => false, 1136 'parent_node_id' => $nodePlacement, 1137 'contentclass_id' => $class->attribute( 'id' ), 1138 'contentclass_identifier' => $class->attribute( 'identifier' ), 1139 'is_modified' => true ); 1140 $relationItem['object'] =& $object; 1141 return $relationItem; 1142 } 1143 1144 function appendObject( $objectID, $priority, &$contentObjectAttribute ) 1145 { 1146 $object =& eZContentObject::fetch( $objectID ); 1147 $class =& $object->attribute( 'content_class' ); 1148 $sectionID = $object->attribute( 'section_id' ); 1149 $relationItem = array( 'identifier' => false, 1150 'priority' => $priority, 1151 'contentobject_id' => $object->attribute( 'id' ), 1152 'contentobject_version' => $object->attribute( 'current_version' ), 1153 'node_id' => $object->attribute( 'main_node_id' ), 1154 'parent_node_id' => $object->attribute( 'main_parent_node_id' ), 1155 'contentclass_id' => $class->attribute( 'id' ), 1156 'contentclass_identifier' => $class->attribute( 'identifier' ), 1157 'is_modified' => false ); 1158 $relationItem['object'] =& $object; 1159 return $relationItem; 1160 } 1161 1162 /*! 1163 Returns the content. 1164 */ 1165 function &objectAttributeContent( &$contentObjectAttribute ) 1166 { 1167 $xmlText = $contentObjectAttribute->attribute( 'data_text' ); 1168 if ( trim( $xmlText ) == '' ) 1169 { 1170 $objectAttributeContent = eZObjectRelationListType::defaultObjectAttributeContent(); 1171 return $objectAttributeContent; 1172 } 1173 $doc =& eZObjectRelationListType::parseXML( $xmlText ); 1174 $content = eZObjectRelationListType::createObjectContentStructure( $doc ); 1175 1176 return $content; 1177 } 1178 1179 /*! 1180 \reimp 1181 */ 1182 function &classAttributeContent( &$classAttribute ) 1183 { 1184 $xmlText = $classAttribute->attribute( 'data_text5' ); 1185 if ( trim( $xmlText ) == '' ) 1186 { 1187 $classAttributeContent = eZObjectRelationListType::defaultClassAttributeContent(); 1188 return $classAttributeContent; 1189 } 1190 $doc =& eZObjectRelationListType::parseXML( $xmlText ); 1191 $content = eZObjectRelationListType::createClassContentStructure( $doc ); 1192 return $content; 1193 } 1194 1195 function &parseXML( $xmlText ) 1196 { 1197 $xml = new eZXML(); 1198 $dom =& $xml->domTree( $xmlText ); 1199 return $dom; 1200 } 1201 1202 function defaultClassAttributeContent() 1203 { 1204 return array( 'object_class' => '', 1205 'selection_type' => 0, 1206 'type' => 0, 1207 'class_constraint_list' => array(), 1208 'default_placement' => false ); 1209 } 1210 1211 function defaultObjectAttributeContent() 1212 { 1213 return array( 'relation_list' => array() ); 1214 } 1215 1216 function createClassContentStructure( &$doc ) 1217 { 1218 $content = eZObjectRelationListType::defaultClassAttributeContent(); 1219 $root =& $doc->root(); 1220 $objectPlacement =& $root->elementByName( 'contentobject-placement' ); 1221 1222 if ( $objectPlacement and $objectPlacement->hasAttributes() ) 1223 { 1224 $nodeID = $objectPlacement->attributeValue( 'node-id' ); 1225 $content['default_placement'] = array( 'node_id' => $nodeID ); 1226 } 1227 $constraints =& $root->elementByName( 'constraints' ); 1228 if ( $constraints ) 1229 { 1230 $allowedClassList = $constraints->elementsByName( 'allowed-class' ); 1231 foreach( $allowedClassList as $allowedClass ) 1232 { 1233 $content['class_constraint_list'][] = $allowedClass->attributeValue( 'contentclass-identifier' ); 1234 } 1235 } 1236 $type =& $root->elementByName( 'type' ); 1237 if ( $type ) 1238 { 1239 $content['type'] = $type->attributeValue( 'value' ); 1240 } 1241 $selectionType =& $root->elementByName( 'selection_type' ); 1242 if ( $selectionType ) 1243 { 1244 $content['selection_type'] = $selectionType->attributeValue( 'value' ); 1245 } 1246 $objectClass =& $root->elementByName( 'object_class' ); 1247 if ( $objectClass ) 1248 { 1249 $content['object_class'] = $objectClass->attributeValue( 'value' ); 1250 } 1251 1252 return $content; 1253 } 1254 1255 function createObjectContentStructure( &$doc ) 1256 { 1257 $content = eZObjectRelationListType::defaultObjectAttributeContent(); 1258 $root =& $doc->root(); 1259 $relationList =& $root->elementByName( 'relation-list' ); 1260 if ( $relationList ) 1261 { 1262 $relationItems = $relationList->elementsByName( 'relation-item' ); 1263 foreach( $relationItems as $relationItem ) 1264 { 1265 $content['relation_list'][] = $relationItem->attributeValues( eZObjectRelationListType::contentObjectArrayXMLMap(), 1266 false ); 1267 } 1268 } 1269 return $content; 1270 } 1271 1272 /*! 1273 \reimp 1274 */ 1275 function customClassAttributeHTTPAction( &$http, $action, &$classAttribute ) 1276 { 1277 switch ( $action ) 1278 { 1279 case 'browse_for_placement': 1280 { 1281 $module =& $classAttribute->currentModule(); 1282 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 1283 $customActionName = 'CustomActionButton[' . $classAttribute->attribute( 'id' ) . '_browsed_for_placement]'; 1284 eZContentBrowse::browse( array( 'action_name' => 'SelectObjectRelationListNode', 1285 'content' => array( 'contentclass_id' => $classAttribute->attribute( 'contentclass_id' ), 1286 'contentclass_attribute_id' => $classAttribute->attribute( 'id' ), 1287 'contentclass_version' => $classAttribute->attribute( 'version' ), 1288 'contentclass_attribute_identifier' => $classAttribute->attribute( 'identifier' ) ), 1289 'persistent_data' => array( $customActionName => '', 1290 'ContentClassHasInput' => false ), 1291 'description_template' => 'design:class/datatype/browse_objectrelationlist_placement.tpl', 1292 'from_page' => $module->currentRedirectionURI() ), 1293 $module ); 1294 } break; 1295 case 'browsed_for_placement': 1296 { 1297 include_once ( 'kernel/classes/ezcontentbrowse.php' ); 1298 $nodeSelection = eZContentBrowse::result( 'SelectObjectRelationListNode' ); 1299 if ( $nodeSelection and count( $nodeSelection ) > 0 ) 1300 { 1301 $nodeID = $nodeSelection[0]; 1302 $content = $classAttribute->content(); 1303 $content['default_placement'] = array( 'node_id' => $nodeID ); 1304 $classAttribute->setContent( $content ); 1305 } 1306 } break; 1307 case 'disable_placement': 1308 { 1309 $content =& $classAttribute->content(); 1310 $content['default_placement'] = false; 1311 $classAttribute->setContent( $content ); 1312 } break; 1313 default: 1314 { 1315 eZDebug::writeError( "Unknown objectrelationlist action '$action'", 'eZContentObjectRelationListType::customClassAttributeHTTPAction' ); 1316 } break; 1317 } 1318 } 1319 1320 /*! 1321 Returns the meta data used for storing search indeces. 1322 */ 1323 function metaData( $contentObjectAttribute ) 1324 { 1325 $metaDataArray = array(); 1326 $content =& $contentObjectAttribute->content(); 1327 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) 1328 { 1329 $relationItem = $content['relation_list'][$i]; 1330 $subObjectID = $relationItem['contentobject_id']; 1331 if ( !$subObjectID ) 1332 continue; 1333 1334 $attributes =& $content['temp'][$subObjectID]['attributes']; 1335 if ( !$attributes ) 1336 { 1337 $subObjectVersion = $relationItem['contentobject_version']; 1338 $object =& eZContentObject::fetch( $subObjectID ); 1339 if ( eZContentObject::recursionProtect( $subObjectID ) ) 1340 { 1341 if ( !$object ) 1342 { 1343 continue; 1344 } 1345 $attributes =& $object->contentObjectAttributes( true, $subObjectVersion ); 1346 } 1347 } 1348 1349 $metaDataArray = array_merge( $metaDataArray, eZContentObjectAttribute::metaDataArray( $attributes ) ); 1350 } 1351 1352 return $metaDataArray; 1353 } 1354 1355 /*! 1356 \return string representation of an contentobjectattribute data for simplified export 1357 1358 */ 1359 function toString( $contentObjectAttribute ) 1360 { 1361 $objectAttributeContent = $contentObjectAttribute->attribute( 'content' ); 1362 $objectIDList = array(); 1363 foreach( $objectAttributeContent['relation_list'] as $objectInfo ) 1364 { 1365 $objectIDList[] = $objectInfo['contentobject_id']; 1366 } 1367 return implode( '-', $objectIDList ); 1368 } 1369 1370 function fromString( &$contentObjectAttribute, $string ) 1371 { 1372 $objectIDList = explode( '-', $string ); 1373 1374 $content = eZObjectRelationListType::defaultObjectAttributeContent(); 1375 $priority = 0; 1376 foreach( $objectIDList as $objectID ) 1377 { 1378 $object = eZContentObject::fetch( $objectID ); 1379 if ( $object ) 1380 { 1381 ++$priority; 1382 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute ); 1383 } 1384 else 1385 { 1386 eZDebug::writeWarning( $objectID, "Can not create relation because object is missing" ); 1387 } 1388 } 1389 $contentObjectAttribute->setContent( $content ); 1390 return true; 1391 } 1392 1393 function hasObjectAttributeContent( &$contentObjectAttribute ) 1394 { 1395 $content =& $contentObjectAttribute->content(); 1396 return count( $content['relation_list'] ) > 0; 1397 } 1398 1399 /*! 1400 \reimp 1401 */ 1402 function isIndexable() 1403 { 1404 return true; 1405 } 1406 1407 /*! 1408 Returns the content of the string for use as a title 1409 */ 1410 function title( &$contentObjectAttribute ) 1411 { 1412 return false; 1413 } 1414 1415 /*! 1416 \reimp 1417 */ 1418 function serializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode ) 1419 { 1420 $content =& $classAttribute->content(); 1421 if ( $content['default_placement'] ) 1422 $attributeParametersNode->appendChild( eZDOMDocument::createElementNode( 'default-placement', 1423 array( 'node-id' => $content['default_placement']['node_id'] ) ) ); 1424 if ( is_numeric( $content['type'] ) ) 1425 $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'type', $content['type'] ) ); 1426 else 1427 $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'type', '0' ) ); 1428 $classConstraintsNode = eZDOMDocument::createElementNode( 'class-constraints' ); 1429 $attributeParametersNode->appendChild( $classConstraintsNode ); 1430 foreach ( $content['class_constraint_list'] as $classConstraint ) 1431 { 1432 $classConstraintIdentifier = $classConstraint; 1433 $classConstraintsNode->appendChild( eZDOMDocument::createElementNode( 'class-constraint', 1434 array( 'class-identifier' => $classConstraintIdentifier ) ) ); 1435 } 1436 } 1437 1438 /*! 1439 \reimp 1440 */ 1441 function unserializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode ) 1442 { 1443 $content =& $classAttribute->content(); 1444 $defaultPlacementNode = $attributeParametersNode->elementByName( 'default-placement' ); 1445 $content['default_placement'] = false; 1446 if ( $defaultPlacementNode ) 1447 $content['default_placement'] = $defaultPlacementNode->attributeValue( 'node-id' ); 1448 $content['type'] = $attributeParametersNode->elementTextContentByName( 'type' ); 1449 $classConstraintsNode =& $attributeParametersNode->elementByName( 'class-constraints' ); 1450 $classConstraintList = $classConstraintsNode->children(); 1451 $content['class_constraint_list'] = array(); 1452 foreach ( $classConstraintList as $classConstraintNode ) 1453 { 1454 $classIdentifier = $classConstraintNode->attributeValue( 'class-identifier' ); 1455 $content['class_constraint_list'][] = $classIdentifier; 1456 } 1457 $this->storeClassAttributeContent( $classAttribute, $content ); 1458 } 1459 1460 /*! 1461 For each relation export its priority and content object remote_id, like this: 1462 <related-objects> 1463 <relation-list> 1464 <relation-item priority="1" 1465 contentobject-remote-id="faaeb9be3bd98ed09f606fc16d144eca" /> 1466 <relation-item priority="2" 1467 contentobject-remote-id="1bb4fe25487f05527efa8bfd394cecc7" /> 1468 </relation-list> 1469 To do this we fetch content XML and strip all the relation attributes except of "priority" from there, 1470 and add "contentobject-remote-id" attribute. 1471 \reimp 1472 */ 1473 function serializeContentObjectAttribute( &$package, &$objectAttribute ) 1474 { 1475 $node = $this->createContentObjectAttributeDOMNode( $objectAttribute ); 1476 1477 $xml = new eZXML(); 1478 $domDocument = $xml->domTree( $objectAttribute->attribute( 'data_text' ) ); 1479 $rootNode =& $domDocument->root(); 1480 $relationList =& $rootNode->elementByName( 'relation-list' ); 1481 if ( $relationList ) 1482 { 1483 require_once ( 'kernel/classes/ezcontentobject.php' ); 1484 $relationItems = $relationList->elementsByName( 'relation-item' ); 1485 foreach( $relationItems as $i => $relationItem ) 1486 { 1487 // Add related object remote id as attribute to the relation item. 1488 $relatedObjectID = $relationItem->attributeValue( 'contentobject-id' ); 1489 $relatedObject = eZContentObject::fetch( $relatedObjectID ); 1490 $relatedObjectRemoteID = $relatedObject->attribute( 'remote_id' ); 1491 require_once ( 'kernel/classes/ezcontentobject.php' ); 1492 $relationItems[$i]->setAttribute( 'contentobject-remote-id', $relatedObjectRemoteID ); 1493 1494 // Remove all other relation item attributes except of "priority". 1495 foreach ( $relationItem->attributes() as $attribute ) 1496 { 1497 $attrName = $attribute->name(); 1498 if ( $attrName != 'priority' && $attrName != 'contentobject-remote-id' ) 1499 $relationItems[$i]->removeAttribute( $attrName ); 1500 } 1501 } 1502 } 1503 1504 $node->appendChild( $rootNode ); 1505 1506 return $node; 1507 } 1508 1509 /*! 1510 \reimp 1511 */ 1512 function unserializeContentObjectAttribute( &$package, &$objectAttribute, $attributeNode ) 1513 { 1514 $rootNode = $attributeNode->firstChild(); 1515 1516 if ( $rootNode->attributeValue( 'local_name' ) == 'data-text' ) 1517 $xmlString = ''; 1518 else 1519 { 1520 $xmlString = $rootNode->toString( 0 ); 1521 } 1522 1523 $objectAttribute->setAttribute( 'data_text', $xmlString ); 1524 } 1525 1526 function postUnserializeContentObjectAttribute( &$package, &$objectAttribute ) 1527 { 1528 $xmlString = $objectAttribute->attribute( 'data_text' ); 1529 $doc =& $this->parseXML( $xmlString ); 1530 $rootNode =& $doc->root(); 1531 1532 $relationList =& $rootNode->elementByName( 'relation-list' ); 1533 if ( !$relationList ) 1534 return false; 1535 1536 require_once ( 'kernel/classes/ezcontentobject.php' ); 1537 $relationItems = $relationList->elementsByName( 'relation-item' ); 1538 foreach( $relationItems as $i => $relationItem ) 1539 { 1540 $relatedObjectRemoteID = $relationItem->attributeValue( 'contentobject-remote-id' ); 1541 $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID ); 1542 1543 if ( $object === null ) 1544 { 1545 eZDebug::writeWarning( "Object with remote id '$relatedObjectRemoteID' not found: removing the link.", 1546 'eZObjectRelationListType::unserializeContentObjectAttribute()' ); 1547 unset( $relationItems[$i] ); 1548 continue; 1549 } 1550 1551 $relationItems[$i]->setAttribute( 'contentobject-id', $object->attribute( 'id' ) ); 1552 $relationItems[$i]->setAttribute( 'contentobject-version', $object->attribute( 'current_version' ) ); 1553 $relationItems[$i]->setAttribute( 'node-id', $object->attribute( 'main_node_id' ) ); 1554 $relationItems[$i]->setAttribute( 'parent-node-id', $object->attribute( 'main_parent_node_id' ) ); 1555 $relationItems[$i]->setAttribute( 'contentclass-id', $object->attribute( 'contentclass_id' ) ); 1556 $relationItems[$i]->setAttribute( 'contentclass-identifier', $object->attribute( 'class_identifier' ) ); 1557 } 1558 1559 $newXmlString = $rootNode->toString( 0 ); 1560 1561 $objectAttribute->setAttribute( 'data_text', $newXmlString ); 1562 return true; 1563 } 1564 1565 /*! 1566 Removes objects with given ID from the relations list 1567 */ 1568 function removeRelatedObjectItem( &$contentObjectAttribute, $objectID ) 1569 { 1570 $xmlText = $contentObjectAttribute->attribute( 'data_text' ); 1571 if ( trim( $xmlText ) == '' ) return; 1572 1573 $doc =& eZObjectRelationListType::parseXML( $xmlText ); 1574 1575 $return = false; 1576 $root =& $doc->root(); 1577 $relationList =& $root->elementByName( 'relation-list' ); 1578 if ( $relationList ) 1579 { 1580 $relationItems = $relationList->elementsByName( 'relation-item' ); 1581 if ( count( $relationItems ) ) 1582 { 1583 foreach( array_keys( $relationItems ) as $key ) 1584 { 1585 $relationItem =& $relationItems[$key]; 1586 if ( $relationItem->attributeValue( 'contentobject-id' ) == $objectID ) 1587 { 1588 $relationList->removeChild( $relationItem ); 1589 $return = true; 1590 } 1591 } 1592 } 1593 } 1594 eZObjectRelationListType::storeObjectDOMDocument( $doc, $contentObjectAttribute ); 1595 return $return; 1596 } 1597 1598 /// \privatesection 1599 } 1600 1601 eZDataType::register( EZ_DATATYPESTRING_OBJECT_RELATION_LIST, "ezobjectrelationlisttype" ); 1602 1603 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sat Feb 24 10:30:04 2007 | par Balluche grâce à PHPXref 0.7 |