Groups - Version 1.3.10

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 Icon 128x128 Groups
Version 1.3.10
Comparing to
See all releases

Code changes from version 1.3.9 to 1.3.10

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.9
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.9' );
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 !== null ) {
271
- // note that limits by blog_id for multisite are
272
- // enforced when a user is added to a blog
273
- $user_groups = $wpdb->get_results( $wpdb->prepare(
274
- "SELECT group_id FROM $user_group_table WHERE user_id = %d",
275
- Groups_Utility::id( $this->user->ID )
276
- ) );
277
- // get all capabilities directly assigned (those granted through
278
- // groups are added below
279
- $capabilities = array();
280
- $capability_ids = array();
281
- $user_capabilities = $wpdb->get_results( $wpdb->prepare(
282
- "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",
283
- Groups_Utility::id( $this->user->ID )
284
- ) );
285
- if ( $user_capabilities ) {
286
- foreach( $user_capabilities as $user_capability ) {
287
- $capabilities[] = $user_capability->capability;
288
- $capability_ids[] = $user_capability->capability_id;
289
- }
290
  }
291
- // Get all groups the user belongs to directly or through
292
- // inheritance along with their capabilities.
293
- $group_ids = array();
294
- if ( $user_groups ) {
295
- foreach( $user_groups as $user_group ) {
296
- $group_ids[] = Groups_Utility::id( $user_group->group_id );
297
- }
298
- if ( count( $group_ids ) > 0 ) {
299
- $iterations = 0;
300
- $old_group_ids_count = 0;
301
- while( ( $iterations < $limit ) && ( count( $group_ids ) !== $old_group_ids_count ) ) {
302
- $iterations++;
303
- $old_group_ids_count = count( $group_ids );
304
- $id_list = implode( ",", $group_ids );
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
- $rows = $wpdb->get_results(
319
- "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)"
320
  );
321
- if ( count( $rows ) > 0 ) {
322
- foreach ( $rows as $row ) {
323
- if ( !in_array( $row->capability_id, $capability_ids ) ) {
324
- $capabilities[] = $row->capability;
325
- $capability_ids[] = $row->capability_id;
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.9
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