Groups - Version 1.10.1

Version Description

  • Fixed the French translation which introduced incorrect markup breaking the help button.
  • Added the groups_admin_groups_add_form_after_fields filter.
  • Added the groups_admin_groups_add_submit_success action.
  • Added the groups_admin_groups_edit_form_after_fields filter.
  • Added the groups_admin_groups_edit_submit_success action.
  • Fixed some code formatting (tabs).
Download this release

Release Info

Developer itthinx
Plugin Icon 128x128 Groups
Version 1.10.1
Comparing to
See all releases

Code changes from version 1.10.0 to 1.10.1

groups.php CHANGED
@@ -21,7 +21,7 @@
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.10.0
25
  * Author: itthinx
26
  * Author URI: http://www.itthinx.com
27
  * Donate-Link: http://www.itthinx.com
@@ -30,7 +30,7 @@
30
  if ( !defined( 'ABSPATH' ) ) {
31
  exit;
32
  }
33
- define( 'GROUPS_CORE_VERSION', '1.10.0' );
34
  define( 'GROUPS_FILE', __FILE__ );
35
  if ( !defined( 'GROUPS_CORE_DIR' ) ) {
36
  define( 'GROUPS_CORE_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
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.10.1
25
  * Author: itthinx
26
  * Author URI: http://www.itthinx.com
27
  * Donate-Link: http://www.itthinx.com
30
  if ( !defined( 'ABSPATH' ) ) {
31
  exit;
32
  }
33
+ define( 'GROUPS_CORE_VERSION', '1.10.1' );
34
  define( 'GROUPS_FILE', __FILE__ );
35
  if ( !defined( 'GROUPS_CORE_DIR' ) ) {
36
  define( 'GROUPS_CORE_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
languages/groups-fr_FR.mo CHANGED
Binary file
languages/groups-fr_FR.po CHANGED
@@ -3,7 +3,7 @@ msgstr ""
3
  "Project-Id-Version: Groups\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2015-06-30 20:09+0200\n"
6
- "PO-Revision-Date: 2015-06-30 20:09+0200\n"
7
  "Last-Translator: Stéphane PASSEDOUET <s.passedouet@pheeric.com>\n"
8
  "Language-Team: itthinx.com\n"
9
  "Language: fr_FR\n"
@@ -11,7 +11,7 @@ msgstr ""
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n>1;\n"
14
- "X-Generator: Poedit 1.8.2\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
@@ -124,8 +124,7 @@ msgstr "Restrictions d'Accès"
124
  #: lib/admin/groups-admin-groups-remove.php:189
125
  #: lib/admin/groups-admin-groups.php:49 lib/admin/groups-admin-groups.php:148
126
  #: lib/admin/groups-admin-groups.php:179 lib/admin/groups-admin-groups.php:185
127
- #: lib/admin/groups-admin-options.php:39
128
- #: lib/admin/groups-admin-options.php:329
129
  #: lib/admin/groups-admin-tree-view.php:37 lib/test/groups-tests.php:385
130
  #: lib/test/groups-tests.php:391
131
  msgid "Access denied."
@@ -233,9 +232,9 @@ msgid ""
233
  "Become a member of the <em>Premium</em> group - this is required so you can "
234
  "choose the <em>premium</em> capability to restrict access to a post."
235
  msgstr ""
236
- "Devenez un membre du groupe <em>Premium</ em> - cela est nécessaire afin que "
237
- "vous puissiez choisir la capacité <em> Premium </ em> pour restreindre "
238
- "l'accès à une publication."
239
 
240
  # @ groups
241
  #: lib/admin/groups-admin-capabilities.php:346
@@ -291,8 +290,8 @@ msgstr "Annuler"
291
  #: lib/admin/groups-admin-capabilities.php:193
292
  #: lib/admin/groups-admin-groups-add.php:99
293
  #: lib/admin/groups-admin-groups-edit.php:119
294
- #: lib/admin/groups-admin-groups.php:297
295
- #: lib/admin/groups-admin-options.php:251 lib/core/class-groups-help.php:69
296
  msgid "Capabilities"
297
  msgstr "Capacités"
298
 
@@ -508,7 +507,7 @@ msgid ""
508
  "capability to the <em>Premium</em> group."
509
  msgstr ""
510
  "Allez à <strong>Groups > Groups</strong> et attribuez la capacité "
511
- "<em>premium</em> au groupe <em>premium</em>."
512
 
513
  # @ groups
514
  #: lib/access/class-groups-access-meta-boxes.php:158
@@ -640,7 +639,7 @@ msgid ""
640
  "the <em>Premium</em> group."
641
  msgstr ""
642
  "Supposons que vous voulez limiter la visibilité d'une publication aux "
643
- "membres du groupe <em>Premium</ em>."
644
 
645
  #: lib/views/class-groups-shortcodes.php:121
646
  msgid "Log out"
@@ -997,7 +996,7 @@ msgstr "La <em>Capacité</em> ne doit pas être vide."
997
  # @ groups
998
  #: lib/admin/groups-admin-groups-edit.php:198
999
  msgid "The <em>Name</em> must not be empty."
1000
- msgstr "Le <em>Nom</ em> ne doit pas être vide."
1001
 
1002
  # @ groups
1003
  #: lib/admin/groups-admin-capabilities.php:75
3
  "Project-Id-Version: Groups\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2015-06-30 20:09+0200\n"
6
+ "PO-Revision-Date: 2016-02-08 11:32+0100\n"
7
  "Last-Translator: Stéphane PASSEDOUET <s.passedouet@pheeric.com>\n"
8
  "Language-Team: itthinx.com\n"
9
  "Language: fr_FR\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n>1;\n"
14
+ "X-Generator: Poedit 1.8.6\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
124
  #: lib/admin/groups-admin-groups-remove.php:189
125
  #: lib/admin/groups-admin-groups.php:49 lib/admin/groups-admin-groups.php:148
126
  #: lib/admin/groups-admin-groups.php:179 lib/admin/groups-admin-groups.php:185
127
+ #: lib/admin/groups-admin-options.php:39 lib/admin/groups-admin-options.php:329
 
128
  #: lib/admin/groups-admin-tree-view.php:37 lib/test/groups-tests.php:385
129
  #: lib/test/groups-tests.php:391
130
  msgid "Access denied."
232
  "Become a member of the <em>Premium</em> group - this is required so you can "
233
  "choose the <em>premium</em> capability to restrict access to a post."
234
  msgstr ""
235
+ "Devenez un membre du groupe <em>Premium</em> - cela est nécessaire afin que "
236
+ "vous puissiez choisir la capacité <em>premium</em> pour restreindre l'accès "
237
+ "à une publication."
238
 
239
  # @ groups
240
  #: lib/admin/groups-admin-capabilities.php:346
290
  #: lib/admin/groups-admin-capabilities.php:193
291
  #: lib/admin/groups-admin-groups-add.php:99
292
  #: lib/admin/groups-admin-groups-edit.php:119
293
+ #: lib/admin/groups-admin-groups.php:297 lib/admin/groups-admin-options.php:251
294
+ #: lib/core/class-groups-help.php:69
295
  msgid "Capabilities"
296
  msgstr "Capacités"
297
 
507
  "capability to the <em>Premium</em> group."
508
  msgstr ""
509
  "Allez à <strong>Groups > Groups</strong> et attribuez la capacité "
510
+ "<em>premium</em> au groupe <em>Premium</em>."
511
 
512
  # @ groups
513
  #: lib/access/class-groups-access-meta-boxes.php:158
639
  "the <em>Premium</em> group."
640
  msgstr ""
641
  "Supposons que vous voulez limiter la visibilité d'une publication aux "
642
+ "membres du groupe <em>Premium</em>."
643
 
644
  #: lib/views/class-groups-shortcodes.php:121
645
  msgid "Log out"
996
  # @ groups
997
  #: lib/admin/groups-admin-groups-edit.php:198
998
  msgid "The <em>Name</em> must not be empty."
999
+ msgstr "Le <em>Nom</em> ne doit pas être vide."
1000
 
1001
  # @ groups
1002
  #: lib/admin/groups-admin-capabilities.php:75
lib/access/class-groups-access-meta-boxes.php CHANGED
@@ -76,7 +76,6 @@ class Groups_Access_Meta_Boxes {
76
  if ( $pagenow == 'upload.php' ) {
77
  Groups_UIE::enqueue( 'select' );
78
  }
79
-
80
  }
81
 
82
  /**
@@ -251,7 +250,7 @@ class Groups_Access_Meta_Boxes {
251
  }
252
  }
253
  $output .= '</select>';
254
-
255
  $output .= Groups_UIE::render_select( '.select.capability' );
256
  // $output .= '<script type="text/javascript">';
257
  // $output .= 'if (typeof jQuery !== "undefined"){';
76
  if ( $pagenow == 'upload.php' ) {
77
  Groups_UIE::enqueue( 'select' );
78
  }
 
79
  }
80
 
81
  /**
250
  }
251
  }
252
  $output .= '</select>';
253
+
254
  $output .= Groups_UIE::render_select( '.select.capability' );
255
  // $output .= '<script type="text/javascript">';
256
  // $output .= 'if (typeof jQuery !== "undefined"){';
lib/access/class-groups-access-shortcodes.php CHANGED
@@ -27,21 +27,21 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Shortcode handlers.
28
  */
29
  class Groups_Access_Shortcodes {
30
-
31
  /**
32
  * Defines access shortcodes.
33
  */
34
  public static function init() {
35
-
36
  // group restrictions
37
  add_shortcode( 'groups_member', array( __CLASS__, 'groups_member' ) );
38
  add_shortcode( 'groups_non_member', array( __CLASS__, 'groups_non_member' ) );
39
-
40
  // capabilities
41
  add_shortcode( 'groups_can', array( __CLASS__, 'groups_can' ) );
42
  add_shortcode( 'groups_can_not', array( __CLASS__, 'groups_can_not' ) );
43
  }
44
-
45
  /**
46
  * Takes one attribute "group" which is a comma-separated list of group
47
  * names or ids (can be mixed).
@@ -79,7 +79,7 @@ class Groups_Access_Shortcodes {
79
  }
80
  return $output;
81
  }
82
-
83
  /**
84
  * Takes one attribute "group" which is a comma-separated list of group
85
  * names or ids (can be mixed).
@@ -117,7 +117,7 @@ class Groups_Access_Shortcodes {
117
  }
118
  return $output;
119
  }
120
-
121
  /**
122
  * Takes one attribute "capability" that must be a valid capability label
123
  * or a list of capabilities separated by comma.
@@ -149,7 +149,7 @@ class Groups_Access_Shortcodes {
149
  }
150
  return $output;
151
  }
152
-
153
  /**
154
  * Takes one attribute "capability" that must be a valid capability label,
155
  * or a comma-separaed list of those.
27
  * Shortcode handlers.
28
  */
29
  class Groups_Access_Shortcodes {
30
+
31
  /**
32
  * Defines access shortcodes.
33
  */
34
  public static function init() {
35
+
36
  // group restrictions
37
  add_shortcode( 'groups_member', array( __CLASS__, 'groups_member' ) );
38
  add_shortcode( 'groups_non_member', array( __CLASS__, 'groups_non_member' ) );
39
+
40
  // capabilities
41
  add_shortcode( 'groups_can', array( __CLASS__, 'groups_can' ) );
42
  add_shortcode( 'groups_can_not', array( __CLASS__, 'groups_can_not' ) );
43
  }
44
+
45
  /**
46
  * Takes one attribute "group" which is a comma-separated list of group
47
  * names or ids (can be mixed).
79
  }
80
  return $output;
81
  }
82
+
83
  /**
84
  * Takes one attribute "group" which is a comma-separated list of group
85
  * names or ids (can be mixed).
117
  }
118
  return $output;
119
  }
120
+
121
  /**
122
  * Takes one attribute "capability" that must be a valid capability label
123
  * or a list of capabilities separated by comma.
149
  }
150
  return $output;
151
  }
152
+
153
  /**
154
  * Takes one attribute "capability" that must be a valid capability label,
155
  * or a comma-separaed list of those.
lib/access/class-groups-post-access.php CHANGED
@@ -33,17 +33,17 @@ if ( !defined( 'ABSPATH' ) ) {
33
  *
34
  */
35
  class Groups_Post_Access {
36
-
37
  const POSTMETA_PREFIX = 'groups-';
38
-
39
  const CACHE_GROUP = 'groups';
40
  const CAN_READ_POST = 'can_read_post';
41
-
42
  const READ_POST_CAPABILITY = "groups_read_post";
43
  const READ_POST_CAPABILITY_NAME = "Read Post";
44
  const READ_POST_CAPABILITIES = 'read_post_capabilities';
45
  const POST_TYPES = 'post_types';
46
-
47
  /**
48
  * Create needed capabilities on plugin activation.
49
  * Must be called explicitly or hooked into activation.
@@ -172,7 +172,7 @@ class Groups_Post_Access {
172
 
173
  // 2. Filter the posts that require a capability that the user doesn't
174
  // have, or in other words: exclude posts that the user must NOT access:
175
-
176
  // The following is not correct in that it requires the user to have ALL capabilities:
177
  // $where .= sprintf(
178
  // " AND {$wpdb->posts}.ID NOT IN (SELECT DISTINCT ID FROM $wpdb->posts LEFT JOIN $wpdb->postmeta on {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id WHERE {$wpdb->postmeta}.meta_key = '%s' AND {$wpdb->postmeta}.meta_value NOT IN (%s) ) ",
@@ -212,7 +212,7 @@ class Groups_Post_Access {
212
  }
213
  return $result;
214
  }
215
-
216
  /**
217
  * Filter posts by access capability.
218
  *
@@ -229,7 +229,7 @@ class Groups_Post_Access {
229
  }
230
  return $result;
231
  }
232
-
233
  /**
234
  * Filter menu items by access capability.
235
  *
@@ -251,7 +251,7 @@ class Groups_Post_Access {
251
  }
252
  return $result;
253
  }
254
-
255
  /**
256
  * Filter excerpt by access capability.
257
  *
@@ -271,7 +271,7 @@ class Groups_Post_Access {
271
  }
272
  return $result;
273
  }
274
-
275
  /**
276
  * Filter content by access capability.
277
  *
@@ -291,7 +291,7 @@ class Groups_Post_Access {
291
  }
292
  return $result;
293
  }
294
-
295
  /**
296
  * Adds an access capability requirement.
297
  *
@@ -330,7 +330,7 @@ class Groups_Post_Access {
330
  }
331
  return $result;
332
  }
333
-
334
  /**
335
  * Returns true if the post requires the given capability to grant access.
336
  *
@@ -349,7 +349,7 @@ class Groups_Post_Access {
349
  }
350
  return $result;
351
  }
352
-
353
  /**
354
  * Currently does nothing, always returns false.
355
  *
@@ -359,7 +359,7 @@ class Groups_Post_Access {
359
  public static function update( $map ) {
360
  return false;
361
  }
362
-
363
  /**
364
  * Removes a capability requirement from a post.
365
  *
@@ -378,7 +378,7 @@ class Groups_Post_Access {
378
  }
379
  return $result;
380
  }
381
-
382
  /**
383
  * Returns a list of capabilities that grant access to the post.
384
  *
@@ -388,7 +388,7 @@ class Groups_Post_Access {
388
  public static function get_read_post_capabilities( $post_id ) {
389
  return get_post_meta( $post_id, self::POSTMETA_PREFIX . self::READ_POST_CAPABILITY );
390
  }
391
-
392
  /**
393
  * Returns true if the user has any of the capabilities that grant access to the post.
394
  *
33
  *
34
  */
35
  class Groups_Post_Access {
36
+
37
  const POSTMETA_PREFIX = 'groups-';
38
+
39
  const CACHE_GROUP = 'groups';
40
  const CAN_READ_POST = 'can_read_post';
41
+
42
  const READ_POST_CAPABILITY = "groups_read_post";
43
  const READ_POST_CAPABILITY_NAME = "Read Post";
44
  const READ_POST_CAPABILITIES = 'read_post_capabilities';
45
  const POST_TYPES = 'post_types';
46
+
47
  /**
48
  * Create needed capabilities on plugin activation.
49
  * Must be called explicitly or hooked into activation.
172
 
173
  // 2. Filter the posts that require a capability that the user doesn't
174
  // have, or in other words: exclude posts that the user must NOT access:
175
+
176
  // The following is not correct in that it requires the user to have ALL capabilities:
177
  // $where .= sprintf(
178
  // " AND {$wpdb->posts}.ID NOT IN (SELECT DISTINCT ID FROM $wpdb->posts LEFT JOIN $wpdb->postmeta on {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id WHERE {$wpdb->postmeta}.meta_key = '%s' AND {$wpdb->postmeta}.meta_value NOT IN (%s) ) ",
212
  }
213
  return $result;
214
  }
215
+
216
  /**
217
  * Filter posts by access capability.
218
  *
229
  }
230
  return $result;
231
  }
232
+
233
  /**
234
  * Filter menu items by access capability.
235
  *
251
  }
252
  return $result;
253
  }
254
+
255
  /**
256
  * Filter excerpt by access capability.
257
  *
271
  }
272
  return $result;
273
  }
274
+
275
  /**
276
  * Filter content by access capability.
277
  *
291
  }
292
  return $result;
293
  }
294
+
295
  /**
296
  * Adds an access capability requirement.
297
  *
330
  }
331
  return $result;
332
  }
333
+
334
  /**
335
  * Returns true if the post requires the given capability to grant access.
336
  *
349
  }
350
  return $result;
351
  }
352
+
353
  /**
354
  * Currently does nothing, always returns false.
355
  *
359
  public static function update( $map ) {
360
  return false;
361
  }
362
+
363
  /**
364
  * Removes a capability requirement from a post.
365
  *
378
  }
379
  return $result;
380
  }
381
+
382
  /**
383
  * Returns a list of capabilities that grant access to the post.
384
  *
388
  public static function get_read_post_capabilities( $post_id ) {
389
  return get_post_meta( $post_id, self::POSTMETA_PREFIX . self::READ_POST_CAPABILITY );
390
  }
391
+
392
  /**
393
  * Returns true if the user has any of the capabilities that grant access to the post.
394
  *
lib/admin/groups-admin-groups-add.php CHANGED
@@ -42,7 +42,7 @@ function groups_admin_groups_add() {
42
  $current_url = remove_query_arg( 'group_id', $current_url );
43
 
44
  $parent_id = isset( $_POST['parent-id-field'] ) ? $_POST['parent-id-field'] : '';
45
- $name = isset( $_POST['name-field'] ) ? $_POST['name-field'] : '';
46
  $description = isset( $_POST['description-field'] ) ? $_POST['description-field'] : '';
47
 
48
  $group_table = _groups_get_tablename( 'group' );
@@ -112,6 +112,8 @@ function groups_admin_groups_add() {
112
  $output .= Groups_UIE::render_select( '.select.capability' );
113
  $output .= '</div>';
114
 
 
 
115
  $output .= '<div class="field">';
116
  $output .= wp_nonce_field( 'groups-add', GROUPS_ADMIN_GROUPS_NONCE, true, false );
117
  $output .= '<input class="button button-primary" type="submit" value="' . __( 'Add', GROUPS_PLUGIN_DOMAIN ) . '"/>';
@@ -148,7 +150,6 @@ function groups_admin_groups_add_submit() {
148
  $name = isset( $_POST['name-field'] ) ? $_POST['name-field'] : null;
149
 
150
  $group_id = Groups_Group::create( compact( "creator_id", "datetime", "parent_id", "description", "name" ) );
151
-
152
  if ( $group_id ) {
153
  if ( !empty( $_POST['capability_ids'] ) ) {
154
  $caps = $_POST['capability_ids'];
@@ -156,6 +157,7 @@ function groups_admin_groups_add_submit() {
156
  Groups_Group_Capability::create( array( 'group_id' => $group_id, 'capability_id' => $cap ) );
157
  }
158
  }
 
159
  } else {
160
  if ( !$name ) {
161
  Groups_Admin::add_message( __( 'The name must not be empty.', GROUPS_PLUGIN_DOMAIN ), 'error' );
42
  $current_url = remove_query_arg( 'group_id', $current_url );
43
 
44
  $parent_id = isset( $_POST['parent-id-field'] ) ? $_POST['parent-id-field'] : '';
45
+ $name = isset( $_POST['name-field'] ) ? $_POST['name-field'] : '';
46
  $description = isset( $_POST['description-field'] ) ? $_POST['description-field'] : '';
47
 
48
  $group_table = _groups_get_tablename( 'group' );
112
  $output .= Groups_UIE::render_select( '.select.capability' );
113
  $output .= '</div>';
114
 
115
+ $output .= apply_filters( 'groups_admin_groups_add_form_after_fields', '' );
116
+
117
  $output .= '<div class="field">';
118
  $output .= wp_nonce_field( 'groups-add', GROUPS_ADMIN_GROUPS_NONCE, true, false );
119
  $output .= '<input class="button button-primary" type="submit" value="' . __( 'Add', GROUPS_PLUGIN_DOMAIN ) . '"/>';
150
  $name = isset( $_POST['name-field'] ) ? $_POST['name-field'] : null;
151
 
152
  $group_id = Groups_Group::create( compact( "creator_id", "datetime", "parent_id", "description", "name" ) );
 
153
  if ( $group_id ) {
154
  if ( !empty( $_POST['capability_ids'] ) ) {
155
  $caps = $_POST['capability_ids'];
157
  Groups_Group_Capability::create( array( 'group_id' => $group_id, 'capability_id' => $cap ) );
158
  }
159
  }
160
+ do_action( 'groups_admin_groups_add_submit_success', $group_id );
161
  } else {
162
  if ( !$name ) {
163
  Groups_Admin::add_message( __( 'The name must not be empty.', GROUPS_PLUGIN_DOMAIN ), 'error' );
lib/admin/groups-admin-groups-edit.php CHANGED
@@ -151,6 +151,8 @@ function groups_admin_groups_edit( $group_id ) {
151
  $output .= '</div>';
152
  }
153
 
 
 
154
  $output .= '<div class="field">';
155
  $output .= wp_nonce_field( 'groups-edit', GROUPS_ADMIN_GROUPS_NONCE, true, false );
156
  $output .= '<input class="button button-primary" type="submit" value="' . __( 'Save', GROUPS_PLUGIN_DOMAIN ) . '"/>';
@@ -208,7 +210,6 @@ function groups_admin_groups_edit_submit() {
208
  }
209
 
210
  $group_id = Groups_Group::update( compact( "group_id", "name", "parent_id", "description" ) );
211
-
212
  if ( $group_id ) {
213
  $capability_table = _groups_get_tablename( "capability" );
214
  $group_capability_table = _groups_get_tablename( "group_capability" );
@@ -237,6 +238,7 @@ function groups_admin_groups_edit_submit() {
237
  Groups_Group_Capability::create( array( 'group_id' => $group_id, 'capability_id' => $cap ) );
238
  }
239
  }
 
240
  }
241
  return $group_id;
242
  } else {
151
  $output .= '</div>';
152
  }
153
 
154
+ $output .= apply_filters( 'groups_admin_groups_edit_form_after_fields', '', $group_id );
155
+
156
  $output .= '<div class="field">';
157
  $output .= wp_nonce_field( 'groups-edit', GROUPS_ADMIN_GROUPS_NONCE, true, false );
158
  $output .= '<input class="button button-primary" type="submit" value="' . __( 'Save', GROUPS_PLUGIN_DOMAIN ) . '"/>';
210
  }
211
 
212
  $group_id = Groups_Group::update( compact( "group_id", "name", "parent_id", "description" ) );
 
213
  if ( $group_id ) {
214
  $capability_table = _groups_get_tablename( "capability" );
215
  $group_capability_table = _groups_get_tablename( "group_capability" );
238
  Groups_Group_Capability::create( array( 'group_id' => $group_id, 'capability_id' => $cap ) );
239
  }
240
  }
241
+ do_action( 'groups_admin_groups_edit_submit_success', $group_id );
242
  }
243
  return $group_id;
244
  } else {
lib/auto/class-groups-registered.php CHANGED
@@ -68,27 +68,27 @@ class Groups_Registered {
68
  * Initialize hooks that handle addition and removal of users and blogs.
69
  */
70
  public static function init() {
71
-
72
  // For translation of the "Registered" group(s)
73
  __( 'Registered', GROUPS_PLUGIN_DOMAIN );
74
 
75
  // When a blog is added, create a new "Registered" group for that blog.
76
  add_action( 'wpmu_new_blog', array( __CLASS__, 'wpmu_new_blog' ), 10, 2 );
77
-
78
  // Remove group when a blog is deleted? When a blog is deleted,
79
  // Groups_Controller::delete_blog() takes appropriate action.
80
-
81
  // When a user is added, add it to the "Registered" group.
82
  add_action( 'user_register', array( __CLASS__, 'user_register' ) );
83
-
84
  // Note : When a user is deleted this is handled from core.
85
 
86
  // When a user is added to a blog, add it to the blog's "Registered" group.
87
  add_action( 'add_user_to_blog', array( __CLASS__, 'add_user_to_blog' ), 10, 3 );
88
-
89
  // Note : When a user is removed from a blog it's handled from core.
90
  }
91
-
92
  /**
93
  * Create "Registered" group for new blog and add its admin user.
94
  *
@@ -120,14 +120,14 @@ class Groups_Registered {
120
  Groups_Controller::restore_current_blog();
121
  }
122
  }
123
-
124
  /**
125
  * Assign a newly created user to its "Registered" group.
126
  *
127
  * @param int $user_id
128
  */
129
  public static function user_register( $user_id ) {
130
-
131
  $registered_group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME );
132
  if ( !$registered_group ) {
133
  $registered_group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
@@ -157,7 +157,7 @@ class Groups_Registered {
157
  }
158
  }
159
  }
160
-
161
  /**
162
  * Assign a user to its "Registered" group for the given blog.
163
  *
@@ -166,13 +166,13 @@ class Groups_Registered {
166
  * @param int $blog_id Blog ID.
167
  */
168
  public static function add_user_to_blog( $user_id, $role, $blog_id ) {
169
-
170
  if ( is_multisite() ) {
171
  Groups_Controller::switch_to_blog( $blog_id );
172
  }
173
-
174
  global $wpdb;
175
-
176
  // Check if the group table exists, if it does not exist, we are
177
  // probably here because the action has been triggered in the middle
178
  // of wpmu_create_blog() before the wpmu_new_blog action has been
@@ -197,7 +197,7 @@ class Groups_Registered {
197
  );
198
  }
199
  }
200
-
201
  if ( is_multisite() ) {
202
  Groups_Controller::restore_current_blog();
203
  }
68
  * Initialize hooks that handle addition and removal of users and blogs.
69
  */
70
  public static function init() {
71
+
72
  // For translation of the "Registered" group(s)
73
  __( 'Registered', GROUPS_PLUGIN_DOMAIN );
74
 
75
  // When a blog is added, create a new "Registered" group for that blog.
76
  add_action( 'wpmu_new_blog', array( __CLASS__, 'wpmu_new_blog' ), 10, 2 );
77
+
78
  // Remove group when a blog is deleted? When a blog is deleted,
79
  // Groups_Controller::delete_blog() takes appropriate action.
80
+
81
  // When a user is added, add it to the "Registered" group.
82
  add_action( 'user_register', array( __CLASS__, 'user_register' ) );
83
+
84
  // Note : When a user is deleted this is handled from core.
85
 
86
  // When a user is added to a blog, add it to the blog's "Registered" group.
87
  add_action( 'add_user_to_blog', array( __CLASS__, 'add_user_to_blog' ), 10, 3 );
88
+
89
  // Note : When a user is removed from a blog it's handled from core.
90
  }
91
+
92
  /**
93
  * Create "Registered" group for new blog and add its admin user.
94
  *
120
  Groups_Controller::restore_current_blog();
121
  }
122
  }
123
+
124
  /**
125
  * Assign a newly created user to its "Registered" group.
126
  *
127
  * @param int $user_id
128
  */
129
  public static function user_register( $user_id ) {
130
+
131
  $registered_group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME );
132
  if ( !$registered_group ) {
133
  $registered_group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
157
  }
158
  }
159
  }
160
+
161
  /**
162
  * Assign a user to its "Registered" group for the given blog.
163
  *
166
  * @param int $blog_id Blog ID.
167
  */
168
  public static function add_user_to_blog( $user_id, $role, $blog_id ) {
169
+
170
  if ( is_multisite() ) {
171
  Groups_Controller::switch_to_blog( $blog_id );
172
  }
173
+
174
  global $wpdb;
175
+
176
  // Check if the group table exists, if it does not exist, we are
177
  // probably here because the action has been triggered in the middle
178
  // of wpmu_create_blog() before the wpmu_new_blog action has been
197
  );
198
  }
199
  }
200
+
201
  if ( is_multisite() ) {
202
  Groups_Controller::restore_current_blog();
203
  }
lib/core/class-groups-capability.php CHANGED
@@ -35,7 +35,7 @@ class Groups_Capability {
35
  * @var persisted capability object
36
  */
37
  var $capability = null;
38
-
39
  /**
40
  * Create by capability id.
41
  * Must have been persisted.
@@ -44,7 +44,7 @@ class Groups_Capability {
44
  public function __construct( $capability_id ) {
45
  $this->capability = self::read( $capability_id );
46
  }
47
-
48
  /**
49
  * Retrieve a property by name.
50
  *
@@ -106,7 +106,7 @@ class Groups_Capability {
106
  }
107
  return $result;
108
  }
109
-
110
  /**
111
  * Persist a capability.
112
  *
@@ -122,20 +122,20 @@ class Groups_Capability {
122
  * @return capability_id on success, otherwise false
123
  */
124
  public static function create( $map ) {
125
-
126
  global $wpdb;
127
  extract( $map );
128
  $result = false;
129
-
130
  if ( !empty( $capability ) ) {
131
-
132
  if ( self::read_by_capability( $capability ) === false ) {
133
-
134
  $data = array(
135
  'capability' => $capability
136
  );
137
  $formats = array( '%s' );
138
-
139
  if ( !empty( $class ) ) {
140
  $data['class'] = $class;
141
  $formats[] = '%s';
@@ -164,7 +164,7 @@ class Groups_Capability {
164
  }
165
  return $result;
166
  }
167
-
168
  /**
169
  * Retrieve a capability.
170
  *
@@ -223,11 +223,11 @@ class Groups_Capability {
223
  * @return capability_id on success, otherwise false
224
  */
225
  public static function update( $map ) {
226
-
227
  global $wpdb;
228
  extract( $map );
229
  $result = false;
230
-
231
  if ( isset( $capability_id ) && !empty( $capability ) ) {
232
  $capability_table = _groups_get_tablename( 'capability' );
233
  $old_capability = Groups_Capability::read( $capability_id );
@@ -272,7 +272,7 @@ class Groups_Capability {
272
  }
273
  return $result;
274
  }
275
-
276
  /**
277
  * Remove capability and its relations.
278
  *
@@ -283,7 +283,7 @@ class Groups_Capability {
283
 
284
  global $wpdb;
285
  $result = false;
286
-
287
  // avoid nonsense requests
288
  if ( $capability = Groups_Capability::read( $capability_id ) ) {
289
  $capability_table = _groups_get_tablename( 'capability' );
35
  * @var persisted capability object
36
  */
37
  var $capability = null;
38
+
39
  /**
40
  * Create by capability id.
41
  * Must have been persisted.
44
  public function __construct( $capability_id ) {
45
  $this->capability = self::read( $capability_id );
46
  }
47
+
48
  /**
49
  * Retrieve a property by name.
50
  *
106
  }
107
  return $result;
108
  }
109
+
110
  /**
111
  * Persist a capability.
112
  *
122
  * @return capability_id on success, otherwise false
123
  */
124
  public static function create( $map ) {
125
+
126
  global $wpdb;
127
  extract( $map );
128
  $result = false;
129
+
130
  if ( !empty( $capability ) ) {
131
+
132
  if ( self::read_by_capability( $capability ) === false ) {
133
+
134
  $data = array(
135
  'capability' => $capability
136
  );
137
  $formats = array( '%s' );
138
+
139
  if ( !empty( $class ) ) {
140
  $data['class'] = $class;
141
  $formats[] = '%s';
164
  }
165
  return $result;
166
  }
167
+
168
  /**
169
  * Retrieve a capability.
170
  *
223
  * @return capability_id on success, otherwise false
224
  */
225
  public static function update( $map ) {
226
+
227
  global $wpdb;
228
  extract( $map );
229
  $result = false;
230
+
231
  if ( isset( $capability_id ) && !empty( $capability ) ) {
232
  $capability_table = _groups_get_tablename( 'capability' );
233
  $old_capability = Groups_Capability::read( $capability_id );
272
  }
273
  return $result;
274
  }
275
+
276
  /**
277
  * Remove capability and its relations.
278
  *
283
 
284
  global $wpdb;
285
  $result = false;
286
+
287
  // avoid nonsense requests
288
  if ( $capability = Groups_Capability::read( $capability_id ) ) {
289
  $capability_table = _groups_get_tablename( 'capability' );
lib/core/class-groups-controller.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Plugin controller
28
  */
29
  class Groups_Controller {
30
-
31
  /**
32
  * Cache-safe switching in case any multi-site hiccups might occur.
33
  * Clears the cache after switching to the given blog to avoid using
@@ -46,14 +46,14 @@ class Groups_Controller {
46
  wp_cache_reset(); // deprecated in WP 3.5.0
47
  }
48
  }
49
-
50
  /**
51
  * Switch back to previous blog.
52
  */
53
  public static function restore_current_blog() {
54
  restore_current_blog();
55
  }
56
-
57
  /**
58
  * Boot the plugin.
59
  * @see Groups_Registered::wpmu_new_blog()
@@ -62,13 +62,13 @@ class Groups_Controller {
62
  register_activation_hook( GROUPS_FILE, array( __CLASS__, 'activate' ) );
63
  register_deactivation_hook( GROUPS_FILE, array( __CLASS__, 'deactivate' ) );
64
  add_action( 'init', array( __CLASS__, 'init' ) );
65
-
66
  // priority 9 because it needs to be called before Groups_Registered's
67
  // wpmu_new_blog kicks in
68
  add_action( 'wpmu_new_blog', array( __CLASS__, 'wpmu_new_blog' ), 9, 2 );
69
  add_action( 'delete_blog', array( __CLASS__, 'delete_blog' ), 10, 2 );
70
  }
71
-
72
  /**
73
  * Run activation for a newly created blog in a multisite environment.
74
  *
@@ -84,7 +84,7 @@ class Groups_Controller {
84
  }
85
  }
86
  }
87
-
88
  /**
89
  * Run deactivation for a blog that is about to be deleted in a multisite
90
  * environment.
@@ -101,7 +101,7 @@ class Groups_Controller {
101
  }
102
  }
103
  }
104
-
105
  /**
106
  * Initialize.
107
  * Loads the plugin's translations.
@@ -110,7 +110,7 @@ class Groups_Controller {
110
  load_plugin_textdomain( GROUPS_PLUGIN_DOMAIN, null, 'groups/languages' );
111
  self::version_check();
112
  }
113
-
114
  /**
115
  * Plugin activation.
116
  * @param boolean $network_wide
@@ -127,13 +127,13 @@ class Groups_Controller {
127
  self::setup();
128
  }
129
  }
130
-
131
  /**
132
  * Plugin activation work.
133
  */
134
  private static function setup() {
135
  global $wpdb, $wp_roles;
136
-
137
  // create WP capabilities
138
  Groups_Controller::set_default_capabilities();
139
 
@@ -145,7 +145,7 @@ class Groups_Controller {
145
  $charset_collate .= " COLLATE $wpdb->collate";
146
  }
147
 
148
- // create tables
149
  $group_table = _groups_get_tablename( 'group' );
150
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$group_table'" ) != $group_table ) {
151
  $queries[] = "CREATE TABLE $group_table (
@@ -212,7 +212,7 @@ class Groups_Controller {
212
  Groups_WordPress::activate();
213
  // ... end of plugin activation work.
214
  }
215
-
216
  /**
217
  * Checks current version and triggers update if needed.
218
  */
@@ -228,7 +228,7 @@ class Groups_Controller {
228
  }
229
  }
230
  }
231
-
232
  /**
233
  * Update maintenance.
234
  */
@@ -283,7 +283,7 @@ class Groups_Controller {
283
  }
284
  return $result;
285
  }
286
-
287
  /**
288
  * Drop tables and clear data if the plugin is deactivated.
289
  * This will happen only if the user chooses to delete data upon deactivation.
@@ -303,15 +303,15 @@ class Groups_Controller {
303
  self::cleanup();
304
  }
305
  }
306
-
307
  /**
308
  * Plugin deactivation cleanup.
309
  * @param $drop overrides the groups_delete_data option, default is false
310
  */
311
  private static function cleanup( $drop = false ) {
312
-
313
  global $wpdb, $wp_roles;
314
-
315
  $delete_data = Groups_Options::get_option( 'groups_delete_data', false );
316
  if ( $delete_data || $drop ) {
317
  foreach ( $wp_roles->role_objects as $role ) {
@@ -330,7 +330,7 @@ class Groups_Controller {
330
  delete_option( 'groups_delete_data' );
331
  }
332
  }
333
-
334
  /**
335
  * Determines the default capabilities for the administrator role.
336
  * In lack of an administrator role, these capabilities are assigned
@@ -361,7 +361,7 @@ class Groups_Controller {
361
  }
362
  }
363
  }
364
-
365
  /**
366
  * There must be at least one role with the minimum set of capabilities
367
  * to access and manage the Groups plugin's options.
27
  * Plugin controller
28
  */
29
  class Groups_Controller {
30
+
31
  /**
32
  * Cache-safe switching in case any multi-site hiccups might occur.
33
  * Clears the cache after switching to the given blog to avoid using
46
  wp_cache_reset(); // deprecated in WP 3.5.0
47
  }
48
  }
49
+
50
  /**
51
  * Switch back to previous blog.
52
  */
53
  public static function restore_current_blog() {
54
  restore_current_blog();
55
  }
56
+
57
  /**
58
  * Boot the plugin.
59
  * @see Groups_Registered::wpmu_new_blog()
62
  register_activation_hook( GROUPS_FILE, array( __CLASS__, 'activate' ) );
63
  register_deactivation_hook( GROUPS_FILE, array( __CLASS__, 'deactivate' ) );
64
  add_action( 'init', array( __CLASS__, 'init' ) );
65
+
66
  // priority 9 because it needs to be called before Groups_Registered's
67
  // wpmu_new_blog kicks in
68
  add_action( 'wpmu_new_blog', array( __CLASS__, 'wpmu_new_blog' ), 9, 2 );
69
  add_action( 'delete_blog', array( __CLASS__, 'delete_blog' ), 10, 2 );
70
  }
71
+
72
  /**
73
  * Run activation for a newly created blog in a multisite environment.
74
  *
84
  }
85
  }
86
  }
87
+
88
  /**
89
  * Run deactivation for a blog that is about to be deleted in a multisite
90
  * environment.
101
  }
102
  }
103
  }
104
+
105
  /**
106
  * Initialize.
107
  * Loads the plugin's translations.
110
  load_plugin_textdomain( GROUPS_PLUGIN_DOMAIN, null, 'groups/languages' );
111
  self::version_check();
112
  }
113
+
114
  /**
115
  * Plugin activation.
116
  * @param boolean $network_wide
127
  self::setup();
128
  }
129
  }
130
+
131
  /**
132
  * Plugin activation work.
133
  */
134
  private static function setup() {
135
  global $wpdb, $wp_roles;
136
+
137
  // create WP capabilities
138
  Groups_Controller::set_default_capabilities();
139
 
145
  $charset_collate .= " COLLATE $wpdb->collate";
146
  }
147
 
148
+ // create tables
149
  $group_table = _groups_get_tablename( 'group' );
150
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$group_table'" ) != $group_table ) {
151
  $queries[] = "CREATE TABLE $group_table (
212
  Groups_WordPress::activate();
213
  // ... end of plugin activation work.
214
  }
215
+
216
  /**
217
  * Checks current version and triggers update if needed.
218
  */
228
  }
229
  }
230
  }
231
+
232
  /**
233
  * Update maintenance.
234
  */
283
  }
284
  return $result;
285
  }
286
+
287
  /**
288
  * Drop tables and clear data if the plugin is deactivated.
289
  * This will happen only if the user chooses to delete data upon deactivation.
303
  self::cleanup();
304
  }
305
  }
306
+
307
  /**
308
  * Plugin deactivation cleanup.
309
  * @param $drop overrides the groups_delete_data option, default is false
310
  */
311
  private static function cleanup( $drop = false ) {
312
+
313
  global $wpdb, $wp_roles;
314
+
315
  $delete_data = Groups_Options::get_option( 'groups_delete_data', false );
316
  if ( $delete_data || $drop ) {
317
  foreach ( $wp_roles->role_objects as $role ) {
330
  delete_option( 'groups_delete_data' );
331
  }
332
  }
333
+
334
  /**
335
  * Determines the default capabilities for the administrator role.
336
  * In lack of an administrator role, these capabilities are assigned
361
  }
362
  }
363
  }
364
+
365
  /**
366
  * There must be at least one role with the minimum set of capabilities
367
  * to access and manage the Groups plugin's options.
lib/core/class-groups-group-capability.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Group Capability OPM
28
  */
29
  class Groups_Group_Capability {
30
-
31
  /**
32
  * Hook into appropriate actions when needed.
33
  * For now, this does nothing.
@@ -37,7 +37,7 @@ class Groups_Group_Capability {
37
  public static function init() {
38
  // Note that group-capabilities are deleted when a group is deleted.
39
  }
40
-
41
  /**
42
  * Persist a group-capability relation.
43
  *
@@ -45,7 +45,7 @@ class Groups_Group_Capability {
45
  * @return true on success, otherwise false
46
  */
47
  public static function create( $map ) {
48
-
49
  global $wpdb;
50
  extract( $map );
51
  $result = false;
@@ -76,7 +76,7 @@ class Groups_Group_Capability {
76
  }
77
  return $result;
78
  }
79
-
80
  /**
81
  * Retrieve a group-capability relation.
82
  *
@@ -87,7 +87,7 @@ class Groups_Group_Capability {
87
  public static function read( $group_id, $capability_id ) {
88
  global $wpdb;
89
  $result = false;
90
-
91
  $group_capability_table = _groups_get_tablename( 'group_capability' );
92
  $group_capability = $wpdb->get_row( $wpdb->prepare(
93
  "SELECT * FROM $group_capability_table WHERE group_id = %d AND capability_id = %d",
@@ -99,7 +99,7 @@ class Groups_Group_Capability {
99
  }
100
  return $result;
101
  }
102
-
103
  /**
104
  * Update group-capability relation.
105
  *
@@ -119,7 +119,7 @@ class Groups_Group_Capability {
119
  }
120
  return $result;
121
  }
122
-
123
  /**
124
  * Remove group-capability relation.
125
  *
@@ -131,7 +131,7 @@ class Groups_Group_Capability {
131
 
132
  global $wpdb;
133
  $result = false;
134
-
135
  // avoid nonsense requests
136
  if ( !empty( $group_id ) && !empty( $capability_id) ) {
137
  // we can omit checking if the group and capability exist, to
27
  * Group Capability OPM
28
  */
29
  class Groups_Group_Capability {
30
+
31
  /**
32
  * Hook into appropriate actions when needed.
33
  * For now, this does nothing.
37
  public static function init() {
38
  // Note that group-capabilities are deleted when a group is deleted.
39
  }
40
+
41
  /**
42
  * Persist a group-capability relation.
43
  *
45
  * @return true on success, otherwise false
46
  */
47
  public static function create( $map ) {
48
+
49
  global $wpdb;
50
  extract( $map );
51
  $result = false;
76
  }
77
  return $result;
78
  }
79
+
80
  /**
81
  * Retrieve a group-capability relation.
82
  *
87
  public static function read( $group_id, $capability_id ) {
88
  global $wpdb;
89
  $result = false;
90
+
91
  $group_capability_table = _groups_get_tablename( 'group_capability' );
92
  $group_capability = $wpdb->get_row( $wpdb->prepare(
93
  "SELECT * FROM $group_capability_table WHERE group_id = %d AND capability_id = %d",
99
  }
100
  return $result;
101
  }
102
+
103
  /**
104
  * Update group-capability relation.
105
  *
119
  }
120
  return $result;
121
  }
122
+
123
  /**
124
  * Remove group-capability relation.
125
  *
131
 
132
  global $wpdb;
133
  $result = false;
134
+
135
  // avoid nonsense requests
136
  if ( !empty( $group_id ) && !empty( $capability_id) ) {
137
  // we can omit checking if the group and capability exist, to
lib/core/class-groups-group.php CHANGED
@@ -37,7 +37,7 @@ class Groups_Group implements I_Capable {
37
  * @var Object Persisted group.
38
  */
39
  var $group = null;
40
-
41
  /**
42
  * Create by group id.
43
  * Must have been persisted.
@@ -46,7 +46,7 @@ class Groups_Group implements I_Capable {
46
  public function __construct( $group_id ) {
47
  $this->group = self::read( $group_id );
48
  }
49
-
50
  /**
51
  * Retrieve a property by name.
52
  *
@@ -151,7 +151,7 @@ class Groups_Group implements I_Capable {
151
  }
152
  return $result;
153
  }
154
-
155
  /**
156
  * (non-PHPdoc)
157
  * @see I_Capable::can()
@@ -160,13 +160,13 @@ class Groups_Group implements I_Capable {
160
 
161
  global $wpdb;
162
  $result = false;
163
-
164
  if ( $this->group !== null ) {
165
-
166
  $group_table = _groups_get_tablename( "group" );
167
  $capability_table = _groups_get_tablename( "capability" );
168
  $group_capability_table = _groups_get_tablename( "group_capability" );
169
-
170
  // determine capability id
171
  $capability_id = null;
172
  if ( is_numeric( $capability ) ) {
@@ -177,7 +177,7 @@ class Groups_Group implements I_Capable {
177
  $capability
178
  ) );
179
  }
180
-
181
  if ( $capability_id !== null ) {
182
  // check if the group itself can
183
  $result = ( Groups_Group_Capability::read( $this->group->group_id, $capability_id ) !== false );
@@ -210,7 +210,7 @@ class Groups_Group implements I_Capable {
210
  "SELECT capability_id FROM $group_capability_table WHERE capability_id = %d AND group_id IN ($id_list)",
211
  Groups_Utility::id( $capability_id )
212
  ) );
213
-
214
  if ( count( $rows ) > 0 ) {
215
  $result = true;
216
  }
@@ -221,7 +221,7 @@ class Groups_Group implements I_Capable {
221
  $result = apply_filters_ref_array( "groups_group_can", array( $result, &$this, $capability ) );
222
  return $result;
223
  }
224
-
225
  /**
226
  * Persist a group.
227
  *
@@ -240,11 +240,11 @@ class Groups_Group implements I_Capable {
240
  extract( $map );
241
  $result = false;
242
  $error = false;
243
-
244
  if ( !empty( $name ) ) {
245
-
246
  $group_table = _groups_get_tablename( "group" );
247
-
248
  $data = array( 'name' => $name );
249
  $formats = array( '%s' );
250
  if ( !isset( $creator_id ) ) {
@@ -295,7 +295,7 @@ class Groups_Group implements I_Capable {
295
  }
296
  return $result;
297
  }
298
-
299
  /**
300
  * Retrieve a group.
301
  *
@@ -305,7 +305,7 @@ class Groups_Group implements I_Capable {
305
  public static function read( $group_id ) {
306
  global $wpdb;
307
  $result = false;
308
-
309
  $group_table = _groups_get_tablename( 'group' );
310
  $group = $wpdb->get_row( $wpdb->prepare(
311
  "SELECT * FROM $group_table WHERE group_id = %d",
@@ -316,7 +316,7 @@ class Groups_Group implements I_Capable {
316
  }
317
  return $result;
318
  }
319
-
320
  /**
321
  * Retrieve a group by name.
322
  *
@@ -343,7 +343,7 @@ class Groups_Group implements I_Capable {
343
  }
344
  return $result;
345
  }
346
-
347
  /**
348
  * Update group.
349
  *
@@ -351,11 +351,11 @@ class Groups_Group implements I_Capable {
351
  * @return group_id on success, otherwise false
352
  */
353
  public static function update( $map ) {
354
-
355
  global $wpdb;
356
  extract( $map );
357
  $result = false;
358
-
359
  if ( isset( $group_id ) && !empty( $name ) ) {
360
  $old_group = Groups_Group::read( $group_id );
361
  $group_table = _groups_get_tablename( 'group' );
@@ -383,7 +383,7 @@ class Groups_Group implements I_Capable {
383
  // P(g) : parent of g
384
  // ---
385
  // It must hold: !( P(g) in S*(g) )
386
-
387
  // Find all successors of this group
388
  $groups = $wpdb->get_var( "SELECT COUNT(*) FROM $group_table" );
389
  if ( $groups !== null ) {
@@ -392,10 +392,10 @@ class Groups_Group implements I_Capable {
392
  $iterations = 0;
393
  $old_group_ids_count = 0;
394
  while( ( $iterations < $groups ) && ( count( $group_ids ) > 0 ) && ( count( $group_ids ) !== $old_group_ids_count ) ) {
395
-
396
  $iterations++;
397
  $old_group_ids_count = count( $group_ids );
398
-
399
  $id_list = implode( ",", $group_ids );
400
  // We can trust ourselves here, no need to use prepare()
401
  // but careful if this query is modified!
@@ -432,7 +432,7 @@ class Groups_Group implements I_Capable {
432
  }
433
  return $result;
434
  }
435
-
436
  /**
437
  * Remove group and its relations.
438
  *
@@ -443,30 +443,30 @@ class Groups_Group implements I_Capable {
443
 
444
  global $wpdb;
445
  $result = false;
446
-
447
  if ( $group = self::read( $group_id ) ) {
448
-
449
  // delete group-capabilities
450
  $group_capability_table = _groups_get_tablename( 'group_capability' );
451
  $wpdb->query( $wpdb->prepare(
452
  "DELETE FROM $group_capability_table WHERE group_id = %d",
453
  Groups_Utility::id( $group->group_id )
454
  ) );
455
-
456
  // delete group-users
457
  $user_group_table = _groups_get_tablename( 'user_group' );
458
  $wpdb->query( $wpdb->prepare(
459
  "DELETE FROM $user_group_table WHERE group_id = %d",
460
  $group->group_id
461
  ) );
462
-
463
  // set parent_id to null where this group is parent
464
  $group_table = _groups_get_tablename( 'group' );
465
  $wpdb->query( $wpdb->prepare(
466
  "UPDATE $group_table SET parent_id = NULL WHERE parent_id = %d",
467
  $group->group_id
468
  ) );
469
-
470
  // delete group
471
  if ( $wpdb->query( $wpdb->prepare(
472
  "DELETE FROM $group_table WHERE group_id = %d",
37
  * @var Object Persisted group.
38
  */
39
  var $group = null;
40
+
41
  /**
42
  * Create by group id.
43
  * Must have been persisted.
46
  public function __construct( $group_id ) {
47
  $this->group = self::read( $group_id );
48
  }
49
+
50
  /**
51
  * Retrieve a property by name.
52
  *
151
  }
152
  return $result;
153
  }
154
+
155
  /**
156
  * (non-PHPdoc)
157
  * @see I_Capable::can()
160
 
161
  global $wpdb;
162
  $result = false;
163
+
164
  if ( $this->group !== null ) {
165
+
166
  $group_table = _groups_get_tablename( "group" );
167
  $capability_table = _groups_get_tablename( "capability" );
168
  $group_capability_table = _groups_get_tablename( "group_capability" );
169
+
170
  // determine capability id
171
  $capability_id = null;
172
  if ( is_numeric( $capability ) ) {
177
  $capability
178
  ) );
179
  }
180
+
181
  if ( $capability_id !== null ) {
182
  // check if the group itself can
183
  $result = ( Groups_Group_Capability::read( $this->group->group_id, $capability_id ) !== false );
210
  "SELECT capability_id FROM $group_capability_table WHERE capability_id = %d AND group_id IN ($id_list)",
211
  Groups_Utility::id( $capability_id )
212
  ) );
213
+
214
  if ( count( $rows ) > 0 ) {
215
  $result = true;
216
  }
221
  $result = apply_filters_ref_array( "groups_group_can", array( $result, &$this, $capability ) );
222
  return $result;
223
  }
224
+
225
  /**
226
  * Persist a group.
227
  *
240
  extract( $map );
241
  $result = false;
242
  $error = false;
243
+
244
  if ( !empty( $name ) ) {
245
+
246
  $group_table = _groups_get_tablename( "group" );
247
+
248
  $data = array( 'name' => $name );
249
  $formats = array( '%s' );
250
  if ( !isset( $creator_id ) ) {
295
  }
296
  return $result;
297
  }
298
+
299
  /**
300
  * Retrieve a group.
301
  *
305
  public static function read( $group_id ) {
306
  global $wpdb;
307
  $result = false;
308
+
309
  $group_table = _groups_get_tablename( 'group' );
310
  $group = $wpdb->get_row( $wpdb->prepare(
311
  "SELECT * FROM $group_table WHERE group_id = %d",
316
  }
317
  return $result;
318
  }
319
+
320
  /**
321
  * Retrieve a group by name.
322
  *
343
  }
344
  return $result;
345
  }
346
+
347
  /**
348
  * Update group.
349
  *
351
  * @return group_id on success, otherwise false
352
  */
353
  public static function update( $map ) {
354
+
355
  global $wpdb;
356
  extract( $map );
357
  $result = false;
358
+
359
  if ( isset( $group_id ) && !empty( $name ) ) {
360
  $old_group = Groups_Group::read( $group_id );
361
  $group_table = _groups_get_tablename( 'group' );
383
  // P(g) : parent of g
384
  // ---
385
  // It must hold: !( P(g) in S*(g) )
386
+
387
  // Find all successors of this group
388
  $groups = $wpdb->get_var( "SELECT COUNT(*) FROM $group_table" );
389
  if ( $groups !== null ) {
392
  $iterations = 0;
393
  $old_group_ids_count = 0;
394
  while( ( $iterations < $groups ) && ( count( $group_ids ) > 0 ) && ( count( $group_ids ) !== $old_group_ids_count ) ) {
395
+
396
  $iterations++;
397
  $old_group_ids_count = count( $group_ids );
398
+
399
  $id_list = implode( ",", $group_ids );
400
  // We can trust ourselves here, no need to use prepare()
401
  // but careful if this query is modified!
432
  }
433
  return $result;
434
  }
435
+
436
  /**
437
  * Remove group and its relations.
438
  *
443
 
444
  global $wpdb;
445
  $result = false;
446
+
447
  if ( $group = self::read( $group_id ) ) {
448
+
449
  // delete group-capabilities
450
  $group_capability_table = _groups_get_tablename( 'group_capability' );
451
  $wpdb->query( $wpdb->prepare(
452
  "DELETE FROM $group_capability_table WHERE group_id = %d",
453
  Groups_Utility::id( $group->group_id )
454
  ) );
455
+
456
  // delete group-users
457
  $user_group_table = _groups_get_tablename( 'user_group' );
458
  $wpdb->query( $wpdb->prepare(
459
  "DELETE FROM $user_group_table WHERE group_id = %d",
460
  $group->group_id
461
  ) );
462
+
463
  // set parent_id to null where this group is parent
464
  $group_table = _groups_get_tablename( 'group' );
465
  $wpdb->query( $wpdb->prepare(
466
  "UPDATE $group_table SET parent_id = NULL WHERE parent_id = %d",
467
  $group->group_id
468
  ) );
469
+
470
  // delete group
471
  if ( $wpdb->query( $wpdb->prepare(
472
  "DELETE FROM $group_table WHERE group_id = %d",
lib/core/class-groups-options.php CHANGED
@@ -27,14 +27,14 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Groups options handler
28
  */
29
  class Groups_Options {
30
-
31
  /**
32
  * Groups plugin option key.
33
  *
34
  * @var string
35
  */
36
  const option_key = 'groups_options';
37
-
38
  /**
39
  * General option index.
40
  *
@@ -47,13 +47,13 @@ class Groups_Options {
47
  */
48
  private function __construct() {
49
  }
50
-
51
  /**
52
  * No cloning.
53
  */
54
  private function __clone() {
55
  }
56
-
57
  /**
58
  * Would be pointless.
59
  */
@@ -70,7 +70,7 @@ class Groups_Options {
70
  add_option( self::option_key, $options, null, 'no' );
71
  }
72
  }
73
-
74
  /**
75
  * Returns the current Groups options and initializes them
76
  * through init() if needed.
@@ -84,7 +84,7 @@ class Groups_Options {
84
  }
85
  return $options;
86
  }
87
-
88
  /**
89
  * Returns the value of a general setting.
90
  *
@@ -100,8 +100,8 @@ class Groups_Options {
100
  }
101
  return $value;
102
  }
103
-
104
-
105
  /**
106
  * Returns the value of a user setting.
107
  *
@@ -127,7 +127,7 @@ class Groups_Options {
127
  }
128
  return $value;
129
  }
130
-
131
  /**
132
  * Updates a general setting.
133
  *
@@ -139,7 +139,7 @@ class Groups_Options {
139
  $options[self::general][$option] = $new_value;
140
  update_option( self::option_key, $options );
141
  }
142
-
143
  /**
144
  * Updates a user setting.
145
  *
@@ -148,21 +148,21 @@ class Groups_Options {
148
  * @param int $user_id update option for this user, defaults to null for current user
149
  */
150
  public static function update_user_option( $option, $new_value, $user_id = null ) {
151
-
152
  if ( $user_id === null ) {
153
  $current_user = wp_get_current_user();
154
  if ( !empty( $current_user ) ) {
155
  $user_id = $current_user->ID;
156
  }
157
  }
158
-
159
  if ( $user_id !== null ) {
160
  $options = self::get_options();
161
  $options[$user_id][$option] = $new_value;
162
  update_option( self::option_key, $options );
163
  }
164
  }
165
-
166
  /**
167
  * Deletes a general setting.
168
  *
@@ -175,7 +175,7 @@ class Groups_Options {
175
  update_option( self::option_key, $options );
176
  }
177
  }
178
-
179
  /**
180
  * Deletes a user setting.
181
  *
@@ -183,14 +183,14 @@ class Groups_Options {
183
  * @param int $user_id delete option for this user, defaults to null for current user
184
  */
185
  public static function delete_user_option( $option, $user_id = null ) {
186
-
187
  if ( $user_id === null ) {
188
  $current_user = wp_get_current_user();
189
  if ( !empty( $current_user ) ) {
190
  $user_id = $current_user->ID;
191
  }
192
  }
193
-
194
  if ( $user_id !== null ) {
195
  $options = self::get_options();
196
  if ( isset( $options[$user_id][$option] ) ) {
@@ -199,7 +199,7 @@ class Groups_Options {
199
  }
200
  }
201
  }
202
-
203
  /**
204
  * Deletes all settings - this includes user and general options.
205
  */
27
  * Groups options handler
28
  */
29
  class Groups_Options {
30
+
31
  /**
32
  * Groups plugin option key.
33
  *
34
  * @var string
35
  */
36
  const option_key = 'groups_options';
37
+
38
  /**
39
  * General option index.
40
  *
47
  */
48
  private function __construct() {
49
  }
50
+
51
  /**
52
  * No cloning.
53
  */
54
  private function __clone() {
55
  }
56
+
57
  /**
58
  * Would be pointless.
59
  */
70
  add_option( self::option_key, $options, null, 'no' );
71
  }
72
  }
73
+
74
  /**
75
  * Returns the current Groups options and initializes them
76
  * through init() if needed.
84
  }
85
  return $options;
86
  }
87
+
88
  /**
89
  * Returns the value of a general setting.
90
  *
100
  }
101
  return $value;
102
  }
103
+
104
+
105
  /**
106
  * Returns the value of a user setting.
107
  *
127
  }
128
  return $value;
129
  }
130
+
131
  /**
132
  * Updates a general setting.
133
  *
139
  $options[self::general][$option] = $new_value;
140
  update_option( self::option_key, $options );
141
  }
142
+
143
  /**
144
  * Updates a user setting.
145
  *
148
  * @param int $user_id update option for this user, defaults to null for current user
149
  */
150
  public static function update_user_option( $option, $new_value, $user_id = null ) {
151
+
152
  if ( $user_id === null ) {
153
  $current_user = wp_get_current_user();
154
  if ( !empty( $current_user ) ) {
155
  $user_id = $current_user->ID;
156
  }
157
  }
158
+
159
  if ( $user_id !== null ) {
160
  $options = self::get_options();
161
  $options[$user_id][$option] = $new_value;
162
  update_option( self::option_key, $options );
163
  }
164
  }
165
+
166
  /**
167
  * Deletes a general setting.
168
  *
175
  update_option( self::option_key, $options );
176
  }
177
  }
178
+
179
  /**
180
  * Deletes a user setting.
181
  *
183
  * @param int $user_id delete option for this user, defaults to null for current user
184
  */
185
  public static function delete_user_option( $option, $user_id = null ) {
186
+
187
  if ( $user_id === null ) {
188
  $current_user = wp_get_current_user();
189
  if ( !empty( $current_user ) ) {
190
  $user_id = $current_user->ID;
191
  }
192
  }
193
+
194
  if ( $user_id !== null ) {
195
  $options = self::get_options();
196
  if ( isset( $options[$user_id][$option] ) ) {
199
  }
200
  }
201
  }
202
+
203
  /**
204
  * Deletes all settings - this includes user and general options.
205
  */
lib/core/class-groups-user-capability.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * User Capability OPM.
28
  */
29
  class Groups_User_Capability {
30
-
31
  /**
32
  * Hook into appropriate actions.
33
  *
@@ -42,7 +42,7 @@ class Groups_User_Capability {
42
  // when a capability is deleted the relationship must also be resolved
43
  add_action( 'groups_deleted_capability', array( __CLASS__, 'groups_deleted_capability' ) );
44
  }
45
-
46
  /**
47
  * Persist a user-capability relation.
48
  *
@@ -50,7 +50,7 @@ class Groups_User_Capability {
50
  * @return true on success, otherwise false
51
  */
52
  public static function create( $map ) {
53
-
54
  global $wpdb;
55
  extract( $map );
56
  $result = false;
@@ -83,7 +83,7 @@ class Groups_User_Capability {
83
  }
84
  return $result;
85
  }
86
-
87
  /**
88
  * Retrieve a user-capability relation.
89
  *
@@ -94,7 +94,7 @@ class Groups_User_Capability {
94
  public static function read( $user_id, $capability_id ) {
95
  global $wpdb;
96
  $result = false;
97
-
98
  $user_capability_table = _groups_get_tablename( 'user_capability' );
99
  $user_capability = $wpdb->get_row( $wpdb->prepare(
100
  "SELECT * FROM $user_capability_table WHERE user_id = %d AND capability_id = %d",
@@ -106,7 +106,7 @@ class Groups_User_Capability {
106
  }
107
  return $result;
108
  }
109
-
110
  /**
111
  * Update user-capability relation.
112
  *
@@ -127,7 +127,7 @@ class Groups_User_Capability {
127
  }
128
  return $result;
129
  }
130
-
131
  /**
132
  * Remove user-capability relation.
133
  *
@@ -139,7 +139,7 @@ class Groups_User_Capability {
139
 
140
  global $wpdb;
141
  $result = false;
142
-
143
  // avoid nonsense requests
144
  // if ( !empty( $user_id ) && !empty( $capability_id) ) {
145
  if ( !empty( $capability_id) ) {
@@ -160,7 +160,7 @@ class Groups_User_Capability {
160
  }
161
  return $result;
162
  }
163
-
164
  /**
165
  * Hooks into the deleted_user action to remove the deleted user from
166
  * all capabilities it is related to.
@@ -169,7 +169,7 @@ class Groups_User_Capability {
169
  */
170
  public static function deleted_user( $user_id ) {
171
  global $wpdb;
172
-
173
  $user_capability_table = _groups_get_tablename( "user_capability" );
174
  $rows = $wpdb->get_results( $wpdb->prepare(
175
  "SELECT * FROM $user_capability_table WHERE user_id = %d",
@@ -183,7 +183,7 @@ class Groups_User_Capability {
183
  }
184
  }
185
  }
186
-
187
  /**
188
  * Hooks into groups_deleted_capability to resolve all existing relations
189
  * between users and the deleted capability.
27
  * User Capability OPM.
28
  */
29
  class Groups_User_Capability {
30
+
31
  /**
32
  * Hook into appropriate actions.
33
  *
42
  // when a capability is deleted the relationship must also be resolved
43
  add_action( 'groups_deleted_capability', array( __CLASS__, 'groups_deleted_capability' ) );
44
  }
45
+
46
  /**
47
  * Persist a user-capability relation.
48
  *
50
  * @return true on success, otherwise false
51
  */
52
  public static function create( $map ) {
53
+
54
  global $wpdb;
55
  extract( $map );
56
  $result = false;
83
  }
84
  return $result;
85
  }
86
+
87
  /**
88
  * Retrieve a user-capability relation.
89
  *
94
  public static function read( $user_id, $capability_id ) {
95
  global $wpdb;
96
  $result = false;
97
+
98
  $user_capability_table = _groups_get_tablename( 'user_capability' );
99
  $user_capability = $wpdb->get_row( $wpdb->prepare(
100
  "SELECT * FROM $user_capability_table WHERE user_id = %d AND capability_id = %d",
106
  }
107
  return $result;
108
  }
109
+
110
  /**
111
  * Update user-capability relation.
112
  *
127
  }
128
  return $result;
129
  }
130
+
131
  /**
132
  * Remove user-capability relation.
133
  *
139
 
140
  global $wpdb;
141
  $result = false;
142
+
143
  // avoid nonsense requests
144
  // if ( !empty( $user_id ) && !empty( $capability_id) ) {
145
  if ( !empty( $capability_id) ) {
160
  }
161
  return $result;
162
  }
163
+
164
  /**
165
  * Hooks into the deleted_user action to remove the deleted user from
166
  * all capabilities it is related to.
169
  */
170
  public static function deleted_user( $user_id ) {
171
  global $wpdb;
172
+
173
  $user_capability_table = _groups_get_tablename( "user_capability" );
174
  $rows = $wpdb->get_results( $wpdb->prepare(
175
  "SELECT * FROM $user_capability_table WHERE user_id = %d",
183
  }
184
  }
185
  }
186
+
187
  /**
188
  * Hooks into groups_deleted_capability to resolve all existing relations
189
  * between users and the deleted capability.
lib/core/class-groups-user-group.php CHANGED
@@ -27,12 +27,12 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * User Group OPM.
28
  */
29
  class Groups_User_Group {
30
-
31
  /**
32
  * @var persisted object
33
  */
34
  var $user_group = null;
35
-
36
  /**
37
  * Hook into appropriate actions.
38
  * @see wp_delete_user()
@@ -42,12 +42,12 @@ class Groups_User_Group {
42
  // when a user is deleted, it must be removed from all groups it
43
  // belongs to - triggered by wp_delete_user() and wpmu_delete_user()
44
  add_action( "deleted_user", array( __CLASS__, "deleted_user" ) );
45
-
46
  // when a user is removed from a blog, the user must be removed
47
  // from all groups in that blog that it belongs to
48
  add_action( "remove_user_from_blog", array( __CLASS__, "remove_user_from_blog" ), 10, 2 );
49
  }
50
-
51
  /**
52
  * Create by user and group id.
53
  * Must have been persisted.
@@ -57,7 +57,7 @@ class Groups_User_Group {
57
  public function __construct( $user_id, $group_id ) {
58
  $this->user_group = self::read( $user_id, $group_id );
59
  }
60
-
61
  /**
62
  * Retrieve a property by name.
63
  *
@@ -80,7 +80,7 @@ class Groups_User_Group {
80
  }
81
  return $result;
82
  }
83
-
84
  /**
85
  * Persist a user-group relation.
86
  *
@@ -127,7 +127,7 @@ class Groups_User_Group {
127
  }
128
  return $result;
129
  }
130
-
131
  /**
132
  * Retrieve a user-group relation.
133
  *
@@ -138,7 +138,7 @@ class Groups_User_Group {
138
  public static function read( $user_id, $group_id ) {
139
  global $wpdb;
140
  $result = false;
141
-
142
  $user_group_table = _groups_get_tablename( 'user_group' );
143
  $user_group = $wpdb->get_row( $wpdb->prepare(
144
  "SELECT * FROM $user_group_table WHERE user_id = %d AND group_id = %d",
@@ -150,7 +150,7 @@ class Groups_User_Group {
150
  }
151
  return $result;
152
  }
153
-
154
  /**
155
  * Update user-group relation.
156
  *
@@ -172,7 +172,7 @@ class Groups_User_Group {
172
  }
173
  return $result;
174
  }
175
-
176
  /**
177
  * Remove user-group relation.
178
  *
@@ -184,7 +184,7 @@ class Groups_User_Group {
184
 
185
  global $wpdb;
186
  $result = false;
187
-
188
  // avoid nonsense requests
189
  // if ( !empty( $user_id ) && !empty( $group_id ) ) {
190
  if ( !empty( $group_id ) ) {
@@ -205,7 +205,7 @@ class Groups_User_Group {
205
  }
206
  return $result;
207
  }
208
-
209
  /**
210
  * Hooks into the deleted_user action to remove the deleted user from
211
  * all groups it belongs to.
@@ -214,7 +214,7 @@ class Groups_User_Group {
214
  */
215
  public static function deleted_user( $user_id ) {
216
  global $wpdb;
217
-
218
  $user_group_table = _groups_get_tablename( "user_group" );
219
  $rows = $wpdb->get_results( $wpdb->prepare(
220
  "SELECT * FROM $user_group_table WHERE user_id = %d",
@@ -228,7 +228,7 @@ class Groups_User_Group {
228
  }
229
  }
230
  }
231
-
232
  /**
233
  * Hooks into the remove_user_from_blog action to remove the user
234
  * from groups that belong to that blog.
@@ -240,13 +240,13 @@ class Groups_User_Group {
240
  * @param int $blog_id
241
  */
242
  public static function remove_user_from_blog( $user_id, $blog_id ) {
243
-
244
  if ( is_multisite() ) {
245
  Groups_Controller::switch_to_blog( $blog_id );
246
  }
247
-
248
  global $wpdb;
249
-
250
  $group_table = _groups_get_tablename( "group" );
251
  $user_group_table = _groups_get_tablename( "user_group" );
252
  // We can end up here while a blog is being deleted, in that case,
@@ -254,7 +254,7 @@ class Groups_User_Group {
254
  if ( ( $wpdb->get_var( "SHOW TABLES LIKE '" . $group_table . "'" ) == $group_table ) &&
255
  ( $wpdb->get_var( "SHOW TABLES LIKE '" . $user_group_table . "'" ) == $user_group_table )
256
  ) {
257
-
258
  $rows = $wpdb->get_results( $wpdb->prepare(
259
  "SELECT * FROM $user_group_table
260
  LEFT JOIN $group_table ON $user_group_table.group_id = $group_table.group_id
@@ -268,9 +268,9 @@ class Groups_User_Group {
268
  self::delete( $row->user_id, $row->group_id );
269
  }
270
  }
271
-
272
  }
273
-
274
  if ( is_multisite() ) {
275
  Groups_Controller::restore_current_blog();
276
  }
27
  * User Group OPM.
28
  */
29
  class Groups_User_Group {
30
+
31
  /**
32
  * @var persisted object
33
  */
34
  var $user_group = null;
35
+
36
  /**
37
  * Hook into appropriate actions.
38
  * @see wp_delete_user()
42
  // when a user is deleted, it must be removed from all groups it
43
  // belongs to - triggered by wp_delete_user() and wpmu_delete_user()
44
  add_action( "deleted_user", array( __CLASS__, "deleted_user" ) );
45
+
46
  // when a user is removed from a blog, the user must be removed
47
  // from all groups in that blog that it belongs to
48
  add_action( "remove_user_from_blog", array( __CLASS__, "remove_user_from_blog" ), 10, 2 );
49
  }
50
+
51
  /**
52
  * Create by user and group id.
53
  * Must have been persisted.
57
  public function __construct( $user_id, $group_id ) {
58
  $this->user_group = self::read( $user_id, $group_id );
59
  }
60
+
61
  /**
62
  * Retrieve a property by name.
63
  *
80
  }
81
  return $result;
82
  }
83
+
84
  /**
85
  * Persist a user-group relation.
86
  *
127
  }
128
  return $result;
129
  }
130
+
131
  /**
132
  * Retrieve a user-group relation.
133
  *
138
  public static function read( $user_id, $group_id ) {
139
  global $wpdb;
140
  $result = false;
141
+
142
  $user_group_table = _groups_get_tablename( 'user_group' );
143
  $user_group = $wpdb->get_row( $wpdb->prepare(
144
  "SELECT * FROM $user_group_table WHERE user_id = %d AND group_id = %d",
150
  }
151
  return $result;
152
  }
153
+
154
  /**
155
  * Update user-group relation.
156
  *
172
  }
173
  return $result;
174
  }
175
+
176
  /**
177
  * Remove user-group relation.
178
  *
184
 
185
  global $wpdb;
186
  $result = false;
187
+
188
  // avoid nonsense requests
189
  // if ( !empty( $user_id ) && !empty( $group_id ) ) {
190
  if ( !empty( $group_id ) ) {
205
  }
206
  return $result;
207
  }
208
+
209
  /**
210
  * Hooks into the deleted_user action to remove the deleted user from
211
  * all groups it belongs to.
214
  */
215
  public static function deleted_user( $user_id ) {
216
  global $wpdb;
217
+
218
  $user_group_table = _groups_get_tablename( "user_group" );
219
  $rows = $wpdb->get_results( $wpdb->prepare(
220
  "SELECT * FROM $user_group_table WHERE user_id = %d",
228
  }
229
  }
230
  }
231
+
232
  /**
233
  * Hooks into the remove_user_from_blog action to remove the user
234
  * from groups that belong to that blog.
240
  * @param int $blog_id
241
  */
242
  public static function remove_user_from_blog( $user_id, $blog_id ) {
243
+
244
  if ( is_multisite() ) {
245
  Groups_Controller::switch_to_blog( $blog_id );
246
  }
247
+
248
  global $wpdb;
249
+
250
  $group_table = _groups_get_tablename( "group" );
251
  $user_group_table = _groups_get_tablename( "user_group" );
252
  // We can end up here while a blog is being deleted, in that case,
254
  if ( ( $wpdb->get_var( "SHOW TABLES LIKE '" . $group_table . "'" ) == $group_table ) &&
255
  ( $wpdb->get_var( "SHOW TABLES LIKE '" . $user_group_table . "'" ) == $user_group_table )
256
  ) {
257
+
258
  $rows = $wpdb->get_results( $wpdb->prepare(
259
  "SELECT * FROM $user_group_table
260
  LEFT JOIN $group_table ON $user_group_table.group_id = $group_table.group_id
268
  self::delete( $row->user_id, $row->group_id );
269
  }
270
  }
271
+
272
  }
273
+
274
  if ( is_multisite() ) {
275
  Groups_Controller::restore_current_blog();
276
  }
lib/core/class-groups-user.php CHANGED
@@ -445,7 +445,7 @@ class Groups_User implements I_Capable {
445
  }
446
  }
447
  }
448
-
449
  }
450
  }
451
  Groups_Cache::set( self::CAPABILITIES . $this->user->ID, $capabilities, self::CACHE_GROUP );
445
  }
446
  }
447
  }
448
+
449
  }
450
  }
451
  Groups_Cache::set( self::CAPABILITIES . $this->user->ID, $capabilities, self::CACHE_GROUP );
lib/core/class-groups-utility.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Utility functions.
28
  */
29
  class Groups_Utility {
30
-
31
  /**
32
  * Checks an id (0 is accepted => anonymous).
33
  *
@@ -45,7 +45,7 @@ class Groups_Utility {
45
  }
46
  return $result;
47
  }
48
-
49
  /**
50
  * Returns an array of blog_ids for current blogs.
51
  * @return array of int with blog ids
@@ -68,12 +68,12 @@ class Groups_Utility {
68
  }
69
  return $result;
70
  }
71
-
72
-
73
  public static function get_group_tree( &$tree = null ) {
74
  global $wpdb;
75
  $group_table = _groups_get_tablename( 'group' );
76
-
77
  if ( $tree === null ) {
78
  $tree = array();
79
  $root_groups = $wpdb->get_results( "SELECT group_id FROM $group_table WHERE parent_id IS NULL" );
@@ -96,10 +96,10 @@ class Groups_Utility {
96
  self::get_group_tree( $tree[$group_id] );
97
  }
98
  }
99
-
100
  return $tree;
101
  }
102
-
103
  public static function render_group_tree( &$tree, &$output ) {
104
  $output .= '<ul style="padding-left:1em">';
105
  foreach( $tree as $group_id => $nodes ) {
27
  * Utility functions.
28
  */
29
  class Groups_Utility {
30
+
31
  /**
32
  * Checks an id (0 is accepted => anonymous).
33
  *
45
  }
46
  return $result;
47
  }
48
+
49
  /**
50
  * Returns an array of blog_ids for current blogs.
51
  * @return array of int with blog ids
68
  }
69
  return $result;
70
  }
71
+
72
+
73
  public static function get_group_tree( &$tree = null ) {
74
  global $wpdb;
75
  $group_table = _groups_get_tablename( 'group' );
76
+
77
  if ( $tree === null ) {
78
  $tree = array();
79
  $root_groups = $wpdb->get_results( "SELECT group_id FROM $group_table WHERE parent_id IS NULL" );
96
  self::get_group_tree( $tree[$group_id] );
97
  }
98
  }
99
+
100
  return $tree;
101
  }
102
+
103
  public static function render_group_tree( &$tree, &$output ) {
104
  $output .= '<ul style="padding-left:1em">';
105
  foreach( $tree as $group_id => $nodes ) {
lib/core/interface-i-capable.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Capable interface OPM.
28
  */
29
  interface I_Capable {
30
-
31
  /**
32
  * Finds out if I have the given capability.
33
  *
27
  * Capable interface OPM.
28
  */
29
  interface I_Capable {
30
+
31
  /**
32
  * Finds out if I have the given capability.
33
  *
lib/test/groups-tests.php CHANGED
@@ -33,17 +33,17 @@ if ( !defined( 'ABSPATH' ) ) {
33
  if ( defined( 'ABSPATH' ) ) {
34
 
35
  function groups_tests() {
36
-
37
  assert_options( ASSERT_ACTIVE, true );
38
  assert_options( ASSERT_WARNING, true );
39
  assert_options( ASSERT_BAIL, false );
40
-
41
  //
42
  // PART 1 : create test data
43
  //
44
-
45
  // *** groups ***
46
-
47
  // create valid test groups
48
  //
49
  // Fruits [dance] {foo}
@@ -54,7 +54,7 @@ if ( defined( 'ABSPATH' ) ) {
54
  //
55
  // All groups can dance.
56
  // Only Sour and Lemon can sing.
57
- $fruits_group_id = Groups_Group::create( array( 'name' => 'Fruits' ) );
58
  assert( '$fruits_group_id !== false' );
59
  $sweet_group_id = Groups_Group::create( array( 'name' => 'Sweet', 'parent_id' => $fruits_group_id ) );
60
  assert( '$sweet_group_id !== false' );
@@ -64,43 +64,43 @@ if ( defined( 'ABSPATH' ) ) {
64
  assert( '$lemon_group_id !== false' );
65
  $banana_group_id = Groups_Group::create( array( 'name' => 'Banana', 'parent_id' => $sweet_group_id ) );
66
  assert( '$banana_group_id !== false' );
67
-
68
  // fail to create group with missing name
69
  $bogus_group_id = Groups_Group::create( array( ) );
70
  assert( '$bogus_group_id === false; /* empty name */' );
71
-
72
  // fail to create group with wrong parent_id
73
  $bogus_group_id = Groups_Group::create( array( 'name' => 'bogus', 'parent_id' => -1 ) );
74
  assert( '$bogus_group_id === false; /* wrong parent_id */' );
75
-
76
  // *** capabilities ***
77
  $sing_capability_id = Groups_Capability::create( array( 'capability' => 'sing' ) );
78
  assert( '$sing_capability_id !== false' );
79
-
80
  $dance_capability_id = Groups_Capability::create( array( 'capability' => 'dance' ) );
81
  assert( '$dance_capability_id !== false' );
82
-
83
  $clap_capability_id = Groups_Capability::create( array( 'capability' => 'clap' ) );
84
  assert( '$clap_capability_id !== false' );
85
-
86
  // read capability by id
87
  assert( 'Groups_Capability::read( $sing_capability_id )' );
88
-
89
  // read capability by unique label
90
  assert( 'Groups_Capability::read_by_capability( "dance" )' );
91
-
92
-
93
  // *** users ***
94
-
95
  // create test users
96
  $fooname = 'foo' . rand(0, 100);
97
  $foo_user_id = wp_create_user( $fooname, 'foo', $fooname . '@example.com' );
98
  assert( '$foo_user_id instanceof WP_Error === false');
99
-
100
  $barname = 'bar' . rand(0, 100);
101
  $bar_user_id = wp_create_user( $barname, 'bar', $barname . '@example.com' );
102
  assert( '$bar_user_id instanceof WP_Error === false');
103
-
104
  // this user is used to test the automatic resolution of its relationship
105
  // with the banana group when the group is deleted
106
  // it's also used to test automatic resolution of its "clap" capability
@@ -108,12 +108,12 @@ if ( defined( 'ABSPATH' ) ) {
108
  $bazname = 'baz' . rand(0, 100);
109
  $baz_user_id = wp_create_user( $bazname, 'baz', $bazname . '@example.com' );
110
  assert( '$baz_user_id instanceof WP_Error === false');
111
-
112
  // this user is deleted, the group relation must be deleted automatically
113
  $dolname = 'dol' . rand(0, 100);
114
  $dol_user_id = wp_create_user( $dolname, 'dol', $dolname . ' @example.com' );
115
  assert( '$dol_user_id instanceof WP_Error === false');
116
-
117
  // this user is a simple editor, used to test WordPress capabilities
118
  $editorname = 'rotide' . rand(0, 100);
119
  $editor_user_id = wp_create_user( $editorname, 'rotide', $editorname . '@example.com' );
@@ -124,30 +124,30 @@ if ( defined( 'ABSPATH' ) ) {
124
  } else {
125
  $editor_user_id = false;
126
  }
127
-
128
  // *** users & groups ***
129
-
130
  // add valid users to groups
131
  // echo "foo user id: $foo_user_id group: $fruits_group_id<br/>";
132
  assert( 'Groups_User_Group::create(array( "user_id" => $foo_user_id, "group_id" => $fruits_group_id ) )' );
133
  assert( 'Groups_User_Group::create(array( "user_id" => $bar_user_id, "group_id" => $lemon_group_id ) )' );
134
  assert( 'Groups_User_Group::create(array( "user_id" => $baz_user_id, "group_id" => $banana_group_id ) )' );
135
  assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => $sweet_group_id ) )' );
136
-
137
  // add invalid user to group
138
  assert( 'Groups_User_Group::create(array( "user_id" => -1, "group_id" => $sweet_group_id ) ) === false' );
139
-
140
  // add valid user to invalid group
141
  assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => -1 ) ) === false' );
142
-
143
  // define capabilities for groups
144
  assert( 'Groups_Group_Capability::create( array( "group_id" => $fruits_group_id, "capability_id" => $dance_capability_id ) )' );
145
  assert( 'Groups_Group_Capability::create( array( "group_id" => $sour_group_id, "capability_id" => $sing_capability_id ) )' );
146
-
147
  // define capabilities for users
148
  assert( 'Groups_User_Capability::create( array( "user_id" => $foo_user_id, "capability_id" => $clap_capability_id ) )' );
149
  assert( 'Groups_User_Capability::create( array( "user_id" => $baz_user_id, "capability_id" => $clap_capability_id ) )' );
150
-
151
  // check groups that can dance (all)
152
  // just reading will not check the hierarchy of course ...
153
  assert( 'Groups_Group_Capability::read( $fruits_group_id, $dance_capability_id )' );
@@ -161,14 +161,14 @@ if ( defined( 'ABSPATH' ) ) {
161
  assert( 'Groups_Group_Capability::read( $banana_group_id, $sing_capability_id ) === false' );
162
  assert( 'Groups_Group_Capability::read( $sour_group_id, $sing_capability_id )' );
163
  assert( 'Groups_Group_Capability::read( $lemon_group_id, $sing_capability_id ) === false' );
164
-
165
  // hierarchical groups
166
  $fruits_group = new Groups_Group( $fruits_group_id );
167
  $sweet_group = new Groups_Group( $sweet_group_id );
168
  $banana_group = new Groups_Group( $banana_group_id );
169
  $sour_group = new Groups_Group( $sour_group_id );
170
  $lemon_group = new Groups_Group( $lemon_group_id );
171
-
172
  // retrieve users
173
  assert( 'count( $fruits_group->users ) > 0' );
174
 
@@ -184,7 +184,7 @@ if ( defined( 'ABSPATH' ) ) {
184
  assert( '$banana_group->can( $dance_capability_id )' );
185
  assert( '$sour_group->can( $dance_capability_id )' );
186
  assert( '$lemon_group->can( $dance_capability_id )' );
187
-
188
  // only sour and lemon can sing:
189
  assert( '!$fruits_group->can( "sing" )' );
190
  assert( '!$sweet_group->can( "sing" )' );
@@ -197,85 +197,85 @@ if ( defined( 'ABSPATH' ) ) {
197
  assert( '!$banana_group->can( $sing_capability_id )' );
198
  assert( '$sour_group->can( $sing_capability_id )' );
199
  assert( '$lemon_group->can( $sing_capability_id )' );
200
-
201
  // no group can clap
202
  assert( '!$fruits_group->can( $clap_capability_id )' );
203
  assert( '!$sweet_group->can( $clap_capability_id )' );
204
  assert( '!$banana_group->can( $clap_capability_id )' );
205
  assert( '!$sour_group->can( $clap_capability_id )' );
206
  assert( '!$lemon_group->can( $clap_capability_id )' );
207
-
208
  // user capabilities
209
  $foo = new Groups_User( $foo_user_id );
210
  $dol = new Groups_User( $dol_user_id );
211
  $baz = new Groups_User( $baz_user_id );
212
  $bar = new Groups_User( $bar_user_id );
213
-
214
  assert( '$foo->can( "dance" )' );
215
  assert( '$dol->can( "dance" )' );
216
  assert( '$baz->can( "dance" )' );
217
  assert( '$bar->can( "dance" )' );
218
-
219
  assert( '$foo->can( $dance_capability_id )' );
220
  assert( '$dol->can( $dance_capability_id )' );
221
  assert( '$baz->can( $dance_capability_id )' );
222
  assert( '$bar->can( $dance_capability_id )' );
223
-
224
  assert( '!$foo->can( "sing" )' );
225
  assert( '!$dol->can( "sing" )' );
226
  assert( '!$baz->can( "sing" )' );
227
  assert( '$bar->can( "sing" )' );
228
-
229
  assert( '!$foo->can( $sing_capability_id )' );
230
  assert( '!$dol->can( $sing_capability_id )' );
231
  assert( '!$baz->can( $sing_capability_id )' );
232
  assert( '$bar->can( $sing_capability_id )' );
233
-
234
  // only foo & baz can clap
235
  assert( '$foo->can( "clap" )' );
236
  assert( '!$dol->can( "clap" )' );
237
  assert( '$baz->can( "clap" )' );
238
  assert( '!$bar->can( "clap" )' );
239
-
240
  assert( '$foo->can( $clap_capability_id )' );
241
  assert( '!$dol->can( $clap_capability_id )' );
242
  assert( '$baz->can( $clap_capability_id )' );
243
  assert( '!$bar->can( $clap_capability_id )' );
244
-
245
  // user can not what is not defined
246
  assert( '!$foo->can( null )' );
247
  assert( '!$dol->can( null )' );
248
  assert( '!$baz->can( null )' );
249
  assert( '!$bar->can( null )' );
250
-
251
  assert( '!$foo->can( "bogus" )' );
252
  assert( '!$dol->can( "bogus" )' );
253
  assert( '!$baz->can( "bogus" )' );
254
  assert( '!$bar->can( "bogus" )' );
255
-
256
  // groups can not what is not defined
257
  assert( '!$fruits_group->can( null )' );
258
  assert( '!$sweet_group->can( null )' );
259
  assert( '!$banana_group->can( null )' );
260
  assert( '!$sour_group->can( null )' );
261
  assert( '!$lemon_group->can( null )' );
262
-
263
  assert( '!$fruits_group->can( "bogus" )' );
264
  assert( '!$sweet_group->can( "bogus" )' );
265
  assert( '!$banana_group->can( "bogus" )' );
266
  assert( '!$sour_group->can( "bogus" )' );
267
  assert( '!$lemon_group->can( "bogus" )' );
268
-
269
  // test WordPress capabilities
270
  $administrator = new Groups_User( 1 );
271
  assert( '$administrator->can( "activate_plugins" )' );
272
-
273
  if ( $editor_user_id ) {
274
  $editor = new Groups_User( $editor_user_id );
275
  assert( '$editor->can( "edit_posts" )' );
276
  assert( '!$editor->can( "activate_plugins" )' );
277
  }
278
-
279
  if ( is_multisite() ) {
280
  // $randext = rand( 0, 100 );
281
  // $wpmu_test_user_id = wp_create_user( 'wpmu_test_user' . $randext, 'wpmu_test_user' );
@@ -287,26 +287,26 @@ if ( defined( 'ABSPATH' ) ) {
287
  // @todo check that new user is in "Registered" group
288
  // @todo switch to current blog
289
  }
290
-
291
  //
292
  // PART 2 : delete test data
293
  //
294
-
295
  if ( is_multisite() ) {
296
  // @todo delete new blog
297
  }
298
-
299
  // remove capabilities from groups
300
  assert( 'Groups_Group_Capability::delete( $fruits_group_id, $dance_capability_id )' );
301
-
302
  // remove users from groups
303
  assert( 'Groups_User_Group::delete($foo_user_id, $fruits_group_id)' );
304
  assert( 'Groups_User_Group::delete($bar_user_id, $lemon_group_id)' );
305
  // baz must be deleted from user_group when banana group is deleted
306
-
307
  // invalid remove user from group
308
  assert( 'Groups_User_Group::delete($foo_user_id, $banana_group_id) === false' );
309
-
310
  // delete test users
311
  include_once( ABSPATH . '/wp-admin/includes/user.php' );
312
  if ( $foo_user_id && !( $foo_user_id instanceof WP_Error ) ) {
@@ -327,7 +327,7 @@ if ( defined( 'ABSPATH' ) ) {
327
  }
328
  // fail to delete inexisting capabilities
329
  assert( 'Groups_Capability::delete( -1 ) === false' );
330
-
331
  // delete valid test capabilities
332
  if ( $sing_capability_id ) {
333
  assert( 'Groups_Capability::delete( $sing_capability_id ) !== false' );
@@ -342,17 +342,17 @@ if ( defined( 'ABSPATH' ) ) {
342
  if ( $baz_user_id && !( $baz_user_id instanceof WP_Error ) ) {
343
  assert( '!$baz->can( "clap" )' );
344
  }
345
-
346
  // fail to delete inexisting group
347
  assert( 'Groups_Group::delete( -1 ) === false' );
348
-
349
  // delete invalid test group if creation was successful
350
  if ( $bogus_group_id ) {
351
  assert( 'Groups_Group::delete( $bogus_group_id )' );
352
  }
353
-
354
  // delete valid test groups
355
- if ( $fruits_group_id ) {
356
  assert( 'Groups_Group::delete( $fruits_group_id )' );
357
  }
358
  if ( $sweet_group_id ) {
@@ -414,10 +414,10 @@ if ( defined( 'ABSPATH' ) ) {
414
  wp_nonce_field( 'run-tests', 'groups-test-nonce', true, true );
415
  echo '</form>';
416
  }
417
-
418
  }
419
  } else {
420
  echo 'The <i>Groups</i> plugin is not active, not running tests.';
421
  }
422
-
423
- } // ABSPATH defined
33
  if ( defined( 'ABSPATH' ) ) {
34
 
35
  function groups_tests() {
36
+
37
  assert_options( ASSERT_ACTIVE, true );
38
  assert_options( ASSERT_WARNING, true );
39
  assert_options( ASSERT_BAIL, false );
40
+
41
  //
42
  // PART 1 : create test data
43
  //
44
+
45
  // *** groups ***
46
+
47
  // create valid test groups
48
  //
49
  // Fruits [dance] {foo}
54
  //
55
  // All groups can dance.
56
  // Only Sour and Lemon can sing.
57
+ $fruits_group_id = Groups_Group::create( array( 'name' => 'Fruits' ) );
58
  assert( '$fruits_group_id !== false' );
59
  $sweet_group_id = Groups_Group::create( array( 'name' => 'Sweet', 'parent_id' => $fruits_group_id ) );
60
  assert( '$sweet_group_id !== false' );
64
  assert( '$lemon_group_id !== false' );
65
  $banana_group_id = Groups_Group::create( array( 'name' => 'Banana', 'parent_id' => $sweet_group_id ) );
66
  assert( '$banana_group_id !== false' );
67
+
68
  // fail to create group with missing name
69
  $bogus_group_id = Groups_Group::create( array( ) );
70
  assert( '$bogus_group_id === false; /* empty name */' );
71
+
72
  // fail to create group with wrong parent_id
73
  $bogus_group_id = Groups_Group::create( array( 'name' => 'bogus', 'parent_id' => -1 ) );
74
  assert( '$bogus_group_id === false; /* wrong parent_id */' );
75
+
76
  // *** capabilities ***
77
  $sing_capability_id = Groups_Capability::create( array( 'capability' => 'sing' ) );
78
  assert( '$sing_capability_id !== false' );
79
+
80
  $dance_capability_id = Groups_Capability::create( array( 'capability' => 'dance' ) );
81
  assert( '$dance_capability_id !== false' );
82
+
83
  $clap_capability_id = Groups_Capability::create( array( 'capability' => 'clap' ) );
84
  assert( '$clap_capability_id !== false' );
85
+
86
  // read capability by id
87
  assert( 'Groups_Capability::read( $sing_capability_id )' );
88
+
89
  // read capability by unique label
90
  assert( 'Groups_Capability::read_by_capability( "dance" )' );
91
+
92
+
93
  // *** users ***
94
+
95
  // create test users
96
  $fooname = 'foo' . rand(0, 100);
97
  $foo_user_id = wp_create_user( $fooname, 'foo', $fooname . '@example.com' );
98
  assert( '$foo_user_id instanceof WP_Error === false');
99
+
100
  $barname = 'bar' . rand(0, 100);
101
  $bar_user_id = wp_create_user( $barname, 'bar', $barname . '@example.com' );
102
  assert( '$bar_user_id instanceof WP_Error === false');
103
+
104
  // this user is used to test the automatic resolution of its relationship
105
  // with the banana group when the group is deleted
106
  // it's also used to test automatic resolution of its "clap" capability
108
  $bazname = 'baz' . rand(0, 100);
109
  $baz_user_id = wp_create_user( $bazname, 'baz', $bazname . '@example.com' );
110
  assert( '$baz_user_id instanceof WP_Error === false');
111
+
112
  // this user is deleted, the group relation must be deleted automatically
113
  $dolname = 'dol' . rand(0, 100);
114
  $dol_user_id = wp_create_user( $dolname, 'dol', $dolname . ' @example.com' );
115
  assert( '$dol_user_id instanceof WP_Error === false');
116
+
117
  // this user is a simple editor, used to test WordPress capabilities
118
  $editorname = 'rotide' . rand(0, 100);
119
  $editor_user_id = wp_create_user( $editorname, 'rotide', $editorname . '@example.com' );
124
  } else {
125
  $editor_user_id = false;
126
  }
127
+
128
  // *** users & groups ***
129
+
130
  // add valid users to groups
131
  // echo "foo user id: $foo_user_id group: $fruits_group_id<br/>";
132
  assert( 'Groups_User_Group::create(array( "user_id" => $foo_user_id, "group_id" => $fruits_group_id ) )' );
133
  assert( 'Groups_User_Group::create(array( "user_id" => $bar_user_id, "group_id" => $lemon_group_id ) )' );
134
  assert( 'Groups_User_Group::create(array( "user_id" => $baz_user_id, "group_id" => $banana_group_id ) )' );
135
  assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => $sweet_group_id ) )' );
136
+
137
  // add invalid user to group
138
  assert( 'Groups_User_Group::create(array( "user_id" => -1, "group_id" => $sweet_group_id ) ) === false' );
139
+
140
  // add valid user to invalid group
141
  assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => -1 ) ) === false' );
142
+
143
  // define capabilities for groups
144
  assert( 'Groups_Group_Capability::create( array( "group_id" => $fruits_group_id, "capability_id" => $dance_capability_id ) )' );
145
  assert( 'Groups_Group_Capability::create( array( "group_id" => $sour_group_id, "capability_id" => $sing_capability_id ) )' );
146
+
147
  // define capabilities for users
148
  assert( 'Groups_User_Capability::create( array( "user_id" => $foo_user_id, "capability_id" => $clap_capability_id ) )' );
149
  assert( 'Groups_User_Capability::create( array( "user_id" => $baz_user_id, "capability_id" => $clap_capability_id ) )' );
150
+
151
  // check groups that can dance (all)
152
  // just reading will not check the hierarchy of course ...
153
  assert( 'Groups_Group_Capability::read( $fruits_group_id, $dance_capability_id )' );
161
  assert( 'Groups_Group_Capability::read( $banana_group_id, $sing_capability_id ) === false' );
162
  assert( 'Groups_Group_Capability::read( $sour_group_id, $sing_capability_id )' );
163
  assert( 'Groups_Group_Capability::read( $lemon_group_id, $sing_capability_id ) === false' );
164
+
165
  // hierarchical groups
166
  $fruits_group = new Groups_Group( $fruits_group_id );
167
  $sweet_group = new Groups_Group( $sweet_group_id );
168
  $banana_group = new Groups_Group( $banana_group_id );
169
  $sour_group = new Groups_Group( $sour_group_id );
170
  $lemon_group = new Groups_Group( $lemon_group_id );
171
+
172
  // retrieve users
173
  assert( 'count( $fruits_group->users ) > 0' );
174
 
184
  assert( '$banana_group->can( $dance_capability_id )' );
185
  assert( '$sour_group->can( $dance_capability_id )' );
186
  assert( '$lemon_group->can( $dance_capability_id )' );
187
+
188
  // only sour and lemon can sing:
189
  assert( '!$fruits_group->can( "sing" )' );
190
  assert( '!$sweet_group->can( "sing" )' );
197
  assert( '!$banana_group->can( $sing_capability_id )' );
198
  assert( '$sour_group->can( $sing_capability_id )' );
199
  assert( '$lemon_group->can( $sing_capability_id )' );
200
+
201
  // no group can clap
202
  assert( '!$fruits_group->can( $clap_capability_id )' );
203
  assert( '!$sweet_group->can( $clap_capability_id )' );
204
  assert( '!$banana_group->can( $clap_capability_id )' );
205
  assert( '!$sour_group->can( $clap_capability_id )' );
206
  assert( '!$lemon_group->can( $clap_capability_id )' );
207
+
208
  // user capabilities
209
  $foo = new Groups_User( $foo_user_id );
210
  $dol = new Groups_User( $dol_user_id );
211
  $baz = new Groups_User( $baz_user_id );
212
  $bar = new Groups_User( $bar_user_id );
213
+
214
  assert( '$foo->can( "dance" )' );
215
  assert( '$dol->can( "dance" )' );
216
  assert( '$baz->can( "dance" )' );
217
  assert( '$bar->can( "dance" )' );
218
+
219
  assert( '$foo->can( $dance_capability_id )' );
220
  assert( '$dol->can( $dance_capability_id )' );
221
  assert( '$baz->can( $dance_capability_id )' );
222
  assert( '$bar->can( $dance_capability_id )' );
223
+
224
  assert( '!$foo->can( "sing" )' );
225
  assert( '!$dol->can( "sing" )' );
226
  assert( '!$baz->can( "sing" )' );
227
  assert( '$bar->can( "sing" )' );
228
+
229
  assert( '!$foo->can( $sing_capability_id )' );
230
  assert( '!$dol->can( $sing_capability_id )' );
231
  assert( '!$baz->can( $sing_capability_id )' );
232
  assert( '$bar->can( $sing_capability_id )' );
233
+
234
  // only foo & baz can clap
235
  assert( '$foo->can( "clap" )' );
236
  assert( '!$dol->can( "clap" )' );
237
  assert( '$baz->can( "clap" )' );
238
  assert( '!$bar->can( "clap" )' );
239
+
240
  assert( '$foo->can( $clap_capability_id )' );
241
  assert( '!$dol->can( $clap_capability_id )' );
242
  assert( '$baz->can( $clap_capability_id )' );
243
  assert( '!$bar->can( $clap_capability_id )' );
244
+
245
  // user can not what is not defined
246
  assert( '!$foo->can( null )' );
247
  assert( '!$dol->can( null )' );
248
  assert( '!$baz->can( null )' );
249
  assert( '!$bar->can( null )' );
250
+
251
  assert( '!$foo->can( "bogus" )' );
252
  assert( '!$dol->can( "bogus" )' );
253
  assert( '!$baz->can( "bogus" )' );
254
  assert( '!$bar->can( "bogus" )' );
255
+
256
  // groups can not what is not defined
257
  assert( '!$fruits_group->can( null )' );
258
  assert( '!$sweet_group->can( null )' );
259
  assert( '!$banana_group->can( null )' );
260
  assert( '!$sour_group->can( null )' );
261
  assert( '!$lemon_group->can( null )' );
262
+
263
  assert( '!$fruits_group->can( "bogus" )' );
264
  assert( '!$sweet_group->can( "bogus" )' );
265
  assert( '!$banana_group->can( "bogus" )' );
266
  assert( '!$sour_group->can( "bogus" )' );
267
  assert( '!$lemon_group->can( "bogus" )' );
268
+
269
  // test WordPress capabilities
270
  $administrator = new Groups_User( 1 );
271
  assert( '$administrator->can( "activate_plugins" )' );
272
+
273
  if ( $editor_user_id ) {
274
  $editor = new Groups_User( $editor_user_id );
275
  assert( '$editor->can( "edit_posts" )' );
276
  assert( '!$editor->can( "activate_plugins" )' );
277
  }
278
+
279
  if ( is_multisite() ) {
280
  // $randext = rand( 0, 100 );
281
  // $wpmu_test_user_id = wp_create_user( 'wpmu_test_user' . $randext, 'wpmu_test_user' );
287
  // @todo check that new user is in "Registered" group
288
  // @todo switch to current blog
289
  }
290
+
291
  //
292
  // PART 2 : delete test data
293
  //
294
+
295
  if ( is_multisite() ) {
296
  // @todo delete new blog
297
  }
298
+
299
  // remove capabilities from groups
300
  assert( 'Groups_Group_Capability::delete( $fruits_group_id, $dance_capability_id )' );
301
+
302
  // remove users from groups
303
  assert( 'Groups_User_Group::delete($foo_user_id, $fruits_group_id)' );
304
  assert( 'Groups_User_Group::delete($bar_user_id, $lemon_group_id)' );
305
  // baz must be deleted from user_group when banana group is deleted
306
+
307
  // invalid remove user from group
308
  assert( 'Groups_User_Group::delete($foo_user_id, $banana_group_id) === false' );
309
+
310
  // delete test users
311
  include_once( ABSPATH . '/wp-admin/includes/user.php' );
312
  if ( $foo_user_id && !( $foo_user_id instanceof WP_Error ) ) {
327
  }
328
  // fail to delete inexisting capabilities
329
  assert( 'Groups_Capability::delete( -1 ) === false' );
330
+
331
  // delete valid test capabilities
332
  if ( $sing_capability_id ) {
333
  assert( 'Groups_Capability::delete( $sing_capability_id ) !== false' );
342
  if ( $baz_user_id && !( $baz_user_id instanceof WP_Error ) ) {
343
  assert( '!$baz->can( "clap" )' );
344
  }
345
+
346
  // fail to delete inexisting group
347
  assert( 'Groups_Group::delete( -1 ) === false' );
348
+
349
  // delete invalid test group if creation was successful
350
  if ( $bogus_group_id ) {
351
  assert( 'Groups_Group::delete( $bogus_group_id )' );
352
  }
353
+
354
  // delete valid test groups
355
+ if ( $fruits_group_id ) {
356
  assert( 'Groups_Group::delete( $fruits_group_id )' );
357
  }
358
  if ( $sweet_group_id ) {
414
  wp_nonce_field( 'run-tests', 'groups-test-nonce', true, true );
415
  echo '</form>';
416
  }
417
+
418
  }
419
  } else {
420
  echo 'The <i>Groups</i> plugin is not active, not running tests.';
421
  }
422
+
423
+ } // ABSPATH defined
lib/views/class-groups-shortcodes.php CHANGED
@@ -27,7 +27,7 @@ if ( !defined( 'ABSPATH' ) ) {
27
  * Shortcode handlers
28
  */
29
  class Groups_Shortcodes {
30
-
31
  /**
32
  * Adds shortcodes.
33
  */
@@ -190,13 +190,13 @@ class Groups_Shortcodes {
190
  }
191
  $output .= '</ul>';
192
  }
193
-
194
  break;
195
  }
196
  }
197
  return $output;
198
  }
199
-
200
  /**
201
  * Renders the current or a specific user's groups.
202
  * Attributes:
@@ -248,7 +248,7 @@ class Groups_Shortcodes {
248
  if ( $user_id !== null ) {
249
  $user = new Groups_User( $user_id );
250
  $groups = $user->groups;
251
-
252
  if ( !empty( $groups ) ) {
253
  // group attr
254
  if ( $options['group'] !== null ) {
@@ -301,7 +301,7 @@ class Groups_Shortcodes {
301
  $groups = array_reverse( $groups );
302
  break;
303
  }
304
-
305
  switch( $options['format'] ) {
306
  case 'list' :
307
  case 'ul' :
@@ -339,7 +339,7 @@ class Groups_Shortcodes {
339
  }
340
  return $output;
341
  }
342
-
343
  /**
344
  * Group comparison by group_id.
345
  *
@@ -350,7 +350,7 @@ class Groups_Shortcodes {
350
  public static function sort_id( $a, $b ) {
351
  return $a->group_id - $b->group_id;
352
  }
353
-
354
  /**
355
  * Group comparison by name.
356
  *
27
  * Shortcode handlers
28
  */
29
  class Groups_Shortcodes {
30
+
31
  /**
32
  * Adds shortcodes.
33
  */
190
  }
191
  $output .= '</ul>';
192
  }
193
+
194
  break;
195
  }
196
  }
197
  return $output;
198
  }
199
+
200
  /**
201
  * Renders the current or a specific user's groups.
202
  * Attributes:
248
  if ( $user_id !== null ) {
249
  $user = new Groups_User( $user_id );
250
  $groups = $user->groups;
251
+
252
  if ( !empty( $groups ) ) {
253
  // group attr
254
  if ( $options['group'] !== null ) {
301
  $groups = array_reverse( $groups );
302
  break;
303
  }
304
+
305
  switch( $options['format'] ) {
306
  case 'list' :
307
  case 'ul' :
339
  }
340
  return $output;
341
  }
342
+
343
  /**
344
  * Group comparison by group_id.
345
  *
350
  public static function sort_id( $a, $b ) {
351
  return $a->group_id - $b->group_id;
352
  }
353
+
354
  /**
355
  * Group comparison by name.
356
  *
lib/wp/class-groups-wordpress.php CHANGED
@@ -95,7 +95,7 @@ class Groups_WordPress {
95
  public static function activate() {
96
  self::refresh_capabilities();
97
  }
98
-
99
  /**
100
  * Refreshes Groups capabilities based on WordPress capabilities.
101
  * @return int number of capabilities added
95
  public static function activate() {
96
  self::refresh_capabilities();
97
  }
98
+
99
  /**
100
  * Refreshes Groups capabilities based on WordPress capabilities.
101
  * @return int number of capabilities added
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Groups ===
2
- Contributors: itthinx
3
  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: 4.0
6
- Tested up to: 4.4.1
7
- Stable tag: 1.10.0
8
  License: GPLv3
9
 
10
  Groups is an efficient and powerful solution, providing group-based user membership management, group-based capabilities and content access control.
@@ -181,6 +181,14 @@ See also [Groups](http://www.itthinx.com/plugins/groups/)
181
 
182
  == Changelog ==
183
 
 
 
 
 
 
 
 
 
184
  = 1.10.0 =
185
  * Adjusted the Groups and Capabilities screens' UI elements.
186
  * Reduced the filters section footprint on the Groups screen.
@@ -515,5 +523,5 @@ Some installations wouldn't work correctly, showing no capabilities and making i
515
 
516
  == Upgrade Notice ==
517
 
518
- = 1.10.0 =
519
- This release brings several improvements to the user interface and some minor fixes.
1
  === Groups ===
2
+ Contributors: itthinx, proaktion
3
  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: 4.0
6
+ Tested up to: 4.4.2
7
+ Stable tag: 1.10.1
8
  License: GPLv3
9
 
10
  Groups is an efficient and powerful solution, providing group-based user membership management, group-based capabilities and content access control.
181
 
182
  == Changelog ==
183
 
184
+ = 1.10.1 =
185
+ * Fixed the French translation which introduced incorrect markup breaking the help button.
186
+ * Added the groups_admin_groups_add_form_after_fields filter.
187
+ * Added the groups_admin_groups_add_submit_success action.
188
+ * Added the groups_admin_groups_edit_form_after_fields filter.
189
+ * Added the groups_admin_groups_edit_submit_success action.
190
+ * Fixed some code formatting (tabs).
191
+
192
  = 1.10.0 =
193
  * Adjusted the Groups and Capabilities screens' UI elements.
194
  * Reduced the filters section footprint on the Groups screen.
523
 
524
  == Upgrade Notice ==
525
 
526
+ = 1.10.1 =
527
+ This release fixes the French translation and adds some administrative actions and filters.