Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 406 lines (314 sloc) 15.168 kB
6478115 branch 1.3.55 from http://plugins.svn.wordpress.org/role-scoper/tags/…
Matt Richmond authored
1 <?php
2 if( basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']) )
3 die();
4
5 require_once( dirname(__FILE__).'/lib/agapetry_config_items.php');
6
7 class CR_Roles extends AGP_Config_Items {
8 var $role_caps = array();
9 var $role_types = array();
10 var $display_names = array(); // display_names, abbrevs necessary for WP roles (supported for use by RS Extensions, but default role defs call ScoperRoleStrings functions instead
11 var $abbrevs = array();
12 var $micro_abbrevs = array();
13
14 function CR_Roles( $arr = '', $action_hook = '') {
15 $this->role_types = array( 'rs', 'wp' );
16 $this->AGP_Config_Items( $arr, $action_hook );
17 }
18
19 function get_display_name( $role_handle, $context = '' ) {
20 if ( isset( $this->display_names[$role_handle] ) )
21 return $this->display_names[$role_handle];
22
23 require_once( dirname(__FILE__).'/roles-strings_rs.php' );
24 return ScoperRoleStrings::get_display_name( $role_handle, $context );
25 }
26
27 function get_abbrev( $role_handle, $context = '' ) {
28 if ( isset( $this->abbrevs[$role_handle] ) )
29 return $this->abbrevs[$role_handle];
30
31 require_once( dirname(__FILE__).'/roles-strings_rs.php' );
32 return ScoperRoleStrings::get_abbrev( $role_handle, $context );
33 }
34
35 function get_micro_abbrev( $role_handle, $context = '' ) {
36 if ( isset( $this->micro_abbrevs[$role_handle] ) )
37 return $this->micro_abbrevs[$role_handle];
38
39 require_once( dirname(__FILE__).'/roles-strings_rs.php' );
40
41 if( ! $return = ScoperRoleStrings::get_micro_abbrev( $role_handle, $context ) )
42 $return = ScoperRoleStrings::get_abbrev( $role_handle, $context );
43
44 return $return;
45 }
46
47 function &add($name, $defining_module, $display_name = '', $abbrev = '', $role_type = 'rs', $args = array()) {
48 if ( $this->locked ) {
49 $notice = sprintf('A plugin or theme (%1$s) is too late in its attempt to define a role (%2$s).', $defining_module, $name)
50 . '<br /><br />' . 'This must be done via the define_roles_rs hook.';
51 rs_notice($notice);
52 return;
53 }
54
55 $key = ( $name == ANON_ROLEHANDLE_RS ) ? $name : scoper_get_role_handle($name, $role_type);
56
57 if ( 'wp' == $role_type ) {
58 if ( ! $display_name )
59 $display_name = ucwords( str_replace('_', ' ', $name) );
60
61 if ( ! $abbrev )
62 $abbrev = $display_name;
63 }
64
65 if ( $display_name )
66 $this->display_names[$key] = $display_name;
67
68 if ( $abbrev )
69 $this->abbrevs[$key] = $abbrev;
70
71 if ( isset($this->members[$key]) )
72 unset($this->members[$key]);
73
74 $this->members[$key] = new CR_Role($name, $defining_module, $role_type, $args);
75 $this->process($this->members[$key]);
76
77 return $this->members[$key];
78 }
79
80 function process( &$role_def ) {
81 // role type was prefixed for array key, but should remove for name property
82 foreach ( $this->role_types as $role_type ) {
83 $role_def->name = str_replace("{$role_type}_", '', $role_def->name);
84 }
85
86 if ( ! isset($role_def->valid_scopes) )
87 $role_def->valid_scopes = array('blog' => 1, 'term' => 1, 'object' => 1);
88
89 if ( ! isset($role_def->src_name) )
90 $role_def->src_name = '';
91
92 if ( ! isset($role_def->object_type) )
93 $role_def->object_type = ( 'rs' == $role_def->role_type ) ? $role_def->src_name : '';
94 }
95
96 function add_role_caps( $user_role_caps ) {
97 if ( ! is_array( $user_role_caps ) )
98 return;
99
100 foreach( array_keys( $user_role_caps ) as $role_handle ) {
101 if ( $user_role_caps[$role_handle] ) {
102 if( isset( $this->role_caps[$role_handle] ) )
103 $this->role_caps[$role_handle] = array_merge($this->role_caps[$role_handle], $user_role_caps[$role_handle]);
104 else
105 $this->role_caps[$role_handle] = $user_role_caps[$role_handle];
106 }
107 }
108 }
109
110 function remove_role_caps( $disabled_role_caps ) {
111 if ( ! is_array( $disabled_role_caps ) )
112 return;
113
114 foreach ( array_keys($this->role_caps) as $role_handle )
115 if ( ! empty($disabled_role_caps[$role_handle]) )
116 $this->role_caps[$role_handle] = array_diff_key($this->role_caps[$role_handle], $disabled_role_caps[$role_handle]);
117 }
118
119 function get_for_taxonomy($src, $taxonomy = '', $args = array()) {
120 $defaults = array( 'one_otype_per_role' => true, 'ignore_usage_settings' => false );
121 $args = array_merge( $defaults, (array) $args );
122 extract($args);
123
124 if ( ! is_object($src) )
125 $src = $GLOBALS['scoper']->data_sources->get($src);
126
127 if ( ! $src)
128 return;
129
130 $otype_roles = array();
131
132 if ( ! in_array( $taxonomy, array( 'category', 'post_tag' ) ) && $one_otype_per_role ) {
133 if ( $tx = get_taxonomy( $taxonomy ) )
134 if ( ! empty( $tx->object_type ) )
135 $use_otypes = array_unique( (array) $tx->object_type );
136 }
137
138 if ( empty( $use_otypes ) )
139 $use_otypes = array_keys($src->object_types);
140
141 foreach ( $use_otypes as $object_type ) {
142 $use_term_roles = scoper_get_otype_option('use_term_roles', $src->name, $object_type);
143
144 if ( ! $ignore_usage_settings && empty($use_term_roles[$taxonomy]) )
145 continue;
146
147 if ( $roles = $this->get_matching( 'rs', $src->name, $object_type ) ) {
148 if ( $one_otype_per_role )
149 foreach ( array_keys($otype_roles) as $existing_object_type )
150 $roles = array_diff_key($roles, $otype_roles[$existing_object_type]);
151
152 $otype_roles[$object_type] = $roles;
153 }
154 }
155
156 //note: term roles are defined with src_name property corresponding to their object source (i.e. manage_categories has src_name 'post')
157 if ( $taxonomy ) {
158 if ( $roles = $this->get_matching( 'rs', $src->name, $taxonomy ) ) {
159 if ( $one_otype_per_role )
160 foreach ( array_keys($otype_roles) as $object_type )
161 $roles = array_diff_key($roles, $otype_roles[$object_type]);
162
163 if ( $roles )
164 $otype_roles[$taxonomy] = $roles;
165 }
166 }
167
168 return $otype_roles;
169 }
170
171 function add_containing_roles($roles, $role_type = '') {
172 $return_roles = $roles;
173
174 foreach ( array_keys($roles) as $role_handle )
175 if ( $containing = $this->get_containing_roles($role_handle, $role_type) )
176 $return_roles = array_merge($return_roles, $containing);
177
178 return $return_roles;
179 }
180
181 // returns array with role handles as keys
182 function get_containing_roles($role_handle, $role_type = '') {
183 if ( ! isset($this->role_caps[$role_handle]) || ! is_array($this->role_caps[$role_handle]) )
184 return array();
185
186 $containing_roles = array();
187 foreach ( array_keys($this->role_caps) as $other_role_handle )
188 if ( $other_role_handle != $role_handle )
189 if ( ! array_diff_key($this->role_caps[$role_handle], $this->role_caps[$other_role_handle]) )
190 $containing_roles[$other_role_handle] = 1;
191
192 if ( $containing_roles && $role_type )
193 $containing_roles = $this->filter_keys( array_keys($containing_roles), array( 'role_type' => $role_type ), 'names_as_key' );
194
195 return $containing_roles;
196 }
197
198 // returns array with role handles as key
199 function get_contained_roles($role_handles, $include_this_role = false, $role_type = '') {
200 if ( ! $role_handles )
201 return array();
202
203 $role_handles = (array) $role_handles;
204
205 $contained_roles = array();
206
207 foreach ( $role_handles as $role_handle ) {
208 if ( ! isset($this->role_caps[$role_handle]) )
209 continue;
210
211 $role_attributes = $this->get_role_attributes( $role_handle );
212
213 foreach ( array_keys($this->role_caps) as $other_role_handle ) {
214 if ( ( ($other_role_handle != $role_handle) || $include_this_role ) ) {
215 if ( $this->role_caps[$other_role_handle] ) { // don't take credit for including roles that have no pertinent caps
216 if ( ! array_diff_key($this->role_caps[$other_role_handle], $this->role_caps[$role_handle]) ) {
217 // role caps qualify, but only count RS roles of matching object type
218 if ( 'rs' == $role_attributes->role_type ) {
219 if ( $role_attributes->object_type != $this->member_property( $other_role_handle, 'object_type' ) )
220 continue;
221 }
222
223 $contained_roles[$other_role_handle] = 1;
224 }
225 }
226 }
227 }
228 }
229
230 if ( $role_type && $contained_roles )
231 $contained_roles = $this->filter_keys( array_keys($contained_roles), array( 'role_type' => $role_type ), 'names_as_key' );
232
233 if ( $contained_roles && ! $include_this_role )
234 $contained_roles = array_diff_key( $contained_roles, array_flip($role_handles) );
235
236 return $contained_roles;
237 }
238
239 // returns array of role objects
240 function add_contained_roles($assigned) {
241 if ( empty($assigned) )
242 return array();
243
244 $assigned = (array) $assigned;
245
246 $roles = $assigned;
247 foreach ( array_keys($assigned) as $assigned_role_handle ) {
248 if ( $contained_roles = $this->get_contained_roles($assigned_role_handle) )
249 $roles = array_merge( $roles, $contained_roles );
250 }
251
252 return $roles;
253 }
254
255 // returns array[role_handle] = array of term ids
256 function add_contained_term_roles($assigned) {
257 if ( empty($assigned) )
258 return array();
259
260 $assigned = (array) $assigned;
261
262 $role_terms = $assigned;
263
264 // $assigned[role_key] = array of terms for which the role is assigned.
265 // Add contained roles directly into the provided assigned_roles array
266 foreach ( $assigned as $assigned_role_handle => $terms ) {
267
268 // if a user has role assigned for term(s), he also effectively has all its contained roles assigned for same term(s)
269 foreach ( array_keys( $this->get_contained_roles($assigned_role_handle, true) ) as $contained_role_handle ) {
270
271 // may or may not already have roles assigned explicitly or via containment in another assigned role
272 if ( ! isset($role_terms[$contained_role_handle]) )
273 $role_terms[$contained_role_handle] = $terms;
274 else
275 $role_terms[$contained_role_handle] = array_unique( array_merge($role_terms[$contained_role_handle], $terms) );
276 }
277 }
278
279 return $role_terms;
280 }
281
282 // reqd_caps: array of cap names and/or role handles. Role handle format is {$role_type}_{role_name}
283 function role_handles_to_caps($reqd_caps, $find_unprefixed_wproles = false) {
284 foreach ( $reqd_caps as $role_handle ) {
285 if ( isset($this->role_caps[$role_handle]) ) {
286 $reqd_caps = array_merge( $reqd_caps, array_keys($this->role_caps[$role_handle]) );
287 $reqd_caps = array_diff( $reqd_caps, array($role_handle) );
288 }
289 }
290
291 if ( $find_unprefixed_wproles ) {
292 global $wp_roles;
293 foreach ( $reqd_caps as $role_name ) {
294 if ( isset($wp_roles->role_objects[$role_name]->capabilities ) ) {
295 $reqd_caps = array_merge( $reqd_caps, array_keys($wp_roles->role_objects[$role_name]->capabilities) );
296 $reqd_caps = array_diff( $reqd_caps, array($role_name) );
297 }
298 }
299 }
300
301 return array_unique($reqd_caps);
302 }
303
304 function get_role_attributes( $role_handle ) {
305 $attribs = (object) array( 'role_type' => '', 'src_name' => '', 'object_type' => '' );
306
307 if ( isset( $this->members[$role_handle] ) ) {
308 $attribs->role_type = $this->members[$role_handle]->role_type;
309
310 if ( 'rs' == $attribs->role_type ) {
311 $attribs->src_name = $this->members[$role_handle]->src_name;
312 $attribs->object_type = $this->members[$role_handle]->object_type;
313 }
314 }
315
316 return $attribs;
317 }
318
319 // returns array of Role_Defs objects which match the specified parameters
320 function get_matching($role_types = '', $src_names = '', $object_types = '' ) {
321 if ( $role_handles = $this->qualify_roles( '', $role_types, $object_types, array( 'src_name' => $src_names ) ) )
322 return array_intersect_key( $this->members, $role_handles );
323 else
324 return array();
325 }
326
327 // $reqd_caps = single cap name string OR array of cap name strings
328 // returns array of role_handles
329 function qualify_roles($reqd_caps, $role_type = 'rs', $object_type = '', $args = array()) {
330 $defaults = array( 'src_name' => '', 'all_wp_caps' => false );
331 $args = array_merge( $defaults, (array) $args );
332 extract($args);
333
334 $good_roles = array();
335
336 if ( $reqd_caps )
337 $reqd_caps = $this->role_handles_to_caps( (array) $reqd_caps, true); // arg: also check for unprefixed WP rolenames
338
339 if ( $role_type )
340 $role_handles = $this->filter_keys( array_keys($this->members), array( 'role_type' => $role_type ) );
341 else
342 $role_handles = array_keys($this->members);
343
344 foreach ( $role_handles as $role_handle ) {
345 if ( $reqd_caps ) {
346 if ( $all_wp_caps && ( 0 === strpos( $role_handle, 'wp_' ) ) ) {
347 if ( empty( $GLOBALS['wp_roles']->role_objects[ substr($role_handle, 3) ]->capabilities )
348 || array_diff( $reqd_caps, array_keys( $GLOBALS['wp_roles']->role_objects[ substr($role_handle, 3) ]->capabilities ) ) ) // note: this does not observe "false" value in capabilities array
349 continue;
350 } else {
351 if ( empty( $this->role_caps[$role_handle] ) || array_diff( $reqd_caps, array_keys( $this->role_caps[$role_handle] ) ) )
352 continue;
353 }
354 }
355
356 // The required caps test passed or was not applied. Now verify data source and/or object type, if specified...
357 if ( 'rs' == $this->members[$role_handle]->role_type ) {
358 // data source and object type matching only apply to RS roles, which always have a single data source and object type defined
359 if ( $src_name && ! in_array( $this->members[$role_handle]->src_name, (array) $src_name ) )
360 continue;
361
362 // the role qualifies unless its object type is a mismatch
363 if ( $object_type && ! in_array( $this->members[$role_handle]->object_type, (array) $object_type ) )
364 continue;
365 }
366
367 $good_roles[$role_handle] = 1;
368 }
369
370 return $good_roles;
371 }
372
373
374 // Currently, new custom-defined post, page or link roles are problematic because objects or categories with all roles restricted
375 // will suddenly be non-restricted to users whose WP role contains the newly defined RS role.
376 //
377 // TODO: make all custom-defined roles default restricted
378 function remove_invalid() {
379 return;
380
381 /*
382 if ( $custom_members = array_diff_key( $this->members, array_fill_keys( array( 'rs_post_reader', 'rs_private_post_reader', 'rs_post_contributor', 'rs_post_author', 'rs_post_revisor', 'rs_post_editor', 'rs_page_reader', 'rs_private_page_reader', 'rs_page_contributor', 'rs_page_author', 'rs_page_revisor', 'rs_page_editor', 'rs_page_associate', 'rs_link_editor', 'rs_category_manager', 'rs_group_manager' ), true ) ) ) {
383 foreach ( $custom_members as $role_handle => $role_def ) {
384 if ( ( 'post' == $role_def->src_name ) && in_array( $role_def->object_type, array( 'post', 'page' ) )
385 || ( ( 'link' == $role_def->src_name ) && ( 'link' == $role_def->object_type ) ) )
386 unset( $this->members[$role_handle] );
387 }
388 }
389 */
390 }
391 } // end class CR_Roles
392
393 class CR_Role extends AGP_Config_Item {
394 var $role_type;
395 var $src_name;
396 var $object_type;
397 var $valid_scopes;
398 var $objscope_equivalents;
399
400 function CR_Role($name, $defining_module, $role_type = 'rs', $args = array() ) {
401 $this->AGP_Config_Item($name, $defining_module, $args);
402
403 $this->role_type = $role_type;
404 }
405 }
406 ?>
Something went wrong with that request. Please try again.