root/tags/2.3.1/wp-includes/capabilities.php

Revision 5870, 12.4 kB (checked in by ryan, 1 year ago)

Space before slash to properly close br tag. Props tmountjr. fixes #4717

  • Property svn:eol-style set to native
Line 
1 <?php
2
3 class WP_Roles {
4     var $roles;
5
6     var $role_objects = array();
7     var $role_names = array();
8     var $role_key;
9     var $use_db = true;
10
11     function WP_Roles() {
12         $this->_init();
13     }
14
15     function _init () {
16         global $wpdb;
17         global $wp_user_roles;
18         $this->role_key = $wpdb->prefix . 'user_roles';
19         if ( ! empty($wp_user_roles) ) {
20             $this->roles = $wp_user_roles;
21             $this->use_db = false;
22         } else {
23             $this->roles = get_option($this->role_key);
24         }
25
26         if ( empty($this->roles) )
27             return;
28
29         $this->role_objects = array();
30         $this->role_names =  array();
31         foreach ($this->roles as $role => $data) {
32             $this->role_objects[$role] = new WP_Role($role, $this->roles[$role]['capabilities']);
33             $this->role_names[$role] = $this->roles[$role]['name'];
34         }
35     }
36
37     function add_role($role, $display_name, $capabilities = '') {
38         if ( isset($this->roles[$role]) )
39             return;
40
41         $this->roles[$role] = array(
42             'name' => $display_name,
43             'capabilities' => $capabilities);
44         if ( $this->use_db )
45             update_option($this->role_key, $this->roles);
46         $this->role_objects[$role] = new WP_Role($role, $capabilities);
47         $this->role_names[$role] = $display_name;
48         return $this->role_objects[$role];
49     }
50
51     function remove_role($role) {
52         if ( ! isset($this->role_objects[$role]) )
53             return;
54
55         unset($this->role_objects[$role]);
56         unset($this->role_names[$role]);
57         unset($this->roles[$role]);
58
59         if ( $this->use_db )
60             update_option($this->role_key, $this->roles);
61     }
62
63     function add_cap($role, $cap, $grant = true) {
64         $this->roles[$role]['capabilities'][$cap] = $grant;
65         if ( $this->use_db )
66             update_option($this->role_key, $this->roles);
67     }
68
69     function remove_cap($role, $cap) {
70         unset($this->roles[$role]['capabilities'][$cap]);
71         if ( $this->use_db )
72             update_option($this->role_key, $this->roles);
73     }
74
75     function &get_role($role) {
76         if ( isset($this->role_objects[$role]) )
77             return $this->role_objects[$role];
78         else
79             return null;
80     }
81
82     function get_names() {
83         return $this->role_names;
84     }
85
86     function is_role($role)
87     {
88         return isset($this->role_names[$role]);
89     }
90 }
91
92 class WP_Role {
93     var $name;
94     var $capabilities;
95
96     function WP_Role($role, $capabilities) {
97         $this->name = $role;
98         $this->capabilities = $capabilities;
99     }
100
101     function add_cap($cap, $grant = true) {
102         global $wp_roles;
103
104         if ( ! isset($wp_roles) )
105             $wp_roles = new WP_Roles();
106
107         $this->capabilities[$cap] = $grant;
108         $wp_roles->add_cap($this->name, $cap, $grant);
109     }
110
111     function remove_cap($cap) {
112         global $wp_roles;
113
114         if ( ! isset($wp_roles) )
115             $wp_roles = new WP_Roles();
116
117         unset($this->capabilities[$cap]);
118         $wp_roles->remove_cap($this->name, $cap);
119     }
120
121     function has_cap($cap) {
122         $capabilities = apply_filters('role_has_cap', $this->capabilities, $cap, $this->name);
123         if ( !empty($capabilities[$cap]) )
124             return $capabilities[$cap];
125         else
126             return false;
127     }
128
129 }
130
131 class WP_User {
132     var $data;
133     var $ID = 0;
134     var $id = 0; // Deprecated, use $ID instead.
135     var $caps = array();
136     var $cap_key;
137     var $roles = array();
138     var $allcaps = array();
139
140     function WP_User($id, $name = '') {
141         global $wpdb;
142
143         if ( empty($id) && empty($name) )
144             return;
145
146         if ( ! is_numeric($id) ) {
147             $name = $id;
148             $id = 0;
149         }
150
151         if ( ! empty($id) )
152             $this->data = get_userdata($id);
153         else
154             $this->data = get_userdatabylogin($name);
155
156         if ( empty($this->data->ID) )
157             return;
158
159         foreach (get_object_vars($this->data) as $key => $value) {
160             $this->{$key} = $value;
161         }
162
163         $this->id = $this->ID;
164         $this->_init_caps();
165     }
166
167     function _init_caps() {
168         global $wpdb;
169         $this->cap_key = $wpdb->prefix . 'capabilities';
170         $this->caps = &$this->{$this->cap_key};
171         if ( ! is_array($this->caps) )
172             $this->caps = array();
173         $this->get_role_caps();
174     }
175
176     function get_role_caps() {
177         global $wp_roles;
178
179         if ( ! isset($wp_roles) )
180             $wp_roles = new WP_Roles();
181
182         //Filter out caps that are not role names and assign to $this->roles
183         if(is_array($this->caps))
184             $this->roles = array_filter(array_keys($this->caps), array(&$wp_roles, 'is_role'));
185
186         //Build $allcaps from role caps, overlay user's $caps
187         $this->allcaps = array();
188         foreach( (array) $this->roles as $role) {
189             $role = $wp_roles->get_role($role);
190             $this->allcaps = array_merge($this->allcaps, $role->capabilities);
191         }
192         $this->allcaps = array_merge($this->allcaps, $this->caps);
193     }
194
195     function add_role($role) {
196         $this->caps[$role] = true;
197         update_usermeta($this->ID, $this->cap_key, $this->caps);
198         $this->get_role_caps();
199         $this->update_user_level_from_caps();
200     }
201
202     function remove_role($role) {
203         if ( empty($this->roles[$role]) || (count($this->roles) <= 1) )
204             return;
205         unset($this->caps[$role]);
206         update_usermeta($this->ID, $this->cap_key, $this->caps);
207         $this->get_role_caps();
208     }
209
210     function set_role($role) {
211         foreach($this->roles as $oldrole)
212             unset($this->caps[$oldrole]);
213         if ( !empty($role) ) {
214             $this->caps[$role] = true;
215             $this->roles = array($role => true);
216         } else {
217             $this->roles = false;
218         }
219         update_usermeta($this->ID, $this->cap_key, $this->caps);
220         $this->get_role_caps();
221         $this->update_user_level_from_caps();
222     }
223
224     function level_reduction($max, $item) {
225         if(preg_match('/^level_(10|[0-9])$/i', $item, $matches)) {
226             $level = intval($matches[1]);
227             return max($max, $level);
228         } else {
229             return $max;
230         }
231     }
232
233     function update_user_level_from_caps() {
234         global $wpdb;
235         $this->user_level = array_reduce(array_keys($this->allcaps),     array(&$this, 'level_reduction'), 0);
236         update_usermeta($this->ID, $wpdb->prefix.'user_level', $this->user_level);
237     }
238
239     function add_cap($cap, $grant = true) {
240         $this->caps[$cap] = $grant;
241         update_usermeta($this->ID, $this->cap_key, $this->caps);
242     }
243
244     function remove_cap($cap) {
245         if ( empty($this->caps[$cap]) ) return;
246         unset($this->caps[$cap]);
247         update_usermeta($this->ID, $this->cap_key, $this->caps);
248     }
249
250     function remove_all_caps() {
251         global $wpdb;
252         $this->caps = array();
253         update_usermeta($this->ID, $this->cap_key, '');
254         update_usermeta($this->ID, $wpdb->prefix.'user_level', '');
255         $this->get_role_caps();
256     }
257
258     //has_cap(capability_or_role_name) or
259     //has_cap('edit_post', post_id)
260     function has_cap($cap) {
261         if ( is_numeric($cap) )
262             $cap = $this->translate_level_to_cap($cap);
263
264         $args = array_slice(func_get_args(), 1);
265         $args = array_merge(array($cap, $this->ID), $args);
266         $caps = call_user_func_array('map_meta_cap', $args);
267         // Must have ALL requested caps
268         $capabilities = apply_filters('user_has_cap', $this->allcaps, $caps, $args);
269         foreach ($caps as $cap) {
270             //echo "Checking cap $cap<br />";
271             if(empty($capabilities[$cap]) || !$capabilities[$cap])
272                 return false;
273         }
274
275         return true;
276     }
277
278     function translate_level_to_cap($level) {
279         return 'level_' . $level;
280     }
281
282 }
283
284 // Map meta capabilities to primitive capabilities.
285 function map_meta_cap($cap, $user_id) {
286     $args = array_slice(func_get_args(), 2);
287     $caps = array();
288
289     switch ($cap) {
290     case 'delete_user':
291         $caps[] = 'delete_users';
292         break;
293     case 'edit_user':
294         $caps[] = 'edit_users';
295         break;
296     case 'delete_post':
297         $author_data = get_userdata($user_id);
298         //echo "post ID: {$args[0]}<br />";
299         $post = get_post($args[0]);
300         if ( 'page' == $post->post_type ) {
301             $args = array_merge(array('delete_page', $user_id), $args);
302             return call_user_func_array('map_meta_cap', $args);
303         }
304         $post_author_data = get_userdata($post->post_author);
305         //echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br />";
306         // If the user is the author...
307         if ($user_id == $post_author_data->ID) {
308             // If the post is published...
309             if ($post->post_status == 'publish')
310                 $caps[] = 'delete_published_posts';
311             else
312                 // If the post is draft...
313                 $caps[] = 'delete_posts';
314         } else {
315             // The user is trying to edit someone else's post.
316             $caps[] = 'delete_others_posts';
317             // The post is published, extra cap required.
318             if ($post->post_status == 'publish')
319                 $caps[] = 'delete_published_posts';
320             else if ($post->post_status == 'private')
321                 $caps[] = 'delete_private_posts';
322         }
323         break;
324     case 'delete_page':
325         $author_data = get_userdata($user_id);
326         //echo "post ID: {$args[0]}<br />";
327         $page = get_page($args[0]);
328         $page_author_data = get_userdata($page->post_author);
329         //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
330         // If the user is the author...
331         if ($user_id == $page_author_data->ID) {
332             // If the page is published...
333             if ($page->post_status == 'publish')
334                 $caps[] = 'delete_published_pages';
335             else
336                 // If the page is draft...
337                 $caps[] = 'delete_pages';
338         } else {
339             // The user is trying to edit someone else's page.
340             $caps[] = 'delete_others_pages';
341             // The page is published, extra cap required.
342             if ($page->post_status == 'publish')
343                 $caps[] = 'delete_published_pages';
344             else if ($page->post_status == 'private')
345                 $caps[] = 'delete_private_pages';
346         }
347         break;
348         // edit_post breaks down to edit_posts, edit_published_posts, or
349         // edit_others_posts
350     case 'edit_post':
351         $author_data = get_userdata($user_id);
352         //echo "post ID: {$args[0]}<br />";
353         $post = get_post($args[0]);
354         if ( 'page' == $post->post_type ) {
355             $args = array_merge(array('edit_page', $user_id), $args);
356             return call_user_func_array('map_meta_cap', $args);
357         }
358         $post_author_data = get_userdata($post->post_author);
359         //echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br />";
360         // If the user is the author...
361         if ($user_id == $post_author_data->ID) {
362             // If the post is published...
363             if ($post->post_status == 'publish')
364                 $caps[] = 'edit_published_posts';
365             else
366                 // If the post is draft...
367                 $caps[] = 'edit_posts';
368         } else {
369             // The user is trying to edit someone else's post.
370             $caps[] = 'edit_others_posts';
371             // The post is published, extra cap required.
372             if ($post->post_status == 'publish')
373                 $caps[] = 'edit_published_posts';
374             else if ($post->post_status == 'private')
375                 $caps[] = 'edit_private_posts';
376         }
377         break;
378     case 'edit_page':
379         $author_data = get_userdata($user_id);
380         //echo "post ID: {$args[0]}<br />";
381         $page = get_page($args[0]);
382         $page_author_data = get_userdata($page->post_author);
383         //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
384         // If the user is the author...
385         if ($user_id == $page_author_data->ID) {
386             // If the page is published...
387             if ($page->post_status == 'publish')
388                 $caps[] = 'edit_published_pages';
389             else
390                 // If the page is draft...
391                 $caps[] = 'edit_pages';
392         } else {
393             // The user is trying to edit someone else's page.
394             $caps[] = 'edit_others_pages';
395             // The page is published, extra cap required.
396             if ($page->post_status == 'publish')
397                 $caps[] = 'edit_published_pages';
398             else if ($page->post_status == 'private')
399                 $caps[] = 'edit_private_pages';
400         }
401         break;
402     case 'read_post':
403         $post = get_post($args[0]);
404         if ( 'page' == $post->post_type ) {
405             $args = array_merge(array('read_page', $user_id), $args);
406             return call_user_func_array('map_meta_cap', $args);
407         }
408
409         if ( 'private' != $post->post_status ) {
410             $caps[] = 'read';
411             break;
412         }
413
414         $author_data = get_userdata($user_id);
415         $post_author_data = get_userdata($post->post_author);
416         if ($user_id == $post_author_data->ID)
417             $caps[] = 'read';
418         else
419             $caps[] = 'read_private_posts';
420         break;
421     case 'read_page':
422         $page = get_page($args[0]);
423
424         if ( 'private' != $page->post_status ) {
425             $caps[] = 'read';
426             break;
427         }
428
429         $author_data = get_userdata($user_id);
430         $page_author_data = get_userdata($page->post_author);
431         if ($user_id == $page_author_data->ID)
432             $caps[] = 'read';
433         else
434             $caps[] = 'read_private_pages';
435         break;
436     default:
437         // If no meta caps match, return the original cap.
438         $caps[] = $cap;
439     }
440
441     return $caps;
442 }
443
444 // Capability checking wrapper around the global $current_user object.
445 function current_user_can($capability) {
446     $current_user = wp_get_current_user();
447
448     if ( empty($current_user) )
449         return false;
450
451     $args = array_slice(func_get_args(), 1);
452     $args = array_merge(array($capability), $args);
453
454     return call_user_func_array(array(&$current_user, 'has_cap'), $args);
455 }
456
457 // Convenience wrappers around $wp_roles.
458 function get_role($role) {
459     global $wp_roles;
460
461     if ( ! isset($wp_roles) )
462         $wp_roles = new WP_Roles();
463
464     return $wp_roles->get_role($role);
465 }
466
467 function add_role($role, $display_name, $capabilities = '') {
468     global $wp_roles;
469
470     if ( ! isset($wp_roles) )
471         $wp_roles = new WP_Roles();
472
473     return $wp_roles->add_role($role, $display_name, $capabilities);
474 }
475
476 function remove_role($role) {
477     global $wp_roles;
478
479     if ( ! isset($wp_roles) )
480         $wp_roles = new WP_Roles();
481
482     return $wp_roles->remove_role($role);
483 }
484
485 ?>
486
Note: See TracBrowser for help on using the browser.