Wordpress 2.6.2-scripts
[autoinstalls/wordpress.git] / wp-includes / pluggable.php
1 <?php
2 /**
3  * These functions can be replaced via plugins. If plugins do not redefine these
4  * functions, then these will be used instead.
5  *
6  * @package WordPress
7  */
8
9 if ( !function_exists('set_current_user') ) :
10 /**
11  * Changes the current user by ID or name.
12  *
13  * Set $id to null and specify a name if you do not know a user's ID.
14  *
15  * @since 2.0.1
16  * @see wp_set_current_user() An alias of wp_set_current_user()
17  *
18  * @param int|null $id User ID.
19  * @param string $name Optional. The user's username
20  * @return object returns wp_set_current_user()
21  */
22 function set_current_user($id, $name = '') {
23         return wp_set_current_user($id, $name);
24 }
25 endif;
26
27 if ( !function_exists('wp_set_current_user') ) :
28 /**
29  * Changes the current user by ID or name.
30  *
31  * Set $id to null and specify a name if you do not know a user's ID.
32  *
33  * Some WordPress functionality is based on the current user and not based on
34  * the signed in user. Therefore, it opens the ability to edit and perform
35  * actions on users who aren't signed in.
36  *
37  * @since 2.0.4
38  * @global object $current_user The current user object which holds the user data.
39  * @uses do_action() Calls 'set_current_user' hook after setting the current user.
40  *
41  * @param int $id User ID
42  * @param string $name User's username
43  * @return WP_User Current user User object
44  */
45 function wp_set_current_user($id, $name = '') {
46         global $current_user;
47
48         if ( isset($current_user) && ($id == $current_user->ID) )
49                 return $current_user;
50
51         $current_user = new WP_User($id, $name);
52
53         setup_userdata($current_user->ID);
54
55         do_action('set_current_user');
56
57         return $current_user;
58 }
59 endif;
60
61 if ( !function_exists('wp_get_current_user') ) :
62 /**
63  * Retrieve the current user object.
64  *
65  * @since 2.0.4
66  *
67  * @return WP_User Current user WP_User object
68  */
69 function wp_get_current_user() {
70         global $current_user;
71
72         get_currentuserinfo();
73
74         return $current_user;
75 }
76 endif;
77
78 if ( !function_exists('get_currentuserinfo') ) :
79 /**
80  * Populate global variables with information about the currently logged in user.
81  *
82  * Will set the current user, if the current user is not set. The current user
83  * will be set to the logged in person. If no user is logged in, then it will
84  * set the current user to 0, which is invalid and won't have any permissions.
85  *
86  * @since 0.71
87  * @uses $current_user Checks if the current user is set
88  * @uses wp_validate_auth_cookie() Retrieves current logged in user.
89  *
90  * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set
91  */
92 function get_currentuserinfo() {
93         global $current_user;
94
95         if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST )
96                 return false;
97
98         if ( ! empty($current_user) )
99                 return;
100
101         if ( ! $user = wp_validate_auth_cookie() ) {
102                  if ( empty($_COOKIE[LOGGED_IN_COOKIE]) || !$user = wp_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in') ) {
103                         wp_set_current_user(0);
104                         return false;
105                  }
106         }
107
108         wp_set_current_user($user);
109 }
110 endif;
111
112 if ( !function_exists('get_userdata') ) :
113 /**
114  * Retrieve user info by user ID.
115  *
116  * @since 0.71
117  *
118  * @param int $user_id User ID
119  * @return bool|object False on failure, User DB row object
120  */
121 function get_userdata( $user_id ) {
122         global $wpdb;
123
124         $user_id = absint($user_id);
125         if ( $user_id == 0 )
126                 return false;
127
128         $user = wp_cache_get($user_id, 'users');
129
130         if ( $user )
131                 return $user;
132
133         if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id)) )
134                 return false;
135
136         _fill_user($user);
137
138         return $user;
139 }
140 endif;
141
142 if ( !function_exists('update_user_cache') ) :
143 /**
144  * Updates a users cache when overridden by a plugin.
145  *
146  * Core function does nothing.
147  *
148  * @since 1.5
149  *
150  * @return bool Only returns true
151  */
152 function update_user_cache() {
153         return true;
154 }
155 endif;
156
157 if ( !function_exists('get_userdatabylogin') ) :
158 /**
159  * Retrieve user info by login name.
160  *
161  * @since 0.71
162  *
163  * @param string $user_login User's username
164  * @return bool|object False on failure, User DB row object
165  */
166 function get_userdatabylogin($user_login) {
167         global $wpdb;
168         $user_login = sanitize_user( $user_login );
169
170         if ( empty( $user_login ) )
171                 return false;
172
173         $user_id = wp_cache_get($user_login, 'userlogins');
174
175         $user = false;
176         if ( false !== $user_id )
177                 $user = wp_cache_get($user_id, 'users');
178
179         if ( false !== $user )
180                 return $user;
181
182         if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_login = %s", $user_login)) )
183                 return false;
184
185         _fill_user($user);
186
187         return $user;
188 }
189 endif;
190
191 if ( !function_exists('get_user_by_email') ) :
192 /**
193  * Retrieve user info by email.
194  *
195  * @since 2.5
196  *
197  * @param string $email User's email address
198  * @return bool|object False on failure, User DB row object
199  */
200 function get_user_by_email($email) {
201         global $wpdb;
202
203         $user_id = wp_cache_get($email, 'useremail');
204
205         $user = false;
206         if ( false !== $user_id )
207                 $user = wp_cache_get($user_id, 'users');
208
209         if ( false !== $user )
210                 return $user;
211
212         if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_email = %s", $email)) )
213                 return false;
214
215         _fill_user($user);
216
217         return $user;
218 }
219 endif;
220
221 if ( !function_exists( 'wp_mail' ) ) :
222 /**
223  * Send mail, similar to PHP's mail
224  *
225  * A true return value does not automatically mean that the user received the
226  * email successfully. It just only means that the method used was able to
227  * process the request without any errors.
228  *
229  * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
230  * creating a from address like 'Name <email@address.com>' when both are set. If
231  * just 'wp_mail_from' is set, then just the email address will be used with no
232  * name.
233  *
234  * The default content type is 'text/plain' which does not allow using HTML.
235  * However, you can set the content type of the email by using the
236  * 'wp_mail_content_type' filter.
237  *
238  * The default charset is based on the charset used on the blog. The charset can
239  * be set using the 'wp_mail_charset' filter.
240  *
241  * @since 1.2.1
242  * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
243  * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
244  * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
245  * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
246  * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
247  * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
248  *              phpmailer object.
249  * @uses PHPMailer
250  * @
251  *
252  * @param string $to Email address to send message
253  * @param string $subject Email subject
254  * @param string $message Message contents
255  * @param string|array $headers Optional. Additional headers.
256  * @return bool Whether the email contents were sent successfully.
257  */
258 function wp_mail( $to, $subject, $message, $headers = '' ) {
259         // Compact the input, apply the filters, and extract them back out
260         extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers' ) ) );
261
262         global $phpmailer;
263
264         // (Re)create it, if it's gone missing
265         if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
266                 require_once ABSPATH . WPINC . '/class-phpmailer.php';
267                 require_once ABSPATH . WPINC . '/class-smtp.php';
268                 $phpmailer = new PHPMailer();
269         }
270
271         // Headers
272         if ( empty( $headers ) ) {
273                 $headers = array();
274         } elseif ( !is_array( $headers ) ) {
275                 // Explode the headers out, so this function can take both
276                 // string headers and an array of headers.
277                 $tempheaders = (array) explode( "\n", $headers );
278                 $headers = array();
279
280                 // If it's actually got contents
281                 if ( !empty( $tempheaders ) ) {
282                         // Iterate through the raw headers
283                         foreach ( $tempheaders as $header ) {
284                                 if ( strpos($header, ':') === false )
285                                         continue;
286                                 // Explode them out
287                                 list( $name, $content ) = explode( ':', trim( $header ), 2 );
288
289                                 // Cleanup crew
290                                 $name = trim( $name );
291                                 $content = trim( $content );
292
293                                 // Mainly for legacy -- process a From: header if it's there
294                                 if ( 'from' == strtolower($name) ) {
295                                         if ( strpos($content, '<' ) !== false ) {
296                                                 // So... making my life hard again?
297                                                 $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
298                                                 $from_name = str_replace( '"', '', $from_name );
299                                                 $from_name = trim( $from_name );
300
301                                                 $from_email = substr( $content, strpos( $content, '<' ) + 1 );
302                                                 $from_email = str_replace( '>', '', $from_email );
303                                                 $from_email = trim( $from_email );
304                                         } else {
305                                                 $from_name = trim( $content );
306                                         }
307                                 } elseif ( 'content-type' == strtolower($name) ) {
308                                         if ( strpos( $content,';' ) !== false ) {
309                                                 list( $type, $charset ) = explode( ';', $content );
310                                                 $content_type = trim( $type );
311                                                 $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) );
312                                         } else {
313                                                 $content_type = trim( $content );
314                                         }
315                                 } elseif ( 'cc' == strtolower($name) ) {
316                                         $cc = explode(",", $content);
317                                 } elseif ( 'bcc' == strtolower($name) ) {
318                                         $bcc = explode(",", $content);
319                                 } else {
320                                         // Add it to our grand headers array
321                                         $headers[trim( $name )] = trim( $content );
322                                 }
323                         }
324                 }
325         }
326
327         // Empty out the values that may be set
328         $phpmailer->ClearAddresses();
329         $phpmailer->ClearAllRecipients();
330         $phpmailer->ClearAttachments();
331         $phpmailer->ClearBCCs();
332         $phpmailer->ClearCCs();
333         $phpmailer->ClearCustomHeaders();
334         $phpmailer->ClearReplyTos();
335
336         // From email and name
337         // If we don't have a name from the input headers
338         if ( !isset( $from_name ) ) {
339                 $from_name = 'WordPress';
340         }
341
342         // If we don't have an email from the input headers
343         if ( !isset( $from_email ) ) {
344                 // Get the site domain and get rid of www.
345                 $sitename = strtolower( $_SERVER['SERVER_NAME'] );
346                 if ( substr( $sitename, 0, 4 ) == 'www.' ) {
347                         $sitename = substr( $sitename, 4 );
348                 }
349
350                 $from_email = 'wordpress@' . $sitename;
351         }
352
353         // Set the from name and email
354         $phpmailer->From = apply_filters( 'wp_mail_from', $from_email );
355         $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
356
357         // Set destination address
358         $phpmailer->AddAddress( $to );
359
360         // Set mail's subject and body
361         $phpmailer->Subject = $subject;
362         $phpmailer->Body = $message;
363
364         // Add any CC and BCC recipients
365         if ( !empty($cc) ) {
366                 foreach ($cc as $recipient) {
367                         $phpmailer->AddCc( trim($recipient) );
368                 }
369         }
370         if ( !empty($bcc) ) {
371                 foreach ($bcc as $recipient) {
372                         $phpmailer->AddBcc( trim($recipient) );
373                 }
374         }
375
376         // Set to use PHP's mail()
377         $phpmailer->IsMail();
378
379         // Set Content-Type and charset
380         // If we don't have a content-type from the input headers
381         if ( !isset( $content_type ) ) {
382                 $content_type = 'text/plain';
383         }
384
385         $content_type = apply_filters( 'wp_mail_content_type', $content_type );
386
387         // Set whether it's plaintext or not, depending on $content_type
388         if ( $content_type == 'text/html' ) {
389                 $phpmailer->IsHTML( true );
390         } else {
391                 $phpmailer->IsHTML( false );
392         }
393
394         // If we don't have a charset from the input headers
395         if ( !isset( $charset ) ) {
396                 $charset = get_bloginfo( 'charset' );
397         }
398
399         // Set the content-type and charset
400         $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
401
402         // Set custom headers
403         if ( !empty( $headers ) ) {
404                 foreach ( $headers as $name => $content ) {
405                         $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
406                 }
407         }
408
409         do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
410
411         // Send!
412         $result = @$phpmailer->Send();
413
414         return $result;
415 }
416 endif;
417
418 /**
419  * Checks a user's login information and logs them in if it checks out.
420  *
421  * @since 2.5
422  *
423  * @param string $username User's username
424  * @param string $password User's password
425  * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object.
426  */
427 if ( !function_exists('wp_authenticate') ) :
428 function wp_authenticate($username, $password) {
429         $username = sanitize_user($username);
430
431         if ( '' == $username )
432                 return new WP_Error('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));
433
434         if ( '' == $password )
435                 return new WP_Error('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
436
437         $user = get_userdatabylogin($username);
438
439         if ( !$user || ($user->user_login != $username) ) {
440                 do_action( 'wp_login_failed', $username );
441                 return new WP_Error('invalid_username', __('<strong>ERROR</strong>: Invalid username.'));
442         }
443
444         $user = apply_filters('wp_authenticate_user', $user, $password);
445         if ( is_wp_error($user) ) {
446                 do_action( 'wp_login_failed', $username );
447                 return $user;
448         }
449
450         if ( !wp_check_password($password, $user->user_pass, $user->ID) ) {
451                 do_action( 'wp_login_failed', $username );
452                 return new WP_Error('incorrect_password', __('<strong>ERROR</strong>: Incorrect password.'));
453         }
454
455         return new WP_User($user->ID);
456 }
457 endif;
458
459 /**
460  * Log the current user out.
461  *
462  * @since 2.5
463  */
464 if ( !function_exists('wp_logout') ) :
465 function wp_logout() {
466         wp_clear_auth_cookie();
467         do_action('wp_logout');
468 }
469 endif;
470
471 if ( !function_exists('wp_validate_auth_cookie') ) :
472 /**
473  * Validates authentication cookie.
474  *
475  * The checks include making sure that the authentication cookie is set and
476  * pulling in the contents (if $cookie is not used).
477  *
478  * Makes sure the cookie is not expired. Verifies the hash in cookie is what is
479  * should be and compares the two.
480  *
481  * @since 2.5
482  *
483  * @param string $cookie Optional. If used, will validate contents instead of cookie's
484  * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
485  * @return bool|int False if invalid cookie, User ID if valid.
486  */
487 function wp_validate_auth_cookie($cookie = '', $scheme = 'auth') {
488         if ( empty($cookie) ) {
489                 if ( is_ssl() ) {
490                         $cookie_name = SECURE_AUTH_COOKIE;
491                         $scheme = 'secure_auth';
492                 } else {
493                         $cookie_name = AUTH_COOKIE;
494                         $scheme = 'auth';
495                 }
496
497                 if ( empty($_COOKIE[$cookie_name]) )
498                         return false;
499                 $cookie = $_COOKIE[$cookie_name];
500         }
501
502         $cookie_elements = explode('|', $cookie);
503         if ( count($cookie_elements) != 3 )
504                 return false;
505
506         list($username, $expiration, $hmac) = $cookie_elements;
507
508         $expired = $expiration;
509
510         // Allow a grace period for POST and AJAX requests
511         if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] )
512                 $expired += 3600;
513
514         // Quick check to see if an honest cookie has expired
515         if ( $expired < time() )
516                 return false;
517
518         $key = wp_hash($username . '|' . $expiration, $scheme);
519         $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
520
521         if ( $hmac != $hash )
522                 return false;
523
524         $user = get_userdatabylogin($username);
525         if ( ! $user )
526                 return false;
527
528         return $user->ID;
529 }
530 endif;
531
532 if ( !function_exists('wp_generate_auth_cookie') ) :
533 /**
534  * Generate authentication cookie contents.
535  *
536  * @since 2.5
537  * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID
538  *              and expiration of cookie.
539  *
540  * @param int $user_id User ID
541  * @param int $expiration Cookie expiration in seconds
542  * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
543  * @return string Authentication cookie contents
544  */
545 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') {
546         $user = get_userdata($user_id);
547
548         $key = wp_hash($user->user_login . '|' . $expiration, $scheme);
549         $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);
550
551         $cookie = $user->user_login . '|' . $expiration . '|' . $hash;
552
553         return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
554 }
555 endif;
556
557 if ( !function_exists('wp_set_auth_cookie') ) :
558 /**
559  * Sets the authentication cookies based User ID.
560  *
561  * The $remember parameter increases the time that the cookie will be kept. The
562  * default the cookie is kept without remembering is two days. When $remember is
563  * set, the cookies will be kept for 14 days or two weeks.
564  *
565  * @since 2.5
566  *
567  * @param int $user_id User ID
568  * @param bool $remember Whether to remember the user or not
569  */
570 function wp_set_auth_cookie($user_id, $remember = false, $secure = '') {
571         if ( $remember ) {
572                 $expiration = $expire = time() + 1209600;
573         } else {
574                 $expiration = time() + 172800;
575                 $expire = 0;
576         }
577
578         if ( '' === $secure )
579                 $secure = is_ssl() ? true : false;
580
581         if ( $secure ) {
582                 $auth_cookie_name = SECURE_AUTH_COOKIE;
583                 $scheme = 'secure_auth';
584         } else {
585                 $auth_cookie_name = AUTH_COOKIE;
586                 $scheme = 'auth';
587         }
588
589         $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme);
590         $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in');
591
592         do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme);
593         do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in');
594
595         setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure);
596         setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure);
597         setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN);
598         if ( COOKIEPATH != SITECOOKIEPATH )
599                 setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN);
600 }
601 endif;
602
603 if ( !function_exists('wp_clear_auth_cookie') ) :
604 /**
605  * Removes all of the cookies associated with authentication.
606  *
607  * @since 2.5
608  */
609 function wp_clear_auth_cookie() {
610         setcookie(AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
611         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
612         setcookie(AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
613         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
614         setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
615         setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
616
617         // Old cookies
618         setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
619         setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
620         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
621         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
622
623         // Even older cookies
624         setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
625         setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
626         setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
627         setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
628 }
629 endif;
630
631 if ( !function_exists('is_user_logged_in') ) :
632 /**
633  * Checks if the current visitor is a logged in user.
634  *
635  * @since 2.0.0
636  *
637  * @return bool True if user is logged in, false if not logged in.
638  */
639 function is_user_logged_in() {
640         $user = wp_get_current_user();
641
642         if ( $user->id == 0 )
643                 return false;
644
645         return true;
646 }
647 endif;
648
649 if ( !function_exists('auth_redirect') ) :
650 /**
651  * Checks if a user is logged in, if not it redirects them to the login page.
652  *
653  * @since 1.5
654  */
655 function auth_redirect() {
656         // Checks if a user is logged in, if not redirects them to the login page
657
658         if ( is_ssl() || force_ssl_admin() )
659                 $secure = true;
660         else
661                 $secure = false;
662
663         // If https is required and request is http, redirect
664         if ( $secure && !is_ssl() ) {
665                 if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
666                         wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
667                         exit();
668                 } else {
669                         wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
670                         exit();                 
671                 }
672         }
673
674         if ( wp_validate_auth_cookie() )
675                 return;  // The cookie is good so we're done
676
677         // The cookie is no good so force login
678         nocache_headers();
679
680         if ( is_ssl() )
681                 $proto = 'https://';
682         else
683                 $proto = 'http://';
684
685         $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode($proto . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']), 'login' );
686
687         wp_redirect($login_url);
688         exit();
689 }
690 endif;
691
692 if ( !function_exists('check_admin_referer') ) :
693 /**
694  * Makes sure that a user was referred from another admin page.
695  *
696  * To avoid security exploits.
697  *
698  * @since 1.2.0
699  * @uses do_action() Calls 'check_admin_referer' on $action.
700  *
701  * @param string $action Action nonce
702  * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
703  */
704 function check_admin_referer($action = -1, $query_arg = '_wpnonce') {
705         $adminurl = strtolower(admin_url());
706         $referer = strtolower(wp_get_referer());
707         $result = wp_verify_nonce($_REQUEST[$query_arg], $action);
708         if ( !$result && !(-1 == $action && strpos($referer, $adminurl) !== false) ) {
709                 wp_nonce_ays($action);
710                 die();
711         }
712         do_action('check_admin_referer', $action, $result);
713         return $result;
714 }endif;
715
716 if ( !function_exists('check_ajax_referer') ) :
717 /**
718  * Verifies the AJAX request to prevent processing requests external of the blog.
719  *
720  * @since 2.0.4
721  *
722  * @param string $action Action nonce
723  * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
724  */
725 function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) {
726         if ( $query_arg )
727                 $nonce = $_REQUEST[$query_arg];
728         else
729                 $nonce = $_REQUEST['_ajax_nonce'] ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce'];
730
731         $result = wp_verify_nonce( $nonce, $action );
732
733         if ( $die && false == $result )
734                 die('-1');
735
736         do_action('check_ajax_referer', $action, $result);
737
738         return $result;
739 }
740 endif;
741
742 if ( !function_exists('wp_redirect') ) :
743 /**
744  * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
745  *
746  * @link http://support.microsoft.com/kb/q176113/
747  * @since 1.5.1
748  * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
749  *
750  * @param string $location The path to redirect to
751  * @param int $status Status code to use
752  * @return bool False if $location is not set
753  */
754 function wp_redirect($location, $status = 302) {
755         global $is_IIS;
756
757         $location = apply_filters('wp_redirect', $location, $status);
758         $status = apply_filters('wp_redirect_status', $status, $location);
759         
760         if ( !$location ) // allows the wp_redirect filter to cancel a redirect
761                 return false;
762
763         $location = wp_sanitize_redirect($location);
764
765         if ( $is_IIS ) {
766                 header("Refresh: 0;url=$location");
767         } else {
768                 if ( php_sapi_name() != 'cgi-fcgi' )
769                         status_header($status); // This causes problems on IIS and some FastCGI setups
770                 header("Location: $location");
771         }
772 }
773 endif;
774
775 if ( !function_exists('wp_sanitize_redirect') ) :
776 /**
777  * Sanitizes a URL for use in a redirect.
778  *
779  * @since 2.3
780  *
781  * @return string redirect-sanitized URL
782  **/
783 function wp_sanitize_redirect($location) {
784         $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%]|i', '', $location);
785         $location = wp_kses_no_null($location);
786
787         // remove %0d and %0a from location
788         $strip = array('%0d', '%0a');
789         $found = true;
790         while($found) {
791                 $found = false;
792                 foreach($strip as $val) {
793                         while(strpos($location, $val) !== false) {
794                                 $found = true;
795                                 $location = str_replace($val, '', $location);
796                         }
797                 }
798         }
799         return $location;
800 }
801 endif;
802
803 if ( !function_exists('wp_safe_redirect') ) :
804 /**
805  * Performs a safe (local) redirect, using wp_redirect().
806  *
807  * Checks whether the $location is using an allowed host, if it has an absolute
808  * path. A plugin can therefore set or remove allowed host(s) to or from the
809  * list.
810  *
811  * If the host is not allowed, then the redirect is to wp-admin on the siteurl
812  * instead. This prevents malicious redirects which redirect to another host,
813  * but only used in a few places.
814  *
815  * @since 2.3
816  * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing
817  *              WordPress host string and $location host string.
818  *
819  * @return void Does not return anything
820  **/
821 function wp_safe_redirect($location, $status = 302) {
822
823         // Need to look at the URL the way it will end up in wp_redirect()
824         $location = wp_sanitize_redirect($location);
825
826         // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
827         if ( substr($location, 0, 2) == '//' )
828                 $location = 'http:' . $location;
829
830         // In php 5 parse_url may fail if the URL query part contains http://, bug #38143
831         $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location;
832         
833         $lp  = parse_url($test);
834         $wpp = parse_url(get_option('home'));
835
836         $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : '');
837
838         if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) )
839                 $location = admin_url();
840
841         wp_redirect($location, $status);
842 }
843 endif;
844
845 if ( ! function_exists('wp_notify_postauthor') ) :
846 /**
847  * Notify an author of a comment/trackback/pingback to one of their posts.
848  *
849  * @since 1.0.0
850  *
851  * @param int $comment_id Comment ID
852  * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback'
853  * @return bool False if user email does not exist. True on completion.
854  */
855 function wp_notify_postauthor($comment_id, $comment_type='') {
856         $comment = get_comment($comment_id);
857         $post    = get_post($comment->comment_post_ID);
858         $user    = get_userdata( $post->post_author );
859
860         if ('' == $user->user_email) return false; // If there's no email to send the comment to
861
862         $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
863
864         $blogname = get_option('blogname');
865
866         if ( empty( $comment_type ) ) $comment_type = 'comment';
867
868         if ('comment' == $comment_type) {
869                 $notify_message  = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
870                 $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
871                 $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
872                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
873                 $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
874                 $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
875                 $notify_message .= __('You can see all comments on this post here: ') . "\r\n";
876                 $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title );
877         } elseif ('trackback' == $comment_type) {
878                 $notify_message  = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
879                 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
880                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
881                 $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
882                 $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n";
883                 $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title );
884         } elseif ('pingback' == $comment_type) {
885                 $notify_message  = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
886                 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
887                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
888                 $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n";
889                 $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n";
890                 $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title );
891         }
892         $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n";
893         $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
894         $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
895
896         $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
897
898         if ( '' == $comment->comment_author ) {
899                 $from = "From: \"$blogname\" <$wp_email>";
900                 if ( '' != $comment->comment_author_email )
901                         $reply_to = "Reply-To: $comment->comment_author_email";
902         } else {
903                 $from = "From: \"$comment->comment_author\" <$wp_email>";
904                 if ( '' != $comment->comment_author_email )
905                         $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>";
906         }
907
908         $message_headers = "$from\n"
909                 . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
910
911         if ( isset($reply_to) )
912                 $message_headers .= $reply_to . "\n";
913
914         $notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id);
915         $subject = apply_filters('comment_notification_subject', $subject, $comment_id);
916         $message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id);
917
918         @wp_mail($user->user_email, $subject, $notify_message, $message_headers);
919
920         return true;
921 }
922 endif;
923
924 if ( !function_exists('wp_notify_moderator') ) :
925 /**
926  * Notifies the moderator of the blog about a new comment that is awaiting approval.
927  *
928  * @since 1.0
929  * @uses $wpdb
930  *
931  * @param int $comment_id Comment ID
932  * @return bool Always returns true
933  */
934 function wp_notify_moderator($comment_id) {
935         global $wpdb;
936
937         if( get_option( "moderation_notify" ) == 0 )
938                 return true;
939
940         $comment = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_ID=%d LIMIT 1", $comment_id));
941         $post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID=%d LIMIT 1", $comment->comment_post_ID));
942
943         $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
944         $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'");
945
946         switch ($comment->comment_type)
947         {
948                 case 'trackback':
949                         $notify_message  = sprintf( __('A new trackback on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n";
950                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
951                         $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
952                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
953                         $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
954                         break;
955                 case 'pingback':
956                         $notify_message  = sprintf( __('A new pingback on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n";
957                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
958                         $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
959                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
960                         $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
961                         break;
962                 default: //Comments
963                         $notify_message  = sprintf( __('A new comment on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n";
964                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
965                         $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
966                         $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
967                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
968                         $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
969                         $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
970                         break;
971         }
972
973         $notify_message .= sprintf( __('Approve it: %s'),  admin_url("comment.php?action=mac&c=$comment_id") ) . "\r\n";
974         $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
975         $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
976
977         $notify_message .= sprintf( __ngettext('Currently %s comment is waiting for approval. Please visit the moderation panel:', 
978                 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n";
979         $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n";
980
981         $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_option('blogname'), $post->post_title );
982         $admin_email = get_option('admin_email');
983
984         $notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id);
985         $subject = apply_filters('comment_moderation_subject', $subject, $comment_id);
986
987         @wp_mail($admin_email, $subject, $notify_message);
988
989         return true;
990 }
991 endif;
992
993 if ( !function_exists('wp_new_user_notification') ) :
994 /**
995  * Notify the blog admin of a new user, normally via email.
996  *
997  * @since 2.0
998  *
999  * @param int $user_id User ID
1000  * @param string $plaintext_pass Optional. The user's plaintext password
1001  */
1002 function wp_new_user_notification($user_id, $plaintext_pass = '') {
1003         $user = new WP_User($user_id);
1004
1005         $user_login = stripslashes($user->user_login);
1006         $user_email = stripslashes($user->user_email);
1007
1008         $message  = sprintf(__('New user registration on your blog %s:'), get_option('blogname')) . "\r\n\r\n";
1009         $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
1010         $message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
1011
1012         @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), get_option('blogname')), $message);
1013
1014         if ( empty($plaintext_pass) )
1015                 return;
1016
1017         $message  = sprintf(__('Username: %s'), $user_login) . "\r\n";
1018         $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n";
1019         $message .= site_url("wp-login.php", 'login') . "\r\n";
1020
1021         wp_mail($user_email, sprintf(__('[%s] Your username and password'), get_option('blogname')), $message);
1022
1023 }
1024 endif;
1025
1026 if ( !function_exists('wp_nonce_tick') ) :
1027 /**
1028  * Get the time-dependent variable for nonce creation.
1029  *
1030  * A nonce has a lifespan of two ticks. Nonces in their second tick may be
1031  * updated, e.g. by autosave.
1032  *
1033  * @since 2.5
1034  *
1035  * @return int
1036  */
1037 function wp_nonce_tick() {
1038         $nonce_life = apply_filters('nonce_life', 86400);
1039
1040         return ceil(time() / ( $nonce_life / 2 ));
1041 }
1042 endif;
1043
1044 if ( !function_exists('wp_verify_nonce') ) :
1045 /**
1046  * Verify that correct nonce was used with time limit.
1047  *
1048  * The user is given an amount of time to use the token, so therefore, since the
1049  * UID and $action remain the same, the independent variable is the time.
1050  *
1051  * @since 2.0.4
1052  *
1053  * @param string $nonce Nonce that was used in the form to verify
1054  * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
1055  * @return bool Whether the nonce check passed or failed.
1056  */
1057 function wp_verify_nonce($nonce, $action = -1) {
1058         $user = wp_get_current_user();
1059         $uid = (int) $user->id;
1060
1061         $i = wp_nonce_tick();
1062
1063         // Nonce generated 0-12 hours ago
1064         if ( substr(wp_hash($i . $action . $uid), -12, 10) == $nonce )
1065                 return 1;
1066         // Nonce generated 12-24 hours ago
1067         if ( substr(wp_hash(($i - 1) . $action . $uid), -12, 10) == $nonce )
1068                 return 2;
1069         // Invalid nonce
1070         return false;
1071 }
1072 endif;
1073
1074 if ( !function_exists('wp_create_nonce') ) :
1075 /**
1076  * Creates a random, one time use token.
1077  *
1078  * @since 2.0.4
1079  *
1080  * @param string|int $action Scalar value to add context to the nonce.
1081  * @return string The one use form token
1082  */
1083 function wp_create_nonce($action = -1) {
1084         $user = wp_get_current_user();
1085         $uid = (int) $user->id;
1086
1087         $i = wp_nonce_tick();
1088
1089         return substr(wp_hash($i . $action . $uid), -12, 10);
1090 }
1091 endif;
1092
1093 if ( !function_exists('wp_salt') ) :
1094 /**
1095  * Get salt to add to hashes to help prevent attacks.
1096  *
1097  * The secret key is located in two places: the database in case the secret key
1098  * isn't defined in the second place, which is in the wp-config.php file. If you
1099  * are going to set the secret key, then you must do so in the wp-config.php
1100  * file.
1101  *
1102  * The secret key in the database is randomly generated and will be appended to
1103  * the secret key that is in wp-config.php file in some instances. It is
1104  * important to have the secret key defined or changed in wp-config.php.
1105  *
1106  * If you have installed WordPress 2.5 or later, then you will have the
1107  * SECRET_KEY defined in the wp-config.php already. You will want to change the
1108  * value in it because hackers will know what it is. If you have upgraded to
1109  * WordPress 2.5 or later version from a version before WordPress 2.5, then you
1110  * should add the constant to your wp-config.php file.
1111  *
1112  * Below is an example of how the SECRET_KEY constant is defined with a value.
1113  * You must not copy the below example and paste into your wp-config.php. If you
1114  * need an example, then you can have a
1115  * {@link http://api.wordpress.org/secret-key/1.0/ secret key created} for you.
1116  *
1117  * <code>
1118  * define('SECRET_KEY', 'mAry1HadA15|\/|b17w55w1t3asSn09w');
1119  * </code>
1120  *
1121  * Salting passwords helps against tools which has stored hashed values of
1122  * common dictionary strings. The added values makes it harder to crack if given
1123  * salt string is not weak.
1124  *
1125  * @since 2.5
1126  * @link http://api.wordpress.org/secret-key/1.0/ Create a Secret Key for wp-config.php
1127  *
1128  * @return string Salt value from either 'SECRET_KEY' or 'secret' option
1129  */
1130 function wp_salt($scheme = 'auth') {
1131         global $wp_default_secret_key;
1132         $secret_key = '';
1133         if ( defined('SECRET_KEY') && ('' != SECRET_KEY) && ( $wp_default_secret_key != SECRET_KEY) )
1134                 $secret_key = SECRET_KEY;
1135
1136         if ( 'auth' == $scheme ) {
1137                 if ( defined('AUTH_KEY') && ('' != AUTH_KEY) && ( $wp_default_secret_key != AUTH_KEY) )
1138                         $secret_key = AUTH_KEY;
1139
1140                 if ( defined('AUTH_SALT') ) {
1141                         $salt = AUTH_SALT;
1142                 } elseif ( defined('SECRET_SALT') ) {
1143                         $salt = SECRET_SALT;
1144                 } else {
1145                         $salt = get_option('auth_salt');
1146                         if ( empty($salt) ) {
1147                                 $salt = wp_generate_password();
1148                                 update_option('auth_salt', $salt);
1149                         }
1150                 }
1151         } elseif ( 'secure_auth' == $scheme ) {
1152                 if ( defined('SECURE_AUTH_KEY') && ('' != SECURE_AUTH_KEY) && ( $wp_default_secret_key != SECURE_AUTH_KEY) )
1153                         $secret_key = SECURE_AUTH_KEY;
1154
1155                 if ( defined('SECURE_AUTH_SALT') ) {
1156                         $salt = SECRET_AUTH_SALT;
1157                 } else {
1158                         $salt = get_option('secure_auth_salt');
1159                         if ( empty($salt) ) {
1160                                 $salt = wp_generate_password();
1161                                 update_option('secure_auth_salt', $salt);
1162                         }
1163                 }
1164         } elseif ( 'logged_in' == $scheme ) {
1165                 if ( defined('LOGGED_IN_KEY') && ('' != LOGGED_IN_KEY) && ( $wp_default_secret_key != LOGGED_IN_KEY) )
1166                         $secret_key = LOGGED_IN_KEY;
1167
1168                 if ( defined('LOGGED_IN_SALT') ) {
1169                         $salt = LOGGED_IN_SALT;
1170                 } else {
1171                         $salt = get_option('logged_in_salt');
1172                         if ( empty($salt) ) {
1173                                 $salt = wp_generate_password();
1174                                 update_option('logged_in_salt', $salt);
1175                         }
1176                 }
1177         }
1178
1179         return apply_filters('salt', $secret_key . $salt, $scheme);
1180 }
1181 endif;
1182
1183 if ( !function_exists('wp_hash') ) :
1184 /**
1185  * Get hash of given string.
1186  *
1187  * @since 2.0.4
1188  * @uses wp_salt() Get WordPress salt
1189  *
1190  * @param string $data Plain text to hash
1191  * @return string Hash of $data
1192  */
1193 function wp_hash($data, $scheme = 'auth') {
1194         $salt = wp_salt($scheme);
1195
1196         return hash_hmac('md5', $data, $salt);
1197 }
1198 endif;
1199
1200 if ( !function_exists('wp_hash_password') ) :
1201 /**
1202  * Create a hash (encrypt) of a plain text password.
1203  *
1204  * For integration with other applications, this function can be overwritten to
1205  * instead use the other package password checking algorithm.
1206  *
1207  * @since 2.5
1208  * @global object $wp_hasher PHPass object
1209  * @uses PasswordHash::HashPassword
1210  *
1211  * @param string $password Plain text user password to hash
1212  * @return string The hash string of the password
1213  */
1214 function wp_hash_password($password) {
1215         global $wp_hasher;
1216
1217         if ( empty($wp_hasher) ) {
1218                 require_once( ABSPATH . 'wp-includes/class-phpass.php');
1219                 // By default, use the portable hash from phpass
1220                 $wp_hasher = new PasswordHash(8, TRUE);
1221         }
1222
1223         return $wp_hasher->HashPassword($password);
1224 }
1225 endif;
1226
1227 if ( !function_exists('wp_check_password') ) :
1228 /**
1229  * Checks the plaintext password against the encrypted Password.
1230  *
1231  * Maintains compatibility between old version and the new cookie authentication
1232  * protocol using PHPass library. The $hash parameter is the encrypted password
1233  * and the function compares the plain text password when encypted similarly
1234  * against the already encrypted password to see if they match.
1235  *
1236  * For integration with other applications, this function can be overwritten to
1237  * instead use the other package password checking algorithm.
1238  *
1239  * @since 2.5
1240  * @global object $wp_hasher PHPass object used for checking the password
1241  *      against the $hash + $password
1242  * @uses PasswordHash::CheckPassword
1243  *
1244  * @param string $password Plaintext user's password
1245  * @param string $hash Hash of the user's password to check against.
1246  * @return bool False, if the $password does not match the hashed password
1247  */
1248 function wp_check_password($password, $hash, $user_id = '') {
1249         global $wp_hasher;
1250
1251         // If the hash is still md5...
1252         if ( strlen($hash) <= 32 ) {
1253                 $check = ( $hash == md5($password) );
1254                 if ( $check && $user_id ) {
1255                         // Rehash using new hash.
1256                         wp_set_password($password, $user_id);
1257                         $hash = wp_hash_password($password);
1258                 }
1259
1260                 return apply_filters('check_password', $check, $password, $hash, $user_id);
1261         }
1262
1263         // If the stored hash is longer than an MD5, presume the
1264         // new style phpass portable hash.
1265         if ( empty($wp_hasher) ) {
1266                 require_once( ABSPATH . 'wp-includes/class-phpass.php');
1267                 // By default, use the portable hash from phpass
1268                 $wp_hasher = new PasswordHash(8, TRUE);
1269         }
1270
1271         $check = $wp_hasher->CheckPassword($password, $hash);
1272
1273         return apply_filters('check_password', $check, $password, $hash, $user_id);
1274 }
1275 endif;
1276
1277 if ( !function_exists('wp_generate_password') ) :
1278 /**
1279  * Generates a random password drawn from the defined set of characters.
1280  *
1281  * @since 2.5
1282  *
1283  * @return string The random password
1284  **/
1285 function wp_generate_password($length = 12, $special_chars = true) {
1286         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1287         if ( $special_chars )
1288                 $chars .= '!@#$%^&*()';
1289
1290         $password = '';
1291         for ( $i = 0; $i < $length; $i++ )
1292                 $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1);
1293         return $password;
1294 }
1295 endif;
1296
1297 if ( !function_exists('wp_rand') ) :
1298  /**
1299  * Generates a random number
1300  *
1301  * @since 2.6.2
1302  *
1303  * @param int $min Lower limit for the generated number (optional, default is 0)
1304  * @param int $max Upper limit for the generated number (optional, default is 4294967295)
1305  * @return int A random number between min and max
1306  */
1307 function wp_rand( $min = 0, $max = 0 ) {
1308         global $rnd_value;
1309
1310         $seed = get_option('random_seed');
1311
1312         // Reset $rnd_value after 14 uses
1313         // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
1314         if ( strlen($rnd_value) < 8 ) {
1315                 $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
1316                 $rnd_value .= sha1($rnd_value);
1317                 $rnd_value .= sha1($rnd_value . $seed);
1318                 $seed = md5($seed . $rnd_value);
1319                 update_option('random_seed', $seed);
1320         }
1321
1322         // Take the first 8 digits for our value
1323         $value = substr($rnd_value, 0, 8);
1324
1325         // Strip the first eight, leaving the remainder for the next call to wp_rand().
1326         $rnd_value = substr($rnd_value, 8);
1327
1328         $value = abs(hexdec($value));
1329
1330         // Reduce the value to be within the min - max range
1331         // 4294967295 = 0xffffffff = max random number
1332         if ( $max != 0 )
1333                 $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1)));
1334
1335         return abs(intval($value)); 
1336 }
1337 endif;
1338
1339 if ( !function_exists('wp_set_password') ) :
1340 /**
1341  * Updates the user's password with a new encrypted one.
1342  *
1343  * For integration with other applications, this function can be overwritten to
1344  * instead use the other package password checking algorithm.
1345  *
1346  * @since 2.5
1347  * @uses $wpdb WordPress database object for queries
1348  * @uses wp_hash_password() Used to encrypt the user's password before passing to the database
1349  *
1350  * @param string $password The plaintext new user password
1351  * @param int $user_id User ID
1352  */
1353 function wp_set_password( $password, $user_id ) {
1354         global $wpdb;
1355
1356         $hash = wp_hash_password($password);
1357         $query = $wpdb->prepare("UPDATE $wpdb->users SET user_pass = %s, user_activation_key = '' WHERE ID = %d", $hash, $user_id);
1358         $wpdb->query($query);
1359         wp_cache_delete($user_id, 'users');
1360 }
1361 endif;
1362
1363 if ( !function_exists( 'get_avatar' ) ) :
1364 /**
1365  * Retrieve the avatar for a user who provided a user ID or email address.
1366  *
1367  * @since 2.5
1368  * @param int|string|object $id_or_email A user ID,  email address, or comment object
1369  * @param int $size Size of the avatar image
1370  * @param string $default URL to a default image to use if no avatar is available
1371  * @return string <img> tag for the user's avatar
1372 */
1373 function get_avatar( $id_or_email, $size = '96', $default = '' ) {
1374         if ( ! get_option('show_avatars') )
1375                 return false;
1376
1377         if ( !is_numeric($size) )
1378                 $size = '96';
1379
1380         $email = '';
1381         if ( is_numeric($id_or_email) ) {
1382                 $id = (int) $id_or_email;
1383                 $user = get_userdata($id);
1384                 if ( $user )
1385                         $email = $user->user_email;
1386         } elseif ( is_object($id_or_email) ) {
1387                 if ( !empty($id_or_email->user_id) ) {
1388                         $id = (int) $id_or_email->user_id;
1389                         $user = get_userdata($id);
1390                         if ( $user)
1391                                 $email = $user->user_email;
1392                 } elseif ( !empty($id_or_email->comment_author_email) ) {
1393                         $email = $id_or_email->comment_author_email;
1394                 }
1395         } else {
1396                 $email = $id_or_email;
1397         }
1398
1399         if ( empty($default) ) {
1400                 $avatar_default = get_option('avatar_default');
1401                 if ( empty($avatar_default) )
1402                         $default = 'mystery';
1403                 else
1404                         $default = $avatar_default;
1405         }
1406
1407         if ( 'custom' == $default )
1408                 $default = add_query_arg( 's', $size, $defaults[$avatar_default][1] );
1409         elseif ( 'mystery' == $default )
1410                 $default = "http://www.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
1411         elseif ( 'blank' == $default )
1412                 $default = includes_url('images/blank.gif');
1413         elseif ( !empty($email) && 'gravatar_default' == $default )
1414                 $default = '';
1415         elseif ( 'gravatar_default' == $default )
1416                 $default = "http://www.gravatar.com/avatar/s={$size}";
1417         elseif ( empty($email) )
1418                 $default = "http://www.gravatar.com/avatar/?d=$default&amp;s={$size}";
1419
1420         if ( !empty($email) ) {
1421                 $out = 'http://www.gravatar.com/avatar/';
1422                 $out .= md5( strtolower( $email ) );
1423                 $out .= '?s='.$size;
1424                 $out .= '&amp;d=' . urlencode( $default );
1425
1426                 $rating = get_option('avatar_rating');
1427                 if ( !empty( $rating ) )
1428                         $out .= "&amp;r={$rating}";
1429
1430                 $avatar = "<img alt='' src='{$out}' class='avatar avatar-{$size}' height='{$size}' width='{$size}' />";
1431         } else {
1432                 $avatar = "<img alt='' src='{$default}' class='avatar avatar-{$size} avatar-default' height='{$size}' width='{$size}' />";
1433         }
1434
1435         return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default);
1436 }
1437 endif;
1438
1439 if ( !function_exists('wp_setcookie') ) :
1440 /**
1441  * Sets a cookie for a user who just logged in.
1442  *
1443  * @since 1.5
1444  * @deprecated Use wp_set_auth_cookie()
1445  * @see wp_set_auth_cookie()
1446  *
1447  * @param string  $username The user's username
1448  * @param string  $password Optional. The user's password
1449  * @param bool $already_md5 Optional. Whether the password has already been through MD5
1450  * @param string $home Optional. Will be used instead of COOKIEPATH if set
1451  * @param string $siteurl Optional. Will be used instead of SITECOOKIEPATH if set
1452  * @param bool $remember Optional. Remember that the user is logged in
1453  */
1454 function wp_setcookie($username, $password = '', $already_md5 = false, $home = '', $siteurl = '', $remember = false) {
1455         _deprecated_function( __FUNCTION__, '2.5', 'wp_set_auth_cookie()' );
1456         $user = get_userdatabylogin($username);
1457         wp_set_auth_cookie($user->ID, $remember);
1458 }
1459 endif;
1460
1461 if ( !function_exists('wp_clearcookie') ) :
1462 /**
1463  * Clears the authentication cookie, logging the user out.
1464  *
1465  * @since 1.5
1466  * @deprecated Use wp_clear_auth_cookie()
1467  * @see wp_clear_auth_cookie()
1468  */
1469 function wp_clearcookie() {
1470         _deprecated_function( __FUNCTION__, '2.5', 'wp_clear_auth_cookie()' );
1471         wp_clear_auth_cookie();
1472 }
1473 endif;
1474
1475 if ( !function_exists('wp_get_cookie_login') ):
1476 /**
1477  * Gets the user cookie login.
1478  *
1479  * This function is deprecated and should no longer be extended as it won't be
1480  * used anywhere in WordPress. Also, plugins shouldn't use it either.
1481  *
1482  * @since 2.0.4
1483  * @deprecated No alternative
1484  *
1485  * @return bool Always returns false
1486  */
1487 function wp_get_cookie_login() {
1488         _deprecated_function( __FUNCTION__, '2.5', '' );
1489         return false;
1490 }
1491 endif;
1492
1493 if ( !function_exists('wp_login') ) :
1494 /**
1495  * Checks a users login information and logs them in if it checks out.
1496  *
1497  * Use the global $error to get the reason why the login failed. If the username
1498  * is blank, no error will be set, so assume blank username on that case.
1499  *
1500  * Plugins extending this function should also provide the global $error and set
1501  * what the error is, so that those checking the global for why there was a
1502  * failure can utilize it later.
1503  *
1504  * @since 1.2.2
1505  * @deprecated Use wp_signon()
1506  * @global string $error Error when false is returned
1507  *
1508  * @param string $username User's username
1509  * @param string $password User's password
1510  * @param bool $deprecated Not used
1511  * @return bool False on login failure, true on successful check
1512  */
1513 function wp_login($username, $password, $deprecated = '') {
1514         global $error;
1515
1516         $user = wp_authenticate($username, $password);
1517
1518         if ( ! is_wp_error($user) )
1519                 return true;
1520
1521         $error = $user->get_error_message();
1522         return false;
1523 }
1524 endif;
1525
1526 if ( !function_exists( 'wp_text_diff' ) ) :
1527 /**
1528  * Displays a human readable HTML representation of the difference between two strings.
1529  *
1530  * The Diff is available for getting the changes between versions. The output is
1531  * HTML, so the primary use is for displaying the changes. If the two strings
1532  * are equivalent, then an empty string will be returned.
1533  *
1534  * The arguments supported and can be changed are listed below.
1535  *
1536  * 'title' : Default is an empty string. Titles the diff in a manner compatible
1537  *              with the output.
1538  * 'title_left' : Default is an empty string. Change the HTML to the left of the
1539  *              title.
1540  * 'title_right' : Default is an empty string. Change the HTML to the right of
1541  *              the title.
1542  *
1543  * @since 2.6
1544  * @see wp_parse_args() Used to change defaults to user defined settings.
1545  * @uses Text_Diff
1546  * @uses WP_Text_Diff_Renderer_Table
1547  *
1548  * @param string $left_string "old" (left) version of string
1549  * @param string $right_string "new" (right) version of string
1550  * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults.
1551  * @return string Empty string if strings are equivalent or HTML with differences.
1552  */
1553 function wp_text_diff( $left_string, $right_string, $args = null ) {
1554         $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
1555         $args = wp_parse_args( $args, $defaults );
1556
1557         if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) )
1558                 require( ABSPATH . WPINC . '/wp-diff.php' );
1559
1560         // Normalize whitespace
1561         $left_string  = trim($left_string);
1562         $right_string = trim($right_string);
1563         $left_string  = str_replace("\r", "\n", $left_string);
1564         $right_string = str_replace("\r", "\n", $right_string);
1565         $left_string  = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $left_string );
1566         $right_string = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $right_string );
1567         
1568         $left_lines  = split("\n", $left_string);
1569         $right_lines = split("\n", $right_string);
1570
1571         $text_diff = new Text_Diff($left_lines, $right_lines);
1572         $renderer  = new WP_Text_Diff_Renderer_Table();
1573         $diff = $renderer->render($text_diff);
1574
1575         if ( !$diff )
1576                 return '';
1577
1578         $r  = "<table class='diff'>\n";
1579         $r .= "<col class='ltype' /><col class='content' /><col class='ltype' /><col class='content' />";
1580
1581         if ( $args['title'] || $args['title_left'] || $args['title_right'] )
1582                 $r .= "<thead>";
1583         if ( $args['title'] )
1584                 $r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
1585         if ( $args['title_left'] || $args['title_right'] ) {
1586                 $r .= "<tr class='diff-sub-title'>\n";
1587                 $r .= "\t<td></td><th>$args[title_left]</th>\n";
1588                 $r .= "\t<td></td><th>$args[title_right]</th>\n";
1589                 $r .= "</tr>\n";
1590         }
1591         if ( $args['title'] || $args['title_left'] || $args['title_right'] )
1592                 $r .= "</thead>\n";
1593
1594         $r .= "<tbody>\n$diff\n</tbody>\n";
1595         $r .= "</table>";
1596
1597         return $r;
1598 }
1599 endif;
1600
1601 ?>