Wordpress 2.3.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 = '') {
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 ?>