Wordpress 2.6.2
[autoinstalls/wordpress.git] / wp-includes / capabilities.php
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 = array()) {
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
142                 if ( empty($id) && empty($name) )
143                         return;
144
145                 if ( ! is_numeric($id) ) {
146                         $name = $id;
147                         $id = 0;
148                 }
149
150                 if ( ! empty($id) )
151                         $this->data = get_userdata($id);
152                 else
153                         $this->data = get_userdatabylogin($name);
154
155                 if ( empty($this->data->ID) )
156                         return;
157
158                 foreach (get_object_vars($this->data) as $key => $value) {
159                         $this->{$key} = $value;
160                 }
161
162                 $this->id = $this->ID;
163                 $this->_init_caps();
164         }
165
166         function _init_caps() {
167                 global $wpdb;
168                 $this->cap_key = $wpdb->prefix . 'capabilities';
169                 $this->caps = &$this->{$this->cap_key};
170                 if ( ! is_array($this->caps) )
171                         $this->caps = array();
172                 $this->get_role_caps();
173         }
174
175         function get_role_caps() {
176                 global $wp_roles;
177
178                 if ( ! isset($wp_roles) )
179                         $wp_roles = new WP_Roles();
180
181                 //Filter out caps that are not role names and assign to $this->roles
182                 if(is_array($this->caps))
183                         $this->roles = array_filter(array_keys($this->caps), array(&$wp_roles, 'is_role'));
184
185                 //Build $allcaps from role caps, overlay user's $caps
186                 $this->allcaps = array();
187                 foreach( (array) $this->roles as $role) {
188                         $role = $wp_roles->get_role($role);
189                         $this->allcaps = array_merge($this->allcaps, $role->capabilities);
190                 }
191                 $this->allcaps = array_merge($this->allcaps, $this->caps);
192         }
193
194         function add_role($role) {
195                 $this->caps[$role] = true;
196                 update_usermeta($this->ID, $this->cap_key, $this->caps);
197                 $this->get_role_caps();
198                 $this->update_user_level_from_caps();
199         }
200
201         function remove_role($role) {
202                 if ( empty($this->roles[$role]) || (count($this->roles) <= 1) )
203                         return;
204                 unset($this->caps[$role]);
205                 update_usermeta($this->ID, $this->cap_key, $this->caps);
206                 $this->get_role_caps();
207         }
208
209         function set_role($role) {
210                 foreach($this->roles as $oldrole)
211                         unset($this->caps[$oldrole]);
212                 if ( !empty($role) ) {
213                         $this->caps[$role] = true;
214                         $this->roles = array($role => true);
215                 } else {
216                         $this->roles = false;
217                 }
218                 update_usermeta($this->ID, $this->cap_key, $this->caps);
219                 $this->get_role_caps();
220                 $this->update_user_level_from_caps();
221         }
222
223         function level_reduction($max, $item) {
224                 if(preg_match('/^level_(10|[0-9])$/i', $item, $matches)) {
225                         $level = intval($matches[1]);
226                         return max($max, $level);
227                 } else {
228                         return $max;
229                 }
230         }
231
232         function update_user_level_from_caps() {
233                 global $wpdb;
234                 $this->user_level = array_reduce(array_keys($this->allcaps),    array(&$this, 'level_reduction'), 0);
235                 update_usermeta($this->ID, $wpdb->prefix.'user_level', $this->user_level);
236         }
237
238         function add_cap($cap, $grant = true) {
239                 $this->caps[$cap] = $grant;
240                 update_usermeta($this->ID, $this->cap_key, $this->caps);
241         }
242
243         function remove_cap($cap) {
244                 if ( empty($this->caps[$cap]) ) return;
245                 unset($this->caps[$cap]);
246                 update_usermeta($this->ID, $this->cap_key, $this->caps);
247         }
248
249         function remove_all_caps() {
250                 global $wpdb;
251                 $this->caps = array();
252                 update_usermeta($this->ID, $this->cap_key, '');
253                 update_usermeta($this->ID, $wpdb->prefix.'user_level', '');
254                 $this->get_role_caps();
255         }
256
257         //has_cap(capability_or_role_name) or
258         //has_cap('edit_post', post_id)
259         function has_cap($cap) {
260                 if ( is_numeric($cap) )
261                         $cap = $this->translate_level_to_cap($cap);
262
263                 $args = array_slice(func_get_args(), 1);
264                 $args = array_merge(array($cap, $this->ID), $args);
265                 $caps = call_user_func_array('map_meta_cap', $args);
266                 // Must have ALL requested caps
267                 $capabilities = apply_filters('user_has_cap', $this->allcaps, $caps, $args);
268                 foreach ($caps as $cap) {
269                         //echo "Checking cap $cap<br />";
270                         if(empty($capabilities[$cap]) || !$capabilities[$cap])
271                                 return false;
272                 }
273
274                 return true;
275         }
276
277         function translate_level_to_cap($level) {
278                 return 'level_' . $level;
279         }
280
281 }
282
283 // Map meta capabilities to primitive capabilities.
284 function map_meta_cap($cap, $user_id) {
285         $args = array_slice(func_get_args(), 2);
286         $caps = array();
287
288         switch ($cap) {
289         case 'delete_user':
290                 $caps[] = 'delete_users';
291                 break;
292         case 'edit_user':
293                 if ( !isset($args[0]) || $user_id != $args[0] ) {
294                         $caps[] = 'edit_users';
295                 }
296                 break;
297         case 'delete_post':
298                 $author_data = get_userdata($user_id);
299                 //echo "post ID: {$args[0]}<br />";
300                 $post = get_post($args[0]);
301                 if ( 'page' == $post->post_type ) {
302                         $args = array_merge(array('delete_page', $user_id), $args);
303                         return call_user_func_array('map_meta_cap', $args);
304                 }
305                 $post_author_data = get_userdata($post->post_author);
306                 //echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br />";
307                 // If the user is the author...
308                 if ($user_id == $post_author_data->ID) {
309                         // If the post is published...
310                         if ($post->post_status == 'publish')
311                                 $caps[] = 'delete_published_posts';
312                         else
313                                 // If the post is draft...
314                                 $caps[] = 'delete_posts';
315                 } else {
316                         // The user is trying to edit someone else's post.
317                         $caps[] = 'delete_others_posts';
318                         // The post is published, extra cap required.
319                         if ($post->post_status == 'publish')
320                                 $caps[] = 'delete_published_posts';
321                         else if ($post->post_status == 'private')
322                                 $caps[] = 'delete_private_posts';
323                 }
324                 break;
325         case 'delete_page':
326                 $author_data = get_userdata($user_id);
327                 //echo "post ID: {$args[0]}<br />";
328                 $page = get_page($args[0]);
329                 $page_author_data = get_userdata($page->post_author);
330                 //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
331                 // If the user is the author...
332                 if ($user_id == $page_author_data->ID) {
333                         // If the page is published...
334                         if ($page->post_status == 'publish')
335                                 $caps[] = 'delete_published_pages';
336                         else
337                                 // If the page is draft...
338                                 $caps[] = 'delete_pages';
339                 } else {
340                         // The user is trying to edit someone else's page.
341                         $caps[] = 'delete_others_pages';
342                         // The page is published, extra cap required.
343                         if ($page->post_status == 'publish')
344                                 $caps[] = 'delete_published_pages';
345                         else if ($page->post_status == 'private')
346                                 $caps[] = 'delete_private_pages';
347                 }
348                 break;
349                 // edit_post breaks down to edit_posts, edit_published_posts, or
350                 // edit_others_posts
351         case 'edit_post':
352                 $author_data = get_userdata($user_id);
353                 //echo "post ID: {$args[0]}<br />";
354                 $post = get_post($args[0]);
355                 if ( 'page' == $post->post_type ) {
356                         $args = array_merge(array('edit_page', $user_id), $args);
357                         return call_user_func_array('map_meta_cap', $args);
358                 }
359                 $post_author_data = get_userdata($post->post_author);
360                 //echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br />";
361                 // If the user is the author...
362                 if ($user_id == $post_author_data->ID) {
363                         // If the post is published...
364                         if ($post->post_status == 'publish')
365                                 $caps[] = 'edit_published_posts';
366                         else
367                                 // If the post is draft...
368                                 $caps[] = 'edit_posts';
369                 } else {
370                         // The user is trying to edit someone else's post.
371                         $caps[] = 'edit_others_posts';
372                         // The post is published, extra cap required.
373                         if ($post->post_status == 'publish')
374                                 $caps[] = 'edit_published_posts';
375                         else if ($post->post_status == 'private')
376                                 $caps[] = 'edit_private_posts';
377                 }
378                 break;
379         case 'edit_page':
380                 $author_data = get_userdata($user_id);
381                 //echo "post ID: {$args[0]}<br />";
382                 $page = get_page($args[0]);
383                 $page_author_data = get_userdata($page->post_author);
384                 //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
385                 // If the user is the author...
386                 if ($user_id == $page_author_data->ID) {
387                         // If the page is published...
388                         if ($page->post_status == 'publish')
389                                 $caps[] = 'edit_published_pages';
390                         else
391                                 // If the page is draft...
392                                 $caps[] = 'edit_pages';
393                 } else {
394                         // The user is trying to edit someone else's page.
395                         $caps[] = 'edit_others_pages';
396                         // The page is published, extra cap required.
397                         if ($page->post_status == 'publish')
398                                 $caps[] = 'edit_published_pages';
399                         else if ($page->post_status == 'private')
400                                 $caps[] = 'edit_private_pages';
401                 }
402                 break;
403         case 'read_post':
404                 $post = get_post($args[0]);
405                 if ( 'page' == $post->post_type ) {
406                         $args = array_merge(array('read_page', $user_id), $args);
407                         return call_user_func_array('map_meta_cap', $args);
408                 }
409
410                 if ( 'private' != $post->post_status ) {
411                         $caps[] = 'read';
412                         break;
413                 }
414
415                 $author_data = get_userdata($user_id);
416                 $post_author_data = get_userdata($post->post_author);
417                 if ($user_id == $post_author_data->ID)
418                         $caps[] = 'read';
419                 else
420                         $caps[] = 'read_private_posts';
421                 break;
422         case 'read_page':
423                 $page = get_page($args[0]);
424
425                 if ( 'private' != $page->post_status ) {
426                         $caps[] = 'read';
427                         break;
428                 }
429
430                 $author_data = get_userdata($user_id);
431                 $page_author_data = get_userdata($page->post_author);
432                 if ($user_id == $page_author_data->ID)
433                         $caps[] = 'read';
434                 else
435                         $caps[] = 'read_private_pages';
436                 break;
437         default:
438                 // If no meta caps match, return the original cap.
439                 $caps[] = $cap;
440         }
441
442         return $caps;
443 }
444
445 // Capability checking wrapper around the global $current_user object.
446 function current_user_can($capability) {
447         $current_user = wp_get_current_user();
448
449         if ( empty($current_user) )
450                 return false;
451
452         $args = array_slice(func_get_args(), 1);
453         $args = array_merge(array($capability), $args);
454
455         return call_user_func_array(array(&$current_user, 'has_cap'), $args);
456 }
457
458 // Convenience wrappers around $wp_roles.
459 function get_role($role) {
460         global $wp_roles;
461
462         if ( ! isset($wp_roles) )
463                 $wp_roles = new WP_Roles();
464
465         return $wp_roles->get_role($role);
466 }
467
468 function add_role($role, $display_name, $capabilities = array()) {
469         global $wp_roles;
470
471         if ( ! isset($wp_roles) )
472                 $wp_roles = new WP_Roles();
473
474         return $wp_roles->add_role($role, $display_name, $capabilities);
475 }
476
477 function remove_role($role) {
478         global $wp_roles;
479
480         if ( ! isset($wp_roles) )
481                 $wp_roles = new WP_Roles();
482
483         return $wp_roles->remove_role($role);
484 }
485
486 ?>