Groups - Version 1.1.4

Version Description

  • Reduced plugin admin footer.
Download this release

Release Info

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

Code changes from version 1.0.0-beta-3d to 1.1.4

css/groups_admin.css CHANGED
@@ -88,3 +88,13 @@ div.capability.edit label.description-field {
88
  background: url(../images/required.png) transparent no-repeat left center;
89
  padding-left: 16px ! important;
90
  }
 
 
 
 
 
 
 
 
 
 
88
  background: url(../images/required.png) transparent no-repeat left center;
89
  padding-left: 16px ! important;
90
  }
91
+ div.groups-footer {
92
+ padding-top: 4px;
93
+ color: #999;
94
+ }
95
+ div.groups-footer a {
96
+ color: #777;
97
+ }
98
+ div.groups-footer form {
99
+ display: inline;
100
+ }
groups.php CHANGED
@@ -21,13 +21,13 @@
21
  * Plugin Name: Groups
22
  * Plugin URI: http://www.itthinx.com/plugins/groups
23
  * Description: Groups provides group-based user membership management, group-based capabilities and content access control.
24
- * Version: 1.0.0-beta-3d
25
- * Author: itthinx (Karim Rahimpur)
26
  * Author URI: http://www.itthinx.com
27
  * Donate-Link: http://www.itthinx.com
28
  * License: GPLv3
29
  */
30
- define( 'GROUPS_CORE_VERSION', '1.0.0-beta-3d' );
31
  define( 'GROUPS_FILE', __FILE__ );
32
  if ( !defined( 'GROUPS_CORE_DIR' ) ) {
33
  define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
21
  * Plugin Name: Groups
22
  * Plugin URI: http://www.itthinx.com/plugins/groups
23
  * Description: Groups provides group-based user membership management, group-based capabilities and content access control.
24
+ * Version: 1.1.4
25
+ * Author: itthinx
26
  * Author URI: http://www.itthinx.com
27
  * Donate-Link: http://www.itthinx.com
28
  * License: GPLv3
29
  */
30
+ define( 'GROUPS_CORE_VERSION', '1.1.4' );
31
  define( 'GROUPS_FILE', __FILE__ );
32
  if ( !defined( 'GROUPS_CORE_DIR' ) ) {
33
  define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
lib/admin/class-groups-admin-users.php CHANGED
@@ -42,9 +42,11 @@ class Groups_Admin_Users {
42
  add_filter( 'manage_users_custom_column', array( __CLASS__, 'manage_users_custom_column' ), 10, 3 );
43
  }
44
  if ( current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
45
- add_action( 'admin_head', array( __CLASS__, 'admin_head' ) );
46
- // allow to add or remove selected users to groups
47
- add_action( 'load-users.php', array( __CLASS__, 'load_users' ) );
 
 
48
  }
49
  }
50
 
42
  add_filter( 'manage_users_custom_column', array( __CLASS__, 'manage_users_custom_column' ), 10, 3 );
43
  }
44
  if ( current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
45
+ if ( !is_network_admin() ) {
46
+ add_action( 'admin_head', array( __CLASS__, 'admin_head' ) );
47
+ // allow to add or remove selected users to groups
48
+ add_action( 'load-users.php', array( __CLASS__, 'load_users' ) );
49
+ }
50
  }
51
  }
52
 
lib/admin/class-groups-admin.php CHANGED
@@ -23,6 +23,7 @@ class Groups_Admin {
23
  add_action( 'admin_init', array( __CLASS__, 'admin_init' ) );
24
  add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
25
  add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
 
26
  }
27
 
