243 * |
277 * |
244 * User options are just like user metadata except that they have support for |
278 * User options are just like user metadata except that they have support for |
245 * global blog options. If the 'global' parameter is false, which it is by default |
279 * global blog options. If the 'global' parameter is false, which it is by default |
246 * it will prepend the WordPress table prefix to the option name. |
280 * it will prepend the WordPress table prefix to the option name. |
247 * |
281 * |
|
282 * Deletes the user option if $newvalue is empty. |
|
283 * |
248 * @since 2.0.0 |
284 * @since 2.0.0 |
249 * @uses $wpdb WordPress database object for queries |
285 * @uses $wpdb WordPress database object for queries |
250 * |
286 * |
251 * @param int $user_id User ID |
287 * @param int $user_id User ID |
252 * @param string $option_name User option name. |
288 * @param string $option_name User option name. |
253 * @param mixed $newvalue User option value. |
289 * @param mixed $newvalue User option value. |
254 * @param bool $global Optional. Whether option name is blog specific or not. |
290 * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). |
255 * @return unknown |
291 * @return unknown |
256 */ |
292 */ |
257 function update_user_option( $user_id, $option_name, $newvalue, $global = false ) { |
293 function update_user_option( $user_id, $option_name, $newvalue, $global = false ) { |
258 global $wpdb; |
294 global $wpdb; |
|
295 |
259 if ( !$global ) |
296 if ( !$global ) |
260 $option_name = $wpdb->prefix . $option_name; |
297 $option_name = $wpdb->prefix . $option_name; |
261 return update_usermeta( $user_id, $option_name, $newvalue ); |
298 |
262 } |
299 // For backward compatibility. See differences between update_user_meta() and deprecated update_usermeta(). |
263 |
300 // http://core.trac.wordpress.org/ticket/13088 |
264 /** |
301 if ( is_null( $newvalue ) || is_scalar( $newvalue ) && empty( $newvalue ) ) |
265 * Get users for the blog. |
302 return delete_user_meta( $user_id, $option_name ); |
266 * |
303 |
267 * For setups that use the multi-blog feature. Can be used outside of the |
304 return update_user_meta( $user_id, $option_name, $newvalue ); |
268 * multi-blog feature. |
305 } |
269 * |
306 |
270 * @since 2.2.0 |
307 /** |
|
308 * Delete user option with global blog capability. |
|
309 * |
|
310 * User options are just like user metadata except that they have support for |
|
311 * global blog options. If the 'global' parameter is false, which it is by default |
|
312 * it will prepend the WordPress table prefix to the option name. |
|
313 * |
|
314 * @since 3.0.0 |
271 * @uses $wpdb WordPress database object for queries |
315 * @uses $wpdb WordPress database object for queries |
272 * @uses $blog_id The Blog id of the blog for those that use more than one blog |
316 * |
273 * |
317 * @param int $user_id User ID |
274 * @param int $id Blog ID. |
318 * @param string $option_name User option name. |
275 * @return array List of users that are part of that Blog ID |
319 * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). |
276 */ |
320 * @return unknown |
277 function get_users_of_blog( $id = '' ) { |
321 */ |
278 global $wpdb, $blog_id; |
322 function delete_user_option( $user_id, $option_name, $global = false ) { |
279 if ( empty($id) ) |
323 global $wpdb; |
280 $id = (int) $blog_id; |
324 |
281 $users = $wpdb->get_results( "SELECT user_id, user_id AS ID, user_login, display_name, user_email, meta_value FROM $wpdb->users, $wpdb->usermeta WHERE {$wpdb->users}.ID = {$wpdb->usermeta}.user_id AND meta_key = '{$wpdb->prefix}capabilities' ORDER BY {$wpdb->usermeta}.user_id" ); |
325 if ( !$global ) |
282 return $users; |
326 $option_name = $wpdb->prefix . $option_name; |
283 } |
327 return delete_user_meta( $user_id, $option_name ); |
284 |
328 } |
285 // |
329 |
286 // User meta functions |
330 /** |
287 // |
331 * WordPress User Query class. |
288 |
332 * |
289 /** |
333 * @since 3.1.0 |
290 * Remove user meta data. |
334 */ |
291 * |
335 class WP_User_Query { |
292 * @since 2.0.0 |
336 |
293 * @uses $wpdb WordPress database object for queries. |
337 /** |
294 * |
338 * List of found user ids |
295 * @param int $user_id User ID. |
339 * |
|
340 * @since 3.1.0 |
|
341 * @access private |
|
342 * @var array |
|
343 */ |
|
344 var $results; |
|
345 |
|
346 /** |
|
347 * Total number of found users for the current query |
|
348 * |
|
349 * @since 3.1.0 |
|
350 * @access private |
|
351 * @var int |
|
352 */ |
|
353 var $total_users = 0; |
|
354 |
|
355 // SQL clauses |
|
356 var $query_fields; |
|
357 var $query_from; |
|
358 var $query_where; |
|
359 var $query_orderby; |
|
360 var $query_limit; |
|
361 |
|
362 /** |
|
363 * PHP5 constructor |
|
364 * |
|
365 * @since 3.1.0 |
|
366 * |
|
367 * @param string|array $args The query variables |
|
368 * @return WP_User_Query |
|
369 */ |
|
370 function __construct( $query = null ) { |
|
371 if ( !empty( $query ) ) { |
|
372 $this->query_vars = wp_parse_args( $query, array( |
|
373 'blog_id' => $GLOBALS['blog_id'], |
|
374 'role' => '', |
|
375 'meta_key' => '', |
|
376 'meta_value' => '', |
|
377 'meta_compare' => '', |
|
378 'include' => array(), |
|
379 'exclude' => array(), |
|
380 'search' => '', |
|
381 'search_columns' => array(), |
|
382 'orderby' => 'login', |
|
383 'order' => 'ASC', |
|
384 'offset' => '', |
|
385 'number' => '', |
|
386 'count_total' => true, |
|
387 'fields' => 'all', |
|
388 'who' => '' |
|
389 ) ); |
|
390 |
|
391 $this->prepare_query(); |
|
392 $this->query(); |
|
393 } |
|
394 } |
|
395 |
|
396 /** |
|
397 * Prepare the query variables |
|
398 * |
|
399 * @since 3.1.0 |
|
400 * @access private |
|
401 */ |
|
402 function prepare_query() { |
|
403 global $wpdb; |
|
404 |
|
405 $qv = &$this->query_vars; |
|
406 |
|
407 if ( is_array( $qv['fields'] ) ) { |
|
408 $qv['fields'] = array_unique( $qv['fields'] ); |
|
409 |
|
410 $this->query_fields = array(); |
|
411 foreach ( $qv['fields'] as $field ) |
|
412 $this->query_fields[] = $wpdb->users . '.' . esc_sql( $field ); |
|
413 $this->query_fields = implode( ',', $this->query_fields ); |
|
414 } elseif ( 'all' == $qv['fields'] ) { |
|
415 $this->query_fields = "$wpdb->users.*"; |
|
416 } else { |
|
417 $this->query_fields = "$wpdb->users.ID"; |
|
418 } |
|
419 |
|
420 if ( $this->query_vars['count_total'] ) |
|
421 $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; |
|
422 |
|
423 $this->query_from = "FROM $wpdb->users"; |
|
424 $this->query_where = "WHERE 1=1"; |
|
425 |
|
426 // sorting |
|
427 if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { |
|
428 $orderby = 'user_' . $qv['orderby']; |
|
429 } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) { |
|
430 $orderby = $qv['orderby']; |
|
431 } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) { |
|
432 $orderby = 'display_name'; |
|
433 } elseif ( 'post_count' == $qv['orderby'] ) { |
|
434 // todo: avoid the JOIN |
|
435 $where = get_posts_by_author_sql('post'); |
|
436 $this->query_from .= " LEFT OUTER JOIN ( |
|
437 SELECT post_author, COUNT(*) as post_count |
|
438 FROM $wpdb->posts |
|
439 $where |
|
440 GROUP BY post_author |
|
441 ) p ON ({$wpdb->users}.ID = p.post_author) |
|
442 "; |
|
443 $orderby = 'post_count'; |
|
444 } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) { |
|
445 $orderby = 'ID'; |
|
446 } else { |
|
447 $orderby = 'user_login'; |
|
448 } |
|
449 |
|
450 $qv['order'] = strtoupper( $qv['order'] ); |
|
451 if ( 'ASC' == $qv['order'] ) |
|
452 $order = 'ASC'; |
|
453 else |
|
454 $order = 'DESC'; |
|
455 $this->query_orderby = "ORDER BY $orderby $order"; |
|
456 |
|
457 // limit |
|
458 if ( $qv['number'] ) { |
|
459 if ( $qv['offset'] ) |
|
460 $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']); |
|
461 else |
|
462 $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']); |
|
463 } |
|
464 |
|
465 $search = trim( $qv['search'] ); |
|
466 if ( $search ) { |
|
467 $leading_wild = ( ltrim($search, '*') != $search ); |
|
468 $trailing_wild = ( rtrim($search, '*') != $search ); |
|
469 if ( $leading_wild && $trailing_wild ) |
|
470 $wild = 'both'; |
|
471 elseif ( $leading_wild ) |
|
472 $wild = 'leading'; |
|
473 elseif ( $trailing_wild ) |
|
474 $wild = 'trailing'; |
|
475 else |
|
476 $wild = false; |
|
477 if ( $wild ) |
|
478 $search = trim($search, '*'); |
|
479 |
|
480 $search_columns = array(); |
|
481 if ( $qv['search_columns'] ) |
|
482 $search_columns = array_intersect( $qv['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename' ) ); |
|
483 if ( ! $search_columns ) { |
|
484 if ( false !== strpos( $search, '@') ) |
|
485 $search_columns = array('user_email'); |
|
486 elseif ( is_numeric($search) ) |
|
487 $search_columns = array('user_login', 'ID'); |
|
488 elseif ( preg_match('|^https?://|', $search) && ! wp_is_large_network( 'users' ) ) |
|
489 $search_columns = array('user_url'); |
|
490 else |
|
491 $search_columns = array('user_login', 'user_nicename'); |
|
492 } |
|
493 |
|
494 $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild ); |
|
495 } |
|
496 |
|
497 $blog_id = absint( $qv['blog_id'] ); |
|
498 |
|
499 if ( 'authors' == $qv['who'] && $blog_id ) { |
|
500 $qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level'; |
|
501 $qv['meta_value'] = 0; |
|
502 $qv['meta_compare'] = '!='; |
|
503 $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query |
|
504 } |
|
505 |
|
506 $role = trim( $qv['role'] ); |
|
507 |
|
508 if ( $blog_id && ( $role || is_multisite() ) ) { |
|
509 $cap_meta_query = array(); |
|
510 $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; |
|
511 |
|
512 if ( $role ) { |
|
513 $cap_meta_query['value'] = '"' . $role . '"'; |
|
514 $cap_meta_query['compare'] = 'like'; |
|
515 } |
|
516 |
|
517 $qv['meta_query'][] = $cap_meta_query; |
|
518 } |
|
519 |
|
520 $meta_query = new WP_Meta_Query(); |
|
521 $meta_query->parse_query_vars( $qv ); |
|
522 |
|
523 if ( !empty( $meta_query->queries ) ) { |
|
524 $clauses = $meta_query->get_sql( 'user', $wpdb->users, 'ID', $this ); |
|
525 $this->query_from .= $clauses['join']; |
|
526 $this->query_where .= $clauses['where']; |
|
527 |
|
528 if ( 'OR' == $meta_query->relation ) |
|
529 $this->query_fields = 'DISTINCT ' . $this->query_fields; |
|
530 } |
|
531 |
|
532 if ( !empty( $qv['include'] ) ) { |
|
533 $ids = implode( ',', wp_parse_id_list( $qv['include'] ) ); |
|
534 $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; |
|
535 } elseif ( !empty($qv['exclude']) ) { |
|
536 $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); |
|
537 $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)"; |
|
538 } |
|
539 |
|
540 do_action_ref_array( 'pre_user_query', array( &$this ) ); |
|
541 } |
|
542 |
|
543 /** |
|
544 * Execute the query, with the current variables |
|
545 * |
|
546 * @since 3.1.0 |
|
547 * @access private |
|
548 */ |
|
549 function query() { |
|
550 global $wpdb; |
|
551 |
|
552 if ( is_array( $this->query_vars['fields'] ) || 'all' == $this->query_vars['fields'] ) { |
|
553 $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); |
|
554 } else { |
|
555 $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); |
|
556 } |
|
557 |
|
558 if ( $this->query_vars['count_total'] ) |
|
559 $this->total_users = $wpdb->get_var( apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()' ) ); |
|
560 |
|
561 if ( !$this->results ) |
|
562 return; |
|
563 |
|
564 if ( 'all_with_meta' == $this->query_vars['fields'] ) { |
|
565 cache_users( $this->results ); |
|
566 |
|
567 $r = array(); |
|
568 foreach ( $this->results as $userid ) |
|
569 $r[ $userid ] = new WP_User( $userid, '', $this->query_vars['blog_id'] ); |
|
570 |
|
571 $this->results = $r; |
|
572 } |
|
573 } |
|
574 |
|
575 /* |
|
576 * Used internally to generate an SQL string for searching across multiple columns |
|
577 * |
|
578 * @access protected |
|
579 * @since 3.1.0 |
|
580 * |
|
581 * @param string $string |
|
582 * @param array $cols |
|
583 * @param bool $wild Whether to allow wildcard searches. Default is false for Network Admin, true for |
|
584 * single site. Single site allows leading and trailing wildcards, Network Admin only trailing. |
|
585 * @return string |
|
586 */ |
|
587 function get_search_sql( $string, $cols, $wild = false ) { |
|
588 $string = esc_sql( $string ); |
|
589 |
|
590 $searches = array(); |
|
591 $leading_wild = ( 'leading' == $wild || 'both' == $wild ) ? '%' : ''; |
|
592 $trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : ''; |
|
593 foreach ( $cols as $col ) { |
|
594 if ( 'ID' == $col ) |
|
595 $searches[] = "$col = '$string'"; |
|
596 else |
|
597 $searches[] = "$col LIKE '$leading_wild" . like_escape($string) . "$trailing_wild'"; |
|
598 } |
|
599 |
|
600 return ' AND (' . implode(' OR ', $searches) . ')'; |
|
601 } |
|
602 |
|
603 /** |
|
604 * Return the list of users |
|
605 * |
|
606 * @since 3.1.0 |
|
607 * @access public |
|
608 * |
|
609 * @return array |
|
610 */ |
|
611 function get_results() { |
|
612 return $this->results; |
|
613 } |
|
614 |
|
615 /** |
|
616 * Return the total number of users for the current query |
|
617 * |
|
618 * @since 3.1.0 |
|
619 * @access public |
|
620 * |
|
621 * @return array |
|
622 */ |
|
623 function get_total() { |
|
624 return $this->total_users; |
|
625 } |
|
626 } |
|
627 |
|
628 /** |
|
629 * Retrieve list of users matching criteria. |
|
630 * |
|
631 * @since 3.1.0 |
|
632 * @uses $wpdb |
|
633 * @uses WP_User_Query See for default arguments and information. |
|
634 * |
|
635 * @param array $args Optional. |
|
636 * @return array List of users. |
|
637 */ |
|
638 function get_users( $args = array() ) { |
|
639 |
|
640 $args = wp_parse_args( $args ); |
|
641 $args['count_total'] = false; |
|
642 |
|
643 $user_search = new WP_User_Query($args); |
|
644 |
|
645 return (array) $user_search->get_results(); |
|
646 } |
|
647 |
|
648 /** |
|
649 * Get the blogs a user belongs to. |
|
650 * |
|
651 * @since 3.0.0 |
|
652 * |
|
653 * @param int $user_id User ID |
|
654 * @param bool $all Whether to retrieve all blogs, or only blogs that are not marked as deleted, archived, or spam. |
|
655 * @return array A list of the user's blogs. An empty array if the user doesn't exist or belongs to no blogs. |
|
656 */ |
|
657 function get_blogs_of_user( $user_id, $all = false ) { |
|
658 global $wpdb; |
|
659 |
|
660 $user_id = (int) $user_id; |
|
661 |
|
662 // Logged out users can't have blogs |
|
663 if ( empty( $user_id ) ) |
|
664 return array(); |
|
665 |
|
666 $keys = get_user_meta( $user_id ); |
|
667 if ( empty( $keys ) ) |
|
668 return array(); |
|
669 |
|
670 if ( ! is_multisite() ) { |
|
671 $blog_id = get_current_blog_id(); |
|
672 $blogs = array( $blog_id => new stdClass ); |
|
673 $blogs[ $blog_id ]->userblog_id = $blog_id; |
|
674 $blogs[ $blog_id ]->blogname = get_option('blogname'); |
|
675 $blogs[ $blog_id ]->domain = ''; |
|
676 $blogs[ $blog_id ]->path = ''; |
|
677 $blogs[ $blog_id ]->site_id = 1; |
|
678 $blogs[ $blog_id ]->siteurl = get_option('siteurl'); |
|
679 return $blogs; |
|
680 } |
|
681 |
|
682 $blogs = array(); |
|
683 |
|
684 if ( isset( $keys[ $wpdb->base_prefix . 'capabilities' ] ) && defined( 'MULTISITE' ) ) { |
|
685 $blog = get_blog_details( 1 ); |
|
686 if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) { |
|
687 $blogs[ 1 ] = (object) array( |
|
688 'userblog_id' => 1, |
|
689 'blogname' => $blog->blogname, |
|
690 'domain' => $blog->domain, |
|
691 'path' => $blog->path, |
|
692 'site_id' => $blog->site_id, |
|
693 'siteurl' => $blog->siteurl, |
|
694 ); |
|
695 } |
|
696 unset( $keys[ $wpdb->base_prefix . 'capabilities' ] ); |
|
697 } |
|
698 |
|
699 $keys = array_keys( $keys ); |
|
700 |
|
701 foreach ( $keys as $key ) { |
|
702 if ( 'capabilities' !== substr( $key, -12 ) ) |
|
703 continue; |
|
704 if ( $wpdb->base_prefix && 0 !== strpos( $key, $wpdb->base_prefix ) ) |
|
705 continue; |
|
706 $blog_id = str_replace( array( $wpdb->base_prefix, '_capabilities' ), '', $key ); |
|
707 if ( ! is_numeric( $blog_id ) ) |
|
708 continue; |
|
709 |
|
710 $blog_id = (int) $blog_id; |
|
711 $blog = get_blog_details( $blog_id ); |
|
712 if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) { |
|
713 $blogs[ $blog_id ] = (object) array( |
|
714 'userblog_id' => $blog_id, |
|
715 'blogname' => $blog->blogname, |
|
716 'domain' => $blog->domain, |
|
717 'path' => $blog->path, |
|
718 'site_id' => $blog->site_id, |
|
719 'siteurl' => $blog->siteurl, |
|
720 ); |
|
721 } |
|
722 } |
|
723 |
|
724 return apply_filters( 'get_blogs_of_user', $blogs, $user_id, $all ); |
|
725 } |
|
726 |
|
727 /** |
|
728 * Find out whether a user is a member of a given blog. |
|
729 * |
|
730 * @since MU 1.1 |
|
731 * @uses get_blogs_of_user() |
|
732 * |
|
733 * @param int $user_id Optional. The unique ID of the user. Defaults to the current user. |
|
734 * @param int $blog_id Optional. ID of the blog to check. Defaults to the current site. |
|
735 * @return bool |
|
736 */ |
|
737 function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) { |
|
738 $user_id = (int) $user_id; |
|
739 $blog_id = (int) $blog_id; |
|
740 |
|
741 if ( empty( $user_id ) ) |
|
742 $user_id = get_current_user_id(); |
|
743 |
|
744 if ( empty( $blog_id ) ) |
|
745 $blog_id = get_current_blog_id(); |
|
746 |
|
747 $blogs = get_blogs_of_user( $user_id ); |
|
748 return array_key_exists( $blog_id, $blogs ); |
|
749 } |
|
750 |
|
751 /** |
|
752 * Add meta data field to a user. |
|
753 * |
|
754 * Post meta data is called "Custom Fields" on the Administration Screens. |
|
755 * |
|
756 * @since 3.0.0 |
|
757 * @uses add_metadata() |
|
758 * @link http://codex.wordpress.org/Function_Reference/add_user_meta |
|
759 * |
|
760 * @param int $user_id Post ID. |
|
761 * @param string $meta_key Metadata name. |
|
762 * @param mixed $meta_value Metadata value. |
|
763 * @param bool $unique Optional, default is false. Whether the same key should not be added. |
|
764 * @return bool False for failure. True for success. |
|
765 */ |
|
766 function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { |
|
767 return add_metadata('user', $user_id, $meta_key, $meta_value, $unique); |
|
768 } |
|
769 |
|
770 /** |
|
771 * Remove metadata matching criteria from a user. |
|
772 * |
|
773 * You can match based on the key, or key and value. Removing based on key and |
|
774 * value, will keep from removing duplicate metadata with the same key. It also |
|
775 * allows removing all metadata matching key, if needed. |
|
776 * |
|
777 * @since 3.0.0 |
|
778 * @uses delete_metadata() |
|
779 * @link http://codex.wordpress.org/Function_Reference/delete_user_meta |
|
780 * |
|
781 * @param int $user_id user ID |
|
782 * @param string $meta_key Metadata name. |
|
783 * @param mixed $meta_value Optional. Metadata value. |
|
784 * @return bool False for failure. True for success. |
|
785 */ |
|
786 function delete_user_meta($user_id, $meta_key, $meta_value = '') { |
|
787 return delete_metadata('user', $user_id, $meta_key, $meta_value); |
|
788 } |
|
789 |
|
790 /** |
|
791 * Retrieve user meta field for a user. |
|
792 * |
|
793 * @since 3.0.0 |
|
794 * @uses get_metadata() |
|
795 * @link http://codex.wordpress.org/Function_Reference/get_user_meta |
|
796 * |
|
797 * @param int $user_id Post ID. |
|
798 * @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. |
|
799 * @param bool $single Whether to return a single value. |
|
800 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single |
|
801 * is true. |
|
802 */ |
|
803 function get_user_meta($user_id, $key = '', $single = false) { |
|
804 return get_metadata('user', $user_id, $key, $single); |
|
805 } |
|
806 |
|
807 /** |
|
808 * Update user meta field based on user ID. |
|
809 * |
|
810 * Use the $prev_value parameter to differentiate between meta fields with the |
|
811 * same key and user ID. |
|
812 * |
|
813 * If the meta field for the user does not exist, it will be added. |
|
814 * |
|
815 * @since 3.0.0 |
|
816 * @uses update_metadata |
|
817 * @link http://codex.wordpress.org/Function_Reference/update_user_meta |
|
818 * |
|
819 * @param int $user_id Post ID. |
296 * @param string $meta_key Metadata key. |
820 * @param string $meta_key Metadata key. |
297 * @param mixed $meta_value Metadata value. |
821 * @param mixed $meta_value Metadata value. |
298 * @return bool True deletion completed and false if user_id is not a number. |
822 * @param mixed $prev_value Optional. Previous value to check before removing. |
299 */ |
823 * @return bool False on failure, true if success. |
300 function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) { |
824 */ |
301 global $wpdb; |
825 function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { |
302 if ( !is_numeric( $user_id ) ) |
826 return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value); |
303 return false; |
827 } |
304 $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); |
828 |
305 |
829 /** |
306 if ( is_array($meta_value) || is_object($meta_value) ) |
830 * Count number of users who have each of the user roles. |
307 $meta_value = serialize($meta_value); |
831 * |
308 $meta_value = trim( $meta_value ); |
832 * Assumes there are neither duplicated nor orphaned capabilities meta_values. |
309 |
833 * Assumes role names are unique phrases. Same assumption made by WP_User_Query::prepare_query() |
310 $cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); |
834 * Using $strategy = 'time' this is CPU-intensive and should handle around 10^7 users. |
311 |
835 * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257. |
312 if ( $cur && $cur->umeta_id ) |
836 * |
313 do_action( 'delete_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); |
837 * @since 3.0.0 |
314 |
838 * @param string $strategy 'time' or 'memory' |
315 if ( ! empty($meta_value) ) |
839 * @return array Includes a grand total and an array of counts indexed by role strings. |
316 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value) ); |
840 */ |
317 else |
841 function count_users($strategy = 'time') { |
318 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); |
842 global $wpdb, $wp_roles; |
319 |
843 |
320 wp_cache_delete($user_id, 'users'); |
844 // Initialize |
321 |
845 $id = get_current_blog_id(); |
322 if ( $cur && $cur->umeta_id ) |
846 $blog_prefix = $wpdb->get_blog_prefix($id); |
323 do_action( 'deleted_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); |
847 $result = array(); |
324 |
848 |
325 return true; |
849 if ( 'time' == $strategy ) { |
326 } |
850 global $wp_roles; |
327 |
851 |
328 /** |
852 if ( ! isset( $wp_roles ) ) |
329 * Retrieve user metadata. |
853 $wp_roles = new WP_Roles(); |
330 * |
854 |
331 * If $user_id is not a number, then the function will fail over with a 'false' |
855 $avail_roles = $wp_roles->get_names(); |
332 * boolean return value. Other returned values depend on whether there is only |
856 |
333 * one item to be returned, which be that single item type. If there is more |
857 // Build a CPU-intensive query that will return concise information. |
334 * than one metadata value, then it will be list of metadata values. |
858 $select_count = array(); |
335 * |
859 foreach ( $avail_roles as $this_role => $name ) { |
336 * @since 2.0.0 |
860 $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape( $this_role ) . "\"%', false))"; |
337 * @uses $wpdb WordPress database object for queries. |
861 } |
338 * |
862 $select_count = implode(', ', $select_count); |
339 * @param int $user_id User ID |
863 |
340 * @param string $meta_key Optional. Metadata key. |
864 // Add the meta_value index to the selection list, then run the query. |
341 * @return mixed |
865 $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N ); |
342 */ |
866 |
343 function get_usermeta( $user_id, $meta_key = '') { |
867 // Run the previous loop again to associate results with role names. |
344 global $wpdb; |
868 $col = 0; |
345 $user_id = (int) $user_id; |
869 $role_counts = array(); |
346 |
870 foreach ( $avail_roles as $this_role => $name ) { |
347 if ( !$user_id ) |
871 $count = (int) $row[$col++]; |
348 return false; |
872 if ($count > 0) { |
349 |
873 $role_counts[$this_role] = $count; |
350 if ( !empty($meta_key) ) { |
874 } |
351 $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); |
875 } |
352 $user = wp_cache_get($user_id, 'users'); |
876 |
353 // Check the cached user object |
877 // Get the meta_value index from the end of the result set. |
354 if ( false !== $user && isset($user->$meta_key) ) |
878 $total_users = (int) $row[$col]; |
355 $metas = array($user->$meta_key); |
879 |
356 else |
880 $result['total_users'] = $total_users; |
357 $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); |
881 $result['avail_roles'] =& $role_counts; |
358 } else { |
882 } else { |
359 $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user_id) ); |
883 $avail_roles = array(); |
360 } |
884 |
361 |
885 $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); |
362 if ( empty($metas) ) { |
886 |
363 if ( empty($meta_key) ) |
887 foreach ( $users_of_blog as $caps_meta ) { |
364 return array(); |
888 $b_roles = maybe_unserialize($caps_meta); |
365 else |
889 if ( ! is_array( $b_roles ) ) |
366 return ''; |
890 continue; |
367 } |
891 foreach ( $b_roles as $b_role => $val ) { |
368 |
892 if ( isset($avail_roles[$b_role]) ) { |
369 $metas = array_map('maybe_unserialize', $metas); |
893 $avail_roles[$b_role]++; |
370 |
894 } else { |
371 if ( count($metas) == 1 ) |
895 $avail_roles[$b_role] = 1; |
372 return $metas[0]; |
896 } |
373 else |
897 } |
374 return $metas; |
898 } |
375 } |
899 |
376 |
900 $result['total_users'] = count( $users_of_blog ); |
377 /** |
901 $result['avail_roles'] =& $avail_roles; |
378 * Update metadata of user. |
902 } |
379 * |
903 |
380 * There is no need to serialize values, they will be serialized if it is |
904 return $result; |
381 * needed. The metadata key can only be a string with underscores. All else will |
|
382 * be removed. |
|
383 * |
|
384 * Will remove the metadata, if the meta value is empty. |
|
385 * |
|
386 * @since 2.0.0 |
|
387 * @uses $wpdb WordPress database object for queries |
|
388 * |
|
389 * @param int $user_id User ID |
|
390 * @param string $meta_key Metadata key. |
|
391 * @param mixed $meta_value Metadata value. |
|
392 * @return bool True on successful update, false on failure. |
|
393 */ |
|
394 function update_usermeta( $user_id, $meta_key, $meta_value ) { |
|
395 global $wpdb; |
|
396 if ( !is_numeric( $user_id ) ) |
|
397 return false; |
|
398 $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); |
|
399 |
|
400 /** @todo Might need fix because usermeta data is assumed to be already escaped */ |
|
401 if ( is_string($meta_value) ) |
|
402 $meta_value = stripslashes($meta_value); |
|
403 $meta_value = maybe_serialize($meta_value); |
|
404 |
|
405 if (empty($meta_value)) { |
|
406 return delete_usermeta($user_id, $meta_key); |
|
407 } |
|
408 |
|
409 $cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); |
|
410 |
|
411 if ( $cur ) |
|
412 do_action( 'update_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); |
|
413 |
|
414 if ( !$cur ) |
|
415 $wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') ); |
|
416 else if ( $cur->meta_value != $meta_value ) |
|
417 $wpdb->update($wpdb->usermeta, compact('meta_value'), compact('user_id', 'meta_key') ); |
|
418 else |
|
419 return false; |
|
420 |
|
421 wp_cache_delete($user_id, 'users'); |
|
422 |
|
423 if ( !$cur ) |
|
424 do_action( 'added_usermeta', $wpdb->insert_id, $user_id, $meta_key, $meta_value ); |
|
425 else |
|
426 do_action( 'updated_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); |
|
427 |
|
428 return true; |
|
429 } |
905 } |
430 |
906 |
431 // |
907 // |
432 // Private helper functions |
908 // Private helper functions |
433 // |
909 // |
434 |
910 |
435 /** |
911 /** |
436 * Setup global user vars. |
912 * Set up global user vars. |
437 * |
913 * |
438 * Used by set_current_user() for back compat. Might be deprecated in the |
914 * Used by wp_set_current_user() for back compat. Might be deprecated in the future. |
439 * future. |
|
440 * |
915 * |
441 * @since 2.0.4 |
916 * @since 2.0.4 |
442 * @global string $userdata User description. |
917 * @global string $userdata User description. |
443 * @global string $user_login The user username for logging in |
918 * @global string $user_login The user username for logging in |
444 * @global int $user_level The level of the user |
919 * @global int $user_level The level of the user |
480 * used, either 'include' or 'exclude', but not both. |
959 * used, either 'include' or 'exclude', but not both. |
481 * |
960 * |
482 * The available arguments are as follows: |
961 * The available arguments are as follows: |
483 * <ol> |
962 * <ol> |
484 * <li>show_option_all - Text to show all and whether HTML option exists.</li> |
963 * <li>show_option_all - Text to show all and whether HTML option exists.</li> |
485 * <li>show_option_none - Text for show none and whether HTML option exists. |
964 * <li>show_option_none - Text for show none and whether HTML option exists.</li> |
486 * </li> |
965 * <li>hide_if_only_one_author - Don't create the dropdown if there is only one user.</li> |
487 * <li>orderby - SQL order by clause for what order the users appear. Default is |
966 * <li>orderby - SQL order by clause for what order the users appear. Default is 'display_name'.</li> |
488 * 'display_name'.</li> |
|
489 * <li>order - Default is 'ASC'. Can also be 'DESC'.</li> |
967 * <li>order - Default is 'ASC'. Can also be 'DESC'.</li> |
490 * <li>include - User IDs to include.</li> |
968 * <li>include - User IDs to include.</li> |
491 * <li>exclude - User IDs to exclude.</li> |
969 * <li>exclude - User IDs to exclude.</li> |
492 * <li>multi - Default is 'false'. Whether to skip the ID attribute on the 'select' element.</li> |
970 * <li>multi - Default is 'false'. Whether to skip the ID attribute on the 'select' element. A 'true' value is overridden when id argument is set.</li> |
493 * <li>show - Default is 'display_name'. User table column to display. If the selected item is empty then the user_login will be displayed in parentesis</li> |
971 * <li>show - Default is 'display_name'. User table column to display. If the selected item is empty then the user_login will be displayed in parentheses</li> |
494 * <li>echo - Default is '1'. Whether to display or retrieve content.</li> |
972 * <li>echo - Default is '1'. Whether to display or retrieve content.</li> |
495 * <li>selected - Which User ID is selected.</li> |
973 * <li>selected - Which User ID is selected.</li> |
|
974 * <li>include_selected - Always include the selected user ID in the dropdown. Default is false.</li> |
496 * <li>name - Default is 'user'. Name attribute of select element.</li> |
975 * <li>name - Default is 'user'. Name attribute of select element.</li> |
|
976 * <li>id - Default is the value of the 'name' parameter. ID attribute of select element.</li> |
497 * <li>class - Class attribute of select element.</li> |
977 * <li>class - Class attribute of select element.</li> |
|
978 * <li>blog_id - ID of blog (Multisite only). Defaults to ID of current blog.</li> |
|
979 * <li>who - Which users to query. Currently only 'authors' is supported. Default is all users.</li> |
498 * </ol> |
980 * </ol> |
499 * |
981 * |
500 * @since 2.3.0 |
982 * @since 2.3.0 |
501 * @uses $wpdb WordPress database object for queries |
983 * @uses $wpdb WordPress database object for queries |
502 * |
984 * |
503 * @param string|array $args Optional. Override defaults. |
985 * @param string|array $args Optional. Override defaults. |
504 * @return string|null Null on display. String of HTML content on retrieve. |
986 * @return string|null Null on display. String of HTML content on retrieve. |
505 */ |
987 */ |
506 function wp_dropdown_users( $args = '' ) { |
988 function wp_dropdown_users( $args = '' ) { |
507 global $wpdb; |
|
508 $defaults = array( |
989 $defaults = array( |
509 'show_option_all' => '', 'show_option_none' => '', |
990 'show_option_all' => '', 'show_option_none' => '', 'hide_if_only_one_author' => '', |
510 'orderby' => 'display_name', 'order' => 'ASC', |
991 'orderby' => 'display_name', 'order' => 'ASC', |
511 'include' => '', 'exclude' => '', 'multi' => 0, |
992 'include' => '', 'exclude' => '', 'multi' => 0, |
512 'show' => 'display_name', 'echo' => 1, |
993 'show' => 'display_name', 'echo' => 1, |
513 'selected' => 0, 'name' => 'user', 'class' => '' |
994 'selected' => 0, 'name' => 'user', 'class' => '', 'id' => '', |
|
995 'blog_id' => $GLOBALS['blog_id'], 'who' => '', 'include_selected' => false |
514 ); |
996 ); |
515 |
997 |
516 $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0; |
998 $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0; |
517 |
999 |
518 $r = wp_parse_args( $args, $defaults ); |
1000 $r = wp_parse_args( $args, $defaults ); |
519 extract( $r, EXTR_SKIP ); |
1001 extract( $r, EXTR_SKIP ); |
520 |
1002 |
521 $query = "SELECT * FROM $wpdb->users"; |
1003 $query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who' ) ); |
522 |
1004 $query_args['fields'] = array( 'ID', $show ); |
523 $query_where = array(); |
1005 $users = get_users( $query_args ); |
524 |
|
525 if ( is_array($include) ) |
|
526 $include = join(',', $include); |
|
527 $include = preg_replace('/[^0-9,]/', '', $include); // (int) |
|
528 if ( $include ) |
|
529 $query_where[] = "ID IN ($include)"; |
|
530 |
|
531 if ( is_array($exclude) ) |
|
532 $exclude = join(',', $exclude); |
|
533 $exclude = preg_replace('/[^0-9,]/', '', $exclude); // (int) |
|
534 if ( $exclude ) |
|
535 $query_where[] = "ID NOT IN ($exclude)"; |
|
536 |
|
537 if ( $query_where ) |
|
538 $query .= " WHERE " . join(' AND', $query_where); |
|
539 |
|
540 $query .= " ORDER BY $orderby $order"; |
|
541 |
|
542 $users = $wpdb->get_results( $query ); |
|
543 |
1006 |
544 $output = ''; |
1007 $output = ''; |
545 if ( !empty($users) ) { |
1008 if ( !empty($users) && ( empty($hide_if_only_one_author) || count($users) > 1 ) ) { |
546 $id = $multi ? "" : "id='$name'"; |
1009 $name = esc_attr( $name ); |
547 |
1010 if ( $multi && ! $id ) |
548 $output = "<select name='$name' $id class='$class'>\n"; |
1011 $id = ''; |
|
1012 else |
|
1013 $id = $id ? " id='" . esc_attr( $id ) . "'" : " id='$name'"; |
|
1014 |
|
1015 $output = "<select name='{$name}'{$id} class='$class'>\n"; |
549 |
1016 |
550 if ( $show_option_all ) |
1017 if ( $show_option_all ) |
551 $output .= "\t<option value='0'>$show_option_all</option>\n"; |
1018 $output .= "\t<option value='0'>$show_option_all</option>\n"; |
552 |
1019 |
553 if ( $show_option_none ) |
1020 if ( $show_option_none ) { |
554 $output .= "\t<option value='-1'>$show_option_none</option>\n"; |
1021 $_selected = selected( -1, $selected, false ); |
555 |
1022 $output .= "\t<option value='-1'$_selected>$show_option_none</option>\n"; |
|
1023 } |
|
1024 |
|
1025 $found_selected = false; |
556 foreach ( (array) $users as $user ) { |
1026 foreach ( (array) $users as $user ) { |
557 $user->ID = (int) $user->ID; |
1027 $user->ID = (int) $user->ID; |
558 $_selected = $user->ID == $selected ? " selected='selected'" : ''; |
1028 $_selected = selected( $user->ID, $selected, false ); |
|
1029 if ( $_selected ) |
|
1030 $found_selected = true; |
559 $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')'; |
1031 $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')'; |
560 $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n"; |
1032 $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n"; |
561 } |
1033 } |
562 |
1034 |
|
1035 if ( $include_selected && ! $found_selected && ( $selected > 0 ) ) { |
|
1036 $user = get_userdata( $selected ); |
|
1037 $_selected = selected( $user->ID, $selected, false ); |
|
1038 $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')'; |
|
1039 $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n"; |
|
1040 } |
|
1041 |
563 $output .= "</select>"; |
1042 $output .= "</select>"; |
564 } |
1043 } |
565 |
1044 |
566 $output = apply_filters('wp_dropdown_users', $output); |
1045 $output = apply_filters('wp_dropdown_users', $output); |
567 |
1046 |
568 if ( $echo ) |
1047 if ( $echo ) |
569 echo $output; |
1048 echo $output; |
570 |
1049 |
571 return $output; |
1050 return $output; |
572 } |
|
573 |
|
574 /** |
|
575 * Add user meta data as properties to given user object. |
|
576 * |
|
577 * The finished user data is cached, but the cache is not used to fill in the |
|
578 * user data for the given object. Once the function has been used, the cache |
|
579 * should be used to retrieve user data. The purpose seems then to be to ensure |
|
580 * that the data in the object is always fresh. |
|
581 * |
|
582 * @access private |
|
583 * @since 2.5.0 |
|
584 * @uses $wpdb WordPress database object for queries |
|
585 * |
|
586 * @param object $user The user data object. |
|
587 */ |
|
588 function _fill_user( &$user ) { |
|
589 global $wpdb; |
|
590 |
|
591 $show = $wpdb->hide_errors(); |
|
592 $metavalues = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user->ID)); |
|
593 $wpdb->show_errors($show); |
|
594 |
|
595 if ( $metavalues ) { |
|
596 foreach ( (array) $metavalues as $meta ) { |
|
597 $value = maybe_unserialize($meta->meta_value); |
|
598 $user->{$meta->meta_key} = $value; |
|
599 } |
|
600 } |
|
601 |
|
602 $level = $wpdb->prefix . 'user_level'; |
|
603 if ( isset( $user->{$level} ) ) |
|
604 $user->user_level = $user->{$level}; |
|
605 |
|
606 // For backwards compat. |
|
607 if ( isset($user->first_name) ) |
|
608 $user->user_firstname = $user->first_name; |
|
609 if ( isset($user->last_name) ) |
|
610 $user->user_lastname = $user->last_name; |
|
611 if ( isset($user->description) ) |
|
612 $user->user_description = $user->description; |
|
613 |
|
614 wp_cache_add($user->ID, $user, 'users'); |
|
615 wp_cache_add($user->user_login, $user->ID, 'userlogins'); |
|
616 wp_cache_add($user->user_email, $user->ID, 'useremail'); |
|
617 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); |
|
618 } |
|
619 |
|
620 /** |
|
621 * Sanitize every user field. |
|
622 * |
|
623 * If the context is 'raw', then the user object or array will get minimal santization of the int fields. |
|
624 * |
|
625 * @since 2.3.0 |
|
626 * @uses sanitize_user_field() Used to sanitize the fields. |
|
627 * |
|
628 * @param object|array $user The User Object or Array |
|
629 * @param string $context Optional, default is 'display'. How to sanitize user fields. |
|
630 * @return object|array The now sanitized User Object or Array (will be the same type as $user) |
|
631 */ |
|
632 function sanitize_user_object($user, $context = 'display') { |
|
633 if ( is_object($user) ) { |
|
634 if ( !isset($user->ID) ) |
|
635 $user->ID = 0; |
|
636 if ( isset($user->data) ) |
|
637 $vars = get_object_vars( $user->data ); |
|
638 else |
|
639 $vars = get_object_vars($user); |
|
640 foreach ( array_keys($vars) as $field ) { |
|
641 if ( is_string($user->$field) || is_numeric($user->$field) ) |
|
642 $user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context); |
|
643 } |
|
644 $user->filter = $context; |
|
645 } else { |
|
646 if ( !isset($user['ID']) ) |
|
647 $user['ID'] = 0; |
|
648 foreach ( array_keys($user) as $field ) |
|
649 $user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context); |
|
650 $user['filter'] = $context; |
|
651 } |
|
652 |
|
653 return $user; |
|
654 } |
1051 } |
655 |
1052 |
656 /** |
1053 /** |
657 * Sanitize user field based on context. |
1054 * Sanitize user field based on context. |
658 * |
1055 * |
659 * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The |
1056 * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The |
660 * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' |
1057 * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' |
661 * when calling filters. |
1058 * when calling filters. |
662 * |
1059 * |
663 * @since 2.3.0 |
1060 * @since 2.3.0 |
664 * @uses apply_filters() Calls 'edit_$field' and '${field_no_prefix}_edit_pre' passing $value and |
1061 * @uses apply_filters() Calls 'edit_$field' passing $value and $user_id if $context == 'edit'. |
665 * $user_id if $context == 'edit' and field name prefix == 'user_'. |
1062 * $field is prefixed with 'user_' if it isn't already. |
666 * |
1063 * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db'. $field is prefixed with |
667 * @uses apply_filters() Calls 'edit_user_$field' passing $value and $user_id if $context == 'db'. |
1064 * 'user_' if it isn't already. |
668 * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db' and field name prefix == 'user_'. |
|
669 * @uses apply_filters() Calls '${field}_pre' passing $value if $context == 'db' and field name prefix != 'user_'. |
|
670 * |
|
671 * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything |
1065 * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything |
672 * other than 'raw', 'edit' and 'db' and field name prefix == 'user_'. |
1066 * other than 'raw', 'edit' and 'db'. $field is prefixed with 'user_' if it isn't already. |
673 * @uses apply_filters() Calls 'user_$field' passing $value if $context == anything other than 'raw', |
|
674 * 'edit' and 'db' and field name prefix != 'user_'. |
|
675 * |
1067 * |
676 * @param string $field The user Object field name. |
1068 * @param string $field The user Object field name. |
677 * @param mixed $value The user Object value. |
1069 * @param mixed $value The user Object value. |
678 * @param int $user_id user ID. |
1070 * @param int $user_id user ID. |
679 * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display', |
1071 * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display', |
731 $value = esc_js($value); |
1119 $value = esc_js($value); |
732 |
1120 |
733 return $value; |
1121 return $value; |
734 } |
1122 } |
735 |
1123 |
736 ?> |
1124 /** |
|
1125 * Update all user caches |
|
1126 * |
|
1127 * @since 3.0.0 |
|
1128 * |
|
1129 * @param object $user User object to be cached |
|
1130 */ |
|
1131 function update_user_caches($user) { |
|
1132 wp_cache_add($user->ID, $user, 'users'); |
|
1133 wp_cache_add($user->user_login, $user->ID, 'userlogins'); |
|
1134 wp_cache_add($user->user_email, $user->ID, 'useremail'); |
|
1135 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); |
|
1136 } |
|
1137 |
|
1138 /** |
|
1139 * Clean all user caches |
|
1140 * |
|
1141 * @since 3.0.0 |
|
1142 * |
|
1143 * @param WP_User|int $user User object or ID to be cleaned from the cache |
|
1144 */ |
|
1145 function clean_user_cache( $user ) { |
|
1146 if ( is_numeric( $user ) ) |
|
1147 $user = new WP_User( $user ); |
|
1148 |
|
1149 if ( ! $user->exists() ) |
|
1150 return; |
|
1151 |
|
1152 wp_cache_delete( $user->ID, 'users' ); |
|
1153 wp_cache_delete( $user->user_login, 'userlogins' ); |
|
1154 wp_cache_delete( $user->user_email, 'useremail' ); |
|
1155 wp_cache_delete( $user->user_nicename, 'userslugs' ); |
|
1156 } |
|
1157 |
|
1158 /** |
|
1159 * Checks whether the given username exists. |
|
1160 * |
|
1161 * @since 2.0.0 |
|
1162 * |
|
1163 * @param string $username Username. |
|
1164 * @return null|int The user's ID on success, and null on failure. |
|
1165 */ |
|
1166 function username_exists( $username ) { |
|
1167 if ( $user = get_user_by('login', $username ) ) { |
|
1168 return $user->ID; |
|
1169 } else { |
|
1170 return null; |
|
1171 } |
|
1172 } |
|
1173 |
|
1174 /** |
|
1175 * Checks whether the given email exists. |
|
1176 * |
|
1177 * @since 2.1.0 |
|
1178 * @uses $wpdb |
|
1179 * |
|
1180 * @param string $email Email. |
|
1181 * @return bool|int The user's ID on success, and false on failure. |
|
1182 */ |
|
1183 function email_exists( $email ) { |
|
1184 if ( $user = get_user_by('email', $email) ) |
|
1185 return $user->ID; |
|
1186 |
|
1187 return false; |
|
1188 } |
|
1189 |
|
1190 /** |
|
1191 * Checks whether an username is valid. |
|
1192 * |
|
1193 * @since 2.0.1 |
|
1194 * @uses apply_filters() Calls 'validate_username' hook on $valid check and $username as parameters |
|
1195 * |
|
1196 * @param string $username Username. |
|
1197 * @return bool Whether username given is valid |
|
1198 */ |
|
1199 function validate_username( $username ) { |
|
1200 $sanitized = sanitize_user( $username, true ); |
|
1201 $valid = ( $sanitized == $username ); |
|
1202 return apply_filters( 'validate_username', $valid, $username ); |
|
1203 } |
|
1204 |
|
1205 /** |
|
1206 * Insert an user into the database. |
|
1207 * |
|
1208 * Can update a current user or insert a new user based on whether the user's ID |
|
1209 * is present. |
|
1210 * |
|
1211 * Can be used to update the user's info (see below), set the user's role, and |
|
1212 * set the user's preference on whether they want the rich editor on. |
|
1213 * |
|
1214 * Most of the $userdata array fields have filters associated with the values. |
|
1215 * The exceptions are 'rich_editing', 'role', 'jabber', 'aim', 'yim', |
|
1216 * 'user_registered', and 'ID'. The filters have the prefix 'pre_user_' followed |
|
1217 * by the field name. An example using 'description' would have the filter |
|
1218 * called, 'pre_user_description' that can be hooked into. |
|
1219 * |
|
1220 * The $userdata array can contain the following fields: |
|
1221 * 'ID' - An integer that will be used for updating an existing user. |
|
1222 * 'user_pass' - A string that contains the plain text password for the user. |
|
1223 * 'user_login' - A string that contains the user's username for logging in. |
|
1224 * 'user_nicename' - A string that contains a nicer looking name for the user. |
|
1225 * The default is the user's username. |
|
1226 * 'user_url' - A string containing the user's URL for the user's web site. |
|
1227 * 'user_email' - A string containing the user's email address. |
|
1228 * 'display_name' - A string that will be shown on the site. Defaults to user's |
|
1229 * username. It is likely that you will want to change this, for appearance. |
|
1230 * 'nickname' - The user's nickname, defaults to the user's username. |
|
1231 * 'first_name' - The user's first name. |
|
1232 * 'last_name' - The user's last name. |
|
1233 * 'description' - A string containing content about the user. |
|
1234 * 'rich_editing' - A string for whether to enable the rich editor. False |
|
1235 * if not empty. |
|
1236 * 'user_registered' - The date the user registered. Format is 'Y-m-d H:i:s'. |
|
1237 * 'role' - A string used to set the user's role. |
|
1238 * 'jabber' - User's Jabber account. |
|
1239 * 'aim' - User's AOL IM account. |
|
1240 * 'yim' - User's Yahoo IM account. |
|
1241 * |
|
1242 * @since 2.0.0 |
|
1243 * @uses $wpdb WordPress database layer. |
|
1244 * @uses apply_filters() Calls filters for most of the $userdata fields with the prefix 'pre_user'. See note above. |
|
1245 * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID |
|
1246 * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID |
|
1247 * |
|
1248 * @param array $userdata An array of user data. |
|
1249 * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created. |
|
1250 */ |
|
1251 function wp_insert_user($userdata) { |
|
1252 global $wpdb; |
|
1253 |
|
1254 extract($userdata, EXTR_SKIP); |
|
1255 |
|
1256 // Are we updating or creating? |
|
1257 if ( !empty($ID) ) { |
|
1258 $ID = (int) $ID; |
|
1259 $update = true; |
|
1260 $old_user_data = WP_User::get_data_by( 'id', $ID ); |
|
1261 } else { |
|
1262 $update = false; |
|
1263 // Hash the password |
|
1264 $user_pass = wp_hash_password($user_pass); |
|
1265 } |
|
1266 |
|
1267 $user_login = sanitize_user($user_login, true); |
|
1268 $user_login = apply_filters('pre_user_login', $user_login); |
|
1269 |
|
1270 //Remove any non-printable chars from the login string to see if we have ended up with an empty username |
|
1271 $user_login = trim($user_login); |
|
1272 |
|
1273 if ( empty($user_login) ) |
|
1274 return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') ); |
|
1275 |
|
1276 if ( !$update && username_exists( $user_login ) ) |
|
1277 return new WP_Error('existing_user_login', __('This username is already registered.') ); |
|
1278 |
|
1279 if ( empty($user_nicename) ) |
|
1280 $user_nicename = sanitize_title( $user_login ); |
|
1281 $user_nicename = apply_filters('pre_user_nicename', $user_nicename); |
|
1282 |
|
1283 if ( empty($user_url) ) |
|
1284 $user_url = ''; |
|
1285 $user_url = apply_filters('pre_user_url', $user_url); |
|
1286 |
|
1287 if ( empty($user_email) ) |
|
1288 $user_email = ''; |
|
1289 $user_email = apply_filters('pre_user_email', $user_email); |
|
1290 |
|
1291 if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) ) |
|
1292 return new WP_Error('existing_user_email', __('This email address is already registered.') ); |
|
1293 |
|
1294 if ( empty($display_name) ) |
|
1295 $display_name = $user_login; |
|
1296 $display_name = apply_filters('pre_user_display_name', $display_name); |
|
1297 |
|
1298 if ( empty($nickname) ) |
|
1299 $nickname = $user_login; |
|
1300 $nickname = apply_filters('pre_user_nickname', $nickname); |
|
1301 |
|
1302 if ( empty($first_name) ) |
|
1303 $first_name = ''; |
|
1304 $first_name = apply_filters('pre_user_first_name', $first_name); |
|
1305 |
|
1306 if ( empty($last_name) ) |
|
1307 $last_name = ''; |
|
1308 $last_name = apply_filters('pre_user_last_name', $last_name); |
|
1309 |
|
1310 if ( empty($description) ) |
|
1311 $description = ''; |
|
1312 $description = apply_filters('pre_user_description', $description); |
|
1313 |
|
1314 if ( empty($rich_editing) ) |
|
1315 $rich_editing = 'true'; |
|
1316 |
|
1317 if ( empty($comment_shortcuts) ) |
|
1318 $comment_shortcuts = 'false'; |
|
1319 |
|
1320 if ( empty($admin_color) ) |
|
1321 $admin_color = 'fresh'; |
|
1322 $admin_color = preg_replace('|[^a-z0-9 _.\-@]|i', '', $admin_color); |
|
1323 |
|
1324 if ( empty($use_ssl) ) |
|
1325 $use_ssl = 0; |
|
1326 |
|
1327 if ( empty($user_registered) ) |
|
1328 $user_registered = gmdate('Y-m-d H:i:s'); |
|
1329 |
|
1330 if ( empty($show_admin_bar_front) ) |
|
1331 $show_admin_bar_front = 'true'; |
|
1332 |
|
1333 $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login)); |
|
1334 |
|
1335 if ( $user_nicename_check ) { |
|
1336 $suffix = 2; |
|
1337 while ($user_nicename_check) { |
|
1338 $alt_user_nicename = $user_nicename . "-$suffix"; |
|
1339 $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $alt_user_nicename, $user_login)); |
|
1340 $suffix++; |
|
1341 } |
|
1342 $user_nicename = $alt_user_nicename; |
|
1343 } |
|
1344 |
|
1345 $data = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' ); |
|
1346 $data = stripslashes_deep( $data ); |
|
1347 |
|
1348 if ( $update ) { |
|
1349 $wpdb->update( $wpdb->users, $data, compact( 'ID' ) ); |
|
1350 $user_id = (int) $ID; |
|
1351 } else { |
|
1352 $wpdb->insert( $wpdb->users, $data + compact( 'user_login' ) ); |
|
1353 $user_id = (int) $wpdb->insert_id; |
|
1354 } |
|
1355 |
|
1356 $user = new WP_User( $user_id ); |
|
1357 |
|
1358 foreach ( _get_additional_user_keys( $user ) as $key ) { |
|
1359 if ( isset( $$key ) ) |
|
1360 update_user_meta( $user_id, $key, $$key ); |
|
1361 } |
|
1362 |
|
1363 if ( isset($role) ) |
|
1364 $user->set_role($role); |
|
1365 elseif ( !$update ) |
|
1366 $user->set_role(get_option('default_role')); |
|
1367 |
|
1368 wp_cache_delete($user_id, 'users'); |
|
1369 wp_cache_delete($user_login, 'userlogins'); |
|
1370 |
|
1371 if ( $update ) |
|
1372 do_action('profile_update', $user_id, $old_user_data); |
|
1373 else |
|
1374 do_action('user_register', $user_id); |
|
1375 |
|
1376 return $user_id; |
|
1377 } |
|
1378 |
|
1379 /** |
|
1380 * Update an user in the database. |
|
1381 * |
|
1382 * It is possible to update a user's password by specifying the 'user_pass' |
|
1383 * value in the $userdata parameter array. |
|
1384 * |
|
1385 * If $userdata does not contain an 'ID' key, then a new user will be created |
|
1386 * and the new user's ID will be returned. |
|
1387 * |
|
1388 * If current user's password is being updated, then the cookies will be |
|
1389 * cleared. |
|
1390 * |
|
1391 * @since 2.0.0 |
|
1392 * @see wp_insert_user() For what fields can be set in $userdata |
|
1393 * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already |
|
1394 * |
|
1395 * @param array $userdata An array of user data. |
|
1396 * @return int The updated user's ID. |
|
1397 */ |
|
1398 function wp_update_user($userdata) { |
|
1399 $ID = (int) $userdata['ID']; |
|
1400 |
|
1401 // First, get all of the original fields |
|
1402 $user_obj = get_userdata( $ID ); |
|
1403 |
|
1404 $user = get_object_vars( $user_obj->data ); |
|
1405 |
|
1406 // Add additional custom fields |
|
1407 foreach ( _get_additional_user_keys( $user_obj ) as $key ) { |
|
1408 $user[ $key ] = get_user_meta( $ID, $key, true ); |
|
1409 } |
|
1410 |
|
1411 // Escape data pulled from DB. |
|
1412 $user = add_magic_quotes( $user ); |
|
1413 |
|
1414 // If password is changing, hash it now. |
|
1415 if ( ! empty($userdata['user_pass']) ) { |
|
1416 $plaintext_pass = $userdata['user_pass']; |
|
1417 $userdata['user_pass'] = wp_hash_password($userdata['user_pass']); |
|
1418 } |
|
1419 |
|
1420 wp_cache_delete($user[ 'user_email' ], 'useremail'); |
|
1421 |
|
1422 // Merge old and new fields with new fields overwriting old ones. |
|
1423 $userdata = array_merge($user, $userdata); |
|
1424 $user_id = wp_insert_user($userdata); |
|
1425 |
|
1426 // Update the cookies if the password changed. |
|
1427 $current_user = wp_get_current_user(); |
|
1428 if ( $current_user->ID == $ID ) { |
|
1429 if ( isset($plaintext_pass) ) { |
|
1430 wp_clear_auth_cookie(); |
|
1431 wp_set_auth_cookie($ID); |
|
1432 } |
|
1433 } |
|
1434 |
|
1435 return $user_id; |
|
1436 } |
|
1437 |
|
1438 /** |
|
1439 * A simpler way of inserting an user into the database. |
|
1440 * |
|
1441 * Creates a new user with just the username, password, and email. For more |
|
1442 * complex user creation use wp_insert_user() to specify more information. |
|
1443 * |
|
1444 * @since 2.0.0 |
|
1445 * @see wp_insert_user() More complete way to create a new user |
|
1446 * |
|
1447 * @param string $username The user's username. |
|
1448 * @param string $password The user's password. |
|
1449 * @param string $email The user's email (optional). |
|
1450 * @return int The new user's ID. |
|
1451 */ |
|
1452 function wp_create_user($username, $password, $email = '') { |
|
1453 $user_login = esc_sql( $username ); |
|
1454 $user_email = esc_sql( $email ); |
|
1455 $user_pass = $password; |
|
1456 |
|
1457 $userdata = compact('user_login', 'user_email', 'user_pass'); |
|
1458 return wp_insert_user($userdata); |
|
1459 } |
|
1460 |
|
1461 /** |
|
1462 * Return a list of meta keys that wp_insert_user() is supposed to set. |
|
1463 * |
|
1464 * @access private |
|
1465 * @since 3.3.0 |
|
1466 * |
|
1467 * @param object $user WP_User instance |
|
1468 * @return array |
|
1469 */ |
|
1470 function _get_additional_user_keys( $user ) { |
|
1471 $keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front' ); |
|
1472 return array_merge( $keys, array_keys( _wp_get_user_contactmethods( $user ) ) ); |
|
1473 } |
|
1474 |
|
1475 /** |
|
1476 * Set up the default contact methods |
|
1477 * |
|
1478 * @access private |
|
1479 * @since |
|
1480 * |
|
1481 * @param object $user User data object (optional) |
|
1482 * @return array $user_contactmethods Array of contact methods and their labels. |
|
1483 */ |
|
1484 function _wp_get_user_contactmethods( $user = null ) { |
|
1485 $user_contactmethods = array( |
|
1486 'aim' => __('AIM'), |
|
1487 'yim' => __('Yahoo IM'), |
|
1488 'jabber' => __('Jabber / Google Talk') |
|
1489 ); |
|
1490 return apply_filters( 'user_contactmethods', $user_contactmethods, $user ); |
|
1491 } |