X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/899389d1e4043331309c0433543419258b230b60..4feeb71a9d812a9ae371c28a3d8b442a4394ded7:/wp-includes/pluggable.php diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php index 0779010d..65419a88 100644 --- a/wp-includes/pluggable.php +++ b/wp-includes/pluggable.php @@ -17,17 +17,23 @@ if ( !function_exists('wp_set_current_user') ) : * actions on users who aren't signed in. * * @since 2.0.3 - * @global object $current_user The current user object which holds the user data. + * @global WP_User $current_user The current user object which holds the user data. * - * @param int $id User ID + * @param int $id User ID * @param string $name User's username * @return WP_User Current user User object */ function wp_set_current_user($id, $name = '') { global $current_user; - if ( isset( $current_user ) && ( $current_user instanceof WP_User ) && ( $id == $current_user->ID ) ) + // If `$id` matches the user who's already current, there's nothing to do. + if ( isset( $current_user ) + && ( $current_user instanceof WP_User ) + && ( $id == $current_user->ID ) + && ( null !== $id ) + ) { return $current_user; + } $current_user = new WP_User( $id, $name ); @@ -48,79 +54,19 @@ if ( !function_exists('wp_get_current_user') ) : /** * Retrieve the current user object. * - * @since 2.0.3 - * - * @return WP_User Current user WP_User object - */ -function wp_get_current_user() { - global $current_user; - - get_currentuserinfo(); - - return $current_user; -} -endif; - -if ( !function_exists('get_currentuserinfo') ) : -/** - * Populate global variables with information about the currently logged in user. - * * Will set the current user, if the current user is not set. The current user * will be set to the logged-in person. If no user is logged-in, then it will * set the current user to 0, which is invalid and won't have any permissions. * - * @since 0.71 + * @since 2.0.3 * - * @uses $current_user Checks if the current user is set + * @see _wp_get_current_user() + * @global WP_User $current_user Checks if the current user is set. * - * @return null|false False on XML-RPC Request and invalid auth cookie. Null when current user set. + * @return WP_User Current WP_User instance. */ -function get_currentuserinfo() { - global $current_user; - - if ( ! empty( $current_user ) ) { - if ( $current_user instanceof WP_User ) - return; - - // Upgrade stdClass to WP_User - if ( is_object( $current_user ) && isset( $current_user->ID ) ) { - $cur_id = $current_user->ID; - $current_user = null; - wp_set_current_user( $cur_id ); - return; - } - - // $current_user has a junk value. Force to WP_User with ID 0. - $current_user = null; - wp_set_current_user( 0 ); - return false; - } - - if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) { - wp_set_current_user( 0 ); - return false; - } - - /** - * Filter the current user. - * - * The default filters use this to determine the current user from the - * request's cookies, if available. - * - * Returning a value of false will effectively short-circuit setting - * the current user. - * - * @since 3.9.0 - * - * @param int|bool $user_id User ID if one has been determined, false otherwise. - */ - $user_id = apply_filters( 'determine_current_user', false ); - if ( ! $user_id ) { - wp_set_current_user( 0 ); - return false; - } - - wp_set_current_user( $user_id ); +function wp_get_current_user() { + return _wp_get_current_user(); } endif; @@ -131,7 +77,7 @@ if ( !function_exists('get_userdata') ) : * @since 0.71 * * @param int $user_id User ID - * @return WP_User|bool WP_User object on success, false on failure. + * @return WP_User|false WP_User object on success, false on failure. */ function get_userdata( $user_id ) { return get_user_by( 'id', $user_id ); @@ -143,10 +89,11 @@ if ( !function_exists('get_user_by') ) : * Retrieve user info by a given field * * @since 2.8.0 + * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter. * - * @param string $field The field to retrieve the user with. id | slug | email | login + * @param string $field The field to retrieve the user with. id | ID | slug | email | login. * @param int|string $value A value for $field. A user ID, slug, email address, or login name. - * @return WP_User|bool WP_User object on success, false on failure. + * @return WP_User|false WP_User object on success, false on failure. */ function get_user_by( $field, $value ) { $userdata = WP_User::get_data_by( $field, $value ); @@ -167,6 +114,8 @@ if ( !function_exists('cache_users') ) : * * @since 3.0.0 * + * @global wpdb $wpdb WordPress database abstraction object. + * * @param array $user_ids User ID numbers list */ function cache_users( $user_ids ) { @@ -212,12 +161,12 @@ if ( !function_exists( 'wp_mail' ) ) : * * @since 1.2.1 * - * @uses PHPMailer + * @global PHPMailer $phpmailer * - * @param string|array $to Array or comma-separated list of email addresses to send message. - * @param string $subject Email subject - * @param string $message Message contents - * @param string|array $headers Optional. Additional headers. + * @param string|array $to Array or comma-separated list of email addresses to send message. + * @param string $subject Email subject + * @param string $message Message contents + * @param string|array $headers Optional. Additional headers. * @param string|array $attachments Optional. Files to attach. * @return bool Whether the email contents were sent successfully. */ @@ -405,7 +354,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() try { // Break $recipient into name and address parts if in the format "Foo " $recipient_name = ''; - if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { + if ( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { if ( count( $matches ) == 3 ) { $recipient_name = $matches[1]; $recipient = $matches[2]; @@ -427,7 +376,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() try { // Break $recipient into name and address parts if in the format "Foo " $recipient_name = ''; - if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { + if ( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { if ( count( $matches ) == 3 ) { $recipient_name = $matches[1]; $recipient = $matches[2]; @@ -445,7 +394,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() try { // Break $recipient into name and address parts if in the format "Foo " $recipient_name = ''; - if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { + if ( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { if ( count( $matches ) == 3 ) { $recipient_name = $matches[1]; $recipient = $matches[2]; @@ -498,7 +447,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() // Set custom headers if ( !empty( $headers ) ) { - foreach( (array) $headers as $name => $content ) { + foreach ( (array) $headers as $name => $content ) { $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) ); } @@ -529,6 +478,19 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() try { return $phpmailer->Send(); } catch ( phpmailerException $e ) { + + $mail_error_data = compact( 'to', 'subject', 'message', 'headers', 'attachments' ); + + /** + * Fires after a phpmailerException is caught. + * + * @since 4.4.0 + * + * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array + * containing the mail recipient, subject, message, headers, and attachments. + */ + do_action( 'wp_mail_failed', new WP_Error( $e->getCode(), $e->getMessage(), $mail_error_data ) ); + return false; } } @@ -536,36 +498,40 @@ endif; if ( !function_exists('wp_authenticate') ) : /** - * Checks a user's login information and logs them in if it checks out. + * Authenticate a user, confirming the login credentials are valid. * * @since 2.5.0 + * @since 4.5.0 `$username` now accepts an email address. * - * @param string $username User's username - * @param string $password User's password - * @return WP_User|WP_Error WP_User object if login successful, otherwise WP_Error object. + * @param string $username User's username or email address. + * @param string $password User's password. + * @return WP_User|WP_Error WP_User object if the credentials are valid, + * otherwise WP_Error. */ function wp_authenticate($username, $password) { $username = sanitize_user($username); $password = trim($password); /** - * Filter the user to authenticate. + * Filter whether a set of user login credentials are valid. * - * If a non-null value is passed, the filter will effectively short-circuit - * authentication, returning an error instead. + * A WP_User object is returned if the credentials authenticate a user. + * WP_Error or null otherwise. * * @since 2.8.0 + * @since 4.5.0 `$username` now accepts an email address. * - * @param null|WP_User $user User to authenticate. - * @param string $username User login. - * @param string $password User password + * @param null|WP_User|WP_Error $user WP_User if the user is authenticated. + * WP_Error or null otherwise. + * @param string $username Username or email address. + * @param string $password User password */ $user = apply_filters( 'authenticate', null, $username, $password ); if ( $user == null ) { // TODO what should the error message be? (Or would these even happen?) // Only needed if all authentication handlers fail to return anything. - $user = new WP_Error('authentication_failed', __('ERROR: Invalid username or incorrect password.')); + $user = new WP_Error( 'authentication_failed', __( 'ERROR: Invalid username, email address or incorrect password.' ) ); } $ignore_codes = array('empty_username', 'empty_password'); @@ -575,8 +541,9 @@ function wp_authenticate($username, $password) { * Fires after a user login has failed. * * @since 2.5.0 + * @since 4.5.0 The value of `$username` can now be an email address. * - * @param string $username User login. + * @param string $username Username or email address. */ do_action( 'wp_login_failed', $username ); } @@ -616,9 +583,11 @@ if ( !function_exists('wp_validate_auth_cookie') ) : * * @since 2.5.0 * + * @global int $login_grace_period + * * @param string $cookie Optional. If used, will validate contents instead of cookie's * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in - * @return bool|int False if invalid cookie, User ID if valid. + * @return false|int False if invalid cookie, User ID if valid. */ function wp_validate_auth_cookie($cookie = '', $scheme = '') { if ( ! $cookie_elements = wp_parse_auth_cookie($cookie, $scheme) ) { @@ -723,10 +692,10 @@ if ( !function_exists('wp_generate_auth_cookie') ) : * * @since 2.5.0 * - * @param int $user_id User ID - * @param int $expiration Cookie expiration in seconds - * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in - * @param string $token User's session token to use for this cookie + * @param int $user_id User ID + * @param int $expiration Cookie expiration in seconds + * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in + * @param string $token User's session token to use for this cookie * @return string Authentication cookie contents. Empty string if user does not exist. */ function wp_generate_auth_cookie( $user_id, $expiration, $scheme = 'auth', $token = '' ) { @@ -773,7 +742,7 @@ if ( !function_exists('wp_parse_auth_cookie') ) : * * @param string $cookie * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in - * @return array Authentication cookie components + * @return array|false Authentication cookie components */ function wp_parse_auth_cookie($cookie = '', $scheme = '') { if ( empty($cookie) ) { @@ -815,20 +784,22 @@ endif; if ( !function_exists('wp_set_auth_cookie') ) : /** - * Sets the authentication cookies based on user ID. + * Log in a user by setting authentication cookies. * * The $remember parameter increases the time that the cookie will be kept. The * default the cookie is kept without remembering is two days. When $remember is * set, the cookies will be kept for 14 days or two weeks. * * @since 2.5.0 + * @since 4.3.0 Added the `$token` parameter. * - * @param int $user_id User ID - * @param bool $remember Whether to remember the user - * @param mixed $secure Whether the admin cookies should only be sent over HTTPS. - * Default is_ssl(). + * @param int $user_id User ID + * @param bool $remember Whether to remember the user + * @param mixed $secure Whether the admin cookies should only be sent over HTTPS. + * Default is_ssl(). + * @param string $token Optional. User's session token to use for this cookie. */ -function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { +function wp_set_auth_cookie( $user_id, $remember = false, $secure = '', $token = '' ) { if ( $remember ) { /** * Filter the duration of the authentication cookie expiration period. @@ -856,7 +827,7 @@ function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { $secure = is_ssl(); } - // Frontend cookie is secure when the auth cookie is secure and the site's home URL is forced HTTPS. + // Front-end cookie is secure when the auth cookie is secure and the site's home URL is forced HTTPS. $secure_logged_in_cookie = $secure && 'https' === parse_url( get_option( 'home' ), PHP_URL_SCHEME ); /** @@ -888,8 +859,10 @@ function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { $scheme = 'auth'; } - $manager = WP_Session_Tokens::get_instance( $user_id ); - $token = $manager->create( $expiration ); + if ( '' === $token ) { + $manager = WP_Session_Tokens::get_instance( $user_id ); + $token = $manager->create( $expiration ); + } $auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, $token ); $logged_in_cookie = wp_generate_auth_cookie( $user_id, $expiration, 'logged_in', $token ); @@ -976,10 +949,7 @@ if ( !function_exists('is_user_logged_in') ) : function is_user_logged_in() { $user = wp_get_current_user(); - if ( ! $user->exists() ) - return false; - - return true; + return $user->exists(); } endif; @@ -1014,18 +984,14 @@ function auth_redirect() { } } - if ( is_user_admin() ) { - $scheme = 'logged_in'; - } else { - /** - * Filter the authentication redirect scheme. - * - * @since 2.9.0 - * - * @param string $scheme Authentication redirect scheme. Default empty. - */ - $scheme = apply_filters( 'auth_redirect_scheme', '' ); - } + /** + * Filters the authentication redirect scheme. + * + * @since 2.9.0 + * + * @param string $scheme Authentication redirect scheme. Default empty. + */ + $scheme = apply_filters( 'auth_redirect_scheme', '' ); if ( $user_id = wp_validate_auth_cookie( '', $scheme) ) { /** @@ -1084,10 +1050,6 @@ function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) { $adminurl = strtolower(admin_url()); $referer = strtolower(wp_get_referer()); $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false; - if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) { - wp_nonce_ays($action); - die(); - } /** * Fires once the admin request has been validated or not. @@ -1099,6 +1061,12 @@ function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) { * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. */ do_action( 'check_admin_referer', $action, $result ); + + if ( ! $result && ! ( -1 == $action && strpos( $referer, $adminurl ) === 0 ) ) { + wp_nonce_ays( $action ); + die(); + } + return $result; } endif; @@ -1130,13 +1098,6 @@ function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) { $result = wp_verify_nonce( $nonce, $action ); - if ( $die && false == $result ) { - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) - wp_die( -1 ); - else - die( '-1' ); - } - /** * Fires once the AJAX request has been validated or not. * @@ -1148,6 +1109,14 @@ function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) { */ do_action( 'check_ajax_referer', $action, $result ); + if ( $die && false === $result ) { + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + wp_die( -1 ); + } else { + die( '-1' ); + } + } + return $result; } endif; @@ -1158,8 +1127,10 @@ if ( !function_exists('wp_redirect') ) : * * @since 1.5.1 * + * @global bool $is_IIS + * * @param string $location The path to redirect to. - * @param int $status Status code to use. + * @param int $status Status code to use. * @return bool False if $location is not provided, true otherwise. */ function wp_redirect($location, $status = 302) { @@ -1205,7 +1176,8 @@ if ( !function_exists('wp_sanitize_redirect') ) : * * @since 2.3.0 * - * @return string redirect-sanitized URL + * @param string $location The path to redirect to. + * @return string Redirect-sanitized URL. **/ function wp_sanitize_redirect($location) { $regex = '/ @@ -1221,13 +1193,12 @@ function wp_sanitize_redirect($location) { ){1,40} # ...one or more times )/x'; $location = preg_replace_callback( $regex, '_wp_sanitize_utf8_in_redirect', $location ); - $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!*\[\]()]|i', '', $location); + $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!*\[\]()@]|i', '', $location); $location = wp_kses_no_null($location); // remove %0d and %0a from location $strip = array('%0d', '%0a', '%0D', '%0A'); - $location = _deep_replace($strip, $location); - return $location; + return _deep_replace( $strip, $location ); } /** @@ -1238,6 +1209,9 @@ function wp_sanitize_redirect($location) { * @access private * * @see wp_sanitize_redirect() + * + * @param array $matches RegEx matches against the redirect location. + * @return string URL-encoded version of the first RegEx match. */ function _wp_sanitize_utf8_in_redirect( $matches ) { return urlencode( $matches[0] ); @@ -1252,20 +1226,29 @@ if ( !function_exists('wp_safe_redirect') ) : * path. A plugin can therefore set or remove allowed host(s) to or from the * list. * - * If the host is not allowed, then the redirect is to wp-admin on the siteurl + * If the host is not allowed, then the redirect defaults to wp-admin on the siteurl * instead. This prevents malicious redirects which redirect to another host, * but only used in a few places. * * @since 2.3.0 * - * @return void Does not return anything - **/ + * @param string $location The path to redirect to. + * @param int $status Status code to use. + */ function wp_safe_redirect($location, $status = 302) { // Need to look at the URL the way it will end up in wp_redirect() $location = wp_sanitize_redirect($location); - $location = wp_validate_redirect($location, admin_url()); + /** + * Filter the redirect fallback URL for when the provided redirect is not safe (local). + * + * @since 4.3.0 + * + * @param string $fallback_url The fallback URL to use by default. + * @param int $status The redirect status. + */ + $location = wp_validate_redirect( $location, apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status ) ); wp_redirect($location, $status); } @@ -1284,7 +1267,7 @@ if ( !function_exists('wp_validate_redirect') ) : * @since 2.8.1 * * @param string $location The redirect to validate - * @param string $default The value to return if $location is not allowed + * @param string $default The value to return if $location is not allowed * @return string redirect-sanitized URL **/ function wp_validate_redirect($location, $default = '') { @@ -1296,7 +1279,8 @@ function wp_validate_redirect($location, $default = '') { // In php 5 parse_url may fail if the URL query part contains http://, bug #38143 $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location; - $lp = parse_url($test); + // @-operator is used to prevent possible warnings in PHP < 5.3.3. + $lp = @parse_url($test); // Give up if malformed URL if ( false === $lp ) @@ -1306,9 +1290,17 @@ function wp_validate_redirect($location, $default = '') { if ( isset($lp['scheme']) && !('http' == $lp['scheme'] || 'https' == $lp['scheme']) ) return $default; - // Reject if scheme is set but host is not. This catches urls like https:host.com for which parse_url does not set the host field. - if ( isset($lp['scheme']) && !isset($lp['host']) ) + // Reject if certain components are set but host is not. This catches urls like https:host.com for which parse_url does not set the host field. + if ( ! isset( $lp['host'] ) && ( isset( $lp['scheme'] ) || isset( $lp['user'] ) || isset( $lp['pass'] ) || isset( $lp['port'] ) ) ) { return $default; + } + + // Reject malformed components parse_url() can return on odd inputs. + foreach ( array( 'user', 'pass', 'host' ) as $component ) { + if ( isset( $lp[ $component ] ) && strpbrk( $lp[ $component ], ':/?#@' ) ) { + return $default; + } + } $wpp = parse_url(home_url()); @@ -1335,8 +1327,8 @@ if ( ! function_exists('wp_notify_postauthor') ) : * * @since 1.0.0 * - * @param int $comment_id Comment ID - * @param string $deprecated Not used + * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. + * @param string $deprecated Not used * @return bool True on completion. False if no email addresses were specified. */ function wp_notify_postauthor( $comment_id, $deprecated = null ) { @@ -1345,7 +1337,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { } $comment = get_comment( $comment_id ); - if ( empty( $comment ) ) + if ( empty( $comment ) || empty( $comment->comment_post_ID ) ) return false; $post = get_post( $comment->comment_post_ID ); @@ -1368,7 +1360,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { * @param array $emails An array of email addresses to receive a comment notification. * @param int $comment_id The comment ID. */ - $emails = apply_filters( 'comment_notification_recipients', $emails, $comment_id ); + $emails = apply_filters( 'comment_notification_recipients', $emails, $comment->comment_ID ); $emails = array_filter( $emails ); // If there are no addresses to send the comment to, bail. @@ -1391,7 +1383,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { * Default false. * @param int $comment_id The comment ID. */ - $notify_author = apply_filters( 'comment_notification_notify_author', false, $comment_id ); + $notify_author = apply_filters( 'comment_notification_notify_author', false, $comment->comment_ID ); // The comment was left by the author if ( $author && ! $notify_author && $comment->user_id == $post->post_author ) { @@ -1420,6 +1412,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { // The blogname option is escaped with esc_html on the way into the database in sanitize_option // we want to reverse this for the plain text arena of emails. $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + $comment_content = wp_specialchars_decode( $comment->comment_content ); switch ( $comment->comment_type ) { case 'trackback': @@ -1427,7 +1420,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { /* translators: 1: website name, 2: website IP, 3: website hostname */ $notify_message .= sprintf( __('Website: %1$s (IP: %2$s, %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; $notify_message .= __( 'You can see all trackbacks on this post here:' ) . "\r\n"; /* translators: 1: blog name, 2: post title */ $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title ); @@ -1437,7 +1430,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { /* translators: 1: website name, 2: website IP, 3: website hostname */ $notify_message .= sprintf( __('Website: %1$s (IP: %2$s, %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; $notify_message .= __( 'You can see all pingbacks on this post here:' ) . "\r\n"; /* translators: 1: blog name, 2: post title */ $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title ); @@ -1446,24 +1439,24 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; /* translators: 1: comment author, 2: author IP, 3: author domain */ $notify_message .= sprintf( __( 'Author: %1$s (IP: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; - $notify_message .= sprintf( __( 'E-mail: %s' ), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= sprintf( __( 'Whois: %s' ), "http://whois.arin.net/rest/ip/{$comment->comment_author_IP}" ) . "\r\n"; - $notify_message .= sprintf( __('Comment: %s' ), "\r\n" . $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= sprintf( __('Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; $notify_message .= __( 'You can see all comments on this post here:' ) . "\r\n"; /* translators: 1: blog name, 2: post title */ $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title ); break; } $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n"; - $notify_message .= sprintf( __('Permalink: %s'), get_comment_link( $comment_id ) ) . "\r\n"; + $notify_message .= sprintf( __('Permalink: %s'), get_comment_link( $comment ) ) . "\r\n"; - if ( user_can( $post->post_author, 'edit_comment', $comment_id ) ) { - if ( EMPTY_TRASH_DAYS ) - $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; - else - $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; - $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; + if ( user_can( $post->post_author, 'edit_comment', $comment->comment_ID ) ) { + if ( EMPTY_TRASH_DAYS ) { + $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; + } else { + $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; + } + $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; } $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); @@ -1492,7 +1485,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { * @param string $notify_message The comment notification email text. * @param int $comment_id Comment ID. */ - $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment_id ); + $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment->comment_ID ); /** * Filter the comment notification email subject. @@ -1502,7 +1495,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { * @param string $subject The comment notification email subject. * @param int $comment_id Comment ID. */ - $subject = apply_filters( 'comment_notification_subject', $subject, $comment_id ); + $subject = apply_filters( 'comment_notification_subject', $subject, $comment->comment_ID ); /** * Filter the comment notification email headers. @@ -1512,7 +1505,7 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) { * @param string $message_headers Headers for the comment notification email. * @param int $comment_id Comment ID. */ - $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment_id ); + $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment->comment_ID ); foreach ( $emails as $email ) { @wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); @@ -1524,27 +1517,43 @@ endif; if ( !function_exists('wp_notify_moderator') ) : /** - * Notifies the moderator of the blog about a new comment that is awaiting approval. + * Notifies the moderator of the site about a new comment that is awaiting approval. * * @since 1.0.0 * * @global wpdb $wpdb WordPress database abstraction object. * - * @param int $comment_id Comment ID - * @return bool Always returns true + * Uses the {@see 'notify_moderator'} filter to determine whether the site moderator + * should be notified, overriding the site setting. + * + * @param int $comment_id Comment ID. + * @return true Always returns true. */ function wp_notify_moderator($comment_id) { global $wpdb; - if ( 0 == get_option( 'moderation_notify' ) ) + $maybe_notify = get_option( 'moderation_notify' ); + + /** + * Filter whether to send the site moderator email notifications, overriding the site setting. + * + * @since 4.4.0 + * + * @param bool $maybe_notify Whether to notify blog moderator. + * @param int $comment_ID The id of the comment for the notification. + */ + $maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id ); + + if ( ! $maybe_notify ) { return true; + } $comment = get_comment($comment_id); $post = get_post($comment->comment_post_ID); $user = get_userdata( $post->post_author ); // Send to the administration and to the post author if the author can modify the comment. $emails = array( get_option( 'admin_email' ) ); - if ( user_can( $user->ID, 'edit_comment', $comment_id ) && ! empty( $user->user_email ) ) { + if ( $user && user_can( $user->ID, 'edit_comment', $comment_id ) && ! empty( $user->user_email ) ) { if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) $emails[] = $user->user_email; } @@ -1555,6 +1564,7 @@ function wp_notify_moderator($comment_id) { // The blogname option is escaped with esc_html on the way into the database in sanitize_option // we want to reverse this for the plain text arena of emails. $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + $comment_content = wp_specialchars_decode( $comment->comment_content ); switch ( $comment->comment_type ) { case 'trackback': @@ -1563,7 +1573,7 @@ function wp_notify_moderator($comment_id) { /* translators: 1: website name, 2: website IP, 3: website hostname */ $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment_content . "\r\n\r\n"; break; case 'pingback': $notify_message = sprintf( __('A new pingback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; @@ -1571,29 +1581,30 @@ function wp_notify_moderator($comment_id) { /* translators: 1: website name, 2: website IP, 3: website hostname */ $notify_message .= sprintf( __( 'Website: %1$s (IP: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment_content . "\r\n\r\n"; break; default: // Comments $notify_message = sprintf( __('A new comment on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; $notify_message .= sprintf( __( 'Author: %1$s (IP: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; - $notify_message .= sprintf( __( 'E-mail: %s' ), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; - $notify_message .= sprintf( __( 'Whois: %s' ), "http://whois.arin.net/rest/ip/{$comment->comment_author_IP}" ) . "\r\n"; - $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; break; } - $notify_message .= sprintf( __('Approve it: %s'), admin_url("comment.php?action=approve&c=$comment_id") ) . "\r\n"; + $notify_message .= sprintf( __( 'Approve it: %s' ), admin_url( "comment.php?action=approve&c={$comment_id}#wpbody-content" ) ) . "\r\n"; + if ( EMPTY_TRASH_DAYS ) - $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; + $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment_id}#wpbody-content" ) ) . "\r\n"; else - $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; - $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; + $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment_id}#wpbody-content" ) ) . "\r\n"; + + $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment_id}#wpbody-content" ) ) . "\r\n"; $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:', 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n"; - $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n"; + $notify_message .= admin_url( "edit-comments.php?comment_status=moderated#wpbody-content" ) . "\r\n"; $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), $blogname, $post->post_title ); $message_headers = ''; @@ -1652,9 +1663,9 @@ if ( !function_exists('wp_password_change_notification') ) : * * @since 2.7.0 * - * @param object $user User Object + * @param WP_User $user User object. */ -function wp_password_change_notification(&$user) { +function wp_password_change_notification( $user ) { // send a copy of password change notification to the admin // but check to see if it's the admin whose password we're changing, and skip this if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) { @@ -1674,11 +1685,23 @@ if ( !function_exists('wp_new_user_notification') ) : * A new user registration notification is also sent to admin email. * * @since 2.0.0 + * @since 4.3.0 The `$plaintext_pass` parameter was changed to `$notify`. + * @since 4.3.1 The `$plaintext_pass` parameter was deprecated. `$notify` added as a third parameter. * - * @param int $user_id User ID. - * @param string $plaintext_pass Optional. The user's plaintext password. Default empty. + * @global wpdb $wpdb WordPress database object for queries. + * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance. + * + * @param int $user_id User ID. + * @param null $deprecated Not used (argument deprecated). + * @param string $notify Optional. Type of notification that should happen. Accepts 'admin' or an empty + * string (admin only), or 'both' (admin and user). Default empty. */ -function wp_new_user_notification($user_id, $plaintext_pass = '') { +function wp_new_user_notification( $user_id, $deprecated = null, $notify = '' ) { + if ( $deprecated !== null ) { + _deprecated_argument( __FUNCTION__, '4.3.1' ); + } + + global $wpdb, $wp_hasher; $user = get_userdata( $user_id ); // The blogname option is escaped with esc_html on the way into the database in sanitize_option @@ -1687,19 +1710,36 @@ function wp_new_user_notification($user_id, $plaintext_pass = '') { $message = sprintf(__('New user registration on your site %s:'), $blogname) . "\r\n\r\n"; $message .= sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n"; - $message .= sprintf(__('E-mail: %s'), $user->user_email) . "\r\n"; + $message .= sprintf(__('Email: %s'), $user->user_email) . "\r\n"; @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), $blogname), $message); - if ( empty($plaintext_pass) ) + // `$deprecated was pre-4.3 `$plaintext_pass`. An empty `$plaintext_pass` didn't sent a user notifcation. + if ( 'admin' === $notify || ( empty( $deprecated ) && empty( $notify ) ) ) { return; + } - $message = sprintf(__('Username: %s'), $user->user_login) . "\r\n"; - $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n"; - $message .= wp_login_url() . "\r\n"; + // Generate something random for a password reset key. + $key = wp_generate_password( 20, false ); + + /** This action is documented in wp-login.php */ + do_action( 'retrieve_password_key', $user->user_login, $key ); + + // Now insert the key, hashed, into the DB. + if ( empty( $wp_hasher ) ) { + require_once ABSPATH . WPINC . '/class-phpass.php'; + $wp_hasher = new PasswordHash( 8, true ); + } + $hashed = time() . ':' . $wp_hasher->HashPassword( $key ); + $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user->user_login ) ); + + $message = sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n"; + $message .= __('To set your password, visit the following address:') . "\r\n\r\n"; + $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user->user_login), 'login') . ">\r\n\r\n"; - wp_mail($user->user_email, sprintf(__('[%s] Your username and password'), $blogname), $message); + $message .= wp_login_url() . "\r\n"; + wp_mail($user->user_email, sprintf(__('[%s] Your username and password info'), $blogname), $message); } endif; @@ -1777,6 +1817,18 @@ function wp_verify_nonce( $nonce, $action = -1 ) { return 2; } + /** + * Fires when nonce verification fails. + * + * @since 4.4.0 + * + * @param string $nonce The invalid nonce. + * @param string|int $action The nonce action. + * @param WP_User $user The current user object. + * @param string $token The user's session token. + */ + do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token ); + // Invalid nonce return false; } @@ -1784,9 +1836,11 @@ endif; if ( !function_exists('wp_create_nonce') ) : /** - * Creates a cryptographic token tied to a specific action, user, and window of time. + * Creates a cryptographic token tied to a specific action, user, user session, + * and window of time. * * @since 2.0.3 + * @since 4.0.0 Session tokens were integrated with nonce creation * * @param string|int $action Scalar value to add context to the nonce. * @return string The token. @@ -1836,6 +1890,9 @@ if ( !function_exists('wp_salt') ) : * * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php * + * @staticvar array $cached_salts + * @staticvar array $duplicated_keys + * * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce) * @return string Salt value */ @@ -1916,7 +1973,8 @@ if ( !function_exists('wp_hash') ) : * * @since 2.0.3 * - * @param string $data Plain text to hash + * @param string $data Plain text to hash + * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce) * @return string Hash of $data */ function wp_hash($data, $scheme = 'auth') { @@ -1935,8 +1993,7 @@ if ( !function_exists('wp_hash_password') ) : * * @since 2.5.0 * - * @global object $wp_hasher PHPass object - * @uses PasswordHash::HashPassword + * @global PasswordHash $wp_hasher PHPass object * * @param string $password Plain text user password to hash * @return string The hash string of the password @@ -1968,12 +2025,13 @@ if ( !function_exists('wp_check_password') ) : * * @since 2.5.0 * - * @global object $wp_hasher PHPass object used for checking the password + * @global PasswordHash $wp_hasher PHPass object used for checking the password * against the $hash + $password * @uses PasswordHash::CheckPassword * - * @param string $password Plaintext user's password - * @param string $hash Hash of the user's password to check against. + * @param string $password Plaintext user's password + * @param string $hash Hash of the user's password to check against. + * @param string|int $user_id Optional. User ID. * @return bool False, if the $password does not match the hashed password */ function wp_check_password($password, $hash, $user_id = '') { @@ -1993,10 +2051,10 @@ function wp_check_password($password, $hash, $user_id = '') { * * @since 2.5.0 * - * @param bool $check Whether the passwords match. - * @param string $password The plaintext password. - * @param string $hash The hashed password. - * @param int $user_id User ID. + * @param bool $check Whether the passwords match. + * @param string $password The plaintext password. + * @param string $hash The hashed password. + * @param string|int $user_id User ID. Can be empty. */ return apply_filters( 'check_password', $check, $password, $hash, $user_id ); } @@ -2057,6 +2115,11 @@ if ( !function_exists('wp_rand') ) : * Generates a random number * * @since 2.6.2 + * @since 4.4.0 Uses PHP7 random_int() or the random_compat library if available. + * + * @global string $rnd_value + * @staticvar string $seed + * @staticvar bool $external_rand_source_available * * @param int $min Lower limit for the generated number * @param int $max Upper limit for the generated number @@ -2065,6 +2128,34 @@ if ( !function_exists('wp_rand') ) : function wp_rand( $min = 0, $max = 0 ) { global $rnd_value; + // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. + $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff + + // We only handle Ints, floats are truncated to their integer value. + $min = (int) $min; + $max = (int) $max; + + // Use PHP's CSPRNG, or a compatible method + static $use_random_int_functionality = true; + if ( $use_random_int_functionality ) { + try { + $_max = ( 0 != $max ) ? $max : $max_random_number; + // wp_rand() can accept arguments in either order, PHP cannot. + $_max = max( $min, $_max ); + $_min = min( $min, $_max ); + $val = random_int( $_min, $_max ); + if ( false !== $val ) { + return absint( $val ); + } else { + $use_random_int_functionality = false; + } + } catch ( Error $e ) { + $use_random_int_functionality = false; + } catch ( Exception $e ) { + $use_random_int_functionality = false; + } + } + // Reset $rnd_value after 14 uses // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value if ( strlen($rnd_value) < 8 ) { @@ -2076,8 +2167,9 @@ function wp_rand( $min = 0, $max = 0 ) { $rnd_value .= sha1($rnd_value); $rnd_value .= sha1($rnd_value . $seed); $seed = md5($seed . $rnd_value); - if ( ! defined( 'WP_SETUP_CONFIG' ) ) - set_transient('random_seed', $seed); + if ( ! defined( 'WP_SETUP_CONFIG' ) && ! defined( 'WP_INSTALLING' ) ) { + set_transient( 'random_seed', $seed ); + } } // Take the first 8 digits for our value @@ -2088,9 +2180,6 @@ function wp_rand( $min = 0, $max = 0 ) { $value = abs(hexdec($value)); - // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. - $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff - // Reduce the value to be within the min - max range if ( $max != 0 ) $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); @@ -2115,7 +2204,7 @@ if ( !function_exists('wp_set_password') ) : * @global wpdb $wpdb WordPress database abstraction object. * * @param string $password The plaintext new user password - * @param int $user_id User ID + * @param int $user_id User ID */ function wp_set_password( $password, $user_id ) { global $wpdb; @@ -2135,12 +2224,12 @@ if ( !function_exists( 'get_avatar' ) ) : * @since 4.2.0 Optional `$args` parameter added. * * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash, - * user email, WP_User object, WP_Post object, or comment object. + * user email, WP_User object, WP_Post object, or WP_Comment object. * @param int $size Optional. Height and width of the avatar image file in pixels. Default 96. * @param string $default Optional. URL for the default image or a default type. Accepts '404' * (return a 404 instead of a default image), 'retro' (8bit), 'monsterid' * (monster), 'wavatar' (cartoon face), 'indenticon' (the "quilt"), - * 'mystery', 'mm', or 'mysterman' (The Oyster Man), 'blank' (transparent GIF), + * 'mystery', 'mm', or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF), * or 'gravatar_default' (the Gravatar logo). Default is the value of the * 'avatar_default' option, with a fallback of 'mystery'. * @param string $alt Optional. Alternative text to use in <img> tag. Default empty. @@ -2195,17 +2284,22 @@ function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = $args['width'] = $args['size']; } + if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) { + $id_or_email = get_comment( $id_or_email ); + } + /** * Filter whether to retrieve the avatar URL early. * * Passing a non-null value will effectively short-circuit get_avatar(), passing - * the value through the {@see 'pre_get_avatar'} filter and returning early. + * the value through the {@see 'get_avatar'} filter and returning early. * * @since 4.2.0 * - * @param string $avatar HTML for the user's avatar. Default null. - * @param int|object|string $id_or_email A user ID, email address, or comment object. - * @param array $args Arguments passed to get_avatar_url(), after processing. + * @param string $avatar HTML for the user's avatar. Default null. + * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash, + * user email, WP_User object, WP_Post object, or WP_Comment object. + * @param array $args Arguments passed to get_avatar_url(), after processing. */ $avatar = apply_filters( 'pre_get_avatar', null, $id_or_email, $args ); @@ -2225,13 +2319,13 @@ function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = $url = $args['url']; if ( ! $url || is_wp_error( $url ) ) { - return false; + return false; } $class = array( 'avatar', 'avatar-' . (int) $args['size'], 'photo' ); if ( ! $args['found_avatar'] || $args['force_default'] ) { - $class[] = 'avatar-default'; + $class[] = 'avatar-default'; } if ( $args['class'] ) { @@ -2259,12 +2353,13 @@ function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = * @since 2.5.0 * @since 4.2.0 The `$args` parameter was added. * - * @param string $avatar <img> tag for the user's avatar. - * @param int|object|string $id_or_email A user ID, email address, or comment object. - * @param int $size Square avatar width and height in pixels to retrieve. - * @param string $alt Alternative text to use in the avatar image tag. + * @param string $avatar <img> tag for the user's avatar. + * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash, + * user email, WP_User object, WP_Post object, or WP_Comment object. + * @param int $size Square avatar width and height in pixels to retrieve. + * @param string $alt Alternative text to use in the avatar image tag. * Default empty. - * @param array $args Arguments passed to get_avatar_data(), after processing. + * @param array $args Arguments passed to get_avatar_data(), after processing. */ return apply_filters( 'get_avatar', $avatar, $id_or_email, $args['size'], $args['default'], $args['alt'], $args ); } @@ -2293,16 +2388,16 @@ if ( !function_exists( 'wp_text_diff' ) ) : * @uses Text_Diff * @uses WP_Text_Diff_Renderer_Table * - * @param string $left_string "old" (left) version of string - * @param string $right_string "new" (right) version of string - * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. + * @param string $left_string "old" (left) version of string + * @param string $right_string "new" (right) version of string + * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. * @return string Empty string if strings are equivalent or HTML with differences. */ function wp_text_diff( $left_string, $right_string, $args = null ) { $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' ); $args = wp_parse_args( $args, $defaults ); - if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) ) + if ( ! class_exists( 'WP_Text_Diff_Renderer_Table', false ) ) require( ABSPATH . WPINC . '/wp-diff.php' ); $left_string = normalize_whitespace($left_string);