28
  /**
@@ -133,5 +134,30 @@ class Groups_Admin {
133
 
134
  do_action( 'groups_admin_menu', $pages );
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
  Groups_Admin::init();
23
  add_action( 'admin_init', array( __CLASS__, 'admin_init' ) );
24
  add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
25
  add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
26
+ add_action( 'network_admin_menu', array( __CLASS__, 'network_admin_menu' ) );
27
  }
28
 
29
  /**
134
 
135
  do_action( 'groups_admin_menu', $pages );
136
  }
137
+
138
+ /**
139
+ * Network admin menu.
140
+ */
141
+ public static function network_admin_menu() {
142
+
143
+ include_once( GROUPS_ADMIN_LIB . '/groups-admin-options.php');
144
+
145
+ $pages = array();
146
+
147
+ // main
148
+ $page = add_menu_page(
149
+ __( 'Groups', GROUPS_PLUGIN_DOMAIN ),
150
+ __( 'Groups', GROUPS_PLUGIN_DOMAIN ),
151
+ GROUPS_ADMINISTER_GROUPS,
152
+ 'groups-network-admin',
153
+ apply_filters( 'groups_add_menu_page_function', 'groups_network_admin_options' ),
154
+ GROUPS_PLUGIN_URL . '/images/groups.png'
155
+ );
156
+ $pages[] = $page;
157
+ add_action( 'admin_print_styles-' . $page, array( __CLASS__, 'admin_print_styles' ) );
158
+ add_action( 'admin_print_scripts-' . $page, array( __CLASS__, 'admin_print_scripts' ) );
159
+
160
+ do_action( 'groups_network_admin_menu', $pages );
161
+ }
162
  }
163
  Groups_Admin::init();
lib/admin/groups-admin-options.php CHANGED
@@ -32,6 +32,13 @@ function groups_admin_options() {
32
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
33
  }
34
 
 
 
 
 
 
 
 
35
  echo
36
  '<div>' .
37
  '<h2>' .
@@ -83,11 +90,13 @@ function groups_admin_options() {
83
  }
84
  Groups_Controller::assure_capabilities();
85
 
86
- // delete data
87
- if ( !empty( $_POST['delete-data'] ) ) {
88
- Groups_Options::update_option( 'groups_delete_data', true );
89
- } else {
90
- Groups_Options::update_option( 'groups_delete_data', false );
 
 
91
  }
92
  }
93
  }
@@ -164,16 +173,18 @@ function groups_admin_options() {
164
  __( 'A minimum set of permissions will be preserved.', GROUPS_PLUGIN_DOMAIN ) .
165
  '<br/>' .
166
  __( 'If you lock yourself out, please ask an administrator to help.', GROUPS_PLUGIN_DOMAIN ) .
167
- '</p>';
168
- echo
 
169
  '<h3>' . __( 'Deactivation and data persistence', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
170
  '<p>' .
171
  '<input name="delete-data" type="checkbox" ' . ( $delete_data ? 'checked="checked"' : '' ) . '/>' .
172
- '<label for="delete-data">' . __( 'Delete all plugin data on deactivation', GROUPS_PLUGIN_DOMAIN ) . '</label>' .
173
  '</p>' .
174
  '<p class="description warning">' .
175
  __( 'CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', GROUPS_PLUGIN_DOMAIN ) .
176
  '</p>';
 
177
  echo
178
  '<p>' .
179
  wp_nonce_field( 'admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false ) .
@@ -183,4 +194,51 @@ function groups_admin_options() {
183
  '</form>';
184
  Groups_Help::footer();
185
  }
186
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
33
  }
34
 
35
+ $is_sitewide_plugin = false;
36
+ if ( is_multisite() ) {
37
+ $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
38
+ $active_sitewide_plugins = array_keys( $active_sitewide_plugins );
39
+ $is_sitewide_plugin = in_array( 'groups/groups.php', $active_sitewide_plugins );
40
+ }
41
+
42
  echo
43
  '<div>' .
44
  '<h2>' .
90
  }
91
  Groups_Controller::assure_capabilities();
92
 
93
+ if ( !$is_sitewide_plugin ) {
94
+ // delete data
95
+ if ( !empty( $_POST['delete-data'] ) ) {
96
+ Groups_Options::update_option( 'groups_delete_data', true );
97
+ } else {
98
+ Groups_Options::update_option( 'groups_delete_data', false );
99
+ }
100
  }
101
  }
102
  }
173
  __( 'A minimum set of permissions will be preserved.', GROUPS_PLUGIN_DOMAIN ) .
174
  '<br/>' .
175
  __( 'If you lock yourself out, please ask an administrator to help.', GROUPS_PLUGIN_DOMAIN ) .
