Groups - Version 1.4.9

Version Description

  • Fixed: Tree view doesn't appear/disappear in menu directly after setting the option.
  • Improved: Feedback when options have been saved.
  • Improved: UI size adjustments.
  • Added: New API methods Groups_Group::get_group_ids() and Groups_Group::get_groups().
  • Improved: groups and capabilities table cell titles and ellipsis added.
Download this release

Release Info

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

Code changes from version 1.4.8 to 1.4.9

css/groups_admin.css CHANGED
@@ -125,6 +125,15 @@ div.capability.edit label {
125
  width:10%;
126
  }
127
 
 
 
 
 
 
 
 
 
 
128
  .manage-groups .required,
129
  .manage-capabilities .required {
130
  background: url(../images/required.png) transparent no-repeat left center;
@@ -204,12 +213,14 @@ div.groups-footer form {
204
  .groups-bulk-container .selectize-input {
205
  font-size: inherit;
206
  line-height: 18px;
207
- padding: 1px 1px 2px 1px;
208
  vertical-align: middle;
209
  }
210
  .groups-bulk-container .selectize-input input[type="text"] {
211
  font-size: inherit;
212
  vertical-align: middle;
 
 
213
  }
214
  .groups-bulk-container .button,
215
  .capabilities-bulk-container .button {
@@ -232,3 +243,17 @@ div.groups-footer form {
232
  .groups.messages {
233
  padding: 1em 0;
234
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  width:10%;
126
  }
127
 
128
+ .groups-overview td.capabilities,
129
+ .capabilities-overview td.capability {
130
+ text-overflow: ellipsis;
131
+ }
132
+
133
+ .groups-overview td.capabilities ul {
134
+ margin: 0;
135
+ }
136
+
137
  .manage-groups .required,
138
  .manage-capabilities .required {
139
  background: url(../images/required.png) transparent no-repeat left center;
213
  .groups-bulk-container .selectize-input {
214
  font-size: inherit;
215
  line-height: 18px;
216
+ padding: 0;
217
  vertical-align: middle;
218
  }
219
  .groups-bulk-container .selectize-input input[type="text"] {
220
  font-size: inherit;
221
  vertical-align: middle;
222
+ height: 28px;
223
+ line-height: 28px;
224
  }
225
  .groups-bulk-container .button,
226
  .capabilities-bulk-container .button {
243
  .groups.messages {
244
  padding: 1em 0;
245
  }
246
+
247
+ @media screen and ( max-width: 782px ) {
248
+ .groups-bulk-container .selectize-input {
249
+ padding: 2px;
250
+ }
251
+ .groups-bulk-container .selectize-input .item,
252
+ .groups-bulk-container .selectize-dropdown-content .option {
253
+ font-size: 16px;
254
+ }
255
+ .groups-bulk-container .selectize-input input[type="text"] {
256
+ height: 32px;
257
+ font-size: 16px;
258
+ }
259
+ }
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.4.8
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.4.8' );
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.4.9
25
  * Author: itthinx
26
  * Author URI: http://www.itthinx.com
27
  * Donate-Link: http://www.itthinx.com
28
  * License: GPLv3
29
  */
30
+ define( 'GROUPS_CORE_VERSION', '1.4.9' );
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
@@ -138,7 +138,7 @@ class Groups_Admin_Users {
138
  echo '.groups-bulk-container .selectize-control { min-width: 128px; }';
139
  echo '.groups-bulk-container .selectize-control, .groups-bulk-container select.groups-action { margin-right: 4px; vertical-align: top; }';
140
  echo '.groups-bulk-container .selectize-input { font-size: inherit; line-height: 18px; padding: 1px 2px 2px 2px; vertical-align: middle; }';
141
- echo '.groups-bulk-container .selectize-input input[type="text"] { font-size: inherit; vertical-align: middle; }';
142
  echo '.groups-bulk-container input.button { margin-top: 1px; vertical-align: top; }';
143
  echo '.tablenav .actions { overflow: visible; }'; // this is important so that the selectize options aren't hidden
144
  echo '</style>';
138
  echo '.groups-bulk-container .selectize-control { min-width: 128px; }';
139
  echo '.groups-bulk-container .selectize-control, .groups-bulk-container select.groups-action { margin-right: 4px; vertical-align: top; }';
140
  echo '.groups-bulk-container .selectize-input { font-size: inherit; line-height: 18px; padding: 1px 2px 2px 2px; vertical-align: middle; }';
141
+ echo '.groups-bulk-container .selectize-input input[type="text"] { font-size: inherit; vertical-align: middle; height: 24px; }';
142
  echo '.groups-bulk-container input.button { margin-top: 1px; vertical-align: top; }';
143
  echo '.tablenav .actions { overflow: visible; }'; // this is important so that the selectize options aren't hidden
144
  echo '</style>';
lib/admin/class-groups-admin.php CHANGED
@@ -145,8 +145,13 @@ class Groups_Admin {
145
  $pages[] = $page;
146
  add_action( 'admin_print_styles-' . $page, array( __CLASS__, 'admin_print_styles' ) );
147
  add_action( 'admin_print_scripts-' . $page, array( __CLASS__, 'admin_print_scripts' ) );
148
-
149
- $show_tree_view = Groups_Options::get_option( GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT );
 
 
 
 
 
150
  if ( $show_tree_view ) {
151
  include_once( GROUPS_ADMIN_LIB . '/groups-admin-tree-view.php');
152
  $page = add_submenu_page(
145
  $pages[] = $page;
146
  add_action( 'admin_print_styles-' . $page, array( __CLASS__, 'admin_print_styles' ) );
147
  add_action( 'admin_print_scripts-' . $page, array( __CLASS__, 'admin_print_scripts' ) );
148
+
149
+ if ( isset( $_POST[GROUPS_ADMIN_OPTIONS_NONCE] ) && wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) {
150
+ $show_tree_view = !empty( $_POST[GROUPS_SHOW_TREE_VIEW] );
151
+ } else {
152
+ $show_tree_view = Groups_Options::get_option( GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT );
153
+ }
154
+
155
  if ( $show_tree_view ) {
156
  include_once( GROUPS_ADMIN_LIB . '/groups-admin-tree-view.php');
157
  $page = add_submenu_page(
lib/admin/groups-admin-capabilities.php CHANGED
@@ -418,6 +418,8 @@ function groups_admin_capabilities() {
418
  $output .= '</tbody>';
419
  $output .= '</table>';
420
 
 
 
421
  $output .= '</form>'; // #groups-action
422
 
423
  if ( $paginate ) {
418
  $output .= '</tbody>';
419
  $output .= '</table>';
420
 
421
+ $output .= Groups_UIE::render_add_titles( '.capabilities-overview table td' );
422
+
423
  $output .= '</form>'; // #groups-action
424
 
425
  if ( $paginate ) {
lib/admin/groups-admin-groups.php CHANGED
@@ -460,6 +460,8 @@ function groups_admin_groups() {
460
  $output .= '</tbody>';
461
  $output .= '</table>';
462
 
 
 
463
  $output .= '</form>'; // #groups-action
464
 
465
  if ( $paginate ) {
460
  $output .= '</tbody>';
461
  $output .= '</table>';
462
 
463
+ $output .= Groups_UIE::render_add_titles( '.groups-overview table td' );
464
+
465
  $output .= '</form>'; // #groups-action
466
 
467
  if ( $paginate ) {
lib/admin/groups-admin-options.php CHANGED
@@ -32,13 +32,13 @@ define( 'GROUPS_ADMIN_OPTIONS_NONCE', 'groups-admin-nonce' );
32
  * Options admin screen.
33
  */
34
  function groups_admin_options() {
35
-
36
  global $wpdb, $wp_roles;
37
-
38
  if ( !current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
39
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
40
  }
41
-
42
  $is_sitewide_plugin = false;
43
  if ( is_multisite() ) {
44
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
@@ -46,27 +46,18 @@ function groups_admin_options() {
46
  $is_sitewide_plugin = in_array( 'groups/groups.php', $active_sitewide_plugins );
47
  }
48
 
49
- echo '<div class="groups-options">';
50
-
51
- echo
52
- '<div>' .
53
- '<h2>' .
54
- __( 'Groups options', GROUPS_PLUGIN_DOMAIN ) .
55
- '</h2>' .
56
- '</div>';
57
-
58
  $caps = array(
59
  GROUPS_ACCESS_GROUPS => __( 'Access Groups', GROUPS_PLUGIN_DOMAIN ),
60
  GROUPS_ADMINISTER_GROUPS => __( 'Administer Groups', GROUPS_PLUGIN_DOMAIN ),
61
  GROUPS_ADMINISTER_OPTIONS => __( 'Administer Groups plugin options', GROUPS_PLUGIN_DOMAIN ),
62
  );
63
-
64
  //
65
  // handle options form submission
66
  //
67
  if ( isset( $_POST['submit'] ) ) {
68
  if ( wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) {
69
-
70
  // admin override
71
  if ( empty( $_POST[GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE] ) ) {
72
  $admin_override = false;
@@ -76,7 +67,7 @@ function groups_admin_options() {
76
  // Don't move this to the plugin options, access will be faster
77
  add_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override ); // WP 3.3.1 : update alone wouldn't create the option when value is false
78
  update_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override );
79
-
80
  $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
81
  $post_types = get_post_types( array( 'public' => true ) );
82
  $selected_post_types = is_array( $_POST['add_meta_boxes'] ) ? $_POST['add_meta_boxes'] : array();
@@ -84,7 +75,7 @@ function groups_admin_options() {
84
  $post_types_option[$post_type]['add_meta_box'] = in_array( $post_type, $selected_post_types );
85
  }
86
  Groups_Options::update_option( Groups_Post_Access::POST_TYPES, $post_types_option );
87
-
88
  $valid_read_caps = array( Groups_Post_Access::READ_POST_CAPABILITY );
89
  if ( !empty( $_POST[GROUPS_READ_POST_CAPABILITIES] ) ) {
90
  $read_caps = $_POST[GROUPS_READ_POST_CAPABILITIES];
@@ -97,17 +88,17 @@ function groups_admin_options() {
97
  }
98
  }
99
  Groups_Options::update_option( Groups_Post_Access::READ_POST_CAPABILITIES, $valid_read_caps );
100
-
101
  // tree view
102
  if ( !empty( $_POST[GROUPS_SHOW_TREE_VIEW] ) ) {
103
  Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, true );
104
  } else {
105
  Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, false );
106
  }
107
-
108
  // show in user profiles
109
  Groups_Options::update_option( GROUPS_SHOW_IN_USER_PROFILE, !empty( $_POST[GROUPS_SHOW_IN_USER_PROFILE] ) );
110
-
111
  // roles & capabilities
112
  $rolenames = $wp_roles->get_names();
113
  foreach ( $rolenames as $rolekey => $rolename ) {
@@ -122,7 +113,7 @@ function groups_admin_options() {
122
  }
123
  }
124
  Groups_Controller::assure_capabilities();
125
-
126
  if ( !$is_sitewide_plugin ) {
127
  // delete data
128
  if ( !empty( $_POST['delete-data'] ) ) {
@@ -131,14 +122,24 @@ function groups_admin_options() {
131
  Groups_Options::update_option( 'groups_delete_data', false );
132
  }
133
  }
 
134
  }
135
  }
136
-
 
 
 
 
 
 
 
 
 
137
  $admin_override = get_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE_DEFAULT );
138
-
139
  $show_tree_view = Groups_Options::get_option( GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT );
140
  $show_in_user_profile = Groups_Options::get_option( GROUPS_SHOW_IN_USER_PROFILE, GROUPS_SHOW_IN_USER_PROFILE_DEFAULT );
141
-
142
  $rolenames = $wp_roles->get_names();
143
  $caps_table = '<table class="groups-permissions">';
144
  $caps_table .= '<thead>';
@@ -149,9 +150,9 @@ function groups_admin_options() {
149
  foreach ( $caps as $cap ) {
150
  $caps_table .= '<td class="cap">';
151
  $caps_table .= $cap;
152
- $caps_table .= '</td>';
153
  }
154
-
155
  $caps_table .= '</tr>';
156
  $caps_table .= '</thead>';
157
  $caps_table .= '<tbody>';
@@ -162,7 +163,7 @@ function groups_admin_options() {
162
  $caps_table .= translate_user_role( $rolename );
163
  $caps_table .= '</td>';
164
  foreach ( $caps as $capkey => $capname ) {
165
-
166
  if ( $role->has_cap( $capkey ) ) {
167
  $checked = ' checked="checked" ';
168
  } else {
@@ -213,14 +214,14 @@ function groups_admin_options() {
213
  __( 'Administrators override all access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN ) .
214
  '</label>' .
215
  '</p>';
216
-
217
  echo '<h3>' . __( 'Access restricions', GROUPS_PLUGIN_DOMAIN ) . '</h3>';
218
-
219
  echo '<h4>' . __( 'Post types', GROUPS_PLUGIN_DOMAIN ) . '</h4>';
220
-
221
  echo
222
  '<p class="description">' . __( 'Show access restrictions for these post types.', GROUPS_PLUGIN_DOMAIN ) . '</p>';
223
-
224
  $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
225
  $post_types = get_post_types( array( 'public' => true ) );
226
  echo '<ul>';
@@ -245,7 +246,7 @@ function groups_admin_options() {
245
  __( 'This determines for which post types access restriction settings are offered.', GROUPS_PLUGIN_DOMAIN ) . '<br/>' .
246
  __( 'Disabling this setting for a post type does not remove existing access restrictions on individual posts of that type.', GROUPS_PLUGIN_DOMAIN ) . '<br/>' .
247
  '</p>';
248
-
249
 
250
  echo '<h4>' . __( 'Capabilities', GROUPS_PLUGIN_DOMAIN ) . '</h4>';
251
 
@@ -278,7 +279,7 @@ function groups_admin_options() {
278
  __( 'Show groups in user profiles.', GROUPS_PLUGIN_DOMAIN ) .
279
  '</label>' .
280
  '</p>';
281
-
282
  echo
283
  '<h3>' . __( 'Tree view', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
284
  '<p>' .
@@ -287,7 +288,7 @@ function groups_admin_options() {
287
  __( 'Show the Groups tree view.', GROUPS_PLUGIN_DOMAIN ) .
288
  '</label>' .
289
  '</p>';
290
-
291
  echo
292
  '<h3>' . __( 'Permissions', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
293
  '<p>' . __( 'These permissions apply to Groups management. They do not apply to access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN ) . '</p>' .
@@ -317,7 +318,7 @@ function groups_admin_options() {
317
  '</p>' .
318
  '</div>' .
319
  '</form>';
320
-
321
  echo '</div>'; // .groups-options
322
  Groups_Help::footer();
323
  }
@@ -351,7 +352,7 @@ function groups_network_admin_options() {
351
 
352
  // options form
353
  echo
354
- '<form action="" name="options" method="post">' .
355
  '<div>' .
356
  '<h3>' . __( 'Network deactivation and data persistence', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
357
  '<p>' .
32
  * Options admin screen.
33
  */
34
  function groups_admin_options() {
35
+
36
  global $wpdb, $wp_roles;
37
+
38
  if ( !current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
39
  wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
40
  }
41
+
42
  $is_sitewide_plugin = false;
43
  if ( is_multisite() ) {
44
  $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
46
  $is_sitewide_plugin = in_array( 'groups/groups.php', $active_sitewide_plugins );
47
  }
48
 
 
 
 
 
 
 
 
 
 
49
  $caps = array(
50
  GROUPS_ACCESS_GROUPS => __( 'Access Groups', GROUPS_PLUGIN_DOMAIN ),
51
  GROUPS_ADMINISTER_GROUPS => __( 'Administer Groups', GROUPS_PLUGIN_DOMAIN ),
52
  GROUPS_ADMINISTER_OPTIONS => __( 'Administer Groups plugin options', GROUPS_PLUGIN_DOMAIN ),
53
  );
54
+
55
  //
56
  // handle options form submission
57
  //
58
  if ( isset( $_POST['submit'] ) ) {
59
  if ( wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) {
60
+
61
  // admin override
62
  if ( empty( $_POST[GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE] ) ) {
63
  $admin_override = false;
67
  // Don't move this to the plugin options, access will be faster
68
  add_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override ); // WP 3.3.1 : update alone wouldn't create the option when value is false
69
  update_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override );
70
+
71
  $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
72
  $post_types = get_post_types( array( 'public' => true ) );
73
  $selected_post_types = is_array( $_POST['add_meta_boxes'] ) ? $_POST['add_meta_boxes'] : array();
75
  $post_types_option[$post_type]['add_meta_box'] = in_array( $post_type, $selected_post_types );
76
  }
77
  Groups_Options::update_option( Groups_Post_Access::POST_TYPES, $post_types_option );
78
+
79
  $valid_read_caps = array( Groups_Post_Access::READ_POST_CAPABILITY );
80
  if ( !empty( $_POST[GROUPS_READ_POST_CAPABILITIES] ) ) {
81
  $read_caps = $_POST[GROUPS_READ_POST_CAPABILITIES];
88
  }
89
  }
90
  Groups_Options::update_option( Groups_Post_Access::READ_POST_CAPABILITIES, $valid_read_caps );
91
+
92
  // tree view
93
  if ( !empty( $_POST[GROUPS_SHOW_TREE_VIEW] ) ) {
94
  Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, true );
95
  } else {
96
  Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, false );
97
  }
98
+
99
  // show in user profiles
100
  Groups_Options::update_option( GROUPS_SHOW_IN_USER_PROFILE, !empty( $_POST[GROUPS_SHOW_IN_USER_PROFILE] ) );
101
+
102
  // roles & capabilities
103
  $rolenames = $wp_roles->get_names();
104
  foreach ( $rolenames as $rolekey => $rolename ) {
113
  }
114
  }
115
  Groups_Controller::assure_capabilities();
116
+
117
  if ( !$is_sitewide_plugin ) {
118
  // delete data
119
  if ( !empty( $_POST['delete-data'] ) ) {
122
  Groups_Options::update_option( 'groups_delete_data', false );
123
  }
124
  }
125
+ Groups_Admin::add_message( __( 'Options saved.', GROUPS_PLUGIN_DOMAIN ) );
126
  }
127
  }
128
+
129
+ echo '<div class="groups-options">';
130
+
131
+ echo
132
+ '<h2>' .
133
+ __( 'Groups options', GROUPS_PLUGIN_DOMAIN ) .
134
+ '</h2>';
135
+
136
+ echo Groups_Admin::render_messages();
137
+
138
  $admin_override = get_option( GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE_DEFAULT );
139
+
140
  $show_tree_view = Groups_Options::get_option( GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT );
141
  $show_in_user_profile = Groups_Options::get_option( GROUPS_SHOW_IN_USER_PROFILE, GROUPS_SHOW_IN_USER_PROFILE_DEFAULT );
142
+
143
  $rolenames = $wp_roles->get_names();
144
  $caps_table = '<table class="groups-permissions">';
145
  $caps_table .= '<thead>';
150
  foreach ( $caps as $cap ) {
151
  $caps_table .= '<td class="cap">';
152
  $caps_table .= $cap;
153
+ $caps_table .= '</td>';
154
  }
155
+
156
  $caps_table .= '</tr>';
157
  $caps_table .= '</thead>';
158
  $caps_table .= '<tbody>';
163
  $caps_table .= translate_user_role( $rolename );
164
  $caps_table .= '</td>';
165
  foreach ( $caps as $capkey => $capname ) {
166
+
167
  if ( $role->has_cap( $capkey ) ) {
168
  $checked = ' checked="checked" ';
169
  } else {
214
  __( 'Administrators override all access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN ) .
215
  '</label>' .
216
  '</p>';
217
+
218
  echo '<h3>' . __( 'Access restricions', GROUPS_PLUGIN_DOMAIN ) . '</h3>';
219
+
220
  echo '<h4>' . __( 'Post types', GROUPS_PLUGIN_DOMAIN ) . '</h4>';
221
+
222
  echo
223
  '<p class="description">' . __( 'Show access restrictions for these post types.', GROUPS_PLUGIN_DOMAIN ) . '</p>';
224
+
225
  $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
226
  $post_types = get_post_types( array( 'public' => true ) );
227
  echo '<ul>';
246
  __( 'This determines for which post types access restriction settings are offered.', GROUPS_PLUGIN_DOMAIN ) . '<br/>' .
247
  __( 'Disabling this setting for a post type does not remove existing access restrictions on individual posts of that type.', GROUPS_PLUGIN_DOMAIN ) . '<br/>' .
248
  '</p>';
249
+
250
 
251
  echo '<h4>' . __( 'Capabilities', GROUPS_PLUGIN_DOMAIN ) . '</h4>';
252
 
279
  __( 'Show groups in user profiles.', GROUPS_PLUGIN_DOMAIN ) .
280
  '</label>' .
281
  '</p>';
282
+
283
  echo
284
  '<h3>' . __( 'Tree view', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
285
  '<p>' .
288
  __( 'Show the Groups tree view.', GROUPS_PLUGIN_DOMAIN ) .
289
  '</label>' .
290
  '</p>';
291
+
292
  echo
293
  '<h3>' . __( 'Permissions', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
294
  '<p>' . __( 'These permissions apply to Groups management. They do not apply to access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN ) . '</p>' .
318
  '</p>' .
319
  '</div>' .
320
  '</form>';
321
+
322
  echo '</div>'; // .groups-options
323
  Groups_Help::footer();
324
  }
352
 
353
  // options form
354
  echo
355
+ '<form action="" name="options" method="post">' .
356
  '<div>' .
357
  '<h3>' . __( 'Network deactivation and data persistence', GROUPS_PLUGIN_DOMAIN ) . '</h3>' .
358
  '<p>' .
lib/core/class-groups-group.php CHANGED
@@ -414,4 +414,205 @@ class Groups_Group implements I_Capable {
414
  }
415
  return $result;
416
  }
417
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414
  }
415
  return $result;
416
  }
417
+
418
+ /**
419
+ * Returns an array of group IDs.
420
+ *
421
+ * If no arguments are passed, IDs for all existing groups are returned.
422
+ *
423
+ * @param array $args
424
+ * - ['order_by'] string a Groups_Group property
425
+ * - ['order'] string ASC or DESC. Only applied if 'order_by' is set.
426
+ * - ['parent_id'] int retrieve groups whose parent is indicated by this ID
427
+ * - ['include'] array|string with one or more IDs of groups to include, separated by comma
428
+ * - ['include_by_name'] array|string with one ore more group names of groups to include, separated by comma
429
+ * - ['exclude'] array|string with one or more IDs of groups to exclude, separated by comma
430
+ * - ['exclude_by_name'] array|string with one ore more group names of groups to exclude, separated by comma
431
+ *
432
+ * @return array of int with group IDs
433
+ *
434
+ * @since groups 1.4.9
435
+ */
436
+ public static function get_group_ids( $args = array() ) {
437
+ $result = array();
438
+ $args['fields'] = 'group_id';
439
+ $groups = self::get_groups( $args );
440
+ if ( sizeof( $groups ) > 0 ) {
441
+ foreach ( $groups as $group ) {
442
+ $result[] = $group->group_id;
443
+ }
444
+ }
445
+ return $result;
446
+ }
447
+
448
+ /**
449
+ * Returns an array of database results by querying the group table.
450
+ *
451
+ * @param Array $args
452
+ * - ['fields'] string with fields to get separated by comma. If empty then get all fields.
453
+ * - ['order_by'] string a Groups_Group property
454
+ * - ['order'] string ASC or DESC. Only applied if 'order_by' is set.
455
+ * - ['parent_id'] int retrieve groups whose parent is indicated by this ID
456
+ * - ['include'] array|string with one or more IDs of groups to include, separated by comma
457
+ * - ['include_by_name'] array|string with one ore more group names of groups to include, separated by comma
458
+ * - ['exclude'] array|string with one or more IDs of groups to exclude, separated by comma
459
+ * - ['exclude_by_name'] array|string with one ore more group names of groups to exclude, separated by comma
460
+ *
461
+ * @return array of int with group IDs
462
+ *
463
+ * @since groups 1.4.9
464
+ */
465
+ public static function get_groups( $args = array() ) {
466
+ global $wpdb;
467
+
468
+ extract( $args );
469
+
470
+ if ( !isset( $fields ) ) {
471
+ $fields = "*";
472
+ } else {
473
+ $array_fields = explode( ',', sanitize_text_field( $fields ) );
474
+ $fields = "";
475
+ foreach ( $array_fields as $field ) {
476
+ switch( trim( $field ) ) {
477
+ case 'group_id' :
478
+ case 'parent_id' :
479
+ case 'creator_id' :
480
+ case 'datetime' :
481
+ case 'name' :
482
+ case 'description' :
483
+ $fields .= ',' . trim( $field );
484
+ break;
485
+ }
486
+ }
487
+ if ( strlen( $fields ) > 0 ) {
488
+ $fields = substr( $fields, 1 );
489
+ }
490
+ }
491
+
492
+ if ( !isset( $order_by ) ) {
493
+ $order_by = "";
494
+ } else {
495
+ $order_by = sanitize_text_field( $order_by );
496
+ switch( trim( $field ) ) {
497
+ case 'group_id' :
498
+ case 'parent_id' :
499
+ case 'creator_id' :
500
+ case 'datetime' :
501
+ case 'name' :
502
+ case 'description' :
503
+ $order = '';
504
+ if ( !isset( $order ) || ( !( $order == 'ASC' ) && !( $order == 'DESC' ) ) ) {
505
+ $order = 'DESC';
506
+ }
507
+ $order_by = $wpdb->prepare( " ORDER BY %s $order ", array( $order_by ) );
508
+ break;
509
+ default :
510
+ $order_by = '';
511
+ break;
512
+ }
513
+ }
514
+
515
+ $where = '';
516
+ if ( isset( $parent_id ) ) {
517
+ $parent_id = sanitize_text_field( $parent_id );
518
+ if ( is_numeric ( $parent_id ) ) {
519
+ $where .= $wpdb->prepare( " WHERE parent_id=%s ", array( $parent_id ) );
520
+ }
521
+ }
522
+
523
+ //
524
+ // include by group ID
525
+ //
526
+ $where_include = '';
527
+ $include = !empty( $include ) ? $include : null;
528
+ if ( !empty( $include ) && !is_array( $include ) && is_string( $include ) ) {
529
+ $include = explode( ',', $include );
530
+ }
531
+ if ( count( $include ) > 0 ) {
532
+ $include = implode( ',', array_map( 'intval', array_map( 'trim', $include ) ) );
533
+ if ( strlen( $include ) > 0 ) {
534
+ $where_include = " group_id IN ($include) ";
535
+ }
536
+ }
537
+
538
+ //
539
+ // include by group name
540
+ //
541
+ $where_include_by_name = '';
542
+ $include_by_name = !empty( $include_by_name ) ? $include_by_name : null;
543
+ if ( !empty( $include_by_name ) && !is_array( $include_by_name ) && is_string( $include_by_name ) ) {
544
+ $include_by_name = explode( ',', $include_by_name );
545
+ }
546
+ if ( count( $include_by_name ) > 0 ) {
547
+ $include_by_name = "'" . implode( "','", array_map( 'esc_sql', array_map( 'trim', $include_by_name ) ) ) . "'";
548
+ if ( strlen( $include_by_name ) > 0 ) {
549
+ $where_include_by_name = " name IN ($include_by_name) ";
550
+ }
551
+ }
552
+
553
+ // adding includes ...
554
+ if ( ( $where_include !== '' ) || ( $where_include_by_name !== '' ) ) {
555
+ if ( $where == '' ) {
556
+ $where .= " WHERE ";
557
+ } else {
558
+ $where .= " AND ";
559
+ }
560
+ }
561
+ if ( ( $where_include !== "" ) && ( $where_include_by_name !== "" ) ) {
562
+ $where .= "(";
563
+ }
564
+ if ( $where_include !== "" ) {
565
+ $where .= $where_include;
566
+ }
567
+ if ( ( $where_include !== "" ) && ( $where_include_by_name !== "" ) ) {
568
+ $where .= " OR ";
569
+ }
570
+ if ( $where_include_by_name !== "" ) {
571
+ $where .= $where_include_by_name;
572
+ }
573
+ if ( ( $where_include !== "" ) && ( $where_include_by_name !== "" ) ) {
574
+ $where .= ")";
575
+ }
576
+
577
+ //
578
+ // exclude
579
+ //
580
+ $exclude = !empty( $exclude ) ? $exclude : null;
581
+ if ( !empty( $exclude ) && !is_array( $exclude ) && is_string( $exclude ) ) {
582
+ $exclude = explode( ',', $exclude );
583
+ }
584
+ if ( count( $exclude ) > 0 ) {
585
+ $exclude = implode( ',', array_map( 'intval', array_map( 'trim', $exclude ) ) );
586
+ if ( strlen( $exclude ) > 0 ) {
587
+ if ( empty( $where ) ) {
588
+ $where = " WHERE group_id NOT IN ($exclude) ";
589
+ } else {
590
+ $where .= " AND group_id NOT IN ($exclude) ";
591
+ }
592
+ }
593
+ }
594
+
595
+ //
596
+ // exclude by group name
597
+ //
598
+ $exclude_by_name = !empty( $exclude_by_name ) ? $exclude_by_name : null;
599
+ if ( !empty( $exclude_by_name ) && !is_array( $exclude_by_name ) && is_string( $exclude_by_name ) ) {
600
+ $exclude_by_name = explode( ',', $exclude_by_name );
601
+ }
602
+ if ( count( $exclude_by_name ) > 0 ) {
603
+ $exclude_by_name = "'" . implode( "','", array_map( 'esc_sql', array_map( 'trim', $exclude_by_name ) ) ) . "'";
604
+ if ( strlen( $exclude_by_name ) > 0 ) {
605
+ if ( empty( $where ) ) {
606
+ $where = " WHERE name NOT IN ($exclude_by_name) ";
607
+ } else {
608
+ $where .= " AND name NOT IN ($exclude_by_name) ";
609
+ }
610
+ }
611
+ }
612
+
613
+ $groups_table = _groups_get_tablename( 'group' );
614
+ $groups = $wpdb->get_results( "SELECT $fields FROM $groups_table $where $order_by" );
615
+
616
+ return $groups;
617
+ }
618
+ }
lib/views/class-groups-uie.php CHANGED
@@ -120,5 +120,17 @@ class Groups_UIE {
120
  return $output;
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
124
  Groups_UIE::init();
120
  return $output;
121
  }
122
 
123
+ public static function render_add_titles( $selector ) {
124
+ $output = '<script type="text/javascript">';
125
+ $output .= 'if ( typeof jQuery !== "undefined" ) {';
126
+ $output .= sprintf( 'jQuery("%s").each(', $selector );
127
+ $output .= 'function(){';
128
+ $output .= 'jQuery(this).attr("title", jQuery(this).text());'; // @todo improve for lists, paragraphs, breaks
129
+ $output .= '}';
130
+ $output .= ');';
131
+ $output .= '}';
132
+ $output .= '</script>';
133
+ return $output;
134
+ }
135
  }
136
  Groups_UIE::init();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.itthinx.com/plugins/groups
4
  Tags: access, access control, capability, capabilities, content, download, downloads, file, file access, files, group, groups, member, members, membership, memberships, paypal, permission, permissions, subscription, subscriptions, woocommerce
5
  Requires at least: 3.5
6
  Tested up to: 3.8.1
7
- Stable tag: 1.4.8
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.
@@ -177,6 +177,13 @@ See also [Groups](http://www.itthinx.com/plugins/groups/)
177
 
178
  == Changelog ==
179
 
 
 
 
 
 
 
 
180
  = 1.4.8 =
181
  * Fixed: A closing tag in the group list on the user profile.
182
  * Fixed: Help wording.
@@ -387,6 +394,9 @@ Some installations wouldn't work correctly, showing no capabilities and making i
387
 
388
  == Upgrade Notice ==
389
 
 
 
 
390
  = 1.4.8 =
391
  * Several minor fixes and giving more feedback on the admin side for groups and capabilities.
392
 
4
  Tags: access, access control, capability, capabilities, content, download, downloads, file, file access, files, group, groups, member, members, membership, memberships, paypal, permission, permissions, subscription, subscriptions, woocommerce
5
  Requires at least: 3.5
6
  Tested up to: 3.8.1
7
+ Stable tag: 1.4.9
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.
177
 
178
  == Changelog ==
179
 
180
+ = 1.4.9 =
181
+ * Fixed: Tree view doesn't appear/disappear in menu directly after setting the option.
182
+ * Improved: Feedback when options have been saved.
183
+ * Improved: UI size adjustments.
184
+ * Added: New API methods Groups_Group::get_group_ids() and Groups_Group::get_groups().
185
+ * Improved: groups and capabilities table cell titles and ellipsis added.
186
+
187
  = 1.4.8 =
188
  * Fixed: A closing tag in the group list on the user profile.
189
  * Fixed: Help wording.
394
 
395
  == Upgrade Notice ==
396
 
397
+ = 1.4.9 =
398
+ * UI improvements and API additions.
399
+
400
  = 1.4.8 =
401
  * Several minor fixes and giving more feedback on the admin side for groups and capabilities.
402