Changeset 13576
- Timestamp:
- 03/03/2010 07:08:30 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-admin/includes/schema.php
r13564 r13576 147 147 KEY post_name (post_name), 148 148 KEY type_status_date (post_type,post_status,post_date,ID), 149 KEY post_parent (post_parent) 149 KEY post_parent (post_parent), 150 KEY post_author (post_author) 150 151 ) $charset_collate; 151 152 CREATE TABLE $wpdb->users ( -
trunk/wp-admin/includes/template.php
r13536 r13576 1825 1825 1826 1826 /** 1827 * {@internal Missing Short Description}} 1828 * 1829 * @since unknown 1830 * 1831 * @param unknown_type $user_object 1832 * @param unknown_type $style 1833 * @param unknown_type $role 1834 * @return unknown 1835 */ 1836 function user_row( $user_object, $style = '', $role = '' ) { 1827 * Generate HTML for a single row on the users.php admin panel. 1828 * 1829 * @since 2.1.0 1830 * 1831 * @param object $user_object 1832 * @param string $style Optional. Attributes added to the TR element. Must be sanitized. 1833 * @param string $role Key for the $wp_roles array. 1834 * @param int $numposts Optional. Post count to display for this user. Defaults to zero, as in, a new user has made zero posts. 1835 * @return string 1836 */ 1837 function user_row( $user_object, $style = '', $role = '', $numposts = 0 ) { 1837 1838 global $wp_roles; 1838 1839 … … 1850 1851 if ( strlen( $short_url ) > 35 ) 1851 1852 $short_url = substr( $short_url, 0, 32 ).'...'; 1852 $numposts = get_usernumposts( $user_object->ID );1853 1853 $checkbox = ''; 1854 1854 // Check if the user for this row is editable -
trunk/wp-admin/users.php
r12916 r13576 209 209 $role = isset($_GET['role']) ? $_GET['role'] : null; 210 210 211 // Query the user s211 // Query the user IDs for this page 212 212 $wp_user_search = new WP_User_Search($usersearch, $userspage, $role); 213 214 // Query the post counts for this page 215 $post_counts = count_many_users_posts($wp_user_search->get_results()); 216 217 // Query the users for this page 218 cache_users($wp_user_search->get_results()); 213 219 214 220 $messages = array(); … … 264 270 <ul class="subsubsub"> 265 271 <?php 266 $role_links = array(); 267 $avail_roles = array(); 268 $users_of_blog = get_users_of_blog(); 269 $total_users = count( $users_of_blog ); 270 foreach ( (array) $users_of_blog as $b_user ) { 271 $b_roles = unserialize($b_user->meta_value); 272 foreach ( (array) $b_roles as $b_role => $val ) { 273 if ( !isset($avail_roles[$b_role]) ) 274 $avail_roles[$b_role] = 0; 275 $avail_roles[$b_role]++; 276 } 277 } 272 $users_of_blog = count_users(); 273 $total_users = $users_of_blog['total_users']; 274 $avail_roles =& $users_of_blog['avail_roles']; 278 275 unset($users_of_blog); 279 276 280 277 $current_role = false; 281 278 $class = empty($role) ? ' class="current"' : ''; 279 $role_links = array(); 282 280 $role_links[] = "<li><a href='users.php'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>'; 283 281 foreach ( $wp_roles->get_names() as $this_role => $name ) { … … 373 371 374 372 $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"'; 375 echo "\n\t" . user_row($user_object, $style, $role);373 echo "\n\t", user_row($user_object, $style, $role, $post_counts[(string)$userid]); 376 374 } 377 375 ?> -
trunk/wp-includes/author-template.php
r12699 r13576 152 152 * @since 1.5 153 153 * @uses $post The current post in the Loop's DB object. 154 * @uses get_usernumposts()154 * @uses count_user_posts() 155 155 * @return int The number of posts by the author. 156 156 */ 157 157 function get_the_author_posts() { 158 158 global $post; 159 return get_usernumposts($post->post_author);159 return count_user_posts($post->post_author); 160 160 } 161 161 -
trunk/wp-includes/pluggable.php
r13560 r13576 137 137 138 138 return $user; 139 } 140 endif; 141 142 if ( !function_exists('cache_users') ) : 143 /** 144 * Retrieve info for user lists to prevent multiple queries by get_userdata() 145 * 146 * @since 3.0.0 147 * 148 * @param array $users User ID numbers list 149 */ 150 function cache_users( $users ) { 151 global $wpdb; 152 153 $clean = array(); 154 foreach($users as $id) { 155 $id = (int) $id; 156 if (wp_cache_get($id, 'users')) { 157 // seems to be cached already 158 } else { 159 $clean[] = $id; 160 } 161 } 162 163 if ( 0 == count($clean) ) 164 return; 165 166 $list = implode(',', $clean); 167 168 $results = $wpdb->get_results("SELECT * FROM $wpdb->users WHERE ID IN ($list)"); 169 170 _fill_many_users($results); 139 171 } 140 172 endif; -
trunk/wp-includes/post.php
r13424 r13576 3653 3653 */ 3654 3654 function get_private_posts_cap_sql($post_type) { 3655 global $user_ID; 3656 $cap = ''; 3655 return get_posts_by_author_sql($post_type, FALSE); 3656 } 3657 3658 /** 3659 * Retrieve the post SQL based on capability, author, and type. 3660 * 3661 * See above for full description. 3662 * 3663 * @since 3.0.0 3664 * @param string $post_type currently only supports 'post' or 'page'. 3665 * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term. 3666 * @param int $post_author Optional. Query posts having a single author ID. 3667 * @return string SQL WHERE code that can be added to a query. 3668 */ 3669 function get_posts_by_author_sql($post_type, $full = TRUE, $post_author = NULL) { 3670 global $user_ID, $wpdb; 3657 3671 3658 3672 // Private posts … … 3664 3678 // Dunno what it is, maybe plugins have their own post type? 3665 3679 } else { 3680 $cap = ''; 3666 3681 $cap = apply_filters('pub_priv_sql_capability', $cap); 3667 3682 … … 3669 3684 // We don't know what it is, filters don't change anything, 3670 3685 // so set the SQL up to return nothing. 3671 return '1 = 0'; 3672 } 3673 } 3674 3675 $sql = '(post_status = \'publish\''; 3686 return ' 1 = 0 '; 3687 } 3688 } 3689 3690 if ($full) { 3691 if (is_null($post_author)) { 3692 $sql = $wpdb->prepare('WHERE post_type = %s AND ', $post_type); 3693 } else { 3694 $sql = $wpdb->prepare('WHERE post_author = %d AND post_type = %s AND ', $post_author, $post_type); 3695 } 3696 } else { 3697 $sql = ''; 3698 } 3699 3700 $sql .= "(post_status = 'publish'"; 3676 3701 3677 3702 if (current_user_can($cap)) { 3678 3703 // Does the user have the capability to view private posts? Guess so. 3679 $sql .= ' OR post_status = \'private\'';3704 $sql .= " OR post_status = 'private'"; 3680 3705 } elseif (is_user_logged_in()) { 3681 3706 // Users can view their own private posts. 3682 $sql .= ' OR post_status = \'private\' AND post_author = \'' . $user_ID . '\''; 3683 } 3707 $id = (int) $user_ID; 3708 if (is_null($post_author) || !$full) { 3709 $sql .= " OR post_status = 'private' AND post_author = $id"; 3710 } elseif ($id == (int)$post_author) { 3711 $sql .= " OR post_status = 'private'"; 3712 } // else none 3713 } // else none 3684 3714 3685 3715 $sql .= ')'; -
trunk/wp-includes/user.php
r13553 r13576 149 149 * @return int Amount of posts user has written. 150 150 */ 151 function get_usernumposts($userid) {151 function count_user_posts($userid) { 152 152 global $wpdb; 153 $userid = (int) $userid; 154 $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = %d AND post_type = 'post' AND ", $userid) . get_private_posts_cap_sql('post')); 153 154 $where = get_posts_by_author_sql('post', TRUE, $userid); 155 156 $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts $where" ); 157 155 158 return apply_filters('get_usernumposts', $count, $userid); 159 } 160 161 /** 162 * Number of posts written by a list of users. 163 * 164 * @since 3.0.0 165 * @param array $userid User ID number list. 166 * @return array Amount of posts each user has written. 167 */ 168 function count_many_users_posts($users) { 169 global $wpdb; 170 171 if (0 == count($users)) 172 return array(); 173 174 $userlist = implode(',', $users); 175 $where = get_posts_by_author_sql('post'); 176 177 $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N ); 178 179 $count = array(); 180 foreach($result as $row) { 181 $count[$row[0]] = $row[1]; 182 } 183 184 foreach($users as $id) { 185 $id = (string) $id; 186 if (!isset($count[$id])) 187 $count[$id] = 0; 188 } 189 190 return $count; 156 191 } 157 192 … … 341 376 function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { 342 377 return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value); 378 } 379 380 /** 381 * Count number of users who have each of the user roles. 382 * 383 * Assumes there are neither duplicated nor orphaned capabilities meta_values. 384 * Assumes role names are unique phrases. Same assumption made by WP_User_Search::prepare_query() 385 * Using $strategy = 'time' this is CPU-intensive and should handle around 10^7 users. 386 * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257. 387 * 388 * @since 3.0.0 389 * @param string $strategy 'time' or 'memory' 390 * @return array Includes a grand total and an array of counts indexed by role strings. 391 */ 392 function count_users($strategy = 'time') { 393 global $wpdb, $blog_id, $wp_roles; 394 395 // Initialize 396 $id = (int) $blog_id; 397 $blog_prefix = $wpdb->get_blog_prefix($id); 398 $result = array(); 399 400 if ('time' == $strategy) { 401 $avail_roles = $wp_roles->get_names(); 402 403 // Build a CPU-intensive query that will return concise information. 404 $select_count = array(); 405 foreach ( $avail_roles as $this_role => $name ) { 406 $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%" . like_escape($this_role) . "%', FALSE))"; 407 } 408 $select_count = implode(', ', $select_count); 409 410 // Add the meta_value index to the selection list, then run the query. 411 $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N ); 412 413 // Run the previous loop again to associate results with role names. 414 $col = 0; 415 $role_counts = array(); 416 foreach ( $avail_roles as $this_role => $name ) { 417 $count = (int) $row[$col++]; 418 if ($count > 0) { 419 $role_counts[$this_role] = $count; 420 } 421 } 422 423 // Get the meta_value index from the end of the result set. 424 $total_users = (int) $row[$col]; 425 426 $result['total_users'] = $total_users; 427 $result['avail_roles'] =& $role_counts; 428 } else { 429 $avail_roles = array(); 430 431 $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); 432 433 foreach ( $users_of_blog as $caps_meta ) { 434 $b_roles = unserialize($caps_meta); 435 if ( is_array($b_roles) ) { 436 foreach ( $b_roles as $b_role => $val ) { 437 if ( isset($avail_roles[$b_role]) ) { 438 $avail_roles[$b_role]++; 439 } else { 440 $avail_roles[$b_role] = 1; 441 } 442 } 443 } 444 } 445 446 $result['total_users'] = count( $users_of_blog ); 447 $result['avail_roles'] =& $avail_roles; 448 } 449 450 return $result; 343 451 } 344 452 … … 499 607 * The finished user data is cached, but the cache is not used to fill in the 500 608 * user data for the given object. Once the function has been used, the cache 501 * should be used to retrieve user data. The purpose seems then to be to ensure502 * that the data in the object is always fresh.609 * should be used to retrieve user data. The intention is if the current data 610 * had been cached already, there would be no need to call this function. 503 611 * 504 612 * @access private … … 509 617 */ 510 618 function _fill_user( &$user ) { 619 $metavalues = get_user_metavalues(array($user->ID)); 620 _fill_single_user($user, $metavalues[$user->ID]); 621 } 622 623 /** 624 * Perform the query to get the $metavalues array(s) needed by _fill_user and _fill_many_users 625 * 626 * @since 3.0.0 627 * @param array $ids User ID numbers list. 628 * @return array of arrays. The array is indexed by user_id, containing $metavalues object arrays. 629 */ 630 function get_user_metavalues($ids) { 511 631 global $wpdb; 512 632 633 $clean = array_map('intval', $ids); 634 if ( 0 == count($clean) ) 635 return $objects; 636 637 $list = implode(',', $clean); 638 513 639 $show = $wpdb->hide_errors(); 514 $metavalues = $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user->ID));640 $metavalues = $wpdb->get_results("SELECT user_id, meta_key, meta_value FROM $wpdb->usermeta WHERE user_id IN ($list)"); 515 641 $wpdb->show_errors($show); 516 642 517 if ( $metavalues ) { 518 foreach ( (array) $metavalues as $meta ) { 519 $value = maybe_unserialize($meta->meta_value); 520 $user->{$meta->meta_key} = $value; 521 } 643 $objects = array(); 644 foreach($clean as $id) { 645 $objects[$id] = array(); 646 } 647 foreach($metavalues as $meta_object) { 648 $objects[$meta_object->user_id][] = $meta_object; 649 } 650 651 return $objects; 652 } 653 654 /** 655 * Unserialize user metadata, fill $user object, then cache everything. 656 * 657 * @since 3.0.0 658 * @param object $user The User object. 659 * @param array $metavalues An array of objects provided by get_user_metavalues() 660 */ 661 function _fill_single_user( &$user, &$metavalues ) { 662 global $wpdb; 663 664 foreach ( $metavalues as $meta ) { 665 $value = maybe_unserialize($meta->meta_value); 666 $user->{$meta->meta_key} = $value; 522 667 } 523 668 … … 534 679 $user->user_description = $user->description; 535 680 536 wp_cache_add($user->ID, $user, 'users'); 537 wp_cache_add($user->user_login, $user->ID, 'userlogins'); 538 wp_cache_add($user->user_email, $user->ID, 'useremail'); 539 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); 681 update_user_caches($user); 682 } 683 684 /** 685 * Take an array of user objects, fill them with metas, and cache them. 686 * 687 * @since 3.0.0 688 * @param array $users User objects 689 * @param array $metas User metavalues objects 690 */ 691 function _fill_many_users( &$users ) { 692 $ids = array(); 693 foreach($users as $user_object) { 694 $ids[] = $user_object->ID; 695 } 696 697 $metas = get_user_metavalues($ids); 698 699 foreach($users as $user_object) { 700 if (isset($metas[$user_object->ID])) { 701 _fill_single_user($user_object, $metas[$user_object->ID]); 702 } 703 } 540 704 } 541 705 … … 657 821 658 822 /** 823 * Update all user caches 824 * 825 * @since 3.0.0 826 * 827 * @param object $user User object to be cached 828 */ 829 function update_user_caches(&$user) { 830 wp_cache_add($user->ID, $user, 'users'); 831 wp_cache_add($user->user_login, $user->ID, 'userlogins'); 832 wp_cache_add($user->user_email, $user->ID, 'useremail'); 833 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); 834 } 835 836 /** 659 837 * Clean all user caches 660 838 * 661 * @since 3.0 839 * @since 3.0.0 662 840 * 663 841 * @param int $id User ID 664 * @return void665 842 */ 666 843 function clean_user_cache($id) {
Note: See TracChangeset
for help on using the changeset viewer.