Version Description
- Fix: Under certain conditions with caching involved, capabilities were not correctly retrieved. Thanks to Jason Kadlec who reported the issue.
- Improvement: Related to the above fix, improved the way how *_deep properties are retrieved on cache misses, resulting in slightly better performance.
- Fix: Added a missing text domain.
- Improvement: Added help icon when user has no access restriction capabilities.
- Fix: Redirecting after group action in users screen to end up with a clean admin URL.
Download this release
Release Info
Developer | itthinx |
Plugin | Groups |
Version | 1.3.10 |
Comparing to | |
See all releases |
Code changes from version 1.3.9 to 1.3.10
- groups.php +2 -2
- images/help.png +0 -0
- lib/access/class-groups-access-meta-boxes.php +10 -1
- lib/admin/class-groups-admin-users.php +7 -1
- lib/core/class-groups-user.php +72 -68
- readme.txt +11 -1
groups.php
CHANGED
@@ -21,13 +21,13 @@
|
|
21 |
* Plugin Name: Groups
|
22 |
* Plugin URI: http://www.itthinx.com/plugins/groups
|
23 |
* Description: Groups provides group-based user membership management, group-based capabilities and content access control.
|
24 |
-
* Version: 1.3.
|
25 |
* Author: itthinx
|
26 |
* Author URI: http://www.itthinx.com
|
27 |
* Donate-Link: http://www.itthinx.com
|
28 |
* License: GPLv3
|
29 |
*/
|
30 |
-
define( 'GROUPS_CORE_VERSION', '1.3.
|
31 |
define( 'GROUPS_FILE', __FILE__ );
|
32 |
if ( !defined( 'GROUPS_CORE_DIR' ) ) {
|
33 |
define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
|
21 |
* Plugin Name: Groups
|
22 |
* Plugin URI: http://www.itthinx.com/plugins/groups
|
23 |
* Description: Groups provides group-based user membership management, group-based capabilities and content access control.
|
24 |
+
* Version: 1.3.10
|
25 |
* Author: itthinx
|
26 |
* Author URI: http://www.itthinx.com
|
27 |
* Donate-Link: http://www.itthinx.com
|
28 |
* License: GPLv3
|
29 |
*/
|
30 |
+
define( 'GROUPS_CORE_VERSION', '1.3.10' );
|
31 |
define( 'GROUPS_FILE', __FILE__ );
|
32 |
if ( !defined( 'GROUPS_CORE_DIR' ) ) {
|
33 |
define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
|
images/help.png
ADDED
Binary file
|
lib/access/class-groups-access-meta-boxes.php
CHANGED
@@ -131,7 +131,16 @@ class Groups_Access_Meta_Boxes {
|
|
131 |
$output .= wp_nonce_field( self::SET_CAPABILITY, self::NONCE, true, false );
|
132 |
} else {
|
133 |
$output .= '<p class="description">';
|
134 |
-
$output .= sprintf( __( 'You cannot set any access restrictions.', GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
$output .= '</p>';
|
136 |
}
|
137 |
|
131 |
$output .= wp_nonce_field( self::SET_CAPABILITY, self::NONCE, true, false );
|
132 |
} else {
|
133 |
$output .= '<p class="description">';
|
134 |
+
$output .= sprintf( __( 'You cannot set any access restrictions.', GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
135 |
+
$style = 'cursor:help;vertical-align:middle;';
|
136 |
+
if ( current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
|
137 |
+
$style = 'cursor:pointer;vertical-align:middle;';
|
138 |
+
$output .= sprintf( '<a href="%s">', esc_url( admin_url( 'admin.php?page=groups-admin-options' ) ) );
|
139 |
+
}
|
140 |
+
$output .= sprintf( '<img style="%s" alt="?" title="%s" src="%s" />', $style, esc_attr( __( 'You must be in a group that has at least one capability enabled to enforce read access.', GROUPS_PLUGIN_DOMAIN ) ), esc_attr( GROUPS_PLUGIN_URL . 'images/help.png' ) );
|
141 |
+
if ( current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
|
142 |
+
$output .= '</a>';
|
143 |
+
}
|
144 |
$output .= '</p>';
|
145 |
}
|
146 |
|
lib/admin/class-groups-admin-users.php
CHANGED
@@ -206,6 +206,12 @@ class Groups_Admin_Users {
|
|
206 |
break;
|
207 |
}
|
208 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
210 |
}
|
211 |
}
|
@@ -245,7 +251,7 @@ class Groups_Admin_Users {
|
|
245 |
}
|
246 |
$output .= '</ul>';
|
247 |
} else {
|
248 |
-
$output .= __( '--' );
|
249 |
}
|
250 |
break;
|
251 |
}
|
206 |
break;
|
207 |
}
|
208 |
}
|
209 |
+
$referer = wp_get_referer();
|
210 |
+
if ( $referer ) {
|
211 |
+
$redirect_to = remove_query_arg( array( 'action', 'action2', 'add-to-group', 'bulk-user-group-nonce', 'group_id', 'new_role', 'remove-from-group', 'users' ), $referer );
|
212 |
+
wp_redirect( $redirect_to );
|
213 |
+
exit;
|
214 |
+
}
|
215 |
}
|
216 |
}
|
217 |
}
|
251 |
}
|
252 |
$output .= '</ul>';
|
253 |
} else {
|
254 |
+
$output .= __( '--', GROUPS_PLUGIN_DOMAIN );
|
255 |
}
|
256 |
break;
|
257 |
}
|
lib/core/class-groups-user.php
CHANGED
@@ -133,8 +133,7 @@ class Groups_User implements I_Capable {
|
|
133 |
if ( $this->user !== null ) {
|
134 |
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
135 |
if ( $capability_ids === false ) {
|
136 |
-
$this->init_cache();
|
137 |
-
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
138 |
}
|
139 |
$result = $capability_ids;
|
140 |
}
|
@@ -158,8 +157,7 @@ class Groups_User implements I_Capable {
|
|
158 |
if ( $this->user !== null ) {
|
159 |
$groups_ids = wp_cache_get( self::GROUP_IDS . $this->user->ID, self::CACHE_GROUP );
|
160 |
if ( $group_ids === false ) {
|
161 |
-
$this->init_cache();
|
162 |
-
$group_ids = wp_cache_get( self::GROUP_IDS . $this->user->ID, self::CACHE_GROUP );
|
163 |
}
|
164 |
$result = $group_ids;
|
165 |
}
|
@@ -183,8 +181,7 @@ class Groups_User implements I_Capable {
|
|
183 |
if ( $this->user !== null ) {
|
184 |
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
185 |
if ( $capabilities === false ) {
|
186 |
-
$this->init_cache();
|
187 |
-
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
188 |
}
|
189 |
$result = $capabilities;
|
190 |
}
|
@@ -233,15 +230,13 @@ class Groups_User implements I_Capable {
|
|
233 |
$capability_id = Groups_Utility::id( $capability );
|
234 |
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
235 |
if ( $capability_ids === false ) {
|
236 |
-
$this->init_cache();
|
237 |
-
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
238 |
}
|
239 |
$result = in_array( $capability_id, $capability_ids );
|
240 |
} else if ( is_string( $capability ) ) {
|
241 |
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
242 |
if ( $capabilities === false ) {
|
243 |
-
$this->init_cache();
|
244 |
-
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
245 |
}
|
246 |
$result = in_array( $capability, $capabilities );
|
247 |
}
|
@@ -255,84 +250,93 @@ class Groups_User implements I_Capable {
|
|
255 |
* Builds the cache entries for user groups and capabilities if needed.
|
256 |
* The cache entries are built only if they do not already exist.
|
257 |
* If you want them rebuilt, delete them before calling.
|
|
|
|
|
|
|
|
|
258 |
*/
|
259 |
-
private function init_cache() {
|
260 |
|
261 |
global $wpdb;
|
262 |
|
|
|
|
|
|
|
|
|
263 |
if ( ( $this->user !== null ) && ( wp_cache_get( self::GROUP_IDS . $this->user->ID, self::CACHE_GROUP ) === false ) ) {
|
264 |
$group_table = _groups_get_tablename( "group" );
|
265 |
$capability_table = _groups_get_tablename( "capability" );
|
266 |
$group_capability_table = _groups_get_tablename( "group_capability" );
|
267 |
$user_group_table = _groups_get_tablename( "user_group" );
|
268 |
$user_capability_table = _groups_get_tablename( "user_capability" );
|
|
|
269 |
$limit = $wpdb->get_var( "SELECT COUNT(*) FROM $group_table" );
|
270 |
-
if ( $limit
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
}
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
$parent_group_ids = $wpdb->get_results(
|
306 |
-
"SELECT parent_id FROM $group_table WHERE parent_id IS NOT NULL AND group_id IN ($id_list)"
|
307 |
-
);
|
308 |
-
if ( $parent_group_ids ) {
|
309 |
-
foreach( $parent_group_ids as $parent_group_id ) {
|
310 |
-
$parent_group_id = Groups_Utility::id( $parent_group_id->parent_id );
|
311 |
-
if ( !in_array( $parent_group_id, $group_ids ) ) {
|
312 |
-
$group_ids[] = $parent_group_id;
|
313 |
-
}
|
314 |
-
}
|
315 |
-
}
|
316 |
-
}
|
317 |
$id_list = implode( ",", $group_ids );
|
318 |
-
$
|
319 |
-
"SELECT
|
320 |
);
|
321 |
-
if (
|
322 |
-
foreach
|
323 |
-
|
324 |
-
|
325 |
-
$
|
326 |
}
|
327 |
}
|
328 |
}
|
329 |
-
|
330 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
-
wp_cache_set( self::CAPABILITIES . $this->user->ID, $capabilities, self::CACHE_GROUP );
|
333 |
-
wp_cache_set( self::CAPABILITY_IDS . $this->user->ID, $capability_ids, self::CACHE_GROUP );
|
334 |
-
wp_cache_set( self::GROUP_IDS . $this->user->ID, $group_ids, self::CACHE_GROUP );
|
335 |
}
|
|
|
|
|
|
|
336 |
}
|
337 |
}
|
338 |
|
133 |
if ( $this->user !== null ) {
|
134 |
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
135 |
if ( $capability_ids === false ) {
|
136 |
+
$this->init_cache( $capability_ids );
|
|
|
137 |
}
|
138 |
$result = $capability_ids;
|
139 |
}
|
157 |
if ( $this->user !== null ) {
|
158 |
$groups_ids = wp_cache_get( self::GROUP_IDS . $this->user->ID, self::CACHE_GROUP );
|
159 |
if ( $group_ids === false ) {
|
160 |
+
$this->init_cache( $capability_ids, $capabilities, $group_ids );
|
|
|
161 |
}
|
162 |
$result = $group_ids;
|
163 |
}
|
181 |
if ( $this->user !== null ) {
|
182 |
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
183 |
if ( $capabilities === false ) {
|
184 |
+
$this->init_cache( $capability_ids, $capabilities );
|
|
|
185 |
}
|
186 |
$result = $capabilities;
|
187 |
}
|
230 |
$capability_id = Groups_Utility::id( $capability );
|
231 |
$capability_ids = wp_cache_get( self::CAPABILITY_IDS . $this->user->ID, self::CACHE_GROUP );
|
232 |
if ( $capability_ids === false ) {
|
233 |
+
$this->init_cache( $capability_ids );
|
|
|
234 |
}
|
235 |
$result = in_array( $capability_id, $capability_ids );
|
236 |
} else if ( is_string( $capability ) ) {
|
237 |
$capabilities = wp_cache_get( self::CAPABILITIES . $this->user->ID, self::CACHE_GROUP );
|
238 |
if ( $capabilities === false ) {
|
239 |
+
$this->init_cache( $capability_ids, $capabilities );
|
|
|
240 |
}
|
241 |
$result = in_array( $capability, $capabilities );
|
242 |
}
|
250 |
* Builds the cache entries for user groups and capabilities if needed.
|
251 |
* The cache entries are built only if they do not already exist.
|
252 |
* If you want them rebuilt, delete them before calling.
|
253 |
+
*
|
254 |
+
* @param array $capability_ids carries the capability ids for the user on return, but only if cache entries have been built; will provide an empty array by default
|
255 |
+
* @param array $capabilities carries the capabilities for the user on return, but only if cache entries have been built; will provide an empty array by default
|
256 |
+
* @param array $group_ids carries the group ids for the user on return, but only if cache entries have been built; will provide an empty array by default
|
257 |
*/
|
258 |
+
private function init_cache( &$capability_ids = null, &$capabilities = null, &$group_ids = null ) {
|
259 |
|
260 |
global $wpdb;
|
261 |
|
262 |
+
$capabilities = array();
|
263 |
+
$capability_ids = array();
|
264 |
+
$group_ids = array();
|
265 |
+
|
266 |
if ( ( $this->user !== null ) && ( wp_cache_get( self::GROUP_IDS . $this->user->ID, self::CACHE_GROUP ) === false ) ) {
|
267 |
$group_table = _groups_get_tablename( "group" );
|
268 |
$capability_table = _groups_get_tablename( "capability" );
|
269 |
$group_capability_table = _groups_get_tablename( "group_capability" );
|
270 |
$user_group_table = _groups_get_tablename( "user_group" );
|
271 |
$user_capability_table = _groups_get_tablename( "user_capability" );
|
272 |
+
|
273 |
$limit = $wpdb->get_var( "SELECT COUNT(*) FROM $group_table" );
|
274 |
+
if ( $limit === null ) {
|
275 |
+
$limit = 1;
|
276 |
+
}
|
277 |
+
|
278 |
+
// note that limits by blog_id for multisite are
|
279 |
+
// enforced when a user is added to a blog
|
280 |
+
$user_groups = $wpdb->get_results( $wpdb->prepare(
|
281 |
+
"SELECT group_id FROM $user_group_table WHERE user_id = %d",
|
282 |
+
Groups_Utility::id( $this->user->ID )
|
283 |
+
) );
|
284 |
+
// get all capabilities directly assigned (those granted through
|
285 |
+
// groups are added below
|
286 |
+
$user_capabilities = $wpdb->get_results( $wpdb->prepare(
|
287 |
+
"SELECT c.capability_id, c.capability FROM $user_capability_table uc LEFT JOIN $capability_table c ON c.capability_id = uc.capability_id WHERE user_id = %d",
|
288 |
+
Groups_Utility::id( $this->user->ID )
|
289 |
+
) );
|
290 |
+
if ( $user_capabilities ) {
|
291 |
+
foreach( $user_capabilities as $user_capability ) {
|
292 |
+
$capabilities[] = $user_capability->capability;
|
293 |
+
$capability_ids[] = $user_capability->capability_id;
|
294 |
}
|
295 |
+
}
|
296 |
+
// Get all groups the user belongs to directly or through
|
297 |
+
// inheritance along with their capabilities.
|
298 |
+
|
299 |
+
if ( $user_groups ) {
|
300 |
+
foreach( $user_groups as $user_group ) {
|
301 |
+
$group_ids[] = Groups_Utility::id( $user_group->group_id );
|
302 |
+
}
|
303 |
+
if ( count( $group_ids ) > 0 ) {
|
304 |
+
$iterations = 0;
|
305 |
+
$old_group_ids_count = 0;
|
306 |
+
while( ( $iterations < $limit ) && ( count( $group_ids ) !== $old_group_ids_count ) ) {
|
307 |
+
$iterations++;
|
308 |
+
$old_group_ids_count = count( $group_ids );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
$id_list = implode( ",", $group_ids );
|
310 |
+
$parent_group_ids = $wpdb->get_results(
|
311 |
+
"SELECT parent_id FROM $group_table WHERE parent_id IS NOT NULL AND group_id IN ($id_list)"
|
312 |
);
|
313 |
+
if ( $parent_group_ids ) {
|
314 |
+
foreach( $parent_group_ids as $parent_group_id ) {
|
315 |
+
$parent_group_id = Groups_Utility::id( $parent_group_id->parent_id );
|
316 |
+
if ( !in_array( $parent_group_id, $group_ids ) ) {
|
317 |
+
$group_ids[] = $parent_group_id;
|
318 |
}
|
319 |
}
|
320 |
}
|
|
|
321 |
}
|
322 |
+
$id_list = implode( ",", $group_ids );
|
323 |
+
$rows = $wpdb->get_results(
|
324 |
+
"SELECT $group_capability_table.capability_id, $capability_table.capability FROM $group_capability_table LEFT JOIN $capability_table ON $group_capability_table.capability_id = $capability_table.capability_id WHERE group_id IN ($id_list)"
|
325 |
+
);
|
326 |
+
if ( count( $rows ) > 0 ) {
|
327 |
+
foreach ( $rows as $row ) {
|
328 |
+
if ( !in_array( $row->capability_id, $capability_ids ) ) {
|
329 |
+
$capabilities[] = $row->capability;
|
330 |
+
$capability_ids[] = $row->capability_id;
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
}
|
|
|
|
|
|
|
336 |
}
|
337 |
+
wp_cache_set( self::CAPABILITIES . $this->user->ID, $capabilities, self::CACHE_GROUP );
|
338 |
+
wp_cache_set( self::CAPABILITY_IDS . $this->user->ID, $capability_ids, self::CACHE_GROUP );
|
339 |
+
wp_cache_set( self::GROUP_IDS . $this->user->ID, $group_ids, self::CACHE_GROUP );
|
340 |
}
|
341 |
}
|
342 |
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.itthinx.com/plugins/groups
|
|
4 |
Tags: access, access control, capability, capabilities, content, download, downloads, file, file access, files, group, groups, member, members, membership, memberships, paypal, permission, permissions, subscription, subscriptions, woocommerce
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 3.5.1
|
7 |
-
Stable tag: 1.3.
|
8 |
License: GPLv3
|
9 |
|
10 |
Groups provides group-based user membership management, group-based capabilities and content access control.
|
@@ -327,6 +327,13 @@ See also [Groups](http://www.itthinx.com/plugins/groups/)
|
|
327 |
|
328 |
== Changelog ==
|
329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
= 1.3.9 =
|
331 |
* Fix: added filter hooked on posts_where motivated by pagination issues - the posts must be filtered before the totals are calculated in WP_Query::get_posts().
|
332 |
* Improvement: modified the signature of the the_posts filter method in Groups_Post_Access to receive the $query by reference
|
@@ -448,6 +455,9 @@ Some installations wouldn't work correctly, showing no capabilities and making i
|
|
448 |
|
449 |
== Upgrade Notice ==
|
450 |
|
|
|
|
|
|
|
451 |
= 1.3.9 =
|
452 |
* Brings a substantial performance improvement and solves pagination issues due to post filters among other fixes.
|
453 |
|
4 |
Tags: access, access control, capability, capabilities, content, download, downloads, file, file access, files, group, groups, member, members, membership, memberships, paypal, permission, permissions, subscription, subscriptions, woocommerce
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 3.5.1
|
7 |
+
Stable tag: 1.3.10
|
8 |
License: GPLv3
|
9 |
|
10 |
Groups provides group-based user membership management, group-based capabilities and content access control.
|
327 |
|
328 |
== Changelog ==
|
329 |
|
330 |
+
= 1.3.10 =
|
331 |
+
* Fix: Under certain conditions with caching involved, capabilities were not correctly retrieved. Thanks to Jason Kadlec who [reported the issue](http://wordpress.org/support/topic/nasty-error-with-latest-version).
|
332 |
+
* Improvement: Related to the above fix, improved the way how *_deep properties are retrieved on cache misses, resulting in slightly better performance.
|
333 |
+
* Fix: Added a missing text domain.
|
334 |
+
* Improvement: Added help icon when user has no access restriction capabilities.
|
335 |
+
* Fix: Redirecting after group action in users screen to end up with a clean admin URL.
|
336 |
+
|
337 |
= 1.3.9 =
|
338 |
* Fix: added filter hooked on posts_where motivated by pagination issues - the posts must be filtered before the totals are calculated in WP_Query::get_posts().
|
339 |
* Improvement: modified the signature of the the_posts filter method in Groups_Post_Access to receive the $query by reference
|
455 |
|
456 |
== Upgrade Notice ==
|
457 |
|
458 |
+
= 1.3.10 =
|
459 |
+
* Improves performance slightly more and fixes potential issues with caching.
|
460 |
+
|
461 |
= 1.3.9 =
|
462 |
* Brings a substantial performance improvement and solves pagination issues due to post filters among other fixes.
|
463 |
|