Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezobjectrelationlisttype.php
Go to the documentation of this file.
1 <?php
25 class eZObjectRelationListType extends eZDataType
26 {
27 const DATA_TYPE_STRING = "ezobjectrelationlist";
28
29 public function __construct()
30 {
31 parent::__construct( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', "Object relations", 'Datatype name' ),
32 array( 'serialize_supported' => true ) );
33 }
34
35 public function isRelationType()
36 {
37 return true;
38 }
39
44 function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
45 {
46 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" );
47 if ( $http->hasPostVariable( $postVariableName ) && !$contentObjectAttribute->validateIsRequired() && $http->postVariable( $postVariableName ) == array( "no_relation" ) )
48 {
49 return eZInputValidator::STATE_ACCEPTED;
50 }
51
52 $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
53
54 // Check if selection type is not browse
55 $classContent = $contentClassAttribute->content();
56
57 if ( $classContent['selection_type'] != 0 )
58 {
59 if (
60 $contentObjectAttribute->validateIsRequired()
61 && ( !$http->hasPostVariable( $postVariableName ) || $http->postVariable( $postVariableName ) == array( "no_relation" ) )
62 )
63 {
64 $contentObjectAttribute->setValidationError(
65 ezpI18n::tr(
66 'kernel/classes/datatypes',
67 'Missing objectrelation list input.'
68 )
69 );
70 return eZInputValidator::STATE_INVALID;
71 }
72 return eZInputValidator::STATE_ACCEPTED;
73 }
74 else if ( eZINI::instance()->variable( 'BackwardCompatibilitySettings', 'AdvancedObjectRelationList' ) == "disabled" )
75 {
76 // If in browse mode and relations have been added using the search field
77 // items are stored in the post variable
78 if (
79 $http->hasPostVariable( $postVariableName )
80 && $http->postVariable( $postVariableName ) != array( "no_relation" )
81 && count( $http->postVariable( $postVariableName ) ) > 0
82 )
83 {
84 return eZInputValidator::STATE_ACCEPTED;
85 }
86 }
87
88 // The following code is only there for the support of [BackwardCompatibilitySettings]/AdvancedObjectRelationList
89 // which happens only when $classContent['selection_type'] == 0
90 $content = $contentObjectAttribute->content();
91 if ( $contentObjectAttribute->validateIsRequired() && empty( $content['relation_list'] ) )
92 {
93 $contentObjectAttribute->setValidationError(
94 ezpI18n::tr(
95 'kernel/classes/datatypes',
96 'Missing objectrelation list input.'
97 )
98 );
99 return eZInputValidator::STATE_INVALID;
100 }
101
102 $status = eZInputValidator::STATE_ACCEPTED;
103 $inputParameters = $contentObjectAttribute->inputParameters();
104 $parameters = $contentObjectAttribute->validationParameters();
105 if ( isset( $parameters['prefix-name'] ) && $parameters['prefix-name'] )
106 $parameters['prefix-name'][] = $contentClassAttribute->attribute( 'name' );
107 else
108 $parameters['prefix-name'] = array( $contentClassAttribute->attribute( 'name' ) );
109
110 foreach ( $content['relation_list'] as $relationItem )
111 {
112 if ( !$relationItem['is_modified'] )
113 {
114 continue;
115 }
116
117 $subObjectID = $relationItem['contentobject_id'];
118 $object = eZContentObject::fetch( $subObjectID );
119
120 if ( !$object )
121 {
122 continue;
123 }
124
125 $attributes = $object->contentObjectAttributes(
126 true,
127 $relationItem['contentobject_version'],
128 $contentObjectAttribute->attribute( 'language_code' )
129 );
130
131 $validationResult = $object->validateInput(
132 $attributes,
133 $base . '_ezorl_edit_object_' . $subObjectID,
134 $inputParameters,
135 $parameters
136 );
137 $content['temp'][$subObjectID] = array(
138 'require-fixup' => $validationResult['require-fixup'],
139 'attributes' => $attributes,
140 'object' => $object,
141 );
142 foreach ( $validationResult['status-map'] as $statusItem )
143 {
144 $statusValue = $statusItem['value'];
145 if ( $statusValue == eZInputValidator::STATE_INTERMEDIATE && $status == eZInputValidator::STATE_ACCEPTED )
146 {
147 $status = eZInputValidator::STATE_INTERMEDIATE;
148 }
149 else if ( $statusValue == eZInputValidator::STATE_INVALID )
150 {
151 $contentObjectAttribute->setHasValidationError( false );
152 $status = eZInputValidator::STATE_INVALID;
153 }
154 }
155 }
156
157 $contentObjectAttribute->setContent( $content );
158 return $status;
159 }
160
165 function fixupObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
166 {
167 $content = $contentObjectAttribute->content();
168 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
169 {
170 $relationItem = $content['relation_list'][$i];
171 if ( $relationItem['is_modified'] )
172 {
173 $subObjectID = $relationItem['contentobject_id'];
174 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID;
175 $object = $content['temp'][$subObjectID]['object'];
176 $requireFixup = $content['temp'][$subObjectID]['require-fixup'];
177 if ( $object and
178 $requireFixup )
179 {
180 $attributes = $content['temp'][$subObjectID]['attributes'];
181 $object->fixupInput( $attributes, $attributeBase );
182 }
183 }
184 }
185 }
186
190 function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
191 {
192 $content = $contentObjectAttribute->content();
193 // new object creation
194 $newObjectPostVariableName = "attribute_" . $contentObjectAttribute->attribute( "id" ) . "_new_object_name";
195 if ( $http->hasPostVariable( $newObjectPostVariableName ) )
196 {
197 $name = $http->postVariable( $newObjectPostVariableName );
198 if ( !empty( $name ) )
199 {
200 $content['new_object'] = $name;
201 }
202 }
203 $singleSelectPostVariableName = "single_select_" . $contentObjectAttribute->attribute( "id" );
204 if ( $http->hasPostVariable( $singleSelectPostVariableName ) )
205 $content['singleselect'] = true;
206
207 $postVariableName = $base . "_data_object_relation_list_" . $contentObjectAttribute->attribute( "id" );
208 $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
209 $classContent = $contentClassAttribute->content();
210
211 $selectedObjectIDArray = $http->hasPostVariable( $postVariableName ) ? $http->postVariable( $postVariableName ) : false;
212
213 // If we got an empty object id list
214 if ( ( $selectedObjectIDArray === false && $classContent['selection_type'] != 0 ) || ( isset( $selectedObjectIDArray[0] ) && $selectedObjectIDArray[0] === 'no_relation' ) )
215 {
216 $content['relation_list'] = array();
217 $contentObjectAttribute->setContent( $content );
218 return true;
219 }
220 // Type is browse and we have no http input
221 else if ( $selectedObjectIDArray === false )
222 {
223 return false;
224 }
225
226 // Check if selection type is not browse
227 if ( $classContent['selection_type'] != 0 )
228 {
229 $priority = 0;
230 $content['relation_list'] = array();
231 foreach ( $selectedObjectIDArray as $objectID )
232 {
233 // Check if the given object ID has a numeric value, if not go to the next object.
234 if ( !is_numeric( $objectID ) )
235 {
236 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", __METHOD__ );
237
238 continue;
239 }
240 ++$priority;
241 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
242 }
243
244 $contentObjectAttribute->setContent( $content );
245 return true;
246 }
247
248 $priorities = array();
249 $priorityBase = $base . '_priority';
250 $contentObjectAttributeID = $contentObjectAttribute->attribute( 'id' );
251 if ( $http->hasPostVariable( $priorityBase ) )
252 $priorities = $http->postVariable( $priorityBase );
253
254 // Add new relations
255 if ( $selectedObjectIDArray )
256 {
257 foreach ( $selectedObjectIDArray as $x => $objectID )
258 {
259 // Check if the given object ID has a numeric value, if not go to the next object.
260 if ( !is_numeric( $objectID ) )
261 {
262 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", __METHOD__ );
263
264 continue;
265 }
266 for ( $y = 0, $c = count( $content['relation_list'] ); $y < $c; ++$y )
267 {
268 if ( $objectID == $content['relation_list'][$y]['contentobject_id'] )
269 {
270 continue 2;
271 }
272 }
273 $content['relation_list'][] = $this->appendObject( $objectID, $priorities[$contentObjectAttributeID][$x], $contentObjectAttribute );
274 }
275 }
276
277 // Indexing priorities by object id
278 // and make sure each priority is unique
279 $existingPriorities = array();
280 $prioritiesByContentObjectId = array();
281 foreach ( $selectedObjectIDArray as $k => $id )
282 {
283 $priority = (int)$priorities[$contentObjectAttributeID][$k];
284 while ( isset( $existingPriorities[$priority] ) )
285 {
286 $priority++;
287 }
288 $prioritiesByContentObjectId[$id] = $priority;
289 $existingPriorities[$priority] = $priority;
290 }
291
292 foreach ( $content['relation_list'] as &$relationItem )
293 {
294 if ( $relationItem['is_modified'] )
295 {
296 $subObjectID = $relationItem['contentobject_id'];
297 $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID;
298 $object = $content['temp'][$subObjectID]['object'];
299 if ( $object )
300 {
301 $attributes = $content['temp'][$subObjectID]['attributes'];
302
303 $customActionAttributeArray = array();
304 $fetchResult = $object->fetchInput( $attributes, $attributeBase,
305 $customActionAttributeArray,
306 $contentObjectAttribute->inputParameters() );
307 $content['temp'][$subObjectID]['attribute-input-map'] = $fetchResult['attribute-input-map'];
308 $content['temp'][$subObjectID]['attributes'] = $attributes;
309 $content['temp'][$subObjectID]['object'] = $object;
310 }
311 }
312 $relationItem['priority'] = $prioritiesByContentObjectId[$relationItem['contentobject_id']];
313 }
314
315 usort(
316 $content['relation_list'],
317 function ( $a, $b )
318 {
319 return $a['priority'] - $b['priority'];
320 }
321 );
322 $p = 1;
323 foreach ( $content['relation_list'] as &$relationItem )
324 {
325 $relationItem['priority'] = $p;
326 $p++;
327 }
328
329 $contentObjectAttribute->setContent( $content );
330 return true;
331 }
332
333 function createNewObject( $contentObjectAttribute, $name )
334 {
335 $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
336 $classContent = $classAttribute->content();
337 $classID = $classContent['object_class'];
338 if ( !isset( $classID ) or !is_numeric( $classID ) )
339 return false;
340
341 $defaultPlacementNode = ( is_array( $classContent['default_placement'] ) and isset( $classContent['default_placement']['node_id'] ) ) ? $classContent['default_placement']['node_id'] : false;
342 if ( !$defaultPlacementNode )
343 {
344 eZDebug::writeError( 'Default placement is missing', __METHOD__ );
345 return false;
346 }
347
348 $node = eZContentObjectTreeNode::fetch( $defaultPlacementNode );
349 // Check if current user can create a new node as child of this node.
350 if ( !$node or !$node->canCreate() )
351 {
352 eZDebug::writeError( 'Default placement is wrong or the current user can\'t create a new node as child of this node.', __METHOD__ );
353 return false;
354 }
355
356 $classList = $node->canCreateClassList( false );
357 $canCreate = false;
358 // Check if current user can create object of class (with $classID)
359 foreach ( $classList as $class )
360 {
361 if ( $class['id'] == $classID )
362 {
363 $canCreate = true;
364 break;
365 }
366 }
367 if ( !$canCreate )
368 {
369 eZDebug::writeError( 'The current user is not allowed to create objects of class (ID=' . $classID . ')', __METHOD__ );
370 return false;
371 }
372
373 $class = eZContentClass::fetch( $classID );
374 if ( !$class )
375 return false;
376
377 $currentObject = $contentObjectAttribute->attribute( 'object' );
378 $sectionID = $currentObject->attribute( 'section_id' );
379 //instantiate object, same section, currentuser as owner (i.e. provide false as param)
380 $newObjectInstance = $class->instantiate( false, $sectionID );
381 $nodeassignment = $newObjectInstance->createNodeAssignment( $defaultPlacementNode, true );
382 $nodeassignment->store();
383 $newObjectInstance->sync();
384 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObjectInstance->attribute( 'id' ), 'version' => 1 ) );
385 // so it updates the attributes
386 $newObjectInstance->rename( $name );
387
388 return $newObjectInstance->attribute( 'id' );
389 }
390
391 function storeObjectAttribute( $contentObjectAttribute )
392 {
393 $content = $contentObjectAttribute->content();
394 if ( isset( $content['new_object'] ) )
395 {
396 $newID = $this->createNewObject( $contentObjectAttribute, $content['new_object'] );
397 // if this is a single element selection mode (radio or dropdown), then the newly created item is the only one selected
398 if ( $newID )
399 {
400 if ( isset( $content['singleselect'] ) )
401 $content['relation_list'] = array();
402 $content['relation_list'][] = $this->appendObject( $newID, 0, $contentObjectAttribute );
403 }
404 unset( $content['new_object'] );
405 $contentObjectAttribute->setContent( $content );
406 }
407
408 $contentClassAttributeID = $contentObjectAttribute->ContentClassAttributeID;
409 $contentObjectID = $contentObjectAttribute->ContentObjectID;
410 $contentObjectVersion = $contentObjectAttribute->Version;
411 $languageCode = $contentObjectAttribute->attribute( 'language_code' );
412
414 $contentObject = $contentObjectAttribute->object();
415
416 if ( $contentObjectAttribute->ID !== null )
417 {
418 // cleanup previous relations
419 $contentObject->removeContentObjectRelation( false, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
420
421 // if translatable, we need to re-add the relations for other languages of (previously) published version.
422 $publishedVersionNo = $contentObject->publishedVersion();
423 if ( $contentObjectAttribute->contentClassAttributeCanTranslate() && $publishedVersionNo > 0 )
424 {
425 $existingRelations = array();
426
427 // get published translations of this attribute
428 $pubAttribute = eZContentObjectAttribute::fetch($contentObjectAttribute->ID, $publishedVersionNo);
429 if ( $pubAttribute )
430 {
431 foreach( $pubAttribute->fetchAttributeTranslations() as $attributeTranslation )
432 {
433 // skip if language is the one being saved
434 if ( $attributeTranslation->LanguageCode === $languageCode )
435 continue;
436
437 $relationList = $attributeTranslation->value();
438 foreach ($relationList['relation_list'] as $relationItem) {
439 $existingRelations[] = $relationItem['contentobject_id'];
440 }
441 }
442 }
443
444 // fetch existing attribute translations for current editing version
445 foreach( $contentObjectAttribute->fetchAttributeTranslations() as $attributeTranslation )
446 {
447 if ( $attributeTranslation->LanguageCode === $languageCode )
448 continue;
449
450 $relationList = $attributeTranslation->value();
451 foreach ($relationList['relation_list'] as $relationItem) {
452 $existingRelations[] = $relationItem['contentobject_id'];
453 }
454 }
455
456 foreach( array_unique($existingRelations) as $existingObjectId )
457 {
458 $contentObject->addContentObjectRelation( $existingObjectId, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
459 }
460 }
461 }
462
463 foreach( $content['relation_list'] as $relationItem )
464 {
465 // Installing content object, postUnserialize is not called yet,
466 // so object's ID is unknown.
467 if ( !$relationItem['contentobject_id'] || !isset( $relationItem['contentobject_id'] ) )
468 continue;
469
470 $subObjectID = $relationItem['contentobject_id'];
471 $subObjectVersion = $relationItem['contentobject_version'];
472
473 eZContentObject::fetch( $contentObjectID )->addContentObjectRelation( $subObjectID, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE );
474
475 if ( $relationItem['is_modified'] && isset( $content['temp'][$subObjectID]['object' ] ) )
476 {
477 // handling sub-objects
478 $object = $content['temp'][$subObjectID]['object'];
479 if ( $object )
480 {
481 $attributes = $content['temp'][$subObjectID]['attributes'];
482 $attributeInputMap = $content['temp'][$subObjectID]['attribute-input-map'];
483 $object->storeInput( $attributes,
484 $attributeInputMap );
485 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID );
486 if ( $version )
487 {
488 $version->setAttribute( 'modified', time() );
489 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT );
490 $version->store();
491 }
492
493 $object->store();
494 }
495 }
496 }
497 return $this->storeObjectAttributeContent( $contentObjectAttribute, $content );
498 }
499
500 function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes )
501 {
502 $content = $contentObjectAttribute->content();
503 foreach( $content['relation_list'] as $key => $relationItem )
504 {
505 if ( $relationItem['is_modified'] )
506 {
507 $subObjectID = $relationItem['contentobject_id'];
508 $subObjectVersion = $relationItem['contentobject_version'];
509 $object = eZContentObject::fetch( $subObjectID );
510
511 $time = time();
512
513 $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID );
514 $version->setAttribute( 'modified', $time );
515 $version->store();
516
517 if ( $relationItem['parent_node_id'] > 0 )
518 {
519 // action 1: edit a normal object
520 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $relationItem['parent_node_id'], false ) )
521 {
522 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ),
523 'contentobject_version' => $object->attribute( 'current_version' ),
524 'parent_node' => $relationItem['parent_node_id'],
525 'sort_field' => eZContentObjectTreeNode::SORT_FIELD_PUBLISHED,
526 'sort_order' => eZContentObjectTreeNode::SORT_ORDER_DESC,
527 'is_main' => 1 ) );
528 $nodeAssignment->store();
529 }
530 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $object->attribute( 'id' ),
531 'version' => $subObjectVersion ) );
532 $objectNodeID = $object->attribute( 'main_node_id' );
533 $content['relation_list'][$key]['node_id'] = $objectNodeID;
534 }
535 else
536 {
537 // action 2: edit a nodeless object (or creating a new node
538 // Make the previous version archived
539 $currentVersion = $object->currentVersion();
540 $currentVersion->setAttribute( 'status', eZContentObjectVersion::STATUS_ARCHIVED );
541 $currentVersion->setAttribute( 'modified', $time );
542 $currentVersion->store();
543
544 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_PUBLISHED );
545 $version->store();
546
547 $object->setAttribute( 'status', eZContentObject::STATUS_PUBLISHED );
548 if ( !$object->attribute( 'published' ) )
549 $object->setAttribute( 'published', $time );
550 $object->setAttribute( 'modified', $time );
551 $object->setAttribute( 'current_version', $subObjectVersion );
552 $class = $object->contentClass();
553 $objectName = $class->contentObjectName( $object, $version->attribute( 'version' ) );
554 $object->setName( $objectName, $version->attribute( 'version' ) );
555 $object->store();
556
557 if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $contentObject->attribute( 'main_node_id' ), false ) )
558 {
559 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ),
560 'contentobject_version' => $object->attribute( 'current_version' ),
561 'parent_node' => $contentObject->attribute( 'main_node_id' ),
562 'sort_field' => eZContentObjectTreeNode::SORT_FIELD_PUBLISHED,
563 'sort_order' => eZContentObjectTreeNode::SORT_ORDER_DESC,
564 'is_main' => 1 ) );
565 $nodeAssignment->store();
566 }
567 }
568 $content['relation_list'][$key]['is_modified'] = false;
569 }
570 }
571 $this->storeObjectAttributeContent( $contentObjectAttribute, $content );
572 $contentObjectAttribute->setContent( $content );
573 $contentObjectAttribute->store();
574 }
575
576 function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
577 {
578
579 static $copiedRelatedAccordance;
580 if ( !isset( $copiedRelatedAccordance ) )
581 $copiedRelatedAccordance = array();
582
583 if ( $currentVersion != false )
584 {
585 $dataText = $originalContentObjectAttribute->attribute( 'data_text' );
586 $contentObjectAttribute->setAttribute( 'data_text', $dataText );
587 $contentObjectID = $contentObjectAttribute->attribute( 'contentobject_id' );
588 $originalContentObjectID = $originalContentObjectAttribute->attribute( 'contentobject_id' );
589
590 if ( $contentObjectID != $originalContentObjectID )
591 {
592 $classContent = $this->defaultClassAttributeContent();
593 if ( !$classContent['default_placement'] )
594 {
595 $content = $originalContentObjectAttribute->content();
596 $contentModified = false;
597
598 foreach ( $content['relation_list'] as $key => $relationItem )
599 {
600 // create related object copies only if they are subobjects
601 $object = eZContentObject::fetch( $relationItem['contentobject_id'] );
602 if ( !$object instanceof eZContentObject )
603 {
604 unset( $content['relation_list'][$key] );
605 $contentModified = true;
606 continue;
607 }
608
609 $mainNode = $object->attribute( 'main_node' );
610 if ( $mainNode instanceof eZContentObjectTreeNode )
611 {
612 $node = ( is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] ) ?
613 eZContentObjectTreeNode::fetch( $relationItem['node_id'] ) : null;
614
615 if ( !$node or $node->attribute( 'contentobject_id' ) != $relationItem['contentobject_id'] )
616 {
617 $content['relation_list'][$key]['node_id'] = $mainNode->attribute( 'node_id' );
618 $node = $mainNode;
619 $contentModified = true;
620 }
621
622 if ( $node instanceof eZContentObjectTreeNode )
623 $parentNodeID = $node->attribute( 'parent_node_id' );
624 else
625 $parentNodeID = -1;
626
627 if ( $relationItem['parent_node_id'] != $parentNodeID )
628 {
629 $content['relation_list'][$key]['parent_node_id'] = $parentNodeID;
630 $contentModified = true;
631 }
632 }
633 else if ( $object->attribute( 'status' ) != eZContentObject::STATUS_ARCHIVED )
634 {
635 if ( !isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) )
636 $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] = array();
637
638 if ( isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) and
639 isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] ) )
640 {
641 $newObjectID = $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ][ 'to' ];
642 }
643 else
644 {
645 $newObject = $object->copy( true );
646 $newObjectID = $newObject->attribute( 'id' );
647 $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] = array( 'to' => $newObjectID,
648 'from' => $originalContentObjectID );
649 }
650 $content['relation_list'][$key]['contentobject_id'] = $newObjectID;
651 $contentModified = true;
652 }
653 }
654
655 if ( $contentModified )
656 {
657 $contentObjectAttribute->setContent( $content );
658 $contentObjectAttribute->store();
659 }
660 }
661 }
662 }
663 }
664
665 function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
666 {
667 return eZInputValidator::STATE_ACCEPTED;
668 }
669
670 function fixupClassAttributeHTTPInput( $http, $base, $classAttribute )
671 {
672 }
673
674 function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
675 {
676 $content = $classAttribute->content();
677 $postVariable = 'ContentClass_ezobjectrelationlist_class_list_' . $classAttribute->attribute( 'id' );
678 if ( $http->hasPostVariable( $postVariable ) )
679 {
680 $constrainedList = $http->postVariable( $postVariable );
681 $constrainedClassList = array();
682 foreach ( $constrainedList as $constraint )
683 {
684 if ( trim( $constraint ) != '' )
685 $constrainedClassList[] = $constraint;
686 }
687 $content['class_constraint_list'] = $constrainedClassList;
688 }
689 $typeVariable = 'ContentClass_ezobjectrelationlist_type_' . $classAttribute->attribute( 'id' );
690 if ( $http->hasPostVariable( $typeVariable ) )
691 {
692 $type = $http->postVariable( $typeVariable );
693 $content['type'] = $type;
694 }
695 $selectionTypeVariable = 'ContentClass_ezobjectrelationlist_selection_type_' . $classAttribute->attribute( 'id' );
696 if ( $http->hasPostVariable( $selectionTypeVariable ) )
697 {
698 $selectionType = $http->postVariable( $selectionTypeVariable );
699 $content['selection_type'] = $selectionType;
700 }
701 $objectClassVariable = 'ContentClass_ezobjectrelation_object_class_' . $classAttribute->attribute( 'id' );
702 if ( $http->hasPostVariable( $objectClassVariable ) )
703 {
704 $content['object_class'] = $http->postVariable( $objectClassVariable );
705 }
706
707 $classAttribute->setContent( $content );
708 $classAttribute->store();
709 return true;
710 }
711
712 function initializeClassAttribute( $classAttribute )
713 {
714 $xmlText = $classAttribute->attribute( 'data_text5' );
715 if ( trim( $xmlText ) == '' )
716 {
717 $content = $this->defaultClassAttributeContent();
718 return $this->storeClassAttributeContent( $classAttribute, $content );
719 }
720 }
721
722 function preStoreClassAttribute( $classAttribute, $version )
723 {
724 $content = $classAttribute->content();
725 return $this->storeClassAttributeContent( $classAttribute, $content );
726 }
727
728 function storeClassAttributeContent( $classAttribute, $content )
729 {
730 if ( is_array( $content ) )
731 {
732 $doc = $this->createClassDOMDocument( $content );
733 $this->storeClassDOMDocument( $doc, $classAttribute );
734 return true;
735 }
736 return false;
737 }
738
739 function storeObjectAttributeContent( $objectAttribute, $content )
740 {
741 if ( is_array( $content ) )
742 {
743 $doc = $this->createObjectDOMDocument( $content );
744 $this->storeObjectDOMDocument( $doc, $objectAttribute );
745 return true;
746 }
747 return false;
748 }
749
750 static function storeClassDOMDocument( $doc, $classAttribute )
751 {
752 $docText = self::domString( $doc );
753 $classAttribute->setAttribute( 'data_text5', $docText );
754 }
755
756 static function storeObjectDOMDocument( $doc, $objectAttribute )
757 {
758 $docText = self::domString( $doc );
759 $objectAttribute->setAttribute( 'data_text', $docText );
760 }
761
768 static function domString( $domDocument )
769 {
770 $ini = eZINI::instance();
771 $xmlCharset = $ini->variable( 'RegionalSettings', 'ContentXMLCharset' );
772 if ( $xmlCharset == 'enabled' )
773 {
774 $charset = eZTextCodec::internalCharset();
775 }
776 else if ( $xmlCharset == 'disabled' )
777 $charset = true;
778 else
779 $charset = $xmlCharset;
780 if ( $charset !== true )
781 {
782 $charset = eZCharsetInfo::realCharsetCode( $charset );
783 }
784 $domString = $domDocument->saveXML();
785 return $domString;
786 }
787
788 static function createClassDOMDocument( $content )
789 {
790 $doc = new DOMDocument( '1.0', 'utf-8' );
791 $root = $doc->createElement( 'related-objects' );
792 $constraints = $doc->createElement( 'constraints' );
793 foreach ( $content['class_constraint_list'] as $constraintClassIdentifier )
794 {
795 unset( $constraintElement );
796 $constraintElement = $doc->createElement( 'allowed-class' );
797 $constraintElement->setAttribute( 'contentclass-identifier', $constraintClassIdentifier );
798 $constraints->appendChild( $constraintElement );
799 }
800 $root->appendChild( $constraints );
801 $constraintType = $doc->createElement( 'type' );
802 $constraintType->setAttribute( 'value', $content['type'] );
803 $root->appendChild( $constraintType );
804 $selectionType = $doc->createElement( 'selection_type' );
805 $selectionType->setAttribute( 'value', $content['selection_type'] );
806 $root->appendChild( $selectionType );
807 $objectClass = $doc->createElement( 'object_class' );
808 $objectClass->setAttribute( 'value', $content['object_class'] );
809 $root->appendChild( $objectClass );
810
811 $placementNode = $doc->createElement( 'contentobject-placement' );
812 if ( $content['default_placement'] )
813 {
814 $placementNode->setAttribute( 'node-id', $content['default_placement']['node_id'] );
815 }
816 $root->appendChild( $placementNode );
817 $doc->appendChild( $root );
818 return $doc;
819 }
820
821 static function createObjectDOMDocument( $content )
822 {
823 $doc = new DOMDocument( '1.0', 'utf-8' );
824 $root = $doc->createElement( 'related-objects' );
825 $relationList = $doc->createElement( 'relation-list' );
826 $attributeDefinitions = self::contentObjectArrayXMLMap();
827
828 foreach ( $content['relation_list'] as $relationItem )
829 {
830 unset( $relationElement );
831 $relationElement = $doc->createElement( 'relation-item' );
832
833 foreach ( $attributeDefinitions as $attributeXMLName => $attributeKey )
834 {
835 if ( isset( $relationItem[$attributeKey] ) && $relationItem[$attributeKey] !== false )
836 {
837 $value = $relationItem[$attributeKey];
838 $relationElement->setAttribute( $attributeXMLName, $value );
839 }
840 }
841
842 $relationList->appendChild( $relationElement );
843 }
844 $root->appendChild( $relationList );
845 $doc->appendChild( $root );
846 return $doc;
847 }
848
861 static function contentObjectArrayXMLMap()
862 {
863 return array( 'identifier' => 'identifier',
864 'priority' => 'priority',
865 'in-trash' => 'in_trash',
866 'contentobject-id' => 'contentobject_id',
867 'is-modified' => 'is_modified',
868
869 // The following attributes should in retrospective have been prefixed with "original"
870 // If you are interested in current published meta data of relation, fetch content object.
871 'contentobject-version' => 'contentobject_version',
872 'node-id' => 'node_id',
873 'parent-node-id' => 'parent_node_id',
874 'contentclass-id' => 'contentclass_id',
875 'contentclass-identifier' => 'contentclass_identifier',
876 'contentobject-remote-id' => 'contentobject_remote_id' );
877 }
878
879 function deleteStoredObjectAttribute( $objectAttribute, $version = null )
880 {
881 $content = $objectAttribute->content();
882 if ( is_array( $content ) and
883 is_array( $content['relation_list'] ) )
884 {
885 $db = eZDB::instance();
886 $db->begin();
887 foreach ( $content['relation_list'] as $deletionItem )
888 {
889 $this->removeRelationObject( $objectAttribute, $deletionItem );
890 }
891 $db->commit();
892 }
893 }
894
895 function deleteNotVersionedStoredClassAttribute( eZContentClassAttribute $classAttribute )
896 {
897 eZContentObjectAttribute::removeRelationsByContentClassAttributeId( $classAttribute->attribute( 'id' ) );
898 }
899
900 function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
901 {
902 $contentobjectID = false;
903 if ( eZDataType::fetchActionValue( $action, 'new_class', $classID ) or
904 $action == 'new_class' )
905 {
906 if ( $action == 'new_class' )
907 {
908 $base = $parameters['base_name'];
909 $classVariableName = $base . '_new_class';
910 if ( $http->hasPostVariable( $classVariableName ) )
911 {
912 $classVariable = $http->postVariable( $classVariableName );
913 $classID = $classVariable[$contentObjectAttribute->attribute( 'id' )];
914 $class = eZContentClass::fetch( $classID );
915 }
916 else
917 return false;
918 }
919 else
920 $class = eZContentClass::fetch( $classID );
921 if ( $class )
922 {
923 $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
924 $class_content = $classAttribute->content();
925 $content = $contentObjectAttribute->content();
926 $priority = 0;
927 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
928 {
929 if ( $content['relation_list'][$i]['priority'] > $priority )
930 $priority = $content['relation_list'][$i]['priority'];
931 }
932
933 $base = $parameters['base_name'];
934 $nodePlacement = false;
935 $nodePlacementName = $base . '_object_initial_node_placement';
936 if ( $http->hasPostVariable( $nodePlacementName ) )
937 {
938 $nodePlacementMap = $http->postVariable( $nodePlacementName );
939 if ( isset( $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )] ) )
940 $nodePlacement = $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )];
941 }
942 $relationItem = $this->createInstance( $class,
943 $priority + 1,
944 $contentObjectAttribute,
945 $nodePlacement );
946 if ( $class_content['default_placement'] )
947 {
948 $relationItem['parent_node_id'] = $class_content['default_placement']['node_id'];
949 }
950
951 $content['relation_list'][] = $relationItem;
952
953 $hasAttributeInput = false;
954 $attributeInputVariable = $base . '_has_attribute_input';
955 if ( $http->hasPostVariable( $attributeInputVariable ) )
956 {
957 $attributeInputMap = $http->postVariable( $attributeInputVariable );
958 if ( isset( $attributeInputMap[$contentObjectAttribute->attribute( 'id' )] ) )
959 $hasAttributeInput = $attributeInputMap[$contentObjectAttribute->attribute( 'id' )];
960 }
961
962 if ( $hasAttributeInput )
963 {
964 $object = $relationItem['object'];
965 $attributes = $object->contentObjectAttributes();
966 foreach ( $attributes as $attribute )
967 {
968 $attributeBase = $base . '_ezorl_init_class_' . $object->attribute( 'contentclass_id' ) . '_attr_' . $attribute->attribute( 'contentclassattribute_id' );
969 $oldAttributeID = $attribute->attribute( 'id' );
970 $attribute->setAttribute( 'id', false );
971 if ( $attribute->fetchInput( $http, $attributeBase ) )
972 {
973 $attribute->setAttribute( 'id', $oldAttributeID );
974 $attribute->store();
975 }
976 }
977 }
978
979 $contentObjectAttribute->setContent( $content );
980 $contentObjectAttribute->store();
981 }
982 else
983
984 eZDebug::writeError( "Unknown class ID $classID, cannot instantiate object", __METHOD__ );
985 }
986 else if ( eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) or
987 $action == 'edit_objects' or
988 $action == 'remove_objects' )
989 {
990 $base = $parameters['base_name'];
991 $selectionBase = $base . '_selection';
992 $selections = array();
993 $http = eZHTTPTool::instance();
994 if ( $http->hasPostVariable( $selectionBase ) )
995 {
996 $selectionMap = $http->postVariable( $selectionBase );
997 $selections = $selectionMap[$contentObjectAttribute->attribute( 'id' )];
998 }
999 if ( $contentobjectID !== false )
1000 $selections[] = $contentobjectID;
1001 if ( $action == 'edit_objects' or
1002 eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) )
1003 {
1004 $content = $contentObjectAttribute->content();
1005 foreach ( $content['relation_list'] as $key => $relationItem )
1006 {
1007 if ( !$relationItem['is_modified'] and
1008 in_array( $relationItem['contentobject_id'], $selections ) )
1009 {
1010 $object = eZContentObject::fetch( $relationItem['contentobject_id'] );
1011 if ( $object->attribute( 'can_edit' ) )
1012 {
1013 $content['relation_list'][$key]['is_modified'] = true;
1014
1015 $translationSourceBase = $base . '_translation_source_' .
1016 $contentObjectAttribute->attribute( 'id' ) . '_' .
1017 $relationItem['contentobject_id'];
1018 $languageFrom = false;
1019 if( $http->hasPostVariable( $translationSourceBase ) &&
1020 $http->postVariable( $translationSourceBase ) !== '' )
1021 {
1022 $languageFrom = $http->postVariable( $translationSourceBase );
1023 }
1024
1025 $version = $object->createNewVersionIn( $contentObjectAttribute->attribute( 'language_code' ), $languageFrom );
1026 $content['relation_list'][$key]['contentobject_version'] = $version->attribute( 'version' );
1027 }
1028 }
1029 }
1030 $contentObjectAttribute->setContent( $content );
1031 $contentObjectAttribute->store();
1032 }
1033 else if ( $action == 'remove_objects' )
1034 {
1035 $content = $contentObjectAttribute->content();
1036 $relationList = $content['relation_list'];
1037 $newRelationList = array();
1038 foreach( $relationList as $relationItem )
1039 {
1040 if ( in_array( $relationItem['contentobject_id'], $selections ) )
1041 {
1042 $this->removeRelationObject( $contentObjectAttribute, $relationItem );
1043 }
1044 else
1045 {
1046 $newRelationList[] = $relationItem;
1047 }
1048 }
1049 $content['relation_list'] = $newRelationList;
1050 $contentObjectAttribute->setContent( $content );
1051 $contentObjectAttribute->store();
1052 }
1053 }
1054 else if ( $action == 'browse_objects' )
1055 {
1056 $module = $parameters['module'];
1057 $redirectionURI = $parameters['current-redirection-uri'];
1058
1059 $ini = eZINI::instance( 'content.ini' );
1060 $browseType = 'AddRelatedObjectListToDataType';
1061 $browseTypeINIVariable = $ini->variable( 'ObjectRelationDataTypeSettings', 'ClassAttributeStartNode' );
1062 foreach ( $browseTypeINIVariable as $value )
1063 {
1064 list( $classAttributeID, $type ) = explode( ';',$value );
1065 if ( is_numeric( $classAttributeID ) and
1066 $classAttributeID == $contentObjectAttribute->attribute( 'contentclassattribute_id' ) and
1067 strlen( $type ) > 0 )
1068 {
1069 $browseType = $type;
1070 break;
1071 }
1072 }
1073
1074 // Fetch the list of "allowed" classes .
1075 // A user can select objects of only those allowed classes when browsing.
1076 $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
1077 $classContent = $classAttribute->content();
1078 if ( isset( $classContent['class_constraint_list'] ) )
1079 {
1080 $classConstraintList = $classContent['class_constraint_list'];
1081 }
1082 else
1083 {
1084 $classConstraintList = array();
1085 }
1086
1087 $browseParameters = array( 'action_name' => 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ),
1088 'type' => $browseType,
1089 'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $contentObjectAttribute->attribute( 'id' ) . '_set_object_relation_list]',
1090 'value' => $contentObjectAttribute->attribute( 'id' ) ),
1091 'persistent_data' => array( 'HasObjectInput' => 0 ),
1092 'from_page' => $redirectionURI );
1093 $base = $parameters['base_name'];
1094 $nodePlacementName = $base . '_browse_for_object_start_node';
1095 if ( $http->hasPostVariable( $nodePlacementName ) )
1096 {
1097 $nodePlacement = $http->postVariable( $nodePlacementName );
1098 if ( isset( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ) )
1099 $browseParameters['start_node'] = eZContentBrowse::nodeAliasID( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] );
1100 }
1101 if ( count($classConstraintList) > 0 )
1102 $browseParameters['class_array'] = $classConstraintList;
1103
1104 eZContentBrowse::browse( $browseParameters,
1105 $module );
1106 }
1107 else if ( $action == 'set_object_relation_list' )
1108 {
1109 if ( !$http->hasPostVariable( 'BrowseCancelButton' ) )
1110 {
1111 $selectedObjectIDArray = $http->postVariable( "SelectedObjectIDArray" );
1112 $content = $contentObjectAttribute->content();
1113 $priority = 0;
1114 for ( $i = 0; $i < count( $content['relation_list'] ); ++$i )
1115 {
1116 if ( $content['relation_list'][$i]['priority'] > $priority )
1117 $priority = $content['relation_list'][$i]['priority'];
1118 }
1119 if( $selectedObjectIDArray !== null )
1120 {
1121 foreach ( $selectedObjectIDArray as $objectID )
1122 {
1123 // Check if the given object ID has a numeric value, if not go to the next object.
1124 if ( !is_numeric( $objectID ) )
1125 {
1126 eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", __METHOD__ );
1127
1128 continue;
1129 }
1130
1131 /* Here we check if current object is already in the related objects list.
1132 * If so, we don't add it again.
1133 * FIXME: Stupid linear search. Maybe there's some better way?
1134 */
1135 $found = false;
1136 foreach ( $content['relation_list'] as $i )
1137 {
1138 if ( $i['contentobject_id'] == $objectID )
1139 {
1140 $found = true;
1141 break;
1142 }
1143 }
1144 if ( $found )
1145 continue;
1146
1147 ++$priority;
1148 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
1149 $contentObjectAttribute->setContent( $content );
1150 $contentObjectAttribute->store();
1151 }
1152 }
1153 }
1154 }
1155 else
1156 {
1157 eZDebug::writeError( "Unknown custom HTTP action: " . $action,
1158 'eZObjectRelationListType' );
1159 }
1160 }
1161
1162 function handleCustomObjectHTTPActions( $http, $attributeDataBaseName,
1163 $customActionAttributeArray, $customActionParameters )
1164 {
1165 $contentObjectAttribute = $customActionParameters['contentobject_attribute'];
1166 $content = $contentObjectAttribute->content();
1167 foreach( $content['relation_list'] as $relationItem )
1168 {
1169 if ( $relationItem['is_modified'] )
1170 {
1171 $subObjectID = $relationItem['contentobject_id'];
1172 $subObjectVersion = $relationItem['contentobject_version'];
1173
1174 $attributeBase = $attributeDataBaseName . '_ezorl_edit_object_' . $subObjectID;
1175 if ( eZContentObject::recursionProtect( $subObjectID ) )
1176 {
1177 if ( isset ( $content['temp'] ) )
1178 $object = $content['temp'][$subObjectID]['object'];
1179 else
1180 $object = eZContentObject::fetch( $subObjectID );
1181 if ( $object )
1182 $object->handleAllCustomHTTPActions( $attributeBase,
1183 $customActionAttributeArray,
1184 $customActionParameters,
1185 $subObjectVersion );
1186 }
1187 }
1188 }
1189 }
1190
1195 static function isItemPublished( $relationItem )
1196 {
1197 return is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] > 0;
1198 }
1199
1205 static function removeRelationObject( $contentObjectAttribute, $deletionItem )
1206 {
1207 if ( self::isItemPublished( $deletionItem ) )
1208 {
1209 return;
1210 }
1211
1212 $hostObject = $contentObjectAttribute->attribute( 'object' );
1213 $hostObjectID = $hostObject->attribute( 'id' );
1214
1215 // Do not try removing the object if present in trash
1216 // Only objects being really orphaned (not even being in trash) should be removed by this method.
1217 // See issue #019457
1218 if (
1219 (int)eZPersistentObject::count(
1220 eZContentObjectTrashNode::definition(),
1221 array( "contentobject_id" => $hostObjectID )
1222 ) > 0
1223 )
1224 {
1225 return;
1226 }
1227
1228 $hostObjectVersions = $hostObject->versions();
1229 $isDeletionAllowed = true;
1230
1231 // check if the relation item to be deleted is unique in the domain of all host-object versions
1232 foreach ( $hostObjectVersions as $version )
1233 {
1234 if ( $isDeletionAllowed and
1235 $version->attribute( 'version' ) != $contentObjectAttribute->attribute( 'version' ) )
1236 {
1237 $relationAttribute = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(),
1238 null,
1239 array( 'version' => $version->attribute( 'version' ),
1240 'contentobject_id' => $hostObjectID,
1241 'contentclassattribute_id' => $contentObjectAttribute->attribute( 'contentclassattribute_id' ) ) );
1242
1243 if ( count( $relationAttribute ) > 0 )
1244 {
1245 $relationContent = $relationAttribute[0]->content();
1246 if ( is_array( $relationContent ) and
1247 is_array( $relationContent['relation_list'] ) )
1248 {
1249 foreach( $relationContent['relation_list'] as $relationItem )
1250 {
1251 if ( $deletionItem['contentobject_id'] == $relationItem['contentobject_id'] &&
1252 $deletionItem['contentobject_version'] == $relationItem['contentobject_version'] )
1253 {
1254 $isDeletionAllowed = false;
1255 break 2;
1256 }
1257 }
1258 }
1259 }
1260 }
1261 }
1262
1263 if ( $isDeletionAllowed )
1264 {
1265 $subObjectVersion = eZContentObjectVersion::fetchVersion( $deletionItem['contentobject_version'],
1266 $deletionItem['contentobject_id'] );
1267 if ( $subObjectVersion instanceof eZContentObjectVersion )
1268 {
1269 $subObjectVersion->removeThis();
1270 }
1271 else
1272 {
1273 eZDebug::writeError( 'Cleanup of subobject-version failed. Could not fetch object from relation list.\n' .
1274 'Requested subobject id: ' . $deletionItem['contentobject_id'] . '\n' .
1275 'Requested Subobject version: ' . $deletionItem['contentobject_version'],
1276 __METHOD__ );
1277 }
1278 }
1279 }
1280
1281
1282 function createInstance( $class, $priority, $contentObjectAttribute, $nodePlacement = false )
1283 {
1284 $currentObject = $contentObjectAttribute->attribute( 'object' );
1285 $sectionID = $currentObject->attribute( 'section_id' );
1286 $object = $class->instantiate( false, $sectionID, false, $contentObjectAttribute->attribute( 'language_code' ) );
1287 if ( !is_numeric( $nodePlacement ) or $nodePlacement <= 0 )
1288 $nodePlacement = false;
1289 $object->sync();
1290 $relationItem = array( 'identifier' => false,
1291 'priority' => $priority,
1292 'in_trash' => false,
1293 'contentobject_id' => $object->attribute( 'id' ),
1294 'contentobject_version' => $object->attribute( 'current_version' ),
1295 'contentobject_remote_id' => $object->attribute( 'remote_id' ),
1296 'node_id' => false,
1297 'parent_node_id' => $nodePlacement,
1298 'contentclass_id' => $class->attribute( 'id' ),
1299 'contentclass_identifier' => $class->attribute( 'identifier' ),
1300 'is_modified' => true );
1301 $relationItem['object'] = $object;
1302 return $relationItem;
1303 }
1304
1313 public function appendObject( $objectID, $priority, $contentObjectAttribute )
1314 {
1315 $object = eZContentObject::fetch( $objectID );
1316
1317 if ( null === $object )
1318 {
1319 return;
1320 }
1321
1322 $class = $object->attribute( 'content_class' );
1323 $sectionID = $object->attribute( 'section_id' );
1324 $relationItem = array( 'identifier' => false,
1325 'priority' => $priority,
1326 'in_trash' => false,
1327 'contentobject_id' => $object->attribute( 'id' ),
1328 'contentobject_version' => $object->attribute( 'current_version' ),
1329 'contentobject_remote_id' => $object->attribute( 'remote_id' ),
1330 'node_id' => $object->attribute( 'main_node_id' ),
1331 'parent_node_id' => $object->attribute( 'main_parent_node_id' ),
1332 'contentclass_id' => $class->attribute( 'id' ),
1333 'contentclass_identifier' => $class->attribute( 'identifier' ),
1334 'is_modified' => false );
1335 $relationItem['object'] = $object;
1336 return $relationItem;
1337 }
1338
1339
1340 function fixRelatedObjectItem ( $contentObjectAttribute, $objectID, $mode )
1341 {
1342 switch ( $mode )
1343 {
1344 case 'move':
1345 {
1346 $this->fixRelationsMove( $objectID, $contentObjectAttribute );
1347 } break;
1348
1349 case 'trash':
1350 {
1351 $this->fixRelationsTrash( $objectID, $contentObjectAttribute );
1352 } break;
1353
1354 case 'restore':
1355 {
1356 $this->fixRelationsRestore( $objectID, $contentObjectAttribute );
1357 } break;
1358
1359 case 'remove':
1360 {
1361 $this->fixRelationsRemove( $objectID, $contentObjectAttribute );
1362 } break;
1363
1364 case 'swap':
1365 {
1366 $this->fixRelationsSwap( $objectID, $contentObjectAttribute );
1367 } break;
1368
1369 default:
1370 {
1371 eZDebug::writeWarning( 'Unknown mode: ' . $mode, __METHOD__ );
1372 } break;
1373 }
1374 }
1375
1376 function fixRelationsMove ( $objectID, $contentObjectAttribute )
1377 {
1378 $this->fixRelationsSwap( $objectID, $contentObjectAttribute );
1379 }
1380
1381 function fixRelationsTrash ( $objectID, $contentObjectAttribute )
1382 {
1383 $content = $contentObjectAttribute->attribute( 'content' );
1384 foreach ( array_keys( $content['relation_list'] ) as $key )
1385 {
1386 if ( $content['relation_list'][$key]['contentobject_id'] == $objectID )
1387 {
1388 $content['relation_list'][$key]['in_trash'] = true;
1389 $content['relation_list'][$key]['node_id'] = null;
1390 $content['relation_list'][$key]['parent_node_id']= null;
1391 }
1392 }
1393 $this->storeObjectAttributeContent( $contentObjectAttribute, $content );
1394 $contentObjectAttribute->setContent( $content );
1395 $contentObjectAttribute->storeData();
1396 }
1397
1398 function fixRelationsRestore ( $objectID, $contentObjectAttribute )
1399 {
1400 $content = $contentObjectAttribute->content();
1401
1402 foreach ( array_keys( $content['relation_list'] ) as $key )
1403 {
1404 if ( $content['relation_list'][$key]['contentobject_id'] == $objectID )
1405 {
1406 $priority = $content['relation_list'][$key]['priority'];
1407 $content['relation_list'][$key] = $this->appendObject( $objectID, $priority, $contentObjectAttribute);
1408 }
1409 }
1410 $this->storeObjectAttributeContent( $contentObjectAttribute, $content );
1411 $contentObjectAttribute->setContent( $content );
1412 $contentObjectAttribute->storeData();
1413 }
1414
1415 function fixRelationsRemove ( $objectID, $contentObjectAttribute )
1416 {
1417 $this->removeRelatedObjectItem( $contentObjectAttribute, $objectID );
1418 $contentObjectAttribute->storeData();
1419 }
1420
1421 function fixRelationsSwap ( $objectID, $contentObjectAttribute )
1422 {
1423 $content =& $contentObjectAttribute->content();
1424
1425 foreach ( array_keys( $content['relation_list'] ) as $key )
1426 {
1427 $relatedObject =& $content['relation_list'][$key];
1428 if ( $relatedObject['contentobject_id'] == $objectID )
1429 {
1430 $priority = $content['relation_list'][$key]['priority'];
1431 $content['relation_list'][$key] = $this->appendObject($objectID, $priority, $contentObjectAttribute );
1432 }
1433 }
1434
1435 $this->storeObjectAttributeContent( $contentObjectAttribute, $content );
1436 $contentObjectAttribute->setContent( $content );
1437 $contentObjectAttribute->storeData();
1438 }
1439
1440
1444 function objectAttributeContent( $contentObjectAttribute )
1445 {
1446 $xmlText = $contentObjectAttribute->attribute( 'data_text' );
1447 if ( trim( $xmlText ) == '' )
1448 {
1449 $objectAttributeContent = $this->defaultObjectAttributeContent();
1450 return $objectAttributeContent;
1451 }
1452 $doc = $this->parseXML( $xmlText );
1453 $content = $this->createObjectContentStructure( $doc );
1454
1455 return $content;
1456 }
1457
1458 function classAttributeContent( $classAttribute )
1459 {
1460 $xmlText = $classAttribute->attribute( 'data_text5' );
1461 if ( trim( $xmlText ) == '' )
1462 {
1463 return $this->defaultClassAttributeContent();
1464 }
1465 $doc = $this->parseXML( $xmlText );
1466 return $this->createClassContentStructure( $doc );
1467 }
1468
1469 static function parseXML( $xmlText )
1470 {
1471 $dom = new DOMDocument( '1.0', 'utf-8' );
1472 $dom->loadXML( $xmlText );
1473 return $dom;
1474 }
1475
1476 function defaultClassAttributeContent()
1477 {
1478 return array( 'object_class' => '',
1479 'selection_type' => 0,
1480 'type' => 0,
1481 'class_constraint_list' => array(),
1482 'default_placement' => false );
1483 }
1484
1485 function defaultObjectAttributeContent()
1486 {
1487 return array( 'relation_list' => array() );
1488 }
1489
1490 function createClassContentStructure( $doc )
1491 {
1492 $content = $this->defaultClassAttributeContent();
1493 $root = $doc->documentElement;
1494 if( $root !== null )
1495 {
1496 $objectPlacement = $root->getElementsByTagName( 'contentobject-placement' )->item( 0 );
1497
1498 if ( $objectPlacement and $objectPlacement->hasAttributes() )
1499 {
1500 $nodeID = $objectPlacement->getAttribute( 'node-id' );
1501 $content['default_placement'] = array( 'node_id' => $nodeID );
1502 }
1503 $constraints = $root->getElementsByTagName( 'constraints' )->item( 0 );
1504 if ( $constraints )
1505 {
1506 $allowedClassList = $constraints->getElementsByTagName( 'allowed-class' );
1507 foreach( $allowedClassList as $allowedClass )
1508 {
1509 $content['class_constraint_list'][] = $allowedClass->getAttribute( 'contentclass-identifier' );
1510 }
1511 }
1512 $type = $root->getElementsByTagName( 'type' )->item( 0 );
1513 if ( $type )
1514 {
1515 $content['type'] = $type->getAttribute( 'value' );
1516 }
1517 $selectionType = $root->getElementsByTagName( 'selection_type' )->item( 0 );
1518 if ( $selectionType )
1519 {
1520 $content['selection_type'] = $selectionType->getAttribute( 'value' );
1521 }
1522 $objectClass = $root->getElementsByTagName( 'object_class' )->item( 0 );
1523 if ( $objectClass )
1524 {
1525 $content['object_class'] = $objectClass->getAttribute( 'value' );
1526 }
1527 }
1528 return $content;
1529 }
1530
1531 function createObjectContentStructure( $doc )
1532 {
1533 $content = $this->defaultObjectAttributeContent();
1534 $root = $doc->documentElement;
1535 $relationList = $root->getElementsByTagName( 'relation-list' )->item( 0 );
1536 if ( $relationList )
1537 {
1538 $contentObjectArrayXMLMap = $this->contentObjectArrayXMLMap();
1539 $relationItems = $relationList->getElementsByTagName( 'relation-item' );
1540 foreach ( $relationItems as $relationItem )
1541 {
1542 $hash = array();
1543
1544 foreach ( $contentObjectArrayXMLMap as $attributeXMLName => $attributeKey )
1545 {
1546 $attributeValue = $relationItem->hasAttribute( $attributeXMLName ) ? $relationItem->getAttribute( $attributeXMLName ) : false;
1547 $hash[$attributeKey] = $attributeValue;
1548 }
1549 $content['relation_list'][] = $hash;
1550 }
1551 }
1552 return $content;
1553 }
1554
1555 function customClassAttributeHTTPAction( $http, $action, $classAttribute )
1556 {
1557 switch ( $action )
1558 {
1559 case 'browse_for_placement':
1560 {
1561 $module = $classAttribute->currentModule();
1562 $customActionName = 'CustomActionButton[' . $classAttribute->attribute( 'id' ) . '_browsed_for_placement]';
1563 eZContentBrowse::browse( array( 'action_name' => 'SelectObjectRelationListNode',
1564 'content' => array( 'contentclass_id' => $classAttribute->attribute( 'contentclass_id' ),
1565 'contentclass_attribute_id' => $classAttribute->attribute( 'id' ),
1566 'contentclass_version' => $classAttribute->attribute( 'version' ),
1567 'contentclass_attribute_identifier' => $classAttribute->attribute( 'identifier' ) ),
1568 'persistent_data' => array( $customActionName => '',
1569 'ContentClassHasInput' => false ),
1570 'description_template' => 'design:class/datatype/browse_objectrelationlist_placement.tpl',
1571 'from_page' => $module->currentRedirectionURI() ),
1572 $module );
1573 } break;
1574 case 'browsed_for_placement':
1575 {
1576 $nodeSelection = eZContentBrowse::result( 'SelectObjectRelationListNode' );
1577 if ( $nodeSelection and count( $nodeSelection ) > 0 )
1578 {
1579 $nodeID = $nodeSelection[0];
1580 $content = $classAttribute->content();
1581 $content['default_placement'] = array( 'node_id' => $nodeID );
1582 $classAttribute->setContent( $content );
1583 }
1584 } break;
1585 case 'disable_placement':
1586 {
1587 $content = $classAttribute->content();
1588 $content['default_placement'] = false;
1589 $classAttribute->setContent( $content );
1590 } break;
1591 default:
1592 {
1593 eZDebug::writeError( "Unknown objectrelationlist action '$action'", __METHOD__ );
1594 } break;
1595 }
1596 }
1597
1601 function metaData( $contentObjectAttribute )
1602 {
1603 $metaDataArray = $attributes = array();
1604 $content = $contentObjectAttribute->content();
1605 $language = $contentObjectAttribute->attribute( 'language_code' );
1606 foreach( $content['relation_list'] as $relationItem )
1607 {
1608 $subObjectID = $relationItem['contentobject_id'];
1609 if ( !$subObjectID )
1610 continue;
1611
1612 if ( isset( $content['temp'] ) )
1613 $attributes = $content['temp'][$subObjectID]['attributes'];
1614 else
1615 {
1616 $subObjectVersionNum = $relationItem['contentobject_version'];
1617 $subObject = eZContentObject::fetch( $subObjectID );
1618
1619 if ( !$subObject )
1620 {
1621 continue;
1622 }
1623
1624 // Using last version of object (version inside xml data is the original version)
1625 $subCurrentVersionObject = $subObject->currentVersion();
1626 if( $subCurrentVersionObject instanceof eZContentObjectVersion )
1627 {
1628 $subObjectVersionNum = $subCurrentVersionObject->attribute( 'version' );
1629 }
1630 $attributes = $subObject->contentObjectAttributes( true, $subObjectVersionNum, $language );
1631 }
1632
1633 $attributeMetaDataArray = eZContentObjectAttribute::metaDataArray( $attributes, true );
1634 $metaDataArray = array_merge( $metaDataArray, $attributeMetaDataArray );
1635 }
1636
1637 return $metaDataArray;
1638 }
1639
1644 function toString( $contentObjectAttribute )
1645 {
1646 $objectAttributeContent = $contentObjectAttribute->attribute( 'content' );
1647 $objectIDList = array();
1648 foreach( $objectAttributeContent['relation_list'] as $objectInfo )
1649 {
1650 $objectIDList[] = $objectInfo['contentobject_id'];
1651 }
1652 return implode( '-', $objectIDList );
1653 }
1654
1655 function fromString( $contentObjectAttribute, $string )
1656 {
1657 $objectIDList = explode( '-', $string );
1658
1659 $content = $this->defaultObjectAttributeContent();
1660 $priority = 0;
1661 foreach( $objectIDList as $objectID )
1662 {
1663 $object = eZContentObject::fetch( $objectID );
1664 if ( $object )
1665 {
1666 ++$priority;
1667 $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute );
1668 }
1669 else
1670 {
1671 eZDebug::writeWarning( $objectID, "Can not create relation because object is missing" );
1672 }
1673 }
1674 $contentObjectAttribute->setContent( $content );
1675 return true;
1676 }
1677
1678 function hasObjectAttributeContent( $contentObjectAttribute )
1679 {
1680 $content = $contentObjectAttribute->content();
1681 return count( $content['relation_list'] ) > 0;
1682 }
1683
1684 function isIndexable()
1685 {
1686 return true;
1687 }
1688
1693 function title( $contentObjectAttribute, $name = null )
1694 {
1695 $objectAttributeContent = $this->objectAttributeContent( $contentObjectAttribute );
1696
1697 if ( count( $objectAttributeContent['relation_list'] ) > 0 )
1698 {
1699 $target = $objectAttributeContent['relation_list'][0];
1700 $targetObject = eZContentObject::fetch( $target['contentobject_id'] );
1701 $attributeLanguage = $contentObjectAttribute->attribute( 'language_code' );
1702 $targetObjectName = $targetObject->name( false, $attributeLanguage );
1703 return $targetObjectName;
1704 }
1705 else
1706 {
1707 return false;
1708 }
1709 }
1710
1711 function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
1712 {
1713 $dom = $attributeParametersNode->ownerDocument;
1714 $content = $classAttribute->content();
1715 if ( $content['default_placement'] )
1716 {
1717 $defaultPlacementNode = $dom->createElement( 'default-placement' );
1718 $defaultPlacementNode->setAttribute( 'node-id', $content['default_placement']['node_id'] );
1719 $attributeParametersNode->appendChild( $defaultPlacementNode );
1720 }
1721
1722 $type = is_numeric( $content['type'] ) ? $content['type'] : '0';
1723 $typeNode = $dom->createElement( 'type' );
1724 $typeNode->appendChild( $dom->createTextNode( $type ) );
1725 $attributeParametersNode->appendChild( $typeNode );
1726
1727 $classConstraintsNode = $dom->createElement( 'class-constraints' );
1728 $attributeParametersNode->appendChild( $classConstraintsNode );
1729 foreach ( $content['class_constraint_list'] as $classConstraint )
1730 {
1731 $classConstraintIdentifier = $classConstraint;
1732 $classConstraintNode = $dom->createElement( 'class-constraint' );
1733 $classConstraintNode->setAttribute( 'class-identifier', $classConstraintIdentifier );
1734 $classConstraintsNode->appendChild( $classConstraintNode );
1735 }
1736
1737 if ( isset( $content['selection_type'] ) && is_numeric( $content['selection_type'] ) )
1738 {
1739 $selectionTypeNode = $dom->createElement( 'selection-type' );
1740 $selectionTypeNode->appendChild( $dom->createTextNode( $content['selection_type'] ) );
1741 $attributeParametersNode->appendChild( $selectionTypeNode );
1742 }
1743
1744 if ( isset( $content['object_class'] ) && is_numeric( $content['object_class'] ) )
1745 {
1746 $objectClassNode = $dom->createElement( 'object-class' );
1747 $objectClassNode->appendChild( $dom->createTextNode( $content['object_class'] ) );
1748 $attributeParametersNode->appendChild( $objectClassNode );
1749 }
1750 }
1751
1752 function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
1753 {
1754 $content = $classAttribute->content();
1755 $defaultPlacementNode = $attributeParametersNode->getElementsByTagName( 'default-placement' )->item( 0 );
1756 $content['default_placement'] = false;
1757
1758 if ( $defaultPlacementNode )
1759 {
1760 $content['default_placement'] = array( 'node_id' => $defaultPlacementNode->getAttribute( 'node-id' ) );
1761 }
1762 $content['type'] = $attributeParametersNode->getElementsByTagName( 'type' )->item( 0 )->textContent;
1763 $classConstraintsNode = $attributeParametersNode->getElementsByTagName( 'class-constraints' )->item( 0 );
1764 $classConstraintList = $classConstraintsNode->getElementsByTagName( 'class-constraint' );
1765 $content['class_constraint_list'] = array();
1766 foreach ( $classConstraintList as $classConstraintNode )
1767 {
1768 $classIdentifier = $classConstraintNode->getAttribute( 'class-identifier' );
1769 $content['class_constraint_list'][] = $classIdentifier;
1770 }
1771
1772 $objectClassNode = $attributeParametersNode->getElementsByTagName( 'object-class' )->item( 0 );
1773 if ( $objectClassNode )
1774 {
1775 $content['object_class'] = $objectClassNode->textContent;
1776 }
1777
1778 $selectionTypeNode = $attributeParametersNode->getElementsByTagName( 'selection-type' )->item( 0 );
1779 if ( $selectionTypeNode )
1780 {
1781 $content['selection_type'] = $selectionTypeNode->textContent;
1782 }
1783
1784 $classAttribute->setContent( $content );
1785 $this->storeClassAttributeContent( $classAttribute, $content );
1786 }
1787
1800 function serializeContentObjectAttribute( $package, $objectAttribute )
1801 {
1802 $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
1803
1804 eZDebug::writeDebug( $objectAttribute->attribute( 'data_text' ), 'xml string from data_text field' );
1805 if ( $objectAttribute->attribute( 'data_text' ) === null )
1806 {
1807 $content = array( 'relation_list' => array() );
1808 $dom = $this->createObjectDOMDocument( $content );
1809 }
1810 else
1811 {
1812 $dom = new DOMDocument( '1.0', 'utf-8' );
1813 $success = $dom->loadXML( $objectAttribute->attribute( 'data_text' ) );
1814 }
1815 $rootNode = $dom->documentElement;
1816 $relationList = $rootNode->getElementsByTagName( 'relation-list' )->item( 0 );
1817 if ( $relationList )
1818 {
1819 $relationItems = $relationList->getElementsByTagName( 'relation-item' );
1820 for ( $i = 0; $i < $relationItems->length; $i++ )
1821 {
1822 $relationItem = $relationItems->item( $i );
1823 // Add related object remote id as attribute to the relation item.
1824 $relatedObjectID = $relationItem->getAttribute( 'contentobject-id' );
1825 $relatedObject = eZContentObject::fetch( $relatedObjectID );
1826 $relatedObjectRemoteID = $relatedObject->attribute( 'remote_id' );
1827 $relationItem->setAttribute( 'contentobject-remote-id', $relatedObjectRemoteID );
1828
1829 $attributes = $relationItem->attributes;
1830 // Remove all other relation item attributes except of "priority".
1831 // This loop intentionally starts with the last attribute, otherwise you will get unexpected results
1832 for ( $j = $attributes->length - 1; $j >= 0; $j-- )
1833 {
1834 $attribute = $attributes->item( $j );
1835 $attrName = $attribute->localName;
1836
1837 eZDebug::writeDebug( $attrName );
1838 if ( $attrName != 'priority' && $attrName != 'contentobject-remote-id' )
1839 {
1840 $success = $relationItem->removeAttribute( $attribute->localName );
1841 if ( !$success )
1842 {
1843 eZDebug::writeError( 'failed removing attribute ' . $attrName . ' from relation-item element' );
1844 }
1845 }
1846 }
1847 }
1848 }
1849
1850 eZDebug::writeDebug( $dom->saveXML(), 'old xml doc' );
1851
1852 $importedRootNode = $node->ownerDocument->importNode( $rootNode, true );
1853 $node->appendChild( $importedRootNode );
1854
1855 return $node;
1856 }
1857
1858 function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
1859 {
1860 $rootNode = $attributeNode->getElementsByTagName( 'related-objects' )->item( 0 );
1861 $xmlString = $rootNode ? $rootNode->ownerDocument->saveXML( $rootNode ) : '';
1862 $objectAttribute->setAttribute( 'data_text', $xmlString );
1863 }
1864
1865 function postUnserializeContentObjectAttribute( $package, $objectAttribute )
1866 {
1867 $xmlString = $objectAttribute->attribute( 'data_text' );
1868 $doc = $this->parseXML( $xmlString );
1869 $rootNode = $doc->documentElement;
1870
1871 $relationList = $rootNode->getElementsByTagName( 'relation-list' )->item( 0 );
1872 if ( !$relationList )
1873 return false;
1874
1875 $relationItems = $relationList->getElementsByTagName( 'relation-item' );
1876 for ( $i = $relationItems->length - 1; $i >= 0; $i-- )
1877 {
1878 $relationItem = $relationItems->item( $i );
1879 $relatedObjectRemoteID = $relationItem->getAttribute( 'contentobject-remote-id' );
1880 $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID );
1881
1882 if ( $object === null )
1883 {
1884 eZDebug::writeWarning( "Object with remote id '$relatedObjectRemoteID' not found: removing the link.", __METHOD__ );
1885 $relationItem->parentNode->removeChild( $relationItem );
1886 continue;
1887 }
1888
1889 $relationItem->setAttribute( 'contentobject-id', $object->attribute( 'id' ) );
1890 $relationItem->setAttribute( 'contentobject-version', $object->attribute( 'current_version' ) );
1891 $relationItem->setAttribute( 'node-id', $object->attribute( 'main_node_id' ) );
1892 $relationItem->setAttribute( 'parent-node-id', $object->attribute( 'main_parent_node_id' ) );
1893 $relationItem->setAttribute( 'contentclass-id', $object->attribute( 'contentclass_id' ) );
1894 $relationItem->setAttribute( 'contentclass-identifier', $object->attribute( 'class_identifier' ) );
1895 }
1896
1897 $newXmlString = $doc->saveXML( $rootNode );
1898
1899 $objectAttribute->setAttribute( 'data_text', $newXmlString );
1900 return true;
1901 }
1902
1906 function removeRelatedObjectItem( $contentObjectAttribute, $objectID )
1907 {
1908 $xmlText = $contentObjectAttribute->attribute( 'data_text' );
1909 if ( trim( $xmlText ) == '' ) return;
1910
1911 $doc = $this->parseXML( $xmlText );
1912
1913 $return = false;
1914 $root = $doc->documentElement;
1915 $relationList = $root->getElementsByTagName( 'relation-list' )->item( 0 );
1916 if ( $relationList )
1917 {
1918 $relationItems = $relationList->getElementsByTagName( 'relation-item' );
1919 if ( !empty( $relationItems ) )
1920 {
1921 foreach( $relationItems as $relationItem )
1922 {
1923 if ( $relationItem->getAttribute( 'contentobject-id' ) == $objectID )
1924 {
1925 $relationList->removeChild( $relationItem );
1926 $return = true;
1927 }
1928 }
1929 }
1930 }
1931 $this->storeObjectDOMDocument( $doc, $contentObjectAttribute );
1932 return $return;
1933 }
1934
1935 function supportsBatchInitializeObjectAttribute()
1936 {
1937 return true;
1938 }
1939
1941 }
1942
1943 eZDataType::register( eZObjectRelationListType::DATA_TYPE_STRING, "eZObjectRelationListType" );
1944
1945 ?>
eZCharsetInfo\realCharsetCode
static realCharsetCode( $charsetCode)
Definition: ezcharsetinfo.php:186
eZContentBrowse\result
static result( $actionName, $asObject=false)
Definition: ezcontentbrowse.php:258
eZContentBrowse\nodeAliasID
static nodeAliasID( $nodeName)
Definition: ezcontentbrowse.php:224
eZContentBrowse\browse
static browse( $parameters=array(), &$module)
Definition: ezcontentbrowse.php:89
eZContentClassAttribute
Encapsulates data for a class attribute.
Definition: ezcontentclassattribute.php:19
eZContentClass\fetch
static fetch( $id, $asObject=true, $version=eZContentClass::VERSION_STATUS_DEFINED, $user_id=false, $parent_id=null)
Definition: ezcontentclass.php:1116
eZContentObjectAttribute\fetch
static fetch( $id, $version, $asObject=true, $field_filters=null)
Definition: ezcontentobjectattribute.php:136
eZContentObjectAttribute\definition
static definition()
Definition: ezcontentobjectattribute.php:38
eZContentObjectAttribute\metaDataArray
static metaDataArray(&$attributes, $skipRelationAttributes=false)
Definition: ezcontentobjectattribute.php:1198
eZContentObjectAttribute\removeRelationsByContentClassAttributeId
static removeRelationsByContentClassAttributeId( $attributeId)
Definition: ezcontentobjectattribute.php:1494
eZContentObjectTrashNode\definition
static definition()
Definition: ezcontentobjecttrashnode.php:19
eZContentObjectTreeNode
Definition: ezcontentobjecttreenode.php:17
eZContentObjectTreeNode\SORT_FIELD_PUBLISHED
const SORT_FIELD_PUBLISHED
Definition: ezcontentobjecttreenode.php:19
eZContentObjectTreeNode\SORT_ORDER_DESC
const SORT_ORDER_DESC
Definition: ezcontentobjecttreenode.php:32
eZContentObjectTreeNode\fetch
static fetch( $nodeID=false, $lang=false, $asObject=true, $conditions=false)
Definition: ezcontentobjecttreenode.php:3058
eZContentObjectVersion
The class eZContentObjectVersion handles different versions of an content object.
Definition: ezcontentobjectversion.php:19
eZContentObjectVersion\STATUS_DRAFT
const STATUS_DRAFT
Definition: ezcontentobjectversion.php:29
eZContentObjectVersion\STATUS_PUBLISHED
const STATUS_PUBLISHED
Definition: ezcontentobjectversion.php:30
eZContentObjectVersion\STATUS_ARCHIVED
const STATUS_ARCHIVED
Definition: ezcontentobjectversion.php:32
eZContentObjectVersion\fetchVersion
static fetchVersion( $version, $contentObjectID, $asObject=true)
Definition: ezcontentobjectversion.php:166
eZContentObject
Definition: ezcontentobject.php:17
eZContentObject\STATUS_PUBLISHED
const STATUS_PUBLISHED
Definition: ezcontentobject.php:20
eZContentObject\STATUS_ARCHIVED
const STATUS_ARCHIVED
Definition: ezcontentobject.php:21
eZContentObject\fetch
static fetch( $id, $asObject=true)
Definition: ezcontentobject.php:885
eZContentObject\recursionProtect
static recursionProtect( $id)
Definition: ezcontentobject.php:2702
eZContentObject\fetchByRemoteID
static fetchByRemoteID( $remoteID, $asObject=true)
Definition: ezcontentobject.php:865
eZContentObject\RELATION_ATTRIBUTE
const RELATION_ATTRIBUTE
Definition: ezcontentobject.php:40
eZDB\instance
static instance( $databaseImplementation=false, $databaseParameters=false, $forceNewInstance=false)
Definition: ezdb.php:117
eZDataType
Base class for content datatypes.
Definition: ezdatatype.php:46
eZDataType\fetchActionValue
fetchActionValue( $action, $actionName, &$value)
Definition: ezdatatype.php:798
eZDataType\register
static register( $dataTypeString, $className)
Definition: ezdatatype.php:203
eZDataType\storeObjectAttribute
storeObjectAttribute( $objectAttribute)
Definition: ezdatatype.php:632
eZDataType\createContentObjectAttributeDOMNode
createContentObjectAttributeDOMNode( $objectAttribute)
Definition: ezdatatype.php:1371
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDebug\writeDebug
static writeDebug( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:588
eZDebug\writeWarning
static writeWarning( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:502
eZHTTPTool\instance
static instance()
Definition: ezhttptool.php:189
eZInputValidator\STATE_INTERMEDIATE
const STATE_INTERMEDIATE
Definition: ezinputvalidator.php:80
eZInputValidator\STATE_ACCEPTED
const STATE_ACCEPTED
Definition: ezinputvalidator.php:79
eZInputValidator\STATE_INVALID
const STATE_INVALID
Definition: ezinputvalidator.php:81
eZNodeAssignment\fetch
static fetch( $contentObjectID, $version=1, $parentNode=0, $asObject=true)
Definition: eznodeassignment.php:409
eZNodeAssignment\create
static create( $parameters=array())
Definition: eznodeassignment.php:193
eZObjectRelationListType
A content datatype which handles object relations.
Definition: ezobjectrelationlisttype.php:26
eZObjectRelationListType\fetchClassAttributeHTTPInput
fetchClassAttributeHTTPInput( $http, $base, $classAttribute)
Definition: ezobjectrelationlisttype.php:674
eZObjectRelationListType\validateClassAttributeHTTPInput
validateClassAttributeHTTPInput( $http, $base, $classAttribute)
Definition: ezobjectrelationlisttype.php:665
eZObjectRelationListType\initializeClassAttribute
initializeClassAttribute( $classAttribute)
Definition: ezobjectrelationlisttype.php:712
eZObjectRelationListType\fixRelationsRemove
fixRelationsRemove( $objectID, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1415
eZObjectRelationListType\storeObjectAttributeContent
storeObjectAttributeContent( $objectAttribute, $content)
Definition: ezobjectrelationlisttype.php:739
eZObjectRelationListType\deleteStoredObjectAttribute
deleteStoredObjectAttribute( $objectAttribute, $version=null)
Definition: ezobjectrelationlisttype.php:879
eZObjectRelationListType\fixRelationsRestore
fixRelationsRestore( $objectID, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1398
eZObjectRelationListType\defaultClassAttributeContent
defaultClassAttributeContent()
Definition: ezobjectrelationlisttype.php:1476
eZObjectRelationListType\storeClassAttributeContent
storeClassAttributeContent( $classAttribute, $content)
Definition: ezobjectrelationlisttype.php:728
eZObjectRelationListType\createNewObject
createNewObject( $contentObjectAttribute, $name)
Definition: ezobjectrelationlisttype.php:333
eZObjectRelationListType\title
title( $contentObjectAttribute, $name=null)
Definition: ezobjectrelationlisttype.php:1693
eZObjectRelationListType\unserializeContentObjectAttribute
unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode)
Definition: ezobjectrelationlisttype.php:1858
eZObjectRelationListType\deleteNotVersionedStoredClassAttribute
deleteNotVersionedStoredClassAttribute(eZContentClassAttribute $classAttribute)
Definition: ezobjectrelationlisttype.php:895
eZObjectRelationListType\fixRelatedObjectItem
fixRelatedObjectItem( $contentObjectAttribute, $objectID, $mode)
Definition: ezobjectrelationlisttype.php:1340
eZObjectRelationListType\isIndexable
isIndexable()
Definition: ezobjectrelationlisttype.php:1684
eZObjectRelationListType\__construct
__construct()
Definition: ezobjectrelationlisttype.php:29
eZObjectRelationListType\serializeContentObjectAttribute
serializeContentObjectAttribute( $package, $objectAttribute)
Definition: ezobjectrelationlisttype.php:1800
eZObjectRelationListType\fixRelationsSwap
fixRelationsSwap( $objectID, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1421
eZObjectRelationListType\isRelationType
isRelationType()
Definition: ezobjectrelationlisttype.php:35
eZObjectRelationListType\hasObjectAttributeContent
hasObjectAttributeContent( $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1678
eZObjectRelationListType\supportsBatchInitializeObjectAttribute
supportsBatchInitializeObjectAttribute()
Definition: ezobjectrelationlisttype.php:1935
eZObjectRelationListType\createObjectDOMDocument
static createObjectDOMDocument( $content)
Definition: ezobjectrelationlisttype.php:821
eZObjectRelationListType\handleCustomObjectHTTPActions
handleCustomObjectHTTPActions( $http, $attributeDataBaseName, $customActionAttributeArray, $customActionParameters)
Definition: ezobjectrelationlisttype.php:1162
eZObjectRelationListType\serializeContentClassAttribute
serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode)
Definition: ezobjectrelationlisttype.php:1711
eZObjectRelationListType\parseXML
static parseXML( $xmlText)
Definition: ezobjectrelationlisttype.php:1469
eZObjectRelationListType\fixupClassAttributeHTTPInput
fixupClassAttributeHTTPInput( $http, $base, $classAttribute)
Definition: ezobjectrelationlisttype.php:670
eZObjectRelationListType\domString
static domString( $domDocument)
Definition: ezobjectrelationlisttype.php:768
eZObjectRelationListType\fixupObjectAttributeHTTPInput
fixupObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:165
eZObjectRelationListType\fromString
fromString( $contentObjectAttribute, $string)
Definition: ezobjectrelationlisttype.php:1655
eZObjectRelationListType\fetchObjectAttributeHTTPInput
fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:190
eZObjectRelationListType\fixRelationsTrash
fixRelationsTrash( $objectID, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1381
eZObjectRelationListType\createObjectContentStructure
createObjectContentStructure( $doc)
Definition: ezobjectrelationlisttype.php:1531
eZObjectRelationListType\initializeObjectAttribute
initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute)
Definition: ezobjectrelationlisttype.php:576
eZObjectRelationListType\classAttributeContent
classAttributeContent( $classAttribute)
Definition: ezobjectrelationlisttype.php:1458
eZObjectRelationListType\DATA_TYPE_STRING
const DATA_TYPE_STRING
Definition: ezobjectrelationlisttype.php:27
eZObjectRelationListType\removeRelationObject
static removeRelationObject( $contentObjectAttribute, $deletionItem)
Definition: ezobjectrelationlisttype.php:1205
eZObjectRelationListType\validateObjectAttributeHTTPInput
validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:44
eZObjectRelationListType\createClassContentStructure
createClassContentStructure( $doc)
Definition: ezobjectrelationlisttype.php:1490
eZObjectRelationListType\postUnserializeContentObjectAttribute
postUnserializeContentObjectAttribute( $package, $objectAttribute)
Definition: ezobjectrelationlisttype.php:1865
eZObjectRelationListType\objectAttributeContent
objectAttributeContent( $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1444
eZObjectRelationListType\appendObject
appendObject( $objectID, $priority, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1313
eZObjectRelationListType\unserializeContentClassAttribute
unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode)
Definition: ezobjectrelationlisttype.php:1752
eZObjectRelationListType\metaData
metaData( $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1601
eZObjectRelationListType\storeClassDOMDocument
static storeClassDOMDocument( $doc, $classAttribute)
Definition: ezobjectrelationlisttype.php:750
eZObjectRelationListType\customClassAttributeHTTPAction
customClassAttributeHTTPAction( $http, $action, $classAttribute)
Definition: ezobjectrelationlisttype.php:1555
eZObjectRelationListType\toString
toString( $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1644
eZObjectRelationListType\createInstance
createInstance( $class, $priority, $contentObjectAttribute, $nodePlacement=false)
Definition: ezobjectrelationlisttype.php:1282
eZObjectRelationListType\customObjectAttributeHTTPAction
customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters)
Definition: ezobjectrelationlisttype.php:900
eZObjectRelationListType\contentObjectArrayXMLMap
static contentObjectArrayXMLMap()
Definition: ezobjectrelationlisttype.php:861
eZObjectRelationListType\fixRelationsMove
fixRelationsMove( $objectID, $contentObjectAttribute)
Definition: ezobjectrelationlisttype.php:1376
eZObjectRelationListType\preStoreClassAttribute
preStoreClassAttribute( $classAttribute, $version)
Definition: ezobjectrelationlisttype.php:722
eZObjectRelationListType\isItemPublished
static isItemPublished( $relationItem)
Definition: ezobjectrelationlisttype.php:1195
eZObjectRelationListType\removeRelatedObjectItem
removeRelatedObjectItem( $contentObjectAttribute, $objectID)
Definition: ezobjectrelationlisttype.php:1906
eZObjectRelationListType\onPublish
onPublish( $contentObjectAttribute, $contentObject, $publishedNodes)
Definition: ezobjectrelationlisttype.php:500
eZObjectRelationListType\createClassDOMDocument
static createClassDOMDocument( $content)
Definition: ezobjectrelationlisttype.php:788
eZObjectRelationListType\storeObjectDOMDocument
static storeObjectDOMDocument( $doc, $objectAttribute)
Definition: ezobjectrelationlisttype.php:756
eZObjectRelationListType\defaultObjectAttributeContent
defaultObjectAttributeContent()
Definition: ezobjectrelationlisttype.php:1485
eZOperationHandler\execute
static execute( $moduleName, $operationName, $operationParameters, $lastTriggerName=null, $useTriggers=true)
Definition: ezoperationhandler.php:42
eZPersistentObject\count
static count( $def, $conds=null, $field=null)
Definition: ezpersistentobject.php:187
eZPersistentObject\attribute
attribute( $attr, $noFunction=false)
Definition: ezpersistentobject.php:1329
eZPersistentObject\fetchObjectList
static fetchObjectList( $def, $field_filters=null, $conds=null, $sorts=null, $limit=null, $asObject=true, $grouping=false, $custom_fields=null, $custom_tables=null, $custom_conds=null)
Definition: ezpersistentobject.php:806
eZTextCodec\internalCharset
static internalCharset()
Definition: eztextcodec.php:546
ezpI18n\tr
static tr( $context, $source, $comment=null, $arguments=null)
Definition: ezpi18n.php:86
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.