|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZSubtreeNotificationRule class 00004 // 00005 // Created on: <14-May-2003 16:20:24 sp> 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 ezsubtreenotificationrule.php 00032 */ 00033 00034 /*! 00035 \class eZSubtreeNotificationRule ezsubtreenotificationrule.php 00036 \brief The class eZSubtreeNotificationRule does 00037 00038 */ 00039 //include_once( 'kernel/classes/ezcontentobjecttreenode.php' ); 00040 00041 class eZSubtreeNotificationRule extends eZPersistentObject 00042 { 00043 /*! 00044 Constructor 00045 */ 00046 function eZSubtreeNotificationRule( $row ) 00047 { 00048 $this->eZPersistentObject( $row ); 00049 } 00050 00051 static function definition() 00052 { 00053 return array( "fields" => array( "id" => array( 'name' => 'ID', 00054 'datatype' => 'integer', 00055 'default' => 0, 00056 'required' => true ), 00057 "user_id" => array( 'name' => "UserID", 00058 'datatype' => 'integer', 00059 'default' => '', 00060 'required' => true, 00061 'foreign_class' => 'eZUser', 00062 'foreign_attribute' => 'contentobject_id', 00063 'multiplicity' => '1..*' ), 00064 "use_digest" => array( 'name' => "UseDigest", 00065 'datatype' => 'integer', 00066 'default' => 0, 00067 'required' => true ), 00068 "node_id" => array( 'name' => "NodeID", 00069 'datatype' => 'integer', 00070 'default' => 0, 00071 'required' => true, 00072 'foreign_class' => 'eZContentObjectTreeNode', 00073 'foreign_attribute' => 'node_id', 00074 'multiplicity' => '1..*' ) ), 00075 "keys" => array( "id" ), 00076 "function_attributes" => array( 'node' => 'node' ), 00077 "increment_key" => "id", 00078 "sort" => array( "id" => "asc" ), 00079 "class_name" => "eZSubtreeNotificationRule", 00080 "name" => "ezsubtree_notification_rule" ); 00081 } 00082 00083 00084 static function create( $nodeID, $userID, $useDigest = 0 ) 00085 { 00086 $rule = new eZSubtreeNotificationRule( array( 'user_id' => $userID, 00087 'use_digest' => $useDigest, 00088 'node_id' => $nodeID ) ); 00089 return $rule; 00090 } 00091 00092 static function fetchNodesForUserID( $userID, $asObject = true ) 00093 { 00094 $nodeIDList = eZPersistentObject::fetchObjectList( eZSubtreeNotificationRule::definition(), 00095 array( 'node_id' ), array( 'user_id' => $userID ), 00096 null,null,false ); 00097 $nodes = array(); 00098 if ( $asObject ) 00099 { 00100 foreach ( $nodeIDList as $nodeRow ) 00101 { 00102 $nodes[] = eZContentObjectTreeNode::fetch( $nodeRow['node_id'] ); 00103 } 00104 } 00105 else 00106 { 00107 foreach ( $nodeIDList as $nodeRow ) 00108 { 00109 $nodes[] = $nodeRow['node_id']; 00110 } 00111 } 00112 return $nodes; 00113 } 00114 00115 static function fetchList( $userID, $asObject = true, $offset = false, $limit = false ) 00116 { 00117 return eZPersistentObject::fetchObjectList( eZSubtreeNotificationRule::definition(), 00118 null, array( 'user_id' => $userID ), 00119 null, array( 'offset' => $offset, 00120 'length' => $limit ), $asObject ); 00121 } 00122 00123 static function fetchListCount( $userID ) 00124 { 00125 $countRes = eZPersistentObject::fetchObjectList( eZSubtreeNotificationRule::definition(), 00126 array(), 00127 array( 'user_id' => $userID ), 00128 false, 00129 null, 00130 false, 00131 false, 00132 array( array( 'operation' => 'count( id )', 00133 'name' => 'count' ) ) ); 00134 return $countRes[0]['count']; 00135 } 00136 00137 /** 00138 * Fetch allowed subtreenotification rules based on node_id list and a 00139 * content object 00140 * 00141 * @param array $nodeIDList node id list for notification event 00142 * @param eZContentObject content object to add 00143 * 00144 * @return array matching subtree notification rule data 00145 **/ 00146 static function fetchUserList( $nodeIDList, $contentObject ) 00147 { 00148 if ( count( $nodeIDList ) == 0 ) 00149 { 00150 $retValue = array(); 00151 return $retValue; 00152 } 00153 00154 $db = eZDB::instance(); 00155 $concatString = $db->concatString( array( 'user_tree.path_string', "'%'" ) ); 00156 00157 // Select affected users 00158 $sqlINString = $db->generateSQLINStatement( $nodeIDList, 'subtree_rule.node_id', false, false, 'int' ); 00159 $sql = "SELECT DISTINCT subtree_rule.user_id, 00160 user_node.node_id 00161 FROM ezsubtree_notification_rule subtree_rule, 00162 ezcontentobject_tree user_node, 00163 ezuser_setting 00164 WHERE $sqlINString AND 00165 user_node.contentobject_id = subtree_rule.user_id AND 00166 ezuser_setting.user_id = subtree_rule.user_id AND 00167 user_node.is_invisible = 0 AND 00168 ezuser_setting.is_enabled = 1"; 00169 $userPart = $db->arrayQuery( $sql ); 00170 00171 // Remove duplicates 00172 $userNodeIDList = array(); 00173 foreach ( $userPart as $row ) 00174 $userNodeIDList[] = $row['node_id']; 00175 $userNodeIDList = array_unique( $userNodeIDList ); 00176 00177 if ( count( $userNodeIDList ) == 0 ) 00178 { 00179 $retValue = array(); 00180 return $retValue; 00181 } 00182 00183 // Select affected nodes 00184 $sqlINString = $db->generateSQLINstatement( $userNodeIDList, 'user_node.node_id', false, false, 'int' ); 00185 $sql = "SELECT DISTINCT user_node.node_id, 00186 user_node.path_string, 00187 user_tree.contentobject_id 00188 FROM ezcontentobject_tree user_node, 00189 ezcontentobject_tree user_tree 00190 WHERE $sqlINString AND 00191 user_node.path_string LIKE $concatString"; 00192 $nodePart = $db->arrayQuery( $sql ); 00193 00194 // Remove duplicates 00195 $objectIDList = array(); 00196 foreach ( $nodePart as $row ) 00197 if ( $row['contentobject_id'] != '0' ) 00198 $objectIDList[] = $row['contentobject_id']; 00199 $objectIDList = array_unique( $objectIDList ); 00200 00201 if ( count( $objectIDList ) == 0 ) 00202 { 00203 $retValue = array(); 00204 return $retValue; 00205 } 00206 00207 // Select affected roles and policies 00208 $sqlINString = $db->generateSQLINStatement( $objectIDList, 'user_role.contentobject_id', false, false, 'int' ); 00209 $sql = "SELECT DISTINCT user_role.contentobject_id, 00210 policy.id AS policy_id, 00211 user_role.limit_identifier AS limitation, 00212 user_role.limit_value AS value 00213 FROM ezuser_role user_role, 00214 ezpolicy policy 00215 WHERE $sqlINString AND 00216 ( user_role.role_id=policy.role_id AND 00217 ( policy.module_name='*' OR 00218 ( policy.module_name='content' AND 00219 ( policy.function_name='*' OR 00220 policy.function_name='read' 00221 ) 00222 ) 00223 ) 00224 )"; 00225 $rolePart = $db->arrayQuery( $sql ); 00226 00227 // Build resultArray. Make sure there are no duplicates. 00228 $resultArray = array(); 00229 foreach ( $userPart as $up ) 00230 { 00231 foreach ( $nodePart as $np ) 00232 { 00233 if ( $up['node_id'] == $np['node_id'] ) 00234 { 00235 foreach ( $rolePart as $rp ) 00236 { 00237 if ( $np['contentobject_id'] == $rp['contentobject_id'] ) 00238 { 00239 $key = $rp['policy_id'] . $up['user_id'] . $rp['limitation'] . $rp['value']; 00240 $resultArray[$key] = array( 'policy_id' => $rp['policy_id'], 00241 'user_id' => $up['user_id'], 00242 'limitation' => $rp['limitation'], 00243 'value' => $rp['value'] ); 00244 } 00245 } 00246 } 00247 } 00248 } 00249 00250 $policyIDArray = array(); 00251 $limitedPolicyIDArray = array(); 00252 $userIDArray = array(); 00253 foreach( $resultArray as $result ) 00254 { 00255 $userIDArray[(string)$result['user_id']] = (int)$result['user_id']; 00256 } 00257 00258 foreach( $resultArray as $result ) 00259 { 00260 if ( $result['limitation'] == '' ) 00261 { 00262 $policyIDArray[(string)$result['policy_id']][] =& $userIDArray[(string)$result['user_id']]; 00263 } 00264 else 00265 { 00266 $limitedPolicyIDArray[] = array( 'user_id' => $userIDArray[(string)$result['user_id']], 00267 'limitation' => $result['limitation'], 00268 'value' => $result['value'], 00269 'policyID' => $result['policy_id'] ); 00270 } 00271 } 00272 00273 //include_once( 'kernel/classes/ezpolicy.php' ); 00274 $acceptedUserArray = array(); 00275 foreach( array_keys( $policyIDArray ) as $policyID ) 00276 { 00277 foreach( array_keys( $policyIDArray[$policyID] ) as $key ) 00278 { 00279 if ( $policyIDArray[$policyID][$key] === false ) 00280 { 00281 unset( $policyIDArray[$policyID][$key] ); 00282 } 00283 } 00284 00285 if ( count( $policyIDArray[$policyID] ) == 0 ) 00286 { 00287 continue; 00288 } 00289 00290 $userArray = eZSubtreeNotificationRule::checkObjectAccess( $contentObject, $policyID, $policyIDArray[$policyID] ); 00291 $acceptedUserArray = array_merge( $acceptedUserArray, $userArray ); 00292 00293 foreach ( $userArray as $userID ) 00294 { 00295 $userIDArray[(string)$userID] = false; 00296 } 00297 } 00298 00299 foreach( $limitedPolicyIDArray as $policyEntry ) 00300 { 00301 if ( $policyEntry['user_id'] === false ) 00302 { 00303 continue; 00304 } 00305 00306 $userArray = eZSubtreeNotificationRule::checkObjectAccess( $contentObject, 00307 $policyEntry['policyID'], 00308 array( $policyEntry['user_id'] ), 00309 array( $policyEntry['limitation'] => $policyEntry['value'] ) ); 00310 00311 $acceptedUserArray = array_merge( $acceptedUserArray, $userArray ); 00312 foreach ( $userArray as $userID ) 00313 { 00314 $userIDArray[(string)$userID] = false; 00315 } 00316 } 00317 $acceptedUserArray = array_unique( $acceptedUserArray ); 00318 00319 foreach( array_keys( $acceptedUserArray ) as $key ) 00320 { 00321 if ( !is_int( $acceptedUserArray[$key] ) or $acceptedUserArray[$key] == 0 ) 00322 { 00323 unset( $acceptedUserArray[$key] ); 00324 } 00325 } 00326 00327 if ( count( $acceptedUserArray ) == 0 ) 00328 { 00329 $retValue = array(); 00330 return $retValue; 00331 } 00332 00333 $nodeIDWhereString = $db->generateSQLINStatement( $nodeIDList, 'rule.node_id', false, false, 'int' ); 00334 $userIDWhereString = $db->generateSQLINStatement( $acceptedUserArray, 'rule.user_id', false, false, 'int' ); 00335 $rules = $db->arrayQuery( "SELECT rule.user_id, rule.use_digest, ezuser.email as address 00336 FROM ezsubtree_notification_rule rule, ezuser 00337 WHERE rule.user_id=ezuser.contentobject_id AND 00338 $nodeIDWhereString AND 00339 $userIDWhereString" ); 00340 return $rules; 00341 } 00342 00343 /*! 00344 \private 00345 00346 Check access for specified policy on object, and user list. 00347 00348 \param Content object 00349 \param policyID 00350 \param userID array 00351 \param user limits 00352 00353 \return array of user ID's which has access to object 00354 */ 00355 static function checkObjectAccess( $contentObject, $policyID, $userIDArray, $userLimits = false ) 00356 { 00357 $policy = eZPolicy::fetch( $policyID ); 00358 if ( $userLimits ) 00359 { 00360 reset( $userLimits ); 00361 $policy->setAttribute( 'limit_identifier', 'User_' . key( $userLimits ) ); 00362 $policy->setAttribute( 'limit_value', current( $userLimits ) ); 00363 } 00364 00365 $limitationArray = $policy->accessArray(); 00366 $limitationArray = current( current( $limitationArray ) ); 00367 $accessUserIDArray = $userIDArray; 00368 00369 if ( isset( $limitationArray['*'] ) && 00370 $limitationArray['*'] == '*' ) 00371 { 00372 $returnArray = array(); 00373 foreach ( $accessUserIDArray as $userID ) 00374 { 00375 $returnArray[] = $userID; 00376 } 00377 return $returnArray; 00378 } 00379 00380 $limitationArray = current( $limitationArray ); 00381 00382 $user = eZUser::currentUser(); 00383 $classID = $contentObject->attribute( 'contentclass_id' ); 00384 $nodeArray = $contentObject->attribute( 'assigned_nodes' ); 00385 00386 if ( isset( $limitationArray['Subtree' ] ) ) 00387 { 00388 $checkedSubtree = false; 00389 } 00390 else 00391 { 00392 $checkedSubtree = true; 00393 $nodeSubtree = true; 00394 } 00395 if ( isset( $limitationArray['Node'] ) ) 00396 { 00397 $checkedNode = false; 00398 } 00399 else 00400 { 00401 $checkedNode = true; 00402 $nodeLimit = true; 00403 } 00404 00405 foreach ( array_keys( $limitationArray ) as $key ) 00406 { 00407 if ( count( $accessUserIDArray ) == 0 ) 00408 { 00409 return array(); 00410 } 00411 switch( $key ) 00412 { 00413 case 'Class': 00414 { 00415 if ( !in_array( $contentObject->attribute( 'contentclass_id' ), $limitationArray[$key] ) ) 00416 { 00417 return array(); 00418 } 00419 } break; 00420 00421 case 'ParentClass': 00422 { 00423 00424 if ( !in_array( $contentObject->attribute( 'contentclass_id' ), $limitationArray[$key] ) ) 00425 { 00426 return array(); 00427 } 00428 } break; 00429 00430 case 'Section': 00431 case 'User_Section': 00432 { 00433 if ( !in_array( $contentObject->attribute( 'section_id' ), $limitationArray[$key] ) ) 00434 { 00435 return array(); 00436 } 00437 } break; 00438 00439 case 'Owner': 00440 { 00441 if ( in_array( $contentObject->attribute( 'owner_id' ), $userIDArray ) ) 00442 { 00443 $accessUserIDArray = array_intersect( $contentObject->attribute( 'owner_id' ), $accessUserIDArray ); 00444 } 00445 else if ( in_array( $contentObject->ID, $userIDArray ) ) 00446 { 00447 $accessUserIDArray = array_intersect( $contentObject->ID, $accessUserIDArray ); 00448 } 00449 else 00450 { 00451 return array(); 00452 } 00453 } break; 00454 00455 case 'Node': 00456 { 00457 $nodeLimit = true; 00458 foreach ( $nodeArray as $node ) 00459 { 00460 if( in_array( $node->attribute( 'node_id' ), $limitationArray[$key] ) ) 00461 { 00462 $nodeLimit = false; 00463 break; 00464 } 00465 } 00466 if ( $nodeLimit && $checkedSubtree && $nodeSubtree ) 00467 { 00468 return array(); 00469 } 00470 $checkedNode = true; 00471 } break; 00472 00473 case 'Subtree': 00474 { 00475 $nodeSubtree = true; 00476 foreach ( $nodeArray as $node ) 00477 { 00478 $path = $node->attribute( 'path_string' ); 00479 $subtreeArray = $limitationArray[$key]; 00480 $validSubstring = false; 00481 foreach ( $subtreeArray as $subtreeString ) 00482 { 00483 if ( strstr( $path, $subtreeString ) ) 00484 { 00485 $nodeSubtree = false; 00486 break; 00487 } 00488 } 00489 if ( !$nodeSubtree ) 00490 { 00491 break; 00492 } 00493 } 00494 if ( $nodeSubtree && $checkedNode && $nodeLimit ) 00495 { 00496 return array(); 00497 } 00498 $checkedSubtree = true; 00499 } break; 00500 00501 case 'User_Subtree': 00502 { 00503 $userSubtreeLimit = true; 00504 foreach ( $nodeArray as $node ) 00505 { 00506 $path = $node->attribute( 'path_string' ); 00507 $subtreeArray = $limitationArray[$key]; 00508 $validSubstring = false; 00509 foreach ( $subtreeArray as $subtreeString ) 00510 { 00511 if ( strstr( $path, $subtreeString ) ) 00512 { 00513 $userSubtreeLimit = false; 00514 break; 00515 } 00516 } 00517 if ( !$userSubtreeLimit ) 00518 { 00519 break; 00520 } 00521 } 00522 if ( $userSubtreeLimit ) 00523 { 00524 return array(); 00525 } 00526 } break; 00527 } 00528 } 00529 00530 $returnArray = array(); 00531 foreach ( $accessUserIDArray as $userID ) 00532 { 00533 $returnArray[] = $userID; 00534 } 00535 return $returnArray; 00536 } 00537 00538 function node() 00539 { 00540 if ( $this->Node == null ) 00541 { 00542 $this->Node = eZContentObjectTreeNode::fetch( $this->attribute( 'node_id' ) ); 00543 } 00544 return $this->Node; 00545 } 00546 00547 static function removeByNodeAndUserID( $userID, $nodeID ) 00548 { 00549 eZPersistentObject::removeObject( eZSubtreeNotificationRule::definition(), array( 'user_id' => $userID, 00550 'node_id' => $nodeID ) ); 00551 } 00552 00553 /*! 00554 \static 00555 00556 Remove notifications by user id 00557 00558 \param userID 00559 */ 00560 static function removeByUserID( $userID ) 00561 { 00562 eZPersistentObject::removeObject( eZSubtreeNotificationRule::definition(), array( 'user_id' => $userID ) ); 00563 } 00564 00565 /*! 00566 \static 00567 Cleans up all notification rules for all users. 00568 */ 00569 static function cleanup() 00570 { 00571 $db = eZDB::instance(); 00572 $db->query( "DELETE FROM ezsubtree_notification_rule" ); 00573 } 00574 00575 public $Node = null; 00576 } 00577 00578 ?>