Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezcontentobjecttreenode.php
Go to the documentation of this file.
1 <?php
16 class eZContentObjectTreeNode extends eZPersistentObject
17 {
18 const SORT_FIELD_PATH = 1;
19 const SORT_FIELD_PUBLISHED = 2;
20 const SORT_FIELD_MODIFIED = 3;
21 const SORT_FIELD_SECTION = 4;
22 const SORT_FIELD_DEPTH = 5;
23 const SORT_FIELD_CLASS_IDENTIFIER = 6;
24 const SORT_FIELD_CLASS_NAME = 7;
25 const SORT_FIELD_PRIORITY = 8;
26 const SORT_FIELD_NAME = 9;
27 const SORT_FIELD_MODIFIED_SUBNODE = 10;
28 const SORT_FIELD_NODE_ID = 11;
29 const SORT_FIELD_CONTENTOBJECT_ID = 12;
30 const SORT_FIELD_VISIBILITY = 13;
31
32 const SORT_ORDER_DESC = 0;
33 const SORT_ORDER_ASC = 1;
34
35 public function __construct( $row = array() )
36 {
37 parent::__construct( $row );
38 }
39
44 function eZContentObjectTreeNode( $row = array() )
45 {
46 self::__construct( $row );
47 }
48
52 static function definition()
53 {
54 static $definition = array( "fields" => array( "node_id" => array( 'name' => "NodeID",
55 'datatype' => 'integer',
56 'default' => 0,
57 'required' => true ),
58 "parent_node_id" => array( 'name' => "ParentNodeID",
59 'datatype' => 'integer',
60 'default' => 0,
61 'required' => true,
62 'foreign_class' => 'eZContentObjectTreeNode',
63 'foreign_attribute' => 'node_id',
64 'multiplicity' => '1..*' ),
65 "main_node_id" => array( 'name' => "MainNodeID",
66 'datatype' => 'integer',
67 'default' => 0,
68 'required' => true,
69 'foreign_class' => 'eZContentObjectTreeNode',
70 'foreign_attribute' => 'node_id',
71 'multiplicity' => '1..*' ),
72 "contentobject_id" => array( 'name' => "ContentObjectID",
73 'datatype' => 'integer',
74 'default' => 0,
75 'required' => true,
76 'foreign_class' => 'eZContentObject',
77 'foreign_attribute' => 'id',
78 'multiplicity' => '1..*' ),
79 'contentobject_version' => array( 'name' => 'ContentObjectVersion',
80 'datatype' => 'integer',
81 'default' => 0,
82 'required' => true ),
83 'contentobject_is_published' => array( 'name' => 'ContentObjectIsPublished',
84 'datatype' => 'integer',
85 'default' => 0,
86 'required' => true ),
87 "depth" => array( 'name' => "Depth",
88 'datatype' => 'integer',
89 'default' => 0,
90 'required' => true ),
91 'sort_field' => array( 'name' => 'SortField',
92 'datatype' => 'integer',
93 'default' => self::SORT_FIELD_PATH,
94 'required' => true ),
95 'sort_order' => array( 'name' => 'SortOrder',
96 'datatype' => 'integer',
97 'default' => self::SORT_ORDER_ASC,
98 'required' => true ),
99 'priority' => array( 'name' => 'Priority',
100 'datatype' => 'integer',
101 'default' => 0,
102 'required' => true ),
103 'modified_subnode' => array( 'name' => 'ModifiedSubNode',
104 'datatype' => 'integer',
105 'default' => 0,
106 'required' => true ),
107 "path_string" => array( 'name' => "PathString",
108 'datatype' => 'string',
109 'default' => '',
110 'required' => true ),
111 "path_identification_string" => array( 'name' => "PathIdentificationString",
112 'datatype' => 'text',
113 'default' => '',
114 'required' => true ),
115 'remote_id' => array( 'name' => 'RemoteID',
116 'datatype' => 'string',
117 'default' => '',
118 'required' => true ),
119 "is_hidden" => array( 'name' => "IsHidden",
120 'datatype' => 'integer',
121 'default' => 0,
122 'required' => true ),
123 "is_invisible" => array( 'name' => "IsInvisible",
124 'datatype' => 'integer',
125 'default' => 0,
126 'required' => true ) ),
127 "keys" => array( "node_id" ),
128 "function_attributes" => array( "name" => "getName",
129 'data_map' => 'dataMap',
130 'remote_id' => 'remoteID', // Note: This overrides remote_id field
131 "object" => "object",
132 "subtree" => "subTree",
133 "children" => "children",
134 "children_count" => "childrenCount",
135 'view_count' => 'viewCount',
136 'contentobject_version_object' => 'contentObjectVersionObject',
137 'sort_array' => 'sortArray',
138 'can_read' => 'canRead',
139 'can_pdf' => 'canPdf',
140 'can_create' => 'canCreate',
141 'can_edit' => 'canEdit',
142 'can_hide' => 'canHide',
143 'can_remove' => 'canRemove',
144 'can_move' => 'canMoveFrom',
145 'can_move_from' => 'canMoveFrom',
146 'can_add_location' => 'canAddLocation',
147 'can_remove_location' => 'canRemoveLocation',
148 'can_view_embed' => 'canViewEmbed',
149 'is_main' => 'isMain',
150 'creator' => 'creator',
151 "path_with_names" => "pathWithNames",
152 "path" => "fetchPath",
153 'path_array' => 'pathArray',
154 "parent" => "fetchParent",
155 'url' => 'url',
156 'url_alias' => 'urlAlias',
157 'class_identifier' => 'classIdentifier',
158 'class_name' => 'className',
159 'hidden_invisible_string' => 'hiddenInvisibleString',
160 'hidden_status_string' => 'hiddenStatusString',
161 'classes_js_array' => 'availableClassesJsArray',
162 'is_container' => 'classIsContainer' ),
163 "increment_key" => "node_id",
164 "class_name" => "eZContentObjectTreeNode",
165 "name" => "ezcontentobject_tree" );
166 return $definition;
167 }
168
182 static function create( $parentNodeID = null, $contentObjectID = null, $contentObjectVersion = 0,
183 $sortField = 0, $sortOrder = true )
184 {
185 $row = array( 'node_id' => null,
186 'main_node_id' => null,
187 'parent_node_id' => $parentNodeID,
188 'contentobject_id' => $contentObjectID,
189 'contentobject_version' => $contentObjectVersion,
190 'contentobject_is_published' => false,
191 'depth' => 1,
192 'path_string' => null,
193 'path_identification_string' => null,
194 'is_hidden' => false,
195 'is_invisible' => false,
196 'sort_field' => $sortField,
197 'sort_order' => $sortOrder,
198 'modified_subnode' => 0,
199 'remote_id' => eZRemoteIdUtility::generate( 'node' ),
200 'priority' => 0 );
201 $node = new eZContentObjectTreeNode( $row );
202 return $node;
203 }
204
209 static protected $useCurrentUserDraft = false;
210
220 static public function setUseCurrentUserDraft( $enable )
221 {
222 self::$useCurrentUserDraft = (bool) $enable;
223 }
224
231 function dataMap()
232 {
233 $object = $this->object();
234 if ( self::$useCurrentUserDraft )
235 {
236 $draft = eZContentObjectVersion::fetchLatestUserDraft(
237 $object->attribute( 'id' ),
238 eZUser::currentUserID(),
239 $object->currentLanguageObject()->attribute( 'id' ),
240 $object->attribute( 'modified' )
241 );
242
243 if ( $draft instanceof eZContentObjectVersion )
244 return $object->fetchDataMap( $draft->attribute( 'version' ) );
245 }
246 return $object->fetchDataMap( $this->attribute( 'contentobject_version' ) );
247 }
248
258 function remoteID()
259 {
260 $remoteID = $this->attribute( 'remote_id', true );
261 if ( !$remoteID )
262 {
263 $this->setAttribute( 'remote_id', eZRemoteIdUtility::generate( 'node' ) );
264 $this->sync( array( 'remote_id' ) );
265 $remoteID = $this->attribute( 'remote_id', true );
266 }
267
268 return $remoteID;
269 }
270
276 function isMain()
277 {
278 return $this->NodeID == $this->MainNodeID;
279 }
280
288 static function classAttributeIDByIdentifier( $identifier )
289 {
290 return eZContentClassAttribute::classAttributeIDByIdentifier( $identifier );
291 }
292
300 static function classIDByIdentifier( $identifier )
301 {
302 return eZContentClass::classIDByIdentifier( $identifier );
303 }
304
310 function canRead( )
311 {
312 if ( !isset( $this->Permissions["can_read"] ) )
313 {
314 $this->Permissions["can_read"] = $this->checkAccess( 'read' );
315 }
316 return ( $this->Permissions["can_read"] == 1 );
317 }
318
324 function canPdf( )
325 {
326 if ( !isset( $this->Permissions["can_pdf"] ) )
327 {
328 $this->Permissions["can_pdf"] = $this->checkAccess( 'pdf' );
329 }
330 return ( $this->Permissions["can_pdf"] == 1 );
331 }
332
338 function canViewEmbed( )
339 {
340 if ( !isset( $this->Permissions["can_view_embed"] ) )
341 {
342 $this->Permissions["can_view_embed"] = $this->checkAccess( 'view_embed' );
343 }
344 return ( $this->Permissions["can_view_embed"] == 1 );
345 }
346
352 function canEdit( )
353 {
354 if ( !isset( $this->Permissions["can_edit"] ) )
355 {
356 $this->Permissions["can_edit"] = $this->checkAccess( 'edit' );
357 if ( $this->Permissions["can_edit"] != 1 )
358 {
359 $user = eZUser::currentUser();
360 if ( $user->id() == $this->ContentObject->attribute( 'id' ) )
361 {
362 $access = $user->hasAccessTo( 'user', 'selfedit' );
363 if ( $access['accessWord'] == 'yes' )
364 {
365 $this->Permissions["can_edit"] = 1;
366 }
367 }
368 }
369 }
370 return ( $this->Permissions["can_edit"] == 1 );
371 }
372
378 function canHide( )
379 {
380 if ( !isset( $this->Permissions["can_hide"] ) )
381 {
382 $this->Permissions["can_hide"] = $this->checkAccess( 'hide' );
383 }
384 return ( $this->Permissions["can_hide"] == 1 );
385 }
386
392 function canCreate( )
393 {
394 if ( !isset( $this->Permissions["can_create"] ) )
395 {
396 $this->Permissions["can_create"] = $this->checkAccess( 'create' );
397 }
398 return ( $this->Permissions["can_create"] == 1 );
399 }
400
406 function canRemove( )
407 {
408 if ( !isset( $this->Permissions["can_remove"] ) )
409 {
410 $this->Permissions["can_remove"] = $this->checkAccess( 'remove' );
411 }
412 return ( $this->Permissions["can_remove"] == 1 );
413 }
414
420 function canMoveFrom( )
421 {
422 if ( !isset( $this->Permissions['can_move_from'] ) )
423 {
424 $this->Permissions['can_move_from'] = $this->checkAccess( 'edit' ) && $this->checkAccess( 'remove' );
425 }
426 return ( $this->Permissions['can_move_from'] == 1 );
427 }
428
435 function canMoveTo( $classID = false )
436 {
437 if ( !isset( $this->Permissions['can_move_to'] ) )
438 {
439 $this->Permissions['can_move_to'] = $this->checkAccess( 'create', $classID );
440 }
441 return ( $this->Permissions['can_move_to'] == 1 );
442 }
443
449 function canSwap()
450 {
451 if ( !isset( $this->Permissions['can_swap'] ) )
452 {
453 $this->Permissions['can_swap'] = $this->checkAccess( 'edit' );
454 }
455 return ( $this->Permissions['can_swap'] == 1 );
456 }
457
463 function canAddLocation()
464 {
465 if ( !isset( $this->Permissions['can_add_location'] ) )
466 {
467 $this->Permissions['can_add_location'] = $this->checkAccess( 'can_add_location' );
468 }
469 return ( $this->Permissions['can_add_location'] == 1 );
470 }
471
477 function canRemoveLocation()
478 {
479 if ( !isset( $this->Permissions['can_remove_location'] ) )
480 {
481 $this->Permissions['can_remove_location'] = $this->checkAccess( 'can_remove_location' );
482 }
483 return ( $this->Permissions['can_remove_location'] == 1 );
484 }
485
492 static function sortKeyByClassAttributeID( $classAttributeID )
493 {
494 return eZContentClassAttribute::sortKeyTypeByID( $classAttributeID );
495 }
496
503 static function dataTypeByClassAttributeID( $classAttributeID )
504 {
505 return eZContentClassAttribute::dataTypeByID( $classAttributeID );
506 }
507
513 static function fetchListCount()
514 {
515 $sql = "SELECT count( node_id ) as count FROM ezcontentobject_tree";
516 $db = eZDB::instance();
517 $rows = $db->arrayQuery( $sql );
518 return $rows[0]['count'];
519 }
520
529 static function fetchList( $asObject = true, $offset = false, $limit = false )
530 {
531 $sql = "SELECT * FROM ezcontentobject_tree";
532 $parameters = array();
533 if ( $offset !== false )
534 $parameters['offset'] = $offset;
535 if ( $limit !== false )
536 $parameters['limit'] = $limit;
537 $db = eZDB::instance();
538 $rows = $db->arrayQuery( $sql, $parameters );
539 $nodes = array();
540 if ( $asObject )
541 {
542 foreach ( $rows as $row )
543 {
544 $nodes[] = new eZContentObjectTreeNode( $row );
545 }
546 return $nodes;
547 }
548 else
549 return $rows;
550 }
551
560 static function createSortingSQLStrings( $sortList, $treeTableName = 'ezcontentobject_tree', $allowCustomColumns = false )
561 {
562 $sortingInfo = array( 'sortCount' => 0,
563 'sortingFields' => " path_string ASC",
564 'attributeJoinCount' => 0,
565 'attributeFromSQL' => "",
566 'attributeTargetSQL' => "",
567 'attributeWhereSQL' => "" );
568
569 if ( $sortList and is_array( $sortList ) and count( $sortList ) > 0 )
570 {
571 if ( count( $sortList ) > 1 and !is_array( $sortList[0] ) )
572 {
573 $sortList = array( $sortList );
574 }
575
576 $sortingFields = '';
577 $sortCount = 0;
578 $attributeJoinCount = 0;
579 $stateJoinCount = 0;
580 $attributeFromSQL = "";
581 $attributeWhereSQL = "";
582 $datatypeSortingTargetSQL = "";
583
584 foreach ( $sortList as $sortBy )
585 {
586 if ( is_array( $sortBy ) and count( $sortBy ) > 0 )
587 {
588 if ( $sortCount > 0 )
589 {
590 $sortingFields .= ', ';
591 }
592
593 $sortField = $sortBy[0];
594 switch ( $sortField )
595 {
596 case 'path':
597 {
598 $sortingFields .= 'path_string';
599 } break;
600 case 'path_string':
601 {
602 $sortingFields .= 'path_identification_string';
603 } break;
604 case 'published':
605 {
606 $sortingFields .= 'ezcontentobject.published';
607 } break;
608 case 'modified':
609 {
610 $sortingFields .= 'ezcontentobject.modified';
611 } break;
612 case 'modified_subnode':
613 {
614 $sortingFields .= 'modified_subnode';
615 } break;
616 case 'section':
617 {
618 $sortingFields .= 'ezcontentobject.section_id';
619 } break;
620 case 'node_id':
621 {
622 $sortingFields .= $treeTableName . '.node_id';
623 } break;
624 case 'contentobject_id':
625 {
626 $sortingFields .= 'ezcontentobject.id';
627 } break;
628 case 'depth':
629 {
630 $sortingFields .= 'depth';
631 } break;
632 case 'class_identifier':
633 {
634 $sortingFields .= 'ezcontentclass.identifier';
635 } break;
636 case 'class_name':
637 {
638 $classNameFilter = eZContentClassName::sqlFilter();
639 $sortingFields .= 'contentclass_name';
640 $datatypeSortingTargetSQL .= ", $classNameFilter[nameField] AS contentclass_name";
641 $attributeFromSQL .= " INNER JOIN $classNameFilter[from] ON ($classNameFilter[where])";
642 } break;
643 case 'priority':
644 {
645 $sortingFields .= $treeTableName . '.priority';
646 } break;
647 case 'visibility':
648 {
649 $sortingFields .= $treeTableName . '.is_invisible';
650 } break;
651 case 'name':
652 {
653 $sortingFields .= 'ezcontentobject_name.name';
654 } break;
655 case 'trashed':
656 {
657 $sortingFields .= $treeTableName . '.trashed';
658 } break;
659 case 'attribute':
660 {
661 $classAttributeID = $sortBy[2];
662 if ( !is_numeric( $classAttributeID ) )
663 $classAttributeID = eZContentObjectTreeNode::classAttributeIDByIdentifier( $classAttributeID );
664
665
666 $contentAttributeTableAlias = "a$attributeJoinCount";
667 $datatypeFromSQL = "ezcontentobject_attribute $contentAttributeTableAlias";
668 $datatypeWhereSQL = "
669 $contentAttributeTableAlias.contentobject_id = ezcontentobject.id AND
670 $contentAttributeTableAlias.contentclassattribute_id = $classAttributeID AND
671 $contentAttributeTableAlias.version = ezcontentobject.current_version AND";
672 $datatypeWhereSQL .= eZContentLanguage::sqlFilter( $contentAttributeTableAlias, 'ezcontentobject' );
673
674 $dataType = eZDataType::create( eZContentObjectTreeNode::dataTypeByClassAttributeID( $classAttributeID ) );
675 if( is_object( $dataType ) && $dataType->customSorting() )
676 {
677 $params = array();
678 $params['contentobject_attr_id'] = "$contentAttributeTableAlias.id";
679 $params['contentobject_attr_version'] = "$contentAttributeTableAlias.version";
680 $params['table_alias_suffix'] = "$attributeJoinCount";
681
682 $sql = $dataType->customSortingSQL( $params );
683
684 $datatypeFromSQL .= " INNER JOIN $sql[from] ON ($sql[where])";
685 $datatypeSortingFieldSQL = $sql['sorting_field'];
686 $datatypeSortingTargetSQL .= ', ' . $sql['sorting_field'];
687 }
688 else
689 {
690 // Look up datatype for standard sorting
691 $sortKeyType = eZContentObjectTreeNode::sortKeyByClassAttributeID( $classAttributeID );
692 switch ( $sortKeyType )
693 {
694 case 'string':
695 {
696 $sortKey = 'sort_key_string';
697 } break;
698
699 case 'int':
700 default:
701 {
702 $sortKey = 'sort_key_int';
703 } break;
704 }
705
706 $datatypeSortingFieldSQL = "a$attributeJoinCount.$sortKey";
707 $datatypeSortingTargetSQL .= ', ' . $datatypeSortingFieldSQL;
708 }
709
710 $sortingFields .= "$datatypeSortingFieldSQL";
711 $attributeFromSQL .= " INNER JOIN $datatypeFromSQL ON ($datatypeWhereSQL)";
712
713 $attributeJoinCount++;
714 }break;
715
716 case 'state':
717 {
718 $stateGroupID = $sortBy[2];
719 if ( !is_numeric( $stateGroupID ) )
720 {
721 $stateGroup = eZContentObjectStateGroup::fetchByIdentifier( $stateGroupID );
722 if ( $stateGroup )
723 {
724 $stateGroupID = $stateGroup->attribute( 'id' );
725 }
726 else
727 {
728 eZDebug::writeError( "Unknown content object state group '$stateGroupID'" );
729 continue 2;
730 }
731 }
732
733 $stateAlias = "s$stateJoinCount";
734 $stateLinkAlias = "sl$stateJoinCount";
735 $sortingFields .= "$stateAlias.priority";
736 $datatypeSortingTargetSQL .= ", $stateAlias.priority";
737 $attributeFromSQL .=
738 " INNER JOIN ezcobj_state $stateAlias ON ($stateAlias.group_id = $stateGroupID)" .
739 " INNER JOIN ezcobj_state_link $stateLinkAlias" .
740 " ON ($stateLinkAlias.contentobject_id = ezcontentobject.id AND $stateLinkAlias.contentobject_state_id = $stateAlias.id)";
741 } break;
742
743 default:
744 {
745 if ( $allowCustomColumns )
746 {
747 // SEC: validate column name to prevent SQL injection (only allow word chars and dot)
748 if ( preg_match( '/^[a-zA-Z0-9_.]+$/', $sortField ) )
749 {
750 $sortingFields .= $sortField;
751 }
752 else
753 {
754 eZDebug::writeWarning( 'Invalid custom sort field: ' . $sortField, __METHOD__ );
755 continue 2;
756 }
757 }
758 else
759 {
760 eZDebug::writeWarning( 'Unknown sort field: ' . $sortField, __METHOD__ );
761 continue 2;
762 }
763 }
764 }
765 $sortOrder = true; // true is ascending
766 if ( isset( $sortBy[1] ) )
767 $sortOrder = $sortBy[1];
768 $sortingFields .= $sortOrder ? " ASC" : " DESC";
769 ++$sortCount;
770 }
771 }
772
773 $sortingInfo['sortCount'] = $sortCount;
774 $sortingInfo['sortingFields'] = $sortingFields;
775 $sortingInfo['attributeTargetSQL'] = $datatypeSortingTargetSQL;
776 $sortingInfo['attributeJoinCount'] = $attributeJoinCount;
777 $sortingInfo['attributeFromSQL'] = $attributeFromSQL;
778 $sortingInfo['attributeWhereSQL'] = $attributeWhereSQL;
779 }
780 else if ( $sortList === array() )
781 {
782 $sortingInfo['sortingFields'] = '';
783 }
784
785 return $sortingInfo;
786 }
787
795 static function createClassFilteringSQLString( $classFilterType, &$classFilterArray )
796 {
797 // Check for class filtering
798 $classCondition = '';
799
800 if ( isset( $classFilterType ) && is_array( $classFilterArray ) &&
801 ( $classFilterType == 'include' || $classFilterType == 'exclude' ) &&
802 count( $classFilterArray ) > 0 )
803 {
804 $classCondition = ' ';
805 $i = 0;
806 $classCount = count( $classFilterArray );
807 $classIDArray = array();
808 foreach ( $classFilterArray as $classID )
809 {
810 $originalClassID = $classID;
811 // Check if classes are recerenced by identifier
812 if ( is_string( $classID ) && !is_numeric( $classID ) )
813 {
814 $classID = eZContentClass::classIDByIdentifier( $classID );
815 }
816 if ( is_numeric( $classID ) )
817 {
818 $classIDArray[] = $classID;
819 }
820 else
821 {
822 eZDebugSetting::writeWarning( 'kernel-content-class', "Invalid class identifier in subTree() classfilterarray, classID : " . $originalClassID );
823 }
824 }
825
826 if ( count( $classIDArray ) > 0 )
827 {
828 $classCondition .= " ezcontentobject.contentclass_id ";
829 if ( $classFilterType == 'include' )
830 $classCondition .= " IN ";
831 else
832 $classCondition .= " NOT IN ";
833
834 $classIDString = implode( ', ', $classIDArray );
835 $classCondition .= ' ( ' . $classIDString . ' ) AND';
836 }
837 else
838 {
839 if ( count( $classIDArray ) == 0 and count( $classFilterArray ) > 0 and $classFilterType == 'include' )
840 {
841 $classCondition = false;
842 }
843 }
844 }
845
846 return $classCondition;
847 }
848
857 static function createExtendedAttributeFilterSQLStrings( &$extendedAttributeFilter )
858 {
859 $filter = array( 'tables' => '',
860 'joins' => '',
861 'columns' => '',
862 'group_by' => '' );
863
864 if ( $extendedAttributeFilter and count( $extendedAttributeFilter ) > 1 )
865 {
866 $extendedAttributeFilterID = $extendedAttributeFilter['id'];
867 $extendedAttributeFilterParams = $extendedAttributeFilter['params'];
868 $filterINI = eZINI::instance( 'extendedattributefilter.ini' );
869
870 if ( !$filterINI->hasGroup( $extendedAttributeFilterID ) )
871 {
872 eZDebug::writeError( "Unable to find configuration for the extended attribute filter '$extendedAttributeFilterID', the filter will be ignored", __METHOD__ );
873 return $filter;
874 }
875
876 $filterClassName = $filterINI->variable( $extendedAttributeFilterID, 'ClassName' );
877 $filterMethodName = $filterINI->variable( $extendedAttributeFilterID, 'MethodName' );
878
879 if ( $filterINI->hasVariable( $extendedAttributeFilterID, 'FileName' ) )
880 {
881 $filterFile = $filterINI->variable( $extendedAttributeFilterID, 'FileName' );
882
883 if ( $filterINI->hasVariable( $extendedAttributeFilterID, 'ExtensionName' ) )
884 {
885 $extensionName = $filterINI->variable( $extendedAttributeFilterID, 'ExtensionName' );
886 include_once( eZExtension::baseDirectory() . "/$extensionName/$filterFile" );
887 }
888 else
889 {
890 include_once( $filterFile );
891 }
892 }
893
894 if ( !class_exists( $filterClassName, true ) )
895 {
896 eZDebug::writeError( "Unable to find the PHP class '$filterClassName' associated with the extended attribute filter '$extendedAttributeFilterID', the filter will be ignored", __METHOD__ );
897 return $filter;
898 }
899
900 $classObject = new $filterClassName();
901 $parameterArray = array( $extendedAttributeFilterParams );
902
903 $sqlResult = call_user_func_array( array( $classObject, $filterMethodName ), $parameterArray );
904
905 $filter['tables'] = $sqlResult['tables'];
906 $filter['joins'] = $sqlResult['joins'];
907 $filter['columns'] = isset( $sqlResult['columns'] ) ? $sqlResult['columns'] : '';
908
909 if( isset( $sqlResult['group_by'] ) )
910 $filter['group_by'] = $sqlResult['group_by'];
911 }
912
913 return $filter;
914 }
915
922 static function createMainNodeConditionSQLString( $mainNodeOnly )
923 {
924 // Main node check
925 $mainNodeCondition = '';
926 if ( isset( $mainNodeOnly ) && $mainNodeOnly === true )
927 {
928 $mainNodeCondition = 'ezcontentobject_tree.node_id = ezcontentobject_tree.main_node_id AND';
929 }
930
931 return $mainNodeCondition;
932 }
933
945 static function createObjectNameFilterConditionSQLString( $filter )
946 {
947 if ( !$filter )
948 return '';
949
950 $db = eZDB::instance();
951 if ( $filter == 'others' )
952 {
953 $alphabet = eZAlphabetOperator::fetchAlphabet();
954 $sql = '';
955 foreach ( $alphabet as $letter )
956 {
957 $sql .= " AND ezcontentobject_name.name NOT LIKE '". $db->escapeString( $letter ) . "%' ";
958 }
959 return $sql;
960 }
961 $objectNameFilterSQL = " AND ezcontentobject_name.name LIKE '" . $db->escapeString( $filter ) ."%'";
962 return $objectNameFilterSQL;
963 }
964
973 static function createAttributeFilterSQLStrings( &$attributeFilter, &$sortingInfo = array( 'sortCount' => 0, 'attributeJoinCount' => 0 ), $language = false )
974 {
975 // Check for attribute filtering
976
977 $filterSQL = array( 'from' => '',
978 'where' => '' );
979
980 if ( $language !== false && !is_array( $language ) )
981 {
982 $language = array( $language );
983 }
984
985 $totalAttributesFiltersCount = 0;
986 $invalidAttributesFiltersCount = 0;
987
988 if ( isset( $attributeFilter ) && $attributeFilter !== false )
989 {
990 if ( !is_array( $attributeFilter ) )
991 {
992 eZDebug::writeError( "\$attributeFilter needs to be an array", __METHOD__ );
993 return $filterSQL;
994 }
995
996 $filterArray = $attributeFilter;
997
998 // Check if first value of array is a string.
999 // To check for and/or filtering
1000 $filterJoinType = 'AND';
1001 if ( is_string( $filterArray[0] ) )
1002 {
1003 if ( strtolower( $filterArray[0] ) == 'or' )
1004 {
1005 $filterJoinType = 'OR';
1006 }
1007 else if ( strtolower( $filterArray[0] ) == 'and' )
1008 {
1009 $filterJoinType = 'AND';
1010 }
1011 unset( $filterArray[0] );
1012 }
1013
1014 $attibuteFilterJoinSQL = "";
1015 $filterCount = $sortingInfo['sortCount'];
1016 $justFilterCount = 0;
1017
1018 $db = eZDB::instance();
1019 if ( is_array( $filterArray ) )
1020 {
1021 // Handle attribute filters and generate SQL
1022 $totalAttributesFiltersCount = count( $filterArray );
1023
1024 foreach ( $filterArray as $filter )
1025 {
1026 $isFilterValid = true; // by default assumes that filter is valid
1027
1028 $filterAttributeID = $filter[0];
1029 $filterType = $filter[1];
1030 $filterValue = is_array( $filter[2] ) ? '' : $db->escapeString( $filter[2] );
1031
1032 $useAttributeFilter = false;
1033 $filterFieldType = 'integer';
1034 switch ( $filterAttributeID )
1035 {
1036 case 'path':
1037 {
1038 $filterField = 'ezcontentobject_tree.path_string';
1039 $filterFieldType = 'string';
1040 } break;
1041 case 'published':
1042 {
1043 $filterField = 'ezcontentobject.published';
1044 } break;
1045 case 'modified':
1046 {
1047 $filterField = 'ezcontentobject.modified';
1048 } break;
1049 case 'modified_subnode':
1050 {
1051 $filterField = 'ezcontentobject_tree.modified_subnode';
1052 } break;
1053 case 'node_id':
1054 {
1055 $filterField = 'ezcontentobject_tree.node_id';
1056 } break;
1057 case 'contentobject_id':
1058 {
1059 $filterField = 'ezcontentobject_tree.contentobject_id';
1060 } break;
1061 case 'section':
1062 {
1063 $filterField = 'ezcontentobject.section_id';
1064 } break;
1065 case 'state':
1066 {
1067 // state only supports =, !=, in, and not_in
1068 // other operators do not make any sense in this context
1069 $hasFilterOperator = true;
1070
1071 switch ( $filterType )
1072 {
1073 case '=' :
1074 case '!=':
1075 {
1076 $subQueryCondition = 'contentobject_state_id = ' . (int) $filter[2];
1077 $filterOperator = ( $filterType == '=' ? 'IN' : 'NOT IN' );
1078 } break;
1079
1080 case 'in':
1081 case 'not_in' :
1082 {
1083 if ( is_array( $filter[2] ) )
1084 {
1085 $subQueryCondition = $db->generateSQLINStatement( $filter[2], 'contentobject_state_id', false, false, 'int' );
1086 $filterOperator = ( $filterType == 'in' ? 'IN' : 'NOT IN' );
1087 }
1088 else
1089 {
1090 $hasFilterOperator = false;
1091 }
1092 } break;
1093
1094 default :
1095 {
1096 $hasFilterOperator = false;
1097 eZDebug::writeError( "Unknown attribute filter type for state: $filterType", __METHOD__ );
1098 } break;
1099 }
1100
1101 if ( $hasFilterOperator )
1102 {
1103 if ( ( $filterCount - $sortingInfo['sortCount'] ) > 0 )
1104 $attibuteFilterJoinSQL .= " $filterJoinType ";
1105
1106 $attibuteFilterJoinSQL .= "ezcontentobject.id $filterOperator (SELECT contentobject_id FROM ezcobj_state_link WHERE $subQueryCondition)";
1107
1108 $filterCount++;
1109 $justFilterCount++;
1110 }
1111
1112 continue 2;
1113 } break;
1114 case 'depth':
1115 {
1116 $filterField = 'ezcontentobject_tree.depth';
1117 } break;
1118 case 'class_identifier':
1119 {
1120 $filterField = 'ezcontentclass.identifier';
1121 $filterFieldType = 'string';
1122 } break;
1123 case 'class_name':
1124 {
1125 $classNameFilter = eZContentClassName::sqlFilter();
1126 $filterField = $classNameFilter['nameField'];
1127 $filterFieldType = 'string';
1128 $filterSQL['from'] .= " INNER JOIN $classNameFilter[from] ON ($classNameFilter[where])";
1129 } break;
1130 case 'priority':
1131 {
1132 $filterField = 'ezcontentobject_tree.priority';
1133 } break;
1134 case 'name':
1135 {
1136 $filterField = 'ezcontentobject_name.name';
1137 $filterFieldType = 'string';
1138 } break;
1139 case 'owner':
1140 {
1141 $filterField = 'ezcontentobject.owner_id';
1142 } break;
1143 case 'visibility':
1144 {
1145 $filterValue = ( $filterValue == '1' ) ? 0 : 1;
1146 $filterField = 'ezcontentobject_tree.is_invisible';
1147 } break;
1148 default:
1149 {
1150 $useAttributeFilter = true;
1151 } break;
1152 }
1153
1154 if ( $useAttributeFilter )
1155 {
1156 if ( !is_numeric( $filterAttributeID ) )
1157 $filterAttributeID = eZContentObjectTreeNode::classAttributeIDByIdentifier( $filterAttributeID );
1158
1159 if ( $filterAttributeID === false )
1160 {
1161 $isFilterValid = false;
1162 if( $filterJoinType === 'AND' )
1163 {
1164 // go out
1165 $invalidAttributesFiltersCount = $totalAttributesFiltersCount;
1166 break;
1167 }
1168
1169 ++$invalidAttributesFiltersCount;
1170 }
1171 else
1172 {
1173 // Check datatype for filtering
1174 $filterDataType = eZContentObjectTreeNode::sortKeyByClassAttributeID( $filterAttributeID );
1175 if ( $filterDataType === false )
1176 {
1177 $isFilterValid = false;
1178 if( $filterJoinType === 'AND' )
1179 {
1180 // go out
1181 $invalidAttributesFiltersCount = $totalAttributesFiltersCount;
1182 break;
1183 }
1184
1185 // check next filter
1186 ++$invalidAttributesFiltersCount;
1187 }
1188 else
1189 {
1190 $sortKey = false;
1191 if ( $filterDataType == 'string' )
1192 {
1193 $sortKey = 'sort_key_string';
1194 $filterFieldType = 'string';
1195 }
1196 else
1197 {
1198 $sortKey = 'sort_key_int';
1199 }
1200
1201 $filterField = "a$filterCount.$sortKey";
1202
1203 // Use the same joins as we do when sorting,
1204 // if more attributes are filtered by we will append them
1205 if ( $filterCount >= $sortingInfo['attributeJoinCount'] )
1206 {
1207 $filterSQL['from'] .= " INNER JOIN ezcontentobject_attribute a$filterCount ON (a$filterCount.contentobject_id = ezcontentobject.id) ";
1208 }
1209
1210 // Ref http://issues.ez.no/19190
1211 // If language param is set, we must take it into account.
1212 if ( $language )
1213 {
1214 eZContentLanguage::setPrioritizedLanguages( $language );
1215 }
1216 $filterSQL['where'] .= "
1217 a$filterCount.contentobject_id = ezcontentobject.id AND
1218 a$filterCount.contentclassattribute_id = $filterAttributeID AND
1219 a$filterCount.version = ezcontentobject_name.content_version AND ";
1220 $filterSQL['where'] .= eZContentLanguage::sqlFilter( "a$filterCount", 'ezcontentobject' ). ' AND ';
1221 if ( $language )
1222 {
1223 eZContentLanguage::clearPrioritizedLanguages();
1224 }
1225 }
1226 }
1227 }
1228
1229 if ( $isFilterValid )
1230 {
1231 $hasFilterOperator = true;
1232 // Controls quotes around filter value, some filters do this manually
1233 $noQuotes = false;
1234 // Controls if $filterValue or $filter[2] is used, $filterValue is already escaped
1235 $unEscape = false;
1236
1237 switch ( $filterType )
1238 {
1239 case '=' :
1240 {
1241 $filterOperator = '=';
1242 }break;
1243
1244 case '!=' :
1245 {
1246 $filterOperator = '<>';
1247 }break;
1248
1249 case '>' :
1250 {
1251 $filterOperator = '>';
1252 }break;
1253
1254 case '<' :
1255 {
1256 $filterOperator = '<';
1257 }break;
1258
1259 case '<=' :
1260 {
1261 $filterOperator = '<=';
1262 }break;
1263
1264 case '>=' :
1265 {
1266 $filterOperator = '>=';
1267 }break;
1268
1269 case 'like':
1270 case 'not_like':
1271 {
1272 $filterOperator = ( $filterType == 'like' ? 'LIKE' : 'NOT LIKE' );
1273 // We escape the string ourselves, this MUST be done before wildcard replace
1274 $filter[2] = $db->escapeString( $filter[2] );
1275 $unEscape = true;
1276 // Since * is used as wildcard we need to transform the string to
1277 // use % as wildcard. The following rules apply:
1278 // - % -> \%
1279 // - * -> %
1280 // - \* -> *
1281 // - \\ -> \
1282
1283 $filter[2] = preg_replace( array( '#%#m',
1284 '#(?<!\\\\)\\*#m',
1285 '#(?<!\\\\)\\\\\\*#m',
1286 '#\\\\\\\\#m' ),
1287 array( '\\%',
1288 '%',
1289 '*',
1290 '\\\\' ),
1291 $filter[2] );
1292 } break;
1293
1294 case 'in':
1295 case 'not_in' :
1296 {
1297 $filterOperator = ( $filterType == 'in' ? 'IN' : 'NOT IN' );
1298 // Turn off quotes for value, we do this ourselves
1299 $noQuotes = true;
1300 if ( is_array( $filter[2] ) )
1301 {
1302 reset( $filter[2] );
1303 foreach ( $filter[2] as $key => $value )
1304 {
1305 // Non-numerics must be escaped to avoid SQL injection
1306 switch ( $filterFieldType )
1307 {
1308 case 'string':
1309 $filter[2][$key] = "'" . $db->escapeString( $value ) . "'";
1310 break;
1311 case 'integer':
1312 default:
1313 $filter[2][$key] = (int) $value;
1314 }
1315 }
1316 $filterValue = '(' . implode( ",", $filter[2] ) . ')';
1317 }
1318 else
1319 {
1320 $hasFilterOperator = false;
1321 }
1322 } break;
1323
1324 case 'between':
1325 case 'not_between' :
1326 {
1327 $filterOperator = ( $filterType == 'between' ? 'BETWEEN' : 'NOT BETWEEN' );
1328 // Turn off quotes for value, we do this ourselves
1329 $noQuotes = true;
1330 if ( is_array( $filter[2] ) )
1331 {
1332 // Check for non-numerics to avoid SQL injection
1333 if ( !is_numeric( $filter[2][0] ) )
1334 $filter[2][0] = "'" . $db->escapeString( $filter[2][0] ) . "'";
1335 if ( !is_numeric( $filter[2][1] ) )
1336 $filter[2][1] = "'" . $db->escapeString( $filter[2][1] ) . "'";
1337
1338 $filterValue = $filter[2][0] . ' AND ' . $filter[2][1];
1339 }
1340 } break;
1341
1342 default :
1343 {
1344 $hasFilterOperator = false;
1345 eZDebug::writeError( "Unknown attribute filter type: $filterType", __METHOD__ );
1346 }break;
1347
1348 }
1349 if ( $hasFilterOperator )
1350 {
1351 if ( ( $filterCount - $sortingInfo['sortCount'] ) > 0 )
1352 $attibuteFilterJoinSQL .= " $filterJoinType ";
1353
1354 // If $unEscape is true we get the filter value from the 2nd element instead
1355 // which must have been escaped by filter type
1356 $filterValue = $unEscape ? $filter[2] : $filterValue;
1357
1358 $attibuteFilterJoinSQL .= "$filterField $filterOperator ";
1359 $attibuteFilterJoinSQL .= $noQuotes ? "$filterValue " : "'$filterValue' ";
1360
1361 $filterCount++;
1362 $justFilterCount++;
1363 }
1364 }
1365 } // end of 'foreach ( $filterArray as $filter )'
1366
1367 if ( $totalAttributesFiltersCount == $invalidAttributesFiltersCount )
1368 {
1369 eZDebug::writeNotice( "Attribute filter returned false" );
1370 $filterSQL = false;
1371 }
1372 else
1373 {
1374 if ( $justFilterCount > 0 )
1375 $filterSQL['where'] .= " ( " . $attibuteFilterJoinSQL . " ) AND ";
1376 }
1377 } // end of 'if ( is_array( $filterArray ) )'
1378 }
1379
1380 return $filterSQL;
1381 }
1382
1391 static function createNotEqParentSQLString( $nodeID, $depth = false, $depthOperator = 'le' )
1392 {
1393 $notEqParentString = '';
1394 if( !$depth || $depthOperator == 'le' || $depthOperator == 'lt' )
1395 {
1396 $notEqParentString = "ezcontentobject_tree.node_id != $nodeID AND";
1397 }
1398
1399 return $notEqParentString;
1400 }
1401
1411 static function createPathConditionSQLString( $nodePath, $nodeDepth, $depth = false, $depthOperator = 'le' )
1412 {
1413 $pathCondition = '';
1414 $depthCondition = '';
1415
1416 if ( $depth )
1417 {
1418 $sqlDepthOperator = '<=';
1419 if ( $depthOperator )
1420 {
1421 if ( $depthOperator == 'lt' )
1422 {
1423 $sqlDepthOperator = '<';
1424 }
1425 else if ( $depthOperator == 'gt' )
1426 {
1427 $sqlDepthOperator = '>';
1428 }
1429 else if ( $depthOperator == 'le' )
1430 {
1431 $sqlDepthOperator = '<=';
1432 }
1433 else if ( $depthOperator == 'ge' )
1434 {
1435 $sqlDepthOperator = '>=';
1436 }
1437 else if ( $depthOperator == 'eq' )
1438 {
1439 $sqlDepthOperator = '=';
1440 }
1441 }
1442
1443 $nodeDepth += $depth;
1444 $depthCondition = ' ezcontentobject_tree.depth '. $sqlDepthOperator . ' ' . $nodeDepth . ' and ';
1445 }
1446
1447 $pathCondition = " ezcontentobject_tree.path_string like '$nodePath%' and $depthCondition ";
1448 return $pathCondition;
1449 }
1450
1462 static function createPathConditionAndNotEqParentSQLStrings( &$outPathConditionStr, &$outNotEqParentStr, $nodeID, $depth = false, $depthOperator = 'le' )
1463 {
1464 if ( !$depthOperator )
1465 {
1466 $depthOperator = 'le';
1467 }
1468
1469 // check if we are only fetching children
1470 // - depth (lower than or) eqaul to 1
1471 // - depth lower than 2 = depth equal to 1
1472 $onlyChildren = ( $depth === 1 && ( $depthOperator === 'le' || $depthOperator === 'eq' ) ) ||
1473 ( $depth === 2 && $depthOperator === 'lt' );
1474
1475 if ( is_array( $nodeID ) && count( $nodeID ) == 1 )
1476 {
1477 $nodeID = $nodeID[0];
1478 }
1479
1480 if ( is_array( $nodeID ) )
1481 {
1482 $outNotEqParentStr = '';
1483
1484 // a parent_node_id condition suffits when only fetching children
1485 if ( $onlyChildren )
1486 {
1487 $db = eZDB::instance();
1488 $outPathConditionStr = $db->generateSQLINStatement( $nodeID, 'ezcontentobject_tree.parent_node_id', false, true, 'int' ) . ' and';
1489 }
1490 else
1491 {
1492 $nodeIDList = $nodeID;
1493 $sqlPartForOneNodeList = array();
1494
1495 foreach ( $nodeIDList as $nodeID )
1496 {
1497 $node = eZContentObjectTreeNode::fetch( $nodeID, false, false );
1498 if ( !is_array( $node ) )
1499 return false;
1500
1501 $nodePath = $node['path_string'];
1502 $nodeDepth = $node['depth'];
1503 $depthCond = '';
1504 if ( $depth )
1505 {
1506 $sqlDepthOperator = '<=';
1507 if ( $depthOperator )
1508 {
1509 if ( $depthOperator == 'lt' )
1510 {
1511 $sqlDepthOperator = '<';
1512 }
1513 else if ( $depthOperator == 'gt' )
1514 {
1515 $sqlDepthOperator = '>';
1516 }
1517 else if ( $depthOperator == 'le' )
1518 {
1519 $sqlDepthOperator = '<=';
1520 }
1521 else if ( $depthOperator == 'ge' )
1522 {
1523 $sqlDepthOperator = '>=';
1524 }
1525 else if ( $depthOperator == 'eq' )
1526 {
1527 $sqlDepthOperator = '=';
1528 }
1529 }
1530 $nodeDepth += $depth;
1531 $depthCond = ' and ezcontentobject_tree.depth '. $sqlDepthOperator . ' ' . $nodeDepth . ' ';
1532 }
1533
1534 $requireNotEqParentStr = !$depth || $depthOperator == 'le' || $depthOperator == 'lt';
1535 $notEqParentStr = $requireNotEqParentStr ? " and ezcontentobject_tree.node_id != $nodeID " : '';
1536 $sqlPartForOneNodeList[] = " ( ezcontentobject_tree.path_string like '$nodePath%' $depthCond $notEqParentStr ) ";
1537 }
1538 $outPathConditionStr = implode( ' or ', $sqlPartForOneNodeList );
1539 $outPathConditionStr = ' (' . $outPathConditionStr . ') and';
1540 }
1541 }
1542 else
1543 {
1544 if ( $nodeID == 0 )
1545 {
1546 return false;
1547 }
1548
1549 // a parent_node_id condition suffits when only fetching children
1550 if ( $onlyChildren )
1551 {
1552 $outNotEqParentStr = '';
1553 $outPathConditionStr = 'ezcontentobject_tree.parent_node_id = ' . (int) $nodeID . ' and';
1554 }
1555 else
1556 {
1557 $node = eZContentObjectTreeNode::fetch( $nodeID, false, false );
1558 if ( !is_array( $node ) )
1559 return false;
1560
1561 $nodePath = $node['path_string'];
1562 $nodeDepth = $node['depth'];
1563
1564 $outNotEqParentStr = eZContentObjectTreeNode::createNotEqParentSQLString( $nodeID, $depth, $depthOperator );
1565 $outPathConditionStr = eZContentObjectTreeNode::createPathConditionSQLString( $nodePath, $nodeDepth, $depth, $depthOperator );
1566 }
1567 }
1568
1569 return true;
1570 }
1571
1575 static function createGroupBySQLStrings( &$outGroupBySelectText, &$outGroupByText, $groupBy )
1576 {
1577 if ( $groupBy )
1578 {
1579 if ( isset( $groupBy['field'] ) and isset( $groupBy['type'] ) )
1580 {
1581 $groupByField = $groupBy['field'];
1582 $groupByFieldType = $groupBy['type'];
1583
1584 switch ( $groupByField )
1585 {
1586 case 'published':
1587 {
1588 $groupBySelect = eZContentObjectTreeNode::subTreeGroupByDateField( "ezcontentobject." . $groupByField, $groupByFieldType );
1589 $groupBySelect['field'] = "ezcontentobject." . $groupByField;
1590 } break;
1591 case 'modified':
1592 {
1593 $groupBySelect = eZContentObjectTreeNode::subTreeGroupByDateField( "ezcontentobject." . $groupByField, $groupByFieldType );
1594 $groupBySelect['field'] = "ezcontentobject." . $groupByField;
1595 } break;
1596 }
1597
1598 $outGroupBySelectText = ", " . $groupBySelect['select'];
1599 $outGroupByText = "GROUP BY " . $groupBySelect['group_field'];
1600 }
1601 }
1602 }
1603
1607 static function createVersionNameTablesSQLString( $useVersionName )
1608 {
1609 eZDebug::writeStrict( 'Method ' . __METHOD__ . ' has been deprecated in 5.0', 'Deprecation' );
1610
1611 $versionNameTables = '';
1612
1613 if ( $useVersionName )
1614 {
1615 $versionNameTables = ' INNER JOIN ezcontentobject_name ';
1616 }
1617
1618 return $versionNameTables;
1619 }
1620
1624 static function createVersionNameTargetsSQLString( $useVersionName )
1625 {
1626 eZDebug::writeStrict( 'Method ' . __METHOD__ . ' has been deprecated in 5.0', 'Deprecation' );
1627
1628 $versionNameTargets = '';
1629
1630 if ( $useVersionName )
1631 {
1632 $versionNameTargets = ', ezcontentobject_name.name as name, ezcontentobject_name.real_translation ';
1633 }
1634
1635 return $versionNameTargets;
1636 }
1637
1641 static function createVersionNameJoinsSQLString( $useVersionName, $includeAnd = true, $onlyTranslated = false, $lang = false, $treeTableName = 'ezcontentobject_tree' )
1642 {
1643 eZDebug::writeStrict( 'Method ' . __METHOD__ . ' has been deprecated in 5.0', 'Deprecation' );
1644
1645 $versionNameJoins = '';
1646 if ( $useVersionName )
1647 {
1648 if ( $includeAnd )
1649 {
1650 $versionNameJoins .= ' AND ';
1651 }
1652 $versionNameJoins .= " $treeTableName.contentobject_id = ezcontentobject_name.contentobject_id and
1653 $treeTableName.contentobject_version = ezcontentobject_name.content_version and ";
1654 $versionNameJoins .= eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' );
1655 }
1656 return $versionNameJoins;
1657 }
1658
1662 static function createPermissionCheckingSQL( $limitationList, $treeTableName = 'ezcontentobject_tree', $tableAliasName = 'ezcontentobject_tree' )
1663 {
1664 $db = eZDB::instance();
1665
1666 $sqlPermissionCheckingFrom = '';
1667 $sqlPermissionCheckingWhere = '';
1668 $sqlPermissionTempTables = array();
1669 $groupPermTempTable = false;
1670 $createdStateAliases = array();
1671
1672 if ( is_array( $limitationList ) && count( $limitationList ) > 0 )
1673 {
1674 $sqlParts = array();
1675 foreach( $limitationList as $limitationArray )
1676 {
1677 $sqlPartPart = array();
1678 $sqlPartPartPart = array();
1679 $sqlPlacementPart = array();
1680
1681 foreach ( array_keys( $limitationArray ) as $ident )
1682 {
1683 switch( $ident )
1684 {
1685 case 'Class':
1686 {
1687 $sqlPartPart[] = 'ezcontentobject.contentclass_id in (' . implode( ', ', $limitationArray[$ident] ) . ')';
1688 } break;
1689
1690 case 'Section':
1691 case 'User_Section':
1692 {
1693 $sqlPartPart[] = 'ezcontentobject.section_id in (' . implode( ', ', $limitationArray[$ident] ) . ')';
1694 } break;
1695
1696 case 'Owner':
1697 {
1698 $user = eZUser::currentUser();
1699 $userID = $user->attribute( 'contentobject_id' );
1700 $sqlPartPart[] = "ezcontentobject.owner_id = '" . $db->escapeString( $userID ) . "'";
1701 } break;
1702
1703 case 'Group':
1704 {
1705 if ( !$groupPermTempTable )
1706 {
1707 $user = eZUser::currentUser();
1708 $userContentObject = $user->attribute( 'contentobject' );
1709 $parentList = $userContentObject->attribute( 'parent_nodes' );
1710
1711 $groupPermTempTable = $db->generateUniqueTempTableName( 'ezgroup_perm_tmp_%' );
1712 $sqlPermissionTempTables[] = $groupPermTempTable;
1713
1714 $db->createTempTable( "CREATE TEMPORARY TABLE $groupPermTempTable ( user_id int NOT NULL PRIMARY KEY )" );
1715 $db->query( "INSERT INTO $groupPermTempTable
1716 SELECT DISTINCT contentobject_id AS user_id
1717 FROM ezcontentobject_tree
1718 WHERE parent_node_id IN (" . implode( ', ', $parentList ) . ')',
1719 eZDBInterface::SERVER_SLAVE );
1720
1721 $sqlPermissionCheckingFrom .= " LEFT JOIN $groupPermTempTable ON $groupPermTempTable.user_id = ezcontentobject.owner_id";
1722 }
1723 $sqlPartPart[] = "ezcontentobject.owner_id = $groupPermTempTable.user_id";
1724 } break;
1725
1726 case 'Node':
1727 {
1728 $sqlPlacementPart[] = $tableAliasName . '.node_id in (' . implode( ', ', $limitationArray[$ident] ) . ')';
1729 } break;
1730
1731 case 'Subtree':
1732 {
1733 $sqlSubtreePart = array();
1734 foreach ( $limitationArray[$ident] as $limitationPathString )
1735 {
1736 $safePathString = $db->escapeString( $limitationPathString );
1737 $sqlSubtreePart[] = "$tableAliasName.path_string like '$safePathString%'";
1738 }
1739 $sqlPlacementPart[] = implode( ' OR ', $sqlSubtreePart );
1740 } break;
1741
1742 case 'User_Subtree':
1743 {
1744 $sqlPartUserSubtree = array();
1745 foreach ( $limitationArray[$ident] as $limitationPathString )
1746 {
1747 $safePathString = $db->escapeString( $limitationPathString );
1748 $sqlPartUserSubtree[] = "$tableAliasName.path_string like '$safePathString%'";
1749 }
1750 $sqlPartPart[] = implode( ' OR ', $sqlPartUserSubtree );
1751 } break;
1752
1753 default:
1754 {
1755 if ( strncmp( $ident, 'StateGroup_', 11 ) === 0 )
1756 {
1757 $stateIdentifier = substr( $ident, 11 );
1758
1759 if ( !isset( $createdStateAliases[$stateIdentifier] ) )
1760 {
1761 $stateIndex = count( $createdStateAliases );
1762 }
1763 else
1764 {
1765 $stateIndex = $createdStateAliases[$stateIdentifier];
1766 }
1767 $stateTable = "ezcobj_state_{$stateIndex}_perm";
1768
1769 if ( !isset( $createdStateAliases[$stateIdentifier] ) )
1770 {
1771 $createdStateAliases[$stateIdentifier] = $stateIndex;
1772 $stateLinkTable = "ezcobj_state_lnk_{$stateIndex}_perm";
1773 $stateGroupTable = "ezcobj_state_grp_{$stateIndex}_perm";
1774 $stateAliasTables[$stateIdentifier] = $stateTable;
1775
1776 $sqlPermissionCheckingFrom .=
1777 " INNER JOIN ezcobj_state_link $stateLinkTable ON ($stateLinkTable.contentobject_id = ezcontentobject.id) " .
1778 " INNER JOIN ezcobj_state_group $stateGroupTable ON ($stateGroupTable.identifier = '" . $db->escapeString( $stateIdentifier ) . "') " .
1779 " INNER JOIN ezcobj_state $stateTable ON ($stateTable.id = $stateLinkTable.contentobject_state_id AND $stateTable.group_id = $stateGroupTable.id) ";
1780 }
1781
1782 if ( count( $limitationArray[$ident] ) > 1 )
1783 {
1784 $sqlPartPart[] = $db->generateSQLINStatement( $limitationArray[$ident], "$stateTable.id" );
1785 }
1786 else
1787 {
1788 $sqlPartPart[] = "$stateTable.id = " . $limitationArray[$ident][0];
1789 }
1790 }
1791 }
1792 }
1793 }
1794 if ( $sqlPlacementPart )
1795 {
1796 $sqlPartPart[] = '( ( ' . implode( ' ) OR ( ', $sqlPlacementPart ) . ' ) )';
1797 }
1798 if ( $sqlPartPartPart )
1799 {
1800 $sqlPartPart[] = '( ' . implode( ' ) OR ( ', $sqlPartPartPart ) . ' )';
1801 }
1802 $sqlParts[] = implode( ' AND ', $sqlPartPart );
1803 }
1804 $sqlPermissionCheckingWhere .= ' AND ((' . implode( ") OR (", $sqlParts ) . ')) ';
1805 }
1806
1807 $sqlPermissionChecking = array( 'from' => $sqlPermissionCheckingFrom,
1808 'where' => $sqlPermissionCheckingWhere,
1809 'temp_tables' => $sqlPermissionTempTables );
1810
1811 return $sqlPermissionChecking;
1812 }
1813
1814
1820 static function createNodesConditionSQLStringFromPath( $nodePath, $includingLastNodeInThePath, $limit = false )
1821 {
1822 $pathString = false;
1823 $pathArray = explode( '/', trim( $nodePath, '/' ) );
1824
1825 $pathArrayCount = count( $pathArray );
1826
1827 if ( $limit && $includingLastNodeInThePath == false )
1828 {
1829 $limit++;
1830 }
1831
1832 $sliceOffset = $limit && $pathArrayCount > $limit ? $pathArrayCount - $limit : 0;
1833 $sliceLength = $includingLastNodeInThePath ? $pathArrayCount - $sliceOffset : $pathArrayCount - ( $sliceOffset + 1 );
1834
1835 // only take a slice when necessary
1836 if ( ( $sliceOffset + $sliceLength ) < $pathArrayCount )
1837 {
1838 $pathArray = array_slice( $pathArray, $sliceOffset, $sliceLength );
1839 }
1840
1841 if ( $sliceLength == 1 )
1842 {
1843 $pathString = ' node_id = ' . implode( '', $pathArray ) . ' and ';
1844 }
1845 else if ( $sliceLength > 0 )
1846 {
1847 $db = eZDB::instance();
1848 $pathString = ' ' . $db->generateSQLINStatement( $pathArray, 'node_id' ) . ' and ';
1849 }
1850
1851 return $pathString;
1852 }
1853
1859 static function createShowInvisibleSQLString( $useSettings, $fetchHidden = true )
1860 {
1861 $showInvisibleNodesCond = '';
1862 $showInvisible = $fetchHidden;
1863
1864 if ( $useSettings )
1865 $showInvisible = eZContentObjectTreeNode::showInvisibleNodes();
1866
1867 if ( !$showInvisible )
1868 $showInvisibleNodesCond = 'AND ezcontentobject_tree.is_invisible = 0';
1869
1870 return $showInvisibleNodesCond;
1871 }
1872
1877 static function showInvisibleNodes()
1878 {
1879 static $cachedResult;
1880
1881 if ( !isset( $cachedResult ) )
1882 {
1883 $ini = eZINI::instance( 'site.ini' );
1884 $cachedResult = $ini->hasVariable( 'SiteAccessSettings', 'ShowHiddenNodes' ) ?
1885 $ini->variable( 'SiteAccessSettings', 'ShowHiddenNodes' ) == 'true' :
1886 true;
1887 }
1888
1889 return $cachedResult;
1890 }
1891
1895 static function getLimitationList( &$limitation )
1896 {
1897 // do not check currentUser if limitation is disabled
1898 if ( empty( $limitation ) && is_array( $limitation ) )
1899 {
1900 return $limitation;
1901 }
1902
1903 $currentUser = eZUser::currentUser();
1904 $currentUserID = $currentUser->attribute( 'contentobject_id' );
1905 $limitationList = array();
1906
1907 if ( $limitation !== false )
1908 {
1909 $limitationList = $limitation;
1910 }
1911 else if ( isset( $GLOBALS['ezpolicylimitation_list'][$currentUserID]['content']['read'] ) )
1912 {
1913 $limitationList =& $GLOBALS['ezpolicylimitation_list'][$currentUserID]['content']['read'];
1914 eZDebugSetting::writeDebug( 'kernel-content-treenode', $limitationList, "limitation list" );
1915 }
1916 else
1917 {
1918 $accessResult = $currentUser->hasAccessTo( 'content', 'read' );
1919
1920 if ( $accessResult['accessWord'] == 'no' )
1921 {
1922 $limitationList = false;
1923 $GLOBALS['ezpolicylimitation_list'][$currentUserID]['content']['read'] = false;
1924 }
1925 else if ( $accessResult['accessWord'] == 'limited' )
1926 {
1927 $limitationList = $accessResult['policies'];
1928 $GLOBALS['ezpolicylimitation_list'][$currentUserID]['content']['read'] = $accessResult['policies'];
1929 }
1930 }
1931
1932 return $limitationList;
1933 }
1934
1940 static function subTreeByNodeID( $params = false, $nodeID = 0 )
1941 {
1942 if ( !is_numeric( $nodeID ) and !is_array( $nodeID ) )
1943 {
1944 return null;
1945 }
1946
1947 if ( $params === false )
1948 {
1949 $params = array( 'Depth' => false,
1950 'Offset' => false,
1951 //'OnlyTranslated' => false,
1952 'Language' => false,
1953 'Limit' => false,
1954 'SortBy' => false,
1955 'AttributeFilter' => false,
1956 'ExtendedAttributeFilter' => false,
1957 'ClassFilterType' => false,
1958 'ClassFilterArray' => false,
1959 'GroupBy' => false );
1960 }
1961
1962 $offset = ( isset( $params['Offset'] ) && is_numeric( $params['Offset'] ) ) ? $params['Offset'] : false;
1963 //$onlyTranslated = ( isset( $params['OnlyTranslated'] ) ) ? $params['OnlyTranslated'] : false;
1964 $language = ( isset( $params['Language'] ) ) ? $params['Language'] : false;
1965 $limit = ( isset( $params['Limit'] ) && is_numeric( $params['Limit'] ) ) ? $params['Limit'] : false;
1966 $depth = ( isset( $params['Depth'] ) && is_numeric( $params['Depth'] ) ) ? $params['Depth'] : false;
1967 $depthOperator = ( isset( $params['DepthOperator'] ) ) ? $params['DepthOperator'] : false;
1968 $asObject = ( isset( $params['AsObject'] ) ) ? $params['AsObject'] : true;
1969 $loadDataMap = ( isset( $params['LoadDataMap'] ) ) ? $params['LoadDataMap'] : false;
1970 $groupBy = ( isset( $params['GroupBy'] ) ) ? $params['GroupBy'] : false;
1971 $mainNodeOnly = ( isset( $params['MainNodeOnly'] ) ) ? $params['MainNodeOnly'] : false;
1972 $ignoreVisibility = ( isset( $params['IgnoreVisibility'] ) ) ? $params['IgnoreVisibility'] : false;
1973 $objectNameFilter = ( isset( $params['ObjectNameFilter'] ) ) ? $params['ObjectNameFilter'] : false;
1974
1975 if ( $offset < 0 )
1976 {
1977 $offset = abs( $offset );
1978 }
1979
1980 if ( !isset( $params['SortBy'] ) )
1981 $params['SortBy'] = false;
1982 if ( !isset( $params['ClassFilterType'] ) )
1983 $params['ClassFilterType'] = false;
1984
1985 $allowCustomSorting = false;
1986 if ( isset( $params['ExtendedAttributeFilter'] ) && is_array ( $params['ExtendedAttributeFilter'] ) )
1987 {
1988 $allowCustomSorting = true;
1989 }
1990
1991 $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $params['SortBy'], 'ezcontentobject_tree', $allowCustomSorting );
1992 $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString( $params['ClassFilterType'], $params['ClassFilterArray'] );
1993 if ( $classCondition === false )
1994 {
1995 eZDebug::writeNotice( "Class filter returned false" );
1996 return null;
1997 }
1998
1999 $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings( $params['AttributeFilter'], $sortingInfo, $language );
2000 if ( $attributeFilter === false )
2001 {
2002 return null;
2003 }
2004 $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings( $params['ExtendedAttributeFilter'] );
2005 $mainNodeOnlyCond = eZContentObjectTreeNode::createMainNodeConditionSQLString( $mainNodeOnly );
2006
2007 $pathStringCond = '';
2008 $notEqParentString = '';
2009 // If the node(s) doesn't exist we return null.
2010 if ( !eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator ) )
2011 {
2012 return null;
2013 }
2014
2015 if ( $language )
2016 {
2017 if ( !is_array( $language ) )
2018 {
2019 $language = array( $language );
2020 }
2021 // This call must occur after eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings,
2022 // because the parent node may not exist in Language
2023 eZContentLanguage::setPrioritizedLanguages( $language );
2024 }
2025
2026 $groupBySelectText = '';
2027 $groupBySQL = $extendedAttributeFilter['group_by'];
2028 if ( !$groupBySQL )
2029 {
2030 eZContentObjectTreeNode::createGroupBySQLStrings( $groupBySelectText, $groupBySQL, $groupBy );
2031 }
2032 else if ( $groupBy )
2033 {
2034 eZDebug::writeError( "Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__ );
2035 }
2036
2037 $languageFilter = eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );
2038 $objectNameLanguageFilter = eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' );
2039
2040 if ( $language )
2041 {
2042 eZContentLanguage::clearPrioritizedLanguages();
2043 }
2044 $objectNameFilterSQL = eZContentObjectTreeNode::createObjectNameFilterConditionSQLString( $objectNameFilter );
2045
2046 $limitation = ( isset( $params['Limitation'] ) && is_array( $params['Limitation'] ) ) ? $params['Limitation']: false;
2047 $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
2048 $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );
2049
2050 // Determine whether we should show invisible nodes.
2051 $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( !$ignoreVisibility );
2052
2053 $query = "SELECT DISTINCT " .
2054 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
2055 "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, ezcontentobject.section_id, ezcontentobject.status, " .
2056 "ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, ezcontentobject_tree.depth, " .
2057 "ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, ezcontentobject_tree.node_id, " .
2058 "ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, ezcontentobject_tree.priority, " .
2059 "ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, " .
2060 "ezcontentclass.identifier as class_identifier, ezcontentclass.is_container as is_container $groupBySelectText, ezcontentobject_name.name, ezcontentobject_name.real_translation " .
2061 $sortingInfo["attributeTargetSQL"] . " " . $extendedAttributeFilter["columns"] . " " .
2062 "FROM " .
2063 "ezcontentobject_tree " .
2064 "INNER JOIN ezcontentobject ON (ezcontentobject_tree.contentobject_id = ezcontentobject.id) " .
2065 "INNER JOIN ezcontentclass ON (ezcontentclass.version = 0 AND ezcontentclass.id = ezcontentobject.contentclass_id) " .
2066 "INNER JOIN ezcontentobject_name ON ( " .
2067 " ezcontentobject_tree.contentobject_id = ezcontentobject_name.contentobject_id AND " .
2068 " ezcontentobject_tree.contentobject_version = ezcontentobject_name.content_version " .
2069 ") " .
2070 "$sortingInfo[attributeFromSQL] $attributeFilter[from] $extendedAttributeFilter[tables] $sqlPermissionChecking[from] " .
2071 "WHERE " .
2072 "$pathStringCond " .
2073 "$extendedAttributeFilter[joins] " .
2074 "$sortingInfo[attributeWhereSQL] " .
2075 "$attributeFilter[where] " .
2076 "$notEqParentString " .
2077 "$mainNodeOnlyCond " .
2078 "$classCondition " .
2079 "$objectNameLanguageFilter " .
2080 "$showInvisibleNodesCond " .
2081 "$sqlPermissionChecking[where] " .
2082 "$objectNameFilterSQL AND " .
2083 "$languageFilter " .
2084 $groupBySQL;
2085
2086 if ( $sortingInfo['sortingFields'] )
2087 $query .= " ORDER BY $sortingInfo[sortingFields]";
2088
2089 $db = eZDB::instance();
2090
2091 $server = count( $sqlPermissionChecking['temp_tables'] ) > 0 ? eZDBInterface::SERVER_SLAVE : false;
2092
2093 $nodeListArray = $db->arrayQuery( $query, array( 'offset' => $offset,
2094 'limit' => $limit ),
2095 $server );
2096
2097 if ( $asObject )
2098 {
2099 $retNodeList = eZContentObjectTreeNode::makeObjectsArray( $nodeListArray, true, null, $language );
2100 if ( $loadDataMap === true )
2101 eZContentObject::fillNodeListAttributes( $retNodeList );
2102 else if ( $loadDataMap && is_numeric( $loadDataMap ) && $loadDataMap >= count( $retNodeList ) )
2103 eZContentObject::fillNodeListAttributes( $retNodeList );
2104 }
2105 else
2106 {
2107 $retNodeList = $nodeListArray;
2108 }
2109
2110 // cleanup temp tables
2111 $db->dropTempTableList( $sqlPermissionChecking['temp_tables'] );
2112
2113 return $retNodeList;
2114 }
2115
2120 function subTree( $params = false )
2121 {
2122 return eZContentObjectTreeNode::subTreeByNodeID( $params, $this->attribute( 'node_id' ) );
2123 }
2124
2157 static function subTreeMultiPaths( $nodesParams, $listParams = NULL )
2158 {
2159 if( !is_array( $nodesParams ) || !count( $nodesParams ) )
2160 {
2161 eZDebug::writeWarning( __METHOD__.': Nodes parameter must be an array with at least one key.' );
2162 return null;
2163 }
2164
2165 if( $listParams === null )
2166 {
2167 $listParams = array(
2168 'SortBy' => false,
2169 'Offset' => false,
2170 'Limit' => false,
2171 'GroupBy' => false );
2172 }
2173
2174 $offset = ( isset( $listParams['Offset'] ) && is_numeric( $listParams['Offset'] ) ) ? $listParams['Offset'] : false;
2175 $limit = ( isset( $listParams['Limit'] ) && is_numeric( $listParams['Limit'] ) ) ? $listParams['Limit'] : false;
2176 $groupBy = ( isset( $listParams['GroupBy'] ) ) ? $listParams['GroupBy'] : false;
2177 if ( !isset( $listParams['SortBy'] ) )
2178 {
2179 $listParams['SortBy'] = false;
2180 }
2181 $sortBy = $listParams['SortBy'];
2182
2183 $queryNodes = '';
2184
2185 foreach( $nodesParams as $nodeParams )
2186 {
2187 $nodeID = $nodeParams['ParentNodeID'];
2188
2189 if ( !is_numeric( $nodeID ) && !is_array( $nodeID ) )
2190 {
2191 eZDebug::writeWarning( __METHOD__.': Nodes parameter must be numeric or an array with numeric values.' );
2192 $retValue = null;
2193 return $retValue;
2194 }
2195
2196 if ( $nodeParams === null )
2197 {
2198 $nodeParams = array(
2199 'Depth' => false,
2200 //'OnlyTranslated' => false,
2201 'Language' => false,
2202 'AttributeFilter' => false,
2203 'ExtendedAttributeFilter' => false,
2204 'ClassFilterType' => false,
2205 'ClassFilterArray' => false );
2206 }
2207
2208 //$onlyTranslated = ( isset( $nodeParams['OnlyTranslated'] ) ) ? $nodeParams['OnlyTranslated'] : false;
2209 $language = ( isset( $nodeParams['Language'] ) ) ? $nodeParams['Language'] : false;
2210 $depth = ( isset( $nodeParams['Depth'] ) && is_numeric( $nodeParams['Depth'] ) ) ? $nodeParams['Depth'] : false;
2211 $depthOperator = ( isset( $nodeParams['DepthOperator'] ) ) ? $nodeParams['DepthOperator'] : false;
2212 $asObject = ( isset( $nodeParams['AsObject'] ) ) ? $nodeParams['AsObject'] : true;
2213 $mainNodeOnly = ( isset( $nodeParams['MainNodeOnly'] ) ) ? $nodeParams['MainNodeOnly'] : false;
2214 $ignoreVisibility = ( isset( $nodeParams['IgnoreVisibility'] ) ) ? $nodeParams['IgnoreVisibility'] : false;
2215 if ( !isset( $nodeParams['ClassFilterType'] ) )
2216 {
2217 $nodeParams['ClassFilterType'] = false;
2218 }
2219
2220 $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $sortBy );
2221 $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings( $nodeParams['AttributeFilter'], $sortingInfo, $language );
2222
2223 if ( $language )
2224 {
2225 if ( !is_array( $language ) )
2226 {
2227 $language = array( $language );
2228 }
2229 eZContentLanguage::setPrioritizedLanguages( $language );
2230 }
2231
2232 $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString( $nodeParams['ClassFilterType'], $nodeParams['ClassFilterArray'] );
2233 $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings( $nodeParams['ExtendedAttributeFilter'] );
2234 $mainNodeOnlyCond = eZContentObjectTreeNode::createMainNodeConditionSQLString( $mainNodeOnly );
2235
2236 $pathStringCond = '';
2237 $notEqParentString = '';
2238 // If the node(s) doesn't exist we return null.
2239
2240 if ( !eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator ) )
2241 {
2242 $retValue = null;
2243 return $retValue;
2244 }
2245
2246
2247 $languageFilter = ' AND ' . eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );
2248
2249 if ( $language )
2250 {
2251 eZContentLanguage::clearPrioritizedLanguages();
2252 }
2253
2254 $limitation = ( isset( $nodeParams['Limitation'] ) && is_array( $nodeParams['Limitation'] ) ) ? $nodeParams['Limitation']: false;
2255 $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
2256 $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );
2257
2258 // Determine whether we should show invisible nodes.
2259 $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( !$ignoreVisibility );
2260
2261 $queryNodes .= " (
2262 $pathStringCond
2263 $extendedAttributeFilter[joins]
2264 $sortingInfo[attributeWhereSQL]
2265 $attributeFilter[where]
2266 ezcontentclass.version=0 AND
2267 $notEqParentString
2268 $mainNodeOnlyCond
2269 $classCondition
2270 " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . "
2271 $showInvisibleNodesCond
2272 $sqlPermissionChecking[where]
2273 $languageFilter
2274 )
2275 OR";
2276 }
2277
2278 $groupBySelectText = '';
2279 $groupBySQL = $extendedAttributeFilter['group_by'];
2280 if ( !$groupBySQL )
2281 {
2282 eZContentObjectTreeNode::createGroupBySQLStrings( $groupBySelectText, $groupBySQL, $groupBy );
2283 }
2284 else if ( $groupBy )
2285 {
2286 eZDebug::writeError( "Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__ );
2287 }
2288
2289 $query = "SELECT DISTINCT " .
2290 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
2291 "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, " .
2292 "ezcontentobject.section_id, ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, " .
2293 "ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, " .
2294 "ezcontentobject_tree.node_id, ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, " .
2295 "ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, " .
2296 "ezcontentclass.identifier as class_identifier, ezcontentclass.is_container $groupBySelectText, ezcontentobject_name.name, ezcontentobject_name.real_translation " .
2297 "$sortingInfo[attributeTargetSQL], $nodeParams[ResultID] AS resultid " .
2298 "FROM ezcontentobject_tree " .
2299 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
2300 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " .
2301 "INNER JOIN ezcontentobject_name ON ( " .
2302 " ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND " .
2303 " ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version " .
2304 ") " .
2305 "$sortingInfo[attributeFromSQL] " .
2306 "$attributeFilter[from] " .
2307 "$extendedAttributeFilter[tables] " .
2308 "$sqlPermissionChecking[from] " .
2309 "WHERE " .
2310 substr( $queryNodes, 0, -2 ) . " " .
2311 $groupBySQL;
2312
2313 if ( $sortingInfo['sortingFields'] )
2314 {
2315 $query .= " ORDER BY $sortingInfo[sortingFields]";
2316 }
2317
2318 $db = eZDB::instance();
2319
2320 $server = count( $sqlPermissionChecking['temp_tables'] ) > 0 ? eZDBInterface::SERVER_SLAVE : false;
2321
2322 if ( !$offset && !$limit )
2323 {
2324 $nodeListArray = $db->arrayQuery( $query, array(), $server );
2325 }
2326 else
2327 {
2328 $nodeListArray = $db->arrayQuery( $query, array( 'offset' => $offset,
2329 'limit' => $limit ),
2330 $server );
2331 }
2332
2333 if ( $asObject )
2334 {
2335 $retNodeList = eZContentObjectTreeNode::makeObjectsArray( $nodeListArray, true, null, $language );
2336 }
2337 else
2338 {
2339 $retNodeList = $nodeListArray;
2340 }
2341
2342 // cleanup temp tables
2343 $db->dropTempTableList( $sqlPermissionChecking['temp_tables'] );
2344
2345 return $retNodeList;
2346 }
2347
2348 static function subTreeGroupByDateField( $field, $type )
2349 {
2350 $divisor = 0;
2351 switch ( $type )
2352 {
2353 case 'year':
2354 {
2355 $divisor = 60*60*24*365;
2356 } break;
2357 case 'week':
2358 {
2359 $divisor = 60*60*24*7;
2360 } break;
2361 case 'day':
2362 {
2363 $divisor = 60*60*24;
2364 } break;
2365 case 'hour':
2366 {
2367 $divisor = 60*60;
2368 } break;
2369 case 'minute':
2370 {
2371 $divisor = 60;
2372 } break;
2373 case 'second':
2374 {
2375 $divisor = 0;
2376 } break;
2377 default:
2378 {
2379 eZDebug::writeError( "Unknown field type $type", __METHOD__ );
2380 }
2381 }
2382 if ( $divisor > 0 )
2383 $text = "( $field / $divisor ) AS groupbyfield";
2384 else
2385 $text = "$field AS groupbyfield";
2386 return array( 'select' => $text,
2387 'group_field' => "( $field / $divisor )" );
2388 }
2389
2390
2394 static function subTreeCountByNodeID( $params, $nodeID )
2395 {
2396 if ( !is_numeric( $nodeID ) and !is_array( $nodeID ) )
2397 {
2398 return null;
2399 }
2400
2401 $language = ( isset( $params['Language'] ) ) ? $params['Language'] : false;
2402
2403 if ( $language )
2404 {
2405 if ( !is_array( $language ) )
2406 {
2407 $language = array( $language );
2408 }
2409 eZContentLanguage::setPrioritizedLanguages( $language );
2410 }
2411
2412 $depth = isset( $params['Depth'] ) && is_numeric( $params['Depth'] ) ? $params['Depth'] : false;
2413 $depthOperator = isset( $params['DepthOperator'] ) ? $params['DepthOperator'] : false;
2414
2415 $pathStringCond = '';
2416 $notEqParentString = '';
2417 // If the node(s) doesn't exist we return null.
2418 if ( !eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator ) )
2419 {
2420 return null;
2421 }
2422
2423 $db = eZDB::instance();
2424 $ini = eZINI::instance();
2425
2426 // Check for class filtering
2427 $classCondition = '';
2428
2429 if ( isset( $params['ClassFilterType'] ) and isset( $params['ClassFilterArray'] ) and is_array( $params['ClassFilterArray'] ) and
2430 ( $params['ClassFilterType'] == 'include' or $params['ClassFilterType'] == 'exclude' )
2431 and count( $params['ClassFilterArray'] ) > 0 )
2432 {
2433 $classCondition = ' ';
2434 $i = 0;
2435 $classCount = count( $params['ClassFilterArray'] );
2436 $classIDArray = array();
2437 foreach ( $params['ClassFilterArray'] as $classID )
2438 {
2439 $originalClassID = $classID;
2440 // Check if classes are recerenced by identifier
2441 if ( is_string( $classID ) && !is_numeric( $classID ) )
2442 {
2443 $classID = eZContentClass::classIDByIdentifier( $classID );
2444 }
2445 if ( is_numeric( $classID ) )
2446 {
2447 $classIDArray[] = $classID;
2448 }
2449 else
2450 {
2451 eZDebugSetting::writeWarning( 'kernel-content-class', "Invalid class identifier in subTree() classfilterarray, classID : " . $originalClassID );
2452 }
2453 }
2454 if ( count( $classIDArray ) > 0 )
2455 {
2456 $classCondition .= " ezcontentobject.contentclass_id ";
2457 if ( $params['ClassFilterType'] == 'include' )
2458 $classCondition .= " IN ";
2459 else
2460 $classCondition .= " NOT IN ";
2461
2462 $classIDString = implode( ', ', $classIDArray );
2463 $classCondition .= ' ( ' . $classIDString . ' ) AND';
2464 }
2465 }
2466
2467
2468 // Main node check
2469 $mainNodeOnlyCond = '';
2470 if ( isset( $params['MainNodeOnly'] ) && $params['MainNodeOnly'] === true )
2471 {
2472 $mainNodeOnlyCond = 'ezcontentobject_tree.node_id = ezcontentobject_tree.main_node_id AND';
2473 }
2474
2475 $languageFilter = ' AND '.eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );
2476 $objectNameLanguageFilter = eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' );
2477
2478 if ( $language )
2479 {
2480 eZContentLanguage::clearPrioritizedLanguages();
2481 }
2482 $objectNameFilter = ( isset( $params['ObjectNameFilter'] ) ) ? $params['ObjectNameFilter'] : false;
2483
2484 $attributeFilterParam = isset( $params['AttributeFilter'] ) ? $params['AttributeFilter'] : false;
2485 $sortingInfo = array( 'sortCount' => 0, 'attributeJoinCount' => 0 );
2486 $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings( $attributeFilterParam, $sortingInfo, $language );
2487 if ( $attributeFilter === false )
2488 {
2489 return null;
2490 }
2491 $objectNameFilterSQL = eZContentObjectTreeNode::createObjectNameFilterConditionSQLString( $objectNameFilter );
2492
2493 $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings( $params['ExtendedAttributeFilter'] );
2494
2495 // Determine whether we should show invisible nodes.
2496 $ignoreVisibility = isset( $params['IgnoreVisibility'] ) ? $params['IgnoreVisibility'] : false;
2497 $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( !$ignoreVisibility );
2498
2499 $limitation = ( isset( $params['Limitation'] ) && is_array( $params['Limitation'] ) ) ? $params['Limitation']: false;
2500 $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
2501 $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );
2502
2503 $query = "SELECT
2504 count( DISTINCT ezcontentobject_tree.node_id ) as count
2505 FROM
2506 ezcontentobject_tree
2507 INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id)
2508 INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)
2509 INNER JOIN ezcontentobject_name ON (
2510 ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND
2511 ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version
2512 )
2513 $attributeFilter[from]
2514 $extendedAttributeFilter[tables]
2515 $sqlPermissionChecking[from]
2516 WHERE $pathStringCond
2517 $extendedAttributeFilter[joins]
2518 $mainNodeOnlyCond
2519 $classCondition
2520 $attributeFilter[where]
2521 ezcontentclass.version=0 AND
2522 $notEqParentString
2523 $objectNameLanguageFilter
2524 $showInvisibleNodesCond
2525 $sqlPermissionChecking[where]
2526 $objectNameFilterSQL
2527 $languageFilter ";
2528
2529 $server = count( $sqlPermissionChecking['temp_tables'] ) > 0 ? eZDBInterface::SERVER_SLAVE : false;
2530
2531 $nodeListArray = $db->arrayQuery( $query, array(), $server );
2532
2533 // cleanup temp tables
2534 $db->dropTempTableList( $sqlPermissionChecking['temp_tables'] );
2535
2536 return $nodeListArray[0]['count'];
2537 }
2538
2544 function subTreeCount( $params = array() )
2545 {
2546 return eZContentObjectTreeNode::subTreeCountByNodeID( $params, $this->attribute( 'node_id' ) );
2547 }
2548
2552 static function calendar( $params = false, $nodeID = 0 )
2553 {
2554 if ( !is_numeric( $nodeID ) and !is_array( $nodeID ) )
2555 {
2556 return array();
2557 }
2558
2559 if ( $params === false )
2560 {
2561 $params = array( 'Depth' => false,
2562 'Offset' => false,
2563 'Limit' => false,
2564 'AttributeFilter' => false,
2565 'ExtendedAttributeFilter' => false,
2566 'ClassFilterType' => false,
2567 'ClassFilterArray' => false,
2568 'GroupBy' => false );
2569 }
2570
2571 $offset = ( isset( $params['Offset'] ) && is_numeric( $params['Offset'] ) ) ? $params['Offset'] : false;
2572 $limit = ( isset( $params['Limit'] ) && is_numeric( $params['Limit'] ) ) ? $params['Limit'] : false;
2573 $depth = ( isset( $params['Depth'] ) && is_numeric( $params['Depth'] ) ) ? $params['Depth'] : false;
2574 $depthOperator = ( isset( $params['DepthOperator'] ) ) ? $params['DepthOperator'] : false;
2575 $groupBy = ( isset( $params['GroupBy'] ) ) ? $params['GroupBy'] : false;
2576 $mainNodeOnly = ( isset( $params['MainNodeOnly'] ) ) ? $params['MainNodeOnly'] : false;
2577 $ignoreVisibility = ( isset( $params['IgnoreVisibility'] ) ) ? $params['IgnoreVisibility'] : false;
2578 if ( !isset( $params['ClassFilterType'] ) )
2579 $params['ClassFilterType'] = false;
2580
2581 $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString( $params['ClassFilterType'], $params['ClassFilterArray'] );
2582 $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings( $params['AttributeFilter'], $sortingInfo );
2583 $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings( $params['ExtendedAttributeFilter'] );
2584 $mainNodeOnlyCond = eZContentObjectTreeNode::createMainNodeConditionSQLString( $mainNodeOnly );
2585
2586 $pathStringCond = '';
2587 $notEqParentString = '';
2588 eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator );
2589
2590 $groupBySelectText = '';
2591 $groupBySQL = $extendedAttributeFilter['group_by'];
2592 if ( !$groupBySQL )
2593 {
2594 eZContentObjectTreeNode::createGroupBySQLStrings( $groupBySelectText, $groupBySQL, $groupBy );
2595 }
2596 else if ( $groupBy )
2597 {
2598 eZDebug::writeError( "Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__ );
2599 }
2600
2601 $limitation = ( isset( $params['Limitation'] ) && is_array( $params['Limitation'] ) ) ? $params['Limitation']: false;
2602 $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
2603 $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );
2604
2605 // Determine whether we should show invisible nodes.
2606 $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( !$ignoreVisibility );
2607
2608 $query = "SELECT DISTINCT
2609 ezcontentobject.published as published
2610 $groupBySelectText
2611 FROM
2612 ezcontentobject_tree
2613 INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id)
2614 INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)
2615 INNER JOIN ezcontentobject_name ON (
2616 ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND
2617 ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version
2618 )
2619
2620 $attributeFilter[from]
2621 $extendedAttributeFilter[tables]
2622 $sqlPermissionChecking[from]
2623 WHERE
2624 $pathStringCond
2625 $extendedAttributeFilter[joins]
2626 $attributeFilter[where]
2627 ezcontentclass.version = 0 AND
2628 $notEqParentString
2629 $mainNodeOnlyCond
2630 $classCondition
2631 " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . "
2632 $showInvisibleNodesCond
2633 $sqlPermissionChecking[where]
2634 $groupBySQL";
2635
2636
2637 $db = eZDB::instance();
2638
2639 $server = count( $sqlPermissionChecking['temp_tables'] ) > 0 ? eZDBInterface::SERVER_SLAVE : false;
2640
2641 if ( !$offset && !$limit )
2642 {
2643 $nodeListArray = $db->arrayQuery( $query, array(), $server );
2644 }
2645 else
2646 {
2647 $nodeListArray = $db->arrayQuery( $query, array( 'offset' => $offset,
2648 'limit' => $limit ),
2649 $server );
2650 }
2651
2652 // cleanup temp tables
2653 $db->dropTempTableList( $sqlPermissionChecking['temp_tables'] );
2654
2655 return $nodeListArray;
2656 }
2660 function childrenByName( $name )
2661 {
2662 $db = eZDB::instance();
2663
2664 return eZContentObjectTreeNode::makeObjectsArray(
2665 $db->arrayQuery(
2666 "SELECT " .
2667 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
2668 "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, " .
2669 "ezcontentobject.section_id, ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, " .
2670 "ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, " .
2671 "ezcontentobject_tree.node_id, ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, " .
2672 "ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, " .
2673 "ezcontentclass.serialized_name_list as class_serialized_name_list,ezcontentclass.identifier as class_identifier, ezcontentclass.is_container as is_container " .
2674 "FROM ezcontentobject_tree " .
2675 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
2676 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " .
2677 "WHERE path_string LIKE '" . $this->attribute( "path_string" ) . "%' AND " .
2678 "depth <= " . ( $this->Depth + 1 ) . " AND " .
2679 "ezcontentobject.name = '" . $db->escapeString( $name ) . "' AND " .
2680 "ezcontentclass.version = 0 AND " .
2681 "node_id != " . $this->attribute( "node_id" )
2682 ), true, array( "name" => $name )
2683 );
2684 }
2685
2691 function children()
2692 {
2693 return $this->subTree( array( 'Depth' => 1,
2694 'DepthOperator' => 'eq',
2695 'SortBy' => $this->sortArray() ) );
2696 }
2697
2703 function childrenCount( $checkPolicies = true )
2704 {
2705 $params = array( 'Depth' => 1,
2706 'DepthOperator' => 'eq' );
2707 if ( !$checkPolicies )
2708 $params['Limitation'] = array();
2709 return $this->subTreeCount( $params );
2710 }
2711
2715 function viewCount()
2716 {
2717 $count = eZViewCounter::fetch( $this->attribute( 'node_id' ), false );
2718 return (int) $count['count'];
2719 }
2720
2725 static function sortFieldName( $sortFieldID )
2726 {
2727 switch ( $sortFieldID )
2728 {
2729 default:
2730 eZDebug::writeWarning( 'Unknown sort field ID: ' . $sortFieldID, __METHOD__ );
2731 case self::SORT_FIELD_PATH:
2732 return 'path';
2733 case self::SORT_FIELD_PUBLISHED:
2734 return 'published';
2735 case self::SORT_FIELD_MODIFIED:
2736 return 'modified';
2737 case self::SORT_FIELD_SECTION:
2738 return 'section';
2739 case self::SORT_FIELD_DEPTH:
2740 return 'depth';
2741 case self::SORT_FIELD_CLASS_IDENTIFIER:
2742 return 'class_identifier';
2743 case self::SORT_FIELD_CLASS_NAME:
2744 return 'class_name';
2745 case self::SORT_FIELD_PRIORITY:
2746 return 'priority';
2747 case self::SORT_FIELD_NAME:
2748 return 'name';
2749 case self::SORT_FIELD_MODIFIED_SUBNODE:
2750 return 'modified_subnode';
2751 case self::SORT_FIELD_NODE_ID:
2752 return 'node_id';
2753 case self::SORT_FIELD_CONTENTOBJECT_ID:
2754 return 'contentobject_id';
2755 case self::SORT_FIELD_VISIBILITY:
2756 return 'is_invisible';
2757 }
2758 }
2759
2764 static function sortFieldID( $sortFieldName )
2765 {
2766 switch ( $sortFieldName )
2767 {
2768 default:
2769 eZDebug::writeWarning( 'Unknown sort field name: ' . $sortFieldName, __METHOD__ );
2770 case 'path':
2771 return self::SORT_FIELD_PATH;
2772 case 'published':
2773 return self::SORT_FIELD_PUBLISHED;
2774 case 'modified':
2775 return self::SORT_FIELD_MODIFIED;
2776 case 'section':
2777 return self::SORT_FIELD_SECTION;
2778 case 'depth':
2779 return self::SORT_FIELD_DEPTH;
2780 case 'class_identifier':
2781 return self::SORT_FIELD_CLASS_IDENTIFIER;
2782 case 'class_name':
2783 return self::SORT_FIELD_CLASS_NAME;
2784 case 'priority':
2785 return self::SORT_FIELD_PRIORITY;
2786 case 'name':
2787 return self::SORT_FIELD_NAME;
2788 case 'modified_subnode':
2789 return self::SORT_FIELD_MODIFIED_SUBNODE;
2790 case 'node_id':
2791 return self::SORT_FIELD_NODE_ID;
2792 case 'contentobject_id':
2793 return self::SORT_FIELD_CONTENTOBJECT_ID;
2794 case 'is_invisible':
2795 return self::SORT_FIELD_VISIBILITY;
2796 }
2797 }
2798
2804 function sortArray()
2805 {
2806 return eZContentObjectTreeNode::sortArrayBySortFieldAndSortOrder( $this->attribute( 'sort_field' ),
2807 $this->attribute( 'sort_order' ) );
2808 }
2809
2816 static function sortArrayBySortFieldAndSortOrder( $sortField, $sortOrder )
2817 {
2818 return array( array( eZContentObjectTreeNode::sortFieldName( $sortField ),
2819 $sortOrder ) );
2820 }
2821
2828 static function assignSectionToSubTree( $nodeID, $sectionID, $oldSectionID = false, $updateSearchIndexes = true )
2829 {
2830 $db = eZDB::instance();
2831 $node = eZContentObjectTreeNode::fetch( $nodeID );
2832
2833 $objectSimpleIDArray = eZContentObjectTreeNode::getObjectIdsInNodeSubTree($node);
2834 if ( !$objectSimpleIDArray )
2835 return;
2836
2837 $sectionID =(int) $sectionID;
2838
2839 // Who assigns which section at which node should be logged.
2840 $section = eZSection::fetch( $sectionID );
2841 $object = $node->object();
2842 eZAudit::writeAudit( 'section-assign', array( 'Section ID' => $sectionID, 'Section name' => $section->attribute( 'name' ),
2843 'Node ID' => $nodeID,
2844 'Content object ID' => $object->attribute( 'id' ),
2845 'Content object name' => $object->attribute( 'name' ),
2846 'Comment' => 'Assigned a section to the current node and all child objects: eZContentObjectTreeNode::assignSectionToSubTree()' ) );
2847
2848 $filterPart = '';
2849 if ( $oldSectionID !== false )
2850 {
2851 $oldSectionID =(int) $oldSectionID;
2852 $filterPart = " section_id = '$oldSectionID' and ";
2853 }
2854
2855 $db->begin();
2856 foreach ( array_chunk( $objectSimpleIDArray, 100 ) as $pagedObjectIDs )
2857 {
2858 $db->query( "UPDATE ezcontentobject SET section_id='$sectionID' WHERE $filterPart " . $db->generateSQLINStatement( $pagedObjectIDs, 'id', false, true, 'int' ) );
2859 if ( $updateSearchIndexes )
2860 {
2861 eZSearch::updateObjectsSection( $pagedObjectIDs, $sectionID );
2862 }
2863 }
2864 $db->commit();
2865
2866 // clear caches for updated objects
2867 eZContentObject::clearCache( $objectSimpleIDArray );
2868 }
2869
2882 static function updateMainNodeID( $mainNodeID, $objectID, $version, $parentMainNodeID, $updateSection = true )
2883 {
2884 $mainNodeID = (int)$mainNodeID;
2885 $parentMainNodeID = (int)$parentMainNodeID;
2886 $objectID = (int)$objectID;
2887 $version = (int)$version;
2888
2889 $db = eZDB::instance();
2890 $db->begin();
2891 $db->query( "UPDATE ezcontentobject_tree SET main_node_id=$mainNodeID WHERE contentobject_id=$objectID" );
2892 if ( !$version )
2893 {
2894 $rows = $db->arrayQuery( "SELECT current_version FROM ezcontentobject WHERE id=$objectID" );
2895 $version = $rows[0]['current_version'];
2896 }
2897 $db->query( "UPDATE eznode_assignment SET is_main=1 WHERE contentobject_id=$objectID AND contentobject_version=$version AND parent_node=$parentMainNodeID" );
2898 $db->query( "UPDATE eznode_assignment SET is_main=0 WHERE contentobject_id=$objectID AND contentobject_version=$version AND parent_node!=$parentMainNodeID" );
2899
2900 $contentObject = eZContentObject::fetch( $objectID );
2901 $parentContentObject = eZContentObject::fetchByNodeID( $parentMainNodeID );
2902 if ( $updateSection && $contentObject->attribute( 'section_id' ) != $parentContentObject->attribute( 'section_id' ) )
2903 {
2904 $newSectionID = $parentContentObject->attribute( 'section_id' );
2905 eZContentObjectTreeNode::assignSectionToSubTree( $mainNodeID, $newSectionID );
2906 }
2907
2908 $db->commit();
2909
2910 }
2911
2912 function fetchByCRC( $pathStr )
2913 {
2914 eZDebug::writeWarning( "Obsolete: use eZURLAlias instead", __METHOD__ );
2915 return null;
2916 }
2917
2918 static function fetchByContentObjectID( $contentObjectID, $asObject = true, $contentObjectVersion = false )
2919 {
2920 $conds = array( 'contentobject_id' => $contentObjectID );
2921 if ( $contentObjectVersion !== false )
2922 {
2923 $conds['contentobject_version'] = $contentObjectVersion;
2924 }
2925 return eZPersistentObject::fetchObjectList( eZContentObjectTreeNode::definition(),
2926 null,
2927 $conds,
2928 null,
2929 null,
2930 $asObject );
2931 }
2932
2933 static function fetchByRemoteID( $remoteID, $asObject = true )
2934 {
2935 return eZContentObjectTreeNode::fetch( false, false, $asObject, array( "remote_id" => $remoteID ) );
2936 }
2937
2938 static function fetchByPath( $pathString, $asObject = true )
2939 {
2940 return eZContentObjectTreeNode::fetch( false, false, $asObject, array( "path_string" => $pathString ) );
2941 }
2942
2943 static function fetchByURLPath( $pathString, $asObject = true )
2944 {
2945 if ( $pathString == "" )
2946 {
2947 eZDebug::writeWarning( 'Can not fetch, given URLPath is empty', __METHOD__ );
2948 return null;
2949 }
2950
2951 return eZContentObjectTreeNode::fetch( false, false, $asObject, array( "path_identification_string" => $pathString ) );
2952 }
2953
2961 static function fetchAliasesFromNodeList( $nodeList )
2962 {
2963 if ( !is_array( $nodeList ) || count( $nodeList ) < 1 )
2964 return array();
2965
2966 $db = eZDB::instance();
2967 $where = $db->generateSQLINStatement( $nodeList, 'node_id', false, false, 'int' );
2968 $query = "SELECT node_id, path_identification_string FROM ezcontentobject_tree WHERE $where";
2969 $pathListArray = $db->arrayQuery( $query );
2970 return $pathListArray;
2971 }
2972
2981 static function findMainNode( $objectID, $asObject = false )
2982 {
2983 $objectID = (int)$objectID;
2984 $query = "SELECT node_id
2985 FROM ezcontentobject_tree
2986 WHERE contentobject_id=$objectID AND
2987 main_node_id = node_id";
2988 $db = eZDB::instance();
2989 $nodeListArray = $db->arrayQuery( $query );
2990 if ( count( $nodeListArray ) == 1 )
2991 {
2992 if ( $asObject )
2993 {
2994 return eZContentObjectTreeNode::fetch( $nodeListArray[0]['node_id'] );
2995 }
2996 else
2997 {
2998 return $nodeListArray[0]['node_id'];
2999 }
3000
3001 }
3002 else if ( count( $nodeListArray ) > 1 )
3003 {
3004 eZDebug::writeError( $nodeListArray , "There are more then one main_node for objectID: $objectID" );
3005 }
3006
3007 return null;
3008 }
3009
3018 static function findMainNodeArray( $objectIDArray, $asObject = true )
3019 {
3020 if ( empty( $objectIDArray ) )
3021 return null;
3022
3023 $db = eZDB::instance();
3024 $nodeListArray = $db->arrayQuery(
3025 "SELECT " .
3026 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
3027 "ezcontentobject.modified, ezcontentobject.name, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, ezcontentobject.section_id, " .
3028 "ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, " .
3029 "ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, ezcontentobject_tree.node_id, ezcontentobject_tree.parent_node_id, " .
3030 "ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, " .
3031 "ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, ezcontentclass.identifier as class_identifier, ezcontentclass.is_container " .
3032 "FROM ezcontentobject_tree " .
3033 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
3034 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " .
3035 "WHERE " . $db->generateSQLINStatement( $objectIDArray, 'ezcontentobject_tree.contentobject_id', false, false, 'int' ) . " AND " .
3036 "ezcontentobject_tree.main_node_id = ezcontentobject_tree.node_id AND " .
3037 "ezcontentclass.version = 0"
3038 );
3039
3040 if ( $asObject )
3041 {
3042 return eZContentObjectTreeNode::makeObjectsArray( $nodeListArray );
3043 }
3044
3045 return $nodeListArray;
3046 }
3047
3058 static function fetch( $nodeID = false, $lang = false, $asObject = true, $conditions = false )
3059 {
3060 $returnValue = null;
3061 $db = eZDB::instance();
3062 if ( ( is_numeric( $nodeID ) && $nodeID == 1 ) ||
3063 ( is_array( $nodeID ) && count( $nodeID ) === 1 && $nodeID[0] == 1 ) )
3064 {
3065 $query = "SELECT *
3066 FROM ezcontentobject_tree
3067 WHERE node_id = 1";
3068 }
3069 else
3070 {
3071 $versionNameJoins = " AND ";
3072 if ( $lang )
3073 {
3074 $lang = $db->escapeString( $lang );
3075 $versionNameJoins .= " ezcontentobject_name.content_translation = '$lang' ";
3076 }
3077 else
3078 {
3079 $versionNameJoins .= eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' );
3080 }
3081
3082 $languageFilter = ' AND '.eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );
3083
3084 $sqlCondition = '';
3085
3086 if ( $nodeID !== false )
3087 {
3088 if ( is_array( $nodeID ) )
3089 {
3090 if( count( $nodeID ) === 1 )
3091 {
3092 $sqlCondition = 'node_id = ' . (int) $nodeID[0] . ' AND ';
3093 }
3094 else
3095 {
3096 $sqlCondition = $db->generateSQLINStatement( $nodeID, 'node_id', false, true, 'int' ) . ' AND ';
3097 }
3098 }
3099 else
3100 {
3101 $sqlCondition = 'node_id = ' . (int) $nodeID . ' AND ';
3102 }
3103 }
3104
3105 if ( is_array( $conditions ) )
3106 {
3107 foreach ( $conditions as $key => $condition )
3108 {
3109 if ( is_string( $condition ) )
3110 {
3111 $condition = $db->escapeString( $condition );
3112 $condition = "'$condition'";
3113 }
3114
3115 $sqlCondition .= "ezcontentobject_tree." . $db->escapeString( $key ) . "=$condition AND ";
3116 }
3117 }
3118
3119 if ( $sqlCondition == '' )
3120 {
3121 eZDebug::writeWarning( 'Cannot fetch node, emtpy ID or no conditions given', __METHOD__ );
3122 return $returnValue;
3123 }
3124
3125 $query = "SELECT " .
3126 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
3127 "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, ezcontentobject.section_id, " .
3128 "ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, " .
3129 "ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, " .
3130 "ezcontentobject_tree.node_id, ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, ezcontentobject_tree.priority, " .
3131 "ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, " .
3132 "ezcontentclass.identifier as class_identifier, ezcontentclass.is_container, ezcontentobject_name.name, ezcontentobject_name.real_translation " .
3133 "FROM ezcontentobject_tree " .
3134 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
3135 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " .
3136 "INNER JOIN ezcontentobject_name ON ( " .
3137 " ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND " .
3138 " ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version " .
3139 ") " .
3140 "WHERE $sqlCondition " .
3141 "ezcontentclass.version = 0 " .
3142 "$languageFilter " .
3143 $versionNameJoins;
3144 }
3145 $nodeListArray = $db->arrayQuery( $query );
3146
3147 if ( is_array( $nodeListArray ) && !empty( $nodeListArray ) )
3148 {
3149 if ( $asObject )
3150 {
3151 $returnValue = eZContentObjectTreeNode::makeObjectsArray( $nodeListArray, true, null, $lang );
3152 if ( count( $returnValue ) === 1 )
3153 $returnValue = $returnValue[0];
3154 }
3155 else
3156 {
3157 if ( count( $nodeListArray ) === 1 )
3158 $returnValue = $nodeListArray[0];
3159 else
3160 $returnValue = $nodeListArray;
3161 }
3162 }
3163
3164 return $returnValue;
3165 }
3166
3172 static function fetchNode( $contentObjectID, $parentNodeID )
3173 {
3174 $returnValue = null;
3175 $ini = eZINI::instance();
3176 $db = eZDB::instance();
3177 $contentObjectID =(int) $contentObjectID;
3178 $parentNodeID =(int) $parentNodeID;
3179 $query = "SELECT ezcontentobject_tree.*,
3180 ezcontentclass.serialized_name_list as class_serialized_name_list,
3181 ezcontentclass.identifier as class_identifier,
3182 ezcontentclass.is_container as is_container
3183 FROM ezcontentobject_tree,
3184 ezcontentobject,
3185 ezcontentclass
3186 WHERE ezcontentobject_tree.contentobject_id = '$contentObjectID' AND
3187 ezcontentobject.id = '$contentObjectID' AND
3188 ezcontentobject_tree.parent_node_id = '$parentNodeID' AND
3189 ezcontentclass.version=0 AND
3190 ezcontentclass.id = ezcontentobject.contentclass_id AND ".
3191 eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );
3192
3193 $nodeListArray = $db->arrayQuery( $query );
3194 if ( count( $nodeListArray ) == 1 )
3195 {
3196 $retNodeArray = eZContentObjectTreeNode::makeObjectsArray( $nodeListArray, false );
3197 $returnValue = $retNodeArray[0];
3198 }
3199 return $returnValue;
3200 }
3201
3202 function fetchParent()
3203 {
3204 return $this->fetch( $this->attribute( 'parent_node_id' ) );
3205 }
3206
3207 function pathArray()
3208 {
3209 $pathString = $this->attribute( 'path_string' );
3210 $pathItems = explode( '/', $pathString );
3211 $pathArray = array();
3212 foreach ( $pathItems as $pathItem )
3213 {
3214 if ( $pathItem != '' )
3215 $pathArray[] = (int) $pathItem;
3216 }
3217 return $pathArray;
3218 }
3219
3220
3221 function fetchPath()
3222 {
3223 $nodePath = $this->attribute( 'path_string' );
3224
3225 return eZContentObjectTreeNode::fetchNodesByPathString( $nodePath, false, true );
3226 }
3227
3236 static function fetchNodesByPathString( $nodePath, $withLastNode = false, $asObjects = true, $limit = false )
3237 {
3238 $nodesListArray = array();
3239 $pathString = eZContentObjectTreeNode::createNodesConditionSQLStringFromPath( $nodePath, $withLastNode, $limit );
3240
3241 if ( $pathString )
3242 {
3243 $nodesListArray = eZDB::instance()->arrayQuery(
3244 "SELECT " .
3245 "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " .
3246 "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, ezcontentobject.section_id, " .
3247 "ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, ezcontentobject_tree.depth, " .
3248 "ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, ezcontentobject_tree.node_id, " .
3249 "ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, " .
3250 "ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, ezcontentclass.identifier as class_identifier, " .
3251 "ezcontentclass.is_container as is_container, ezcontentobject_name.name, ezcontentobject_name.real_translation " .
3252 "FROM ezcontentobject_tree " .
3253 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
3254 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " .
3255 "INNER JOIN ezcontentobject_name ON ( " .
3256 " ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND " .
3257 " ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version " .
3258 ") " .
3259 "WHERE $pathString ezcontentclass.version = 0 AND " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . " " .
3260 "ORDER BY path_string"
3261 );
3262 }
3263
3264 if ( $asObjects )
3265 {
3266 return eZContentObjectTreeNode::makeObjectsArray( $nodesListArray );
3267 }
3268 return $nodesListArray;
3269 }
3270
3286 static function fetchClassIdentifierListByPathString( $nodePath, $withLastNode, $limit = false )
3287 {
3288 $itemList = array();
3289 $nodes = eZContentObjectTreeNode::fetchNodesByPathString( $nodePath, $withLastNode, false, $limit );
3290
3291 foreach ( $nodes as $node )
3292 {
3293 $itemList[] = array( 'node_id' => $node['node_id'],
3294 'class_identifier' => $node['class_identifier'] );
3295 }
3296
3297 return $itemList;
3298 }
3299
3309 function addChild( $contentobjectID, $asObject = false, $contentObjectVersion = false )
3310 {
3311 return self::addChildTo( $contentobjectID, $this->attribute( 'node_id' ), $asObject, $contentObjectVersion );
3312 }
3313
3324 static function addChildTo( $contentobjectID, $nodeID, $asObject = false, $contentObjectVersion = false )
3325 {
3326 $node = eZContentObjectTreeNode::fetch( $nodeID );
3327 $contentObject = eZContentObject::fetch( $contentobjectID );
3328 if ( !$contentObject )
3329 {
3330 return false;
3331 }
3332
3333 if ( !$contentObjectVersion )
3334 {
3335 $contentObjectVersion = $contentObject->attribute( 'current_version' );
3336 }
3337
3338 $db = eZDB::instance();
3339 $parentMainNodeID = $node->attribute( 'node_id' ); //$parent->attribute( 'main_node_id' );
3340 $parentPath = $node->attribute( 'path_string' );
3341 $parentDepth = $node->attribute( 'depth' );
3342 $isInvinsible = $node->attribute( 'is_invisible' );
3343
3344 $nodeDepth = $parentDepth + 1 ;
3345
3346 $insertedNode = eZContentObjectTreeNode::create( $parentMainNodeID, $contentobjectID );
3347
3348 // set default sorting from content class
3349 $contentClass = $contentObject->attribute( 'content_class' );
3350 $insertedNode->setAttribute( 'sort_field', $contentClass->attribute( 'sort_field' ) );
3351 $insertedNode->setAttribute( 'sort_order', $contentClass->attribute( 'sort_order' ) );
3352
3353 $insertedNode->setAttribute( 'depth', $nodeDepth );
3354 $insertedNode->setAttribute( 'path_string', '/TEMPPATH' );
3355
3356 $insertedNode->setAttribute( 'contentobject_version', $contentObjectVersion );
3357
3358 // If the parent node is invisible, the new created node should be invisible as well.
3359 $insertedNode->setAttribute( 'is_invisible', $isInvinsible );
3360
3361 $db->begin();
3362 $insertedNode->store();
3363 $insertedID = $insertedNode->attribute( 'node_id' );
3364 $newNodePath = $parentPath . $insertedID . '/';
3365 $insertedNode->setAttribute( 'path_string', $newNodePath );
3366 $insertedNode->store();
3367 $db->commit();
3368
3369 if ( $asObject )
3370 {
3371 return $insertedNode;
3372 }
3373 else
3374 {
3375 return $insertedID;
3376 }
3377 }
3378
3382 function pathWithNames( $regenerateCurrent = false )
3383 {
3384 // Only set name if current node is not the content root
3385 $ini = eZINI::instance( 'content.ini' );
3386 $contentRootID = $ini->variable( 'NodeSettings', 'RootNode' );
3387 if ( $this->attribute( 'node_id' ) != $contentRootID )
3388 {
3389 $pathArray = $this->pathArray();
3390 // Get rid of node with ID 1 (a special node)
3391 array_shift( $pathArray );
3392 if ( $regenerateCurrent )
3393 {
3394 // Get rid of current node, path element for this will be calculated
3395 array_pop( $pathArray );
3396 }
3397 if ( count( $pathArray ) == 0 )
3398 {
3399 $path = '';
3400 }
3401 else
3402 {
3403 $path = eZURLAliasML::fetchPathByActionList( "eznode", $pathArray, $this->CurrentLanguage );
3404 }
3405
3406 // Fallback in case fetchPathByActionList() fails,
3407 // then we ask for the path from the parent and generate the current
3408 // entry ourselves.
3409 if ( $path === null )
3410 {
3411 if ( $this->attribute( 'depth' ) == 0 ) // Top node should just return empty string
3412 {
3413 return '';
3414 }
3415
3416 eZDebug::writeError( __METHOD__ . "() failed to fetch path of node " . $this->attribute( 'node_id' ) . ", falling back to generated url entries. Run updateniceurls.php to fix the problem." );
3417
3418 // Return a perma-link when the path lookup failed, this link will always work
3419 $path = 'content/view/full/' . $this->attribute( 'node_id' );
3420 return $path;
3421 }
3422
3423 if ( $regenerateCurrent )
3424 {
3425 $nodeName = $this->attribute( 'name' );
3426 $nodeName = eZURLAliasML::convertToAlias( $nodeName, 'node_' . $this->attribute( 'node_id' ) );
3427
3428 if ( $path != '' )
3429 {
3430 $path .= '/' . $nodeName ;
3431 }
3432 else
3433 {
3434 $path = $nodeName ;
3435 }
3436 }
3437 }
3438 else
3439 {
3440 $path = '';
3441 }
3442
3443 if ( $regenerateCurrent )
3444 {
3445 $path = $this->checkPath( $path );
3446 }
3447 return $path;
3448 }
3449
3453 function checkPath( $path )
3454 {
3455 $path = eZURLAliasML::cleanURL( $path );
3456 $elements = explode( "/", $path );
3457 $element = array_pop( $elements );
3458 return $this->adjustPathElement( $element );
3459 }
3460
3477 function adjustPathElement( $element, $useParentFromNodeObject = false )
3478 {
3479 $nodeID = (int)$this->attribute( 'node_id' );
3480 $parentNodeID = (int)$this->attribute( 'parent_node_id' );
3481 $action = "eznode:" . $nodeID;
3482
3483 $elements = eZURLAliasML::fetchByAction( 'eznode', $nodeID );
3484 if ( count( $elements ) > 0 and !$useParentFromNodeObject )
3485 {
3486 $parentElementID = (int)$elements[0]->attribute( 'parent' );
3487 return eZURLAliasML::findUniqueText( $parentElementID, $element, $action );
3488 }
3489 else
3490 {
3491 $parentElements = eZURLAliasML::fetchByAction( 'eznode', $parentNodeID );
3492 if ( count( $parentElements ) > 0 && $parentElements[0]->attribute( 'text' ) != '' )
3493 {
3494 // Pick one of the parents and get the ID
3495 $parentElementID = (int)$parentElements[0]->attribute( 'id' );
3496 return eZURLAliasML::findUniqueText( $parentElementID, $element, $action );
3497 }
3498 }
3499 return eZURLAliasML::findUniqueText( 0, $element, $action );
3500 }
3501
3506 function updateSubTreePath( $updateParent = true, $nodeMove = false )
3507 {
3508 $changeCount = 0;
3509
3510 $nodeID = $this->attribute( 'node_id' );
3511 $parentNodeID = $this->attribute( 'parent_node_id' );
3512
3513 // Avoid recursion due to database inconsistencies
3514 if ( $nodeID === $parentNodeID )
3515 {
3516 eZDebug::writeError( "Parent node ID equals node ID for node: $nodeID. The node cannot be a parent of itself!", __METHOD__ );
3517 return false;
3518 }
3519
3520 // Only set name if current node is not the content root
3521 $ini = eZINI::instance( 'content.ini' );
3522 $contentRootID = $ini->variable( 'NodeSettings', 'RootNode' );
3523 $obj = $this->object();
3524 $alwaysMask = ( $obj->attribute( 'language_mask' ) & 1 );
3525 $languages = $obj->allLanguages();
3526 $nameList = array();
3527
3528 $initialLanguageID = $obj->attribute( 'initial_language_id' );
3529 $pathIdentificationName = false;
3530 foreach ( $languages as $language )
3531 {
3532 $nodeName = '';
3533 if ( $nodeID != $contentRootID )
3534 {
3535 $objClass = $obj->attribute( 'content_class' );
3536 $nodeName = $objClass->urlAliasName( $obj, false, $language->attribute( 'locale' ) );
3537 $nodeName = eZURLAliasFilter::processFilters( $nodeName, $language, $this );
3538 $nodeName = eZURLAliasML::convertToAlias( $nodeName, 'node_' . $nodeID );
3539 $nodeName = $this->adjustPathElement( $nodeName, $nodeMove );
3540
3541 // Compatibility mode:
3542 // Store name for the 'path_identification_string' column.
3543 if ( $initialLanguageID == $language->attribute( 'id' ) )
3544 {
3545 $pathIdentificationName = eZURLAliasML::convertToAliasCompat( $nodeName, 'node_' . $nodeID );
3546 }
3547 }
3548 $nameList[] = array( 'text' => $nodeName,
3549 'language' => $language );
3550 }
3551
3552 $parentActionName = "eznode";
3553 $parentActionValue = $parentNodeID;
3554
3555 $parentElementID = false;
3556 $existingElements = eZURLAliasML::fetchByAction( "eznode", $nodeID );
3557 $existingElementID = null;
3558 if ( count( $existingElements ) > 0 )
3559 {
3560 $existingElementID = $existingElements[0]->attribute( 'id' );
3561 $parentElementID = $existingElements[0]->attribute( 'parent' );
3562 }
3563
3564 // If we have parent element it means the node is already published
3565 // and we have to see if it has been moved
3566 if ( $parentNodeID != 1 and $updateParent )
3567 {
3568 $parents = eZURLAliasML::fetchByAction( "eznode", $parentNodeID );
3569 if ( count( $parents ) == 0 )
3570 {
3571 $parentNode = $this->fetchParent();
3572
3573 if ( !$parentNode )
3574 {
3575 return false;
3576 }
3577
3578 $result = $parentNode->updateSubTreePath();
3579 if ( !$result )
3580 {
3581 return false;
3582 }
3583 $parents = eZURLAliasML::fetchByAction( $parentActionName, $parentActionValue );
3584 if ( count( $parents ) == 0 )
3585 {
3586 return false;
3587 }
3588 $oldParentElementID = $parentElementID;
3589 foreach ( $parents as $paren )
3590 {
3591 $parentElementID = 0;
3592 if ( $paren->attribute( 'text' ) != '' )
3593 {
3594 $parentElementID = (int)$paren->attribute( 'link' );
3595 break;
3596 }
3597 }
3598 }
3599 else
3600 {
3601 $oldParentElementID = $parentElementID;
3602 $parentElementID = 0;
3603 foreach ( $parents as $paren )
3604 {
3605 if ( $paren->attribute( 'text' ) != '' )
3606 {
3607 $parentElementID = (int)$paren->attribute( 'link' );
3608 break;
3609 }
3610 }
3611 }
3612 }
3613 else // Parent is ID 1, ie. this node is top-level
3614 {
3615 }
3616
3617 $this->updatePathIdentificationString( $pathIdentificationName );
3618
3619 $languageID = $obj->attribute( 'initial_language_id' );
3620 $cleanup = false;
3621 foreach ( $nameList as $nameEntry )
3622 {
3623 $text = $nameEntry['text'];
3624 $language = $nameEntry['language'];
3625 $result = eZURLAliasML::storePath( $text, 'eznode:' . $nodeID, $language, false, $alwaysMask, $parentElementID, $cleanup );
3626 if ( $result['status'] === true )
3627 $changeCount++;
3628 }
3629 return $changeCount;
3630 }
3631
3639 function updatePathIdentificationString( $pathIdentificationName )
3640 {
3641 // Update the path_identification_string column for the node
3642 $pathIdentificationString = '';
3643 if ( $this->attribute( 'parent_node_id' ) != 1 )
3644 {
3645 if ( !isset( $parentNode ) )
3646 $parentNode = $this->fetchParent();
3647 // Avoid crashes due to database inconsistencies
3648 if ( $parentNode instanceof eZContentObjectTreeNode )
3649 {
3650 $pathIdentificationString = $parentNode->attribute( 'path_identification_string' );
3651 }
3652 else
3653 {
3654 eZDebug::writeError( 'Failed to fetch parent node for pathIdentificationName "' . $pathIdentificationName .
3655 '" and parent_node_id ' . $this->attribute( 'parent_node_id' ), __METHOD__ );
3656 }
3657 }
3658 if ( strlen( $pathIdentificationString ) > 0 )
3659 $pathIdentificationString .= '/' . $pathIdentificationName;
3660 else
3661 $pathIdentificationString = $pathIdentificationName;
3662 if ( $this->attribute( 'path_identification_string' ) != $pathIdentificationString )
3663 {
3664 $db = eZDB::instance();
3665 $db->query(
3666 "UPDATE ezcontentobject_tree " .
3667 "SET path_identification_string = " .
3668 $db->concatString(
3669 array(
3670 "'" . $db->escapeString( $pathIdentificationString ) . "'",
3671 $db->subString(
3672 "path_identification_string",
3673 mb_strlen( $this->attribute( 'path_identification_string' ) ) + 1
3674 )
3675 )
3676 ) . " " .
3677 "WHERE path_string LIKE '{$this->attribute( 'path_string' )}_%'"
3678 );
3679
3680 $this->setAttribute( 'path_identification_string', $pathIdentificationString );
3681 $this->sync();
3682 }
3683 }
3684
3689 static function removeNode( $nodeID = 0 )
3690 {
3691 $node = eZContentObjectTreeNode::fetch( $nodeID );
3692 if ( !is_object( $node ) )
3693 {
3694 return;
3695 }
3696
3697 return $node->removeThis();
3698 }
3699
3707 function removeThis()
3708 {
3709 $ini = eZINI::instance();
3710
3711 $object = $this->object();
3712 $nodeID = $this->attribute( 'node_id' );
3713 $objectID = $object->attribute( 'id' );
3714 if ( eZAudit::isAuditEnabled() )
3715 {
3716 // Set audit params.
3717 $objectName = $object->attribute( 'name' );
3718
3719 eZAudit::writeAudit( 'content-delete', array( 'Node ID' => $nodeID, 'Object ID' => $objectID, 'Content Name' => $objectName,
3720 'Comment' => 'Removed the current node: eZContentObjectTreeNode::removeNode()' ) );
3721 }
3722
3723 $db = eZDB::instance();
3724 $db->begin();
3725
3726 $nodePath = $this->attribute( 'path_string' );
3727 $childrensPath = $nodePath ;
3728
3729 $pathString = " path_string like '$childrensPath%' ";
3730
3731 $urlAlias = $this->attribute( 'url_alias' );
3732
3733 // Remove static cache
3734 if ( $ini->variable( 'ContentSettings', 'StaticCache' ) == 'enabled' )
3735 {
3736 $optionArray = array( 'iniFile' => 'site.ini',
3737 'iniSection' => 'ContentSettings',
3738 'iniVariable' => 'StaticCacheHandler' );
3739
3740 $options = new ezpExtensionOptions( $optionArray );
3741
3742 $staticCacheHandler = eZExtension::getHandlerClass( $options );
3743
3744 $staticCacheHandler->removeURL( "/" . $urlAlias );
3745 $staticCacheHandler->generateAlwaysUpdatedCache();
3746
3747 $parent = $this->fetchParent();
3748 }
3749
3750 $db->query( "DELETE FROM ezcontentobject_tree
3751 WHERE $pathString OR
3752 path_string = '$nodePath'" );
3753
3754 // Re-cache parent node
3755 if ( $ini->variable( 'ContentSettings', 'StaticCache' ) == 'enabled' )
3756 {
3757 if ( $parent )
3758 {
3759 $staticCacheHandler->cacheURL( "/" . $parent->urlAlias() );
3760 }
3761 }
3762
3763 // Clean up URL alias entries
3764 eZURLAliasML::removeByAction( 'eznode', $nodeID );
3765
3766 // Clean up content cache
3767 eZContentCacheManager::clearContentCacheIfNeeded( $this->attribute( 'contentobject_id' ) );
3768
3769 // clean up user cache
3770 if ( in_array( $object->attribute( 'contentclass_id' ), eZUser::contentClassIDs() ) )
3771 {
3772 eZUser::removeSessionData( $objectID );
3773 eZUser::purgeUserCacheByUserId( $objectID );
3774 }
3775
3776 $parentNode = $this->attribute( 'parent' );
3777 if ( is_object( $parentNode ) )
3778 {
3779 eZContentCacheManager::clearContentCacheIfNeeded( $parentNode->attribute( 'contentobject_id' ) );
3780 $parentNode->updateAndStoreModified();
3781 eZNodeAssignment::purgeByParentAndContentObjectID( $parentNode->attribute( 'node_id' ), $objectID );
3782 }
3783
3784 // Clean up policies and limitations
3785 eZRole::cleanupByNode( $this );
3786
3787 // Clean up recent items
3788 eZContentBrowseRecent::removeRecentByNodeID( $nodeID );
3789
3790 // Clean up bookmarks
3791 eZContentBrowseBookmark::removeByNodeID( $nodeID );
3792
3793 // Clean up tip-a-friend counter
3794 eZTipafriendCounter::removeForNode( $nodeID );
3795
3796 // Clean up view counter
3797 eZViewCounter::removeCounter( $nodeID );
3798
3799 $db->commit();
3800 }
3801
3826 static function subtreeRemovalInformation( $deleteIDArray )
3827 {
3828 return eZContentObjectTreeNode::removeSubtrees( $deleteIDArray, true, true );
3829 }
3830
3847 static function removeSubtrees( $deleteIDArray, $moveToTrash = true, $infoOnly = false )
3848 {
3849 $moveToTrashAllowed = true;
3850 $deleteResult = array();
3851 $totalChildCount = 0;
3852 $totalLoneNodeCount = 0;
3853 $canRemoveAll = true;
3854 $hasPendingObject = false;
3855
3856 $db = eZDB::instance();
3857 $db->begin();
3858
3859 foreach ( $deleteIDArray as $deleteID )
3860 {
3861 $node = eZContentObjectTreeNode::fetch( $deleteID );
3862 if ( $node === null )
3863 continue;
3864
3865 $object = $node->attribute( 'object' );
3866 if ( $object === null )
3867 continue;
3868
3869 $class = $object->attribute( 'content_class' );
3870 $canRemove = $node->attribute( 'can_remove' );
3871 $canRemoveSubtree = true;
3872
3873 $nodeID = $node->attribute( 'node_id' );
3874 $nodeName = $object->attribute( 'name' );
3875
3876 $childCount = 0;
3877 $newMainNodeID = false;
3878 $objectNodeCount = 0;
3879 $readableChildCount = 0;
3880
3881 if ( $canRemove )
3882 {
3883 $moveToTrashAllowed = $node->isNodeTrashAllowed();
3884
3885 $readableChildCount = $node->subTreeCount( array( 'Limitation' => array() ) );
3886 $childCount = $node->subTreeCount( array( 'IgnoreVisibility' => true ) );
3887 $totalChildCount += $childCount;
3888
3889 $allAssignedNodes = $object->attribute( 'assigned_nodes' );
3890 $objectNodeCount = count( $allAssignedNodes );
3891 // We need to find a new main node ID if we are trying
3892 // to remove the current main node.
3893 if ( $node->attribute( 'main_node_id' ) == $nodeID )
3894 {
3895 if ( count( $allAssignedNodes ) > 1 )
3896 {
3897 foreach( $allAssignedNodes as $assignedNode )
3898 {
3899 $assignedNodeID = $assignedNode->attribute( 'node_id' );
3900 if ( $assignedNodeID == $nodeID )
3901 continue;
3902 $newMainNodeID = $assignedNodeID;
3903 break;
3904 }
3905 }
3906 }
3907
3908 if ( $infoOnly )
3909 {
3910 // Find the number of items in the subtree we are allowed to remove
3911 // if this differs from the total count it means we have items we cannot remove
3912 // We do this by fetching the limitation list for content/remove
3913 // and passing it to the subtree count function.
3914 $currentUser = eZUser::currentUser();
3915 $accessResult = $currentUser->hasAccessTo( 'content', 'remove' );
3916 if ( $accessResult['accessWord'] == 'limited' )
3917 {
3918 $limitationList = $accessResult['policies'];
3919 $removeableChildCount = $node->subTreeCount( array( 'Limitation' => $limitationList, 'IgnoreVisibility' => true ) );
3920 $canRemoveSubtree = ( $removeableChildCount == $childCount );
3921 $canRemove = $canRemoveSubtree;
3922 }
3923 //check if there is sub object in pending status
3924 $limitCount = 100;
3925 $offset = 0;
3926 while( 1 )
3927 {
3928 $children = $node->subTree( array( 'Limitation' => array(),
3929 'SortBy' => array( 'path' , false ),
3930 'Offset' => $offset,
3931 'Limit' => $limitCount,
3932 'IgnoreVisibility' => true,
3933 'AsObject' => false ) );
3934 // fetch pending node assignment(pending object)
3935 $idList = array();
3936 //add node itself into idList
3937 if( $offset === 0 )
3938 {
3939 $idList[] = $nodeID;
3940 }
3941 foreach( $children as $child )
3942 {
3943 $idList[] = $child['node_id'];
3944 }
3945
3946 if( count( $idList ) === 0 )
3947 {
3948 break;
3949 }
3950 $pendingChildCount = eZNodeAssignment::fetchChildCountByVersionStatus( $idList,
3951 eZContentObjectVersion::STATUS_PENDING );
3952 if( $pendingChildCount !== 0 )
3953 {
3954 // there is pending object
3955 $hasPendingObject = true;
3956 break;
3957 }
3958 $offset += $limitCount;
3959 }
3960 }
3961
3962 // We will only remove the subtree if are allowed
3963 // and are told to do so.
3964 if ( $canRemove and !$infoOnly )
3965 {
3966 $moveToTrashTemp = $moveToTrash;
3967 if ( !$moveToTrashAllowed )
3968 $moveToTrashTemp = false;
3969
3970 // Remove children, fetching them by 100 to avoid memory overflow.
3971 // removeNodeFromTree -> removeThis handles cache clearing
3972 while ( 1 )
3973 {
3974 // We should remove the latest subitems first,
3975 // so we should fetch subitems sorted by 'path_string' DESC
3976 $children = $node->subTree( array( 'Limitation' => array(),
3977 'SortBy' => array( 'path' , false ),
3978 'Limit' => 100,
3979 'IgnoreVisibility' => true ) );
3980 if ( !$children )
3981 break;
3982
3983 foreach ( $children as $child )
3984 {
3985 $child->removeNodeFromTree( $moveToTrashTemp );
3986 eZContentObject::clearCache();
3987 }
3988 }
3989
3990 $node->removeNodeFromTree( $moveToTrashTemp );
3991 }
3992 }
3993 if ( !$canRemove )
3994 $canRemoveAll = false;
3995
3996 // Do not create info list if we are removing subtrees
3997 if ( !$infoOnly )
3998 continue;
3999
4000 $soleNodeCount = $node->subtreeSoleNodeCount();
4001 $totalLoneNodeCount += $soleNodeCount;
4002 if ( $objectNodeCount <= 1 )
4003 ++$totalLoneNodeCount;
4004
4005 $item = array( "nodeName" => $nodeName, // Backwards compatibility
4006 "childCount" => $childCount, // Backwards compatibility
4007 "additionalWarning" => '', // Backwards compatibility, this will always be empty
4008 'node' => $node,
4009 'object' => $object,
4010 'class' => $class,
4011 'node_name' => $nodeName,
4012 'child_count' => $childCount,
4013 'object_node_count' => $objectNodeCount,
4014 'sole_node_count' => $soleNodeCount,
4015 'can_remove' => $canRemove,
4016 'can_remove_subtree' => $canRemoveSubtree,
4017 'real_child_count' => $readableChildCount,
4018 'new_main_node_id' => $newMainNodeID );
4019 $deleteResult[] = $item;
4020 }
4021
4022 $db->commit();
4023
4024 if ( !$infoOnly )
4025 return true;
4026
4027 if ( $moveToTrashAllowed and $totalLoneNodeCount == 0 )
4028 $moveToTrashAllowed = false;
4029
4030 return array( 'move_to_trash' => $moveToTrashAllowed,
4031 'total_child_count' => $totalChildCount,
4032 'can_remove_all' => $canRemoveAll,
4033 'delete_list' => $deleteResult,
4034 'has_pending_object' => $hasPendingObject,
4035 'reverse_related_count' => eZContentObjectTreeNode::reverseRelatedCount( $deleteIDArray ) );
4036 }
4037
4047 static function reverseRelatedCount( $nodeIDArray )
4048 {
4049 // Select count of all elements having reverse relations. And ignore those items that don't relate to objects other than being removed.
4050 if ( $nodeIDArray === array() )
4051 {
4052 return 0;
4053 }
4054
4055 $pathStringArray = array();
4056 $path2StringArray = array();
4057 foreach( $nodeIDArray as $nodeID )
4058 {
4059 $contentObjectTreeNode = eZContentObjectTreeNode::fetch( $nodeID, false, false );
4060 $tempPathString = $contentObjectTreeNode['path_string'];
4061
4062 // Create WHERE section
4063 $pathStringArray[] = "tree.path_string like '$tempPathString%'";
4064 $path2StringArray[] = "tree2.path_string like '$tempPathString%'";
4065 }
4066 $path_strings = '( ' . implode( ' OR ', $pathStringArray ) . ' ) ';
4067 $path_strings_where = '( ' . implode( ' OR ', $path2StringArray ) . ' ) ';
4068
4069 // Total count of sub items
4070 $db = eZDB::instance();
4071 $countOfItems = $db->arrayQuery( "SELECT COUNT( DISTINCT( tree.node_id ) ) as count
4072 FROM ezcontentobject_tree tree, ezcontentobject obj,
4073 ezcontentobject_link link LEFT JOIN ezcontentobject_tree tree2
4074 ON link.from_contentobject_id = tree2.contentobject_id
4075 WHERE $path_strings
4076 and link.to_contentobject_id = tree.contentobject_id
4077 and obj.id = link.from_contentobject_id
4078 and obj.current_version = link.from_contentobject_version
4079 and not $path_strings_where" );
4080
4081 if ( $countOfItems )
4082 {
4083 return $countOfItems[0]['count'];
4084 }
4085 }
4086
4098 function removeNodeFromTree( $moveToTrash = true )
4099 {
4100 $nodeID = $this->attribute( 'node_id' );
4101 $object = $this->object();
4102 $assignedNodes = $object->attribute( 'assigned_nodes' );
4103 if ( $nodeID == $this->attribute( 'main_node_id' ) )
4104 {
4105 if ( count( $assignedNodes ) > 1 )
4106 {
4107 $newMainNode = false;
4108 foreach ( $assignedNodes as $assignedNode )
4109 {
4110 $assignedNodeID = $assignedNode->attribute( 'node_id' );
4111 if ( $assignedNodeID == $nodeID )
4112 continue;
4113 $newMainNode = $assignedNode;
4114 break;
4115 }
4116
4117 // We need to change the main node ID before we remove the current node
4118 $db = eZDB::instance();
4119 $db->begin();
4120 eZContentObjectTreeNode::updateMainNodeID( $newMainNode->attribute( 'node_id' ),
4121 $object->attribute( 'id' ),
4122 $object->attribute( 'current_version' ),
4123 $newMainNode->attribute( 'parent_node_id' ) );
4124 $this->removeThis();
4125 eZSearch::addObject( $object );
4126 $db->commit();
4127 }
4128 else
4129 {
4130 // This is the last assignment so we remove the object too
4131 $db = eZDB::instance();
4132 $db->begin();
4133 $this->removeThis();
4134
4135 if ( $moveToTrash )
4136 {
4137 // saving information about this node in ..trash_node table
4138 $trashNode = eZContentObjectTrashNode::createFromNode( $this );
4139 $db = eZDB::instance();
4140 $db->begin();
4141 $trashNode->storeToTrash();
4142 $db->commit();
4143 $object->removeThis();
4144 }
4145 else
4146 {
4147 $object->purge();
4148 }
4149 $db->commit();
4150 }
4151 }
4152 else
4153 {
4154 $this->removeThis();
4155 if ( count( $assignedNodes ) > 1 )
4156 {
4157 eZSearch::addObject( $object );
4158 }
4159 }
4160 }
4161
4168 function subtreeSoleNodeCount( $params = array() )
4169 {
4170 $nodeID = $this->attribute( 'node_id' );
4171 $node = $this;
4172
4173 $depth = false;
4174 if ( isset( $params['Depth'] ) && is_numeric( $params['Depth'] ) )
4175 {
4176 $depth = $params['Depth'];
4177
4178 }
4179
4180 $fromNode = $nodeID;
4181
4182 $nodePath = null;
4183 $nodeDepth = 0;
4184 if ( is_countable( $node ) && count( $node ) != 0 )
4185 {
4186 $nodePath = $node->attribute( 'path_string' );
4187 $nodeDepth = $node->attribute( 'depth' );
4188 }
4189
4190 $childPath = $nodePath;
4191
4192 $db = eZDB::instance();
4193 $pathString = " ezcot.path_string like '$childPath%' and ";
4194
4195 $notEqParentString = "ezcot.node_id != $fromNode";
4196 $depthCond = '';
4197 if ( $depth )
4198 {
4199
4200 $nodeDepth += $depth;
4201 if ( isset( $params[ 'DepthOperator' ] ) && $params[ 'DepthOperator' ] == 'eq' )
4202 {
4203 $depthCond = ' ezcot.depth = ' . $nodeDepth . '';
4204 $notEqParentString = '';
4205 }
4206 else
4207 $depthCond = ' ezcot.depth <= ' . $nodeDepth . ' and ';
4208 }
4209
4210 $tmpTableName = $db->generateUniqueTempTableName( 'eznode_count_%' );
4211 $db->createTempTable( "CREATE TEMPORARY TABLE $tmpTableName ( count int )" );
4212 $query = "INSERT INTO $tmpTableName
4213 SELECT
4214 count( ezcot.main_node_id ) AS count
4215 FROM
4216 ezcontentobject_tree ezcot,
4217 ezcontentobject_tree ezcot_all
4218 WHERE
4219 $pathString
4220 $depthCond
4221 $notEqParentString
4222 and ezcot.contentobject_id = ezcot_all.contentobject_id
4223 GROUP BY ezcot_all.main_node_id
4224 HAVING count( ezcot.main_node_id ) <= 1";
4225
4226 $db->query( $query, eZDBInterface::SERVER_SLAVE );
4227 $query = "SELECT count( * ) AS count
4228 FROM $tmpTableName";
4229
4230 $rows = $db->arrayQuery( $query, array(), eZDBInterface::SERVER_SLAVE );
4231 $db->dropTempTable( "DROP TABLE $tmpTableName" );
4232 return $rows[0]['count'];
4233 }
4234
4240 function move( $newParentNodeID, $nodeID = 0 )
4241 {
4242 if ( $nodeID == 0 )
4243 {
4244 $node = $this;
4245 $nodeID = $node->attribute( 'node_id' );
4246 }
4247 else
4248 {
4249 $node = eZContentObjectTreeNode::fetch( $nodeID );
4250 }
4251
4252 $oldPath = $node->attribute( 'path_string' );
4253 $oldParentNodeID = $node->attribute( 'parent_node_id' );
4254 $newParentNodeID =(int) $newParentNodeID;
4255 if ( $oldParentNodeID != $newParentNodeID )
4256 {
4257 $node->updateAndStoreModified();
4258 // Who moves which content should be logged.
4259 $object = $node->object();
4260 eZAudit::writeAudit( 'content-move', array( 'Node ID' => $node->attribute( 'node_id' ),
4261 'Old parent node ID' => $oldParentNodeID, 'New parent node ID' => $newParentNodeID,
4262 'Object ID' => $object->attribute( 'id' ), 'Content Name' => $object->attribute( 'name' ),
4263 'Comment' => 'Moved the node to the given node: eZContentObjectTreeNode::move()' ) );
4264
4265 $newParentNode = eZContentObjectTreeNode::fetch( $newParentNodeID );
4266 $newParentPath = $newParentNode->attribute( 'path_string' );
4267 $newParentDepth = $newParentNode->attribute( 'depth' );
4268 $newPath = $newParentPath . $nodeID;
4269 $oldDepth = $node->attribute( 'depth' );
4270
4271 $oldPathLength = strlen( $oldPath );
4272 $moveQuery = "UPDATE
4273 ezcontentobject_tree
4274 SET
4275 parent_node_id = $newParentNodeID
4276 WHERE
4277 node_id = $nodeID";
4278 $db = eZDB::instance();
4279 $subStringString = $db->subString( 'path_string', $oldPathLength );
4280 $newPathString = $db->concatString( array( "'$newPath'", $subStringString ) );
4281 $moveQuery1 = "UPDATE
4282 ezcontentobject_tree
4283 SET
4284 path_identification_string = " .
4285 $db->concatString(
4286 array(
4287 "'" . $db->escapeString( $newParentNode->PathIdentificationString ) . "'",
4288 $db->subString(
4289 "path_identification_string",
4290 mb_strlen( $node->PathIdentificationString ) + 1
4291 )
4292 )
4293 ) . ",
4294 path_string = $newPathString,
4295 depth = depth + $newParentDepth - $oldDepth + 1
4296 WHERE
4297 path_string LIKE '$oldPath%'";
4298 $db->begin();
4299 $db->query( $moveQuery );
4300 $db->query( $moveQuery1 );
4301
4303 // Clean up policies and limitations
4304
4305 $expireRoleCache = false;
4306
4307 $limitationsToFix = eZPolicyLimitation::findByType( 'SubTree', $node->attribute( 'path_string' ), false );
4308 if ( count( $limitationsToFix ) > 0 )
4309 {
4310 $limitationIDString = $db->generateSQLINStatement( $limitationsToFix, 'limitation_id' );
4311 $subStringString = $db->subString( 'value', $oldPathLength );
4312 $newValue = $db->concatString( array( "'$newPath'", $subStringString ) );
4313
4314 $query = "UPDATE
4315 ezpolicy_limitation_value
4316 SET
4317 value = $newValue
4318 WHERE
4319 value LIKE '$oldPath%' AND $limitationIDString";
4320
4321 $db->query( $query );
4322
4323 $expireRoleCache = true;
4324 }
4325
4326 // clean up limitations on role assignment level
4327 $countRows = $db->arrayQuery( "SELECT COUNT(*) AS row_count FROM ezuser_role WHERE limit_identifier='Subtree' AND limit_value LIKE '$oldPath%'" );
4328 $assignmentsToFixCount = $countRows[0]['row_count'];
4329
4330 if ( $assignmentsToFixCount > 0 )
4331 {
4332 $subStringString = $db->subString( 'limit_value', $oldPathLength );
4333 $newValue = $db->concatString( array( "'$newPath'", $subStringString ) );
4334
4335 $db->query( "UPDATE
4336 ezuser_role
4337 SET
4338 limit_value = $newValue
4339 WHERE
4340 limit_identifier='Subtree' AND limit_value LIKE '$oldPath%'"
4341 );
4342
4343 $expireRoleCache = true;
4344 }
4345
4346 if ( $expireRoleCache )
4347 {
4348 eZRole::expireCache();
4349 }
4350
4351 // Update "is_invisible" node attribute.
4352 $newNode = eZContentObjectTreeNode::fetch( $nodeID );
4353 eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode );
4354 $db->commit();
4355 }
4356 }
4357
4358 function checkAccess( $functionName, $originalClassID = false, $parentClassID = false, $returnAccessList = false, $language = false )
4359 {
4360 $classID = $originalClassID;
4361 $user = eZUser::currentUser();
4362 $userID = $user->attribute( 'contentobject_id' );
4363
4364 // Fetch the ID of the language if we get a string with a language code
4365 // e.g. 'eng-GB'
4366 $originalLanguage = $language;
4367 if ( is_string( $language ) && strlen( $language ) > 0 )
4368 {
4369 $language = eZContentLanguage::idByLocale( $language );
4370 }
4371 else
4372 {
4373 $language = false;
4374 }
4375
4376 // This will be filled in with the available languages of the object
4377 // if a Language check is performed.
4378 $languageList = false;
4379
4380 // This will be filled if parent object is needed.
4381 $parentObject = false;
4382
4383 $origFunctionName = $functionName;
4384 // The 'move' function simply reuses 'edit' for generic access
4385 // but adds another top-level check below
4386 // The original function is still available in $origFunctionName
4387 if ( $functionName == 'move' )
4388 $functionName = 'edit';
4389
4390 // Manage locations depends if it's removal or not.
4391 if ( $functionName == 'can_add_location' ||
4392 $functionName == 'can_remove_location' )
4393 {
4394 $functionName = 'manage_locations';
4395 }
4396
4397 $accessResult = $user->hasAccessTo( 'content' , $functionName );
4398 $accessWord = $accessResult['accessWord'];
4399 if ( $origFunctionName == 'can_remove_location' )
4400 {
4401 if ( $this->ParentNodeID <= 1 )
4402 {
4403 return 0;
4404 }
4405 $currentNode = eZContentObjectTreeNode::fetch( $this->ParentNodeID );
4406 if ( !$currentNode instanceof eZContentObjectTreeNode )
4407 {
4408 return 0;
4409 }
4410 $contentObject = $currentNode->attribute( 'object' );
4411 }
4412 else
4413 {
4414 $currentNode = $this;
4415 $contentObject = $this->attribute( 'object' );
4416 }
4417
4418 /*
4419 // Uncomment this part if 'create' permissions should become implied 'edit'.
4420 // Merges in 'create' policies with 'edit'
4421 if ( $functionName == 'edit' &&
4422 !in_array( $accessWord, array( 'yes', 'no' ) ) )
4423 {
4424 // Add in create policies.
4425 $accessExtraResult = $user->hasAccessTo( 'content', 'create' );
4426 if ( $accessExtraResult['accessWord'] != 'no' )
4427 {
4428 $accessWord = $accessExtraResult['accessWord'];
4429 if ( isset( $accessExtraResult['policies'] ) )
4430 {
4431 $accessResult['policies'] = array_merge( $accessResult['policies'],
4432 $accessExtraResult['policies'] );
4433 }
4434 if ( isset( $accessExtraResult['accessList'] ) )
4435 {
4436 $accessResult['accessList'] = array_merge( $accessResult['accessList'],
4437 $accessExtraResult['accessList'] );
4438 }
4439 }
4440 }
4441 */
4442
4443 if ( $origFunctionName == 'remove' or
4444 $origFunctionName == 'move' or
4445 $origFunctionName == 'can_remove_location' )
4446 {
4447 // We do not allow these actions on top-level nodes
4448 // - remove
4449 // - move
4450 if ( $this->ParentNodeID <= 1 )
4451 {
4452 return 0;
4453 }
4454 }
4455
4456 if ( $classID === false )
4457 {
4458 $classID = $contentObject->attribute( 'contentclass_id' );
4459 }
4460 if ( $accessWord == 'yes' )
4461 {
4462 return 1;
4463 }
4464 else if ( $accessWord == 'no' )
4465 {
4466 if ( $functionName == 'edit' )
4467 {
4468 // Check if we have 'create' access under the main parent
4469 $object = $currentNode->object();
4470 if ( $object && $object->attribute( 'current_version' ) == 1 && !$object->attribute( 'status' ) )
4471 {
4472 $mainNode = eZNodeAssignment::fetchForObject( $object->attribute( 'id' ), $object->attribute( 'current_version' ) );
4473 $parentObj = $mainNode[0]->attribute( 'parent_contentobject' );
4474 if ( $parentObj instanceof eZContentObject )
4475 {
4476 $result = $parentObj->checkAccess( 'create', $object->attribute( 'contentclass_id' ),
4477 $parentObj->attribute( 'contentclass_id' ), false, $originalLanguage );
4478 return $result;
4479 }
4480 else
4481 {
4482 eZDebug::writeError( "Error retrieving parent object of main node for object id: " . $object->attribute( 'id' ), __METHOD__ );
4483 }
4484 }
4485 }
4486
4487 return 0;
4488 }
4489 else
4490 {
4491 $policies = $accessResult['policies'];
4492 $access = 'denied';
4493
4494 foreach ( $policies as $pkey => $limitationArray )
4495 {
4496 if ( $access == 'allowed' )
4497 {
4498 break;
4499 }
4500
4501 $limitationList = array();
4502 if ( isset( $limitationArray['Subtree' ] ) )
4503 {
4504 $checkedSubtree = false;
4505 }
4506 else
4507 {
4508 $checkedSubtree = true;
4509 $accessSubtree = false;
4510 }
4511 if ( isset( $limitationArray['Node'] ) )
4512 {
4513 $checkedNode = false;
4514 }
4515 else
4516 {
4517 $checkedNode = true;
4518 $accessNode = false;
4519 }
4520 foreach ( $limitationArray as $key => $valueList )
4521 {
4522 $access = 'denied';
4523 switch( $key )
4524 {
4525 case 'Class':
4526 {
4527 if ( $functionName == 'create' and
4528 !$originalClassID )
4529 {
4530 $access = 'allowed';
4531 }
4532 else if ( $functionName == 'create' and
4533 in_array( $classID, $valueList ) )
4534 {
4535 $access = 'allowed';
4536 }
4537 else if ( $functionName != 'create' and
4538 in_array( $contentObject->attribute( 'contentclass_id' ), $valueList ) )
4539 {
4540 $access = 'allowed';
4541 }
4542 else
4543 {
4544 $access = 'denied';
4545 $limitationList = array( 'Limitation' => $key,
4546 'Required' => $valueList );
4547 }
4548 } break;
4549
4550 case 'ParentClass':
4551 {
4552 if ( in_array( $contentObject->attribute( 'contentclass_id' ), $valueList ) )
4553 {
4554 $access = 'allowed';
4555 }
4556 else
4557 {
4558 $access = 'denied';
4559 $limitationList = array( 'Limitation' => $key,
4560 'Required' => $valueList );
4561 }
4562 } break;
4563
4564 case 'Section':
4565 case 'User_Section':
4566 {
4567 if ( in_array( $contentObject->attribute( 'section_id' ), $valueList ) )
4568 {
4569 $access = 'allowed';
4570 }
4571 else
4572 {
4573 $access = 'denied';
4574 $limitationList = array( 'Limitation' => $key,
4575 'Required' => $valueList );
4576 }
4577 } break;
4578
4579 case 'Language':
4580 {
4581 $languageMask = 0;
4582 // If we don't have a language list yet we need to fetch it
4583 // and optionally filter out based on $language.
4584 if ( $functionName == 'create' )
4585 {
4586 // If the function is 'create' we do not use the language_mask for matching.
4587 if ( $language !== false )
4588 {
4589 $languageMask = $language;
4590 }
4591 else
4592 {
4593 // If the create is used and no language specified then
4594 // we need to match against all possible languages (which
4595 // is all bits set, ie. -1).
4596 $languageMask = -1;
4597 }
4598 }
4599 else
4600 {
4601 if ( $language !== false )
4602 {
4603 if ( $languageList === false )
4604 {
4605 $languageMask = $contentObject->attribute( 'language_mask' );
4606 // We are restricting language check to just one language
4607 $languageMask &= $language;
4608 // If the resulting mask is 0 it means that the user is trying to
4609 // edit a language which does not exist, ie. translating.
4610 // The mask will then become the language trying to edit.
4611 if ( $languageMask == 0 )
4612 {
4613 $languageMask = $language;
4614 }
4615 }
4616 }
4617 else
4618 {
4619 $languageMask = -1;
4620 }
4621 }
4622 // Fetch limit mask for limitation list
4623 $limitMask = eZContentLanguage::maskByLocale( $valueList );
4624 if ( ( $languageMask & $limitMask ) != 0 )
4625 {
4626 $access = 'allowed';
4627 }
4628 else
4629 {
4630 $access = 'denied';
4631 $limitationList = array( 'Limitation' => $key,
4632 'Required' => $valueList );
4633 }
4634 } break;
4635
4636 case 'Owner':
4637 case 'ParentOwner':
4638 {
4639 // if limitation value == 2, anonymous limited to current session.
4640 if ( in_array( 2, $valueList ) &&
4641 $user->isAnonymous() )
4642 {
4643 $createdObjectIDList = eZPreferences::value( 'ObjectCreationIDList' );
4644 if ( $createdObjectIDList &&
4645 in_array( $contentObject->attribute( 'id' ), unserialize( $createdObjectIDList ) ) )
4646 {
4647 $access = 'allowed';
4648 }
4649 }
4650 else if ( $contentObject->attribute( 'owner_id' ) == $userID || $contentObject->attribute( 'id' ) == $userID )
4651 {
4652 $access = 'allowed';
4653 }
4654 if ( $access != 'allowed' )
4655 {
4656 $access = 'denied';
4657 $limitationList = array ( 'Limitation' => $key );
4658 }
4659 } break;
4660
4661 case 'Group':
4662 case 'ParentGroup':
4663 {
4664 $access = $contentObject->checkGroupLimitationAccess( $valueList, $userID );
4665
4666 if ( $access != 'allowed' )
4667 {
4668 $access = 'denied';
4669 $limitationList = array ( 'Limitation' => $key,
4670 'Required' => $valueList );
4671 }
4672 } break;
4673
4674 case 'State':
4675 {
4676 if ( count( array_intersect( $valueList, $contentObject->attribute( 'state_id_array' ) ) ) == 0 )
4677 {
4678 $access = 'denied';
4679 $limitationList = array ( 'Limitation' => $key,
4680 'Required' => $valueList );
4681 }
4682 else
4683 {
4684 $access = 'allowed';
4685 }
4686 } break;
4687
4688 case 'ParentDepth':
4689 {
4690 if ( in_array( $currentNode->attribute( 'depth' ), $valueList ) )
4691 {
4692 $access = 'allowed';
4693 }
4694 else
4695 {
4696 $access = 'denied';
4697 $limitationList = array( 'Limitation' => $key,
4698 'Required' => $valueList );
4699 }
4700 } break;
4701
4702 case 'Node':
4703 {
4704 $accessNode = false;
4705 $mainNodeID = $currentNode->attribute( 'main_node_id' );
4706 foreach ( $valueList as $nodeID )
4707 {
4708 $node = eZContentObjectTreeNode::fetch( $nodeID, false, false );
4709 $limitationNodeID = $node['main_node_id'];
4710 if ( $mainNodeID == $limitationNodeID )
4711 {
4712 $access = 'allowed';
4713 $accessNode = true;
4714 break;
4715 }
4716 }
4717 if ( $access != 'allowed' && $checkedSubtree && !$accessSubtree )
4718 {
4719 $access = 'denied';
4720 // ??? TODO: if there is a limitation on Subtree, return two limitations?
4721 $limitationList = array( 'Limitation' => $key,
4722 'Required' => $valueList );
4723 }
4724 else
4725 {
4726 $access = 'allowed';
4727 }
4728 $checkedNode = true;
4729 } break;
4730
4731 case 'Subtree':
4732 {
4733 $accessSubtree = false;
4734 $path = $currentNode->attribute( 'path_string' );
4735 $subtreeArray = $valueList;
4736 foreach ( $subtreeArray as $subtreeString )
4737 {
4738 if ( strstr( $path, $subtreeString ) )
4739 {
4740 $access = 'allowed';
4741 $accessSubtree = true;
4742 break;
4743 }
4744 }
4745 if ( $access != 'allowed' && $checkedNode && !$accessNode )
4746 {
4747 $access = 'denied';
4748 // ??? TODO: if there is a limitation on Node, return two limitations?
4749 $limitationList = array( 'Limitation' => $key,
4750 'Required' => $valueList );
4751 }
4752 else
4753 {
4754 $access = 'allowed';
4755 }
4756 $checkedSubtree = true;
4757 } break;
4758
4759 case 'User_Subtree':
4760 {
4761 $path = $currentNode->attribute( 'path_string' );
4762 $subtreeArray = $valueList;
4763 foreach ( $subtreeArray as $subtreeString )
4764 {
4765 if ( strstr( $path, $subtreeString ) )
4766 {
4767 $access = 'allowed';
4768 }
4769 }
4770 if ( $access != 'allowed' )
4771 {
4772 $access = 'denied';
4773 $limitationList = array( 'Limitation' => $key,
4774 'Required' => $valueList );
4775 }
4776 } break;
4777
4778 default:
4779 {
4780 if ( strncmp( $key, 'StateGroup_', 11 ) === 0 )
4781 {
4782 if ( count( array_intersect( $valueList, $contentObject->attribute( 'state_id_array' ) ) ) == 0 )
4783 {
4784 $access = 'denied';
4785 $limitationList = array ( 'Limitation' => $key,
4786 'Required' => $valueList );
4787 }
4788 else
4789 {
4790 $access = 'allowed';
4791 }
4792 }
4793 }
4794 }
4795
4796 if ( $access == 'denied' )
4797 {
4798 break;
4799 }
4800 }
4801
4802 $policyList[] = array( 'PolicyID' => $pkey,
4803 'LimitationList' => $limitationList );
4804 }
4805 if ( $access == 'denied' )
4806 {
4807 $accessList = array( 'FunctionRequired' => array ( 'Module' => 'content',
4808 'Function' => $origFunctionName,
4809 'ClassID' => $classID,
4810 'MainNodeID' => $currentNode->attribute( 'main_node_id' ) ),
4811 'PolicyList' => $policyList );
4812 return 0;
4813 }
4814 else
4815 {
4816 return 1;
4817 }
4818 }
4819 }
4820
4821 // code-template::create-block: class-list-from-policy, is-node
4822 // code-template::auto-generated:START class-list-from-policy
4823 // This code is automatically generated from templates/classlistfrompolicy.ctpl
4824 // DO NOT EDIT THIS CODE DIRECTLY, CHANGE THE TEMPLATE FILE INSTEAD
4825
4826 function classListFromPolicy( $policy, $allowedLanguageCodes = false )
4827 {
4828 $canCreateClassIDListPart = array();
4829 $hasClassIDLimitation = false;
4830 $user = eZUser::currentUser();
4831 $userID = $user->attribute( 'contentobject_id' );
4832
4833 $object = false;
4834 if ( isset( $policy['ParentOwner'] ) )
4835 {
4836 if ( $object === false )
4837 $object = $this->attribute( 'object' );
4838
4839 // if limitation value == 2, anonymous limited to current session.
4840 if ( in_array( 2, $policy['ParentOwner'] ) && $user->isAnonymous() )
4841 {
4842 $createdObjectIDList = eZPreferences::value( 'ObjectCreationIDList' );
4843 if ( !$createdObjectIDList ||
4844 !in_array( $object->ID, unserialize( $createdObjectIDList ) ) )
4845 {
4846 return array();
4847 }
4848 }
4849 else if ( $object->attribute( 'owner_id' ) != $userID &&
4850 $object->ID != $userID )
4851 {
4852 return array();
4853 }
4854 }
4855
4856 if ( isset( $policy['ParentGroup'] ) )
4857 {
4858 if ( $object === false )
4859 $object = $this->attribute( 'object' );
4860
4861 $access = $object->checkGroupLimitationAccess( $policy['ParentGroup'], $userID );
4862 if ( $access !== 'allowed' )
4863 {
4864 return array();
4865 }
4866 }
4867
4868 if ( isset( $policy['Class'] ) )
4869 {
4870 $canCreateClassIDListPart = $policy['Class'];
4871 $hasClassIDLimitation = true;
4872 }
4873
4874 if ( isset( $policy['User_Section'] ) )
4875 {
4876 if ( $object === false )
4877 $object = $this->attribute( 'object' );
4878
4879 if ( !in_array( $object->attribute( 'section_id' ), $policy['User_Section'] ) )
4880 {
4881 return array();
4882 }
4883 }
4884
4885 if ( isset( $policy['User_Subtree'] ) )
4886 {
4887 $allowed = false;
4888 if ( $object === false )
4889 $object = $this->attribute( 'object' );
4890
4891 $assignedNodes = $object->attribute( 'assigned_nodes' );
4892 foreach ( $assignedNodes as $assignedNode )
4893 {
4894 $path = $assignedNode->attribute( 'path_string' );
4895 foreach ( $policy['User_Subtree'] as $subtreeString )
4896 {
4897 if ( strstr( $path, $subtreeString ) )
4898 {
4899 $allowed = true;
4900 break;
4901 }
4902 }
4903 }
4904 if( !$allowed )
4905 {
4906 return array();
4907 }
4908 }
4909
4910 if ( isset( $policy['Section'] ) )
4911 {
4912 if ( $object === false )
4913 $object = $this->attribute( 'object' );
4914
4915 if ( !in_array( $object->attribute( 'section_id' ), $policy['Section'] ) )
4916 {
4917 return array();
4918 }
4919 }
4920
4921 if ( isset( $policy['ParentClass'] ) )
4922 {
4923 if ( $object === false )
4924 $object = $this->attribute( 'object' );
4925
4926 if ( !in_array( $object->attribute( 'contentclass_id' ), $policy['ParentClass'] ) )
4927 {
4928 return array();
4929 }
4930 }
4931
4932 if ( isset( $policy['ParentDepth'] ) && is_array( $policy['ParentDepth'] ) )
4933 {
4934 $NodeDepth = $this->attribute( 'depth' );
4935 if ( !in_array( '*', $policy['ParentDepth'] ) && !in_array( $NodeDepth, $policy['ParentDepth'] ) )
4936 {
4937 return array();
4938 }
4939 }
4940
4941 if ( isset( $policy['Assigned'] ) )
4942 {
4943 if ( $object === false )
4944 $object = $this->attribute( 'object' );
4945
4946 if ( $object->attribute( 'owner_id' ) != $userID )
4947 {
4948 return array();
4949 }
4950 }
4951
4952 $allowedNode = false;
4953 if ( isset( $policy['Node'] ) )
4954 {
4955 $allowed = false;
4956 foreach( $policy['Node'] as $nodeID )
4957 {
4958 $mainNodeID = $this->attribute( 'main_node_id' );
4959 $node = eZContentObjectTreeNode::fetch( $nodeID, false, false );
4960 if ( $mainNodeID == $node['main_node_id'] )
4961 {
4962 $allowed = true;
4963 $allowedNode = true;
4964 break;
4965 }
4966 }
4967 if ( !$allowed && !isset( $policy['Subtree'] ) )
4968 {
4969 return array();
4970 }
4971 }
4972
4973 if ( isset( $policy['Subtree'] ) )
4974 {
4975 $allowed = false;
4976 if ( $object === false )
4977 $object = $this->attribute( 'object' );
4978 $assignedNodes = $object->attribute( 'assigned_nodes' );
4979 foreach ( $assignedNodes as $assignedNode )
4980 {
4981 $path = $assignedNode->attribute( 'path_string' );
4982 foreach ( $policy['Subtree'] as $subtreeString )
4983 {
4984 if ( strstr( $path, $subtreeString ) )
4985 {
4986 $allowed = true;
4987 break;
4988 }
4989 }
4990 }
4991 if ( !$allowed && !$allowedNode )
4992 {
4993 return array();
4994 }
4995 }
4996
4997 if ( isset( $policy['Language'] ) )
4998 {
4999 if ( $allowedLanguageCodes )
5000 {
5001 $allowedLanguageCodes = array_intersect( $allowedLanguageCodes, $policy['Language'] );
5002 }
5003 else
5004 {
5005 $allowedLanguageCodes = $policy['Language'];
5006 }
5007 }
5008
5009 if ( $hasClassIDLimitation )
5010 {
5011 return array( 'classes' => $canCreateClassIDListPart, 'language_codes' => $allowedLanguageCodes );
5012 }
5013 return array( 'classes' => '*', 'language_codes' => $allowedLanguageCodes );
5014 }
5015
5016 // This code is automatically generated from templates/classlistfrompolicy.ctpl
5017 // code-template::auto-generated:END class-list-from-policy
5018
5019 // code-template::create-block: can-instantiate-class-list, group-filter, object-policy-list, name-create, object-creation, object-sql-creation, current-subtree-limitation
5020 // code-template::auto-generated:START can-instantiate-class-list
5021 // This code is automatically generated from templates/classcreatelist.ctpl
5022 // DO NOT EDIT THIS CODE DIRECTLY, CHANGE THE TEMPLATE FILE INSTEAD
5023
5029 protected function hasCurrentSubtreeLimitation( array $policy )
5030 {
5031 // No Subtree nor Node limitation, so we consider that it is potentially OK to create content under current subtree
5032 if ( !isset( $policy['Subtree'] ) && !isset( $policy['Node'] ) )
5033 {
5034 return true;
5035 }
5036
5037 // First check subtree limitations
5038 if ( isset( $policy['Subtree'] ) )
5039 {
5040 foreach ( $policy['Subtree'] as $subtreeString )
5041 {
5042 if ( strpos( $this->attribute( 'path_string' ), $subtreeString ) !== false )
5043 {
5044 return true;
5045 }
5046 }
5047 }
5048
5049 // Then check node limitations
5050 if ( isset( $policy['Node'] ) )
5051 {
5052 foreach ( $policy['Node'] as $subtreeString )
5053 {
5054 if ( strpos( $this->attribute( 'path_string' ), $subtreeString ) !== false )
5055 {
5056 return true;
5057 }
5058 }
5059 }
5060
5061 return false;
5062 }
5063
5077 function canCreateClassList( $asObject = false, $includeFilter = true, $groupList = false, $fetchID = false )
5078 {
5079 $ini = eZINI::instance();
5080 $groupArray = array();
5081 $languageCodeList = eZContentLanguage::fetchLocaleList();
5082 $allowedLanguages = array( '*' => array() );
5083
5084 $user = eZUser::currentUser();
5085 $accessResult = $user->hasAccessTo( 'content' , 'create' );
5086 $accessWord = $accessResult['accessWord'];
5087
5088 $classIDArray = array();
5089 $classList = array();
5090 $fetchAll = false;
5091 if ( $accessWord == 'yes' )
5092 {
5093 $fetchAll = true;
5094 $allowedLanguages['*'] = $languageCodeList;
5095 }
5096 else if ( $accessWord == 'no' )
5097 {
5098 // Cannot create any objects, return empty list.
5099 return $classList;
5100 }
5101 else
5102 {
5103 foreach ( $accessResult['policies'] as $policy )
5104 {
5105 $policyArray = $this->classListFromPolicy( $policy, $languageCodeList );
5106 if ( empty( $policyArray ) )
5107 continue;
5108
5109 // Wildcard on all classes
5110 if ( $policyArray['classes'] == '*' )
5111 {
5112 $fetchAll = true;
5113 $allowedLanguages['*'] = array_unique( array_merge( $allowedLanguages['*'], $policyArray['language_codes'] ) );
5114
5115 // we remove individual class ids that are overriden in all languages by the wildcard (#EZP-20933)
5116 foreach ( $allowedLanguages as $classId => $classLanguageCodes )
5117 {
5118 if ( $classId == '*' )
5119 continue;
5120
5121 if ( !count( array_diff( $classLanguageCodes, $allowedLanguages['*'] ) ) )
5122 {
5123 unset( $allowedLanguages[$classId] );
5124 }
5125 }
5126 }
5127 else if ( is_array( $policyArray['classes'] ) && $this->hasCurrentSubtreeLimitation( $policy ) )
5128 {
5129 foreach( $policyArray['classes'] as $class )
5130 {
5131 if ( isset( $allowedLanguages[$class] ) )
5132 {
5133 $allowedLanguages[$class] = array_unique( array_merge( $allowedLanguages[$class], $policyArray['language_codes'] ) );
5134 }
5135 else
5136 {
5137 // we don't add class identifiers that are already covered by the 'all classes' in a language
5138 if ( !empty( $allowedLanguages['*'] ) )
5139 {
5140 if ( !count( array_diff( $policyArray['language_codes'], $allowedLanguages['*'] ) ) )
5141 {
5142 continue;
5143 }
5144 }
5145 $allowedLanguages[$class] = $policyArray['language_codes'];
5146 }
5147 }
5148 $classIDArray = array_merge( $classIDArray, array_diff( $policyArray['classes'], $classIDArray ) );
5149 }
5150 }
5151 }
5152
5153 $db = eZDB::instance();
5154
5155 $filterTableSQL = '';
5156 $filterSQL = '';
5157 // Create extra SQL statements for the class group filters.
5158 if ( is_array( $groupList ) )
5159 {
5160 if ( count( $groupList ) == 0 )
5161 {
5162 return $classList;
5163 }
5164
5165 $filterTableSQL = ', ezcontentclass_classgroup ccg';
5166 $filterSQL = ( " AND" .
5167 " cc.id = ccg.contentclass_id AND" .
5168 " " );
5169 $filterSQL .= $db->generateSQLINStatement( $groupList, 'ccg.group_id', !$includeFilter, true, 'int' );
5170 }
5171
5172 $classNameFilter = eZContentClassName::sqlFilter( 'cc' );
5173
5174 if ( $fetchAll )
5175 {
5176 // If $asObject is true we fetch all fields in class
5177 $fields = $asObject ? "cc.*, $classNameFilter[nameField]" : "cc.id, $classNameFilter[nameField]";
5178 $rows = $db->arrayQuery( "SELECT DISTINCT $fields " .
5179 "FROM ezcontentclass cc$filterTableSQL, $classNameFilter[from] " .
5180 "WHERE cc.version = " . eZContentClass::VERSION_STATUS_DEFINED . " $filterSQL AND $classNameFilter[where] " .
5181 "ORDER BY $classNameFilter[nameField] ASC" );
5182 $classList = eZPersistentObject::handleRows( $rows, 'eZContentClass', $asObject );
5183 }
5184 else
5185 {
5186 // If the constrained class list is empty we are not allowed to create any class
5187 if ( count( $classIDArray ) == 0 )
5188 {
5189 return $classList;
5190 }
5191
5192 $classIDCondition = $db->generateSQLINStatement( $classIDArray, 'cc.id' );
5193 // If $asObject is true we fetch all fields in class
5194 $fields = $asObject ? "cc.*, $classNameFilter[nameField]" : "cc.id, $classNameFilter[nameField]";
5195 $rows = $db->arrayQuery( "SELECT DISTINCT $fields " .
5196 "FROM ezcontentclass cc$filterTableSQL, $classNameFilter[from] " .
5197 "WHERE $classIDCondition AND" .
5198 " cc.version = " . eZContentClass::VERSION_STATUS_DEFINED . " $filterSQL AND $classNameFilter[where] " .
5199 "ORDER BY $classNameFilter[nameField] ASC" );
5200 $classList = eZPersistentObject::handleRows( $rows, 'eZContentClass', $asObject );
5201 }
5202
5203 if ( $asObject )
5204 {
5205 foreach ( $classList as $key => $class )
5206 {
5207 $id = $class->attribute( 'id' );
5208 if ( isset( $allowedLanguages[$id] ) )
5209 {
5210 $languageCodes = array_unique( array_merge( $allowedLanguages['*'], $allowedLanguages[$id] ) );
5211 }
5212 else
5213 {
5214 $languageCodes = $allowedLanguages['*'];
5215 }
5216 $classList[$key]->setCanInstantiateLanguages( $languageCodes );
5217 }
5218 }
5219
5220 eZDebugSetting::writeDebug( 'kernel-content-class', $classList, "class list fetched from db" );
5221 return $classList;
5222 }
5223
5224 // This code is automatically generated from templates/classcreatelist.ctpl
5225 // code-template::auto-generated:END can-instantiate-class-list
5226
5227 static public function makeObjectsArray( $array , $with_contentobject = true, array|null $propertiesOverride = null, $lang = null )
5228 {
5229 $retNodes = array();
5230 if ( !is_array( $array ) )
5231 return $retNodes;
5232
5233 foreach ( $array as $node )
5234 {
5235 if ( $propertiesOverride !== null )
5236 {
5237 $node = $propertiesOverride + $node;
5238 }
5239
5240 if ( $node['node_id'] == 1 && (!array_key_exists( 'name', $node ) || !$node['name'] ) )
5241 {
5242 $node['name'] = ezpI18n::tr( 'kernel/content', 'Top Level Nodes' );
5243 }
5244
5245 $object = new eZContentObjectTreeNode(
5246 array(
5247 "node_id" => $node["node_id"],
5248 "parent_node_id" => $node["parent_node_id"],
5249 "main_node_id" => $node["main_node_id"],
5250 "contentobject_id" => isset( $node["id"] ) ? $node["id"] : $node["contentobject_id"],
5251 "contentobject_version" => $node["contentobject_version"],
5252 "contentobject_is_published" => $node["contentobject_is_published"],
5253 "depth" => $node["depth"],
5254 "sort_field" => $node["sort_field"],
5255 "sort_order" => $node["sort_order"],
5256 "priority" => $node["priority"],
5257 "modified_subnode" => $node["modified_subnode"],
5258 "path_string" => $node["path_string"],
5259 "path_identification_string" => $node["path_identification_string"],
5260 "remote_id" => $node["remote_id"],
5261 "is_hidden" => $node["is_hidden"],
5262 "is_invisible" => $node["is_invisible"],
5263 )
5264 );
5265 // If the name is not set it will be fetched later on when
5266 // getName()/attribute( 'name' ) is accessed.
5267 if ( isset( $node['name'] ) )
5268 {
5269 $object->setName( $node['name'] );
5270 }
5271
5272 if ( isset( $node['class_serialized_name_list'] ) )
5273 {
5274 $node['class_name'] = eZContentClass::nameFromSerializedString( $node['class_serialized_name_list'] );
5275 $object->ClassName = $node['class_name'];
5276 }
5277 if ( isset( $node['class_identifier'] ) )
5278 $object->ClassIdentifier = $node['class_identifier'];
5279
5280 if ( isset( $node['is_container'] ) )
5281 $object->ClassIsContainer = $node['is_container'];
5282
5283 if ( $with_contentobject )
5284 {
5285 if ( isset( $node['class_name'] ) )
5286 {
5287 $row = array(
5288 "id" => $node["id"],
5289 "section_id" => $node["section_id"],
5290 "owner_id" => $node["owner_id"],
5291 "contentclass_id" => $node["contentclass_id"],
5292 "name" => $node["name"],
5293 "published" => $node["published"],
5294 "modified" => $node["modified"],
5295 "current_version" => $node["current_version"],
5296 "status" => $node["status"],
5297 "remote_id" => $node["object_remote_id"],
5298 "language_mask" => $node["language_mask"],
5299 "initial_language_id" => $node["initial_language_id"],
5300 "class_name" => $node["class_name"],
5301 );
5302
5303 if ( isset( $node['class_identifier'] ) )
5304 $row['class_identifier'] = $node['class_identifier'];
5305
5306 $contentObject = new eZContentObject( $row );
5307 }
5308 else
5309 {
5310 $contentObject = new eZContentObject( array() );
5311 if ( isset( $node['name'] ) )
5312 $contentObject->setCachedName( $node['name'] );
5313 }
5314 if ( isset( $node['real_translation'] ) && $node['real_translation'] != '' )
5315 {
5316 if ( $node['real_translation'] == $lang )
5317 {
5318 $object->CurrentLanguage = $node['real_translation'];
5319 }
5320
5321 $contentObject->CurrentLanguage = $node['real_translation'];
5322 }
5323 if ( $node['node_id'] == 1 )
5324 {
5325 $contentObject->ClassName = 'Folder';
5326 $contentObject->ClassIdentifier = 'folder';
5327 $contentObject->ClassID = 1;
5328 $contentObject->SectionID = 1;
5329 }
5330
5331 $object->setContentObject( $contentObject );
5332 }
5333 $retNodes[] = $object;
5334 }
5335 return $retNodes;
5336 }
5337
5342 static function getParentNodeId( $nodeID )
5343 {
5344 if ( !isset( $nodeID ) )
5345 return null;
5346 $db = eZDB::instance();
5347 $nodeID =(int) $nodeID;
5348 $parentArr = $db->arrayQuery( "SELECT
5349 parent_node_id
5350 FROM
5351 ezcontentobject_tree
5352 WHERE
5353 node_id = $nodeID");
5354 return $parentArr[0]['parent_node_id'];
5355 }
5356
5368 static function getParentNodeIdListByContentObjectID( $objectIDs, $groupByObjectId = false, $onlyMainNode = false )
5369 {
5370 if ( !$objectIDs )
5371 return null;
5372 if ( !is_array( $objectIDs ) )
5373 $objectIDs = array( $objectIDs );
5374
5375 $db = eZDB::instance();
5376 $query = 'SELECT
5377 parent_node_id, contentobject_id
5378 FROM
5379 ezcontentobject_tree
5380 WHERE ' . $db->generateSQLINStatement( $objectIDs, 'contentobject_id', false, false, 'int' );
5381
5382 if ( $onlyMainNode )
5383 {
5384 $query .= ' AND node_id = main_node_id';
5385 }
5386
5387 $list = $db->arrayQuery( $query );
5388 $parentNodeIDs = array();
5389 if ( $groupByObjectId )
5390 {
5391 foreach( $list as $item )
5392 {
5393 $objectID = $item['contentobject_id'];
5394 if ( !isset( $parentNodeIDs[$objectID] ) )
5395 {
5396 $parentNodeIDs[$objectID] = array();
5397 }
5398 $parentNodeIDs[$objectID][] = $item['parent_node_id'];
5399 }
5400 }
5401 else
5402 {
5403 foreach( $list as $item )
5404 {
5405 $parentNodeIDs[] = $item['parent_node_id'];
5406 }
5407 }
5408 return $parentNodeIDs;
5409 }
5410
5415 static function deleteNodeWhereParent( $node, $id )
5416 {
5417 eZContentObjectTreeNode::removeNode( eZContentObjectTreeNode::findNode( $node, $id ) );
5418
5419 }
5420
5421 static function findNode( $parentNode, $id, $asObject = false, $remoteID = false )
5422 {
5423 if ( !isset( $parentNode) || $parentNode == NULL )
5424 {
5425 $parentNode = 2;
5426 }
5427 $propertiesOverride = array( "parent_node_id" => $parentNode = (int) $parentNode );
5428 $db = eZDB::instance();
5429 if ( $asObject )
5430 {
5431 if ( $remoteID )
5432 {
5433 $objectIDFilter = "ezcontentobject.remote_id = '" . $db->escapeString( $id ) . "'";
5434 $propertiesOverride["object_remote_id"] = $id;
5435 }
5436 else
5437 {
5438 $objectIDFilter = 'contentobject_id = ' . (int) $id;
5439 $propertiesOverride["id"] = $id;
5440 }
5441
5442 $retNodeArray = eZContentObjectTreeNode::makeObjectsArray(
5443 $db->arrayQuery(
5444 "SELECT " .
5445 "ezcontentobject.contentclass_id, ezcontentobject.current_version, " .
5446 ( !isset( $propertiesOverride["id"] ) ? "ezcontentobject.id, " : "" ) .
5447 "ezcontentobject.initial_language_id, ezcontentobject.language_mask, ezcontentobject.modified, " .
5448 "ezcontentobject.name, ezcontentobject.owner_id, ezcontentobject.published, " .
5449 ( !isset( $propertiesOverride["object_remote_id"] ) ? "ezcontentobject.remote_id AS object_remote_id, " : "" ) .
5450 "ezcontentobject.section_id, ezcontentobject.status, " .
5451 "ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, " .
5452 "ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, ezcontentobject_tree.node_id, " .
5453 "ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, " .
5454 "ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, ezcontentclass.identifier as class_identifier, ezcontentclass.is_container " .
5455 "FROM ezcontentobject_tree " .
5456 "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " .
5457 "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id AND ezcontentclass.version = 0) " .
5458 "WHERE parent_node_id = $parentNode AND " .
5459 $objectIDFilter
5460 ),
5461 true,
5462 $propertiesOverride
5463 );
5464
5465 if ( !empty( $retNodeArray ) )
5466 {
5467 return $retNodeArray[0];
5468 }
5469 else
5470 {
5471 return null;
5472 }
5473 }
5474 else
5475 {
5476 $id = (int) $id;
5477 $getNodeQuery = "SELECT node_id
5478 FROM ezcontentobject_tree
5479 WHERE
5480 parent_node_id=$parentNode AND
5481 contentobject_id = $id ";
5482 $nodeArr = $db->arrayQuery( $getNodeQuery );
5483 if ( isset( $nodeArr[0] ) )
5484 {
5485 return $nodeArr[0]['node_id'];
5486 }
5487 else
5488 {
5489 return false;
5490 }
5491 }
5492 }
5493
5494 function getName( $language = false )
5495 {
5496 // If the name is not set yet we fetch it from the object table
5497 if ( $this->Name === null || $language !== false )
5498 {
5499 $db = eZDB::instance();
5500 if ( $this->CurrentLanguage || $language !== false )
5501 {
5502 $sql = "SELECT name FROM ezcontentobject_name WHERE"
5503 . " contentobject_id=" . (int)$this->ContentObjectID
5504 . " AND content_version=" . (int)$this->attribute( 'contentobject_version' )
5505 . " AND real_translation='" . $db->escapeString( $language ?: $this->CurrentLanguage ) . "'";
5506 }
5507 else
5508 {
5509 $sql = "SELECT name FROM ezcontentobject WHERE id=" . (int) $this->ContentObjectID;
5510 }
5511 $rows = $db->arrayQuery( $sql );
5512 if ( count( $rows ) > 0 )
5513 {
5514 if ( $language !== false )
5515 {
5516 return $rows[0]['name'];
5517 }
5518 $this->Name = $rows[0]['name'];
5519 }
5520 else
5521 {
5522 if ( $language !== false )
5523 {
5524 return false;
5525 }
5526 $this->Name = false;
5527 }
5528 }
5529 return $this->Name;
5530 }
5531
5532 function setName( $name )
5533 {
5534 $this->Name = $name;
5535 }
5536
5550 static function unserialize( $contentNodeDOMNode, $contentObject, $version, $isMain, &$nodeList, &$options, $handlerType = 'ezcontentobject' )
5551 {
5552 $parentNodeID = -1;
5553
5554 $remoteID = $contentNodeDOMNode->getAttribute( 'remote-id' );
5555 $parentNodeRemoteID = $contentNodeDOMNode->getAttribute( 'parent-node-remote-id' );
5556 $node = eZContentObjectTreeNode::fetchByRemoteID( $remoteID );
5557 if ( is_object( $node ) )
5558 {
5559 $description = "Node with remote ID $remoteID already exists.";
5560
5561 $choosenAction = eZPackageHandler::errorChoosenAction( eZContentObject::PACKAGE_ERROR_EXISTS,
5562 $options, $description, $handlerType, false );
5563
5564 switch( $choosenAction )
5565 {
5566 // In case user have choosen "Keep existing object and create new"
5567 case eZContentObject::PACKAGE_NEW:
5568 {
5569 $newRemoteID = eZRemoteIdUtility::generate( 'node' );
5570 $node->setAttribute( 'remote_id', $newRemoteID );
5571 $node->store();
5572 $nodeInfo = array( 'contentobject_id' => $node->attribute( 'contentobject_id' ),
5573 'contentobject_version' => $node->attribute( 'contentobject_version' ),
5574 'parent_remote_id' => $remoteID );
5575 $nodeAssignment = eZPersistentObject::fetchObject( eZNodeAssignment::definition(),
5576 null,
5577 $nodeInfo );
5578 if ( is_object( $nodeAssignment ) )
5579 {
5580 $nodeAssignment->setAttribute( 'parent_remote_id', $newRemoteID );
5581 $nodeAssignment->store();
5582 }
5583 } break;
5584
5585 // When running non-interactively with ezpm.php
5586 case eZPackage::NON_INTERACTIVE:
5587 case eZContentObject::PACKAGE_UPDATE:
5588 {
5589 // Update existing node settigns.
5590 if ( !$parentNodeRemoteID )
5591 {
5592 // when top node of subtree export, only update node sort field and sort order
5593 $node->setAttribute( 'sort_field', eZContentObjectTreeNode::sortFieldID( $contentNodeDOMNode->getAttribute( 'sort-field' ) ) );
5594 $node->setAttribute( 'sort_order', $contentNodeDOMNode->getAttribute( 'sort-order' ) );
5595 $node->store();
5596 return true;
5597 }
5598 } break;
5599
5600 default:
5601 {
5602 // This error may occur only if data integrity is broken
5603 $options['error'] = array( 'error_code' => eZContentObject::PACKAGE_ERROR_NODE_EXISTS,
5604 'element_id' => $remoteID,
5605 'description' => $description );
5606 return false;
5607 } break;
5608 }
5609 }
5610
5611 if ( $parentNodeRemoteID )
5612 {
5613 $parentNode = eZContentObjectTreeNode::fetchByRemoteID( $parentNodeRemoteID );
5614 if ( $parentNode !== null )
5615 {
5616 $parentNodeID = $parentNode->attribute( 'node_id' );
5617 }
5618 }
5619 else
5620 {
5621 if ( isset( $options['top_nodes_map'][$contentNodeDOMNode->getAttribute( 'node-id' )]['new_node_id'] ) )
5622 {
5623 $parentNodeID = $options['top_nodes_map'][$contentNodeDOMNode->getAttribute( 'node-id' )]['new_node_id'];
5624 }
5625 else if ( isset( $options['top_nodes_map']['*'] ) )
5626 {
5627 $parentNodeID = $options['top_nodes_map']['*'];
5628 }
5629 else
5630 {
5631 eZDebug::writeError( 'New parent node not set ' . $contentNodeDOMNode->getAttribute( 'name' ), __METHOD__ );
5632 }
5633 }
5634
5635 $isMain = ( $isMain && $contentNodeDOMNode->getAttribute( 'is-main-node' ) );
5636
5637 $nodeInfo = array( 'contentobject_id' => $contentObject->attribute( 'id' ),
5638 'contentobject_version' => $version,
5639 'is_main' => $isMain,
5640 'parent_node' => $parentNodeID,
5641 'parent_remote_id' => $remoteID, // meaning processed node remoteID (not parent)
5642 'sort_field' => eZContentObjectTreeNode::sortFieldID( $contentNodeDOMNode->getAttribute( 'sort-field' ) ),
5643 'sort_order' => $contentNodeDOMNode->getAttribute( 'sort-order' ) );
5644
5645 if ( $parentNodeID == -1 && $parentNodeRemoteID )
5646 {
5647 if ( !isset( $options['suspended-nodes'] ) )
5648 {
5649 $options['suspended-nodes'] = array();
5650 }
5651
5652 $options['suspended-nodes'][$parentNodeRemoteID] = array( 'nodeinfo' => $nodeInfo,
5653 'priority' => $contentNodeDOMNode->getAttribute( 'priority' ) );
5654 return true;
5655 }
5656
5657 $existNodeAssignment = eZPersistentObject::fetchObject( eZNodeAssignment::definition(),
5658 null,
5659 $nodeInfo );
5660 $nodeInfo['priority'] = $contentNodeDOMNode->getAttribute( 'priority' );
5661 if( !is_object( $existNodeAssignment ) )
5662 {
5663 $nodeAssignment = eZNodeAssignment::create( $nodeInfo );
5664 $nodeList[] = $nodeInfo;
5665 $nodeAssignment->store();
5666 }
5667
5668 return true;
5669 }
5670
5678 function serialize( $options, $contentNodeIDArray, $topNodeIDArray )
5679 {
5680 if ( $options['node_assignment'] == 'main' &&
5681 $this->attribute( 'main_node_id' ) != $this->attribute( 'node_id' ) )
5682 {
5683 return false;
5684 }
5685 if ( ! in_array( $this->attribute( 'node_id' ), array_keys( $contentNodeIDArray ) ) )
5686 {
5687 return false;
5688 }
5689
5690 $dom = new DOMDocument( '1.0', 'utf-8' );
5691
5692 $nodeAssignmentNode = $dom->createElement( 'node-assignment' );
5693 if ( $this->attribute( 'main_node_id' ) == $this->attribute( 'node_id' ) )
5694 {
5695 $nodeAssignmentNode->setAttribute( 'is-main-node', 1 );
5696 }
5697 if( !in_array( $this->attribute( 'node_id'), $topNodeIDArray ) )
5698 {
5699 $parentNode = $this->attribute( 'parent' );
5700 $nodeAssignmentNode->setAttribute( 'parent-node-remote-id', $parentNode->attribute( 'remote_id' ) );
5701 }
5702 $nodeAssignmentNode->setAttribute( 'name', $this->attribute( 'name' ) );
5703 $nodeAssignmentNode->setAttribute( 'node-id', $this->attribute( 'node_id' ) );
5704 $nodeAssignmentNode->setAttribute( 'remote-id', $this->attribute( 'remote_id' ) );
5705 $nodeAssignmentNode->setAttribute( 'sort-field', eZContentObjectTreeNode::sortFieldName( $this->attribute( 'sort_field' ) ) );
5706 $nodeAssignmentNode->setAttribute( 'sort-order', $this->attribute( 'sort_order' ) );
5707 $nodeAssignmentNode->setAttribute( 'priority', $this->attribute( 'priority' ) );
5708 return $nodeAssignmentNode;
5709 }
5710
5716 function updateAndStoreModified()
5717 {
5718 $pathString = trim( $this->attribute( 'path_string' ), '/' );
5719
5720 // during publishing, a temporary path is generated. The update query shouldn't be executed as it doesn't affect anything
5721 if ( $pathString == 'TEMPPATH' )
5722 return;
5723 $pathArray = explode( '/', $pathString );
5724
5725 if ( count( $pathArray ) > 0 )
5726 {
5727 $db = eZDB::instance();
5728 $db->query( 'UPDATE ezcontentobject_tree SET modified_subnode=' . time() .
5729 ' WHERE ' . $db->generateSQLINStatement( $pathArray, 'node_id', false, true, 'int' ) );
5730 }
5731 }
5732
5737 function store( $fieldFilters = null )
5738 {
5739 $db = eZDB::instance();
5740
5741 $db->begin();
5742 parent::store( $fieldFilters );
5743 $this->updateAndStoreModified();
5744 $db->commit();
5745 }
5746
5752 function object()
5753 {
5754 if ( $this->hasContentObject() )
5755 {
5756 return $this->ContentObject;
5757 }
5758 $contentobject_id = $this->attribute( 'contentobject_id' );
5759 $obj = eZContentObject::fetch( $contentobject_id );
5760 if ( $this->CurrentLanguage )
5761 {
5762 $obj->setCurrentLanguage( $this->CurrentLanguage );
5763 }
5764 $this->ContentObject = $obj;
5765 return $obj;
5766 }
5767
5773 function hasContentObject()
5774 {
5775 if ( isset( $this->ContentObject ) && $this->ContentObject instanceof eZContentObject )
5776 return true;
5777 else
5778 return false;
5779 }
5780
5786 function setContentObject( $object )
5787 {
5788 $this->ContentObject = $object;
5789 }
5790
5796 function creator()
5797 {
5798 $db = eZDB::instance();
5799 $query = "SELECT creator_id
5800 FROM ezcontentobject_version
5801 WHERE
5802 contentobject_id = '$this->ContentObjectID' AND
5803 version = '$this->ContentObjectVersion' ";
5804
5805 $creatorArray = $db->arrayQuery( $query );
5806 return eZContentObject::fetch( $creatorArray[0]['creator_id'] );
5807 }
5808
5815 function contentObjectVersionObject( $asObject = true )
5816 {
5817 $version = eZContentObjectVersion::fetchVersion( $this->ContentObjectVersion, $this->ContentObjectID, $asObject );
5818 if ( $this->CurrentLanguage != false )
5819 {
5820 $version->CurrentLanguage = $this->CurrentLanguage;
5821 }
5822 return $version;
5823 }
5824
5830 function urlAlias()
5831 {
5832 $useURLAlias =& $GLOBALS['eZContentObjectTreeNodeUseURLAlias'];
5833 $ini = eZINI::instance();
5834 $cleanURL = '';
5835 if ( !isset( $useURLAlias ) )
5836 {
5837 $useURLAlias = $ini->variable( 'URLTranslator', 'Translation' ) == 'enabled';
5838 }
5839 if ( $useURLAlias )
5840 {
5841 $path = $this->pathWithNames();
5842 if ( $ini->hasVariable( 'SiteAccessSettings', 'PathPrefix' ) &&
5843 $ini->variable( 'SiteAccessSettings', 'PathPrefix' ) != '' )
5844 {
5845 $prepend = $ini->variable( 'SiteAccessSettings', 'PathPrefix' );
5846 $pathIdenStr = substr( $prepend, strlen( $prepend ) -1 ) == '/'
5847 ? $path . '/'
5848 : $path;
5849 if ( strncasecmp( $pathIdenStr, $prepend, strlen( $prepend ) ) == 0 )
5850 $cleanURL = eZURLAliasML::cleanURL( substr( $path, strlen( $prepend ) ) );
5851 else
5852 $cleanURL = eZURLAliasML::cleanURL( $path );
5853 }
5854 else
5855 {
5856 $cleanURL = eZURLAliasML::cleanURL( $path );
5857 }
5858 }
5859 else
5860 {
5861 $cleanURL = eZURLAliasML::cleanURL( 'content/view/full/' . $this->NodeID );
5862 }
5863
5864 return $cleanURL;
5865 }
5866
5872 function url()
5873 {
5874 $ini = eZINI::instance();
5875 if ( $ini->variable( 'URLTranslator', 'Translation' ) == 'enabled' )
5876 {
5877 return $this->urlAlias();
5878 }
5879 return 'content/view/full/' . $this->NodeID;
5880 }
5881
5887 public function classIdentifier()
5888 {
5889 if ( $this->ClassIdentifier === null )
5890 {
5891 $object = $this->object();
5892 $this->ClassIdentifier = $object->contentClassIdentifier();
5893 }
5894
5895 return $this->ClassIdentifier;
5896 }
5897
5903 public function className()
5904 {
5905 if ( $this->ClassName === null )
5906 {
5907 $object = $this->object();
5908 $class = $object->contentClass();
5909 $this->ClassName = $class->attribute( 'name' );
5910 }
5911
5912 return $this->ClassName;
5913 }
5914
5920 public function classIsContainer()
5921 {
5922 if ( $this->ClassIsContainer === null )
5923 {
5924 $object = $this->object();
5925 $class = $object->contentClass();
5926 $this->ClassIsContainer = $class->attribute( 'is_container' );
5927 }
5928 return $this->ClassIsContainer;
5929 }
5930
5937 function hiddenInvisibleString()
5938 {
5939 return ( $this->IsHidden ? 'H' : '-' ) . '/' . ( $this->IsInvisible ? 'X' : '-' );
5940 }
5941
5948 function hiddenStatusString()
5949 {
5950 if( $this->IsHidden )
5951 {
5952 return ezpI18n::tr( 'kernel/content', 'Hidden' );
5953 }
5954 else if( $this->IsInvisible )
5955 {
5956 return ezpI18n::tr( 'kernel/content', 'Hidden by superior' );
5957 }
5958 return ezpI18n::tr( 'kernel/content', 'Visible' );
5959 }
5960
5985 static function hideSubTree( eZContentObjectTreeNode $node, $modifyRootNode = true )
5986 {
5987 $nodeID = (int)$node->attribute( 'node_id' );
5988 $time = (int)time();
5989 $db = eZDB::instance();
5990
5991 if ( eZAudit::isAuditEnabled() )
5992 {
5993 // Set audit params.
5994 $objectID = $node->attribute( 'contentobject_id' );
5995 $objectName = $node->attribute( 'name' );
5996 eZAudit::writeAudit( 'content-hide', array( 'Node ID' => $nodeID,
5997 'Object ID' => $objectID,
5998 'Content Name' => $objectName,
5999 'Time' => $time,
6000 'Comment' => 'Node has been hidden: eZContentObjectTreeNode::hideSubTree()' ) );
6001 }
6002
6003 $db->begin();
6004
6005 if ( !$node->attribute( 'is_invisible' ) ) // if root node is visible
6006 {
6007 // 1) Mark root node as hidden and invisible.
6008 if ( $modifyRootNode )
6009 $db->query( "UPDATE ezcontentobject_tree SET is_hidden=1, is_invisible=1, modified_subnode=$time WHERE node_id=$nodeID" );
6010
6011 // 2) Recursively mark child nodes as invisible, except for ones which have been previously marked as invisible.
6012 $nodePath = $db->escapeString( $node->attribute( 'path_string' ) );
6013 $db->query( "UPDATE ezcontentobject_tree SET is_invisible=1, modified_subnode=$time WHERE is_invisible=0 AND path_string LIKE '$nodePath%'" );
6014 }
6015 else
6016 {
6017 // Mark root node as hidden
6018 if ( $modifyRootNode )
6019 $db->query( "UPDATE ezcontentobject_tree SET is_hidden=1, modified_subnode=$time WHERE node_id=$nodeID" );
6020 }
6021
6022 $node->updateAndStoreModified();
6023
6024 $db->commit();
6025
6026 eZContentObjectTreeNode::clearViewCacheForSubtree( $node, $modifyRootNode );
6027 }
6028
6049 static function unhideSubTree( eZContentObjectTreeNode $node, $modifyRootNode = true )
6050 {
6051 $nodeID = (int)$node->attribute( 'node_id' );
6052 $db = eZDB::instance();
6053 $nodePath = $db->escapeString( $node->attribute( 'path_string' ) );
6054 $nodeInvisible = $node->attribute( 'is_invisible' );
6055 $parentNode = $node->attribute( 'parent' );
6056 if ( !$parentNode instanceof eZContentObjectTreeNode )
6057 {
6058 eZDebug::writeError( "Parent of Node #$nodeID doesn't exist or inaccesible.", __METHOD__ );
6059 return;
6060 }
6061
6062 $time = time();
6063
6064 if ( eZAudit::isAuditEnabled() )
6065 {
6066 // Set audit params.
6067 $objectID = $node->attribute( 'contentobject_id' );
6068 $objectName = $node->attribute( 'name' );
6069
6070 eZAudit::writeAudit( 'content-hide', array( 'Node ID' => $nodeID,
6071 'Object ID' => $objectID,
6072 'Content Name' => $objectName,
6073 'Time' => $time,
6074 'Comment' => 'Node has been unhidden: eZContentObjectTreeNode::unhideSubTree()' ) );
6075 }
6076
6077 $db->begin();
6078
6079 if ( ! $parentNode->attribute( 'is_invisible' ) ) // if parent node is visible
6080 {
6081 // 1) Mark root node as not hidden and visible.
6082 if ( $modifyRootNode )
6083 $db->query( "UPDATE ezcontentobject_tree SET is_invisible=0, is_hidden=0, modified_subnode=$time WHERE node_id=$nodeID" );
6084
6085 // 2) Recursively mark child nodes as visible (except for nodes previosly marked as hidden, and all their children).
6086
6087 // 2.1) $hiddenChildren = Fetch all hidden children for the root node
6088 $hiddenChildren = $db->arrayQuery( "SELECT path_string FROM ezcontentobject_tree " .
6089 "WHERE node_id <> $nodeID AND is_hidden=1 AND path_string LIKE '$nodePath%'" );
6090 $skipSubtreesString = '';
6091 foreach ( $hiddenChildren as $i )
6092 $skipSubtreesString .= " AND path_string NOT LIKE '" . $db->escapeString( $i['path_string'] ) . "%'";
6093
6094 // 2.2) Mark those children as visible which are not under nodes in $hiddenChildren
6095 $db->query( "UPDATE ezcontentobject_tree SET is_invisible=0, modified_subnode=$time WHERE path_string LIKE '$nodePath%' $skipSubtreesString" );
6096 }
6097 else
6098 {
6099 // Mark root node as not hidden.
6100 if ( $modifyRootNode )
6101 $db->query( "UPDATE ezcontentobject_tree SET is_hidden=0, modified_subnode=$time WHERE node_id=$nodeID" );
6102 }
6103
6104 $node->updateAndStoreModified();
6105
6106 $db->commit();
6107
6108 eZContentObjectTreeNode::clearViewCacheForSubtree( $node, $modifyRootNode );
6109 }
6110
6119 static function updateNodeVisibility( $node, $parentNode, $recursive = true )
6120 {
6121 if ( !$node )
6122 {
6123 eZDebug::writeWarning( 'No such node to update visibility for.' );
6124 return;
6125 }
6126
6127 if ( !$parentNode )
6128 {
6129 eZDebug::writeWarning( 'No parent node found when updating node visibility' );
6130 return;
6131 }
6132
6133 if ( $node->attribute( 'is_hidden' ) == 0 &&
6134 $parentNode->attribute( 'is_invisible' ) != $node->attribute( 'is_invisible' ) )
6135 {
6136 $parentNodeIsVisible = $parentNode->attribute( 'is_invisible' );
6137 $nodeID = $node->attribute( 'node_id' );
6138 $db = eZDB::instance();
6139 $db->begin();
6140 $db->query( "UPDATE ezcontentobject_tree SET is_invisible=$parentNodeIsVisible WHERE node_id=$nodeID" );
6141
6142 if ( $recursive )
6143 {
6144 // update visibility for children of the node
6145 if( $parentNodeIsVisible )
6146 eZContentObjectTreeNode::hideSubTree( $node, $modifyRootNode = false );
6147 else
6148 eZContentObjectTreeNode::unhideSubTree( $node, $modifyRootNode = false );
6149 }
6150 $db->commit();
6151 }
6152 }
6153
6161 static function clearViewCacheForSubtree( eZContentObjectTreeNode $node, $clearForRootNode = true )
6162 {
6163 // Max nodes to fetch at a time
6164 static $limit = 200;
6165
6166 if ( $clearForRootNode )
6167 {
6168 $objectID = $node->attribute( 'contentobject_id' );
6169 eZContentCacheManager::clearContentCacheIfNeeded( $objectID );
6170 }
6171
6172 $offset = 0;
6173 $params = array( 'AsObject' => false,
6174 'Depth' => false,
6175 'Limitation' => array() ); // Empty array means no permission checking
6176 $subtreeCount = $node->subTreeCount( $params );
6177 while ( $offset < $subtreeCount )
6178 {
6179 $params['Offset'] = $offset;
6180 $params['Limit'] = $limit;
6181
6182 $subtreeChunk = $node->subTree( $params );
6183 $nNodesInChunk = count( $subtreeChunk );
6184 $offset += $nNodesInChunk;
6185 if ( $nNodesInChunk == 0 )
6186 break;
6187
6188 $objectIDList = array();
6189 foreach ( $subtreeChunk as $curNode )
6190 $objectIDList[] = $curNode['id'];
6191 unset( $subtreeChunk );
6192
6193 eZContentCacheManager::clearContentCacheIfNeeded( array_unique( $objectIDList ) );
6194 }
6195
6196 return true;
6197 }
6198
6205 static function setVersionByObjectID( $objectID, $newVersion )
6206 {
6207 $db = eZDB::instance();
6208 $db->query( "UPDATE ezcontentobject_tree SET contentobject_version='$newVersion' WHERE contentobject_id='$objectID'" );
6209 }
6210
6216 function currentLanguage()
6217 {
6218 return $this->CurrentLanguage;
6219 }
6220
6226 function setCurrentLanguage( $languageCode )
6227 {
6228 $this->CurrentLanguage = $languageCode;
6229 if ( $this->hasContentObject() )
6230 {
6231 $this->ContentObject->setCurrentLanguage( $languageCode );
6232 }
6233 $this->Name = null;
6234 }
6235
6239 static function parentDepthLimitationList()
6240 {
6241 $maxLevel = 0;
6242 $ini = eZINI::instance();
6243 if ( $ini->hasVariable( 'RoleSettings', 'MaxParentDepthLimitation' ) )
6244 $maxLevel = $ini->variable( 'RoleSettings', 'MaxParentDepthLimitation' );
6245
6246 $depthArray = array();
6247 for ( $i = 1; $i <= $maxLevel; $i++ )
6248 {
6249 $depthArray[] = array( 'name' => $i, 'id' => $i );
6250 }
6251
6252 return $depthArray;
6253 }
6254
6261 function availableClassesJsArray()
6262 {
6263 return eZContentObjectTreeNode::availableClassListJsArray( array( 'node' => $this ) );
6264 }
6265
6273 static function availableClassListJsArray( $parameters = false )
6274 {
6275 $iniMenu = eZINI::instance( 'contentstructuremenu.ini' );
6276 $falseValue = "''";
6277
6278 if ( $iniMenu->hasVariable( 'TreeMenu', 'CreateHereMenu' ) )
6279 {
6280 $createHereMenu = $iniMenu->variable( 'TreeMenu', 'CreateHereMenu' );
6281 }
6282 else
6283 {
6284 $createHereMenu = 'simplified';
6285 }
6286
6287 if ( $createHereMenu != 'simplified' and $createHereMenu != 'full' )
6288 return $falseValue;
6289
6290 $ini = eZINI::instance( 'content.ini' );
6291 list( $usersClassGroupID, $setupClassGroupID ) = $ini->variableMulti( 'ClassGroupIDs', array( 'Users', 'Setup' ) );
6292 $userRootNode = $ini->variable( 'NodeSettings', 'UserRootNode' );
6293 $groupIDs = false;
6294 $filterType = 'include';
6295
6296 if ( !is_array( $parameters ) )
6297 return $falseValue;
6298
6299 $node = isset( $parameters['node'] ) ? $parameters['node'] : false;
6300 if ( is_object( $node ) )
6301 {
6302 if ( $createHereMenu == 'full' and !$node->canCreate() )
6303 return $falseValue;
6304
6305 $obj = $node->object();
6306 $contentClass = $obj->attribute( 'content_class' );
6307 if ( !$contentClass->attribute( 'is_container' ) )
6308 {
6309 return $falseValue;
6310 }
6311
6312 $pathArray = $node->pathArray();
6313 }
6314 else
6315 {
6316 // If current object is not container we should not return class list, should not display "create here" menu.
6317 if ( isset( $parameters['is_container'] ) and !$parameters['is_container'] )
6318 return $falseValue;
6319
6320 // Check if current user can create under this node
6321 if ( $createHereMenu == 'full' and isset( $parameters['node_id'] ) )
6322 {
6323 $node = eZContentObjectTreeNode::fetch( $parameters['node_id'] );
6324 if ( is_object( $node ) and !$node->canCreate() )
6325 return $falseValue;
6326 }
6327 $pathString = isset( $parameters['path_string'] ) ? $parameters['path_string'] : false;
6328 if ( !$pathString )
6329 return $falseValue;
6330
6331 $pathItems = explode( '/', $pathString );
6332 $pathArray = array();
6333 foreach ( $pathItems as $pathItem )
6334 {
6335 if ( $pathItem != '' )
6336 $pathArray[] = (int) $pathItem;
6337 }
6338 }
6339
6340 if ( in_array( $userRootNode, $pathArray ) )
6341 {
6342 $groupIDs = array( $usersClassGroupID );
6343 }
6344 else
6345 {
6346 $groupIDs = array( $usersClassGroupID, $setupClassGroupID );
6347 $filterType = 'exclude';
6348 }
6349
6350 if ( $createHereMenu == 'simplified' )
6351 {
6352 $classes = eZContentClass::fetchAllClasses( false, $filterType == 'include', $groupIDs );
6353 return eZContentObjectTreeNode::getClassesJsArray( false, $filterType == 'include', $groupIDs, false, $classes );
6354 }
6355
6356 return eZContentObjectTreeNode::getClassesJsArray( $node, $filterType == 'include', $groupIDs );
6357 }
6358
6369 static function getClassesJsArray( $node = false, $includeFilter = true, $groupList = false, $fetchID = false, $classes = false )
6370 {
6371 $falseValue = "''";
6372 // If $classes is false we should check $node and fetch class list
6373 if ( $classes === false )
6374 {
6375 // If $node is object we should fetch available classes from node, from ezcontentclass otherwise
6376 $classes = ( $node instanceOf eZContentObjectTreeNode )
6377 ? $node->canCreateClassList( false, $includeFilter, $groupList, $fetchID )
6378 : eZContentClass::canInstantiateClassList( false, $includeFilter, $groupList, $fetchID );
6379 }
6380 if ( !is_array( $classes ) )
6381 return $falseValue;
6382
6383 // Create javascript array
6384 $classList = array();
6385 foreach ( $classes as $class )
6386 {
6387 if ( $class instanceOf eZContentClass )
6388 {
6389 $classID = $class->attribute( 'id' );
6390 $className = $class->attribute( 'name' );
6391 }
6392 elseif ( is_array( $class ) )
6393 {
6394 $classID = $class['id'];
6395 $className = $class['name'];
6396 }
6397 $classList[] = array(
6398 'classID' => (int) $classID,
6399 'name' => $className
6400 );
6401 }
6402
6403 if ( $classList )
6404 return json_encode( $classList );
6405
6406 return $falseValue;
6407 }
6408
6409
6416 public function isNodeTrashAllowed()
6417 {
6418 $userClassIDArray = eZUser::contentClassIDs();
6419
6420 $class = $this->attribute( 'object' )->attribute( 'content_class' );
6421
6422 // If current object has ezuser attributes, it can't be sent to trash
6423 if ( in_array( $class->attribute( 'id' ), $userClassIDArray ) )
6424 {
6425 return false;
6426 }
6427
6428 // Checking for children using classes with ezuser attribute. Using == because subTreecount returns strings
6429 return $this->subTreeCount(
6430 array(
6431 'Limitation' => array(),
6432 'SortBy' => array( 'path' , false ),
6433 'IgnoreVisibility' => true,
6434 'ClassFilterType' => 'include',
6435 'ClassFilterArray' => $userClassIDArray,
6436 'AsObject' => false
6437 )
6438 ) == 0 ;
6439 }
6440
6446 static function getObjectIdsInNodeSubTree($node)
6447 {
6448 $db = eZDB::instance();
6449 $nodePath = $node->attribute( 'path_string' );
6450 $pathString = " path_string like '$nodePath%' AND ";
6451
6452 $objectIDArray = $db->arrayQuery( "SELECT
6453 ezcontentobject.id
6454 FROM
6455 ezcontentobject_tree, ezcontentobject
6456 WHERE
6457 $pathString
6458 ezcontentobject_tree.contentobject_id=ezcontentobject.id AND
6459 ezcontentobject_tree.main_node_id=ezcontentobject_tree.node_id" );
6460
6461 if ( count( $objectIDArray ) == 0 )
6462 return null;
6463
6464 $objectSimpleIDArray = array();
6465
6466 foreach ( $objectIDArray as $objectID )
6467 {
6468 $objectSimpleIDArray[] = $objectID['id'];
6469 }
6470
6471 return $objectSimpleIDArray;
6472 }
6473
6477 public $CurrentLanguage = false;
6478
6482 public $Name;
6483
6487 public $ClassIdentifier = null;
6488
6492 public $ClassName = null;
6493
6494 public $ContentObject;
6495 public $Permissions;
6496
6500 protected $ClassIsContainer = null;
6501 }
6502
6503 ?>
eZAlphabetOperator\fetchAlphabet
static fetchAlphabet()
Definition: ezalphabetoperator.php:63
eZAudit\isAuditEnabled
static isAuditEnabled()
Definition: ezaudit.php:90
eZAudit\writeAudit
static writeAudit( $auditName, $auditAttributes=array())
Definition: ezaudit.php:51
eZContentBrowseBookmark\removeByNodeID
static removeByNodeID( $nodeID)
Definition: ezcontentbrowsebookmark.php:158
eZContentBrowseRecent\removeRecentByNodeID
static removeRecentByNodeID( $nodeID)
Definition: ezcontentbrowserecent.php:202
eZContentCacheManager\clearContentCacheIfNeeded
static clearContentCacheIfNeeded( $objectID, $versionNum=true, $additionalNodeList=false)
Definition: ezcontentcachemanager.php:1062
eZContentClassAttribute\sortKeyTypeByID
static sortKeyTypeByID( $classAttributeID)
Definition: ezcontentclassattribute.php:654
eZContentClassAttribute\classAttributeIDByIdentifier
static classAttributeIDByIdentifier( $identifier)
Definition: ezcontentclassattribute.php:865
eZContentClassAttribute\dataTypeByID
static dataTypeByID( $classAttributeID)
Definition: ezcontentclassattribute.php:671
eZContentClassName\sqlFilter
static sqlFilter( $languageTable='ezcontentclass')
Definition: ezcontentclassname.php:75
eZContentClass
Handles eZ Publish content classes.
Definition: ezcontentclass.php:20
eZContentClass\fetchAllClasses
static fetchAllClasses( $asObject=true, $includeFilter=true, $groupList=false)
Definition: ezcontentclass.php:662
eZContentClass\VERSION_STATUS_DEFINED
const VERSION_STATUS_DEFINED
Definition: ezcontentclass.php:22
eZContentClass\nameFromSerializedString
static nameFromSerializedString( $serializedNameList)
Definition: ezcontentclass.php:1529
eZContentClass\canInstantiateClassList
static canInstantiateClassList( $asObject=false, $includeFilter=true, $groupList=false, $fetchID=false)
Definition: ezcontentclass.php:379
eZContentClass\classIDByIdentifier
static classIDByIdentifier( $identifier)
Definition: ezcontentclass.php:1790
eZContentLanguage\clearPrioritizedLanguages
static clearPrioritizedLanguages()
Definition: ezcontentlanguage.php:393
eZContentLanguage\fetchLocaleList
static fetchLocaleList()
Definition: ezcontentlanguage.php:231
eZContentLanguage\sqlFilter
static sqlFilter( $languageTable, $languageListTable=null, $languageAttributeName='language_id', $languageListAttributeName='language_mask', $lang=false)
Definition: ezcontentlanguage.php:692
eZContentLanguage\idByLocale
static idByLocale( $locale)
Definition: ezcontentlanguage.php:637
eZContentLanguage\maskByLocale
static maskByLocale( $locales, $setZerothBit=false)
Definition: ezcontentlanguage.php:546
eZContentLanguage\languagesSQLFilter
static languagesSQLFilter( $languageListTable, $languageListAttributeName='language_mask')
Definition: ezcontentlanguage.php:659
eZContentLanguage\setPrioritizedLanguages
static setPrioritizedLanguages( $languages)
Definition: ezcontentlanguage.php:381
eZContentObjectTrashNode\createFromNode
static createFromNode( $node)
Definition: ezcontentobjecttrashnode.php:120
eZContentObjectTreeNode
Definition: ezcontentobjecttreenode.php:17
eZContentObjectTreeNode\canPdf
canPdf()
Definition: ezcontentobjecttreenode.php:324
eZContentObjectTreeNode\clearViewCacheForSubtree
static clearViewCacheForSubtree(eZContentObjectTreeNode $node, $clearForRootNode=true)
Definition: ezcontentobjecttreenode.php:6161
eZContentObjectTreeNode\store
store( $fieldFilters=null)
Definition: ezcontentobjecttreenode.php:5737
eZContentObjectTreeNode\createExtendedAttributeFilterSQLStrings
static createExtendedAttributeFilterSQLStrings(&$extendedAttributeFilter)
Definition: ezcontentobjecttreenode.php:857
eZContentObjectTreeNode\definition
static definition()
Definition: ezcontentobjecttreenode.php:52
eZContentObjectTreeNode\setVersionByObjectID
static setVersionByObjectID( $objectID, $newVersion)
Definition: ezcontentobjecttreenode.php:6205
eZContentObjectTreeNode\SORT_FIELD_SECTION
const SORT_FIELD_SECTION
Definition: ezcontentobjecttreenode.php:21
eZContentObjectTreeNode\hideSubTree
static hideSubTree(eZContentObjectTreeNode $node, $modifyRootNode=true)
Definition: ezcontentobjecttreenode.php:5985
eZContentObjectTreeNode\fetchParent
fetchParent()
Definition: ezcontentobjecttreenode.php:3202
eZContentObjectTreeNode\classIsContainer
classIsContainer()
Definition: ezcontentobjecttreenode.php:5920
eZContentObjectTreeNode\createNodesConditionSQLStringFromPath
static createNodesConditionSQLStringFromPath( $nodePath, $includingLastNodeInThePath, $limit=false)
Definition: ezcontentobjecttreenode.php:1820
eZContentObjectTreeNode\makeObjectsArray
static makeObjectsArray( $array, $with_contentobject=true, array|null $propertiesOverride=null, $lang=null)
Definition: ezcontentobjecttreenode.php:5227
eZContentObjectTreeNode\SORT_FIELD_PATH
const SORT_FIELD_PATH
Definition: ezcontentobjecttreenode.php:18
eZContentObjectTreeNode\subTreeCount
subTreeCount( $params=array())
Definition: ezcontentobjecttreenode.php:2544
eZContentObjectTreeNode\$ContentObject
$ContentObject
Definition: ezcontentobjecttreenode.php:6494
eZContentObjectTreeNode\dataTypeByClassAttributeID
static dataTypeByClassAttributeID( $classAttributeID)
Definition: ezcontentobjecttreenode.php:503
eZContentObjectTreeNode\fetchByCRC
fetchByCRC( $pathStr)
Definition: ezcontentobjecttreenode.php:2912
eZContentObjectTreeNode\classListFromPolicy
classListFromPolicy( $policy, $allowedLanguageCodes=false)
Definition: ezcontentobjecttreenode.php:4826
eZContentObjectTreeNode\remoteID
remoteID()
Definition: ezcontentobjecttreenode.php:258
eZContentObjectTreeNode\availableClassesJsArray
availableClassesJsArray()
Definition: ezcontentobjecttreenode.php:6261
eZContentObjectTreeNode\dataMap
dataMap()
Definition: ezcontentobjecttreenode.php:231
eZContentObjectTreeNode\getParentNodeId
static getParentNodeId( $nodeID)
Definition: ezcontentobjecttreenode.php:5342
eZContentObjectTreeNode\getClassesJsArray
static getClassesJsArray( $node=false, $includeFilter=true, $groupList=false, $fetchID=false, $classes=false)
Definition: ezcontentobjecttreenode.php:6369
eZContentObjectTreeNode\subtreeRemovalInformation
static subtreeRemovalInformation( $deleteIDArray)
Definition: ezcontentobjecttreenode.php:3826
eZContentObjectTreeNode\assignSectionToSubTree
static assignSectionToSubTree( $nodeID, $sectionID, $oldSectionID=false, $updateSearchIndexes=true)
Definition: ezcontentobjecttreenode.php:2828
eZContentObjectTreeNode\$Name
$Name
Definition: ezcontentobjecttreenode.php:6482
eZContentObjectTreeNode\url
url()
Definition: ezcontentobjecttreenode.php:5872
eZContentObjectTreeNode\updateAndStoreModified
updateAndStoreModified()
Definition: ezcontentobjecttreenode.php:5716
eZContentObjectTreeNode\calendar
static calendar( $params=false, $nodeID=0)
Definition: ezcontentobjecttreenode.php:2552
eZContentObjectTreeNode\$CurrentLanguage
$CurrentLanguage
Definition: ezcontentobjecttreenode.php:6477
eZContentObjectTreeNode\hiddenStatusString
hiddenStatusString()
Definition: ezcontentobjecttreenode.php:5948
eZContentObjectTreeNode\createSortingSQLStrings
static createSortingSQLStrings( $sortList, $treeTableName='ezcontentobject_tree', $allowCustomColumns=false)
Definition: ezcontentobjecttreenode.php:560
eZContentObjectTreeNode\getName
getName( $language=false)
Definition: ezcontentobjecttreenode.php:5494
eZContentObjectTreeNode\SORT_FIELD_PUBLISHED
const SORT_FIELD_PUBLISHED
Definition: ezcontentobjecttreenode.php:19
eZContentObjectTreeNode\canRemoveLocation
canRemoveLocation()
Definition: ezcontentobjecttreenode.php:477
eZContentObjectTreeNode\childrenCount
childrenCount( $checkPolicies=true)
Definition: ezcontentobjecttreenode.php:2703
eZContentObjectTreeNode\createShowInvisibleSQLString
static createShowInvisibleSQLString( $useSettings, $fetchHidden=true)
Definition: ezcontentobjecttreenode.php:1859
eZContentObjectTreeNode\createVersionNameTablesSQLString
static createVersionNameTablesSQLString( $useVersionName)
Definition: ezcontentobjecttreenode.php:1607
eZContentObjectTreeNode\createPathConditionSQLString
static createPathConditionSQLString( $nodePath, $nodeDepth, $depth=false, $depthOperator='le')
Definition: ezcontentobjecttreenode.php:1411
eZContentObjectTreeNode\unhideSubTree
static unhideSubTree(eZContentObjectTreeNode $node, $modifyRootNode=true)
Definition: ezcontentobjecttreenode.php:6049
eZContentObjectTreeNode\createGroupBySQLStrings
static createGroupBySQLStrings(&$outGroupBySelectText, &$outGroupByText, $groupBy)
Definition: ezcontentobjecttreenode.php:1575
eZContentObjectTreeNode\eZContentObjectTreeNode
eZContentObjectTreeNode( $row=array())
Definition: ezcontentobjecttreenode.php:44
eZContentObjectTreeNode\getParentNodeIdListByContentObjectID
static getParentNodeIdListByContentObjectID( $objectIDs, $groupByObjectId=false, $onlyMainNode=false)
Definition: ezcontentobjecttreenode.php:5368
eZContentObjectTreeNode\setContentObject
setContentObject( $object)
Definition: ezcontentobjecttreenode.php:5786
eZContentObjectTreeNode\fetchByRemoteID
static fetchByRemoteID( $remoteID, $asObject=true)
Definition: ezcontentobjecttreenode.php:2933
eZContentObjectTreeNode\createVersionNameJoinsSQLString
static createVersionNameJoinsSQLString( $useVersionName, $includeAnd=true, $onlyTranslated=false, $lang=false, $treeTableName='ezcontentobject_tree')
Definition: ezcontentobjecttreenode.php:1641
eZContentObjectTreeNode\sortArrayBySortFieldAndSortOrder
static sortArrayBySortFieldAndSortOrder( $sortField, $sortOrder)
Definition: ezcontentobjecttreenode.php:2816
eZContentObjectTreeNode\canViewEmbed
canViewEmbed()
Definition: ezcontentobjecttreenode.php:338
eZContentObjectTreeNode\creator
creator()
Definition: ezcontentobjecttreenode.php:5796
eZContentObjectTreeNode\sortArray
sortArray()
Definition: ezcontentobjecttreenode.php:2804
eZContentObjectTreeNode\canMoveFrom
canMoveFrom()
Definition: ezcontentobjecttreenode.php:420
eZContentObjectTreeNode\hiddenInvisibleString
hiddenInvisibleString()
Definition: ezcontentobjecttreenode.php:5937
eZContentObjectTreeNode\canMoveTo
canMoveTo( $classID=false)
Definition: ezcontentobjecttreenode.php:435
eZContentObjectTreeNode\$ClassIsContainer
$ClassIsContainer
Definition: ezcontentobjecttreenode.php:6500
eZContentObjectTreeNode\fetchByPath
static fetchByPath( $pathString, $asObject=true)
Definition: ezcontentobjecttreenode.php:2938
eZContentObjectTreeNode\SORT_ORDER_DESC
const SORT_ORDER_DESC
Definition: ezcontentobjecttreenode.php:32
eZContentObjectTreeNode\updateMainNodeID
static updateMainNodeID( $mainNodeID, $objectID, $version, $parentMainNodeID, $updateSection=true)
Definition: ezcontentobjecttreenode.php:2882
eZContentObjectTreeNode\canCreateClassList
canCreateClassList( $asObject=false, $includeFilter=true, $groupList=false, $fetchID=false)
Definition: ezcontentobjecttreenode.php:5077
eZContentObjectTreeNode\SORT_FIELD_VISIBILITY
const SORT_FIELD_VISIBILITY
Definition: ezcontentobjecttreenode.php:30
eZContentObjectTreeNode\subTree
subTree( $params=false)
Definition: ezcontentobjecttreenode.php:2120
eZContentObjectTreeNode\checkAccess
checkAccess( $functionName, $originalClassID=false, $parentClassID=false, $returnAccessList=false, $language=false)
Definition: ezcontentobjecttreenode.php:4358
eZContentObjectTreeNode\SORT_FIELD_NODE_ID
const SORT_FIELD_NODE_ID
Definition: ezcontentobjecttreenode.php:28
eZContentObjectTreeNode\SORT_FIELD_CLASS_IDENTIFIER
const SORT_FIELD_CLASS_IDENTIFIER
Definition: ezcontentobjecttreenode.php:23
eZContentObjectTreeNode\SORT_FIELD_MODIFIED
const SORT_FIELD_MODIFIED
Definition: ezcontentobjecttreenode.php:20
eZContentObjectTreeNode\fetchNodesByPathString
static fetchNodesByPathString( $nodePath, $withLastNode=false, $asObjects=true, $limit=false)
Definition: ezcontentobjecttreenode.php:3236
eZContentObjectTreeNode\create
static create( $parentNodeID=null, $contentObjectID=null, $contentObjectVersion=0, $sortField=0, $sortOrder=true)
Definition: ezcontentobjecttreenode.php:182
eZContentObjectTreeNode\fetch
static fetch( $nodeID=false, $lang=false, $asObject=true, $conditions=false)
Definition: ezcontentobjecttreenode.php:3058
eZContentObjectTreeNode\fetchPath
fetchPath()
Definition: ezcontentobjecttreenode.php:3221
eZContentObjectTreeNode\parentDepthLimitationList
static parentDepthLimitationList()
Definition: ezcontentobjecttreenode.php:6239
eZContentObjectTreeNode\SORT_FIELD_CLASS_NAME
const SORT_FIELD_CLASS_NAME
Definition: ezcontentobjecttreenode.php:24
eZContentObjectTreeNode\updateNodeVisibility
static updateNodeVisibility( $node, $parentNode, $recursive=true)
Definition: ezcontentobjecttreenode.php:6119
eZContentObjectTreeNode\sortFieldName
static sortFieldName( $sortFieldID)
Definition: ezcontentobjecttreenode.php:2725
eZContentObjectTreeNode\canSwap
canSwap()
Definition: ezcontentobjecttreenode.php:449
eZContentObjectTreeNode\sortKeyByClassAttributeID
static sortKeyByClassAttributeID( $classAttributeID)
Definition: ezcontentobjecttreenode.php:492
eZContentObjectTreeNode\className
className()
Definition: ezcontentobjecttreenode.php:5903
eZContentObjectTreeNode\classAttributeIDByIdentifier
static classAttributeIDByIdentifier( $identifier)
Definition: ezcontentobjecttreenode.php:288
eZContentObjectTreeNode\canEdit
canEdit()
Definition: ezcontentobjecttreenode.php:352
eZContentObjectTreeNode\findMainNode
static findMainNode( $objectID, $asObject=false)
Definition: ezcontentobjecttreenode.php:2981
eZContentObjectTreeNode\urlAlias
urlAlias()
Definition: ezcontentobjecttreenode.php:5830
eZContentObjectTreeNode\removeNode
static removeNode( $nodeID=0)
Definition: ezcontentobjecttreenode.php:3689
eZContentObjectTreeNode\fetchNode
static fetchNode( $contentObjectID, $parentNodeID)
Definition: ezcontentobjecttreenode.php:3172
eZContentObjectTreeNode\adjustPathElement
adjustPathElement( $element, $useParentFromNodeObject=false)
Definition: ezcontentobjecttreenode.php:3477
eZContentObjectTreeNode\classIDByIdentifier
static classIDByIdentifier( $identifier)
Definition: ezcontentobjecttreenode.php:300
eZContentObjectTreeNode\createNotEqParentSQLString
static createNotEqParentSQLString( $nodeID, $depth=false, $depthOperator='le')
Definition: ezcontentobjecttreenode.php:1391
eZContentObjectTreeNode\deleteNodeWhereParent
static deleteNodeWhereParent( $node, $id)
Definition: ezcontentobjecttreenode.php:5415
eZContentObjectTreeNode\canRemove
canRemove()
Definition: ezcontentobjecttreenode.php:406
eZContentObjectTreeNode\findNode
static findNode( $parentNode, $id, $asObject=false, $remoteID=false)
Definition: ezcontentobjecttreenode.php:5421
eZContentObjectTreeNode\getObjectIdsInNodeSubTree
static getObjectIdsInNodeSubTree($node)
Definition: ezcontentobjecttreenode.php:6446
eZContentObjectTreeNode\$ClassName
$ClassName
Definition: ezcontentobjecttreenode.php:6492
eZContentObjectTreeNode\setUseCurrentUserDraft
static setUseCurrentUserDraft( $enable)
Definition: ezcontentobjecttreenode.php:220
eZContentObjectTreeNode\removeThis
removeThis()
Definition: ezcontentobjecttreenode.php:3707
eZContentObjectTreeNode\$Permissions
$Permissions
Definition: ezcontentobjecttreenode.php:6495
eZContentObjectTreeNode\$ClassIdentifier
$ClassIdentifier
Definition: ezcontentobjecttreenode.php:6487
eZContentObjectTreeNode\createObjectNameFilterConditionSQLString
static createObjectNameFilterConditionSQLString( $filter)
Definition: ezcontentobjecttreenode.php:945
eZContentObjectTreeNode\canHide
canHide()
Definition: ezcontentobjecttreenode.php:378
eZContentObjectTreeNode\fetchByContentObjectID
static fetchByContentObjectID( $contentObjectID, $asObject=true, $contentObjectVersion=false)
Definition: ezcontentobjecttreenode.php:2918
eZContentObjectTreeNode\sortFieldID
static sortFieldID( $sortFieldName)
Definition: ezcontentobjecttreenode.php:2764
eZContentObjectTreeNode\canCreate
canCreate()
Definition: ezcontentobjecttreenode.php:392
eZContentObjectTreeNode\updateSubTreePath
updateSubTreePath( $updateParent=true, $nodeMove=false)
Definition: ezcontentobjecttreenode.php:3506
eZContentObjectTreeNode\createPathConditionAndNotEqParentSQLStrings
static createPathConditionAndNotEqParentSQLStrings(&$outPathConditionStr, &$outNotEqParentStr, $nodeID, $depth=false, $depthOperator='le')
Definition: ezcontentobjecttreenode.php:1462
eZContentObjectTreeNode\isMain
isMain()
Definition: ezcontentobjecttreenode.php:276
eZContentObjectTreeNode\addChild
addChild( $contentobjectID, $asObject=false, $contentObjectVersion=false)
Definition: ezcontentobjecttreenode.php:3309
eZContentObjectTreeNode\subTreeCountByNodeID
static subTreeCountByNodeID( $params, $nodeID)
Definition: ezcontentobjecttreenode.php:2394
eZContentObjectTreeNode\unserialize
static unserialize( $contentNodeDOMNode, $contentObject, $version, $isMain, &$nodeList, &$options, $handlerType='ezcontentobject')
Definition: ezcontentobjecttreenode.php:5550
eZContentObjectTreeNode\fetchByURLPath
static fetchByURLPath( $pathString, $asObject=true)
Definition: ezcontentobjecttreenode.php:2943
eZContentObjectTreeNode\$useCurrentUserDraft
static $useCurrentUserDraft
Definition: ezcontentobjecttreenode.php:209
eZContentObjectTreeNode\createMainNodeConditionSQLString
static createMainNodeConditionSQLString( $mainNodeOnly)
Definition: ezcontentobjecttreenode.php:922
eZContentObjectTreeNode\pathWithNames
pathWithNames( $regenerateCurrent=false)
Definition: ezcontentobjecttreenode.php:3382
eZContentObjectTreeNode\removeSubtrees
static removeSubtrees( $deleteIDArray, $moveToTrash=true, $infoOnly=false)
Definition: ezcontentobjecttreenode.php:3847
eZContentObjectTreeNode\fetchListCount
static fetchListCount()
Definition: ezcontentobjecttreenode.php:513
eZContentObjectTreeNode\reverseRelatedCount
static reverseRelatedCount( $nodeIDArray)
Definition: ezcontentobjecttreenode.php:4047
eZContentObjectTreeNode\subTreeByNodeID
static subTreeByNodeID( $params=false, $nodeID=0)
Definition: ezcontentobjecttreenode.php:1940
eZContentObjectTreeNode\showInvisibleNodes
static showInvisibleNodes()
Definition: ezcontentobjecttreenode.php:1877
eZContentObjectTreeNode\SORT_ORDER_ASC
const SORT_ORDER_ASC
Definition: ezcontentobjecttreenode.php:33
eZContentObjectTreeNode\getLimitationList
static getLimitationList(&$limitation)
Definition: ezcontentobjecttreenode.php:1895
eZContentObjectTreeNode\SORT_FIELD_CONTENTOBJECT_ID
const SORT_FIELD_CONTENTOBJECT_ID
Definition: ezcontentobjecttreenode.php:29
eZContentObjectTreeNode\object
object()
Definition: ezcontentobjecttreenode.php:5752
eZContentObjectTreeNode\SORT_FIELD_MODIFIED_SUBNODE
const SORT_FIELD_MODIFIED_SUBNODE
Definition: ezcontentobjecttreenode.php:27
eZContentObjectTreeNode\createClassFilteringSQLString
static createClassFilteringSQLString( $classFilterType, &$classFilterArray)
Definition: ezcontentobjecttreenode.php:795
eZContentObjectTreeNode\createPermissionCheckingSQL
static createPermissionCheckingSQL( $limitationList, $treeTableName='ezcontentobject_tree', $tableAliasName='ezcontentobject_tree')
Definition: ezcontentobjecttreenode.php:1662
eZContentObjectTreeNode\createVersionNameTargetsSQLString
static createVersionNameTargetsSQLString( $useVersionName)
Definition: ezcontentobjecttreenode.php:1624
eZContentObjectTreeNode\checkPath
checkPath( $path)
Definition: ezcontentobjecttreenode.php:3453
eZContentObjectTreeNode\updatePathIdentificationString
updatePathIdentificationString( $pathIdentificationName)
Definition: ezcontentobjecttreenode.php:3639
eZContentObjectTreeNode\subTreeMultiPaths
static subTreeMultiPaths( $nodesParams, $listParams=NULL)
Definition: ezcontentobjecttreenode.php:2157
eZContentObjectTreeNode\hasContentObject
hasContentObject()
Definition: ezcontentobjecttreenode.php:5773
eZContentObjectTreeNode\fetchClassIdentifierListByPathString
static fetchClassIdentifierListByPathString( $nodePath, $withLastNode, $limit=false)
Definition: ezcontentobjecttreenode.php:3286
eZContentObjectTreeNode\currentLanguage
currentLanguage()
Definition: ezcontentobjecttreenode.php:6216
eZContentObjectTreeNode\serialize
serialize( $options, $contentNodeIDArray, $topNodeIDArray)
Definition: ezcontentobjecttreenode.php:5678
eZContentObjectTreeNode\removeNodeFromTree
removeNodeFromTree( $moveToTrash=true)
Definition: ezcontentobjecttreenode.php:4098
eZContentObjectTreeNode\findMainNodeArray
static findMainNodeArray( $objectIDArray, $asObject=true)
Definition: ezcontentobjecttreenode.php:3018
eZContentObjectTreeNode\fetchAliasesFromNodeList
static fetchAliasesFromNodeList( $nodeList)
Definition: ezcontentobjecttreenode.php:2961
eZContentObjectTreeNode\availableClassListJsArray
static availableClassListJsArray( $parameters=false)
Definition: ezcontentobjecttreenode.php:6273
eZContentObjectTreeNode\isNodeTrashAllowed
isNodeTrashAllowed()
Definition: ezcontentobjecttreenode.php:6416
eZContentObjectTreeNode\addChildTo
static addChildTo( $contentobjectID, $nodeID, $asObject=false, $contentObjectVersion=false)
Definition: ezcontentobjecttreenode.php:3324
eZContentObjectTreeNode\SORT_FIELD_NAME
const SORT_FIELD_NAME
Definition: ezcontentobjecttreenode.php:26
eZContentObjectTreeNode\setName
setName( $name)
Definition: ezcontentobjecttreenode.php:5532
eZContentObjectTreeNode\createAttributeFilterSQLStrings
static createAttributeFilterSQLStrings(&$attributeFilter, &$sortingInfo=array( 'sortCount'=> 0, 'attributeJoinCount'=> 0), $language=false)
Definition: ezcontentobjecttreenode.php:973
eZContentObjectTreeNode\canRead
canRead()
Definition: ezcontentobjecttreenode.php:310
eZContentObjectTreeNode\subTreeGroupByDateField
static subTreeGroupByDateField( $field, $type)
Definition: ezcontentobjecttreenode.php:2348
eZContentObjectTreeNode\SORT_FIELD_PRIORITY
const SORT_FIELD_PRIORITY
Definition: ezcontentobjecttreenode.php:25
eZContentObjectTreeNode\subtreeSoleNodeCount
subtreeSoleNodeCount( $params=array())
Definition: ezcontentobjecttreenode.php:4168
eZContentObjectTreeNode\setCurrentLanguage
setCurrentLanguage( $languageCode)
Definition: ezcontentobjecttreenode.php:6226
eZContentObjectTreeNode\fetchList
static fetchList( $asObject=true, $offset=false, $limit=false)
Definition: ezcontentobjecttreenode.php:529
eZContentObjectTreeNode\classIdentifier
classIdentifier()
Definition: ezcontentobjecttreenode.php:5887
eZContentObjectTreeNode\contentObjectVersionObject
contentObjectVersionObject( $asObject=true)
Definition: ezcontentobjecttreenode.php:5815
eZContentObjectTreeNode\viewCount
viewCount()
Definition: ezcontentobjecttreenode.php:2715
eZContentObjectTreeNode\move
move( $newParentNodeID, $nodeID=0)
Definition: ezcontentobjecttreenode.php:4240
eZContentObjectTreeNode\hasCurrentSubtreeLimitation
hasCurrentSubtreeLimitation(array $policy)
Definition: ezcontentobjecttreenode.php:5029
eZContentObjectTreeNode\childrenByName
childrenByName( $name)
Definition: ezcontentobjecttreenode.php:2660
eZContentObjectTreeNode\pathArray
pathArray()
Definition: ezcontentobjecttreenode.php:3207
eZContentObjectTreeNode\SORT_FIELD_DEPTH
const SORT_FIELD_DEPTH
Definition: ezcontentobjecttreenode.php:22
eZContentObjectTreeNode\children
children()
Definition: ezcontentobjecttreenode.php:2691
eZContentObjectTreeNode\__construct
__construct( $row=array())
Definition: ezcontentobjecttreenode.php:35
eZContentObjectTreeNode\canAddLocation
canAddLocation()
Definition: ezcontentobjecttreenode.php:463
eZContentObjectVersion
The class eZContentObjectVersion handles different versions of an content object.
Definition: ezcontentobjectversion.php:19
eZContentObjectVersion\STATUS_PENDING
const STATUS_PENDING
Definition: ezcontentobjectversion.php:31
eZContentObjectVersion\fetchVersion
static fetchVersion( $version, $contentObjectID, $asObject=true)
Definition: ezcontentobjectversion.php:166
eZContentObjectVersion\fetchLatestUserDraft
static fetchLatestUserDraft( $objectID, $userID, $languageID, $modified=0)
Definition: ezcontentobjectversion.php:254
eZContentObject
Definition: ezcontentobject.php:17
eZContentObject\fillNodeListAttributes
static fillNodeListAttributes( $objList, $asObject=true)
Definition: ezcontentobject.php:2290
eZContentObject\clearCache
static clearCache( $idArray=array())
Definition: ezcontentobject.php:284
eZContentObject\PACKAGE_UPDATE
const PACKAGE_UPDATE
Definition: ezcontentobject.php:32
eZContentObject\fetch
static fetch( $id, $asObject=true)
Definition: ezcontentobject.php:885
eZContentObject\fetchByNodeID
static fetchByNodeID( $nodeID, $asObject=true)
Definition: ezcontentobject.php:1072
eZContentObject\PACKAGE_ERROR_EXISTS
const PACKAGE_ERROR_EXISTS
Definition: ezcontentobject.php:24
eZContentObject\PACKAGE_ERROR_NODE_EXISTS
const PACKAGE_ERROR_NODE_EXISTS
Definition: ezcontentobject.php:25
eZContentObject\PACKAGE_NEW
const PACKAGE_NEW
Definition: ezcontentobject.php:31
eZDBInterface\SERVER_SLAVE
const SERVER_SLAVE
Definition: ezdbinterface.php:43
eZDB\instance
static instance( $databaseImplementation=false, $databaseParameters=false, $forceNewInstance=false)
Definition: ezdb.php:117
eZDataType\create
static create( $dataTypeString)
Definition: ezdatatype.php:151
eZDebugSetting\writeDebug
static writeDebug( $conditionName, $string, $label="")
Definition: ezdebugsetting.php:127
eZDebugSetting\writeWarning
static writeWarning( $conditionName, $string, $label="")
Definition: ezdebugsetting.php:99
eZDebug\writeStrict
static writeStrict( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:414
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDebug\writeNotice
static writeNotice( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:459
eZDebug\writeWarning
static writeWarning( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:502
eZExtension\baseDirectory
static baseDirectory(eZINI|null $siteINI=null)
Definition: ezextension.php:39
eZExtension\getHandlerClass
static getHandlerClass(ezpExtensionOptions $options)
Definition: ezextension.php:531
eZNodeAssignment\fetchChildCountByVersionStatus
static fetchChildCountByVersionStatus( $parentNodeIDList, $status=eZContentObjectVersion::STATUS_PENDING)
Definition: eznodeassignment.php:461
eZNodeAssignment\fetchForObject
static fetchForObject( $contentObjectID, $version=1, $main=0, $asObject=true)
Definition: eznodeassignment.php:392
eZNodeAssignment\purgeByParentAndContentObjectID
static purgeByParentAndContentObjectID( $parentNodeID, $contentObjectID)
Definition: eznodeassignment.php:347
eZNodeAssignment\definition
static definition()
Definition: eznodeassignment.php:44
eZNodeAssignment\create
static create( $parameters=array())
Definition: eznodeassignment.php:193
eZPackageHandler\errorChoosenAction
static errorChoosenAction( $errorCode, &$installParameters, $description, $handlerType, $resetError=true)
Definition: ezpackagehandler.php:213
eZPackage\NON_INTERACTIVE
const NON_INTERACTIVE
Definition: ezpackage.php:33
eZPersistentObject
Definition: ezpersistentobject.php:33
eZPersistentObject\$NodeID
$NodeID
Definition: ezpersistentobject.php:1460
eZPersistentObject\$MainNodeID
$MainNodeID
Definition: ezpersistentobject.php:1462
eZPersistentObject\fetchObject
static fetchObject( $def, $field_filters, $conds, $asObject=true, $grouping=null, $custom_fields=null)
Definition: ezpersistentobject.php:213
eZPersistentObject\sync
sync( $fieldFilters=null)
Definition: ezpersistentobject.php:319
eZPersistentObject\setAttribute
setAttribute( $attr, $val)
Definition: ezpersistentobject.php:1374
eZPersistentObject\handleRows
static handleRows( $rows, $class_name, $asObject)
Definition: ezpersistentobject.php:963
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
eZPersistentObject\$contentobject_id
$contentobject_id
Definition: ezpersistentobject.php:1526
eZPolicyLimitation\findByType
static findByType( $type, $value, $asObject=true, $useLike=true)
Definition: ezpolicylimitation.php:351
eZPreferences\value
static value( $name, $user=false)
Definition: ezpreferences.php:106
eZRemoteIdUtility\generate
static generate( $type='')
Definition: ezremoteidutility.php:21
eZRole\cleanupByNode
static cleanupByNode( $node)
Definition: ezrole.php:418
eZRole\expireCache
static expireCache()
Definition: ezrole.php:568
eZSearch\updateObjectsSection
static updateObjectsSection(array $objectIDs, $sectionID)
Definition: ezsearch.php:504
eZSearch\addObject
static addObject( $contentObject, $commit=true)
Definition: ezsearch.php:98
eZSection\fetch
static fetch( $sectionID, $asObject=true)
Definition: ezsection.php:64
eZTipafriendCounter\removeForNode
static removeForNode( $nodeID)
Definition: eztipafriendcounter.php:55
eZURLAliasFilter\processFilters
static processFilters( $text, $languageObject, $caller)
Definition: ezurlaliasfilter.php:59
eZURLAliasML\fetchByAction
static fetchByAction( $actionName, $actionValue, $maskLanguages=false, $onlyPrioritized=false, $includeRedirections=false)
Definition: ezurlaliasml.php:967
eZURLAliasML\removeByAction
static removeByAction( $actionName, $actionValue)
Definition: ezurlaliasml.php:304
eZURLAliasML\convertToAlias
static convertToAlias( $urlElement, $defaultValue=false)
Definition: ezurlaliasml.php:2292
eZURLAliasML\fetchPathByActionList
static fetchPathByActionList( $actionName, $actionValues, $locale=null)
Definition: ezurlaliasml.php:1103
eZURLAliasML\cleanURL
static cleanURL( $url)
Definition: ezurlaliasml.php:2182
eZURLAliasML\storePath
static storePath( $path, $action, $languageName=false, $linkID=false, $alwaysAvailable=false, $rootID=false, $cleanupElements=true, $autoAdjustName=false, $reportErrors=true, $aliasRedirects=true)
Definition: ezurlaliasml.php:454
eZURLAliasML\findUniqueText
static findUniqueText( $parentElementID, $text, $action, $linkCheck=false, $languageID=false)
Definition: ezurlaliasml.php:1888
eZURLAliasML\convertToAliasCompat
static convertToAliasCompat( $urlElement, $defaultValue=false)
Definition: ezurlaliasml.php:2332
eZUser\purgeUserCacheByUserId
static purgeUserCacheByUserId( $userId)
Definition: ezuser.php:1345
eZUser\contentClassIDs
static contentClassIDs()
Definition: ezuser.php:2912
eZUser\currentUserID
static currentUserID()
Definition: ezuser.php:1731
eZUser\removeSessionData
static removeSessionData( $userID)
Definition: ezuser.php:619
eZUser\currentUser
static currentUser()
Definition: ezuser.php:1716
eZViewCounter\removeCounter
static removeCounter( $node_id)
Definition: ezviewcounter.php:45
eZViewCounter\fetch
static fetch( $node_id, $asObject=true)
Definition: ezviewcounter.php:83
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+.