Version Description
- Fix: using substitute wp_cache_switch_to_blog instead of deprecated function wp_cache_reset when available (from 3.5.0)
- Fix: don't show access restriction meta box on attachments, the option is added with the attachment fields (3.5 uses common post edit screen but save_post isn't triggered on attachments)
- Improvement: limiting choice of access restrictions to those the current user has
- Fix: restrict access to edit or delete posts based on the post's access restrictions
- Feature: added option to refresh capabilities
- Fix: replaced use of get_user_by() (memory leaks on large user sets) with query & added batch limit when adding users to Registered group on activation
Download this release
Release Info
Developer | itthinx |
Plugin | Groups |
Version | 1.3.8 |
Comparing to | |
See all releases |
Code changes from version 1.3.7 to 1.3.8
- css/groups_admin.css +19 -0
- groups.php +2 -2
- images/refresh.png +0 -0
- lib/access/class-groups-access-meta-boxes.php +107 -74
- lib/access/class-groups-post-access.php +31 -2
- lib/admin/groups-admin-capabilities.php +15 -2
- lib/auto/class-groups-registered.php +17 -9
- lib/core/class-groups-controller.php +5 -1
- lib/core/class-groups-user-group.php +1 -1
- lib/wp/class-groups-wordpress.php +32 -22
- readme.txt +15 -2
css/groups_admin.css
CHANGED
@@ -40,6 +40,18 @@
|
|
40 |
height: 20px;
|
41 |
vertical-align: middle;
|
42 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
div.field {
|
44 |
padding-bottom: 0.62em;
|
45 |
}
|
@@ -113,3 +125,10 @@ div.groups-footer form {
|
|
113 |
.groups-options .groups-permissions td.checkbox {
|
114 |
text-align: center;
|
115 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
height: 20px;
|
41 |
vertical-align: middle;
|
42 |
}
|
43 |
+
.manage a.refresh {
|
44 |
+
text-decoration: none;
|
45 |
+
cursor: pointer;
|
46 |
+
float: right;
|
47 |
+
}
|
48 |
+
.manage a.refresh .icon {
|
49 |
+
vertical-align: middle;
|
50 |
+
}
|
51 |
+
.manage a.refresh .label {
|
52 |
+
height: 20px;
|
53 |
+
vertical-align: middle;
|
54 |
+
}
|
55 |
div.field {
|
56 |
padding-bottom: 0.62em;
|
57 |
}
|
125 |
.groups-options .groups-permissions td.checkbox {
|
126 |
text-align: center;
|
127 |
}
|
128 |
+
.info {
|
129 |
+
background-color: #eec;
|
130 |
+
border: 1px solid #cca;
|
131 |
+
border-radius: 4px;
|
132 |
+
margin: 1em;
|
133 |
+
padding: 1em;
|
134 |
+
}
|
groups.php
CHANGED
@@ -21,13 +21,13 @@
|
|
21 |
* Plugin Name: Groups
|
22 |
* Plugin URI: http://www.itthinx.com/plugins/groups
|
23 |
* Description: Groups provides group-based user membership management, group-based capabilities and content access control.
|
24 |
-
* Version: 1.3.
|
25 |
* Author: itthinx
|
26 |
* Author URI: http://www.itthinx.com
|
27 |
* Donate-Link: http://www.itthinx.com
|
28 |
* License: GPLv3
|
29 |
*/
|
30 |
-
define( 'GROUPS_CORE_VERSION', '1.3.
|
31 |
define( 'GROUPS_FILE', __FILE__ );
|
32 |
if ( !defined( 'GROUPS_CORE_DIR' ) ) {
|
33 |
define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
|
21 |
* Plugin Name: Groups
|
22 |
* Plugin URI: http://www.itthinx.com/plugins/groups
|
23 |
* Description: Groups provides group-based user membership management, group-based capabilities and content access control.
|
24 |
+
* Version: 1.3.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.3.8' );
|
31 |
define( 'GROUPS_FILE', __FILE__ );
|
32 |
if ( !defined( 'GROUPS_CORE_DIR' ) ) {
|
33 |
define( 'GROUPS_CORE_DIR', WP_PLUGIN_DIR . '/groups' );
|
images/refresh.png
ADDED
Binary file
|
lib/access/class-groups-access-meta-boxes.php
CHANGED
@@ -48,7 +48,7 @@ class Groups_Access_Meta_Boxes {
|
|
48 |
public static function add_meta_boxes( $post_type, $post = null ) {
|
49 |
global $wp_version;
|
50 |
$post_type_object = get_post_type_object( $post_type );
|
51 |
-
if ( $post_type_object ) {
|
52 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
53 |
if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
|
54 |
if ( $wp_version < 3.3 ) {
|
@@ -102,33 +102,39 @@ class Groups_Access_Meta_Boxes {
|
|
102 |
}
|
103 |
}
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
$
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
119 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
-
$output .= '</ul>';
|
122 |
-
$output .= '</div>';
|
123 |
-
|
124 |
-
$output .= '<p class="description">';
|
125 |
-
$output .= sprintf( __( "Only groups or users that have one of the selected capabilities are allowed to read this %s.", GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
126 |
-
$output .= '</p>';
|
127 |
-
$output .= wp_nonce_field( self::SET_CAPABILITY, self::NONCE, true, false );
|
128 |
|
129 |
echo $output;
|
130 |
}
|
131 |
-
|
132 |
/**
|
133 |
* Save capability options.
|
134 |
*
|
@@ -140,7 +146,7 @@ class Groups_Access_Meta_Boxes {
|
|
140 |
} else {
|
141 |
$post_type = get_post_type( $post_id );
|
142 |
$post_type_object = get_post_type_object( $post_type );
|
143 |
-
if ( $post_type_object ) {
|
144 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
145 |
if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
|
146 |
if ( isset( $_POST[self::NONCE] ) && wp_verify_nonce( $_POST[self::NONCE], self::SET_CAPABILITY ) ) {
|
@@ -151,14 +157,19 @@ class Groups_Access_Meta_Boxes {
|
|
151 |
// If the post ID is not provided, it will throw:
|
152 |
// PHP Notice: Undefined offset: 0 in /var/www/groups-forums/wp-includes/capabilities.php on line 1067
|
153 |
if ( current_user_can( 'edit_'.$post_type, $post_id ) ) {
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
163 |
}
|
164 |
}
|
@@ -169,7 +180,7 @@ class Groups_Access_Meta_Boxes {
|
|
169 |
}
|
170 |
}
|
171 |
}
|
172 |
-
|
173 |
/**
|
174 |
* Render capabilities box for attachment post type (Media).
|
175 |
* @param array $form_fields
|
@@ -177,45 +188,45 @@ class Groups_Access_Meta_Boxes {
|
|
177 |
* @return array
|
178 |
*/
|
179 |
public static function attachment_fields_to_edit( $form_fields, $post ) {
|
180 |
-
|
181 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
182 |
if ( !isset( $post_types_option['attachment']['add_meta_box'] ) || $post_types_option['attachment']['add_meta_box'] ) {
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
201 |
}
|
202 |
-
|
203 |
-
|
204 |
-
$output .= '</div>';
|
205 |
-
|
206 |
-
$output .= '<p class="description">';
|
207 |
-
$output .= sprintf( __( "Only groups or users that have one of the selected capabilities are allowed to read this %s.", GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
208 |
-
$output .= '</p>';
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
|
|
|
|
|
|
|
|
|
|
215 |
}
|
216 |
return $form_fields;
|
217 |
}
|
218 |
-
|
219 |
/**
|
220 |
* Save capabilities for attachment post type (Media).
|
221 |
* When multiple attachments are saved, this is called once for each.
|
@@ -226,21 +237,43 @@ class Groups_Access_Meta_Boxes {
|
|
226 |
public static function attachment_fields_to_save( $post, $attachment ) {
|
227 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
228 |
if ( !isset( $post_types_option['attachment']['add_meta_box'] ) || $post_types_option['attachment']['add_meta_box'] ) {
|
229 |
-
if ( current_user_can( 'edit_attachment' ) ) {
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
|
|
|
|
238 |
}
|
239 |
-
}
|
240 |
}
|
241 |
}
|
242 |
}
|
243 |
return $post;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
}
|
245 |
|
246 |
}
|
48 |
public static function add_meta_boxes( $post_type, $post = null ) {
|
49 |
global $wp_version;
|
50 |
$post_type_object = get_post_type_object( $post_type );
|
51 |
+
if ( $post_type_object && $post_type != 'attachment' ) {
|
52 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
53 |
if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
|
54 |
if ( $wp_version < 3.3 ) {
|
102 |
}
|
103 |
}
|
104 |
|
105 |
+
if ( self::user_can_restrict() ) {
|
106 |
+
$output .= __( "Enforce read access", GROUPS_PLUGIN_DOMAIN );
|
107 |
+
$read_caps = get_post_meta( $post_id, Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY );
|
108 |
+
$valid_read_caps = Groups_Options::get_option( Groups_Post_Access::READ_POST_CAPABILITIES, array( Groups_Post_Access::READ_POST_CAPABILITY ) );
|
109 |
+
$output .= '<div style="padding:0 1em;margin:1em 0;border:1px solid #ccc;border-radius:4px;">';
|
110 |
+
$output .= '<ul>';
|
111 |
+
foreach( $valid_read_caps as $valid_read_cap ) {
|
112 |
+
if ( $capability = Groups_Capability::read_by_capability( $valid_read_cap ) ) {
|
113 |
+
$checked = in_array( $capability->capability, $read_caps ) ? ' checked="checked" ' : '';
|
114 |
+
$output .= '<li>';
|
115 |
+
$output .= '<label>';
|
116 |
+
$output .= '<input name="' . self::CAPABILITY . '[]" ' . $checked . ' type="checkbox" value="' . esc_attr( $capability->capability_id ) . '" />';
|
117 |
+
$output .= wp_filter_nohtml_kses( $capability->capability );
|
118 |
+
$output .= '</label>';
|
119 |
+
$output .= '</li>';
|
120 |
+
}
|
121 |
}
|
122 |
+
$output .= '</ul>';
|
123 |
+
$output .= '</div>';
|
124 |
+
|
125 |
+
$output .= '<p class="description">';
|
126 |
+
$output .= sprintf( __( "Only groups or users that have one of the selected capabilities are allowed to read this %s.", GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
127 |
+
$output .= '</p>';
|
128 |
+
$output .= wp_nonce_field( self::SET_CAPABILITY, self::NONCE, true, false );
|
129 |
+
} else {
|
130 |
+
$output .= '<p class="description">';
|
131 |
+
$output .= sprintf( __( 'You cannot set any access restrictions.', GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
132 |
+
$output .= '</p>';
|
133 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
echo $output;
|
136 |
}
|
137 |
+
|
138 |
/**
|
139 |
* Save capability options.
|
140 |
*
|
146 |
} else {
|
147 |
$post_type = get_post_type( $post_id );
|
148 |
$post_type_object = get_post_type_object( $post_type );
|
149 |
+
if ( $post_type_object && $post_type != 'attachment' ) {
|
150 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
151 |
if ( !isset( $post_types_option[$post_type]['add_meta_box'] ) || $post_types_option[$post_type]['add_meta_box'] ) {
|
152 |
if ( isset( $_POST[self::NONCE] ) && wp_verify_nonce( $_POST[self::NONCE], self::SET_CAPABILITY ) ) {
|
157 |
// If the post ID is not provided, it will throw:
|
158 |
// PHP Notice: Undefined offset: 0 in /var/www/groups-forums/wp-includes/capabilities.php on line 1067
|
159 |
if ( current_user_can( 'edit_'.$post_type, $post_id ) ) {
|
160 |
+
if ( self::user_can_restrict() ) {
|
161 |
+
Groups_Post_Access::delete( $post_id, null );
|
162 |
+
$user = new Groups_User( get_current_user_id() );
|
163 |
+
if ( !empty( $_POST[self::CAPABILITY] ) ) {
|
164 |
+
foreach ( $_POST[self::CAPABILITY] as $capability_id ) {
|
165 |
+
if ( $capability = Groups_Capability::read( $capability_id ) ) {
|
166 |
+
if ( $user->can( $capability->capability_id ) ) {
|
167 |
+
Groups_Post_Access::create( array(
|
168 |
+
'post_id' => $post_id,
|
169 |
+
'capability' => $capability->capability
|
170 |
+
) );
|
171 |
+
}
|
172 |
+
}
|
173 |
}
|
174 |
}
|
175 |
}
|
180 |
}
|
181 |
}
|
182 |
}
|
183 |
+
|
184 |
/**
|
185 |
* Render capabilities box for attachment post type (Media).
|
186 |
* @param array $form_fields
|
188 |
* @return array
|
189 |
*/
|
190 |
public static function attachment_fields_to_edit( $form_fields, $post ) {
|
|
|
191 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
192 |
if ( !isset( $post_types_option['attachment']['add_meta_box'] ) || $post_types_option['attachment']['add_meta_box'] ) {
|
193 |
+
if ( self::user_can_restrict() ) {
|
194 |
+
$output = "";
|
195 |
+
$post_singular_name = __( 'Media', GROUPS_PLUGIN_DOMAIN );
|
196 |
|
197 |
+
$output .= __( "Enforce read access", GROUPS_PLUGIN_DOMAIN );
|
198 |
+
$read_caps = get_post_meta( $post->ID, Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY );
|
199 |
+
$valid_read_caps = Groups_Options::get_option( Groups_Post_Access::READ_POST_CAPABILITIES, array( Groups_Post_Access::READ_POST_CAPABILITY ) );
|
200 |
+
$output .= '<div style="padding:0 1em;margin:1em 0;border:1px solid #ccc;border-radius:4px;">';
|
201 |
+
$output .= '<ul>';
|
202 |
+
foreach( $valid_read_caps as $valid_read_cap ) {
|
203 |
+
if ( $capability = Groups_Capability::read_by_capability( $valid_read_cap ) ) {
|
204 |
+
$checked = in_array( $capability->capability, $read_caps ) ? ' checked="checked" ' : '';
|
205 |
+
$output .= '<li>';
|
206 |
+
$output .= '<label>';
|
207 |
+
$output .= '<input name="attachments[' . $post->ID . '][' . self::CAPABILITY . '][]" ' . $checked . ' type="checkbox" value="' . esc_attr( $capability->capability_id ) . '" />';
|
208 |
+
$output .= wp_filter_nohtml_kses( $capability->capability );
|
209 |
+
$output .= '</label>';
|
210 |
+
$output .= '</li>';
|
211 |
+
}
|
212 |
}
|
213 |
+
$output .= '</ul>';
|
214 |
+
$output .= '</div>';
|
|
|
|
|
|
|
|
|
|
|
215 |
|
216 |
+
$output .= '<p class="description">';
|
217 |
+
$output .= sprintf( __( "Only groups or users that have one of the selected capabilities are allowed to read this %s.", GROUPS_PLUGIN_DOMAIN ), $post_singular_name );
|
218 |
+
$output .= '</p>';
|
219 |
+
|
220 |
+
$form_fields['groups_access'] = array(
|
221 |
+
'label' => __( 'Access restrictions', GROUPS_PLUGIN_DOMAIN ),
|
222 |
+
'input' => 'html',
|
223 |
+
'html' => $output
|
224 |
+
);
|
225 |
+
}
|
226 |
}
|
227 |
return $form_fields;
|
228 |
}
|
229 |
+
|
230 |
/**
|
231 |
* Save capabilities for attachment post type (Media).
|
232 |
* When multiple attachments are saved, this is called once for each.
|
237 |
public static function attachment_fields_to_save( $post, $attachment ) {
|
238 |
$post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() );
|
239 |
if ( !isset( $post_types_option['attachment']['add_meta_box'] ) || $post_types_option['attachment']['add_meta_box'] ) {
|
240 |
+
if ( current_user_can( 'edit_attachment' ) ) {
|
241 |
+
if ( self::user_can_restrict() ) {
|
242 |
+
Groups_Post_Access::delete( $post['ID'], null );
|
243 |
+
if ( !empty( $attachment[self::CAPABILITY] ) ) {
|
244 |
+
foreach ( $attachment[self::CAPABILITY] as $capability_id ) {
|
245 |
+
if ( $capability = Groups_Capability::read( $capability_id ) ) {
|
246 |
+
Groups_Post_Access::create( array(
|
247 |
+
'post_id' => $post['ID'],
|
248 |
+
'capability' => $capability->capability
|
249 |
+
) );
|
250 |
+
}
|
251 |
}
|
252 |
+
}
|
253 |
}
|
254 |
}
|
255 |
}
|
256 |
return $post;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Returns true if the current user has at least one of the capabilities
|
261 |
+
* that can be used to restrict access to posts.
|
262 |
+
* @return boolean
|
263 |
+
*/
|
264 |
+
private static function user_can_restrict() {
|
265 |
+
$has_read_cap = false;
|
266 |
+
$user = new Groups_User( get_current_user_id() );
|
267 |
+
$valid_read_caps = Groups_Options::get_option( Groups_Post_Access::READ_POST_CAPABILITIES, array( Groups_Post_Access::READ_POST_CAPABILITY ) );
|
268 |
+
foreach( $valid_read_caps as $valid_read_cap ) {
|
269 |
+
if ( $capability = Groups_Capability::read_by_capability( $valid_read_cap ) ) {
|
270 |
+
if ( $user->can( $capability->capability_id ) ) {
|
271 |
+
$has_read_cap = true;
|
272 |
+
break;
|
273 |
+
}
|
274 |
+
}
|
275 |
+
}
|
276 |
+
return $has_read_cap;
|
277 |
}
|
278 |
|
279 |
}
|
lib/access/class-groups-post-access.php
CHANGED
@@ -45,7 +45,10 @@ class Groups_Post_Access {
|
|
45 |
__( "Read Post", GROUPS_PLUGIN_DOMAIN );
|
46 |
}
|
47 |
}
|
48 |
-
|
|
|
|
|
|
|
49 |
public static function init() {
|
50 |
// post access
|
51 |
add_filter( 'get_pages', array( __CLASS__, "get_pages" ), 1 );
|
@@ -54,12 +57,38 @@ class Groups_Post_Access {
|
|
54 |
// content access
|
55 |
add_filter( "get_the_excerpt", array( __CLASS__, "get_the_excerpt" ), 1 );
|
56 |
add_filter( "the_content", array( __CLASS__, "the_content" ), 1 );
|
|
|
|
|
57 |
// @todo these could be interesting to add later ...
|
58 |
// add_filter( "plugin_row_meta", array( __CLASS__, "plugin_row_meta" ), 1 );
|
59 |
// add_filter( "posts_join_paged", array( __CLASS__, "posts_join_paged" ), 1 );
|
60 |
// add_filter( "posts_where_paged", array( __CLASS__, "posts_where_paged" ), 1 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
-
|
|
|
|
|
63 |
/**
|
64 |
* Filter pages by access capability.
|
65 |
*
|
45 |
__( "Read Post", GROUPS_PLUGIN_DOMAIN );
|
46 |
}
|
47 |
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Sets up filters to restrict access.
|
51 |
+
*/
|
52 |
public static function init() {
|
53 |
// post access
|
54 |
add_filter( 'get_pages', array( __CLASS__, "get_pages" ), 1 );
|
57 |
// content access
|
58 |
add_filter( "get_the_excerpt", array( __CLASS__, "get_the_excerpt" ), 1 );
|
59 |
add_filter( "the_content", array( __CLASS__, "the_content" ), 1 );
|
60 |
+
// edit & delete post
|
61 |
+
add_filter( 'map_meta_cap', array( __CLASS__, 'map_meta_cap' ), 10, 4 );
|
62 |
// @todo these could be interesting to add later ...
|
63 |
// add_filter( "plugin_row_meta", array( __CLASS__, "plugin_row_meta" ), 1 );
|
64 |
// add_filter( "posts_join_paged", array( __CLASS__, "posts_join_paged" ), 1 );
|
65 |
// add_filter( "posts_where_paged", array( __CLASS__, "posts_where_paged" ), 1 );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Restrict access to edit or delete posts based on the post's access restrictions.
|
70 |
+
* @param array $caps
|
71 |
+
* @param string $cap
|
72 |
+
* @param int $user_id
|
73 |
+
* @param array $args
|
74 |
+
* @return array
|
75 |
+
*/
|
76 |
+
public static function map_meta_cap( $caps, $cap, $user_id, $args ) {
|
77 |
+
if ( isset( $args[0] ) ) {
|
78 |
+
if ( strpos( $cap, 'edit_' ) === 0 || strpos( $cap, 'delete_' ) === 0 ) {
|
79 |
+
if ( $post_type = get_post_type( $args[0] ) ) {
|
80 |
+
if ( $cap === "edit_$post_type" || $cap === "delete_$post_type" ) {
|
81 |
+
$post_id = $args[0];
|
82 |
+
if ( !self::user_can_read_post( $post_id, $user_id ) ) {
|
83 |
+
$caps[] = 'do_not_allow';
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
}
|
89 |
+
return $caps;
|
90 |
+
}
|
91 |
+
|
92 |
/**
|
93 |
* Filter pages by access capability.
|
94 |
*
|
lib/admin/groups-admin-capabilities.php
CHANGED
@@ -99,6 +99,18 @@ function groups_admin_capabilities() {
|
|
99 |
return groups_admin_capabilities_remove( $_GET['capability_id'] );
|
100 |
}
|
101 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
}
|
104 |
|
@@ -166,10 +178,11 @@ function groups_admin_capabilities() {
|
|
166 |
__( 'Capabilities', GROUPS_PLUGIN_DOMAIN ) .
|
167 |
'</h2>' .
|
168 |
'</div>';
|
169 |
-
|
170 |
$output .=
|
171 |
'<div class="manage">' .
|
172 |
-
"<a title='" . __( 'Click to add a new capability', GROUPS_PLUGIN_DOMAIN ) . "' class='add button' href='" . esc_url( $current_url ) . "&action=add'><img class='icon' alt='" . __( 'Add', GROUPS_PLUGIN_DOMAIN) . "' src='". GROUPS_PLUGIN_URL ."images/add.png'/><span class='label'>" . __( 'New Capability', GROUPS_PLUGIN_DOMAIN) . "</span></a>" .
|
|
|
173 |
'</div>';
|
174 |
|
175 |
$row_count = isset( $_POST['row_count'] ) ? intval( $_POST['row_count'] ) : 0;
|
99 |
return groups_admin_capabilities_remove( $_GET['capability_id'] );
|
100 |
}
|
101 |
break;
|
102 |
+
case 'refresh' :
|
103 |
+
if ( check_admin_referer( 'refresh' ) ) {
|
104 |
+
$n = Groups_WordPress::refresh_capabilities();
|
105 |
+
if ( $n > 0 ) {
|
106 |
+
$output .= '<div class="info">' . sprintf( _n( 'One capability has been added.', '%d capabilities have been added.', $n, GROUPS_PLUGIN_DOMAIN ), $n ) . '</div>';
|
107 |
+
} else {
|
108 |
+
$output .= '<div class="info">' . __( 'No new capabilities have been found.', GROUPS_PLUGIN_DOMAIN ) . '</div>';
|
109 |
+
}
|
110 |
+
} else {
|
111 |
+
wp_die( __( 'A Duck!', GROUPS_PLUGIN_DOMAIN ) );
|
112 |
+
}
|
113 |
+
break;
|
114 |
}
|
115 |
}
|
116 |
|
178 |
__( 'Capabilities', GROUPS_PLUGIN_DOMAIN ) .
|
179 |
'</h2>' .
|
180 |
'</div>';
|
181 |
+
|
182 |
$output .=
|
183 |
'<div class="manage">' .
|
184 |
+
"<a title='" . __( 'Click to add a new capability', GROUPS_PLUGIN_DOMAIN ) . "' class='add button' href='" . esc_url( $current_url ) . "&action=add'><img class='icon' alt='" . __( 'Add', GROUPS_PLUGIN_DOMAIN) . "' src='". GROUPS_PLUGIN_URL . "images/add.png'/><span class='label'>" . __( 'New Capability', GROUPS_PLUGIN_DOMAIN) . "</span></a>" .
|
185 |
+
"<a title='" . __( 'Click to refresh capabilities', GROUPS_PLUGIN_DOMAIN ) . "' class='refresh button' href='" . esc_url( wp_nonce_url( $current_url, 'refresh' ) ) . "&action=refresh'><img class='icon' alt='" . __( 'Refresh', GROUPS_PLUGIN_DOMAIN) . "' src='". GROUPS_PLUGIN_URL . "images/refresh.png'/><span class='label'>" . __( '', GROUPS_PLUGIN_DOMAIN) . "</span></a>" .
|
186 |
'</div>';
|
187 |
|
188 |
$row_count = isset( $_POST['row_count'] ) ? intval( $_POST['row_count'] ) : 0;
|
lib/auto/class-groups-registered.php
CHANGED
@@ -26,27 +26,35 @@ class Groups_Registered {
|
|
26 |
|
27 |
const REGISTERED_GROUP_NAME = 'Registered';
|
28 |
|
|
|
|
|
29 |
/**
|
30 |
* Creates groups for registered users.
|
31 |
* Must be called explicitly or hooked into activation.
|
32 |
*/
|
33 |
public static function activate() {
|
34 |
-
|
35 |
global $wpdb;
|
36 |
-
|
37 |
// create a group for the blog if it doesn't exist
|
38 |
if ( !( $group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME ) ) ) {
|
39 |
$group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
|
40 |
} else {
|
41 |
$group_id = $group->group_id;
|
42 |
}
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
Groups_User_Group::
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
}
|
52 |
}
|
26 |
|
27 |
const REGISTERED_GROUP_NAME = 'Registered';
|
28 |
|
29 |
+
const BATCH_LIMIT = 100;
|
30 |
+
|
31 |
/**
|
32 |
* Creates groups for registered users.
|
33 |
* Must be called explicitly or hooked into activation.
|
34 |
*/
|
35 |
public static function activate() {
|
36 |
+
|
37 |
global $wpdb;
|
38 |
+
|
39 |
// create a group for the blog if it doesn't exist
|
40 |
if ( !( $group = Groups_Group::read_by_name( self::REGISTERED_GROUP_NAME ) ) ) {
|
41 |
$group_id = Groups_Group::create( array( "name" => self::REGISTERED_GROUP_NAME ) );
|
42 |
} else {
|
43 |
$group_id = $group->group_id;
|
44 |
}
|
45 |
+
if ( $group_id ) {
|
46 |
+
$n = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->users" );
|
47 |
+
for ( $i = 0; $i < $n; $i += self::BATCH_LIMIT ) {
|
48 |
+
$users = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->users LIMIT %d, %d", $i, self::BATCH_LIMIT ) );
|
49 |
+
foreach( $users as $user ) {
|
50 |
+
// add the user to the group
|
51 |
+
if ( !Groups_User_Group::read( $user->ID, $group_id ) ) {
|
52 |
+
Groups_User_Group::create( array( "user_id" => $user->ID, "group_id" => $group_id ) );
|
53 |
+
}
|
54 |
+
}
|
55 |
+
unset( $users );
|
56 |
+
if ( function_exists( 'gc_collect_cycles' ) ) {
|
57 |
+
gc_collect_cycles();
|
58 |
}
|
59 |
}
|
60 |
}
|
lib/core/class-groups-controller.php
CHANGED
@@ -36,7 +36,11 @@ class Groups_Controller {
|
|
36 |
*/
|
37 |
public static function switch_to_blog( $blog_id ) {
|
38 |
switch_to_blog( $blog_id );
|
39 |
-
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
36 |
*/
|
37 |
public static function switch_to_blog( $blog_id ) {
|
38 |
switch_to_blog( $blog_id );
|
39 |
+
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
|
40 |
+
wp_cache_switch_to_blog( $blog_id ); // introduced in WP 3.5.0
|
41 |
+
} else {
|
42 |
+
wp_cache_reset(); // deprecated in WP 3.5.0
|
43 |
+
}
|
44 |
}
|
45 |
|
46 |
/**
|
lib/core/class-groups-user-group.php
CHANGED
@@ -93,7 +93,7 @@ class Groups_User_Group {
|
|
93 |
// if ( !empty( $user_id ) && !empty( $group_id ) ) {
|
94 |
if ( !empty( $group_id ) ) {
|
95 |
// make sure user and group exist
|
96 |
-
if ( ( false !== Groups_Utility::id( $user_id ) ) &&
|
97 |
// only allow to add users to groups if they belong to the
|
98 |
// group's blog or we have the anonymous user
|
99 |
if ( is_user_member_of_blog( Groups_Utility::id( $user_id ) ) || ( Groups_Utility::id( $user_id ) === 0 ) ) {
|
93 |
// if ( !empty( $user_id ) && !empty( $group_id ) ) {
|
94 |
if ( !empty( $group_id ) ) {
|
95 |
// make sure user and group exist
|
96 |
+
if ( ( false !== Groups_Utility::id( $user_id ) ) && ( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->users WHERE ID = %d", $user_id ) ) > 0 ) && ( $group = Groups_Group::read( $group_id ) ) ) {
|
97 |
// only allow to add users to groups if they belong to the
|
98 |
// group's blog or we have the anonymous user
|
99 |
if ( is_user_member_of_blog( Groups_Utility::id( $user_id ) ) || ( Groups_Utility::id( $user_id ) === 0 ) ) {
|
lib/wp/class-groups-wordpress.php
CHANGED
@@ -89,30 +89,40 @@ class Groups_WordPress {
|
|
89 |
* @see Groups_Controller::activate()
|
90 |
*/
|
91 |
public static function activate() {
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
Groups_Capability::create( array( 'capability' => $capability ) );
|
114 |
-
|
|
|
115 |
}
|
|
|
116 |
}
|
117 |
}
|
118 |
Groups_WordPress::init();
|
89 |
* @see Groups_Controller::activate()
|
90 |
*/
|
91 |
public static function activate() {
|
92 |
+
self::refresh_capabilities();
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Refreshes Groups capabilities based on WordPress capabilities.
|
97 |
+
* @return int number of capabilities added
|
98 |
+
*/
|
99 |
+
public static function refresh_capabilities() {
|
100 |
+
global $wp_roles;
|
101 |
+
$capabilities = array();
|
102 |
+
$count = 0;
|
103 |
+
if ( !isset( $wp_roles ) ) {
|
104 |
+
// just trigger initialization
|
105 |
+
get_role( 'administrator' );
|
106 |
+
}
|
107 |
+
$roles = $wp_roles->roles;
|
108 |
+
if ( is_array( $roles ) ) {
|
109 |
+
foreach ( $roles as $rolename => $atts ) {
|
110 |
+
if ( isset( $atts['capabilities'] ) && is_array( $atts['capabilities'] ) ) {
|
111 |
+
foreach ( $atts['capabilities'] as $capability => $value ) {
|
112 |
+
if ( !in_array( $capability, $capabilities ) ) {
|
113 |
+
$capabilities[] = $capability;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
}
|
119 |
+
foreach ( $capabilities as $capability ) {
|
120 |
+
if ( !Groups_Capability::read_by_capability( $capability ) ) {
|
121 |
Groups_Capability::create( array( 'capability' => $capability ) );
|
122 |
+
$count++;
|
123 |
+
}
|
124 |
}
|
125 |
+
return $count;
|
126 |
}
|
127 |
}
|
128 |
Groups_WordPress::init();
|
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, download, downloads, file, file access, files, group, groups, member, members, membership, memberships, paypal, permission, permissions, subscription, subscriptions, woocommerce
|
5 |
Requires at least: 3.3
|
6 |
-
Tested up to: 3.5
|
7 |
-
Stable tag: 1.3.
|
8 |
License: GPLv3
|
9 |
|
10 |
Groups provides group-based user membership management, group-based capabilities and content access control.
|
@@ -16,6 +16,8 @@ It integrates standard WordPress capabilities and application-specific capabilit
|
|
16 |
|
17 |
### Extensions ###
|
18 |
|
|
|
|
|
19 |
- [Groups File Access](http://www.itthinx.com/plugins/groups-file-access/) Groups File Access is an extension that allows to provide file download links for authorized users. Access to files is restricted to users by their group membership.
|
20 |
- [Groups Forums](http://www.itthinx.com/plugins/groups-forums/) A powerful and yet light-weight forum system.
|
21 |
- [Groups Jigoshop](http://jigoshop.com/product/subscriptions/) Groups integration for Jigoshop that supports memberships and subscriptions.
|
@@ -324,6 +326,14 @@ See also [Groups](http://www.itthinx.com/plugins/groups/)
|
|
324 |
|
325 |
== Changelog ==
|
326 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
= 1.3.7 =
|
328 |
* Fix: missing argument for meta box when saving a post
|
329 |
* Fix: Groups conflicting with other plugins adding columns to the Users screen (in the manage_users_custom_column filter) thanks to [Erwin](http://www.transpontine.com) who spotted this :)
|
@@ -430,6 +440,9 @@ Some installations wouldn't work correctly, showing no capabilities and making i
|
|
430 |
|
431 |
== Upgrade Notice ==
|
432 |
|
|
|
|
|
|
|
433 |
= 1.3.7 =
|
434 |
* Please update, this includes fixes: missing argument for meta box when saving a post; Groups conflicting with other plugins adding columns to the Users screen.
|
435 |
|
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: 3.3
|
6 |
+
Tested up to: 3.5.1
|
7 |
+
Stable tag: 1.3.8
|
8 |
License: GPLv3
|
9 |
|
10 |
Groups provides group-based user membership management, group-based capabilities and content access control.
|
16 |
|
17 |
### Extensions ###
|
18 |
|
19 |
+
|
20 |
+
- [Groups Blog Protect](http://wordpress.org/extend/plugins/groups-blog-protect/) Protect access to blogs by group membership.
|
21 |
- [Groups File Access](http://www.itthinx.com/plugins/groups-file-access/) Groups File Access is an extension that allows to provide file download links for authorized users. Access to files is restricted to users by their group membership.
|
22 |
- [Groups Forums](http://www.itthinx.com/plugins/groups-forums/) A powerful and yet light-weight forum system.
|
23 |
- [Groups Jigoshop](http://jigoshop.com/product/subscriptions/) Groups integration for Jigoshop that supports memberships and subscriptions.
|
326 |
|
327 |
== Changelog ==
|
328 |
|
329 |
+
= 1.3.8 =
|
330 |
+
* Fix: using substitute wp_cache_switch_to_blog instead of deprecated function wp_cache_reset when available (from 3.5.0)
|
331 |
+
* Fix: don't show access restriction meta box on attachments, the option is added with the attachment fields (3.5 uses common post edit screen but save_post isn't triggered on attachments)
|
332 |
+
* Improvement: limiting choice of access restrictions to those the current user has
|
333 |
+
* Fix: restrict access to edit or delete posts based on the post's access restrictions
|
334 |
+
* Feature: added option to refresh capabilities
|
335 |
+
* Fix: replaced use of get_user_by() (memory leaks on large user sets) with query & added batch limit when adding users to Registered group on activation
|
336 |
+
|
337 |
= 1.3.7 =
|
338 |
* Fix: missing argument for meta box when saving a post
|
339 |
* Fix: Groups conflicting with other plugins adding columns to the Users screen (in the manage_users_custom_column filter) thanks to [Erwin](http://www.transpontine.com) who spotted this :)
|
440 |
|
441 |
== Upgrade Notice ==
|
442 |
|
443 |
+
= 1.3.8 =
|
444 |
+
* This release includes several fixes and improvements, including more limiting features for access restrictions.
|
445 |
+
|
446 |
= 1.3.7 =
|
447 |
* Please update, this includes fixes: missing argument for meta box when saving a post; Groups conflicting with other plugins adding columns to the Users screen.
|
448 |
|