PluginProbe
User Access Manager / 1.2.6.9
User Access Manager v1.2.6.9
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
← All changes | class/UamAccessHandler.class.php +619 -262 1.01.2.6.9 View file →
@@ -8,9 +8,9 @@
8 8 *
9 9 * @category UserAccessManager
10 10 * @package UserAccessManager
11 11 * @author Alexander Schneider <alexanderschneider85@googlemail.com>
12 - * @copyright 2008-2010 Alexander Schneider
12 + * @copyright 2008-2013 Alexander Schneider
13 13 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
14 14 * @version SVN: $Id$
15 15 * @link http://wordpress.org/extend/plugins/user-access-manager/
16 16 */
@@ -26,134 +26,297 @@
26 26 */
27 27
28 28 class UamAccessHandler
29 29 {
30 - protected $userAccessManager = null;
31 - protected $postUserGroups = array();
32 - protected $categoryUserGroups = array();
33 - protected $userUserGroups = array();
34 - protected $postAccess = array();
35 - protected $categroyAccess = array();
36 - protected $userGroups = array(
30 + protected $_oUserAccessManager = null;
31 + protected $_aObjectUserGroups = array();
32 + protected $_aObjectAccess = array();
33 + protected $_aUserGroups = array(
37 34 'filtered' => array(),
38 35 'noneFiltered' => array(),
39 36 );
37 + protected $_aPlObjects = array();
38 + protected $_aObjectTypes = array(
39 + 'category',
40 + 'user',
41 + 'role',
42 + );
43 + protected $_aPostableTypes = array(
44 + 'post',
45 + 'page',
46 + 'attachment',
47 + );
48 + protected $_aPostableTypesMap = array();
49 + protected $_aAllObjectTypes = null;
50 + protected $_aAllObjectTypesMap = null;
51 + protected $_aSqlResults = array();
52 + protected $_aValidObjectTypes = array();
40 53
41 54 /**
42 - * The consturctor
55 + * The constructor
43 56 *
44 - * @param object &$userAccessManager The user access manager object.
57 + * @param UserAccessManager $oUserAccessManager The user access manager object.
58 + */
59 + public function __construct(UserAccessManager &$oUserAccessManager)
60 + {
61 + $this->_oUserAccessManager = $oUserAccessManager;
62 +
63 + $this->_aPostableTypes = array_merge($this->_aPostableTypes, get_post_types(array('publicly_queryable' => true), 'names'));
64 + $this->_aPostableTypes = array_unique($this->_aPostableTypes);
65 +
66 + $this->_aPostableTypesMap = array_flip($this->_aPostableTypes);
67 +
68 + $this->_aObjectTypes = array_merge($this->_aPostableTypes, $this->_aObjectTypes);
69 + add_action( 'registered_post_type', array( &$this, 'registered_post_type'), 10, 2);
70 + }
71 +
72 + /**
73 + * used for adding custom post types using the registered_post_type hook
74 + * @see http://wordpress.org/support/topic/modifying-post-type-using-the-registered_post_type-hook
75 + *
76 + * @param string $post_type The string for the new post_type
77 + * @param stdClass $oArgs The array of arguments used to create the post_type
78 + *
79 + */
80 + public function registered_post_type($post_type, $oArgs)
81 + {
82 + if ($oArgs->publicly_queryable) {
83 + $this->_aPostableTypes[] = $oArgs->name;
84 + $this->_aPostableTypes = array_unique($this->_aPostableTypes);
85 + $this->_aPostableTypesMap = array_flip($this->_aPostableTypes);
86 + $this->_aObjectTypes = array_merge($this->_aPostableTypes, $this->_aObjectTypes);
87 + $this->_aAllObjectTypes = null;
88 + $this->_aAllObjectTypesMap = null;
89 + $this->_aValidObjectTypes = null;
90 + }
91 + }
92 +
93 + /**
94 + * Checks if type is postable.
95 + *
96 + * @param string $sType
97 + *
98 + * @return bool
99 + */
100 + public function isPostableType($sType)
101 + {
102 + return isset($this->_aPostableTypesMap[$sType]);
103 + }
104 +
105 + /**
106 + * Returns the user access manager object.
45 107 *
46 - * @return null
108 + * @return UserAccessManager
47 109 */
48 - function __construct(&$userAccessManager)
110 + public function &getUserAccessManager()
49 111 {
50 - $this->userAccessManager = $userAccessManager;
112 + return $this->_oUserAccessManager;
51 113 }
52 114
53 115 /**
54 - * Returns the user access manager object.
116 + * Returns the predefined object types.
55 117 *
56 - * @return object
118 + * @return array
57 119 */
58 - function &getUserAccessManager()
120 + public function getObjectTypes()
59 121 {
60 - return $this->userAccessManager;
122 + return $this->_aObjectTypes;
61 123 }
62 124
63 125 /**
126 + * Returns the predefined object types.
127 + *
128 + * @return array;
129 + */
130 + public function getPostableTypes()
131 + {
132 + return $this->_aPostableTypes;
133 + }
134 +
135 + /**
136 + * Returns all objects types.
137 + *
138 + * @return array
139 + */
140 + public function getAllObjectTypes()
141 + {
142 + if ($this->_aAllObjectTypes === null) {
143 + $aPlObjects = $this->getPlObjects();
144 +
145 + $this->_aAllObjectTypes = array_merge(
146 + $this->_aObjectTypes,
147 + array_keys($aPlObjects)
148 + );
149 + }
150 +
151 + return $this->_aAllObjectTypes;
152 + }
153 +
154 + /**
155 + * Returns all objects types as map.
156 + *
157 + * @return array
158 + */
159 + public function getAllObjectTypesMap()
160 + {
161 + if ($this->_aAllObjectTypesMap === null) {
162 + $this->_aAllObjectTypesMap = array_flip($this->getAllObjectTypes());
163 + }
164 +
165 + return $this->_aAllObjectTypesMap;
166 + }
167 +
168 + /**
169 + * Magic method getter.
170 + *
171 + * @param string $sName The name of the function
172 + * @param array $aArguments The arguments for the function
173 + *
174 + * @return mixed
175 + */
176 + public function __call($sName, $aArguments)
177 + {
178 + $oUserAccessManager = $this->getUserAccessManager();
179 +
180 + if ($oUserAccessManager->startsWith($sName, 'getUserGroupsFor')) {
181 + $sPrefix = 'getUserGroupsFor';
182 + } elseif ($oUserAccessManager->startsWith($sName, 'checkAccessFor')) {
183 + $sPrefix = 'checkAccessFor';
184 + }
185 +
186 + if (isset($sPrefix)) {
187 + $sObjectType = str_replace($sPrefix, '', $sName);
188 + $sObjectType = strtolower($sObjectType);
189 +
190 + $iObjectId = $aArguments[0];
191 +
192 + if ($sPrefix == 'getUserGroupsFor') {
193 + return $this->getUserGroupsForObject($sObjectType, $iObjectId);
194 + } elseif ($sPrefix == 'checkAccessFor') {
195 + return $this->checkObjectAccess($sObjectType, $iObjectId);
196 + }
197 + }
198 +
199 + return null;
200 + }
201 +
202 + /**
64 203 * Filter the user groups of an object if authors_can_add_posts_to_groups
65 204 * option is enabled
66 205 *
67 - * @param array $userGroups The user groups.
206 + * @param UamUserGroup[] $aUserGroups The user groups.
68 207 *
69 208 * @return array
70 209 */
71 - private function _filterUserGroups($userGroups)
210 + protected function _filterUserGroups($aUserGroups)
72 211 {
73 - $uamOptions = $this->getUserAccessManager()->getAdminOptions();
212 + $aUamOptions = $this->getUserAccessManager()->getAdminOptions();
74 213
75 - if ($uamOptions['authors_can_add_posts_to_groups'] == 'true'
76 - && !$this->checkUserAccess()
77 - && $this->getUserAccessManager()->atAdminPanel
214 + if ($aUamOptions['authors_can_add_posts_to_groups'] == 'true'
215 + && !$this->checkUserAccess('manage_user_groups')
216 + && $this->getUserAccessManager()->atAdminPanel()
78 217 ) {
79 - global $current_user;
218 + $oCurrentUser = $this->getUserAccessManager()->getCurrentUser();
219 + $aUserGroupsForUser = $this->getUserGroupsForObject('user', $oCurrentUser->ID);
80 220
81 - $userGroupsForUser
82 - = $this->getUserGroupsForUser($current_user->ID);
83 -
84 - foreach ($userGroups as $key => $uamUserGroup) {
85 - if (!array_key_exists($uamUserGroup->getId(), $userGroupsForUser)) {
86 - unset($userGroups[$key]);
221 + foreach ($aUserGroups as $sKey => $oUamUserGroup) {
222 + if (!isset($aUserGroupsForUser[$oUamUserGroup->getId()])) {
223 + unset($aUserGroups[$sKey]);
87 224 }
88 225 }
89 226 }
90 227
91 - return $userGroups;
228 + return $aUserGroups;
92 229 }
230 +
231 + /**
232 + * Checks if the object type is a valid one.
233 + *
234 + * @param string $sObjectType The object type to check.
235 + *
236 + * @return boolean
237 + */
238 + public function isValidObjectType($sObjectType)
239 + {
240 + if (!isset($this->_aValidObjectTypes[$sObjectType])) {
241 + $aObjectTypesMap = $this->getAllObjectTypesMap();
242 +
243 + if (isset($aObjectTypesMap[$sObjectType])) {
244 + $this->_aValidObjectTypes[$sObjectType] = true;
245 + } else {
246 + $this->_aValidObjectTypes[$sObjectType] = false;
247 + }
248 + }
249 +
250 + return $this->_aValidObjectTypes[$sObjectType];
251 + }
93 252
94 253 /**
95 254 * Returns all user groups or one requested by the user group id.
96 255 *
97 - * @param integer $userGroupId The id of the single user group
98 - * which should be returned.
99 - * @param boolean $filter Filter the groups.
256 + * @param integer $iUserGroupId The id of the single user group which should be returned.
257 + * @param boolean $blFilter Filter the groups.
100 258 *
101 - * @return array|object
259 + * @return UamUserGroup[]|UamUserGroup
102 260 */
103 - function getUserGroups($userGroupId = null, $filter = true)
261 + public function getUserGroups($iUserGroupId = null, $blFilter = true)
104 262 {
105 - if ($filter) {
106 - $filterAttr = 'filtered';
263 + if ($blFilter) {
264 + $sFilterAttr = 'filtered';
107 265 } else {
108 - $filterAttr = 'noneFiltered';
266 + $sFilterAttr = 'noneFiltered';
109 267 }
110 268
111 - if ($userGroupId == null
112 - && $this->userGroups[$filterAttr] != array()
269 + if ($iUserGroupId === null
270 + && $this->_aUserGroups[$sFilterAttr] != array()
113 271 ) {
114 - return $this->userGroups[$filterAttr];
115 - } elseif ($userGroupId != null
116 - && $this->userGroups[$filterAttr] != array()
272 + return $this->_aUserGroups[$sFilterAttr];
273 + } elseif ($iUserGroupId !== null
274 + && $this->_aUserGroups[$sFilterAttr] != array()
117 275 ) {
118 - if (isset($this->userGroups[$filterAttr][$userGroupId])) {
119 - return $this->userGroups[$filterAttr][$userGroupId];
276 + if (isset($this->_aUserGroups[$sFilterAttr][$iUserGroupId])) {
277 + return $this->_aUserGroups[$sFilterAttr][$iUserGroupId];
120 278 } else {
121 279 return null;
122 280 }
123 281 }
124 282
125 - $this->userGroups[$filterAttr] = array();
126 -
283 + $this->_aUserGroups[$sFilterAttr] = array();
284 +
285 + /**
286 + * @var wpdb $wpdb
287 + */
127 288 global $wpdb;
128 289
129 - $userGroupsDb = $wpdb->get_results(
130 - "SELECT ID
131 - FROM " . DB_ACCESSGROUP . "
132 - ORDER BY ID", ARRAY_A
290 + $aUserGroupsDb = $wpdb->get_results(
291 + "SELECT ID
292 + FROM " . DB_ACCESSGROUP . "
293 + ORDER BY ID", ARRAY_A
133 294 );
134 295
135 - if (isset($userGroupsDb)) {
136 - foreach ($userGroupsDb as $userGroupDb) {
137 - $this->userGroups[$filterAttr][$userGroupDb['ID']]
138 - = new UamUserGroup(&$this, $userGroupDb['ID']);
296 + if (isset($aUserGroupsDb)) {
297 + foreach ($aUserGroupsDb as $aUserGroupDb) {
298 + $this->_aUserGroups[$sFilterAttr][$aUserGroupDb['ID']] = new UamUserGroup($this, $aUserGroupDb['ID']);
139 299 }
140 300 }
141 301
142 302 //Filter the user groups
143 - if ($filter) {
144 - $this->userGroups[$filterAttr]
145 - = $this->_filterUserGroups($this->userGroups[$filterAttr]);
303 + if ($blFilter) {
304 + $this->_aUserGroups[$sFilterAttr] = $this->_filterUserGroups($this->_aUserGroups[$sFilterAttr]);
146 305 }
147 306
148 - if ($userGroupId == null) {
149 - return $this->userGroups[$filterAttr];
150 - } elseif ($userGroupId != null) {
151 - if (isset($this->userGroups[$filterAttr][$userGroupId])) {
152 - return $this->userGroups[$filterAttr][$userGroupId];
153 - } else {
154 - return null;
307 + if ($iUserGroupId == null) {
308 + if (isset($this->_aUserGroups[$sFilterAttr])) {
309 + return $this->_aUserGroups[$sFilterAttr];
155 310 }
311 +
312 + return array();
313 + } else {
314 + if (isset($this->_aUserGroups[$sFilterAttr][$iUserGroupId])) {
315 + return $this->_aUserGroups[$sFilterAttr][$iUserGroupId];
316 + }
317 +
318 + return null;
156 319 }
157 320 }
158 321
159 322 /**
@@ -158,30 +321,32 @@
158 321
159 322 /**
160 323 * Adds a user group.
161 324 *
162 - * @param object $userGroup The user group which we want to add.
325 + * @param UamUserGroup $oUserGroup The user group which we want to add.
163 326 *
164 327 * @return null
165 328 */
166 - function addUserGroup($userGroup)
329 + public function addUserGroup($oUserGroup)
167 330 {
168 331 $this->getUserGroups();
169 - $this->userGroups[$userGroup->getId()] = $userGroup;
332 + $this->_aUserGroups['noneFiltered'][$oUserGroup->getId()] = $oUserGroup;
333 + $this->_aUserGroups['filtered'] = array();
170 334 }
171 335
172 336 /**
173 337 * Deletes a user group.
174 338 *
175 - * @param integer $userGroupId The user group id which we want to delete.
339 + * @param integer $iUserGroupId The user group _iId which we want to delete.
176 340 *
177 341 * @return null
178 342 */
179 - function deleteUserGroup($userGroupId)
343 + public function deleteUserGroup($iUserGroupId)
180 344 {
181 - if ($this->getUserGroups($userGroupId) != null) {
182 - $this->getUserGroups($userGroupId)->delete();
183 - unset($this->userGroups[$userGroupId]);
345 + if ($this->getUserGroups($iUserGroupId) != null) {
346 + $this->getUserGroups($iUserGroupId)->delete();
347 + unset($this->_aUserGroups['noneFiltered'][$iUserGroupId]);
348 + $this->_aUserGroups['filtered'] = array();
184 349 }
185 350 }
186 351
187 352 /**
@@ -186,248 +351,395 @@
186 351
187 352 /**
188 353 * Returns the user groups for the given object.
189 354 *
190 - * @param integer $objectId The id of the object.
191 - * @param string $type The type for what we want the groups.
192 - * @param boolean $filter Filter the groups.
355 + * @param string $sObjectType The object type.
356 + * @param integer $iObjectId The _iId of the object.
357 + * @param boolean $blFilter Filter the groups.
193 358 *
194 - * @return array
359 + * @return UamUserGroup[]
195 360 */
196 - private function _getUserGroupsForObject($objectId, $type, $filter = true)
361 + public function getUserGroupsForObject($sObjectType, $iObjectId, $blFilter = true)
197 362 {
198 - $objectUserGroups = array();
363 + if (!$this->isValidObjectType($sObjectType)) {
364 + return array();
365 + }
366 +
367 + if ($sObjectType == 'user') {
368 + $blFilter = false;
369 + }
370 +
371 + if ($blFilter) {
372 + $sFilterAttr = 'filtered';
373 + } else {
374 + $sFilterAttr = 'noneFiltered';
375 + }
199 376
200 - $userGroups = $this->getUserGroups(null, $filter);
201 -
202 - if (isset($userGroups)) {
203 - foreach ($userGroups as $userGroup) {
204 - $objectMembership = $userGroup->{$type.'IsMember'}($objectId, true);
205 -
206 - if ($objectMembership !== false) {
207 - if (isset($objectMembership['byPost'])
208 - || isset($objectMembership['byCategory'])
209 - || isset($objectMembership['byRole'])
377 + if (isset($this->_aObjectUserGroups[$sObjectType][$sFilterAttr][$iObjectId])) {
378 + return $this->_aObjectUserGroups[$sObjectType][$sFilterAttr][$iObjectId];
379 + }
380 +
381 + $sCacheKey = 'getUserGroupsForObject|'.$sObjectType.'|'.$sFilterAttr.'|'.$iObjectId;
382 + $oUserAccessManager = $this->getUserAccessManager();
383 + $aObjectUserGroups = $oUserAccessManager->getFromCache($sCacheKey);
384 +
385 + if ($aObjectUserGroups !== null) {
386 + $this->_aObjectUserGroups[$sObjectType][$sFilterAttr][$iObjectId] = $aObjectUserGroups;
387 + } else {
388 + $aObjectUserGroups = array();
389 + $aUserGroups = $this->getUserGroups(null, $blFilter);
390 +
391 + $aCurIp = explode(".", $_SERVER['REMOTE_ADDR']);
392 +
393 + if (isset($aUserGroups)) {
394 + foreach ($aUserGroups as $oUserGroup) {
395 + $mObjectMembership = $oUserGroup->objectIsMember($sObjectType, $iObjectId, true);
396 +
397 + if ($mObjectMembership !== false
398 + || $sObjectType == 'user' && $this->checkUserIp($aCurIp, $oUserGroup->getIpRange())
210 399 ) {
211 - $userGroup->setRecursive[$objectId] = $objectMembership;
400 + if (is_array($mObjectMembership)) {
401 + $oUserGroup->setRecursiveMembership($sObjectType, $iObjectId, $mObjectMembership);
402 + }
403 +
404 + $aObjectUserGroups[$oUserGroup->getId()] = $oUserGroup;
212 405 }
406 + }
407 + }
213 408
214 - $objectUserGroups[$userGroup->getId()]
215 - = $userGroup;
216 - }
409 + //Filter the user groups
410 + if ($blFilter) {
411 + $aObjectUserGroups = $this->_filterUserGroups($aObjectUserGroups);
217 412 }
413 +
414 + $oUserAccessManager->addToCache($sCacheKey, $aObjectUserGroups);
218 415 }
219 -
220 - //Filter the user groups
221 - if ($filter) {
222 - $objectUserGroups = $this->_filterUserGroups($objectUserGroups);
223 - }
224 -
225 - return $objectUserGroups;
416 +
417 + $this->_aObjectUserGroups[$sObjectType][$sFilterAttr][$iObjectId] = $aObjectUserGroups;
418 + return $this->_aObjectUserGroups[$sObjectType][$sFilterAttr][$iObjectId];
226 419 }
227 420
228 421 /**
229 - * Returns the user groups of the given post.
422 + * Unset the user groups for _aObjects.
230 423 *
231 - * @param integer $postId The id of the post from which we want the groups.
232 - * @param boolean $filter Filter the groups.
424 + * @return null
425 + */
426 + public function unsetUserGroupsForObject()
427 + {
428 + $this->_aObjectUserGroups = array();
429 + }
430 +
431 + /**
432 + * Checks if the current_user has access to the given post.
233 433 *
234 - * @return array
434 + * @param string $sObjectType The object type which should be checked.
435 + * @param integer $iObjectId The _iId of the object.
436 + *
437 + * @return boolean
235 438 */
236 - function getUserGroupsForPost($postId, $filter = true)
439 + public function checkObjectAccess($sObjectType, $iObjectId)
237 440 {
238 - if ($filter) {
239 - $filterAttr = 'filtered';
441 + if (!$this->isValidObjectType($sObjectType)) {
442 + return true;
443 + }
444 +
445 + if (isset($this->_aObjectAccess[$sObjectType][$iObjectId])) {
446 + return $this->_aObjectAccess[$sObjectType][$iObjectId];
447 + }
448 +
449 + $oCurrentUser = $this->getUserAccessManager()->getCurrentUser();
450 +
451 + if ($this->isPostableType($sObjectType)) {
452 + $oPost = $this->getUserAccessManager()->getPost($iObjectId);
453 + $sAuthorId = $oPost->post_author;
240 454 } else {
241 - $filterAttr = 'noneFiltered';
455 + $sAuthorId = -1;
242 456 }
243 457
244 - if (isset($this->postUserGroups[$filterAttr][$postId])) {
245 - return $this->postUserGroups[$filterAttr][$postId];
458 + $aUamOptions = $this->getUserAccessManager()->getAdminOptions();
459 + $aMembership = $this->getUserGroupsForObject($sObjectType, $iObjectId, false);
460 +
461 + if ($aMembership == array()
462 + || $this->checkUserAccess('manage_user_groups')
463 + || $oCurrentUser->ID == $sAuthorId
464 + && $aUamOptions['authors_has_access_to_own'] == 'true'
465 + ) {
466 + return $this->_aObjectAccess[$sObjectType][$iObjectId] = true;
246 467 }
247 468
248 - $this->postUserGroups[$filterAttr][$postId]
249 - = $this->_getUserGroupsForObject($postId, 'post', $filter);
469 + $aCurIp = explode(".", $_SERVER['REMOTE_ADDR']);
470 +
471 + foreach ($aMembership as $sKey => $oUserGroup) {
472 + if ($this->checkUserIp($aCurIp, $oUserGroup->getIpRange())
473 + || $oUserGroup->objectIsMember('user', $oCurrentUser->ID)
474 + ) {
475 + return $this->_aObjectAccess[$sObjectType][$iObjectId] = true;
476 + }
250 477
251 - return $this->postUserGroups[$filterAttr][$postId];
478 + if ($this->getUserAccessManager()->atAdminPanel() && $oUserGroup->getWriteAccess() == 'all'
479 + || !$this->getUserAccessManager()->atAdminPanel() && $oUserGroup->getReadAccess() == 'all'
480 + ) {
481 + unset($aMembership[$sKey]);
482 + }
483 + }
484 +
485 + if ($aMembership == array()) {
486 + return $this->_aObjectAccess[$sObjectType][$iObjectId] = true;
487 + }
488 +
489 + return $this->_aObjectAccess[$sObjectType][$iObjectId] = false;
252 490 }
253 491
492 +
493 + /*
494 + * SQL functions.
495 + */
496 +
254 497 /**
255 - * Returns the user groups of the given category.
498 + * Returns the user groups for the current user as sql string.
256 499 *
257 - * @param integer $categoryId The id of the category from which
258 - * we want the groups.
259 - * @param boolean $filter Filter the groups.
260 - *
261 - * @return array
500 + * @return string
262 501 */
263 - function getUserGroupsForCategory($categoryId, $filter = true)
502 + protected function _getUserGroupsForUserAsSqlString()
264 503 {
265 - if ($filter) {
266 - $filterAttr = 'filtered';
267 - } else {
268 - $filterAttr = 'noneFiltered';
504 + if (isset($this->_aSqlResults['groupsForUser'])) {
505 + return $this->_aSqlResults['groupsForUser'];
269 506 }
507 +
508 + $oCurrentUser = $this->getUserAccessManager()->getCurrentUser();
509 + $aUserUserGroups = $this->getUserGroupsForObject('user', $oCurrentUser->ID, false);
510 + $aUserUserGroupIds = array();
270 511
271 - if (isset($this->categoryUserGroups[$filterAttr][$categoryId])) {
272 - return $this->categoryUserGroups[$filterAttr][$categoryId];
512 + foreach ($aUserUserGroups as $oUserUserGroup) {
513 + $aUserUserGroupIds[] = $oUserUserGroup->getId();
273 514 }
274 -
275 - $this->categoryUserGroups[$filterAttr][$categoryId]
276 - = $this->_getUserGroupsForObject($categoryId, 'category', $filter);
277 515
278 - return $this->categoryUserGroups[$filterAttr][$categoryId];
516 + if ($aUserUserGroupIds !== array()) {
517 + $sUserUserGroups = implode(', ', $aUserUserGroupIds);
518 + } else {
519 + $sUserUserGroups = "''";
520 + }
521 +
522 + $this->_aSqlResults['groupsForUser'] = $sUserUserGroups;
523 + return $this->_aSqlResults['groupsForUser'];
279 524 }
280 525
281 - /**
282 - * Returns the user groups of the given user.
526 + /**
527 + * Returns the categories assigned to the user.
283 528 *
284 - * @param integer $userId The id of the user from which we want the groups.
285 - *
286 529 * @return array
287 530 */
288 - function getUserGroupsForUser($userId)
531 + public function getCategoriesForUser()
289 532 {
290 - if (isset($this->userUserGroups[$userId])) {
291 - return $this->userUserGroups[$userId];
533 + /**
534 + * @var wpdb $wpdb
535 + */
536 + global $wpdb;
537 +
538 + if (isset($this->_aSqlResults['categoriesAssignedToUser'])) {
539 + return $this->_aSqlResults['categoriesAssignedToUser'];
292 540 }
293 541
294 - $this->userUserGroups[$userId]
295 - = $this->_getUserGroupsForObject($userId, 'user', false);
296 -
297 - return $this->userUserGroups[$userId];
542 + $sUserUserGroups = $this->_getUserGroupsForUserAsSqlString();
543 +
544 + $sCategoriesAssignedToUserSql = "
545 + SELECT igc.object_id
546 + FROM ".DB_ACCESSGROUP_TO_OBJECT." AS igc
547 + WHERE igc.object_type = 'category'
548 + AND igc.group_id IN (".$sUserUserGroups.")";
549 +
550 + $this->_aSqlResults['categoriesAssignedToUser'] = $wpdb->get_col($sCategoriesAssignedToUserSql);
551 + return $this->_aSqlResults['categoriesAssignedToUser'];
298 552 }
299 553
300 554 /**
301 - * Checks if the current_user has access to the given post.
555 + * Returns the posts assigned to the user.
302 556 *
303 - * @param integer $objectId The id of the object.
304 - * @param array $membership The group membership for the object.
305 - * @param string $type The object type which should be checked.
557 + * @return array
558 + */
559 + public function getPostsForUser()
560 + {
561 + /**
562 + * @var wpdb $wpdb
563 + */
564 + global $wpdb;
565 +
566 + if (isset($this->_aSqlResults['postsAssignedToUser'])) {
567 + return $this->_aSqlResults['postsAssignedToUser'];
568 + }
569 +
570 + $sUserUserGroup = $this->_getUserGroupsForUserAsSqlString();
571 + $sPostableTypes = "'".implode("','", $this->getPostableTypes())."'";
572 +
573 + $sPostAssignedToUserSql = "
574 + SELECT igp.object_id
575 + FROM ".DB_ACCESSGROUP_TO_OBJECT." AS igp
576 + WHERE igp.object_type IN (".$sPostableTypes.")
577 + AND igp.group_id IN (".$sUserUserGroup.")";
578 +
579 + $this->_aSqlResults['postsAssignedToUser'] = $wpdb->get_col($sPostAssignedToUserSql);
580 + return $this->_aSqlResults['postsAssignedToUser'];
581 + }
582 +
583 + /**
584 + * Returns the excluded posts.
306 585 *
307 - * @return boolean
586 + * @return array
308 587 */
309 - private function _checkAccess($objectId, $membership, $type = null)
588 + public function getExcludedPosts()
310 589 {
311 - global $current_user;
590 + /**
591 + * @var wpdb $wpdb
592 + */
593 + global $wpdb;
312 594
313 - $uamOptions = $this->getUserAccessManager()->getAdminOptions();
595 + if ($this->checkUserAccess('manage_user_groups')) {
596 + $this->_aSqlResults['excludedPosts'] = array();
597 + }
314 598
315 - if ($type == 'post') {
316 - $post = get_post($objectId);
317 - $authorId = $post->post_author;
599 + if (isset($this->_aSqlResults['excludedPosts'])) {
600 + return $this->_aSqlResults['excludedPosts'];
601 + }
602 +
603 + if ($this->getUserAccessManager()->atAdminPanel()) {
604 + $sAccessType = "write";
318 605 } else {
319 - $authorId = -1;
606 + $sAccessType = "read";
320 607 }
321 -
322 - if ($membership == array()
323 - || $this->checkUserAccess()
324 - || $current_user->ID == $authorId
325 - && $uamOptions['authors_has_access_to_own'] == 'true'
326 - ) {
327 - return true;
608 +
609 + $aCategoriesAssignedToUser = $this->getCategoriesForUser();
610 +
611 + if ($aCategoriesAssignedToUser !== array()) {
612 + $sCategoriesAssignedToUser = implode(', ', $aCategoriesAssignedToUser);
613 + } else {
614 + $sCategoriesAssignedToUser = "''";
328 615 }
329 616
330 - $curIp = explode(".", $_SERVER['REMOTE_ADDR']);
617 + $aPostAssignedToUser = $this->getPostsForUser();
331 618
332 - foreach ($membership as $key => $userGroup) {
333 - if ($this->checkUserIp($curIp, $userGroup->getIpRange())
334 - || $userGroup->userIsMember($current_user->ID)
335 - ) {
336 - return true;
337 - }
338 -
339 - if ($this->getUserAccessManager()->atAdminPanel
340 - && $userGroup->getWriteAccess() == 'all'
341 - || !$this->getUserAccessManager()->atAdminPanel
342 - && $userGroup->getReadAccess() == 'all'
343 - ) {
344 - unset($membership[$key]);
345 - }
619 + if ($aPostAssignedToUser !== array()) {
620 + $sPostAssignedToUser = implode(', ', $aPostAssignedToUser);
621 + } else {
622 + $sPostAssignedToUser = "''";
346 623 }
347 624
348 - if ($membership == array()) {
349 - return true;
350 - }
625 + $sPostSql = "SELECT DISTINCT p.ID
626 + FROM $wpdb->posts AS p
627 + INNER JOIN $wpdb->term_relationships AS tr
628 + ON p.ID = tr.object_id
629 + INNER JOIN $wpdb->term_taxonomy tt
630 + ON tr.term_taxonomy_id = tt.term_taxonomy_id
631 + WHERE tt.taxonomy = 'category'
632 + AND tt.term_id IN (
633 + SELECT gc.object_id
634 + FROM ".DB_ACCESSGROUP." iag
635 + INNER JOIN ".DB_ACCESSGROUP_TO_OBJECT." AS gc
636 + ON iag.id = gc.group_id
637 + WHERE gc.object_type = 'category'
638 + AND iag.".$sAccessType."_access != 'all'
639 + AND gc.object_id NOT IN (".$sCategoriesAssignedToUser.")
640 + ) AND p.ID NOT IN (".$sPostAssignedToUser.")
641 + UNION
642 + SELECT DISTINCT gp.object_id
643 + FROM ".DB_ACCESSGROUP." AS ag
644 + INNER JOIN ".DB_ACCESSGROUP_TO_OBJECT." AS gp
645 + ON ag.id = gp.group_id
646 + INNER JOIN $wpdb->term_relationships AS tr
647 + ON gp.object_id = tr.object_id
648 + INNER JOIN $wpdb->term_taxonomy tt
649 + ON tr.term_taxonomy_id = tt.term_taxonomy_id
650 + WHERE gp.object_type = 'post'
651 + AND ag.".$sAccessType."_access != 'all'
652 + AND gp.object_id NOT IN (".$sPostAssignedToUser.")
653 + AND tt.term_id NOT IN (".$sCategoriesAssignedToUser.")";
351 654
352 - return false;
655 + $this->_aSqlResults['excludedPosts'] = $wpdb->get_col($sPostSql);
656 + return $this->_aSqlResults['excludedPosts'];
353 657 }
354 658
355 - /**
356 - * Checks if the current_user has access to the given post.
659 +
660 + /*
661 + * Other functions
662 + */
663 +
664 + /**
665 + * Checks if the given ip matches with the range.
357 666 *
358 - * @param integer $postId The id of the post which we want to check.
667 + * @param array $aCurIp The ip of the current user.
668 + * @param array $aIpRanges The ip ranges.
359 669 *
360 670 * @return boolean
361 671 */
362 - function checkAccess($postId)
363 - {
364 - if (isset($this->postAccess[$postId])) {
365 - return $this->postAccess[$postId];
366 - }
672 + public function checkUserIp($aCurIp, $aIpRanges)
673 + {
674 + if (isset($aIpRanges)) {
675 + foreach ($aIpRanges as $aIpRange) {
676 + $aIpRange = explode("-", $aIpRange);
677 + $aRangeBegin = explode(".", $aIpRange[0]);
678 +
679 + if (isset($aIpRange[1])) {
680 + $aRangeEnd = explode(".", $aIpRange[1]);
681 + } else {
682 + $aRangeEnd = explode(".", $aIpRange[0]);
683 + }
367 684
368 - $postMembership = $this->getUserGroupsForPost($postId, false);
685 + $iCurIp = ($aCurIp[0] << 24) + ($aCurIp[1] << 16) + ($aCurIp[2] << 8) + $aCurIp[3];
686 + $iRangeBegin = ($aRangeBegin[0] << 24) + ($aRangeBegin[1] << 16) + ($aRangeBegin[2] << 8) + $aRangeBegin[3];
687 + $iRangeEnd = ($aRangeEnd[0] << 24) + ($aRangeEnd[1] << 16) + ($aRangeEnd[2] << 8) + $aRangeEnd[3];
688 +
689 + if ($iRangeBegin <= $iCurIp && $iCurIp <= $iRangeEnd) {
690 + return true;
691 + }
692 + }
693 + }
369 694
370 - $this->postAccess[$postId]
371 - = $this->_checkAccess($postId, $postMembership, 'post');
372 -
373 - return $this->postAccess[$postId];
695 + return false;
374 696 }
375 697
376 698 /**
377 - * Checks if the current_user has access to the given category.
699 + * Return the role of the user.
378 700 *
379 - * @param integer $categoryId The id of the category which we want to check.
701 + * @param integer $iUserId The user _iId.
380 702 *
381 - * @return boolean
703 + * @return array
382 704 */
383 - function checkCategoryAccess($categoryId)
384 - {
385 - if (isset($this->categroyAccess[$categoryId])) {
386 - return $this->categroyAccess[$categoryId];
387 - }
388 -
389 - $categoryMembership = $this->getUserGroupsForCategory($categoryId, false);
705 + protected function _getUserRole($iUserId)
706 + {
707 + /**
708 + * @var wpdb $wpdb
709 + */
710 + global $wpdb;
390 711
391 - $this->categroyAccess[$categoryId]
392 - = $this->_checkAccess($categoryId, $categoryMembership);
393 -
394 - return $this->categroyAccess[$categoryId];
712 + $oUserData = get_userdata($iUserId);
713 +
714 + if (!empty($oUserData->user_level) && !isset($oUserData->user_level)) {
715 + $oUserData->user_level = null;
716 + }
717 +
718 + if (isset($oUserData->{$wpdb->prefix . "capabilities"})) {
719 + $aCapabilities = $oUserData->{$wpdb->prefix . "capabilities"};
720 + } else {
721 + $aCapabilities = array();
722 + }
723 +
724 + $aRoles = (is_array($aCapabilities) && count($aCapabilities) > 0) ? array_keys($aCapabilities) : array('norole');
725 + return $aRoles;
395 726 }
396 727
397 728 /**
398 - * Checks if the given ip matches with the range.
729 + * Checks if the user is an admin user
399 730 *
400 - * @param string $curIp The ip of the current user.
401 - * @param array $ipRanges The ip ranges.
731 + * @param integer $iUserId The user _iId.
402 732 *
403 733 * @return boolean
404 734 */
405 - function checkUserIp($curIp, $ipRanges)
735 + public function userIsAdmin($iUserId)
406 736 {
407 - if (isset($ipRanges)) {
408 - foreach ($ipRanges as $ipRange) {
409 - $ipRange = explode("-", $ipRange);
410 - $rangeBegin = explode(".", $ipRange[0]);
411 -
412 - if (isset($ipRange[1])) {
413 - $rangeEnd = explode(".", $ipRange[1]);
414 - } else {
415 - $rangeEnd = explode(".", $ipRange[0]);
416 - }
417 -
418 - if ($rangeBegin[0] <= $curIp[0]
419 - && $curIp[0] <= $rangeEnd[0]
420 - && $rangeBegin[1] <= $curIp[1]
421 - && $curIp[1] <= $rangeEnd[1]
422 - && $rangeBegin[2] <= $curIp[2]
423 - && $curIp[2] <= $rangeEnd[2]
424 - && $rangeBegin[3] <= $curIp[3]
425 - && $curIp[3] <= $rangeEnd[3]
426 - ) {
427 - return true;
428 - }
429 - }
737 + $aRoles = $this->_getUserRole($iUserId);
738 + $aRolesMap = array_keys($aRoles);
739 +
740 + if (isset($aRolesMap['administrator']) || is_super_admin($iUserId)) {
741 + return true;
430 742 }
431 743
432 744 return false;
433 745 }
@@ -433,36 +745,35 @@
433 745 }
434 746
435 747 /**
436 748 * Checks the user access by user level.
437 - *
749 + *
750 + * @param bool|string $sAllowedCapability If true check also for the capability.
751 + *
438 752 * @return boolean
439 753 */
440 - function checkUserAccess()
754 + public function checkUserAccess($sAllowedCapability = false)
441 755 {
442 - global $current_user, $wpdb;
756 + $oCurrentUser = $this->getUserAccessManager()->getCurrentUser();
757 + $aUamOptions = $this->getUserAccessManager()->getAdminOptions();
758 +
759 + $aRoles = $this->_getUserRole($oCurrentUser->ID);
760 + $aRolesMap = array_keys($aRoles);
761 + $aOrderedRoles = $this->getRolesOrdered();
762 + $iRightsLevel = 0;
443 763
444 - $uamOptions = $this->getUserAccessManager()->getAdminOptions();
445 - $curUserdata = get_userdata($current_user->ID);
446 -
447 - if (!isset($curUserdata->user_level)) {
448 - $curUserdata->user_level = null;
764 + foreach ($aRoles as $sRole) {
765 + if (isset($aOrderedRoles[$sRole])
766 + && $aOrderedRoles[$sRole] > $iRightsLevel
767 + ) {
768 + $iRightsLevel = $aOrderedRoles[$sRole];
769 + }
449 770 }
450 -
451 - if (isset($curUserdata->{$wpdb->prefix . "capabilities"})) {
452 - $capabilities = $curUserdata->{$wpdb->prefix . "capabilities"};
453 - } else {
454 - $capabilities = null;
455 - }
456 -
457 - $role = is_array($capabilities) ?
458 - array_keys($capabilities) : 'norole';
459 - $role = trim($role[0]);
460 -
461 - $orderedRoles = $this->getRolesOrdered();
462 -
463 - if ($orderedRoles[$role] >= $orderedRoles[$uamOptions['full_access_role']]
464 - || $role == 'administrator'
771 +
772 + if ($iRightsLevel >= $aOrderedRoles[$aUamOptions['full_access_role']]
773 + || isset($aRolesMap['administrator'])
774 + || is_super_admin($oCurrentUser->ID)
775 + || ($sAllowedCapability && $oCurrentUser->has_cap($sAllowedCapability))
465 776 ) {
466 777 return true;
467 778 }
468 779
@@ -469,22 +780,68 @@
469 780 return false;
470 781 }
471 782
472 783 /**
473 - * Returns the roles as assoziative array.
784 + * Returns the roles as associative array.
474 785 *
475 786 * @return array
476 787 */
477 - function getRolesOrdered()
788 + public function getRolesOrdered()
478 789 {
479 - $orderedRoles = array(
790 + $aOrderedRoles = array(
480 791 'norole' => 0,
481 792 'subscriber' => 1,
482 793 'contributor' => 2,
483 794 'author' => 3,
484 - 'editor' => 4,
795 + 'editor' => 4,
485 796 'administrator' => 5
486 797 );
487 798
488 - return $orderedRoles;
799 + return $aOrderedRoles;
800 + }
801 +
802 + /**
803 + * Registers object that should be handelt by the user access manager.
804 + *
805 + * @param array $oObject The object which you want to register.
806 + *
807 + * @return boolean
808 + */
809 + public function registerPlObject($oObject)
810 + {
811 + if (!isset($oObject['name']) || !isset($oObject['reference'])
812 + || !isset($oObject['getFull']) || !isset($oObject['getFullObjects'])
813 + ) {
814 + return false;
815 + }
816 +
817 + $this->_aPlObjects[$oObject['name']] = $oObject;
818 +
819 + return true;
820 + }
821 +
822 + /**
823 + * Returns a registered pluggable object.
824 + *
825 + * @param string $sObjectName The name of the object which should be returned.
826 + *
827 + * @return array
828 + */
829 + public function getPlObject($sObjectName)
830 + {
831 + if (isset($this->_aPlObjects[$sObjectName])) {
832 + return $this->_aPlObjects[$sObjectName];
833 + }
834 +
835 + return array();
836 + }
837 +
838 + /**
839 + * Returns all registered pluggable objects.
840 + *
841 + * @return array
842 + */
843 + public function getPlObjects()
844 + {
845 + return $this->_aPlObjects;
489 846 }
490 847 }