|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZContentStructureTreeOperator class 00004 // 00005 // Created on: <14-Jul-2004 14:18:58 dl> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! \file ezcontentstructuretreeoperator.php 00032 */ 00033 00034 /*! 00035 \class eZContentStructureTreeOperator ezcontentstructuretreeoperator.php 00036 \brief 00037 */ 00038 00039 require_once( 'kernel/classes/ezcontentlanguage.php' ); 00040 //include_once( 'kernel/classes/ezcontentclassnamelist.php' ); 00041 00042 class eZContentStructureTreeOperator 00043 { 00044 function eZContentStructureTreeOperator( $name = 'content_structure_tree' ) 00045 { 00046 $this->Operators = array( $name ); 00047 } 00048 00049 /*! 00050 Returns the operators in this class. 00051 */ 00052 function operatorList() 00053 { 00054 return $this->Operators; 00055 } 00056 00057 /*! 00058 See eZTemplateOperator::namedParameterList() 00059 */ 00060 function namedParameterList() 00061 { 00062 return array( 'root_node_id' => array( 'type' => 'int', 00063 'required' => true, 00064 'default' => 0 ), 00065 'class_filter' => array( 'type' => 'array', 00066 'required' => false, 00067 'default' => false ), 00068 'max_depth' => array( 'type' => 'int', 00069 'required' => false, 00070 'default' => 0 ), 00071 'max_nodes' => array( 'type' => 'int', 00072 'required' => false, 00073 'default' => 0 ), 00074 'sort_by' => array( 'type' => 'array', 00075 'required' => false, 00076 'default' => 'false' ), 00077 'fetch_hidden' => array( 'type' => 'bool', 00078 'required' => false, 00079 'default' => 'false' ), 00080 'unfold_node_id' => array( 'type' => 'int', 00081 'required' => false, 00082 'default' => 0 ) ); 00083 } 00084 00085 /*! 00086 \reimp 00087 */ 00088 function modify( $tpl, $operatorName, $operatorParameters, $rootNamespace, $currentNamespace, &$operatorValue, $namedParameters ) 00089 { 00090 $sortArray = false; 00091 $fetchHidden = false; 00092 if ( $namedParameters[ 'sort_by' ] != 'false' ) 00093 { 00094 if( is_array($namedParameters[ 'sort_by' ])) 00095 { 00096 $sortArray = array(); 00097 foreach( $namedParameters[ 'sort_by' ] as $parameter ) 00098 { 00099 $sortingMethod = explode("/", $parameter ); 00100 $sortingMethod[1] = ($sortingMethod[1] == 'ascending') ? '1' : '0'; 00101 $sortArray[] = $sortingMethod; 00102 } 00103 } 00104 else 00105 { 00106 $sortingMethod = explode("/", $namedParameters[ 'sort_by' ]); 00107 $sortingMethod[1] = ($sortingMethod[1] == 'ascending') ? '1' : '0'; 00108 $sortArray = array(); 00109 $sortArray[] = $sortingMethod; 00110 } 00111 } 00112 00113 if ( $namedParameters[ 'fetch_hidden' ] != 'false' ) 00114 { 00115 $fetchHidden = true; 00116 } 00117 $operatorValue = eZContentStructureTreeOperator::contentStructureTree( $namedParameters['root_node_id'], 00118 $namedParameters['class_filter'], 00119 $namedParameters['max_depth'], 00120 $namedParameters['max_nodes'], 00121 $sortArray, 00122 $fetchHidden, 00123 $namedParameters['unfold_node_id'] ); 00124 } 00125 00126 /*! 00127 \static 00128 Returns one-level children of node \a $nodeID if \a $countChildren = false, 00129 othewise returns count of one-level children of node \a nodeID. 00130 */ 00131 function subTree( $params, $nodeID, $countChildren = false ) 00132 { 00133 $nodeListArray = array(); 00134 00135 // sorting params 00136 $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $params['SortBy'] ); 00137 00138 // node params 00139 $notEqParentString = ''; 00140 $pathStringCond = ''; 00141 eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, 1, false ); 00142 00143 // class filter 00144 $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString( $params['ClassFilterType'], $params['ClassFilterArray'] ); 00145 if ( $classCondition === false ) 00146 { 00147 return $nodeListArray; 00148 } 00149 00150 // permissions 00151 $limitationParams = false; 00152 $limitationList = eZContentObjectTreeNode::getLimitationList( $limitationParams ); 00153 00154 if ( $limitationList === false ) 00155 { 00156 return $nodeListArray; 00157 } 00158 00159 $permissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList ); 00160 00161 // version 00162 $useVersionName = true; 00163 $versionNameTables = eZContentObjectTreeNode::createVersionNameTablesSQLString( $useVersionName ); 00164 $versionNameTargets = eZContentObjectTreeNode::createVersionNameTargetsSQLString( $useVersionName ); 00165 $versionNameJoins = eZContentObjectTreeNode::createVersionNameJoinsSQLString( $useVersionName ); 00166 00167 // invisible nodes. 00168 $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( false, $params['FetchHidden'] ); 00169 00170 $query = ''; 00171 if ( $countChildren ) 00172 { 00173 $query = "SELECT count(*) as count 00174 FROM 00175 ezcontentobject_tree, 00176 ezcontentobject,ezcontentclass 00177 $versionNameTables 00178 $permissionChecking[from] 00179 WHERE $pathStringCond 00180 $classCondition 00181 ezcontentclass.version=0 AND 00182 $notEqParentString 00183 ezcontentobject_tree.contentobject_id = ezcontentobject.id AND 00184 ezcontentclass.id = ezcontentobject.contentclass_id 00185 $versionNameJoins 00186 $permissionChecking[where] "; 00187 } 00188 else 00189 { 00190 $query = "SELECT ezcontentobject.*, 00191 ezcontentobject_tree.*, 00192 ezcontentclass.serialized_name_list as class_serialized_name_list, 00193 ezcontentclass.identifier as class_identifier, 00194 ezcontentclass.is_container as is_container 00195 $versionNameTargets 00196 FROM 00197 ezcontentobject_tree, 00198 ezcontentobject,ezcontentclass 00199 $versionNameTables 00200 $sortingInfo[attributeFromSQL] 00201 $permissionChecking[from] 00202 WHERE 00203 $pathStringCond 00204 $sortingInfo[attributeWhereSQL] 00205 ezcontentclass.version=0 AND 00206 $notEqParentString 00207 ezcontentobject_tree.contentobject_id = ezcontentobject.id AND 00208 ezcontentclass.id = ezcontentobject.contentclass_id AND 00209 $classCondition 00210 ezcontentobject_tree.contentobject_is_published = 1 00211 $versionNameJoins 00212 $showInvisibleNodesCond 00213 $permissionChecking[where] 00214 ORDER BY $sortingInfo[sortingFields]"; 00215 00216 } 00217 00218 $db = eZDB::instance(); 00219 $nodeListArray = $db->arrayQuery( $query ); 00220 00221 // cleanup temp tables 00222 $db->dropTempTableList( $permissionChecking['temp_tables'] ); 00223 00224 if ( $countChildren ) 00225 { 00226 return $nodeListArray[0]['count']; 00227 } 00228 else 00229 { 00230 foreach ( $nodeListArray as $key => $row ) 00231 { 00232 $nodeListArray[$key]['path_identification_string'] = eZContentObjectTreeNode::fetch( $row['node_id'] )->pathWithNames(); 00233 } 00234 return $nodeListArray; 00235 } 00236 } 00237 00238 /*! 00239 \static 00240 \Returns a tree of content structure: 00241 tree = array( tree_node, children ), where 00242 'tree_node' is array( 'node' => info about node, 00243 'object' => info about object ); 00244 00245 'children' is array( tree_node, children ); 00246 */ 00247 function contentStructureTree( $rootNodeID, $classFilter, $maxDepth, $maxNodes, $sortArray, $fetchHidden, $unfoldNodeID ) 00248 { 00249 $contentTree = eZContentStructureTreeOperator::initContentStructureTree( $rootNodeID, $fetchHidden, $classFilter ); 00250 00251 // if root node is invisible then no point to fetch children 00252 //if ( count( $contentTree ) == 0 ) 00253 // return $contentTree; 00254 00255 if ( $contentTree === false) 00256 return $contentTree; 00257 00258 $nodesLeft = $maxNodes - 1; 00259 $depthLeft = $maxDepth - 1; 00260 00261 eZContentStructureTreeOperator::children( $contentTree, $classFilter, $depthLeft, $nodesLeft, $sortArray, $fetchHidden, $unfoldNodeID ); 00262 00263 return $contentTree; 00264 } 00265 00266 /*! 00267 \static 00268 \private 00269 Parameters the same as in \a children. 00270 \Returns one-level children. 00271 */ 00272 function oneLevelChildren( &$contentTree, &$classFilter, &$sortBy, &$nodesLeft, $fetchHidden ) 00273 { 00274 $parentNode = $contentTree['parent_node']; 00275 00276 if ( !is_array( $parentNode ) || count( $parentNode['node'] ) == 0 ) 00277 { 00278 return false; 00279 } 00280 00281 if ( !$parentNode['object']['is_container'] || $parentNode['node']['children_count'] == 0 ) 00282 { 00283 return true; 00284 } 00285 00286 // fill parent node attributes 00287 if ( $nodesLeft != 0) 00288 { 00289 // get children 00290 $sortArray = ( $sortBy == false ) ? $parentNode['node']['sort_array'] : $sortBy; 00291 00292 $children = eZContentStructureTreeOperator::subTree( array( 'SortBy' => $sortArray, 00293 'ClassFilterType' => 'include', 00294 'ClassFilterArray'=> $classFilter, 00295 'NodePath' => $parentNode['node']['path_string'], 00296 'NodeDepth' => $parentNode['node']['depth'], 00297 'FetchHidden' => $fetchHidden ), 00298 $parentNode['node']['node_id'] ); 00299 if ( $children && count( $children ) > 0 ) 00300 { 00301 $childrenNodes =& $contentTree['children']; 00302 // fill children attributes 00303 foreach ( $children as $child ) 00304 { 00305 $childrenCount = 0; 00306 00307 if ( $child['is_container'] == '1' ) 00308 { 00309 $childrenCount = eZContentStructureTreeOperator::subTree( array( 'SortBy' => false, 00310 'ClassFilterType' => 'include', 00311 'ClassFilterArray'=> $classFilter, 00312 'NodePath' => $child['path_string'], 00313 'NodeDepth' => $child['depth'], 00314 'FetchHidden' => $fetchHidden ), 00315 $child['node_id'], 00316 true ); 00317 } 00318 00319 $childNode = eZContentStructureTreeOperator::createContentStructureNode( $child, $childrenCount ); 00320 00321 $childrenNodes[] = array( 'parent_node' => $childNode, 00322 'children' => array() ); 00323 00324 --$nodesLeft; 00325 if ( $nodesLeft == 0 ) 00326 { 00327 return false; 00328 } 00329 } 00330 } 00331 return true; 00332 } 00333 00334 return false; 00335 } 00336 00337 /*! 00338 \static 00339 \private 00340 Creates a tree of content by recursive calls to \a children and \a oneLevelChildren. 00341 \a $contentTree is a tree at previous call to \a children. 00342 \a $classFilter is an array of class ids. Only nodes of these classes will be fetched from db. 00343 \a $depthLeft determines a depth of recursion. 00344 \a $nodesLeft determines a number of nodes which are left to fetch. 00345 \a $sortBy is a method of sorting one-level children. 00346 \a $fetchHidden - should or not fetch unpublished/hidden nodes 00347 */ 00348 function children( &$contentTree, &$classFilter, &$depthLeft, &$nodesLeft, &$sortBy, $fetchHidden, $unfoldNodeID ) 00349 { 00350 if ( $depthLeft == 0 ) 00351 return false; 00352 00353 if ( eZContentStructureTreeOperator::oneLevelChildren( $contentTree, $classFilter, $sortBy, $nodesLeft, $fetchHidden ) ) 00354 { 00355 --$depthLeft; 00356 if ( $depthLeft != 0 ) 00357 { 00358 $children =& $contentTree['children']; 00359 00360 foreach( $children as &$child ) 00361 { 00362 $currentDepth = $depthLeft; 00363 00364 if ( $unfoldNodeID != 0 and $unfoldNodeID != $child['parent_node']['node']['node_id'] ) 00365 continue; 00366 00367 if ( !eZContentStructureTreeOperator::children( $child, $classFilter, $currentDepth, $nodesLeft, $sortBy, $fetchHidden, 0 ) ) 00368 { 00369 return false; 00370 } 00371 } 00372 } 00373 return true; 00374 } 00375 return false; 00376 } 00377 00378 /*! 00379 \static 00380 \private 00381 Creates a node of content structure tree and sets up attributes of node 00382 using \a $treeNode to retrieve necessary data. 00383 \return new content structure tree node. 00384 */ 00385 function createContentStructureNode( &$treeNode, $childrenCount ) 00386 { 00387 $node = array( 'node' => array( 'node_id' => $treeNode['node_id'], 00388 'path_identification_string' => $treeNode['path_identification_string'], 00389 'children_count' => $childrenCount, 00390 'sort_array' => eZContentObjectTreeNode::sortArrayBySortFieldAndSortOrder( $treeNode['sort_field'], $treeNode['sort_order'] ), 00391 'path_string' => $treeNode['path_string'], 00392 'depth' => $treeNode['depth'], 00393 'is_hidden' => $treeNode['is_hidden'], 00394 'is_invisible' => $treeNode['is_invisible'] ), 00395 'classes_js_array' => eZContentObjectTreeNode::availableClassListJsArray( array( 'path_string' => $treeNode['path_string'], 'is_container' => $treeNode['is_container'], 'node_id' => $treeNode['node_id'] ) ), 00396 'object' => array( 'id' => $treeNode['id'], 00397 'name' => $treeNode['name'], 00398 'class_identifier' => $treeNode['class_identifier'], 00399 'class_name' => eZContentClass::nameFromSerializedString( $treeNode['class_serialized_name_list'] ), 00400 'published' => $treeNode['published'], 00401 'is_container' => ( $treeNode['is_container'] == '1' ), 00402 'language_js_array' => eZContentLanguage::jsArrayByMask( $treeNode['language_mask'] ) ) ); 00403 return $node; 00404 } 00405 00406 /*! 00407 \static 00408 \private 00409 Initializes a tree: creates root node. 00410 \return a tree with one node and empty children subtree. 00411 */ 00412 function initContentStructureTree( $rootNodeID, $fetchHidden, $classFilter = false ) 00413 { 00414 // create initial subtree with root node and empty children. 00415 $nodes = false; 00416 $rootTreeNode = eZContentObjectTreeNode::fetch( $rootNodeID ); 00417 if ( $rootTreeNode && $rootTreeNode->canRead() ) 00418 { 00419 if ( !$fetchHidden && ( $rootTreeNode->attribute( 'is_hidden' ) || $rootTreeNode->attribute( 'is_invisible' ) ) ) 00420 { 00421 return false; 00422 } 00423 else 00424 { 00425 $contentObject = $rootTreeNode->attribute( 'object' ); 00426 00427 $viewNodeAllowed = true; 00428 if ( is_array( $classFilter ) && count( $classFilter ) > 0 ) 00429 { 00430 $contentClassIdentifier = $contentObject->attribute( 'class_identifier' ); 00431 00432 if ( !in_array( $contentClassIdentifier, $classFilter ) ) 00433 $viewNodeAllowed = false; 00434 } 00435 00436 if ( $viewNodeAllowed ) 00437 { 00438 $rootNode = array( 'node' => array( 'node_id' => $rootTreeNode->attribute( 'node_id' ), 00439 'path_identification_string' => $rootTreeNode->pathWithNames(), 00440 'children_count' => $rootTreeNode->attribute( 'children_count' ), 00441 'sort_array' => $rootTreeNode->attribute( 'sort_array' ), 00442 'path_string' => $rootTreeNode->attribute( 'path_string' ), 00443 'depth' => $rootTreeNode->attribute( 'depth' ), 00444 'is_hidden' => $rootTreeNode->attribute( 'is_hidden' ), 00445 'is_invisible' => $rootTreeNode->attribute( 'is_invisible' ) ), 00446 'classes_js_array' => eZContentObjectTreeNode::availableClassListJsArray( array( 'node' => &$rootTreeNode ) ), 00447 'object' => array( 'id' => $contentObject->attribute( 'id' ), 00448 'name' => $contentObject->attribute( 'name' ), 00449 'class_identifier' => $contentObject->attribute( 'class_identifier' ), 00450 'class_name' => $contentObject->attribute('class_name'), 00451 'published' => $contentObject->attribute( 'published' ), 00452 'is_container' => true, 00453 'language_js_array' => eZContentLanguage::jsArrayByMask( $contentObject->attribute( 'language_mask' ) ) ) ); 00454 00455 $nodes = array( 'parent_node' => &$rootNode, 00456 'children' => array() ); 00457 } 00458 } 00459 } 00460 00461 return $nodes; 00462 } 00463 00464 /// \privatesection 00465 public $Operators; 00466 } 00467 ?>