|
1 <?php |
|
2 /** |
|
3 * WordPress User API |
|
4 * |
|
5 * @package WordPress |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Authenticate user with remember capability. |
|
10 * |
|
11 * The credentials is an array that has 'user_login', 'user_password', and |
|
12 * 'remember' indices. If the credentials is not given, then the log in form |
|
13 * will be assumed and used if set. |
|
14 * |
|
15 * The various authentication cookies will be set by this function and will be |
|
16 * set for a longer period depending on if the 'remember' credential is set to |
|
17 * true. |
|
18 * |
|
19 * @since 2.5.0 |
|
20 * |
|
21 * @param array $credentials Optional. User info in order to sign on. |
|
22 * @param bool $secure_cookie Optional. Whether to use secure cookie. |
|
23 * @return object Either WP_Error on failure, or WP_User on success. |
|
24 */ |
|
25 function wp_signon( $credentials = '', $secure_cookie = '' ) { |
|
26 if ( empty($credentials) ) { |
|
27 if ( ! empty($_POST['log']) ) |
|
28 $credentials['user_login'] = $_POST['log']; |
|
29 if ( ! empty($_POST['pwd']) ) |
|
30 $credentials['user_password'] = $_POST['pwd']; |
|
31 if ( ! empty($_POST['rememberme']) ) |
|
32 $credentials['remember'] = $_POST['rememberme']; |
|
33 } |
|
34 |
|
35 if ( !empty($credentials['remember']) ) |
|
36 $credentials['remember'] = true; |
|
37 else |
|
38 $credentials['remember'] = false; |
|
39 |
|
40 // TODO do we deprecate the wp_authentication action? |
|
41 do_action_ref_array('wp_authenticate', array(&$credentials['user_login'], &$credentials['user_password'])); |
|
42 |
|
43 if ( '' === $secure_cookie ) |
|
44 $secure_cookie = is_ssl(); |
|
45 |
|
46 $secure_cookie = apply_filters('secure_signon_cookie', $secure_cookie, $credentials); |
|
47 |
|
48 global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie |
|
49 $auth_secure_cookie = $secure_cookie; |
|
50 |
|
51 add_filter('authenticate', 'wp_authenticate_cookie', 30, 3); |
|
52 |
|
53 $user = wp_authenticate($credentials['user_login'], $credentials['user_password']); |
|
54 |
|
55 if ( is_wp_error($user) ) { |
|
56 if ( $user->get_error_codes() == array('empty_username', 'empty_password') ) { |
|
57 $user = new WP_Error('', ''); |
|
58 } |
|
59 |
|
60 return $user; |
|
61 } |
|
62 |
|
63 wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie); |
|
64 do_action('wp_login', $user->user_login, $user); |
|
65 return $user; |
|
66 } |
|
67 |
|
68 /** |
|
69 * Authenticate the user using the username and password. |
|
70 */ |
|
71 add_filter('authenticate', 'wp_authenticate_username_password', 20, 3); |
|
72 function wp_authenticate_username_password($user, $username, $password) { |
|
73 if ( is_a($user, 'WP_User') ) { return $user; } |
|
74 |
|
75 if ( empty($username) || empty($password) ) { |
|
76 if ( is_wp_error( $user ) ) |
|
77 return $user; |
|
78 |
|
79 $error = new WP_Error(); |
|
80 |
|
81 if ( empty($username) ) |
|
82 $error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.')); |
|
83 |
|
84 if ( empty($password) ) |
|
85 $error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.')); |
|
86 |
|
87 return $error; |
|
88 } |
|
89 |
|
90 $user = get_user_by('login', $username); |
|
91 |
|
92 if ( !$user ) |
|
93 return new WP_Error( 'invalid_username', sprintf( __( '<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?' ), wp_lostpassword_url() ) ); |
|
94 |
|
95 $user = apply_filters('wp_authenticate_user', $user, $password); |
|
96 if ( is_wp_error($user) ) |
|
97 return $user; |
|
98 |
|
99 if ( !wp_check_password($password, $user->user_pass, $user->ID) ) |
|
100 return new WP_Error( 'incorrect_password', sprintf( __( '<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ), |
|
101 $username, wp_lostpassword_url() ) ); |
|
102 |
|
103 return $user; |
|
104 } |
|
105 |
|
106 /** |
|
107 * Authenticate the user using the WordPress auth cookie. |
|
108 */ |
|
109 function wp_authenticate_cookie($user, $username, $password) { |
|
110 if ( is_a($user, 'WP_User') ) { return $user; } |
|
111 |
|
112 if ( empty($username) && empty($password) ) { |
|
113 $user_id = wp_validate_auth_cookie(); |
|
114 if ( $user_id ) |
|
115 return new WP_User($user_id); |
|
116 |
|
117 global $auth_secure_cookie; |
|
118 |
|
119 if ( $auth_secure_cookie ) |
|
120 $auth_cookie = SECURE_AUTH_COOKIE; |
|
121 else |
|
122 $auth_cookie = AUTH_COOKIE; |
|
123 |
|
124 if ( !empty($_COOKIE[$auth_cookie]) ) |
|
125 return new WP_Error('expired_session', __('Please log in again.')); |
|
126 |
|
127 // If the cookie is not set, be silent. |
|
128 } |
|
129 |
|
130 return $user; |
|
131 } |
|
132 |
|
133 /** |
|
134 * For multisite blogs, check if the authenticated user has been marked as a |
|
135 * spammer, or if the user's primary blog has been marked as spam. |
|
136 * |
|
137 * @since 3.7.0 |
|
138 */ |
|
139 function wp_authenticate_spam_check( $user ) { |
|
140 if ( $user && is_a( $user, 'WP_User' ) && is_multisite() ) { |
|
141 $spammed = apply_filters( 'check_is_user_spammed', is_user_spammy(), $user ); |
|
142 |
|
143 if ( $spammed ) |
|
144 return new WP_Error( 'spammer_account', __( '<strong>ERROR</strong>: Your account has been marked as a spammer.' ) ); |
|
145 } |
|
146 return $user; |
|
147 } |
|
148 |
|
149 /** |
|
150 * Number of posts user has written. |
|
151 * |
|
152 * @since 3.0.0 |
|
153 * @uses $wpdb WordPress database object for queries. |
|
154 * |
|
155 * @param int $userid User ID. |
|
156 * @return int Amount of posts user has written. |
|
157 */ |
|
158 function count_user_posts($userid) { |
|
159 global $wpdb; |
|
160 |
|
161 $where = get_posts_by_author_sql('post', true, $userid); |
|
162 |
|
163 $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts $where" ); |
|
164 |
|
165 return apply_filters('get_usernumposts', $count, $userid); |
|
166 } |
|
167 |
|
168 /** |
|
169 * Number of posts written by a list of users. |
|
170 * |
|
171 * @since 3.0.0 |
|
172 * |
|
173 * @param array $users Array of user IDs. |
|
174 * @param string $post_type Optional. Post type to check. Defaults to post. |
|
175 * @param bool $public_only Optional. Only return counts for public posts. Defaults to false. |
|
176 * @return array Amount of posts each user has written. |
|
177 */ |
|
178 function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) { |
|
179 global $wpdb; |
|
180 |
|
181 $count = array(); |
|
182 if ( empty( $users ) || ! is_array( $users ) ) |
|
183 return $count; |
|
184 |
|
185 $userlist = implode( ',', array_map( 'absint', $users ) ); |
|
186 $where = get_posts_by_author_sql( $post_type, true, null, $public_only ); |
|
187 |
|
188 $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N ); |
|
189 foreach ( $result as $row ) { |
|
190 $count[ $row[0] ] = $row[1]; |
|
191 } |
|
192 |
|
193 foreach ( $users as $id ) { |
|
194 if ( ! isset( $count[ $id ] ) ) |
|
195 $count[ $id ] = 0; |
|
196 } |
|
197 |
|
198 return $count; |
|
199 } |
|
200 |
|
201 // |
|
202 // User option functions |
|
203 // |
|
204 |
|
205 /** |
|
206 * Get the current user's ID |
|
207 * |
|
208 * @since MU |
|
209 * |
|
210 * @uses wp_get_current_user |
|
211 * |
|
212 * @return int The current user's ID |
|
213 */ |
|
214 function get_current_user_id() { |
|
215 if ( ! function_exists( 'wp_get_current_user' ) ) |
|
216 return 0; |
|
217 $user = wp_get_current_user(); |
|
218 return ( isset( $user->ID ) ? (int) $user->ID : 0 ); |
|
219 } |
|
220 |
|
221 /** |
|
222 * Retrieve user option that can be either per Site or per Network. |
|
223 * |
|
224 * If the user ID is not given, then the current user will be used instead. If |
|
225 * the user ID is given, then the user data will be retrieved. The filter for |
|
226 * the result, will also pass the original option name and finally the user data |
|
227 * object as the third parameter. |
|
228 * |
|
229 * The option will first check for the per site name and then the per Network name. |
|
230 * |
|
231 * @since 2.0.0 |
|
232 * @uses $wpdb WordPress database object for queries. |
|
233 * @uses apply_filters() Calls 'get_user_option_$option' hook with result, |
|
234 * option parameter, and user data object. |
|
235 * |
|
236 * @param string $option User option name. |
|
237 * @param int $user Optional. User ID. |
|
238 * @param bool $deprecated Use get_option() to check for an option in the options table. |
|
239 * @return mixed |
|
240 */ |
|
241 function get_user_option( $option, $user = 0, $deprecated = '' ) { |
|
242 global $wpdb; |
|
243 |
|
244 if ( !empty( $deprecated ) ) |
|
245 _deprecated_argument( __FUNCTION__, '3.0' ); |
|
246 |
|
247 if ( empty( $user ) ) |
|
248 $user = get_current_user_id(); |
|
249 |
|
250 if ( ! $user = get_userdata( $user ) ) |
|
251 return false; |
|
252 |
|
253 $prefix = $wpdb->get_blog_prefix(); |
|
254 if ( $user->has_prop( $prefix . $option ) ) // Blog specific |
|
255 $result = $user->get( $prefix . $option ); |
|
256 elseif ( $user->has_prop( $option ) ) // User specific and cross-blog |
|
257 $result = $user->get( $option ); |
|
258 else |
|
259 $result = false; |
|
260 |
|
261 return apply_filters("get_user_option_{$option}", $result, $option, $user); |
|
262 } |
|
263 |
|
264 /** |
|
265 * Update user option with global blog capability. |
|
266 * |
|
267 * User options are just like user metadata except that they have support for |
|
268 * global blog options. If the 'global' parameter is false, which it is by default |
|
269 * it will prepend the WordPress table prefix to the option name. |
|
270 * |
|
271 * Deletes the user option if $newvalue is empty. |
|
272 * |
|
273 * @since 2.0.0 |
|
274 * @uses $wpdb WordPress database object for queries |
|
275 * |
|
276 * @param int $user_id User ID |
|
277 * @param string $option_name User option name. |
|
278 * @param mixed $newvalue User option value. |
|
279 * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). |
|
280 * @return unknown |
|
281 */ |
|
282 function update_user_option( $user_id, $option_name, $newvalue, $global = false ) { |
|
283 global $wpdb; |
|
284 |
|
285 if ( !$global ) |
|
286 $option_name = $wpdb->get_blog_prefix() . $option_name; |
|
287 |
|
288 return update_user_meta( $user_id, $option_name, $newvalue ); |
|
289 } |
|
290 |
|
291 /** |
|
292 * Delete user option with global blog capability. |
|
293 * |
|
294 * User options are just like user metadata except that they have support for |
|
295 * global blog options. If the 'global' parameter is false, which it is by default |
|
296 * it will prepend the WordPress table prefix to the option name. |
|
297 * |
|
298 * @since 3.0.0 |
|
299 * @uses $wpdb WordPress database object for queries |
|
300 * |
|
301 * @param int $user_id User ID |
|
302 * @param string $option_name User option name. |
|
303 * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). |
|
304 * @return unknown |
|
305 */ |
|
306 function delete_user_option( $user_id, $option_name, $global = false ) { |
|
307 global $wpdb; |
|
308 |
|
309 if ( !$global ) |
|
310 $option_name = $wpdb->get_blog_prefix() . $option_name; |
|
311 return delete_user_meta( $user_id, $option_name ); |
|
312 } |
|
313 |
|
314 /** |
|
315 * WordPress User Query class. |
|
316 * |
|
317 * @since 3.1.0 |
|
318 */ |
|
319 class WP_User_Query { |
|
320 |
|
321 /** |
|
322 * Query vars, after parsing |
|
323 * |
|
324 * @since 3.5.0 |
|
325 * @access public |
|
326 * @var array |
|
327 */ |
|
328 var $query_vars = array(); |
|
329 |
|
330 /** |
|
331 * List of found user ids |
|
332 * |
|
333 * @since 3.1.0 |
|
334 * @access private |
|
335 * @var array |
|
336 */ |
|
337 var $results; |
|
338 |
|
339 /** |
|
340 * Total number of found users for the current query |
|
341 * |
|
342 * @since 3.1.0 |
|
343 * @access private |
|
344 * @var int |
|
345 */ |
|
346 var $total_users = 0; |
|
347 |
|
348 // SQL clauses |
|
349 var $query_fields; |
|
350 var $query_from; |
|
351 var $query_where; |
|
352 var $query_orderby; |
|
353 var $query_limit; |
|
354 |
|
355 /** |
|
356 * PHP5 constructor |
|
357 * |
|
358 * @since 3.1.0 |
|
359 * |
|
360 * @param string|array $args The query variables |
|
361 * @return WP_User_Query |
|
362 */ |
|
363 function __construct( $query = null ) { |
|
364 if ( !empty( $query ) ) { |
|
365 $this->query_vars = wp_parse_args( $query, array( |
|
366 'blog_id' => $GLOBALS['blog_id'], |
|
367 'role' => '', |
|
368 'meta_key' => '', |
|
369 'meta_value' => '', |
|
370 'meta_compare' => '', |
|
371 'include' => array(), |
|
372 'exclude' => array(), |
|
373 'search' => '', |
|
374 'search_columns' => array(), |
|
375 'orderby' => 'login', |
|
376 'order' => 'ASC', |
|
377 'offset' => '', |
|
378 'number' => '', |
|
379 'count_total' => true, |
|
380 'fields' => 'all', |
|
381 'who' => '' |
|
382 ) ); |
|
383 |
|
384 $this->prepare_query(); |
|
385 $this->query(); |
|
386 } |
|
387 } |
|
388 |
|
389 /** |
|
390 * Prepare the query variables |
|
391 * |
|
392 * @since 3.1.0 |
|
393 * @access private |
|
394 */ |
|
395 function prepare_query() { |
|
396 global $wpdb; |
|
397 |
|
398 $qv =& $this->query_vars; |
|
399 |
|
400 if ( is_array( $qv['fields'] ) ) { |
|
401 $qv['fields'] = array_unique( $qv['fields'] ); |
|
402 |
|
403 $this->query_fields = array(); |
|
404 foreach ( $qv['fields'] as $field ) { |
|
405 $field = 'ID' === $field ? 'ID' : sanitize_key( $field ); |
|
406 $this->query_fields[] = "$wpdb->users.$field"; |
|
407 } |
|
408 $this->query_fields = implode( ',', $this->query_fields ); |
|
409 } elseif ( 'all' == $qv['fields'] ) { |
|
410 $this->query_fields = "$wpdb->users.*"; |
|
411 } else { |
|
412 $this->query_fields = "$wpdb->users.ID"; |
|
413 } |
|
414 |
|
415 if ( isset( $qv['count_total'] ) && $qv['count_total'] ) |
|
416 $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; |
|
417 |
|
418 $this->query_from = "FROM $wpdb->users"; |
|
419 $this->query_where = "WHERE 1=1"; |
|
420 |
|
421 // sorting |
|
422 if ( isset( $qv['orderby'] ) ) { |
|
423 if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { |
|
424 $orderby = 'user_' . $qv['orderby']; |
|
425 } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) { |
|
426 $orderby = $qv['orderby']; |
|
427 } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) { |
|
428 $orderby = 'display_name'; |
|
429 } elseif ( 'post_count' == $qv['orderby'] ) { |
|
430 // todo: avoid the JOIN |
|
431 $where = get_posts_by_author_sql('post'); |
|
432 $this->query_from .= " LEFT OUTER JOIN ( |
|
433 SELECT post_author, COUNT(*) as post_count |
|
434 FROM $wpdb->posts |
|
435 $where |
|
436 GROUP BY post_author |
|
437 ) p ON ({$wpdb->users}.ID = p.post_author) |
|
438 "; |
|
439 $orderby = 'post_count'; |
|
440 } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) { |
|
441 $orderby = 'ID'; |
|
442 } elseif ( 'meta_value' == $qv['orderby'] ) { |
|
443 $orderby = "$wpdb->usermeta.meta_value"; |
|
444 } else { |
|
445 $orderby = 'user_login'; |
|
446 } |
|
447 } |
|
448 |
|
449 if ( empty( $orderby ) ) |
|
450 $orderby = 'user_login'; |
|
451 |
|
452 $qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : ''; |
|
453 if ( 'ASC' == $qv['order'] ) |
|
454 $order = 'ASC'; |
|
455 else |
|
456 $order = 'DESC'; |
|
457 $this->query_orderby = "ORDER BY $orderby $order"; |
|
458 |
|
459 // limit |
|
460 if ( isset( $qv['number'] ) && $qv['number'] ) { |
|
461 if ( $qv['offset'] ) |
|
462 $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']); |
|
463 else |
|
464 $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']); |
|
465 } |
|
466 |
|
467 $search = ''; |
|
468 if ( isset( $qv['search'] ) ) |
|
469 $search = trim( $qv['search'] ); |
|
470 |
|
471 if ( $search ) { |
|
472 $leading_wild = ( ltrim($search, '*') != $search ); |
|
473 $trailing_wild = ( rtrim($search, '*') != $search ); |
|
474 if ( $leading_wild && $trailing_wild ) |
|
475 $wild = 'both'; |
|
476 elseif ( $leading_wild ) |
|
477 $wild = 'leading'; |
|
478 elseif ( $trailing_wild ) |
|
479 $wild = 'trailing'; |
|
480 else |
|
481 $wild = false; |
|
482 if ( $wild ) |
|
483 $search = trim($search, '*'); |
|
484 |
|
485 $search_columns = array(); |
|
486 if ( $qv['search_columns'] ) |
|
487 $search_columns = array_intersect( $qv['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename' ) ); |
|
488 if ( ! $search_columns ) { |
|
489 if ( false !== strpos( $search, '@') ) |
|
490 $search_columns = array('user_email'); |
|
491 elseif ( is_numeric($search) ) |
|
492 $search_columns = array('user_login', 'ID'); |
|
493 elseif ( preg_match('|^https?://|', $search) && ! ( is_multisite() && wp_is_large_network( 'users' ) ) ) |
|
494 $search_columns = array('user_url'); |
|
495 else |
|
496 $search_columns = array('user_login', 'user_nicename'); |
|
497 } |
|
498 |
|
499 $search_columns = apply_filters( 'user_search_columns', $search_columns, $search, $this ); |
|
500 |
|
501 $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild ); |
|
502 } |
|
503 |
|
504 $blog_id = 0; |
|
505 if ( isset( $qv['blog_id'] ) ) |
|
506 $blog_id = absint( $qv['blog_id'] ); |
|
507 |
|
508 if ( isset( $qv['who'] ) && 'authors' == $qv['who'] && $blog_id ) { |
|
509 $qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level'; |
|
510 $qv['meta_value'] = 0; |
|
511 $qv['meta_compare'] = '!='; |
|
512 $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query |
|
513 } |
|
514 |
|
515 $role = ''; |
|
516 if ( isset( $qv['role'] ) ) |
|
517 $role = trim( $qv['role'] ); |
|
518 |
|
519 if ( $blog_id && ( $role || is_multisite() ) ) { |
|
520 $cap_meta_query = array(); |
|
521 $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; |
|
522 |
|
523 if ( $role ) { |
|
524 $cap_meta_query['value'] = '"' . $role . '"'; |
|
525 $cap_meta_query['compare'] = 'like'; |
|
526 } |
|
527 |
|
528 $qv['meta_query'][] = $cap_meta_query; |
|
529 } |
|
530 |
|
531 $meta_query = new WP_Meta_Query(); |
|
532 $meta_query->parse_query_vars( $qv ); |
|
533 |
|
534 if ( !empty( $meta_query->queries ) ) { |
|
535 $clauses = $meta_query->get_sql( 'user', $wpdb->users, 'ID', $this ); |
|
536 $this->query_from .= $clauses['join']; |
|
537 $this->query_where .= $clauses['where']; |
|
538 |
|
539 if ( 'OR' == $meta_query->relation ) |
|
540 $this->query_fields = 'DISTINCT ' . $this->query_fields; |
|
541 } |
|
542 |
|
543 if ( ! empty( $qv['include'] ) ) { |
|
544 $ids = implode( ',', wp_parse_id_list( $qv['include'] ) ); |
|
545 $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; |
|
546 } elseif ( ! empty( $qv['exclude'] ) ) { |
|
547 $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); |
|
548 $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)"; |
|
549 } |
|
550 |
|
551 do_action_ref_array( 'pre_user_query', array( &$this ) ); |
|
552 } |
|
553 |
|
554 /** |
|
555 * Execute the query, with the current variables |
|
556 * |
|
557 * @since 3.1.0 |
|
558 * @access private |
|
559 */ |
|
560 function query() { |
|
561 global $wpdb; |
|
562 |
|
563 $qv =& $this->query_vars; |
|
564 |
|
565 if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) { |
|
566 $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); |
|
567 } else { |
|
568 $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); |
|
569 } |
|
570 |
|
571 if ( isset( $qv['count_total'] ) && $qv['count_total'] ) |
|
572 $this->total_users = $wpdb->get_var( apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()' ) ); |
|
573 |
|
574 if ( !$this->results ) |
|
575 return; |
|
576 |
|
577 if ( 'all_with_meta' == $qv['fields'] ) { |
|
578 cache_users( $this->results ); |
|
579 |
|
580 $r = array(); |
|
581 foreach ( $this->results as $userid ) |
|
582 $r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] ); |
|
583 |
|
584 $this->results = $r; |
|
585 } elseif ( 'all' == $qv['fields'] ) { |
|
586 foreach ( $this->results as $key => $user ) { |
|
587 $this->results[ $key ] = new WP_User( $user ); |
|
588 } |
|
589 } |
|
590 } |
|
591 |
|
592 /** |
|
593 * Retrieve query variable. |
|
594 * |
|
595 * @since 3.5.0 |
|
596 * @access public |
|
597 * |
|
598 * @param string $query_var Query variable key. |
|
599 * @return mixed |
|
600 */ |
|
601 function get( $query_var ) { |
|
602 if ( isset( $this->query_vars[$query_var] ) ) |
|
603 return $this->query_vars[$query_var]; |
|
604 |
|
605 return null; |
|
606 } |
|
607 |
|
608 /** |
|
609 * Set query variable. |
|
610 * |
|
611 * @since 3.5.0 |
|
612 * @access public |
|
613 * |
|
614 * @param string $query_var Query variable key. |
|
615 * @param mixed $value Query variable value. |
|
616 */ |
|
617 function set( $query_var, $value ) { |
|
618 $this->query_vars[$query_var] = $value; |
|
619 } |
|
620 |
|
621 /* |
|
622 * Used internally to generate an SQL string for searching across multiple columns |
|
623 * |
|
624 * @access protected |
|
625 * @since 3.1.0 |
|
626 * |
|
627 * @param string $string |
|
628 * @param array $cols |
|
629 * @param bool $wild Whether to allow wildcard searches. Default is false for Network Admin, true for |
|
630 * single site. Single site allows leading and trailing wildcards, Network Admin only trailing. |
|
631 * @return string |
|
632 */ |
|
633 function get_search_sql( $string, $cols, $wild = false ) { |
|
634 $string = esc_sql( $string ); |
|
635 |
|
636 $searches = array(); |
|
637 $leading_wild = ( 'leading' == $wild || 'both' == $wild ) ? '%' : ''; |
|
638 $trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : ''; |
|
639 foreach ( $cols as $col ) { |
|
640 if ( 'ID' == $col ) |
|
641 $searches[] = "$col = '$string'"; |
|
642 else |
|
643 $searches[] = "$col LIKE '$leading_wild" . like_escape($string) . "$trailing_wild'"; |
|
644 } |
|
645 |
|
646 return ' AND (' . implode(' OR ', $searches) . ')'; |
|
647 } |
|
648 |
|
649 /** |
|
650 * Return the list of users |
|
651 * |
|
652 * @since 3.1.0 |
|
653 * @access public |
|
654 * |
|
655 * @return array |
|
656 */ |
|
657 function get_results() { |
|
658 return $this->results; |
|
659 } |
|
660 |
|
661 /** |
|
662 * Return the total number of users for the current query |
|
663 * |
|
664 * @since 3.1.0 |
|
665 * @access public |
|
666 * |
|
667 * @return array |
|
668 */ |
|
669 function get_total() { |
|
670 return $this->total_users; |
|
671 } |
|
672 } |
|
673 |
|
674 /** |
|
675 * Retrieve list of users matching criteria. |
|
676 * |
|
677 * @since 3.1.0 |
|
678 * @uses $wpdb |
|
679 * @uses WP_User_Query See for default arguments and information. |
|
680 * |
|
681 * @param array $args Optional. |
|
682 * @return array List of users. |
|
683 */ |
|
684 function get_users( $args = array() ) { |
|
685 |
|
686 $args = wp_parse_args( $args ); |
|
687 $args['count_total'] = false; |
|
688 |
|
689 $user_search = new WP_User_Query($args); |
|
690 |
|
691 return (array) $user_search->get_results(); |
|
692 } |
|
693 |
|
694 /** |
|
695 * Get the blogs a user belongs to. |
|
696 * |
|
697 * @since 3.0.0 |
|
698 * |
|
699 * @param int $user_id User ID |
|
700 * @param bool $all Whether to retrieve all blogs, or only blogs that are not marked as deleted, archived, or spam. |
|
701 * @return array A list of the user's blogs. An empty array if the user doesn't exist or belongs to no blogs. |
|
702 */ |
|
703 function get_blogs_of_user( $user_id, $all = false ) { |
|
704 global $wpdb; |
|
705 |
|
706 $user_id = (int) $user_id; |
|
707 |
|
708 // Logged out users can't have blogs |
|
709 if ( empty( $user_id ) ) |
|
710 return array(); |
|
711 |
|
712 $keys = get_user_meta( $user_id ); |
|
713 if ( empty( $keys ) ) |
|
714 return array(); |
|
715 |
|
716 if ( ! is_multisite() ) { |
|
717 $blog_id = get_current_blog_id(); |
|
718 $blogs = array( $blog_id => new stdClass ); |
|
719 $blogs[ $blog_id ]->userblog_id = $blog_id; |
|
720 $blogs[ $blog_id ]->blogname = get_option('blogname'); |
|
721 $blogs[ $blog_id ]->domain = ''; |
|
722 $blogs[ $blog_id ]->path = ''; |
|
723 $blogs[ $blog_id ]->site_id = 1; |
|
724 $blogs[ $blog_id ]->siteurl = get_option('siteurl'); |
|
725 $blogs[ $blog_id ]->archived = 0; |
|
726 $blogs[ $blog_id ]->spam = 0; |
|
727 $blogs[ $blog_id ]->deleted = 0; |
|
728 return $blogs; |
|
729 } |
|
730 |
|
731 $blogs = array(); |
|
732 |
|
733 if ( isset( $keys[ $wpdb->base_prefix . 'capabilities' ] ) && defined( 'MULTISITE' ) ) { |
|
734 $blog = get_blog_details( 1 ); |
|
735 if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) { |
|
736 $blogs[ 1 ] = (object) array( |
|
737 'userblog_id' => 1, |
|
738 'blogname' => $blog->blogname, |
|
739 'domain' => $blog->domain, |
|
740 'path' => $blog->path, |
|
741 'site_id' => $blog->site_id, |
|
742 'siteurl' => $blog->siteurl, |
|
743 'archived' => 0, |
|
744 'spam' => 0, |
|
745 'deleted' => 0 |
|
746 ); |
|
747 } |
|
748 unset( $keys[ $wpdb->base_prefix . 'capabilities' ] ); |
|
749 } |
|
750 |
|
751 $keys = array_keys( $keys ); |
|
752 |
|
753 foreach ( $keys as $key ) { |
|
754 if ( 'capabilities' !== substr( $key, -12 ) ) |
|
755 continue; |
|
756 if ( $wpdb->base_prefix && 0 !== strpos( $key, $wpdb->base_prefix ) ) |
|
757 continue; |
|
758 $blog_id = str_replace( array( $wpdb->base_prefix, '_capabilities' ), '', $key ); |
|
759 if ( ! is_numeric( $blog_id ) ) |
|
760 continue; |
|
761 |
|
762 $blog_id = (int) $blog_id; |
|
763 $blog = get_blog_details( $blog_id ); |
|
764 if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) { |
|
765 $blogs[ $blog_id ] = (object) array( |
|
766 'userblog_id' => $blog_id, |
|
767 'blogname' => $blog->blogname, |
|
768 'domain' => $blog->domain, |
|
769 'path' => $blog->path, |
|
770 'site_id' => $blog->site_id, |
|
771 'siteurl' => $blog->siteurl, |
|
772 'archived' => 0, |
|
773 'spam' => 0, |
|
774 'deleted' => 0 |
|
775 ); |
|
776 } |
|
777 } |
|
778 |
|
779 return apply_filters( 'get_blogs_of_user', $blogs, $user_id, $all ); |
|
780 } |
|
781 |
|
782 /** |
|
783 * Find out whether a user is a member of a given blog. |
|
784 * |
|
785 * @since MU 1.1 |
|
786 * @uses get_blogs_of_user() |
|
787 * |
|
788 * @param int $user_id Optional. The unique ID of the user. Defaults to the current user. |
|
789 * @param int $blog_id Optional. ID of the blog to check. Defaults to the current site. |
|
790 * @return bool |
|
791 */ |
|
792 function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) { |
|
793 $user_id = (int) $user_id; |
|
794 $blog_id = (int) $blog_id; |
|
795 |
|
796 if ( empty( $user_id ) ) |
|
797 $user_id = get_current_user_id(); |
|
798 |
|
799 if ( empty( $blog_id ) ) |
|
800 $blog_id = get_current_blog_id(); |
|
801 |
|
802 $blogs = get_blogs_of_user( $user_id ); |
|
803 return array_key_exists( $blog_id, $blogs ); |
|
804 } |
|
805 |
|
806 /** |
|
807 * Add meta data field to a user. |
|
808 * |
|
809 * Post meta data is called "Custom Fields" on the Administration Screens. |
|
810 * |
|
811 * @since 3.0.0 |
|
812 * @uses add_metadata() |
|
813 * @link http://codex.wordpress.org/Function_Reference/add_user_meta |
|
814 * |
|
815 * @param int $user_id Post ID. |
|
816 * @param string $meta_key Metadata name. |
|
817 * @param mixed $meta_value Metadata value. |
|
818 * @param bool $unique Optional, default is false. Whether the same key should not be added. |
|
819 * @return int|bool Meta ID on success, false on failure. |
|
820 */ |
|
821 function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { |
|
822 return add_metadata('user', $user_id, $meta_key, $meta_value, $unique); |
|
823 } |
|
824 |
|
825 /** |
|
826 * Remove metadata matching criteria from a user. |
|
827 * |
|
828 * You can match based on the key, or key and value. Removing based on key and |
|
829 * value, will keep from removing duplicate metadata with the same key. It also |
|
830 * allows removing all metadata matching key, if needed. |
|
831 * |
|
832 * @since 3.0.0 |
|
833 * @uses delete_metadata() |
|
834 * @link http://codex.wordpress.org/Function_Reference/delete_user_meta |
|
835 * |
|
836 * @param int $user_id user ID |
|
837 * @param string $meta_key Metadata name. |
|
838 * @param mixed $meta_value Optional. Metadata value. |
|
839 * @return bool True on success, false on failure. |
|
840 */ |
|
841 function delete_user_meta($user_id, $meta_key, $meta_value = '') { |
|
842 return delete_metadata('user', $user_id, $meta_key, $meta_value); |
|
843 } |
|
844 |
|
845 /** |
|
846 * Retrieve user meta field for a user. |
|
847 * |
|
848 * @since 3.0.0 |
|
849 * @uses get_metadata() |
|
850 * @link http://codex.wordpress.org/Function_Reference/get_user_meta |
|
851 * |
|
852 * @param int $user_id Post ID. |
|
853 * @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. |
|
854 * @param bool $single Whether to return a single value. |
|
855 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single |
|
856 * is true. |
|
857 */ |
|
858 function get_user_meta($user_id, $key = '', $single = false) { |
|
859 return get_metadata('user', $user_id, $key, $single); |
|
860 } |
|
861 |
|
862 /** |
|
863 * Update user meta field based on user ID. |
|
864 * |
|
865 * Use the $prev_value parameter to differentiate between meta fields with the |
|
866 * same key and user ID. |
|
867 * |
|
868 * If the meta field for the user does not exist, it will be added. |
|
869 * |
|
870 * @since 3.0.0 |
|
871 * @uses update_metadata |
|
872 * @link http://codex.wordpress.org/Function_Reference/update_user_meta |
|
873 * |
|
874 * @param int $user_id Post ID. |
|
875 * @param string $meta_key Metadata key. |
|
876 * @param mixed $meta_value Metadata value. |
|
877 * @param mixed $prev_value Optional. Previous value to check before removing. |
|
878 * @return bool True on success, false on failure. |
|
879 */ |
|
880 function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { |
|
881 return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value); |
|
882 } |
|
883 |
|
884 /** |
|
885 * Count number of users who have each of the user roles. |
|
886 * |
|
887 * Assumes there are neither duplicated nor orphaned capabilities meta_values. |
|
888 * Assumes role names are unique phrases. Same assumption made by WP_User_Query::prepare_query() |
|
889 * Using $strategy = 'time' this is CPU-intensive and should handle around 10^7 users. |
|
890 * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257. |
|
891 * |
|
892 * @since 3.0.0 |
|
893 * @param string $strategy 'time' or 'memory' |
|
894 * @return array Includes a grand total and an array of counts indexed by role strings. |
|
895 */ |
|
896 function count_users($strategy = 'time') { |
|
897 global $wpdb, $wp_roles; |
|
898 |
|
899 // Initialize |
|
900 $id = get_current_blog_id(); |
|
901 $blog_prefix = $wpdb->get_blog_prefix($id); |
|
902 $result = array(); |
|
903 |
|
904 if ( 'time' == $strategy ) { |
|
905 global $wp_roles; |
|
906 |
|
907 if ( ! isset( $wp_roles ) ) |
|
908 $wp_roles = new WP_Roles(); |
|
909 |
|
910 $avail_roles = $wp_roles->get_names(); |
|
911 |
|
912 // Build a CPU-intensive query that will return concise information. |
|
913 $select_count = array(); |
|
914 foreach ( $avail_roles as $this_role => $name ) { |
|
915 $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape( $this_role ) . "\"%', false))"; |
|
916 } |
|
917 $select_count = implode(', ', $select_count); |
|
918 |
|
919 // Add the meta_value index to the selection list, then run the query. |
|
920 $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N ); |
|
921 |
|
922 // Run the previous loop again to associate results with role names. |
|
923 $col = 0; |
|
924 $role_counts = array(); |
|
925 foreach ( $avail_roles as $this_role => $name ) { |
|
926 $count = (int) $row[$col++]; |
|
927 if ($count > 0) { |
|
928 $role_counts[$this_role] = $count; |
|
929 } |
|
930 } |
|
931 |
|
932 // Get the meta_value index from the end of the result set. |
|
933 $total_users = (int) $row[$col]; |
|
934 |
|
935 $result['total_users'] = $total_users; |
|
936 $result['avail_roles'] =& $role_counts; |
|
937 } else { |
|
938 $avail_roles = array(); |
|
939 |
|
940 $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); |
|
941 |
|
942 foreach ( $users_of_blog as $caps_meta ) { |
|
943 $b_roles = maybe_unserialize($caps_meta); |
|
944 if ( ! is_array( $b_roles ) ) |
|
945 continue; |
|
946 foreach ( $b_roles as $b_role => $val ) { |
|
947 if ( isset($avail_roles[$b_role]) ) { |
|
948 $avail_roles[$b_role]++; |
|
949 } else { |
|
950 $avail_roles[$b_role] = 1; |
|
951 } |
|
952 } |
|
953 } |
|
954 |
|
955 $result['total_users'] = count( $users_of_blog ); |
|
956 $result['avail_roles'] =& $avail_roles; |
|
957 } |
|
958 |
|
959 return $result; |
|
960 } |
|
961 |
|
962 // |
|
963 // Private helper functions |
|
964 // |
|
965 |
|
966 /** |
|
967 * Set up global user vars. |
|
968 * |
|
969 * Used by wp_set_current_user() for back compat. Might be deprecated in the future. |
|
970 * |
|
971 * @since 2.0.4 |
|
972 * @global string $userdata User description. |
|
973 * @global string $user_login The user username for logging in |
|
974 * @global int $user_level The level of the user |
|
975 * @global int $user_ID The ID of the user |
|
976 * @global string $user_email The email address of the user |
|
977 * @global string $user_url The url in the user's profile |
|
978 * @global string $user_identity The display name of the user |
|
979 * |
|
980 * @param int $for_user_id Optional. User ID to set up global data. |
|
981 */ |
|
982 function setup_userdata($for_user_id = '') { |
|
983 global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_identity; |
|
984 |
|
985 if ( '' == $for_user_id ) |
|
986 $for_user_id = get_current_user_id(); |
|
987 $user = get_userdata( $for_user_id ); |
|
988 |
|
989 if ( ! $user ) { |
|
990 $user_ID = 0; |
|
991 $user_level = 0; |
|
992 $userdata = null; |
|
993 $user_login = $user_email = $user_url = $user_identity = ''; |
|
994 return; |
|
995 } |
|
996 |
|
997 $user_ID = (int) $user->ID; |
|
998 $user_level = (int) $user->user_level; |
|
999 $userdata = $user; |
|
1000 $user_login = $user->user_login; |
|
1001 $user_email = $user->user_email; |
|
1002 $user_url = $user->user_url; |
|
1003 $user_identity = $user->display_name; |
|
1004 } |
|
1005 |
|
1006 /** |
|
1007 * Create dropdown HTML content of users. |
|
1008 * |
|
1009 * The content can either be displayed, which it is by default or retrieved by |
|
1010 * setting the 'echo' argument. The 'include' and 'exclude' arguments do not |
|
1011 * need to be used; all users will be displayed in that case. Only one can be |
|
1012 * used, either 'include' or 'exclude', but not both. |
|
1013 * |
|
1014 * The available arguments are as follows: |
|
1015 * <ol> |
|
1016 * <li>show_option_all - Text to show all and whether HTML option exists.</li> |
|
1017 * <li>show_option_none - Text for show none and whether HTML option exists.</li> |
|
1018 * <li>hide_if_only_one_author - Don't create the dropdown if there is only one user.</li> |
|
1019 * <li>orderby - SQL order by clause for what order the users appear. Default is 'display_name'.</li> |
|
1020 * <li>order - Default is 'ASC'. Can also be 'DESC'.</li> |
|
1021 * <li>include - User IDs to include.</li> |
|
1022 * <li>exclude - User IDs to exclude.</li> |
|
1023 * <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> |
|
1024 * <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> |
|
1025 * <li>echo - Default is '1'. Whether to display or retrieve content.</li> |
|
1026 * <li>selected - Which User ID is selected.</li> |
|
1027 * <li>include_selected - Always include the selected user ID in the dropdown. Default is false.</li> |
|
1028 * <li>name - Default is 'user'. Name attribute of select element.</li> |
|
1029 * <li>id - Default is the value of the 'name' parameter. ID attribute of select element.</li> |
|
1030 * <li>class - Class attribute of select element.</li> |
|
1031 * <li>blog_id - ID of blog (Multisite only). Defaults to ID of current blog.</li> |
|
1032 * <li>who - Which users to query. Currently only 'authors' is supported. Default is all users.</li> |
|
1033 * </ol> |
|
1034 * |
|
1035 * @since 2.3.0 |
|
1036 * @uses $wpdb WordPress database object for queries |
|
1037 * |
|
1038 * @param string|array $args Optional. Override defaults. |
|
1039 * @return string|null Null on display. String of HTML content on retrieve. |
|
1040 */ |
|
1041 function wp_dropdown_users( $args = '' ) { |
|
1042 $defaults = array( |
|
1043 'show_option_all' => '', 'show_option_none' => '', 'hide_if_only_one_author' => '', |
|
1044 'orderby' => 'display_name', 'order' => 'ASC', |
|
1045 'include' => '', 'exclude' => '', 'multi' => 0, |
|
1046 'show' => 'display_name', 'echo' => 1, |
|
1047 'selected' => 0, 'name' => 'user', 'class' => '', 'id' => '', |
|
1048 'blog_id' => $GLOBALS['blog_id'], 'who' => '', 'include_selected' => false |
|
1049 ); |
|
1050 |
|
1051 $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0; |
|
1052 |
|
1053 $r = wp_parse_args( $args, $defaults ); |
|
1054 extract( $r, EXTR_SKIP ); |
|
1055 |
|
1056 $query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who' ) ); |
|
1057 $query_args['fields'] = array( 'ID', 'user_login', $show ); |
|
1058 $users = get_users( $query_args ); |
|
1059 |
|
1060 $output = ''; |
|
1061 if ( !empty($users) && ( empty($hide_if_only_one_author) || count($users) > 1 ) ) { |
|
1062 $name = esc_attr( $name ); |
|
1063 if ( $multi && ! $id ) |
|
1064 $id = ''; |
|
1065 else |
|
1066 $id = $id ? " id='" . esc_attr( $id ) . "'" : " id='$name'"; |
|
1067 |
|
1068 $output = "<select name='{$name}'{$id} class='$class'>\n"; |
|
1069 |
|
1070 if ( $show_option_all ) |
|
1071 $output .= "\t<option value='0'>$show_option_all</option>\n"; |
|
1072 |
|
1073 if ( $show_option_none ) { |
|
1074 $_selected = selected( -1, $selected, false ); |
|
1075 $output .= "\t<option value='-1'$_selected>$show_option_none</option>\n"; |
|
1076 } |
|
1077 |
|
1078 $found_selected = false; |
|
1079 foreach ( (array) $users as $user ) { |
|
1080 $user->ID = (int) $user->ID; |
|
1081 $_selected = selected( $user->ID, $selected, false ); |
|
1082 if ( $_selected ) |
|
1083 $found_selected = true; |
|
1084 $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')'; |
|
1085 $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n"; |
|
1086 } |
|
1087 |
|
1088 if ( $include_selected && ! $found_selected && ( $selected > 0 ) ) { |
|
1089 $user = get_userdata( $selected ); |
|
1090 $_selected = selected( $user->ID, $selected, false ); |
|
1091 $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')'; |
|
1092 $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n"; |
|
1093 } |
|
1094 |
|
1095 $output .= "</select>"; |
|
1096 } |
|
1097 |
|
1098 $output = apply_filters('wp_dropdown_users', $output); |
|
1099 |
|
1100 if ( $echo ) |
|
1101 echo $output; |
|
1102 |
|
1103 return $output; |
|
1104 } |
|
1105 |
|
1106 /** |
|
1107 * Sanitize user field based on context. |
|
1108 * |
|
1109 * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The |
|
1110 * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' |
|
1111 * when calling filters. |
|
1112 * |
|
1113 * @since 2.3.0 |
|
1114 * @uses apply_filters() Calls 'edit_$field' passing $value and $user_id if $context == 'edit'. |
|
1115 * $field is prefixed with 'user_' if it isn't already. |
|
1116 * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db'. $field is prefixed with |
|
1117 * 'user_' if it isn't already. |
|
1118 * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything |
|
1119 * other than 'raw', 'edit' and 'db'. $field is prefixed with 'user_' if it isn't already. |
|
1120 * |
|
1121 * @param string $field The user Object field name. |
|
1122 * @param mixed $value The user Object value. |
|
1123 * @param int $user_id user ID. |
|
1124 * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display', |
|
1125 * 'attribute' and 'js'. |
|
1126 * @return mixed Sanitized value. |
|
1127 */ |
|
1128 function sanitize_user_field($field, $value, $user_id, $context) { |
|
1129 $int_fields = array('ID'); |
|
1130 if ( in_array($field, $int_fields) ) |
|
1131 $value = (int) $value; |
|
1132 |
|
1133 if ( 'raw' == $context ) |
|
1134 return $value; |
|
1135 |
|
1136 if ( !is_string($value) && !is_numeric($value) ) |
|
1137 return $value; |
|
1138 |
|
1139 $prefixed = false !== strpos( $field, 'user_' ); |
|
1140 |
|
1141 if ( 'edit' == $context ) { |
|
1142 if ( $prefixed ) { |
|
1143 $value = apply_filters("edit_{$field}", $value, $user_id); |
|
1144 } else { |
|
1145 $value = apply_filters("edit_user_{$field}", $value, $user_id); |
|
1146 } |
|
1147 |
|
1148 if ( 'description' == $field ) |
|
1149 $value = esc_html( $value ); // textarea_escaped? |
|
1150 else |
|
1151 $value = esc_attr($value); |
|
1152 } else if ( 'db' == $context ) { |
|
1153 if ( $prefixed ) { |
|
1154 $value = apply_filters("pre_{$field}", $value); |
|
1155 } else { |
|
1156 $value = apply_filters("pre_user_{$field}", $value); |
|
1157 } |
|
1158 } else { |
|
1159 // Use display filters by default. |
|
1160 if ( $prefixed ) |
|
1161 $value = apply_filters($field, $value, $user_id, $context); |
|
1162 else |
|
1163 $value = apply_filters("user_{$field}", $value, $user_id, $context); |
|
1164 } |
|
1165 |
|
1166 if ( 'user_url' == $field ) |
|
1167 $value = esc_url($value); |
|
1168 |
|
1169 if ( 'attribute' == $context ) |
|
1170 $value = esc_attr($value); |
|
1171 else if ( 'js' == $context ) |
|
1172 $value = esc_js($value); |
|
1173 |
|
1174 return $value; |
|
1175 } |
|
1176 |
|
1177 /** |
|
1178 * Update all user caches |
|
1179 * |
|
1180 * @since 3.0.0 |
|
1181 * |
|
1182 * @param object $user User object to be cached |
|
1183 */ |
|
1184 function update_user_caches($user) { |
|
1185 wp_cache_add($user->ID, $user, 'users'); |
|
1186 wp_cache_add($user->user_login, $user->ID, 'userlogins'); |
|
1187 wp_cache_add($user->user_email, $user->ID, 'useremail'); |
|
1188 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); |
|
1189 } |
|
1190 |
|
1191 /** |
|
1192 * Clean all user caches |
|
1193 * |
|
1194 * @since 3.0.0 |
|
1195 * |
|
1196 * @param WP_User|int $user User object or ID to be cleaned from the cache |
|
1197 */ |
|
1198 function clean_user_cache( $user ) { |
|
1199 if ( is_numeric( $user ) ) |
|
1200 $user = new WP_User( $user ); |
|
1201 |
|
1202 if ( ! $user->exists() ) |
|
1203 return; |
|
1204 |
|
1205 wp_cache_delete( $user->ID, 'users' ); |
|
1206 wp_cache_delete( $user->user_login, 'userlogins' ); |
|
1207 wp_cache_delete( $user->user_email, 'useremail' ); |
|
1208 wp_cache_delete( $user->user_nicename, 'userslugs' ); |
|
1209 } |
|
1210 |
|
1211 /** |
|
1212 * Checks whether the given username exists. |
|
1213 * |
|
1214 * @since 2.0.0 |
|
1215 * |
|
1216 * @param string $username Username. |
|
1217 * @return null|int The user's ID on success, and null on failure. |
|
1218 */ |
|
1219 function username_exists( $username ) { |
|
1220 if ( $user = get_user_by('login', $username ) ) { |
|
1221 return $user->ID; |
|
1222 } else { |
|
1223 return null; |
|
1224 } |
|
1225 } |
|
1226 |
|
1227 /** |
|
1228 * Checks whether the given email exists. |
|
1229 * |
|
1230 * @since 2.1.0 |
|
1231 * @uses $wpdb |
|
1232 * |
|
1233 * @param string $email Email. |
|
1234 * @return bool|int The user's ID on success, and false on failure. |
|
1235 */ |
|
1236 function email_exists( $email ) { |
|
1237 if ( $user = get_user_by('email', $email) ) |
|
1238 return $user->ID; |
|
1239 |
|
1240 return false; |
|
1241 } |
|
1242 |
|
1243 /** |
|
1244 * Checks whether an username is valid. |
|
1245 * |
|
1246 * @since 2.0.1 |
|
1247 * @uses apply_filters() Calls 'validate_username' hook on $valid check and $username as parameters |
|
1248 * |
|
1249 * @param string $username Username. |
|
1250 * @return bool Whether username given is valid |
|
1251 */ |
|
1252 function validate_username( $username ) { |
|
1253 $sanitized = sanitize_user( $username, true ); |
|
1254 $valid = ( $sanitized == $username ); |
|
1255 return apply_filters( 'validate_username', $valid, $username ); |
|
1256 } |
|
1257 |
|
1258 /** |
|
1259 * Insert an user into the database. |
|
1260 * |
|
1261 * Can update a current user or insert a new user based on whether the user's ID |
|
1262 * is present. |
|
1263 * |
|
1264 * Can be used to update the user's info (see below), set the user's role, and |
|
1265 * set the user's preference on whether they want the rich editor on. |
|
1266 * |
|
1267 * Most of the $userdata array fields have filters associated with the values. |
|
1268 * The exceptions are 'rich_editing', 'role', 'jabber', 'aim', 'yim', |
|
1269 * 'user_registered', and 'ID'. The filters have the prefix 'pre_user_' followed |
|
1270 * by the field name. An example using 'description' would have the filter |
|
1271 * called, 'pre_user_description' that can be hooked into. |
|
1272 * |
|
1273 * The $userdata array can contain the following fields: |
|
1274 * 'ID' - An integer that will be used for updating an existing user. |
|
1275 * 'user_pass' - A string that contains the plain text password for the user. |
|
1276 * 'user_login' - A string that contains the user's username for logging in. |
|
1277 * 'user_nicename' - A string that contains a URL-friendly name for the user. |
|
1278 * The default is the user's username. |
|
1279 * 'user_url' - A string containing the user's URL for the user's web site. |
|
1280 * 'user_email' - A string containing the user's email address. |
|
1281 * 'display_name' - A string that will be shown on the site. Defaults to user's |
|
1282 * username. It is likely that you will want to change this, for appearance. |
|
1283 * 'nickname' - The user's nickname, defaults to the user's username. |
|
1284 * 'first_name' - The user's first name. |
|
1285 * 'last_name' - The user's last name. |
|
1286 * 'description' - A string containing content about the user. |
|
1287 * 'rich_editing' - A string for whether to enable the rich editor. False |
|
1288 * if not empty. |
|
1289 * 'user_registered' - The date the user registered. Format is 'Y-m-d H:i:s'. |
|
1290 * 'role' - A string used to set the user's role. |
|
1291 * 'jabber' - User's Jabber account. |
|
1292 * 'aim' - User's AOL IM account. |
|
1293 * 'yim' - User's Yahoo IM account. |
|
1294 * |
|
1295 * @since 2.0.0 |
|
1296 * @uses $wpdb WordPress database layer. |
|
1297 * @uses apply_filters() Calls filters for most of the $userdata fields with the prefix 'pre_user'. See note above. |
|
1298 * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID |
|
1299 * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID |
|
1300 * |
|
1301 * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. |
|
1302 * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created. |
|
1303 */ |
|
1304 function wp_insert_user( $userdata ) { |
|
1305 global $wpdb; |
|
1306 |
|
1307 if ( is_a( $userdata, 'stdClass' ) ) |
|
1308 $userdata = get_object_vars( $userdata ); |
|
1309 elseif ( is_a( $userdata, 'WP_User' ) ) |
|
1310 $userdata = $userdata->to_array(); |
|
1311 |
|
1312 extract( $userdata, EXTR_SKIP ); |
|
1313 |
|
1314 // Are we updating or creating? |
|
1315 if ( !empty($ID) ) { |
|
1316 $ID = (int) $ID; |
|
1317 $update = true; |
|
1318 $old_user_data = WP_User::get_data_by( 'id', $ID ); |
|
1319 } else { |
|
1320 $update = false; |
|
1321 // Hash the password |
|
1322 $user_pass = wp_hash_password($user_pass); |
|
1323 } |
|
1324 |
|
1325 $user_login = sanitize_user($user_login, true); |
|
1326 $user_login = apply_filters('pre_user_login', $user_login); |
|
1327 |
|
1328 //Remove any non-printable chars from the login string to see if we have ended up with an empty username |
|
1329 $user_login = trim($user_login); |
|
1330 |
|
1331 if ( empty($user_login) ) |
|
1332 return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') ); |
|
1333 |
|
1334 if ( !$update && username_exists( $user_login ) ) |
|
1335 return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) ); |
|
1336 |
|
1337 if ( empty($user_nicename) ) |
|
1338 $user_nicename = sanitize_title( $user_login ); |
|
1339 $user_nicename = apply_filters('pre_user_nicename', $user_nicename); |
|
1340 |
|
1341 if ( empty($user_url) ) |
|
1342 $user_url = ''; |
|
1343 $user_url = apply_filters('pre_user_url', $user_url); |
|
1344 |
|
1345 if ( empty($user_email) ) |
|
1346 $user_email = ''; |
|
1347 $user_email = apply_filters('pre_user_email', $user_email); |
|
1348 |
|
1349 if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) ) |
|
1350 return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) ); |
|
1351 |
|
1352 if ( empty($nickname) ) |
|
1353 $nickname = $user_login; |
|
1354 $nickname = apply_filters('pre_user_nickname', $nickname); |
|
1355 |
|
1356 if ( empty($first_name) ) |
|
1357 $first_name = ''; |
|
1358 $first_name = apply_filters('pre_user_first_name', $first_name); |
|
1359 |
|
1360 if ( empty($last_name) ) |
|
1361 $last_name = ''; |
|
1362 $last_name = apply_filters('pre_user_last_name', $last_name); |
|
1363 |
|
1364 if ( empty( $display_name ) ) { |
|
1365 if ( $update ) |
|
1366 $display_name = $user_login; |
|
1367 elseif ( $first_name && $last_name ) |
|
1368 /* translators: 1: first name, 2: last name */ |
|
1369 $display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $first_name, $last_name ); |
|
1370 elseif ( $first_name ) |
|
1371 $display_name = $first_name; |
|
1372 elseif ( $last_name ) |
|
1373 $display_name = $last_name; |
|
1374 else |
|
1375 $display_name = $user_login; |
|
1376 } |
|
1377 $display_name = apply_filters( 'pre_user_display_name', $display_name ); |
|
1378 |
|
1379 if ( empty($description) ) |
|
1380 $description = ''; |
|
1381 $description = apply_filters('pre_user_description', $description); |
|
1382 |
|
1383 if ( empty($rich_editing) ) |
|
1384 $rich_editing = 'true'; |
|
1385 |
|
1386 if ( empty($comment_shortcuts) ) |
|
1387 $comment_shortcuts = 'false'; |
|
1388 |
|
1389 if ( empty($admin_color) ) |
|
1390 $admin_color = 'fresh'; |
|
1391 $admin_color = preg_replace('|[^a-z0-9 _.\-@]|i', '', $admin_color); |
|
1392 |
|
1393 if ( empty($use_ssl) ) |
|
1394 $use_ssl = 0; |
|
1395 |
|
1396 if ( empty($user_registered) ) |
|
1397 $user_registered = gmdate('Y-m-d H:i:s'); |
|
1398 |
|
1399 if ( empty($show_admin_bar_front) ) |
|
1400 $show_admin_bar_front = 'true'; |
|
1401 |
|
1402 $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)); |
|
1403 |
|
1404 if ( $user_nicename_check ) { |
|
1405 $suffix = 2; |
|
1406 while ($user_nicename_check) { |
|
1407 $alt_user_nicename = $user_nicename . "-$suffix"; |
|
1408 $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)); |
|
1409 $suffix++; |
|
1410 } |
|
1411 $user_nicename = $alt_user_nicename; |
|
1412 } |
|
1413 |
|
1414 $data = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' ); |
|
1415 $data = wp_unslash( $data ); |
|
1416 |
|
1417 if ( $update ) { |
|
1418 $wpdb->update( $wpdb->users, $data, compact( 'ID' ) ); |
|
1419 $user_id = (int) $ID; |
|
1420 } else { |
|
1421 $wpdb->insert( $wpdb->users, $data + compact( 'user_login' ) ); |
|
1422 $user_id = (int) $wpdb->insert_id; |
|
1423 } |
|
1424 |
|
1425 $user = new WP_User( $user_id ); |
|
1426 |
|
1427 foreach ( _get_additional_user_keys( $user ) as $key ) { |
|
1428 if ( isset( $$key ) ) |
|
1429 update_user_meta( $user_id, $key, $$key ); |
|
1430 } |
|
1431 |
|
1432 if ( isset($role) ) |
|
1433 $user->set_role($role); |
|
1434 elseif ( !$update ) |
|
1435 $user->set_role(get_option('default_role')); |
|
1436 |
|
1437 wp_cache_delete($user_id, 'users'); |
|
1438 wp_cache_delete($user_login, 'userlogins'); |
|
1439 |
|
1440 if ( $update ) |
|
1441 do_action('profile_update', $user_id, $old_user_data); |
|
1442 else |
|
1443 do_action('user_register', $user_id); |
|
1444 |
|
1445 return $user_id; |
|
1446 } |
|
1447 |
|
1448 /** |
|
1449 * Update an user in the database. |
|
1450 * |
|
1451 * It is possible to update a user's password by specifying the 'user_pass' |
|
1452 * value in the $userdata parameter array. |
|
1453 * |
|
1454 * If current user's password is being updated, then the cookies will be |
|
1455 * cleared. |
|
1456 * |
|
1457 * @since 2.0.0 |
|
1458 * @see wp_insert_user() For what fields can be set in $userdata |
|
1459 * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already |
|
1460 * |
|
1461 * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. |
|
1462 * @return int|WP_Error The updated user's ID or a WP_Error object if the user could not be updated. |
|
1463 */ |
|
1464 function wp_update_user($userdata) { |
|
1465 if ( is_a( $userdata, 'stdClass' ) ) |
|
1466 $userdata = get_object_vars( $userdata ); |
|
1467 elseif ( is_a( $userdata, 'WP_User' ) ) |
|
1468 $userdata = $userdata->to_array(); |
|
1469 |
|
1470 $ID = (int) $userdata['ID']; |
|
1471 |
|
1472 // First, get all of the original fields |
|
1473 $user_obj = get_userdata( $ID ); |
|
1474 if ( ! $user_obj ) |
|
1475 return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) ); |
|
1476 |
|
1477 $user = $user_obj->to_array(); |
|
1478 |
|
1479 // Add additional custom fields |
|
1480 foreach ( _get_additional_user_keys( $user_obj ) as $key ) { |
|
1481 $user[ $key ] = get_user_meta( $ID, $key, true ); |
|
1482 } |
|
1483 |
|
1484 // Escape data pulled from DB. |
|
1485 $user = add_magic_quotes( $user ); |
|
1486 |
|
1487 // If password is changing, hash it now. |
|
1488 if ( ! empty($userdata['user_pass']) ) { |
|
1489 $plaintext_pass = $userdata['user_pass']; |
|
1490 $userdata['user_pass'] = wp_hash_password($userdata['user_pass']); |
|
1491 } |
|
1492 |
|
1493 wp_cache_delete($user[ 'user_email' ], 'useremail'); |
|
1494 |
|
1495 // Merge old and new fields with new fields overwriting old ones. |
|
1496 $userdata = array_merge($user, $userdata); |
|
1497 $user_id = wp_insert_user($userdata); |
|
1498 |
|
1499 // Update the cookies if the password changed. |
|
1500 $current_user = wp_get_current_user(); |
|
1501 if ( $current_user->ID == $ID ) { |
|
1502 if ( isset($plaintext_pass) ) { |
|
1503 wp_clear_auth_cookie(); |
|
1504 wp_set_auth_cookie($ID); |
|
1505 } |
|
1506 } |
|
1507 |
|
1508 return $user_id; |
|
1509 } |
|
1510 |
|
1511 /** |
|
1512 * A simpler way of inserting an user into the database. |
|
1513 * |
|
1514 * Creates a new user with just the username, password, and email. For more |
|
1515 * complex user creation use wp_insert_user() to specify more information. |
|
1516 * |
|
1517 * @since 2.0.0 |
|
1518 * @see wp_insert_user() More complete way to create a new user |
|
1519 * |
|
1520 * @param string $username The user's username. |
|
1521 * @param string $password The user's password. |
|
1522 * @param string $email The user's email (optional). |
|
1523 * @return int The new user's ID. |
|
1524 */ |
|
1525 function wp_create_user($username, $password, $email = '') { |
|
1526 $user_login = wp_slash( $username ); |
|
1527 $user_email = wp_slash( $email ); |
|
1528 $user_pass = $password; |
|
1529 |
|
1530 $userdata = compact('user_login', 'user_email', 'user_pass'); |
|
1531 return wp_insert_user($userdata); |
|
1532 } |
|
1533 |
|
1534 /** |
|
1535 * Return a list of meta keys that wp_insert_user() is supposed to set. |
|
1536 * |
|
1537 * @since 3.3.0 |
|
1538 * @access private |
|
1539 * |
|
1540 * @param object $user WP_User instance. |
|
1541 * @return array |
|
1542 */ |
|
1543 function _get_additional_user_keys( $user ) { |
|
1544 $keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front' ); |
|
1545 return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) ); |
|
1546 } |
|
1547 |
|
1548 /** |
|
1549 * Set up the user contact methods. |
|
1550 * |
|
1551 * Default contact methods were removed in 3.6. A filter dictates contact methods. |
|
1552 * |
|
1553 * @since 3.7.0 |
|
1554 * |
|
1555 * @param WP_User $user Optional. WP_User object. |
|
1556 * @return array Array of contact methods and their labels. |
|
1557 */ |
|
1558 function wp_get_user_contact_methods( $user = null ) { |
|
1559 $methods = array(); |
|
1560 if ( get_site_option( 'initial_db_version' ) < 23588 ) { |
|
1561 $methods = array( |
|
1562 'aim' => __( 'AIM' ), |
|
1563 'yim' => __( 'Yahoo IM' ), |
|
1564 'jabber' => __( 'Jabber / Google Talk' ) |
|
1565 ); |
|
1566 } |
|
1567 |
|
1568 /** |
|
1569 * Filter the user contact methods. |
|
1570 * |
|
1571 * @since 2.9.0 |
|
1572 * |
|
1573 * @param array $methods Array of contact methods and their labels. |
|
1574 * @param WP_User $user Optional. WP_User object. |
|
1575 */ |
|
1576 return apply_filters( 'user_contactmethods', $methods, $user ); |
|
1577 } |
|
1578 |
|
1579 /** |
|
1580 * The old private function for setting up user contact methods. |
|
1581 * |
|
1582 * @since 2.9.0 |
|
1583 * @access private |
|
1584 */ |
|
1585 function _wp_get_user_contactmethods( $user = null ) { |
|
1586 return wp_get_user_contact_methods( $user ); |
|
1587 } |
|
1588 |
|
1589 /** |
|
1590 * Retrieves a user row based on password reset key and login |
|
1591 * |
|
1592 * A key is considered 'expired' if it exactly matches the value of the |
|
1593 * user_activation_key field, rather than being matched after going through the |
|
1594 * hashing process. This field is now hashed; old values are no longer accepted |
|
1595 * but have a different WP_Error code so good user feedback can be provided. |
|
1596 * |
|
1597 * @uses $wpdb WordPress Database object |
|
1598 * |
|
1599 * @param string $key Hash to validate sending user's password. |
|
1600 * @param string $login The user login. |
|
1601 * @return WP_User|WP_Error WP_User object on success, WP_Error object for invalid or expired keys. |
|
1602 */ |
|
1603 function check_password_reset_key($key, $login) { |
|
1604 global $wpdb, $wp_hasher; |
|
1605 |
|
1606 $key = preg_replace('/[^a-z0-9]/i', '', $key); |
|
1607 |
|
1608 if ( empty( $key ) || !is_string( $key ) ) |
|
1609 return new WP_Error('invalid_key', __('Invalid key')); |
|
1610 |
|
1611 if ( empty($login) || !is_string($login) ) |
|
1612 return new WP_Error('invalid_key', __('Invalid key')); |
|
1613 |
|
1614 $row = $wpdb->get_row( $wpdb->prepare( "SELECT ID, user_activation_key FROM $wpdb->users WHERE user_login = %s", $login ) ); |
|
1615 if ( ! $row ) |
|
1616 return new WP_Error('invalid_key', __('Invalid key')); |
|
1617 |
|
1618 if ( empty( $wp_hasher ) ) { |
|
1619 require_once ABSPATH . 'wp-includes/class-phpass.php'; |
|
1620 $wp_hasher = new PasswordHash( 8, true ); |
|
1621 } |
|
1622 |
|
1623 if ( $wp_hasher->CheckPassword( $key, $row->user_activation_key ) ) |
|
1624 return get_userdata( $row->ID ); |
|
1625 |
|
1626 if ( $key === $row->user_activation_key ) { |
|
1627 $return = new WP_Error( 'expired_key', __( 'Invalid key' ) ); |
|
1628 $user_id = $row->ID; |
|
1629 |
|
1630 /** |
|
1631 * Filter the return value of check_password_reset_key() when an |
|
1632 * old-style key is used (plain-text key was stored in the database). |
|
1633 * |
|
1634 * @since 3.7.0 |
|
1635 * |
|
1636 * @param WP_Error $return A WP_Error object denoting an expired key. |
|
1637 * Return a WP_User object to validate the key. |
|
1638 * @param int $user_id The matched user ID. |
|
1639 */ |
|
1640 return apply_filters( 'password_reset_key_expired', $return, $user_id ); |
|
1641 } |
|
1642 |
|
1643 return new WP_Error( 'invalid_key', __( 'Invalid key' ) ); |
|
1644 } |
|
1645 |
|
1646 /** |
|
1647 * Handles resetting the user's password. |
|
1648 * |
|
1649 * @param object $user The user |
|
1650 * @param string $new_pass New password for the user in plaintext |
|
1651 */ |
|
1652 function reset_password( $user, $new_pass ) { |
|
1653 do_action( 'password_reset', $user, $new_pass ); |
|
1654 |
|
1655 wp_set_password( $new_pass, $user->ID ); |
|
1656 update_user_option( $user->ID, 'default_password_nag', false, true ); |
|
1657 |
|
1658 wp_password_change_notification( $user ); |
|
1659 } |
|
1660 |
|
1661 /** |
|
1662 * Handles registering a new user. |
|
1663 * |
|
1664 * @param string $user_login User's username for logging in |
|
1665 * @param string $user_email User's email address to send password and add |
|
1666 * @return int|WP_Error Either user's ID or error on failure. |
|
1667 */ |
|
1668 function register_new_user( $user_login, $user_email ) { |
|
1669 $errors = new WP_Error(); |
|
1670 |
|
1671 $sanitized_user_login = sanitize_user( $user_login ); |
|
1672 $user_email = apply_filters( 'user_registration_email', $user_email ); |
|
1673 |
|
1674 // Check the username |
|
1675 if ( $sanitized_user_login == '' ) { |
|
1676 $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) ); |
|
1677 } elseif ( ! validate_username( $user_login ) ) { |
|
1678 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); |
|
1679 $sanitized_user_login = ''; |
|
1680 } elseif ( username_exists( $sanitized_user_login ) ) { |
|
1681 $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ) ); |
|
1682 } |
|
1683 |
|
1684 // Check the e-mail address |
|
1685 if ( $user_email == '' ) { |
|
1686 $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your e-mail address.' ) ); |
|
1687 } elseif ( ! is_email( $user_email ) ) { |
|
1688 $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn’t correct.' ) ); |
|
1689 $user_email = ''; |
|
1690 } elseif ( email_exists( $user_email ) ) { |
|
1691 $errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) ); |
|
1692 } |
|
1693 |
|
1694 do_action( 'register_post', $sanitized_user_login, $user_email, $errors ); |
|
1695 |
|
1696 $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email ); |
|
1697 |
|
1698 if ( $errors->get_error_code() ) |
|
1699 return $errors; |
|
1700 |
|
1701 $user_pass = wp_generate_password( 12, false ); |
|
1702 $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email ); |
|
1703 if ( ! $user_id || is_wp_error( $user_id ) ) { |
|
1704 $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn’t register you… please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) ); |
|
1705 return $errors; |
|
1706 } |
|
1707 |
|
1708 update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag. |
|
1709 |
|
1710 wp_new_user_notification( $user_id, $user_pass ); |
|
1711 |
|
1712 return $user_id; |
|
1713 } |