176
+ '</p>';
177
+ if ( !$is_sitewide_plugin ) {
178
+ echo
179
  '<h3>' . __( 'Deactivation and data persistence', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
180
  '<p>' .
181
  '<input name="delete-data" type="checkbox" ' . ( $delete_data ? 'checked="checked"' : '' ) . '/>' .
182
+ '<label for="delete-data">' . __( 'Delete all Groups plugin data on deactivation', GROUPS_PLUGIN_DOMAIN ) . '</label>' .
183
  '</p>' .
184
  '<p class="description warning">' .
185
  __( 'CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', GROUPS_PLUGIN_DOMAIN ) .
186
  '</p>';
187
+ }
188
  echo
189
  '<p>' .
190
  wp_nonce_field( 'admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false ) .
194
  '</form>';
195
  Groups_Help::footer();
196
  }
197
+
198
+ function groups_network_admin_options() {
199
+
200
+ if ( !current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
201
+ wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
202
+ }
203
+
204
+ echo
205
+ '<div>' .
206
+ '<h2>' .
207
+ __( 'Groups network options', GROUPS_PLUGIN_DOMAIN ) .
208
+ '</h2>' .
209
+ '</div>';
210
+
211
+ // handle options form submission
212
+ if ( isset( $_POST['submit'] ) ) {
213
+ if ( wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) {
214
+ // delete data
215
+ if ( !empty( $_POST['delete-data'] ) ) {
216
+ Groups_Options::update_option( 'groups_network_delete_data', true );
217
+ } else {
218
+ Groups_Options::update_option( 'groups_network_delete_data', false );
219
+ }
220
+ }
221
+ }
222
+
223
+ $delete_data = Groups_Options::get_option( 'groups_network_delete_data', false );
224
+
225
+ // options form
226
+ echo
227
+ '<form action="" name="options" method="post">' .
228
+ '<div>' .
229
+ '<h3>' . __( 'Network deactivation and data persistence', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
230
+ '<p>' .
231
+ '<input name="delete-data" type="checkbox" ' . ( $delete_data ? 'checked="checked"' : '' ) . '/>' .
232
+ '<label for="delete-data">' . __( 'Delete all Groups plugin data for ALL sites on network deactivation', GROUPS_PLUGIN_DOMAIN ) . '</label>' .
233
+ '</p>' .
234
+ '<p class="description warning">' .
235
+ __( 'CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED for <strong>all sites</strong>. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', GROUPS_PLUGIN_DOMAIN ) .
236
+ '</p>' .
237
+ '<p>' .
238
+ wp_nonce_field( 'admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false ) .
239
+ '<input type="submit" name="submit" value="' . __( 'Save', GROUPS_PLUGIN_DOMAIN ) . '"/>' .
240
+ '</p>' .
241
+ '</div>' .
242
+ '</form>';
243
+ Groups_Help::footer();
244
+ }
lib/auto/class-groups-registered.php CHANGED
@@ -85,7 +85,7 @@ class Groups_Registered {
85
  */
86
  public static function wpmu_new_blog( $blog_id, $user_id, $domain = null, $path = null, $site_id = null, $meta = null ) {
87
  if ( is_multisite() ) {
88
- switch_to_blog( $blog_id );
89
  }
90
  if ( !( $group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME ) ) ) {
91
  $group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
@@ -99,7 +99,7 @@ class Groups_Registered {
99
  }
100
  }
101
  if ( is_multisite() ) {
102
- restore_current_blog();
103
  }
104
  }
105
 
@@ -117,12 +117,26 @@ class Groups_Registered {
117
  $registered_group_id = $registered_group->group_id;
118
  }
119
  if ( $registered_group_id ) {
120
- Groups_User_Group::create(
121
- array(
122
- 'user_id' => $user_id,
123
- 'group_id' => $registered_group_id
124
- )
125
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
  }
128
 
@@ -135,7 +149,7 @@ class Groups_Registered {
135
  function add_user_to_blog( $user_id, $role, $blog_id ) {
136
 
137
  if ( is_multisite() ) {
138
- switch_to_blog( $blog_id );
139
  }
140
 
141
  global $wpdb;
@@ -166,7 +180,7 @@ class Groups_Registered {
166
  }
167
 
168
  if ( is_multisite() ) {
169
- restore_current_blog();
170
  }
171
  }
172
 
85
  */
86
  public static function wpmu_new_blog( $blog_id, $user_id, $domain = null, $path = null, $site_id = null, $meta = null ) {
87
  if ( is_multisite() ) {
88
+ Groups_Controller::switch_to_blog( $blog_id );
89
  }
90
  if ( !( $group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME ) ) ) {
91
  $group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
99
  }
100
  }
101
  if ( is_multisite() ) {
102
+ Groups_Controller::restore_current_blog();
103
  }
104
  }
105
 
117
  $registered_group_id = $registered_group->group_id;
118
  }
119
  if ( $registered_group_id ) {
120
+ // Multisite: If a new user registers with the main blog,
121
+ // the user is added, but it doesn't appear on the Users admin
122
+ // screen of the main blog. It doesn't have the Subscriber role
123
+ // (or any other) for that blog, unless it is explicitly added by the
124
+ // blog's admin to the site. In other words, a user that has just
125
+ // registered with the site's main blog can access the profile page
126
+ // on the back end, but doesn't appear as a user to the site's admin.
127
+ // Currently, on WP 3.3.2, like it or not, it's like that.
128
+ // Unless the user actually has a capability (role)
129
+ // for a blog, it won't appear in the blog's users list. After
130
+ // registering with the blog, the user does not have a capability.
131
+ // Thus, we need to check that is_user_member_of_blog( $user_id ) here.
132
+ if ( !is_multisite() || is_user_member_of_blog( $user_id ) ) {
133
+ Groups_User_Group::create(
134
+ array(
135
+ 'user_id' => $user_id,
136
+ 'group_id' => $registered_group_id
137
+ )
138
+ );
139
+ }
140
  }
141
  }
142
 
149
  function add_user_to_blog( $user_id, $role, $blog_id ) {
150
 
151
  if ( is_multisite() ) {
152
+ Groups_Controller::switch_to_blog( $blog_id );
153
  }
154
 
155
  global $wpdb;
180
  }
181
 
182
  if ( is_multisite() ) {
183
+ Groups_Controller::restore_current_blog();
184
  }
185
  }
186
 
lib/core/class-groups-controller.php CHANGED
@@ -20,6 +20,28 @@
20
  */
21
  class Groups_Controller {
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  /**
24
  * Boot the plugin.
25
  * @see Groups_Registered::wpmu_new_blog()
@@ -44,9 +66,9 @@ class Groups_Controller {
44
  if ( is_multisite() ) {
45
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
46
  if ( key_exists( 'groups/groups.php', $active_sitewide_plugins ) ) {
47
- switch_to_blog( $blog_id );
48
  self::setup();
49
- restore_current_blog();
50
  }
51
  }
52
  }
@@ -61,9 +83,9 @@ class Groups_Controller {
61
  if ( is_multisite() ) {
62
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
63
  if ( key_exists( 'groups/groups.php', $active_sitewide_plugins ) ) {
64
- switch_to_blog( $blog_id );
65
  self::cleanup( $drop );
66
- restore_current_blog();
67
  }
68
  }
69
  }
@@ -82,20 +104,16 @@ class Groups_Controller {
82
  * @param boolean $network_wide
83
  */
84
  public static function activate( $network_wide = false ) {
85
-
86
- $blog_ids = Groups_Utility::get_blogs();
87
- foreach ( $blog_ids as $blog_id ) {
88
- if ( is_multisite() && $network_wide ) {
89
- switch_to_blog( $blog_id );
 
90
  }
91
-
92
  self::setup();
93
-
94
- if ( is_multisite() && $network_wide ) {
95
- restore_current_blog();
96
- }
97
  }
98
-
99
  }
100
 
101
  /**
@@ -207,13 +225,32 @@ class Groups_Controller {
207
  $queries = array();
208
  switch ( $previous_version ) {
209
  case '1.0.0' :
210
- // fix hideously big index
211
  $capability_table = _groups_get_tablename( 'capability' );
212
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$capability_table'" ) == $capability_table ) {
 
 
 
 
 
 
 
 
213
  $queries[] = "ALTER TABLE $capability_table DROP INDEX capability_kco;";
214
  $queries[] = "ALTER TABLE $capability_table ADD INDEX capability_kco (capability(20),class(20),object(20));";
215
  }
216
  break;
 
 
 
 
 
 
 
 
 
 
 
 
217
  default :
218
  } // switch
219
  foreach ( $queries as $query ) {
@@ -229,19 +266,18 @@ class Groups_Controller {
229
  * This will happen only if the user chooses to delete data upon deactivation.
230
  * @param boolean $network_wide
231
  */
232
- public static function deactivate( $network_wide ) {
233
-
234
- $blog_ids = Groups_Utility::get_blogs();
235
- foreach ( $blog_ids as $blog_id ) {
236
- if ( is_multisite() && $network_wide ) {
237
- switch_to_blog( $blog_id );
 
 
 
238
  }
239
-
240
  self::cleanup();
241
-
242
- if ( is_multisite() && $network_wide ) {
243
- restore_current_blog();
244
- }
245
  }
246
  }
247
 
20
  */
21
  class Groups_Controller {
22
 
23
+ /**
24
+ * Cache-safe switching in case any multi-site hiccups might occur.
25
+ * Clears the cache after switching to the given blog to avoid using
26
+ * another blog's cached values.
27
+ * See wp_cache_reset() in wp-includes/cache.php
28
+ * @see wp_cache_reset()
29
+ * @link http://core.trac.wordpress.org/ticket/14941
30
+ *
31
+ * @param int $blog_id
32
+ */
33
+ public static function switch_to_blog( $blog_id ) {
34
+ switch_to_blog( $blog_id );
35
+ wp_cache_reset();
36
+ }
37
+
38
+ /**
39
+ * Switch back to previous blog.
40
+ */
41
+ public static function restore_current_blog() {
42
+ restore_current_blog();
43
+ }
44
+
45
  /**
46
  * Boot the plugin.
47
  * @see Groups_Registered::wpmu_new_blog()
66
  if ( is_multisite() ) {
67
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
68
  if ( key_exists( 'groups/groups.php', $active_sitewide_plugins ) ) {
69
+ self::switch_to_blog( $blog_id );
70
  self::setup();
71
+ self::restore_current_blog();
72
  }
73
  }
74
  }
83
  if ( is_multisite() ) {
84
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
85
  if ( key_exists( 'groups/groups.php', $active_sitewide_plugins ) ) {
86
+ self::switch_to_blog( $blog_id );
87
  self::cleanup( $drop );
88
+ self::restore_current_blog();
89
  }
90
  }
91
  }
104
  * @param boolean $network_wide
105
  */
106
  public static function activate( $network_wide = false ) {
107
+ if ( is_multisite() && $network_wide ) {
108
+ $blog_ids = Groups_Utility::get_blogs();
109
+ foreach ( $blog_ids as $blog_id ) {
110
+ self::switch_to_blog( $blog_id );
111
+ self::setup();
112
+ self::restore_current_blog();
113
  }
114
+ } else {
115
  self::setup();
 
 
 
 
116
  }
 
117
  }
118
 
119
  /**
225
  $queries = array();
226
  switch ( $previous_version ) {
227
  case '1.0.0' :
 
228
  $capability_table = _groups_get_tablename( 'capability' );
229
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$capability_table'" ) == $capability_table ) {
230
+ // increase column sizes
231
+ $queries[] = "ALTER TABLE $capability_table MODIFY capability VARCHAR(255) UNIQUE NOT NULL;";
232
+ $queries[] = "ALTER TABLE $capability_table MODIFY class VARCHAR(255) DEFAULT NULL;";
233
+ $queries[] = "ALTER TABLE $capability_table MODIFY object VARCHAR(255) DEFAULT NULL;";
234
+ // correct capabilities
235
+ $queries[] = "UPDATE $capability_table SET capability='delete_published_pages' WHERE capability='delete_published_pag';";
236
+ $queries[] = "UPDATE $capability_table SET capability='delete_published_posts' WHERE capability='delete_published_pos';";
237
+ // fix hideously big index
238
  $queries[] = "ALTER TABLE $capability_table DROP INDEX capability_kco;";
239
  $queries[] = "ALTER TABLE $capability_table ADD INDEX capability_kco (capability(20),class(20),object(20));";
240
  }
241
  break;
242
+ case '1.0.0-beta-3d' :
243
+ $capability_table = _groups_get_tablename( 'capability' );
244
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '$capability_table'" ) == $capability_table ) {
245
+ // increase column sizes
246
+ $queries[] = "ALTER TABLE $capability_table MODIFY capability VARCHAR(255) UNIQUE NOT NULL;";
247
+ $queries[] = "ALTER TABLE $capability_table MODIFY class VARCHAR(255) DEFAULT NULL;";
248
+ $queries[] = "ALTER TABLE $capability_table MODIFY object VARCHAR(255) DEFAULT NULL;";
249
+ // correct capabilities
250
+ $queries[] = "UPDATE $capability_table SET capability='delete_published_pages' WHERE capability='delete_published_pag';";
251
+ $queries[] = "UPDATE $capability_table SET capability='delete_published_posts' WHERE capability='delete_published_pos';";
252
+ }
253
+ break;
254
  default :
255
  } // switch
256
  foreach ( $queries as $query ) {
266
  * This will happen only if the user chooses to delete data upon deactivation.
267
  * @param boolean $network_wide
268
  */
269
+ public static function deactivate( $network_wide = false ) {
270
+ if ( is_multisite() && $network_wide ) {
271
+ if ( Groups_Options::get_option( 'groups_network_delete_data', false ) ) {
272
+ $blog_ids = Groups_Utility::get_blogs();
273
+ foreach ( $blog_ids as $blog_id ) {
274
+ self::switch_to_blog( $blog_id );
275
+ self::cleanup( true );
276
+ self::restore_current_blog();
277
+ }
278
  }
279
+ } else {
280
  self::cleanup();
 
 
 
 
281
  }
282
  }
283
 
lib/core/class-groups-help.php CHANGED
@@ -65,16 +65,14 @@ class Groups_Help {
65
  */
66
  public static function footer( $render = true ) {
67
  $footer = '<div class="groups-footer">' .
68
- '<p>' .
69
- __( 'Thank you for using the <a href="http://www.itthinx.com/plugins/groups" target="_blank">Groups</a> plugin by <a href="http://www.itthinx.com" target="_blank">itthinx</a>.', GROUPS_PLUGIN_DOMAIN ) .
70
- '</p>' .
71
- '<p>' .
72
- __( 'If you require <em>consulting services</em>, <em>support</em> or <em>customization</em>, you may <a href="http://www.itthinx.com/" target="_blank">contact me here</a>.', GROUPS_PLUGIN_DOMAIN ) .
73
- '</p>' .
74
- '<p>' .
75
- __( 'If you find this plugin useful, please consider making a donation:', GROUPS_PLUGIN_DOMAIN ) .
76
  self::donate( false ) .
77
- '</p>' .
78
  '</div>';
79
  $footer = apply_filters( 'groups_footer', $footer );
80
  if ( $render ) {
@@ -91,8 +89,8 @@ class Groups_Help {
91
  * @param boolean $small
92
  */
93
  public static function donate( $render = true, $small = false ) {
94
- $donate = '
95
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
96
  <input type="hidden" name="cmd" value="_donations">
97
  <input type="hidden" name="business" value="itthinx@itthinx.com">
98
  <input type="hidden" name="lc" value="US">
@@ -101,10 +99,8 @@ class Groups_Help {
101
  <input type="hidden" name="no_note" value="0">
102
  <input type="hidden" name="currency_code" value="EUR">
103
  <input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_SM.gif:NonHostedGuest">
104
- <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
105
- <img alt="" border="0" src="https://www.paypalobjects.com/es_ES/i/scr/pixel.gif" width="1" height="1">
106
- </form>
107
- ';
108
  if ( $render ) {
109
  echo $donate;
110
  } else {
65
  */
66
  public static function footer( $render = true ) {
67
  $footer = '<div class="groups-footer">' .
68
+ // '<p>' .
69
+ __( 'Thank you for using <a href="http://www.itthinx.com/plugins/groups" target="_blank">Groups</a> by <a href="http://www.itthinx.com" target="_blank">itthinx</a>.', GROUPS_PLUGIN_DOMAIN ) .
70
+ ' ' .
71
+ __( 'For consulting and development services related to Groups go <a href="http://www.itthinx.com/contact/" target="_blank">here</a>.', GROUPS_PLUGIN_DOMAIN ) .
72
+ ' ' .
73
+ __( 'You can also support the project:', GROUPS_PLUGIN_DOMAIN ) .
 
 
74
  self::donate( false ) .
75
+ // '</p>' .
76
  '</div>';
77
  $footer = apply_filters( 'groups_footer', $footer );
78
  if ( $render ) {
89
  * @param boolean $small
90
  */
91
  public static function donate( $render = true, $small = false ) {
92
+ $donate =
93
+ '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
94
  <input type="hidden" name="cmd" value="_donations">
95
  <input type="hidden" name="business" value="itthinx@itthinx.com">
96
  <input type="hidden" name="lc" value="US">
99
  <input type="hidden" name="no_note" value="0">
100
  <input type="hidden" name="currency_code" value="EUR">
101
  <input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_SM.gif:NonHostedGuest">
102
+ <input type="submit" name="submit" value="Contribute" style="border:1px solid #ccc;border-radius:4px;cursor:pointer;padding:0;margin:0;color:#999;">
103
+ </form>';
 
 
104
  if ( $render ) {
105
  echo $donate;
106
  } else {
lib/core/class-groups-user-group.php CHANGED
@@ -231,7 +231,7 @@ class Groups_User_Group {
231
  public static function remove_user_from_blog( $user_id, $blog_id ) {
232
 
233
  if ( is_multisite() ) {
234
- switch_to_blog( $blog_id );
235
  }
236
 
237
  global $wpdb;
@@ -261,7 +261,7 @@ class Groups_User_Group {
261
  }
262
 
263
  if ( is_multisite() ) {
264
- restore_current_blog();
265
  }
266
  }
267
  }
231
  public static function remove_user_from_blog( $user_id, $blog_id ) {
232
 
233
  if ( is_multisite() ) {
234
+ Groups_Controller::switch_to_blog( $blog_id );
235
  }
236
 
237
  global $wpdb;
261
  }
262
 
263
  if ( is_multisite() ) {
264
+ Groups_Controller::restore_current_blog();
265
  }
266
  }
267
  }
lib/core/class-groups-utility.php CHANGED
@@ -47,7 +47,7 @@ class Groups_Utility {
47
  $result = array();
48
  if ( is_multisite() ) {
49
  $blogs = $wpdb->get_results( $wpdb->prepare(
50
- "SELECT blog_id FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC",
51
  $wpdb->siteid
52
  ) );
53
  if ( is_array( $blogs ) ) {
47
  $result = array();
48
  if ( is_multisite() ) {
49
  $blogs = $wpdb->get_results( $wpdb->prepare(
50
+ "SELECT blog_id FROM $wpdb->blogs WHERE site_id = %d AND archived = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC",
51
  $wpdb->siteid
52
  ) );
53
  if ( is_array( $blogs ) ) {
lib/core/groups-tests.php CHANGED
@@ -381,9 +381,37 @@ if ( defined( 'ABSPATH' ) ) {
381
  if ( !current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
382
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
383
  } else {
384
- echo '<h1>Running tests for <i>Groups</i> plugin ...</h1>';
385
- groups_tests();
386
- echo '<h2>Finished.</h2>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  }
388
  } else {
389
  echo 'The <i>Groups</i> plugin is not active, not running tests.';
381
  if ( !current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
382
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
383
  } else {
384
+ $run = isset( $_POST['run'] ) ? $_POST['run'] : null;
385
+ switch( $run ) {
386
+ case 'run' :
387
+ if ( !isset( $_POST['groups-test-nonce'] ) || !wp_verify_nonce( $_POST['groups-test-nonce'], 'run-tests' ) ) {
388
+ wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
389
+ }
390
+ echo '<h1>Running tests for <i>Groups</i> plugin ...</h1>';
391
+ groups_tests();
392
+ echo '<h2>Finished.</h2>';
393
+ break;
394
+ default :
395
+ $url = get_bloginfo( 'url' );
396
+ echo '<p style="color:#f00; font-weight:bold;">';
397
+ echo 'DO NOT CONTINUE UNLESS YOU KNOW WHAT YOU ARE DOING.';
398
+ echo '</p>';
399
+ echo '<ul>';
400
+ echo '<li>This will run tests for the Groups plugin on this site.</li>';
401
+ echo '<li>Unless you are a developer who knows what she or he is doing, you do not need to do this and you do not want to proceed.</li>';
402
+ echo '<li>It may <strong>completely destroy your site</strong>.</li>';
403
+ echo '<li>Run only at your own risk, do not blame anyone if something goes wrong.</li>';
404
+ echo '<li>You <strong>agree to be solely responsible for any damage</strong> this may cause to the site.';
405
+ echo '<li>Make a full backup of your site and database before you continue.</li>';
406
+ echo '<li>If in doubt, <strong><a href="' . $url . '">do not continue</a></strong>.</li>';
407
+ echo '</ul>';
408
+ echo '<form action="" method="post">';
409
+ echo '<input name="run" value="run" type="hidden" />';
410
+ echo '<input type="submit" value="Go" />';
411
+ wp_nonce_field( 'run-tests', 'groups-test-nonce', true, true );
412
+ echo '</form>';
413
+ }
414
+
415
  }
416
  } else {
417
  echo 'The <i>Groups</i> plugin is not active, not running tests.';
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: itthinx
3
  Donate link: http://www.itthinx.com/plugins/groups
4
  Tags: access, access control, capability, capabilities, content, group, groups, member, members, membership, permission, permissions
5
  Requires at least: 3.0
6
- Tested up to: 3.3.1
7
- Stable tag: 1.0.0-beta-3d
8
 
9
  Groups provides group-based user membership management, group-based capabilities and content access control.
10
 
@@ -214,9 +214,7 @@ The documentation is a work in progress, if you don't find anything there yet bu
214
 
215
  = I have a question, where do I ask? =
216
 
217
- Please contact me at [itthinx.com](http://www.itthinx.com/).
218
-
219
- You can also leave a comment at the [Groups plugin page](http://www.itthinx.com/plugins/groups/).
220
 
221
  == Screenshots ==
222
 
@@ -232,6 +230,26 @@ See also [Groups](http://www.itthinx.com/plugins/groups/)
232
 
233
  == Changelog ==
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  = 1.0.0-beta-3d =
236
  * Fixed issues caused by an excessively long index for the capability DB table.
237
  Some installations wouldn't work correctly, showing no capabilities and making it impossible to add new ones.
@@ -257,6 +275,9 @@ Some installations wouldn't work correctly, showing no capabilities and making i
257
 
258
  == Upgrade Notice ==
259
 
 
 
 
260
  = 1.0.0-beta-3d =
261
  * The capability DB table had a ridiculously long index, this update fixes it.
262
 
@@ -281,3 +302,4 @@ Some installations wouldn't work correctly, showing no capabilities and making i
281
  The Groups plugin provides an extensive framework to handle memberships, group-based capabilities and access control.
282
  Read more on the official [Groups](http://www.itthinx.com/plugins/groups/) page and the [Groups documentation](http://www.itthinx.com/documentation/groups/) page.
283
 
 
3
  Donate link: http://www.itthinx.com/plugins/groups
4
  Tags: access, access control, capability, capabilities, content, group, groups, member, members, membership, permission, permissions
5
  Requires at least: 3.0
6
+ Tested up to: 3.3.2
7
+ Stable tag: 1.1.4
8
 
9
  Groups provides group-based user membership management, group-based capabilities and content access control.
10
 
214
 
215
  = I have a question, where do I ask? =
216
 
217
+ You can leave a comment at the [Groups plugin page](http://www.itthinx.com/plugins/groups/).
 
 
218
 
219
  == Screenshots ==
220
 
230
 
231
  == Changelog ==
232
 
233
+ = 1.1.4 =
234
+ * Reduced plugin admin footer.
235
+
236
+ = 1.1.3 =
237
+ * Added safety & warning to test page.
238
+
239
+ = 1.1.2 =
240
+ * Tested on WP 3.3.2
241
+
242
+ = 1.1.1 =
243
+ * Multisite: Fixed (removed) conditions that would only make Groups act on public and non-mature sites
244
+ * Multisite: Adding add/remove to group only on sites', not network users admin screen
245
+ * Multisite: Added constraint in user_register hook checking if the user is a member of the blog
246
+
247
+ = 1.1.0 =
248
+ * Added Groups menu to network admin
249
+ * Added option to delete plugin data for all sites on multisite installations; removed option for individual sites
250
+ * Improved activation and deactivation for network installs
251
+ * Increases column sizes on capabilities table and fixes cut-off capabilities delete_published_pages and delete_published_posts
252
+
253
  = 1.0.0-beta-3d =
254
  * Fixed issues caused by an excessively long index for the capability DB table.
255
  Some installations wouldn't work correctly, showing no capabilities and making it impossible to add new ones.
275
 
276
  == Upgrade Notice ==
277
 
278
+ = 1.1.4 =
279
+ * Several bug fixes and improvements.
280
+
281
  = 1.0.0-beta-3d =
282
  * The capability DB table had a ridiculously long index, this update fixes it.
283
 
302
  The Groups plugin provides an extensive framework to handle memberships, group-based capabilities and access control.
303
  Read more on the official [Groups](http://www.itthinx.com/plugins/groups/) page and the [Groups documentation](http://www.itthinx.com/documentation/groups/) page.
304
 
305
+