WordPress.org

Make WordPress Core

Ticket #8833: 8833.5.patch

File 8833.5.patch, 124.8 KB (added by Viper007Bond, 9 years ago)

Remove an accidental part of a collision error message

  • wp-includes/functions.php

     
    3737        if( 'U' == $dateformatstring )
    3838                return $i;
    3939
    40         if ( $translate)
    41             return date_i18n( $dateformatstring, $i );
     40        if ( $translate )
     41                return date_i18n( $dateformatstring, $i );
    4242        else
    43             return date( $dateformatstring, $i );
     43                return date( $dateformatstring, $i );
    4444}
    4545
    4646/**
     
    16941694}
    16951695
    16961696/**
     1697 * Get the time-dependent variable for nonce creation.
     1698 *
     1699 * A nonce has a lifespan of two ticks. Nonces in their second tick may be
     1700 * updated, e.g. by autosave.
     1701 *
     1702 * This function should not be used directly. Use the pluggable version instead.
     1703 * @see wp_nonce_tick()
     1704 *
     1705 * @package WordPress
     1706 * @subpackage Security
     1707 * @since 2.8.0
     1708 *
     1709 * @return int
     1710 */
     1711function _wp_nonce_tick() {
     1712        $nonce_life = apply_filters('nonce_life', 86400);
     1713
     1714        return ceil( time() / ( $nonce_life / 2 ) );
     1715}
     1716
     1717/**
     1718 * Verify that correct nonce was used with time limit.
     1719 *
     1720 * The user is given an amount of time to use the token, so therefore, since the
     1721 * UID and $action remain the same, the independent variable is the time.
     1722 *
     1723 * This function should not be used directly. Use the pluggable version instead.
     1724 * @see wp_verify_nonce()
     1725 *
     1726 * @package WordPress
     1727 * @subpackage Security
     1728 * @since 2.8.0
     1729 *
     1730 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_verify_nonce" filter.
     1731 * @param string $nonce Nonce that was used in the form to verify
     1732 * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
     1733 * @return bool Whether the nonce check passed or failed.
     1734 */
     1735function _wp_verify_nonce( $existing = null, $nonce, $action = -1 ) {
     1736        if ( null !== $existing )
     1737                return $existing;
     1738
     1739        $user = wp_get_current_user();
     1740        $uid = (int) $user->id;
     1741
     1742        $i = wp_nonce_tick();
     1743
     1744        // Nonce generated 0-12 hours ago
     1745        if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) == $nonce )
     1746                return 1;
     1747        // Nonce generated 12-24 hours ago
     1748        if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) == $nonce )
     1749                return 2;
     1750        // Invalid nonce
     1751        return false;
     1752}
     1753
     1754/**
     1755 * Creates a random, one time use token.
     1756 *
     1757 * This function should not be used directly. Use the pluggable version instead.
     1758 * @see wp_create_nonce()
     1759 *
     1760 * @package WordPress
     1761 * @subpackage Security
     1762 * @since 2.8.0
     1763 *
     1764 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_create_nonce" filter.
     1765 * @param string|int $action Scalar value to add context to the nonce.
     1766 * @return string The one use form token
     1767 */
     1768function _wp_create_nonce( $existing = null, $action = -1 ) {
     1769        if ( null !== $existing )
     1770                return $existing;
     1771
     1772        $user = wp_get_current_user();
     1773        $uid = (int) $user->id;
     1774
     1775        $i = wp_nonce_tick();
     1776
     1777        return substr( wp_hash($i . $action . $uid, 'nonce'), -12, 10 );
     1778}
     1779
     1780/**
    16971781 * Retrieve URL with nonce added to URL query.
    16981782 *
    16991783 * @package WordPress
     
    17551839}
    17561840
    17571841/**
     1842 * Get salt to add to hashes to help prevent attacks.
     1843 *
     1844 * The secret key is located in two places: the database in case the secret key
     1845 * isn't defined in the second place, which is in the wp-config.php file. If you
     1846 * are going to set the secret key, then you must do so in the wp-config.php
     1847 * file.
     1848 *
     1849 * The secret key in the database is randomly generated and will be appended to
     1850 * the secret key that is in wp-config.php file in some instances. It is
     1851 * important to have the secret key defined or changed in wp-config.php.
     1852 *
     1853 * If you have installed WordPress 2.5 or later, then you will have the
     1854 * SECRET_KEY defined in the wp-config.php already. You will want to change the
     1855 * value in it because hackers will know what it is. If you have upgraded to
     1856 * WordPress 2.5 or later version from a version before WordPress 2.5, then you
     1857 * should add the constant to your wp-config.php file.
     1858 *
     1859 * Below is an example of how the SECRET_KEY constant is defined with a value.
     1860 * You must not copy the below example and paste into your wp-config.php. If you
     1861 * need an example, then you can have a
     1862 * {@link https://api.wordpress.org/secret-key/1.1/ secret key created} for you.
     1863 *
     1864 * <code>
     1865 * define('SECRET_KEY', 'mAry1HadA15|\/|b17w55w1t3asSn09w');
     1866 * </code>
     1867 *
     1868 * Salting passwords helps against tools which has stored hashed values of
     1869 * common dictionary strings. The added values makes it harder to crack if given
     1870 * salt string is not weak.
     1871 *
     1872 * This function should not be used directly. Use the pluggable version instead.
     1873 * @see wp_salt()
     1874 *
     1875 * @package WordPress
     1876 * @subpackage Security
     1877 * @since 2.8.0
     1878 * @link https://api.wordpress.org/secret-key/1.1/ Create a Secret Key for wp-config.php
     1879 *
     1880 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_salt" filter.
     1881 * @param string $scheme Auth scheme.
     1882 * @return string Salt value from either 'SECRET_KEY' or 'secret' option
     1883 */
     1884function _wp_salt( $existing = null, $scheme = 'auth' ) {
     1885        if ( null !== $existing )
     1886                return $existing;
     1887
     1888        global $wp_default_secret_key;
     1889        $secret_key = '';
     1890        if ( defined('SECRET_KEY') && ('' != SECRET_KEY) && ( $wp_default_secret_key != SECRET_KEY) )
     1891                $secret_key = SECRET_KEY;
     1892
     1893        if ( 'auth' == $scheme ) {
     1894                if ( defined('AUTH_KEY') && ('' != AUTH_KEY) && ( $wp_default_secret_key != AUTH_KEY) )
     1895                        $secret_key = AUTH_KEY;
     1896
     1897                if ( defined('AUTH_SALT') ) {
     1898                        $salt = AUTH_SALT;
     1899                } elseif ( defined('SECRET_SALT') ) {
     1900                        $salt = SECRET_SALT;
     1901                } else {
     1902                        $salt = get_option('auth_salt');
     1903                        if ( empty($salt) ) {
     1904                                $salt = wp_generate_password(64);
     1905                                update_option('auth_salt', $salt);
     1906                        }
     1907                }
     1908        } elseif ( 'secure_auth' == $scheme ) {
     1909                if ( defined('SECURE_AUTH_KEY') && ('' != SECURE_AUTH_KEY) && ( $wp_default_secret_key != SECURE_AUTH_KEY) )
     1910                        $secret_key = SECURE_AUTH_KEY;
     1911
     1912                if ( defined('SECURE_AUTH_SALT') ) {
     1913                        $salt = SECURE_AUTH_SALT;
     1914                } else {
     1915                        $salt = get_option('secure_auth_salt');
     1916                        if ( empty($salt) ) {
     1917                                $salt = wp_generate_password(64);
     1918                                update_option('secure_auth_salt', $salt);
     1919                        }
     1920                }
     1921        } elseif ( 'logged_in' == $scheme ) {
     1922                if ( defined('LOGGED_IN_KEY') && ('' != LOGGED_IN_KEY) && ( $wp_default_secret_key != LOGGED_IN_KEY) )
     1923                        $secret_key = LOGGED_IN_KEY;
     1924
     1925                if ( defined('LOGGED_IN_SALT') ) {
     1926                        $salt = LOGGED_IN_SALT;
     1927                } else {
     1928                        $salt = get_option('logged_in_salt');
     1929                        if ( empty($salt) ) {
     1930                                $salt = wp_generate_password(64);
     1931                                update_option('logged_in_salt', $salt);
     1932                        }
     1933                }
     1934        } elseif ( 'nonce' == $scheme ) {
     1935                if ( defined('NONCE_KEY') && ('' != NONCE_KEY) && ( $wp_default_secret_key != NONCE_KEY) )
     1936                        $secret_key = NONCE_KEY;
     1937
     1938                if ( defined('NONCE_SALT') ) {
     1939                        $salt = NONCE_SALT;
     1940                } else {
     1941                        $salt = get_option('nonce_salt');
     1942                        if ( empty($salt) ) {
     1943                                $salt = wp_generate_password(64);
     1944                                update_option('nonce_salt', $salt);
     1945                        }
     1946                }
     1947        } else {
     1948                // ensure each auth scheme has its own unique salt
     1949                $salt = hash_hmac('md5', $scheme, $secret_key);
     1950        }
     1951
     1952        return apply_filters('salt', $secret_key . $salt, $scheme);
     1953}
     1954
     1955/**
     1956 * Get hash of given string.
     1957 *
     1958 * This function should not be used directly. Use the pluggable version instead.
     1959 * @see wp_hash()
     1960 *
     1961 * @package WordPress
     1962 * @subpackage Security
     1963 * @since 2.8.0
     1964 * @uses wp_salt() Get WordPress salt
     1965 *
     1966 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_hash" filter.
     1967 * @param string $data Plain text to hash
     1968 * @return string Hash of $data
     1969 */
     1970function _wp_hash( $existing = null, $data, $scheme = 'auth' ) {
     1971        if ( null !== $existing )
     1972                return $existing;
     1973
     1974        $salt = wp_salt($scheme);
     1975
     1976        return hash_hmac('md5', $data, $salt);
     1977}
     1978
     1979/**
     1980 * Create a hash (encrypt) of a plain text password.
     1981 *
     1982 * This function should not be used directly. Use the pluggable version instead.
     1983 * @see wp_hash_password()
     1984 *
     1985 * @package WordPress
     1986 * @subpackage Security
     1987 * @since 2.8.0
     1988 * @global object $wp_hasher PHPass object
     1989 * @uses PasswordHash::HashPassword
     1990 *
     1991 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_hash_password" filter.
     1992 * @param string $password Plain text user password to hash
     1993 * @return string The hash string of the password
     1994 */
     1995function _wp_hash_password( $existing = null, $password ) {
     1996        if ( null !== $existing )
     1997                return $existing;
     1998
     1999        global $wp_hasher;
     2000
     2001        if ( empty($wp_hasher) ) {
     2002                require_once( ABSPATH . 'wp-includes/class-phpass.php');
     2003                // By default, use the portable hash from phpass
     2004                $wp_hasher = new PasswordHash(8, TRUE);
     2005        }
     2006
     2007        return $wp_hasher->HashPassword($password);
     2008}
     2009
     2010/**
     2011 * Checks the plaintext password against the encrypted password.
     2012 *
     2013 * Maintains compatibility between old version and the new cookie authentication
     2014 * protocol using PHPass library. The $hash parameter is the encrypted password
     2015 * and the function compares the plain text password when encypted similarly
     2016 * against the already encrypted password to see if they match.
     2017 *
     2018 * For integration with other applications, this function can be overwritten to
     2019 * instead use the other package password checking algorithm.
     2020 *
     2021 * This function should not be used directly. Use the pluggable version instead.
     2022 * @see wp_check_password()
     2023 *
     2024 * @package WordPress
     2025 * @subpackage Security
     2026 * @since 2.8.0
     2027 * @global object $wp_hasher PHPass object used for checking the password
     2028 *       against the $hash + $password
     2029 * @uses PasswordHash::CheckPassword
     2030 *
     2031 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_check_password" filter.
     2032 * @param string $password Plaintext user's password
     2033 * @param string $hash Hash of the user's password to check against.
     2034 * @return bool False, if the $password does not match the hashed password
     2035 */
     2036function _wp_check_password( $existing = null, $password, $hash, $user_id = '' ) {
     2037        if ( null !== $existing )
     2038                return $existing;
     2039
     2040        global $wp_hasher;
     2041
     2042        // If the hash is still md5...
     2043        if ( strlen($hash) <= 32 ) {
     2044                $check = ( $hash == md5($password) );
     2045                if ( $check && $user_id ) {
     2046                        // Rehash using new hash.
     2047                        wp_set_password($password, $user_id);
     2048                        $hash = wp_hash_password($password);
     2049                }
     2050
     2051                return apply_filters('check_password', $check, $password, $hash, $user_id);
     2052        }
     2053
     2054        // If the stored hash is longer than an MD5, presume the
     2055        // new style phpass portable hash.
     2056        if ( empty($wp_hasher) ) {
     2057                require_once( ABSPATH . 'wp-includes/class-phpass.php');
     2058                // By default, use the portable hash from phpass
     2059                $wp_hasher = new PasswordHash(8, TRUE);
     2060        }
     2061
     2062        $check = $wp_hasher->CheckPassword($password, $hash);
     2063
     2064        return apply_filters('check_password', $check, $password, $hash, $user_id);
     2065}
     2066
     2067/**
     2068 * Generates a random password drawn from the defined set of characters.
     2069 *
     2070 * This function should not be used directly. Use the pluggable version instead.
     2071 * @see wp_generate_password()
     2072 *
     2073 * @since 2.8.0
     2074 *
     2075 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_generate_password" filter.
     2076 * @param int $length The length of password to generate
     2077 * @param bool $special_chars Whether to include standard special characters
     2078 * @return string The random password
     2079 **/
     2080function _wp_generate_password( $existing = null, $length = 12, $special_chars = true ) {
     2081        if ( null !== $existing )
     2082                return $existing;
     2083
     2084        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
     2085        if ( $special_chars )
     2086                $chars .= '!@#$%^&*()';
     2087
     2088        $password = '';
     2089        for ( $i = 0; $i < $length; $i++ )
     2090                $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1);
     2091        return $password;
     2092}
     2093
     2094/**
     2095 * Generates a random number
     2096 *
     2097 * This function should not be used directly. Use the pluggable version instead.
     2098 * @see wp_rand()
     2099 *
     2100 * @since 2.8.0
     2101 *
     2102 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_rand" filter.
     2103 * @param int $min Lower limit for the generated number (optional, default is 0)
     2104 * @param int $max Upper limit for the generated number (optional, default is 4294967295)
     2105 * @return int A random number between min and max
     2106 */
     2107function _wp_rand( $existing = null, $min = 0, $max = 0 ) {
     2108        if ( null !== $existing )
     2109                return $existing;
     2110
     2111        global $rnd_value;
     2112
     2113        $seed = get_transient('random_seed');
     2114
     2115        // Reset $rnd_value after 14 uses
     2116        // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
     2117        if ( strlen($rnd_value) < 8 ) {
     2118                $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
     2119                $rnd_value .= sha1($rnd_value);
     2120                $rnd_value .= sha1($rnd_value . $seed);
     2121                $seed = md5($seed . $rnd_value);
     2122                set_transient('random_seed', $seed);
     2123        }
     2124
     2125        // Take the first 8 digits for our value
     2126        $value = substr($rnd_value, 0, 8);
     2127
     2128        // Strip the first eight, leaving the remainder for the next call to wp_rand().
     2129        $rnd_value = substr($rnd_value, 8);
     2130
     2131        $value = abs(hexdec($value));
     2132
     2133        // Reduce the value to be within the min - max range
     2134        // 4294967295 = 0xffffffff = max random number
     2135        if ( $max != 0 )
     2136                $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1)));
     2137
     2138        return abs(intval($value));
     2139}
     2140
     2141/**
    17582142 * Retrieve or display referer hidden field for forms.
    17592143 *
    17602144 * The referer link is the current Request URI from the server super global. The
     
    18372221}
    18382222
    18392223/**
     2224 * Makes sure that a user was referred from another admin page.
     2225 *
     2226 * To avoid security exploits.
     2227 *
     2228 * This function should not be used directly. Use the pluggable version instead.
     2229 * @see check_admin_referer()
     2230 *
     2231 * @since 2.8.0
     2232 * @uses do_action() Calls 'check_admin_referer' on $action.
     2233 *
     2234 * @param mixed $existing Any existing data provided by another function in the "pluggable-check_admin_referer" filter.
     2235 * @param string $action Action nonce
     2236 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
     2237 */
     2238function _check_admin_referer( $existing = null, $action = -1, $query_arg = '_wpnonce' ) {
     2239        if ( null !== $existing )
     2240                return $existing;
     2241
     2242        $adminurl = strtolower(admin_url());
     2243        $referer = strtolower(wp_get_referer());
     2244        $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
     2245        if ( !$result && !(-1 == $action && strpos($referer, $adminurl) !== false) ) {
     2246                wp_nonce_ays($action);
     2247                die();
     2248        }
     2249        do_action('check_admin_referer', $action, $result);
     2250        return $result;
     2251}
     2252
     2253/**
     2254 * Verifies the AJAX request to prevent processing requests external of the blog.
     2255 *
     2256 * This function should not be used directly. Use the pluggable version instead.
     2257 * @see check_ajax_referer()
     2258 *
     2259 * @since 2.8.0
     2260 *
     2261 * @param mixed $existing Any existing data provided by another function in the "pluggable-check_ajax_referer" filter.
     2262 * @param string $action Action nonce
     2263 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
     2264 */
     2265function _check_ajax_referer( $existing = null, $action = -1, $query_arg = false, $die = true ) {
     2266        if ( null !== $existing )
     2267                return $existing;
     2268
     2269        if ( $query_arg )
     2270                $nonce = $_REQUEST[$query_arg];
     2271        else
     2272                $nonce = $_REQUEST['_ajax_nonce'] ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce'];
     2273
     2274        $result = wp_verify_nonce( $nonce, $action );
     2275
     2276        if ( $die && false == $result )
     2277                die('-1');
     2278
     2279        do_action('check_ajax_referer', $action, $result);
     2280
     2281        return $result;
     2282}
     2283
     2284/**
     2285 * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
     2286 *
     2287 * This function should not be used directly. Use the pluggable version instead.
     2288 * @see wp_redirect()
     2289 *
     2290 * @link http://support.microsoft.com/kb/q176113/
     2291 * @since 2.8.0
     2292 * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
     2293 *
     2294 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_redirect" filter.
     2295 * @param string $location The path to redirect to
     2296 * @param int $status Status code to use
     2297 * @return bool False if $location is not set
     2298 */
     2299function _wp_redirect( $existing = null, $location, $status = 302 ) {
     2300        if ( null !== $existing )
     2301                return $existing;
     2302
     2303        global $is_IIS;
     2304
     2305        $location = apply_filters('wp_redirect', $location, $status);
     2306        $status = apply_filters('wp_redirect_status', $status, $location);
     2307
     2308        if ( !$location ) // allows the wp_redirect filter to cancel a redirect
     2309                return false;
     2310
     2311        $location = wp_sanitize_redirect($location);
     2312
     2313        if ( $is_IIS ) {
     2314                header("Refresh: 0;url=$location");
     2315        } else {
     2316                if ( php_sapi_name() != 'cgi-fcgi' )
     2317                        status_header($status); // This causes problems on IIS and some FastCGI setups
     2318                header("Location: $location");
     2319        }
     2320}
     2321
     2322/**
     2323 * Sanitizes a URL for use in a redirect.
     2324 *
     2325 * This function should not be used directly. Use the pluggable version instead.
     2326 * @see wp_sanitize_redirect()
     2327 *
     2328 * @since 2.8.0
     2329 *
     2330 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_sanitize_redirect" filter.
     2331 * @param string $location The path to redirect to
     2332 * @return string redirect-sanitized URL
     2333 **/
     2334function _wp_sanitize_redirect( $existing = null, $location ) {
     2335        if ( null !== $existing )
     2336                return $existing;
     2337
     2338        $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location);
     2339        $location = wp_kses_no_null($location);
     2340
     2341        // remove %0d and %0a from location
     2342        $strip = array('%0d', '%0a');
     2343        $found = true;
     2344        while ($found) {
     2345                $found = false;
     2346                foreach( (array) $strip as $val ) {
     2347                        while(strpos($location, $val) !== false) {
     2348                                $found = true;
     2349                                $location = str_replace($val, '', $location);
     2350                        }
     2351                }
     2352        }
     2353        return $location;
     2354}
     2355
     2356/**
     2357 * Performs a safe (local) redirect, using wp_redirect().
     2358 *
     2359 * Checks whether the $location is using an allowed host, if it has an absolute
     2360 * path. A plugin can therefore set or remove allowed host(s) to or from the
     2361 * list.
     2362 *
     2363 * If the host is not allowed, then the redirect is to wp-admin on the siteurl
     2364 * instead. This prevents malicious redirects which redirect to another host,
     2365 * but only used in a few places.
     2366 *
     2367 * This function should not be used directly. Use the pluggable version instead.
     2368 * @see wp_safe_redirect()
     2369 *
     2370 * @since 2.8.0
     2371 * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing
     2372 *              WordPress host string and $location host string.
     2373 *
     2374 * @return void Does not return anything
     2375 **/
     2376function _wp_safe_redirect( $location, $status = 302 ) {
     2377        // Need to look at the URL the way it will end up in wp_redirect()
     2378        $location = wp_sanitize_redirect($location);
     2379
     2380        // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
     2381        if ( substr($location, 0, 2) == '//' )
     2382                $location = 'http:' . $location;
     2383
     2384        // In PHP5 parse_url may fail if the URL query part contains http://, bug #38143
     2385        $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location;
     2386
     2387        $lp  = parse_url($test);
     2388        $wpp = parse_url(get_option('home'));
     2389
     2390        $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : '');
     2391
     2392        if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) )
     2393                $location = admin_url();
     2394
     2395        wp_redirect($location, $status);
     2396}
     2397
     2398/**
    18402399 * Recursive directory creation based on full path.
    18412400 *
    18422401 * Will attempt to set permissions on folders.
     
    31463705        return $structure;
    31473706}
    31483707
     3708/**
     3709 * Send mail, similar to PHP's mail
     3710 *
     3711 * A true return value does not automatically mean that the user received the
     3712 * email successfully. It just only means that the method used was able to
     3713 * process the request without any errors.
     3714 *
     3715 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
     3716 * creating a from address like 'Name <email@address.com>' when both are set. If
     3717 * just 'wp_mail_from' is set, then just the email address will be used with no
     3718 * name.
     3719 *
     3720 * The default content type is 'text/plain' which does not allow using HTML.
     3721 * However, you can set the content type of the email by using the
     3722 * 'wp_mail_content_type' filter.
     3723 *
     3724 * The default charset is based on the charset used on the blog. The charset can
     3725 * be set using the 'wp_mail_charset' filter.
     3726 *
     3727 * This function should not be used directly. Use the pluggable version instead.
     3728 * @see wp_mail()
     3729 *
     3730 * @since 2.8.0
     3731 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
     3732 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
     3733 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
     3734 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
     3735 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
     3736 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
     3737 *              phpmailer object.
     3738 * @uses PHPMailer
     3739 *
     3740 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_mail" filter.
     3741 * @param string $to Email address to send message
     3742 * @param string $subject Email subject
     3743 * @param string $message Message contents
     3744 * @param string|array $headers Optional. Additional headers.
     3745 * @param string|array $attachments Optional. Files to attach.
     3746 * @return bool Whether the email contents were sent successfully.
     3747 */
     3748function _wp_mail( $existing = null, $to, $subject, $message, $headers = '', $attachments = array() ) {
     3749        if ( null !== $existing )
     3750                return $existing;
    31493751
     3752        // Compact the input, apply the filters, and extract them back out
     3753        extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) );
     3754
     3755        if ( !is_array($attachments) )
     3756                $attachments = explode( "\n", $attachments );
     3757
     3758        global $phpmailer;
     3759
     3760        // (Re)create it, if it's gone missing
     3761        if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
     3762                require_once ABSPATH . WPINC . '/class-phpmailer.php';
     3763                require_once ABSPATH . WPINC . '/class-smtp.php';
     3764                $phpmailer = new PHPMailer();
     3765        }
     3766
     3767        // Headers
     3768        if ( empty( $headers ) ) {
     3769                $headers = array();
     3770        } else {
     3771                if ( !is_array( $headers ) ) {
     3772                        // Explode the headers out, so this function can take both
     3773                        // string headers and an array of headers.
     3774                        $tempheaders = (array) explode( "\n", $headers );
     3775                } else {
     3776                        $tempheaders = $headers;
     3777                }
     3778                $headers = array();
     3779
     3780                // If it's actually got contents
     3781                if ( !empty( $tempheaders ) ) {
     3782                        // Iterate through the raw headers
     3783                        foreach ( (array) $tempheaders as $header ) {
     3784                                if ( strpos($header, ':') === false ) {
     3785                                        if ( false !== stripos( $header, 'boundary=' ) ) {
     3786                                                $parts = preg_split('/boundary=/i', trim( $header ) );
     3787                                                $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
     3788                                        }
     3789                                        continue;
     3790                                }
     3791                                // Explode them out
     3792                                list( $name, $content ) = explode( ':', trim( $header ), 2 );
     3793
     3794                                // Cleanup crew
     3795                                $name = trim( $name );
     3796                                $content = trim( $content );
     3797
     3798                                // Mainly for legacy -- process a From: header if it's there
     3799                                if ( 'from' == strtolower($name) ) {
     3800                                        if ( strpos($content, '<' ) !== false ) {
     3801                                                // So... making my life hard again?
     3802                                                $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
     3803                                                $from_name = str_replace( '"', '', $from_name );
     3804                                                $from_name = trim( $from_name );
     3805
     3806                                                $from_email = substr( $content, strpos( $content, '<' ) + 1 );
     3807                                                $from_email = str_replace( '>', '', $from_email );
     3808                                                $from_email = trim( $from_email );
     3809                                        } else {
     3810                                                $from_email = trim( $content );
     3811                                        }
     3812                                } elseif ( 'content-type' == strtolower($name) ) {
     3813                                        if ( strpos( $content,';' ) !== false ) {
     3814                                                list( $type, $charset ) = explode( ';', $content );
     3815                                                $content_type = trim( $type );
     3816                                                if ( false !== stripos( $charset, 'charset=' ) ) {
     3817                                                        $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) );
     3818                                                } elseif ( false !== stripos( $charset, 'boundary=' ) ) {
     3819                                                        $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) );
     3820                                                        $charset = '';
     3821                                                }
     3822                                        } else {
     3823                                                $content_type = trim( $content );
     3824                                        }
     3825                                } elseif ( 'cc' == strtolower($name) ) {
     3826                                        $cc = explode(",", $content);
     3827                                } elseif ( 'bcc' == strtolower($name) ) {
     3828                                        $bcc = explode(",", $content);
     3829                                } else {
     3830                                        // Add it to our grand headers array
     3831                                        $headers[trim( $name )] = trim( $content );
     3832                                }
     3833                        }
     3834                }
     3835        }
     3836
     3837        // Empty out the values that may be set
     3838        $phpmailer->ClearAddresses();
     3839        $phpmailer->ClearAllRecipients();
     3840        $phpmailer->ClearAttachments();
     3841        $phpmailer->ClearBCCs();
     3842        $phpmailer->ClearCCs();
     3843        $phpmailer->ClearCustomHeaders();
     3844        $phpmailer->ClearReplyTos();
     3845
     3846        // From email and name
     3847        // If we don't have a name from the input headers
     3848        if ( !isset( $from_name ) ) {
     3849                $from_name = 'WordPress';
     3850        }
     3851
     3852        /* If we don't have an email from the input headers default to wordpress@$sitename
     3853         * Some hosts will block outgoing mail from this address if it doesn't exist but
     3854         * there's no easy alternative. Defaulting to admin_email might appear to be another
     3855         * option but some hosts may refuse to relay mail from an unknown domain. See
     3856         * http://trac.wordpress.org/ticket/5007.
     3857         */
     3858
     3859        if ( !isset( $from_email ) ) {
     3860                // Get the site domain and get rid of www.
     3861                $sitename = strtolower( $_SERVER['SERVER_NAME'] );
     3862                if ( substr( $sitename, 0, 4 ) == 'www.' ) {
     3863                        $sitename = substr( $sitename, 4 );
     3864                }
     3865
     3866                $from_email = 'wordpress@' . $sitename;
     3867        }
     3868
     3869        // Plugin authors can override the potentially troublesome default
     3870        $phpmailer->From = apply_filters( 'wp_mail_from', $from_email );
     3871        $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
     3872
     3873        // Set destination address
     3874        $phpmailer->AddAddress( $to );
     3875
     3876        // Set mail's subject and body
     3877        $phpmailer->Subject = $subject;
     3878        $phpmailer->Body = $message;
     3879
     3880        // Add any CC and BCC recipients
     3881        if ( !empty($cc) ) {
     3882                foreach ( (array) $cc as $recipient ) {
     3883                        $phpmailer->AddCc( trim($recipient) );
     3884                }
     3885        }
     3886        if ( !empty($bcc) ) {
     3887                foreach ( (array) $bcc as $recipient) {
     3888                        $phpmailer->AddBcc( trim($recipient) );
     3889                }
     3890        }
     3891
     3892        // Set to use PHP's mail()
     3893        $phpmailer->IsMail();
     3894
     3895        // Set Content-Type and charset
     3896        // If we don't have a content-type from the input headers
     3897        if ( !isset( $content_type ) ) {
     3898                $content_type = 'text/plain';
     3899        }
     3900
     3901        $content_type = apply_filters( 'wp_mail_content_type', $content_type );
     3902
     3903        $phpmailer->ContentType = $content_type;
     3904
     3905        // Set whether it's plaintext or not, depending on $content_type
     3906        if ( $content_type == 'text/html' ) {
     3907                $phpmailer->IsHTML( true );
     3908        }
     3909
     3910        // If we don't have a charset from the input headers
     3911        if ( !isset( $charset ) ) {
     3912                $charset = get_bloginfo( 'charset' );
     3913        }
     3914
     3915        // Set the content-type and charset
     3916        $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
     3917
     3918        // Set custom headers
     3919        if ( !empty( $headers ) ) {
     3920                foreach( (array) $headers as $name => $content ) {
     3921                        $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
     3922                }
     3923                if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) {
     3924                        $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
     3925                }
     3926        }
     3927
     3928        if ( !empty( $attachments ) ) {
     3929                foreach ( $attachments as $attachment ) {
     3930                        $phpmailer->AddAttachment($attachment);
     3931                }
     3932        }
     3933
     3934        do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
     3935
     3936        // Send!
     3937        $result = @$phpmailer->Send();
     3938
     3939        return $result;
     3940}
     3941
     3942/**
     3943 * Notify an author of a comment/trackback/pingback to one of their posts.
     3944 *
     3945 * This function should not be used directly. Use the pluggable version instead.
     3946 * @see wp_notify_postauthor()
     3947 *
     3948 * @since 2.8.0
     3949 *
     3950 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_notify_postauthor" filter.
     3951 * @param int $comment_id Comment ID
     3952 * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback'
     3953 * @return bool False if user email does not exist. True on completion.
     3954 */
     3955function _wp_notify_postauthor( $existing = null, $comment_id, $comment_type = '' ) {
     3956        if ( null !== $existing )
     3957                return $existing;
     3958
     3959        $comment      = get_comment($comment_id);
     3960        $post         = get_post($comment->comment_post_ID);
     3961        $user         = get_userdata( $post->post_author );
     3962        $current_user = wp_get_current_user();
     3963       
     3964        if ( $current_user->ID == $user->ID ) return false; // The author moderated a comment on his own post
     3965
     3966        if ('' == $user->user_email) return false; // If there's no email to send the comment to
     3967
     3968        $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
     3969
     3970        $blogname = get_option('blogname');
     3971
     3972        if ( empty( $comment_type ) ) $comment_type = 'comment';
     3973
     3974        if ('comment' == $comment_type) {
     3975                $notify_message  = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
     3976                $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     3977                $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
     3978                $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     3979                $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
     3980                $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
     3981                $notify_message .= __('You can see all comments on this post here: ') . "\r\n";
     3982                $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title );
     3983        } elseif ('trackback' == $comment_type) {
     3984                $notify_message  = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
     3985                $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     3986                $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     3987                $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
     3988                $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n";
     3989                $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title );
     3990        } elseif ('pingback' == $comment_type) {
     3991                $notify_message  = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
     3992                $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     3993                $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     3994                $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n";
     3995                $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n";
     3996                $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title );
     3997        }
     3998        $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n";
     3999        $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
     4000        $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
     4001
     4002        $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
     4003
     4004        if ( '' == $comment->comment_author ) {
     4005                $from = "From: \"$blogname\" <$wp_email>";
     4006                if ( '' != $comment->comment_author_email )
     4007                        $reply_to = "Reply-To: $comment->comment_author_email";
     4008        } else {
     4009                $from = "From: \"$comment->comment_author\" <$wp_email>";
     4010                if ( '' != $comment->comment_author_email )
     4011                        $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>";
     4012        }
     4013
     4014        $message_headers = "$from\n"
     4015                . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
     4016
     4017        if ( isset($reply_to) )
     4018                $message_headers .= $reply_to . "\n";
     4019
     4020        $notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id);
     4021        $subject = apply_filters('comment_notification_subject', $subject, $comment_id);
     4022        $message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id);
     4023
     4024        @wp_mail($user->user_email, $subject, $notify_message, $message_headers);
     4025
     4026        return true;
     4027}
     4028
     4029/**
     4030 * Notifies the moderator of the blog about a new comment that is awaiting approval.
     4031 *
     4032 * This function should not be used directly. Use the pluggable version instead.
     4033 * @see wp_notify_moderator()
     4034 *
     4035 * @since 2.8.0
     4036 * @uses $wpdb
     4037 *
     4038 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_notify_moderator" filter.
     4039 * @param int $comment_id Comment ID
     4040 * @return bool Always returns true
     4041 */
     4042function _wp_notify_moderator( $existing = null, $comment_id ) {
     4043        if ( null !== $existing )
     4044                return $existing;
     4045
     4046        global $wpdb;
     4047
     4048        if ( get_option( 'moderation_notify' ) == 0 )
     4049                return true;
     4050
     4051        $comment = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_ID=%d LIMIT 1", $comment_id));
     4052        $post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID=%d LIMIT 1", $comment->comment_post_ID));
     4053
     4054        $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
     4055        $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'");
     4056
     4057        switch ($comment->comment_type) {
     4058                case 'trackback':
     4059                        $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";
     4060                        $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
     4061                        $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     4062                        $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     4063                        $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
     4064                        break;
     4065                case 'pingback':
     4066                        $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";
     4067                        $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
     4068                        $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     4069                        $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     4070                        $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
     4071                        break;
     4072                default: //Comments
     4073                        $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";
     4074                        $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
     4075                        $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
     4076                        $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
     4077                        $notify_message .= sprintf( __('URL     : %s'), $comment->comment_author_url ) . "\r\n";
     4078                        $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
     4079                        $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
     4080                        break;
     4081        }
     4082
     4083        $notify_message .= sprintf( __('Approve it: %s'),  admin_url("comment.php?action=mac&c=$comment_id") ) . "\r\n";
     4084        $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
     4085        $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
     4086
     4087        $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:',
     4088                'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n";
     4089        $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n";
     4090
     4091        $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_option('blogname'), $post->post_title );
     4092        $admin_email = get_option('admin_email');
     4093
     4094        $notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id);
     4095        $subject = apply_filters('comment_moderation_subject', $subject, $comment_id);
     4096
     4097        @wp_mail($admin_email, $subject, $notify_message);
     4098
     4099        return true;
     4100}
     4101
     4102/**
     4103 * Notify the blog admin of a user changing password, normally via email.
     4104 *
     4105 * This function should not be used directly. Use the pluggable version instead.
     4106 * @see wp_password_change_notification()
     4107 *
     4108 * @since 2.8.0
     4109 *
     4110 * @param object $user User Object
     4111 */
     4112function _wp_password_change_notification( &$user ) {
     4113        // send a copy of password change notification to the admin
     4114        // but check to see if it's the admin whose password we're changing, and skip this
     4115        if ( $user->user_email != get_option('admin_email') ) {
     4116                $message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n";
     4117                wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), get_option('blogname')), $message);
     4118        }
     4119}
     4120
     4121/**
     4122 * Notify the blog admin of a new user, normally via email.
     4123 *
     4124 * This function should not be used directly. Use the pluggable version instead.
     4125 * @see wp_new_user_notification()
     4126 *
     4127 * @since 2.8.0
     4128 *
     4129 * @param int $user_id User ID
     4130 * @param string $plaintext_pass Optional. The user's plaintext password
     4131 */
     4132function _wp_new_user_notification( $user_id, $plaintext_pass = '' ) {
     4133        $user = new WP_User($user_id);
     4134
     4135        $user_login = stripslashes($user->user_login);
     4136        $user_email = stripslashes($user->user_email);
     4137
     4138        $message  = sprintf(__('New user registration on your blog %s:'), get_option('blogname')) . "\r\n\r\n";
     4139        $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
     4140        $message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
     4141
     4142        @wp_mail( get_option('admin_email'), sprintf(__('[%s] New User Registration'), get_option('blogname') ), $message);
     4143
     4144        if ( empty($plaintext_pass) )
     4145                return;
     4146
     4147        $message  = sprintf(__('Username: %s'), $user_login) . "\r\n";
     4148        $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n";
     4149        $message .= wp_login_url() . "\r\n";
     4150
     4151        wp_mail( $user_email, sprintf( __('[%s] Your username and password'), get_option('blogname') ), $message );
     4152}
     4153
     4154/**
     4155 * Displays a human readable HTML representation of the difference between two strings.
     4156 *
     4157 * The Diff is available for getting the changes between versions. The output is
     4158 * HTML, so the primary use is for displaying the changes. If the two strings
     4159 * are equivalent, then an empty string will be returned.
     4160 *
     4161 * The arguments supported and can be changed are listed below.
     4162 *
     4163 * 'title' : Default is an empty string. Titles the diff in a manner compatible
     4164 *       with the output.
     4165 * 'title_left' : Default is an empty string. Change the HTML to the left of the
     4166 *       title.
     4167 * 'title_right' : Default is an empty string. Change the HTML to the right of
     4168 *       the title.
     4169 *
     4170 * This function should not be used directly. Use the pluggable version instead.
     4171 * @see wp_text_diff()
     4172 *
     4173 * @since 2.8.0
     4174 * @see wp_parse_args() Used to change defaults to user defined settings.
     4175 * @uses Text_Diff
     4176 * @uses WP_Text_Diff_Renderer_Table
     4177 *
     4178 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_text_diff" filter.
     4179 * @param string $left_string "old" (left) version of string
     4180 * @param string $right_string "new" (right) version of string
     4181 * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults.
     4182 * @return string Empty string if strings are equivalent or HTML with differences.
     4183 */
     4184function _wp_text_diff( $existing = null, $left_string, $right_string, $args = null ) {
     4185        if ( null !== $existing )
     4186                return $existing;
     4187
     4188        $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
     4189        $args = wp_parse_args( $args, $defaults );
     4190
     4191        if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) )
     4192                require( ABSPATH . WPINC . '/wp-diff.php' );
     4193
     4194        $left_string  = normalize_whitespace($left_string);
     4195        $right_string = normalize_whitespace($right_string);
     4196
     4197        $left_lines  = split("\n", $left_string);
     4198        $right_lines = split("\n", $right_string);
     4199
     4200        $text_diff = new Text_Diff($left_lines, $right_lines);
     4201        $renderer  = new WP_Text_Diff_Renderer_Table();
     4202        $diff = $renderer->render($text_diff);
     4203
     4204        if ( !$diff )
     4205                return '';
     4206
     4207        $r  = "<table class='diff'>\n";
     4208        $r .= "<col class='ltype' /><col class='content' /><col class='ltype' /><col class='content' />";
     4209
     4210        if ( $args['title'] || $args['title_left'] || $args['title_right'] )
     4211                $r .= "<thead>";
     4212        if ( $args['title'] )
     4213                $r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
     4214        if ( $args['title_left'] || $args['title_right'] ) {
     4215                $r .= "<tr class='diff-sub-title'>\n";
     4216                $r .= "\t<td></td><th>$args[title_left]</th>\n";
     4217                $r .= "\t<td></td><th>$args[title_right]</th>\n";
     4218                $r .= "</tr>\n";
     4219        }
     4220        if ( $args['title'] || $args['title_left'] || $args['title_right'] )
     4221                $r .= "</thead>\n";
     4222
     4223        $r .= "<tbody>\n$diff\n</tbody>\n";
     4224        $r .= "</table>";
     4225
     4226        return $r;
     4227}
     4228
    31504229?>
  • wp-includes/general-template.php

     
    20132013        return apply_filters( "get_the_generator_{$type}", $gen, $type );
    20142014}
    20152015
     2016/**
     2017 * Retrieve the avatar for a user who provided a user ID or email address.
     2018 *
     2019 * This function should not be used directly. Use the pluggable version instead.
     2020 * @see get_avatar()
     2021 *
     2022 * @since 2.8.0
     2023 *
     2024 * @param mixed $existing Any existing data provided by another function in the "pluggable-get_avatar" filter.
     2025 * @param int|string|object $id_or_email A user ID,  email address, or comment object
     2026 * @param int $size Size of the avatar image
     2027 * @param string $default URL to a default image to use if no avatar is available
     2028 * @param string $alt Alternate text to use in image tag. Defaults to blank
     2029 * @return string <img> tag for the user's avatar
     2030*/
     2031function _get_avatar( $existing = null, $id_or_email, $size = '96', $default = '', $alt = false ) {
     2032        if ( null !== $existing )
     2033                return $existing;
     2034
     2035        if ( ! get_option('show_avatars') )
     2036                return false;
     2037
     2038        if ( false === $alt)
     2039                $safe_alt = '';
     2040        else
     2041                $safe_alt = attr( $alt );
     2042
     2043        if ( !is_numeric($size) )
     2044                $size = '96';
     2045
     2046        $email = '';
     2047        if ( is_numeric($id_or_email) ) {
     2048                $id = (int) $id_or_email;
     2049                $user = get_userdata($id);
     2050                if ( $user )
     2051                        $email = $user->user_email;
     2052        } elseif ( is_object($id_or_email) ) {
     2053                if ( isset($id_or_email->comment_type) && '' != $id_or_email->comment_type && 'comment' != $id_or_email->comment_type )
     2054                        return false; // No avatar for pingbacks or trackbacks
     2055
     2056                if ( !empty($id_or_email->user_id) ) {
     2057                        $id = (int) $id_or_email->user_id;
     2058                        $user = get_userdata($id);
     2059                        if ( $user)
     2060                                $email = $user->user_email;
     2061                } elseif ( !empty($id_or_email->comment_author_email) ) {
     2062                        $email = $id_or_email->comment_author_email;
     2063                }
     2064        } else {
     2065                $email = $id_or_email;
     2066        }
     2067
     2068        if ( empty($default) ) {
     2069                $avatar_default = get_option('avatar_default');
     2070                if ( empty($avatar_default) )
     2071                        $default = 'mystery';
     2072                else
     2073                        $default = $avatar_default;
     2074        }
     2075
     2076        if ( is_ssl() )
     2077                $host = 'https://secure.gravatar.com';
     2078        else
     2079                $host = 'http://www.gravatar.com';
     2080
     2081        if ( 'mystery' == $default )
     2082                $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
     2083        elseif ( 'blank' == $default )
     2084                $default = includes_url('images/blank.gif');
     2085        elseif ( !empty($email) && 'gravatar_default' == $default )
     2086                $default = '';
     2087        elseif ( 'gravatar_default' == $default )
     2088                $default = "$host/avatar/s={$size}";
     2089        elseif ( empty($email) )
     2090                $default = "$host/avatar/?d=$default&amp;s={$size}";
     2091        elseif ( strpos($default, 'http://') === 0 )
     2092                $default = add_query_arg( 's', $size, $default );
     2093
     2094        if ( !empty($email) ) {
     2095                $out = "$host/avatar/";
     2096                $out .= md5( strtolower( $email ) );
     2097                $out .= '?s='.$size;
     2098                $out .= '&amp;d=' . urlencode( $default );
     2099
     2100                $rating = get_option('avatar_rating');
     2101                if ( !empty( $rating ) )
     2102                        $out .= "&amp;r={$rating}";
     2103
     2104                $avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
     2105        } else {
     2106                $avatar = "<img alt='{$safe_alt}' src='{$default}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
     2107        }
     2108
     2109        return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt);
     2110}
     2111
    20162112?>
  • wp-includes/pluggable.php

     
    1919 * @param string $name Optional. The user's username
    2020 * @return object returns wp_set_current_user()
    2121 */
    22 function set_current_user($id, $name = '') {
    23         return wp_set_current_user($id, $name);
     22function set_current_user( $id, $name = '' ) {
     23        return wp_set_current_user( $id, $name );
    2424}
    2525endif;
    2626
     
    3030 *
    3131 * Set $id to null and specify a name if you do not know a user's ID.
    3232 *
    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.
     33 * @see _wp_set_current_user()
    3634 *
    3735 * @since 2.0.3
    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.
    4036 *
    4137 * @param int $id User ID
    4238 * @param string $name User's username
    4339 * @return WP_User Current user User object
    4440 */
    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;
     41function wp_set_current_user( $id, $name = '' ) {
     42        return apply_filters( 'pluggable-wp_set_current_user', null, $id, $name );
    5843}
     44add_filter( 'pluggable-wp_set_current_user', '_wp_set_current_user', 10, 3 );
    5945endif;
    6046
    6147if ( !function_exists('wp_get_current_user') ) :
    6248/**
    6349 * Retrieve the current user object.
    6450 *
     51 * @see _wp_get_current_user()
     52 *
    6553 * @since 2.0.3
    6654 *
    6755 * @return WP_User Current user WP_User object
    6856 */
    6957function wp_get_current_user() {
    70         global $current_user;
    71 
    72         get_currentuserinfo();
    73 
    74         return $current_user;
     58        return apply_filters( 'pluggable-wp_get_current_user', null );
    7559}
     60add_filter( 'pluggable-wp_get_current_user', '_wp_get_current_user' );
    7661endif;
    7762
    7863if ( !function_exists('get_currentuserinfo') ) :
    7964/**
    8065 * Populate global variables with information about the currently logged in user.
    8166 *
    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.
     67 * @see _get_currentuserinfo()
    8568 *
    8669 * @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.
    8970 *
    90  * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set
     71 * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set.
    9172 */
    9273function 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);
     74        return apply_filters( 'pluggable-get_currentuserinfo', null );
    10975}
     76add_filter( 'pluggable-get_currentuserinfo', '_get_currentuserinfo' );
    11077endif;
    11178
    11279if ( !function_exists('get_userdata') ) :
    11380/**
    11481 * Retrieve user info by user ID.
    11582 *
     83 * @see _get_userdata()
     84 *
    11685 * @since 0.71
    11786 *
    11887 * @param int $user_id User ID
    11988 * @return bool|object False on failure, User DB row object
    12089 */
    12190function 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;
     91        return apply_filters( 'pluggable-get_userdata', null, $user_id );
    13992}
     93add_filter( 'pluggable-get_userdata', '_get_userdata', 10, 2 );
    14094endif;
    14195
    14296if ( !function_exists('get_user_by') ) :
    14397/**
    14498 * Retrieve user info by a given field
    14599 *
     100 * @see _get_user_by()
     101 *
    146102 * @since 2.8.0
    147103 *
    148104 * @param string $field The field to retrieve the user with.  id | slug | email | login
    149105 * @param int|string $value A value for $field.  A user ID, slug, email address, or login name.
    150106 * @return bool|object False on failure, User DB row object
    151107 */
    152 function get_user_by($field, $value) {
    153         global $wpdb;
    154 
    155         switch ($field) {
    156                 case 'id':
    157                         return get_userdata($value);
    158                         break;
    159                 case 'slug':
    160                         $user_id = wp_cache_get($value, 'userslugs');
    161                         $field = 'user_nicename';
    162                         break;
    163                 case 'email':
    164                         $user_id = wp_cache_get($value, 'useremail');
    165                         $field = 'user_email';
    166                         break;
    167                 case 'login':
    168                         $value = sanitize_user( $value );
    169                         $user_id = wp_cache_get($value, 'userlogins');
    170                         $field = 'user_login';
    171                         break;
    172                 default:
    173                         return false;
    174         }
    175 
    176          if ( false !== $user_id )
    177                 return get_userdata($user_id);
    178 
    179         if ( !$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE $field = %s", $value) ) )
    180                 return false;
    181 
    182         _fill_user($user);
    183 
    184         return $user;
     108function get_user_by( $field, $value ) {
     109        return apply_filters( 'pluggable-get_user_by', null, $field, $value );
    185110}
     111add_filter( 'pluggable-get_user_by', '_get_user_by', 10, 3 );
    186112endif;
    187113
    188114if ( !function_exists('get_userdatabylogin') ) :
     
    194120 * @param string $user_login User's username
    195121 * @return bool|object False on failure, User DB row object
    196122 */
    197 function get_userdatabylogin($user_login) {
    198         return get_user_by('login', $user_login);
     123function get_userdatabylogin( $user_login ) {
     124        return get_user_by( 'login', $user_login );
    199125}
    200126endif;
    201127
     
    208134 * @param string $email User's email address
    209135 * @return bool|object False on failure, User DB row object
    210136 */
    211 function get_user_by_email($email) {
    212         return get_user_by('email', $email);
     137function get_user_by_email( $email ) {
     138        return get_user_by( 'email', $email );
    213139}
    214140endif;
    215141
     
    217143/**
    218144 * Send mail, similar to PHP's mail
    219145 *
    220  * A true return value does not automatically mean that the user received the
    221  * email successfully. It just only means that the method used was able to
    222  * process the request without any errors.
     146 * @see _wp_mail()
    223147 *
    224  * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
    225  * creating a from address like 'Name <email@address.com>' when both are set. If
    226  * just 'wp_mail_from' is set, then just the email address will be used with no
    227  * name.
    228  *
    229  * The default content type is 'text/plain' which does not allow using HTML.
    230  * However, you can set the content type of the email by using the
    231  * 'wp_mail_content_type' filter.
    232  *
    233  * The default charset is based on the charset used on the blog. The charset can
    234  * be set using the 'wp_mail_charset' filter.
    235  *
    236148 * @since 1.2.1
    237  * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
    238  * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
    239  * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
    240  * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
    241  * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
    242  * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
    243  *              phpmailer object.
    244  * @uses PHPMailer
    245  * @
    246149 *
    247150 * @param string $to Email address to send message
    248151 * @param string $subject Email subject
     
    252155 * @return bool Whether the email contents were sent successfully.
    253156 */
    254157function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
    255         // Compact the input, apply the filters, and extract them back out
    256         extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) );
    257 
    258         if ( !is_array($attachments) )
    259                 $attachments = explode( "\n", $attachments );
    260 
    261         global $phpmailer;
    262 
    263         // (Re)create it, if it's gone missing
    264         if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
    265                 require_once ABSPATH . WPINC . '/class-phpmailer.php';
    266                 require_once ABSPATH . WPINC . '/class-smtp.php';
    267                 $phpmailer = new PHPMailer();
    268         }
    269 
    270         // Headers
    271         if ( empty( $headers ) ) {
    272                 $headers = array();
    273         } else {
    274                 if ( !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                 } else {
    279                         $tempheaders = $headers;
    280                 }
    281                 $headers = array();
    282 
    283                 // If it's actually got contents
    284                 if ( !empty( $tempheaders ) ) {
    285                         // Iterate through the raw headers
    286                         foreach ( (array) $tempheaders as $header ) {
    287                                 if ( strpos($header, ':') === false ) {
    288                                         if ( false !== stripos( $header, 'boundary=' ) ) {
    289                                                 $parts = preg_split('/boundary=/i', trim( $header ) );
    290                                                 $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
    291                                         }
    292                                         continue;
    293                                 }
    294                                 // Explode them out
    295                                 list( $name, $content ) = explode( ':', trim( $header ), 2 );
    296 
    297                                 // Cleanup crew
    298                                 $name = trim( $name );
    299                                 $content = trim( $content );
    300 
    301                                 // Mainly for legacy -- process a From: header if it's there
    302                                 if ( 'from' == strtolower($name) ) {
    303                                         if ( strpos($content, '<' ) !== false ) {
    304                                                 // So... making my life hard again?
    305                                                 $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
    306                                                 $from_name = str_replace( '"', '', $from_name );
    307                                                 $from_name = trim( $from_name );
    308 
    309                                                 $from_email = substr( $content, strpos( $content, '<' ) + 1 );
    310                                                 $from_email = str_replace( '>', '', $from_email );
    311                                                 $from_email = trim( $from_email );
    312                                         } else {
    313                                                 $from_email = trim( $content );
    314                                         }
    315                                 } elseif ( 'content-type' == strtolower($name) ) {
    316                                         if ( strpos( $content,';' ) !== false ) {
    317                                                 list( $type, $charset ) = explode( ';', $content );
    318                                                 $content_type = trim( $type );
    319                                                 if ( false !== stripos( $charset, 'charset=' ) ) {
    320                                                         $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) );
    321                                                 } elseif ( false !== stripos( $charset, 'boundary=' ) ) {
    322                                                         $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) );
    323                                                         $charset = '';
    324                                                 }
    325                                         } else {
    326                                                 $content_type = trim( $content );
    327                                         }
    328                                 } elseif ( 'cc' == strtolower($name) ) {
    329                                         $cc = explode(",", $content);
    330                                 } elseif ( 'bcc' == strtolower($name) ) {
    331                                         $bcc = explode(",", $content);
    332                                 } else {
    333                                         // Add it to our grand headers array
    334                                         $headers[trim( $name )] = trim( $content );
    335                                 }
    336                         }
    337                 }
    338         }
    339 
    340         // Empty out the values that may be set
    341         $phpmailer->ClearAddresses();
    342         $phpmailer->ClearAllRecipients();
    343         $phpmailer->ClearAttachments();
    344         $phpmailer->ClearBCCs();
    345         $phpmailer->ClearCCs();
    346         $phpmailer->ClearCustomHeaders();
    347         $phpmailer->ClearReplyTos();
    348 
    349         // From email and name
    350         // If we don't have a name from the input headers
    351         if ( !isset( $from_name ) ) {
    352                 $from_name = 'WordPress';
    353         }
    354 
    355         /* If we don't have an email from the input headers default to wordpress@$sitename
    356          * Some hosts will block outgoing mail from this address if it doesn't exist but
    357          * there's no easy alternative. Defaulting to admin_email might appear to be another
    358          * option but some hosts may refuse to relay mail from an unknown domain. See
    359          * http://trac.wordpress.org/ticket/5007.
    360          */
    361 
    362         if ( !isset( $from_email ) ) {
    363                 // Get the site domain and get rid of www.
    364                 $sitename = strtolower( $_SERVER['SERVER_NAME'] );
    365                 if ( substr( $sitename, 0, 4 ) == 'www.' ) {
    366                         $sitename = substr( $sitename, 4 );
    367                 }
    368 
    369                 $from_email = 'wordpress@' . $sitename;
    370         }
    371 
    372         // Plugin authors can override the potentially troublesome default
    373         $phpmailer->From = apply_filters( 'wp_mail_from', $from_email );
    374         $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
    375 
    376         // Set destination address
    377         $phpmailer->AddAddress( $to );
    378 
    379         // Set mail's subject and body
    380         $phpmailer->Subject = $subject;
    381         $phpmailer->Body = $message;
    382 
    383         // Add any CC and BCC recipients
    384         if ( !empty($cc) ) {
    385                 foreach ( (array) $cc as $recipient ) {
    386                         $phpmailer->AddCc( trim($recipient) );
    387                 }
    388         }
    389         if ( !empty($bcc) ) {
    390                 foreach ( (array) $bcc as $recipient) {
    391                         $phpmailer->AddBcc( trim($recipient) );
    392                 }
    393         }
    394 
    395         // Set to use PHP's mail()
    396         $phpmailer->IsMail();
    397 
    398         // Set Content-Type and charset
    399         // If we don't have a content-type from the input headers
    400         if ( !isset( $content_type ) ) {
    401                 $content_type = 'text/plain';
    402         }
    403 
    404         $content_type = apply_filters( 'wp_mail_content_type', $content_type );
    405 
    406         $phpmailer->ContentType = $content_type;
    407 
    408         // Set whether it's plaintext or not, depending on $content_type
    409         if ( $content_type == 'text/html' ) {
    410                 $phpmailer->IsHTML( true );
    411         }
    412 
    413         // If we don't have a charset from the input headers
    414         if ( !isset( $charset ) ) {
    415                 $charset = get_bloginfo( 'charset' );
    416         }
    417 
    418         // Set the content-type and charset
    419         $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
    420 
    421         // Set custom headers
    422         if ( !empty( $headers ) ) {
    423                 foreach( (array) $headers as $name => $content ) {
    424                         $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
    425                 }
    426                 if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) {
    427                         $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
    428                 }
    429         }
    430 
    431         if ( !empty( $attachments ) ) {
    432                 foreach ( $attachments as $attachment ) {
    433                         $phpmailer->AddAttachment($attachment);
    434                 }
    435         }
    436 
    437         do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
    438 
    439         // Send!
    440         $result = @$phpmailer->Send();
    441 
    442         return $result;
     158        return apply_filters( 'pluggable-wp_mail', null, $to, $subject, $message, $headers, $attachments );
    443159}
     160add_filter( 'pluggable-wp_mail', '_wp_mail', 10, 6 );
    444161endif;
    445162
    446163if ( !function_exists('wp_authenticate') ) :
    447164/**
    448165 * Checks a user's login information and logs them in if it checks out.
    449166 *
     167 * @see _wp_authenticate()
     168 *
    450169 * @since 2.5.0
    451170 *
    452171 * @param string $username User's username
    453172 * @param string $password User's password
    454173 * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object.
    455174 */
    456 function wp_authenticate($username, $password) {
    457         $username = sanitize_user($username);
    458         $password = trim($password);
    459 
    460         $user = apply_filters('authenticate', null, $username, $password);
    461 
    462         if ( $user == null ) {
    463                 // TODO what should the error message be? (Or would these even happen?)
    464                 // Only needed if all authentication handlers fail to return anything.
    465                 $user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
    466         }
    467 
    468         $ignore_codes = array('empty_username', 'empty_password');
    469 
    470         if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) {
    471                 do_action('wp_login_failed', $username);
    472         }
    473 
    474         return $user;
     175function wp_authenticate( $username, $password ) {
     176        return apply_filters( 'pluggable-wp_authenticate', null, $username, $password );
    475177}
     178add_filter( 'pluggable-wp_authenticate', '_wp_authenticate', 10, 3 );
    476179endif;
    477180
    478181if ( !function_exists('wp_logout') ) :
    479182/**
    480183 * Log the current user out.
    481184 *
     185 * @see _wp_logout()
     186 *
    482187 * @since 2.5.0
    483188 */
    484189function wp_logout() {
    485         wp_clear_auth_cookie();
    486         do_action('wp_logout');
     190        do_action( 'pluggable-wp_logout' );
    487191}
     192add_action( 'pluggable-wp_logout', '_wp_logout' );
    488193endif;
    489194
    490195if ( !function_exists('wp_validate_auth_cookie') ) :
    491196/**
    492197 * Validates authentication cookie.
    493198 *
    494  * The checks include making sure that the authentication cookie is set and
    495  * pulling in the contents (if $cookie is not used).
     199 * @see _wp_authenticate()
    496200 *
    497  * Makes sure the cookie is not expired. Verifies the hash in cookie is what is
    498  * should be and compares the two.
    499  *
    500201 * @since 2.5
    501202 *
    502203 * @param string $cookie Optional. If used, will validate contents instead of cookie's
    503204 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
    504205 * @return bool|int False if invalid cookie, User ID if valid.
    505206 */
    506 function wp_validate_auth_cookie($cookie = '', $scheme = '') {
    507         if ( ! $cookie_elements = wp_parse_auth_cookie($cookie, $scheme) ) {
    508                 do_action('auth_cookie_malformed', $cookie, $scheme);
    509                 return false;
    510         }
    511 
    512         extract($cookie_elements, EXTR_OVERWRITE);
    513 
    514         $expired = $expiration;
    515 
    516         // Allow a grace period for POST and AJAX requests
    517         if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] )
    518                 $expired += 3600;
    519 
    520         // Quick check to see if an honest cookie has expired
    521         if ( $expired < time() ) {
    522                 do_action('auth_cookie_expired', $cookie_elements);
    523                 return false;
    524         }
    525 
    526         $user = get_userdatabylogin($username);
    527         if ( ! $user ) {
    528                 do_action('auth_cookie_bad_username', $cookie_elements);
    529                 return false;
    530         }
    531 
    532         $pass_frag = substr($user->user_pass, 8, 4);
    533 
    534         $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);
    535         $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
    536 
    537         if ( $hmac != $hash ) {
    538                 do_action('auth_cookie_bad_hash', $cookie_elements);
    539                 return false;
    540         }
    541 
    542         do_action('auth_cookie_valid', $cookie_elements, $user);
    543 
    544         return $user->ID;
     207function wp_validate_auth_cookie( $cookie = '', $scheme = '' ) {
     208        return apply_filters( 'pluggable-wp_validate_auth_cookie', null, $cookie, $scheme );
    545209}
     210add_filter( 'pluggable-wp_validate_auth_cookie', '_wp_validate_auth_cookie', 10, 3 );
    546211endif;
    547212
    548213if ( !function_exists('wp_generate_auth_cookie') ) :
    549214/**
    550215 * Generate authentication cookie contents.
    551216 *
     217 * @see _wp_generate_auth_cookie()
     218 *
    552219 * @since 2.5
    553  * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID
    554  *              and expiration of cookie.
    555220 *
    556221 * @param int $user_id User ID
    557222 * @param int $expiration Cookie expiration in seconds
    558223 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
    559224 * @return string Authentication cookie contents
    560225 */
    561 function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') {
    562         $user = get_userdata($user_id);
    563 
    564         $pass_frag = substr($user->user_pass, 8, 4);
    565 
    566         $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);
    567         $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);
    568 
    569         $cookie = $user->user_login . '|' . $expiration . '|' . $hash;
    570 
    571         return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
     226function wp_generate_auth_cookie( $user_id, $expiration, $scheme = 'auth' ) {
     227        return apply_filters( 'pluggable-wp_generate_auth_cookie', null, $user_id, $expiration, $scheme );
    572228}
     229add_filter( 'pluggable-wp_generate_auth_cookie', '_wp_generate_auth_cookie', 10, 4 );
    573230endif;
    574231
    575232if ( !function_exists('wp_parse_auth_cookie') ) :
    576233/**
    577234 * Parse a cookie into its components
    578235 *
     236 * @see _wp_parse_auth_cookie()
     237 *
    579238 * @since 2.7
    580239 *
    581240 * @param string $cookie
    582241 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
    583242 * @return array Authentication cookie components
    584243 */
    585 function wp_parse_auth_cookie($cookie = '', $scheme = '') {
    586         if ( empty($cookie) ) {
    587                 switch ($scheme){
    588                         case 'auth':
    589                                 $cookie_name = AUTH_COOKIE;
    590                                 break;
    591                         case 'secure_auth':
    592                                 $cookie_name = SECURE_AUTH_COOKIE;
    593                                 break;
    594                         case "logged_in":
    595                                 $cookie_name = LOGGED_IN_COOKIE;
    596                                 break;
    597                         default:
    598                                 if ( is_ssl() ) {
    599                                         $cookie_name = SECURE_AUTH_COOKIE;
    600                                         $scheme = 'secure_auth';
    601                                 } else {
    602                                         $cookie_name = AUTH_COOKIE;
    603                                         $scheme = 'auth';
    604                                 }
    605             }
    606 
    607                 if ( empty($_COOKIE[$cookie_name]) )
    608                         return false;
    609                 $cookie = $_COOKIE[$cookie_name];
    610         }
    611 
    612         $cookie_elements = explode('|', $cookie);
    613         if ( count($cookie_elements) != 3 )
    614                 return false;
    615 
    616         list($username, $expiration, $hmac) = $cookie_elements;
    617 
    618         return compact('username', 'expiration', 'hmac', 'scheme');
     244function wp_parse_auth_cookie( $cookie = '', $scheme = '' ) {
     245        return apply_filters( 'pluggable-wp_parse_auth_cookie', null, $cookie, $scheme );
    619246}
     247add_filter( 'pluggable-wp_parse_auth_cookie', '_wp_parse_auth_cookie', 10, 3 );
    620248endif;
    621249
    622250if ( !function_exists('wp_set_auth_cookie') ) :
     
    627255 * default the cookie is kept without remembering is two days. When $remember is
    628256 * set, the cookies will be kept for 14 days or two weeks.
    629257 *
     258 * @see _wp_set_auth_cookie()
     259 *
    630260 * @since 2.5
    631261 *
    632262 * @param int $user_id User ID
    633263 * @param bool $remember Whether to remember the user or not
    634264 */
    635 function wp_set_auth_cookie($user_id, $remember = false, $secure = '') {
    636         if ( $remember ) {
    637                 $expiration = $expire = time() + apply_filters('auth_cookie_expiration', 1209600, $user_id, $remember);
    638         } else {
    639                 $expiration = time() + apply_filters('auth_cookie_expiration', 172800, $user_id, $remember);
    640                 $expire = 0;
    641         }
    642 
    643         if ( '' === $secure )
    644                 $secure = is_ssl() ? true : false;
    645 
    646         if ( $secure ) {
    647                 $auth_cookie_name = SECURE_AUTH_COOKIE;
    648                 $scheme = 'secure_auth';
    649         } else {
    650                 $auth_cookie_name = AUTH_COOKIE;
    651                 $scheme = 'auth';
    652         }
    653 
    654         $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme);
    655         $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in');
    656 
    657         do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme);
    658         do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in');
    659 
    660         // Set httponly if the php version is >= 5.2.0
    661         if ( version_compare(phpversion(), '5.2.0', 'ge') ) {
    662                 setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true);
    663                 setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true);
    664                 setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, false, true);
    665                 if ( COOKIEPATH != SITECOOKIEPATH )
    666                         setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, false, true);
    667         } else {
    668                 $cookie_domain = COOKIE_DOMAIN;
    669                 if ( !empty($cookie_domain) )
    670                         $cookie_domain .= '; HttpOnly';
    671                 setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, $cookie_domain, $secure);
    672                 setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, $cookie_domain, $secure);
    673                 setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, $cookie_domain);
    674                 if ( COOKIEPATH != SITECOOKIEPATH )
    675                         setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, $cookie_domain);
    676         }
     265function wp_set_auth_cookie( $user_id, $remember = false, $secure = '' ) {
     266        do_action( 'pluggable-wp_set_auth_cookie', $user_id, $remember, $secure );
    677267}
     268add_action( 'pluggable-wp_set_auth_cookie', '_wp_set_auth_cookie', 10, 3 );
    678269endif;
    679270
    680271if ( !function_exists('wp_clear_auth_cookie') ) :
    681272/**
    682273 * Removes all of the cookies associated with authentication.
    683274 *
     275 * @see _wp_clear_auth_cookie()
     276 *
    684277 * @since 2.5
    685278 */
    686279function wp_clear_auth_cookie() {
    687         do_action('clear_auth_cookie');
    688 
    689         setcookie(AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
    690         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
    691         setcookie(AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
    692         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
    693         setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
    694         setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
    695 
    696         // Old cookies
    697         setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
    698         setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
    699         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
    700         setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
    701 
    702         // Even older cookies
    703         setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
    704         setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
    705         setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
    706         setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     280        do_action( 'pluggable-wp_clear_auth_cookie' );
    707281}
     282add_action( 'pluggable-wp_clear_auth_cookie', '_wp_clear_auth_cookie' );
    708283endif;
    709284
    710285if ( !function_exists('is_user_logged_in') ) :
    711286/**
    712287 * Checks if the current visitor is a logged in user.
    713288 *
     289 * @see _is_user_logged_in()
     290 *
    714291 * @since 2.0.0
    715292 *
    716293 * @return bool True if user is logged in, false if not logged in.
    717294 */
    718295function is_user_logged_in() {
    719         $user = wp_get_current_user();
    720 
    721         if ( $user->id == 0 )
    722                 return false;
    723 
    724         return true;
     296        return apply_filters( 'pluggable-is_user_logged_in', null );
    725297}
     298add_filter( 'pluggable-is_user_logged_in', '_is_user_logged_in' );
    726299endif;
    727300
    728301if ( !function_exists('auth_redirect') ) :
    729302/**
    730303 * Checks if a user is logged in, if not it redirects them to the login page.
    731304 *
     305 * @see _auth_redirect()
     306 *
    732307 * @since 1.5
    733308 */
    734309function auth_redirect() {
    735         // Checks if a user is logged in, if not redirects them to the login page
    736 
    737         if ( is_ssl() || force_ssl_admin() )
    738                 $secure = true;
    739         else
    740                 $secure = false;
    741 
    742         // If https is required and request is http, redirect
    743         if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) {
    744                 if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
    745                         wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
    746                         exit();
    747                 } else {
    748                         wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    749                         exit();
    750                 }
    751         }
    752 
    753         if ( $user_id = wp_validate_auth_cookie() ) {
    754                 do_action('auth_redirect', $user_id);
    755 
    756                 // If the user wants ssl but the session is not ssl, redirect.
    757                 if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) {
    758                         if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
    759                                 wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
    760                                 exit();
    761                         } else {
    762                                 wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    763                                 exit();
    764                         }
    765                 }
    766 
    767                 return;  // The cookie is good so we're done
    768         }
    769 
    770         // The cookie is no good so force login
    771         nocache_headers();
    772 
    773         if ( is_ssl() )
    774                 $proto = 'https://';
    775         else
    776                 $proto = 'http://';
    777 
    778         $redirect = ( strpos($_SERVER['REQUEST_URI'], '/options.php') && wp_get_referer() ) ? wp_get_referer() : $proto . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    779 
    780         $login_url = wp_login_url($redirect);
    781 
    782         wp_redirect($login_url);
    783         exit();
     310        do_action( 'pluggable-auth_redirect' );
    784311}
     312add_action( 'pluggable-auth_redirect', '_auth_redirect' );
    785313endif;
    786314
    787315if ( !function_exists('check_admin_referer') ) :
     
    790318 *
    791319 * To avoid security exploits.
    792320 *
     321 * @see _check_admin_referer()
     322 *
    793323 * @since 1.2.0
    794  * @uses do_action() Calls 'check_admin_referer' on $action.
    795324 *
    796325 * @param string $action Action nonce
    797326 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
    798327 */
    799 function check_admin_referer($action = -1, $query_arg = '_wpnonce') {
    800         $adminurl = strtolower(admin_url());
    801         $referer = strtolower(wp_get_referer());
    802         $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
    803         if ( !$result && !(-1 == $action && strpos($referer, $adminurl) !== false) ) {
    804                 wp_nonce_ays($action);
    805                 die();
    806         }
    807         do_action('check_admin_referer', $action, $result);
    808         return $result;
    809 }endif;
     328function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
     329        return apply_filters( 'pluggable-check_admin_referer', null, $action, $query_arg );
     330}
     331add_filter( 'pluggable-check_admin_referer', '_check_admin_referer', 10, 3 );
     332endif;
    810333
    811334if ( !function_exists('check_ajax_referer') ) :
    812335/**
    813336 * Verifies the AJAX request to prevent processing requests external of the blog.
    814337 *
     338 * @see _check_ajax_referer()
     339 *
    815340 * @since 2.0.3
    816341 *
    817342 * @param string $action Action nonce
    818343 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5)
    819344 */
    820345function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) {
    821         if ( $query_arg )
    822                 $nonce = $_REQUEST[$query_arg];
    823         else
    824                 $nonce = $_REQUEST['_ajax_nonce'] ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce'];
    825 
    826         $result = wp_verify_nonce( $nonce, $action );
    827 
    828         if ( $die && false == $result )
    829                 die('-1');
    830 
    831         do_action('check_ajax_referer', $action, $result);
    832 
    833         return $result;
     346        return apply_filters( 'pluggable-check_admin_referer', null, $action, $query_arg, $die );
    834347}
     348add_filter( 'pluggable-check_admin_referer', '_check_ajax_referer', 10, 4 );
    835349endif;
    836350
    837351if ( !function_exists('wp_redirect') ) :
    838352/**
    839  * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
     353 * Redirects to another page.
    840354 *
    841  * @link http://support.microsoft.com/kb/q176113/
     355 * @see _wp_redirect()
     356 *
    842357 * @since 1.5.1
    843  * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
    844358 *
    845359 * @param string $location The path to redirect to
    846360 * @param int $status Status code to use
    847361 * @return bool False if $location is not set
    848362 */
    849 function wp_redirect($location, $status = 302) {
    850         global $is_IIS;
    851 
    852         $location = apply_filters('wp_redirect', $location, $status);
    853         $status = apply_filters('wp_redirect_status', $status, $location);
    854 
    855         if ( !$location ) // allows the wp_redirect filter to cancel a redirect
    856                 return false;
    857 
    858         $location = wp_sanitize_redirect($location);
    859 
    860         if ( $is_IIS ) {
    861                 header("Refresh: 0;url=$location");
    862         } else {
    863                 if ( php_sapi_name() != 'cgi-fcgi' )
    864                         status_header($status); // This causes problems on IIS and some FastCGI setups
    865                 header("Location: $location");
    866         }
     363function wp_redirect( $location, $status = 302 ) {
     364        return apply_filters( 'pluggable-wp_redirect', null, $location, $status );
    867365}
     366add_filter( 'pluggable-wp_redirect', '_wp_redirect', 10, 3 );
    868367endif;
    869368
    870369if ( !function_exists('wp_sanitize_redirect') ) :
    871370/**
    872371 * Sanitizes a URL for use in a redirect.
    873372 *
     373 * @see _wp_sanitize_redirect()
     374 *
    874375 * @since 2.3
    875376 *
    876377 * @return string redirect-sanitized URL
    877378 **/
    878 function wp_sanitize_redirect($location) {
    879         $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location);
    880         $location = wp_kses_no_null($location);
    881 
    882         // remove %0d and %0a from location
    883         $strip = array('%0d', '%0a');
    884         $found = true;
    885         while($found) {
    886                 $found = false;
    887                 foreach( (array) $strip as $val ) {
    888                         while(strpos($location, $val) !== false) {
    889                                 $found = true;
    890                                 $location = str_replace($val, '', $location);
    891                         }
    892                 }
    893         }
    894         return $location;
     379function wp_sanitize_redirect( $location ) {
     380        return apply_filters( 'pluggable-wp_sanitize_redirect', null, $location );
    895381}
     382add_filter( 'pluggable-wp_sanitize_redirect', '_wp_sanitize_redirect', 10, 2 );
    896383endif;
    897384
    898385if ( !function_exists('wp_safe_redirect') ) :
     
    907394 * instead. This prevents malicious redirects which redirect to another host,
    908395 * but only used in a few places.
    909396 *
     397 * @see _wp_safe_redirect()
     398 *
    910399 * @since 2.3
    911400 * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing
    912401 *              WordPress host string and $location host string.
    913402 *
    914403 * @return void Does not return anything
    915404 **/
    916 function wp_safe_redirect($location, $status = 302) {
    917 
    918         // Need to look at the URL the way it will end up in wp_redirect()
    919         $location = wp_sanitize_redirect($location);
    920 
    921         // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
    922         if ( substr($location, 0, 2) == '//' )
    923                 $location = 'http:' . $location;
    924 
    925         // In php 5 parse_url may fail if the URL query part contains http://, bug #38143
    926         $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location;
    927 
    928         $lp  = parse_url($test);
    929         $wpp = parse_url(get_option('home'));
    930 
    931         $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : '');
    932 
    933         if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) )
    934                 $location = admin_url();
    935 
    936         wp_redirect($location, $status);
     405function wp_safe_redirect( $location, $status = 302 ) {
     406        do_action( 'pluggable-wp_safe_redirect', $location, $status );
    937407}
     408add_action( 'pluggable-wp_safe_redirect', '_wp_safe_redirect', 10, 2 );
    938409endif;
    939410
    940 if ( ! function_exists('wp_notify_postauthor') ) :
     411if ( !function_exists('wp_notify_postauthor') ) :
    941412/**
    942413 * Notify an author of a comment/trackback/pingback to one of their posts.
    943414 *
     415 * @see _wp_notify_postauthor()
     416 *
    944417 * @since 1.0.0
    945418 *
    946419 * @param int $comment_id Comment ID
    947420 * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback'
    948421 * @return bool False if user email does not exist. True on completion.
    949422 */
    950 function wp_notify_postauthor($comment_id, $comment_type='') {
    951         $comment = get_comment($comment_id);
    952         $post    = get_post($comment->comment_post_ID);
    953         $user    = get_userdata( $post->post_author );
    954         $current_user = wp_get_current_user();
    955        
    956         if ( $current_user->ID == $user->ID ) return false; // The author moderated a comment on his own post
    957 
    958         if ('' == $user->user_email) return false; // If there's no email to send the comment to
    959 
    960         $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
    961 
    962         $blogname = get_option('blogname');
    963 
    964         if ( empty( $comment_type ) ) $comment_type = 'comment';
    965 
    966         if ('comment' == $comment_type) {
    967                 $notify_message  = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
    968                 $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    969                 $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
    970                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    971                 $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
    972                 $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
    973                 $notify_message .= __('You can see all comments on this post here: ') . "\r\n";
    974                 $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title );
    975         } elseif ('trackback' == $comment_type) {
    976                 $notify_message  = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
    977                 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    978                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    979                 $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
    980                 $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n";
    981                 $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title );
    982         } elseif ('pingback' == $comment_type) {
    983                 $notify_message  = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
    984                 $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    985                 $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    986                 $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n";
    987                 $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n";
    988                 $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title );
    989         }
    990         $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n";
    991         $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
    992         $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
    993 
    994         $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
    995 
    996         if ( '' == $comment->comment_author ) {
    997                 $from = "From: \"$blogname\" <$wp_email>";
    998                 if ( '' != $comment->comment_author_email )
    999                         $reply_to = "Reply-To: $comment->comment_author_email";
    1000         } else {
    1001                 $from = "From: \"$comment->comment_author\" <$wp_email>";
    1002                 if ( '' != $comment->comment_author_email )
    1003                         $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>";
    1004         }
    1005 
    1006         $message_headers = "$from\n"
    1007                 . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
    1008 
    1009         if ( isset($reply_to) )
    1010                 $message_headers .= $reply_to . "\n";
    1011 
    1012         $notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id);
    1013         $subject = apply_filters('comment_notification_subject', $subject, $comment_id);
    1014         $message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id);
    1015 
    1016         @wp_mail($user->user_email, $subject, $notify_message, $message_headers);
    1017 
    1018         return true;
     423function wp_notify_postauthor( $comment_id, $comment_type = '' ) {
     424        return apply_filters( 'pluggable-wp_notify_postauthor', null, $comment_id, $comment_type );
    1019425}
     426add_filter( 'pluggable-wp_notify_postauthor', '_wp_notify_postauthor', 10, 3 );
    1020427endif;
    1021428
    1022429if ( !function_exists('wp_notify_moderator') ) :
    1023430/**
    1024431 * Notifies the moderator of the blog about a new comment that is awaiting approval.
    1025432 *
     433 * @see _wp_notify_moderator()
     434 *
    1026435 * @since 1.0
    1027  * @uses $wpdb
    1028436 *
    1029437 * @param int $comment_id Comment ID
    1030438 * @return bool Always returns true
    1031439 */
    1032 function wp_notify_moderator($comment_id) {
    1033         global $wpdb;
    1034 
    1035         if( get_option( "moderation_notify" ) == 0 )
    1036                 return true;
    1037 
    1038         $comment = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_ID=%d LIMIT 1", $comment_id));
    1039         $post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID=%d LIMIT 1", $comment->comment_post_ID));
    1040 
    1041         $comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
    1042         $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'");
    1043 
    1044         switch ($comment->comment_type)
    1045         {
    1046                 case 'trackback':
    1047                         $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";
    1048                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
    1049                         $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    1050                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    1051                         $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
    1052                         break;
    1053                 case 'pingback':
    1054                         $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";
    1055                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
    1056                         $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    1057                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    1058                         $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
    1059                         break;
    1060                 default: //Comments
    1061                         $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";
    1062                         $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
    1063                         $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
    1064                         $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
    1065                         $notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
    1066                         $notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
    1067                         $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
    1068                         break;
    1069         }
    1070 
    1071         $notify_message .= sprintf( __('Approve it: %s'),  admin_url("comment.php?action=mac&c=$comment_id") ) . "\r\n";
    1072         $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=cdc&c=$comment_id") ) . "\r\n";
    1073         $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=cdc&dt=spam&c=$comment_id") ) . "\r\n";
    1074 
    1075         $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:',
    1076                 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n";
    1077         $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n";
    1078 
    1079         $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_option('blogname'), $post->post_title );
    1080         $admin_email = get_option('admin_email');
    1081 
    1082         $notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id);
    1083         $subject = apply_filters('comment_moderation_subject', $subject, $comment_id);
    1084 
    1085         @wp_mail($admin_email, $subject, $notify_message);
    1086 
    1087         return true;
     440function wp_notify_moderator( $comment_id ) {
     441        return apply_filters( 'pluggable-wp_notify_moderator', null, $comment_id );
    1088442}
     443add_filter( 'pluggable-wp_notify_moderator', '_wp_notify_moderator', 10, 2 );
    1089444endif;
    1090445
    1091446if ( !function_exists('wp_password_change_notification') ) :
    1092447/**
    1093448 * Notify the blog admin of a user changing password, normally via email.
    1094449 *
     450 * @see _wp_password_change_notification()
     451 *
    1095452 * @since 2.7
    1096453 *
    1097454 * @param object $user User Object
    1098455 */
    1099 function wp_password_change_notification(&$user) {
    1100         // send a copy of password change notification to the admin
    1101         // but check to see if it's the admin whose password we're changing, and skip this
    1102         if ( $user->user_email != get_option('admin_email') ) {
    1103                 $message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n";
    1104                 wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), get_option('blogname')), $message);
    1105         }
     456function wp_password_change_notification( &$user ) {
     457        do_action( 'pluggable-wp_password_change_notification', $user );
    1106458}
     459add_action( 'pluggable-wp_password_change_notification', '_wp_password_change_notification' );
    1107460endif;
    1108461
    1109462if ( !function_exists('wp_new_user_notification') ) :
    1110463/**
    1111464 * Notify the blog admin of a new user, normally via email.
    1112465 *
     466 * @see _wp_new_user_notification()
     467 *
    1113468 * @since 2.0
    1114469 *
    1115470 * @param int $user_id User ID
    1116471 * @param string $plaintext_pass Optional. The user's plaintext password
    1117472 */
    1118 function wp_new_user_notification($user_id, $plaintext_pass = '') {
    1119         $user = new WP_User($user_id);
    1120 
    1121         $user_login = stripslashes($user->user_login);
    1122         $user_email = stripslashes($user->user_email);
    1123 
    1124         $message  = sprintf(__('New user registration on your blog %s:'), get_option('blogname')) . "\r\n\r\n";
    1125         $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
    1126         $message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
    1127 
    1128         @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), get_option('blogname')), $message);
    1129 
    1130         if ( empty($plaintext_pass) )
    1131                 return;
    1132 
    1133         $message  = sprintf(__('Username: %s'), $user_login) . "\r\n";
    1134         $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n";
    1135         $message .= wp_login_url() . "\r\n";
    1136 
    1137         wp_mail($user_email, sprintf(__('[%s] Your username and password'), get_option('blogname')), $message);
    1138 
     473function wp_new_user_notification( $user_id, $plaintext_pass = '' ) {
     474        do_action( 'pluggable-wp_new_user_notification', $user_id, $plaintext_pass );
    1139475}
     476add_action( 'pluggable-wp_new_user_notification', '_wp_new_user_notification', 10, 2 );
    1140477endif;
    1141478
    1142479if ( !function_exists('wp_nonce_tick') ) :
    1143480/**
    1144481 * Get the time-dependent variable for nonce creation.
    1145482 *
    1146  * A nonce has a lifespan of two ticks. Nonces in their second tick may be
    1147  * updated, e.g. by autosave.
     483 * @see _wp_nonce_tick()
    1148484 *
    1149485 * @since 2.5
    1150486 *
    1151487 * @return int
    1152488 */
    1153489function wp_nonce_tick() {
    1154         $nonce_life = apply_filters('nonce_life', 86400);
    1155 
    1156         return ceil(time() / ( $nonce_life / 2 ));
     490        return apply_filters( 'pluggable-wp_nonce_tick', null );
    1157491}
     492add_filter( 'pluggable-wp_nonce_tick', '_wp_nonce_tick' );
    1158493endif;
    1159494
    1160495if ( !function_exists('wp_verify_nonce') ) :
     
    1164499 * The user is given an amount of time to use the token, so therefore, since the
    1165500 * UID and $action remain the same, the independent variable is the time.
    1166501 *
     502 * @see _wp_verify_nonce()
     503 *
    1167504 * @since 2.0.3
    1168505 *
    1169506 * @param string $nonce Nonce that was used in the form to verify
    1170507 * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
    1171508 * @return bool Whether the nonce check passed or failed.
    1172509 */
    1173 function wp_verify_nonce($nonce, $action = -1) {
    1174         $user = wp_get_current_user();
    1175         $uid = (int) $user->id;
    1176 
    1177         $i = wp_nonce_tick();
    1178 
    1179         // Nonce generated 0-12 hours ago
    1180         if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) == $nonce )
    1181                 return 1;
    1182         // Nonce generated 12-24 hours ago
    1183         if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) == $nonce )
    1184                 return 2;
    1185         // Invalid nonce
    1186         return false;
     510function wp_verify_nonce( $nonce, $action = -1 ) {
     511        return apply_filters( 'pluggable-wp_verify_nonce', null, $nonce, $action );
    1187512}
     513add_filter( 'pluggable-wp_verify_nonce', '_wp_verify_nonce', 10, 3 );
    1188514endif;
    1189515
    1190516if ( !function_exists('wp_create_nonce') ) :
    1191517/**
    1192518 * Creates a random, one time use token.
    1193519 *
     520 * @see _wp_create_nonce()
     521 *
    1194522 * @since 2.0.3
    1195523 *
    1196524 * @param string|int $action Scalar value to add context to the nonce.
    1197525 * @return string The one use form token
    1198526 */
    1199 function wp_create_nonce($action = -1) {
    1200         $user = wp_get_current_user();
    1201         $uid = (int) $user->id;
    1202 
    1203         $i = wp_nonce_tick();
    1204 
    1205         return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10);
     527function wp_create_nonce( $action = -1 ) {
     528        return apply_filters( 'pluggable-wp_create_nonce', null, $action );
    1206529}
     530add_filter( 'pluggable-wp_create_nonce', '_wp_create_nonce', 10, 2 );
    1207531endif;
    1208532
    1209533if ( !function_exists('wp_salt') ) :
    1210534/**
    1211535 * Get salt to add to hashes to help prevent attacks.
    1212536 *
    1213  * The secret key is located in two places: the database in case the secret key
    1214  * isn't defined in the second place, which is in the wp-config.php file. If you
    1215  * are going to set the secret key, then you must do so in the wp-config.php
    1216  * file.
     537 * @see _wp_salt()
    1217538 *
    1218  * The secret key in the database is randomly generated and will be appended to
    1219  * the secret key that is in wp-config.php file in some instances. It is
    1220  * important to have the secret key defined or changed in wp-config.php.
    1221  *
    1222  * If you have installed WordPress 2.5 or later, then you will have the
    1223  * SECRET_KEY defined in the wp-config.php already. You will want to change the
    1224  * value in it because hackers will know what it is. If you have upgraded to
    1225  * WordPress 2.5 or later version from a version before WordPress 2.5, then you
    1226  * should add the constant to your wp-config.php file.
    1227  *
    1228  * Below is an example of how the SECRET_KEY constant is defined with a value.
    1229  * You must not copy the below example and paste into your wp-config.php. If you
    1230  * need an example, then you can have a
    1231  * {@link https://api.wordpress.org/secret-key/1.1/ secret key created} for you.
    1232  *
    1233  * <code>
    1234  * define('SECRET_KEY', 'mAry1HadA15|\/|b17w55w1t3asSn09w');
    1235  * </code>
    1236  *
    1237  * Salting passwords helps against tools which has stored hashed values of
    1238  * common dictionary strings. The added values makes it harder to crack if given
    1239  * salt string is not weak.
    1240  *
    1241539 * @since 2.5
    1242540 * @link https://api.wordpress.org/secret-key/1.1/ Create a Secret Key for wp-config.php
    1243541 *
    1244542 * @return string Salt value from either 'SECRET_KEY' or 'secret' option
    1245543 */
    1246 function wp_salt($scheme = 'auth') {
    1247         global $wp_default_secret_key;
    1248         $secret_key = '';
    1249         if ( defined('SECRET_KEY') && ('' != SECRET_KEY) && ( $wp_default_secret_key != SECRET_KEY) )
    1250                 $secret_key = SECRET_KEY;
    1251 
    1252         if ( 'auth' == $scheme ) {
    1253                 if ( defined('AUTH_KEY') && ('' != AUTH_KEY) && ( $wp_default_secret_key != AUTH_KEY) )
    1254                         $secret_key = AUTH_KEY;
    1255 
    1256                 if ( defined('AUTH_SALT') ) {
    1257                         $salt = AUTH_SALT;
    1258                 } elseif ( defined('SECRET_SALT') ) {
    1259                         $salt = SECRET_SALT;
    1260                 } else {
    1261                         $salt = get_option('auth_salt');
    1262                         if ( empty($salt) ) {
    1263                                 $salt = wp_generate_password(64);
    1264                                 update_option('auth_salt', $salt);
    1265                         }
    1266                 }
    1267         } elseif ( 'secure_auth' == $scheme ) {
    1268                 if ( defined('SECURE_AUTH_KEY') && ('' != SECURE_AUTH_KEY) && ( $wp_default_secret_key != SECURE_AUTH_KEY) )
    1269                         $secret_key = SECURE_AUTH_KEY;
    1270 
    1271                 if ( defined('SECURE_AUTH_SALT') ) {
    1272                         $salt = SECURE_AUTH_SALT;
    1273                 } else {
    1274                         $salt = get_option('secure_auth_salt');
    1275                         if ( empty($salt) ) {
    1276                                 $salt = wp_generate_password(64);
    1277                                 update_option('secure_auth_salt', $salt);
    1278                         }
    1279                 }
    1280         } elseif ( 'logged_in' == $scheme ) {
    1281                 if ( defined('LOGGED_IN_KEY') && ('' != LOGGED_IN_KEY) && ( $wp_default_secret_key != LOGGED_IN_KEY) )
    1282                         $secret_key = LOGGED_IN_KEY;
    1283 
    1284                 if ( defined('LOGGED_IN_SALT') ) {
    1285                         $salt = LOGGED_IN_SALT;
    1286                 } else {
    1287                         $salt = get_option('logged_in_salt');
    1288                         if ( empty($salt) ) {
    1289                                 $salt = wp_generate_password(64);
    1290                                 update_option('logged_in_salt', $salt);
    1291                         }
    1292                 }
    1293         } elseif ( 'nonce' == $scheme ) {
    1294                 if ( defined('NONCE_KEY') && ('' != NONCE_KEY) && ( $wp_default_secret_key != NONCE_KEY) )
    1295                         $secret_key = NONCE_KEY;
    1296 
    1297                 if ( defined('NONCE_SALT') ) {
    1298                         $salt = NONCE_SALT;
    1299                 } else {
    1300                         $salt = get_option('nonce_salt');
    1301                         if ( empty($salt) ) {
    1302                                 $salt = wp_generate_password(64);
    1303                                 update_option('nonce_salt', $salt);
    1304                         }
    1305                 }
    1306         } else {
    1307                 // ensure each auth scheme has its own unique salt
    1308                 $salt = hash_hmac('md5', $scheme, $secret_key);
    1309         }
    1310 
    1311         return apply_filters('salt', $secret_key . $salt, $scheme);
     544function wp_salt( $scheme = 'auth' ) {
     545        return apply_filters( 'pluggable-wp_salt', null, $scheme );
    1312546}
     547add_filter( 'pluggable-wp_salt', '_wp_salt', 10, 2 );
    1313548endif;
    1314549
    1315550if ( !function_exists('wp_hash') ) :
    1316551/**
    1317552 * Get hash of given string.
    1318553 *
     554 * @see _wp_hash()
     555 *
    1319556 * @since 2.0.3
    1320  * @uses wp_salt() Get WordPress salt
    1321557 *
    1322558 * @param string $data Plain text to hash
    1323559 * @return string Hash of $data
    1324560 */
    1325 function wp_hash($data, $scheme = 'auth') {
    1326         $salt = wp_salt($scheme);
    1327 
    1328         return hash_hmac('md5', $data, $salt);
     561function wp_hash( $data, $scheme = 'auth' ) {
     562        return apply_filters( 'pluggable-wp_hash', null, $data, $scheme );
    1329563}
     564add_filter( 'pluggable-wp_hash', '_wp_hash', 10, 3 );
    1330565endif;
    1331566
    1332567if ( !function_exists('wp_hash_password') ) :
     
    1336571 * For integration with other applications, this function can be overwritten to
    1337572 * instead use the other package password checking algorithm.
    1338573 *
     574 * @see _wp_hash_password()
     575 *
    1339576 * @since 2.5
    1340577 * @global object $wp_hasher PHPass object
    1341578 * @uses PasswordHash::HashPassword
     
    1343580 * @param string $password Plain text user password to hash
    1344581 * @return string The hash string of the password
    1345582 */
    1346 function wp_hash_password($password) {
    1347         global $wp_hasher;
    1348 
    1349         if ( empty($wp_hasher) ) {
    1350                 require_once( ABSPATH . 'wp-includes/class-phpass.php');
    1351                 // By default, use the portable hash from phpass
    1352                 $wp_hasher = new PasswordHash(8, TRUE);
    1353         }
    1354 
    1355         return $wp_hasher->HashPassword($password);
     583function wp_hash_password( $password ) {
     584        return apply_filters( 'pluggable-wp_hash_password', null, $password );
    1356585}
     586add_filter( 'pluggable-wp_hash_password', '_wp_hash_password', 10, 2 );
    1357587endif;
    1358588
    1359589if ( !function_exists('wp_check_password') ) :
    1360590/**
    1361  * Checks the plaintext password against the encrypted Password.
     591 * Checks the plaintext password against the encrypted password.
    1362592 *
    1363  * Maintains compatibility between old version and the new cookie authentication
    1364  * protocol using PHPass library. The $hash parameter is the encrypted password
    1365  * and the function compares the plain text password when encypted similarly
    1366  * against the already encrypted password to see if they match.
    1367  *
    1368593 * For integration with other applications, this function can be overwritten to
    1369594 * instead use the other package password checking algorithm.
    1370595 *
     596 * @see _wp_check_password()
     597 *
    1371598 * @since 2.5
    1372599 * @global object $wp_hasher PHPass object used for checking the password
    1373600 *      against the $hash + $password
     
    1377604 * @param string $hash Hash of the user's password to check against.
    1378605 * @return bool False, if the $password does not match the hashed password
    1379606 */
    1380 function wp_check_password($password, $hash, $user_id = '') {
    1381         global $wp_hasher;
    1382 
    1383         // If the hash is still md5...
    1384         if ( strlen($hash) <= 32 ) {
    1385                 $check = ( $hash == md5($password) );
    1386                 if ( $check && $user_id ) {
    1387                         // Rehash using new hash.
    1388                         wp_set_password($password, $user_id);
    1389                         $hash = wp_hash_password($password);
    1390                 }
    1391 
    1392                 return apply_filters('check_password', $check, $password, $hash, $user_id);
    1393         }
    1394 
    1395         // If the stored hash is longer than an MD5, presume the
    1396         // new style phpass portable hash.
    1397         if ( empty($wp_hasher) ) {
    1398                 require_once( ABSPATH . 'wp-includes/class-phpass.php');
    1399                 // By default, use the portable hash from phpass
    1400                 $wp_hasher = new PasswordHash(8, TRUE);
    1401         }
    1402 
    1403         $check = $wp_hasher->CheckPassword($password, $hash);
    1404 
    1405         return apply_filters('check_password', $check, $password, $hash, $user_id);
     607function wp_check_password( $password, $hash, $user_id = '' ) {
     608        return apply_filters( 'pluggable-wp_check_password', null, $password, $hash, $user_id );
    1406609}
     610add_filter( 'pluggable-wp_check_password', '_wp_check_password', 10, 4 );
    1407611endif;
    1408612
    1409613if ( !function_exists('wp_generate_password') ) :
    1410614/**
    1411  * Generates a random password drawn from the defined set of characters.
     615 * Generates a random password.
    1412616 *
     617 * @see _wp_generate_password()
     618 *
    1413619 * @since 2.5
    1414620 *
    1415621 * @param int $length The length of password to generate
    1416622 * @param bool $special_chars Whether to include standard special characters
    1417623 * @return string The random password
    1418624 **/
    1419 function wp_generate_password($length = 12, $special_chars = true) {
    1420         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    1421         if ( $special_chars )
    1422                 $chars .= '!@#$%^&*()';
    1423 
    1424         $password = '';
    1425         for ( $i = 0; $i < $length; $i++ )
    1426                 $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1);
    1427         return $password;
     625function wp_generate_password( $length = 12, $special_chars = true ) {
     626        return apply_filters( 'pluggable-wp_generate_password', null, $length, $special_chars );
    1428627}
     628add_filter( 'pluggable-wp_generate_password', '_wp_generate_password', 10, 3 );
    1429629endif;
    1430630
    1431631if ( !function_exists('wp_rand') ) :
    1432  /**
     632/**
    1433633 * Generates a random number
    1434634 *
     635 * @see _wp_rand()
     636 *
    1435637 * @since 2.6.2
    1436638 *
    1437639 * @param int $min Lower limit for the generated number (optional, default is 0)
     
    1439641 * @return int A random number between min and max
    1440642 */
    1441643function wp_rand( $min = 0, $max = 0 ) {
    1442         global $rnd_value;
    1443 
    1444         $seed = get_transient('random_seed');
    1445 
    1446         // Reset $rnd_value after 14 uses
    1447         // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
    1448         if ( strlen($rnd_value) < 8 ) {
    1449                 $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
    1450                 $rnd_value .= sha1($rnd_value);
    1451                 $rnd_value .= sha1($rnd_value . $seed);
    1452                 $seed = md5($seed . $rnd_value);
    1453                 set_transient('random_seed', $seed);
    1454         }
    1455 
    1456         // Take the first 8 digits for our value
    1457         $value = substr($rnd_value, 0, 8);
    1458 
    1459         // Strip the first eight, leaving the remainder for the next call to wp_rand().
    1460         $rnd_value = substr($rnd_value, 8);
    1461 
    1462         $value = abs(hexdec($value));
    1463 
    1464         // Reduce the value to be within the min - max range
    1465         // 4294967295 = 0xffffffff = max random number
    1466         if ( $max != 0 )
    1467                 $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1)));
    1468 
    1469         return abs(intval($value));
     644        return apply_filters( 'pluggable-wp_rand', null, $min, $max );
    1470645}
     646add_filter( 'pluggable-wp_rand', '_wp_rand', 10, 3 );
    1471647endif;
    1472648
    1473649if ( !function_exists('wp_set_password') ) :
     
    1477653 * For integration with other applications, this function can be overwritten to
    1478654 * instead use the other package password checking algorithm.
    1479655 *
     656 * @see _wp_set_password()
     657 *
    1480658 * @since 2.5
    1481659 * @uses $wpdb WordPress database object for queries
    1482660 * @uses wp_hash_password() Used to encrypt the user's password before passing to the database
     
    1485663 * @param int $user_id User ID
    1486664 */
    1487665function wp_set_password( $password, $user_id ) {
    1488         global $wpdb;
    1489 
    1490         $hash = wp_hash_password($password);
    1491         $wpdb->update($wpdb->users, array('user_pass' => $hash, 'user_activation_key' => ''), array('ID' => $user_id) );
    1492 
    1493         wp_cache_delete($user_id, 'users');
     666        do_action( 'pluggable-wp_set_password', $password, $user_id );
    1494667}
     668add_action( 'pluggable-wp_set_password', '_wp_set_password', 10, 2 );
    1495669endif;
    1496670
    1497671if ( !function_exists( 'get_avatar' ) ) :
    1498672/**
    1499673 * Retrieve the avatar for a user who provided a user ID or email address.
    1500674 *
     675 * @see _get_avatar()
     676 *
    1501677 * @since 2.5
    1502678 * @param int|string|object $id_or_email A user ID,  email address, or comment object
    1503679 * @param int $size Size of the avatar image
     
    1506682 * @return string <img> tag for the user's avatar
    1507683*/
    1508684function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) {
    1509         if ( ! get_option('show_avatars') )
    1510                 return false;
    1511 
    1512         if ( false === $alt)
    1513                 $safe_alt = '';
    1514         else
    1515                 $safe_alt = attr( $alt );
    1516 
    1517         if ( !is_numeric($size) )
    1518                 $size = '96';
    1519 
    1520         $email = '';
    1521         if ( is_numeric($id_or_email) ) {
    1522                 $id = (int) $id_or_email;
    1523                 $user = get_userdata($id);
    1524                 if ( $user )
    1525                         $email = $user->user_email;
    1526         } elseif ( is_object($id_or_email) ) {
    1527                 if ( isset($id_or_email->comment_type) && '' != $id_or_email->comment_type && 'comment' != $id_or_email->comment_type )
    1528                         return false; // No avatar for pingbacks or trackbacks
    1529 
    1530                 if ( !empty($id_or_email->user_id) ) {
    1531                         $id = (int) $id_or_email->user_id;
    1532                         $user = get_userdata($id);
    1533                         if ( $user)
    1534                                 $email = $user->user_email;
    1535                 } elseif ( !empty($id_or_email->comment_author_email) ) {
    1536                         $email = $id_or_email->comment_author_email;
    1537                 }
    1538         } else {
    1539                 $email = $id_or_email;
    1540         }
    1541 
    1542         if ( empty($default) ) {
    1543                 $avatar_default = get_option('avatar_default');
    1544                 if ( empty($avatar_default) )
    1545                         $default = 'mystery';
    1546                 else
    1547                         $default = $avatar_default;
    1548         }
    1549 
    1550         if ( is_ssl() )
    1551                 $host = 'https://secure.gravatar.com';
    1552         else
    1553                 $host = 'http://www.gravatar.com';
    1554 
    1555         if ( 'mystery' == $default )
    1556                 $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
    1557         elseif ( 'blank' == $default )
    1558                 $default = includes_url('images/blank.gif');
    1559         elseif ( !empty($email) && 'gravatar_default' == $default )
    1560                 $default = '';
    1561         elseif ( 'gravatar_default' == $default )
    1562                 $default = "$host/avatar/s={$size}";
    1563         elseif ( empty($email) )
    1564                 $default = "$host/avatar/?d=$default&amp;s={$size}";
    1565         elseif ( strpos($default, 'http://') === 0 )
    1566                 $default = add_query_arg( 's', $size, $default );
    1567 
    1568         if ( !empty($email) ) {
    1569                 $out = "$host/avatar/";
    1570                 $out .= md5( strtolower( $email ) );
    1571                 $out .= '?s='.$size;
    1572                 $out .= '&amp;d=' . urlencode( $default );
    1573 
    1574                 $rating = get_option('avatar_rating');
    1575                 if ( !empty( $rating ) )
    1576                         $out .= "&amp;r={$rating}";
    1577 
    1578                 $avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
    1579         } else {
    1580                 $avatar = "<img alt='{$safe_alt}' src='{$default}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
    1581         }
    1582 
    1583         return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt);
     685        return apply_filters( 'pluggable-get_avatar', null, $id_or_email, $size, $default, $alt );
    1584686}
     687add_filter( 'pluggable-get_avatar', '_get_avatar', 10, 5 );
    1585688endif;
    1586689
    1587690if ( !function_exists('wp_setcookie') ) :
     
    1658761 * @param bool $deprecated Not used
    1659762 * @return bool False on login failure, true on successful check
    1660763 */
    1661 function wp_login($username, $password, $deprecated = '') {
     764function wp_login( $username, $password, $deprecated = '' ) {
    1662765        global $error;
    1663766
    1664767        $user = wp_authenticate($username, $password);
     
    1679782 * HTML, so the primary use is for displaying the changes. If the two strings
    1680783 * are equivalent, then an empty string will be returned.
    1681784 *
    1682  * The arguments supported and can be changed are listed below.
     785 * @see _wp_text_diff()
    1683786 *
    1684  * 'title' : Default is an empty string. Titles the diff in a manner compatible
    1685  *              with the output.
    1686  * 'title_left' : Default is an empty string. Change the HTML to the left of the
    1687  *              title.
    1688  * 'title_right' : Default is an empty string. Change the HTML to the right of
    1689  *              the title.
    1690  *
    1691787 * @since 2.6
    1692788 * @see wp_parse_args() Used to change defaults to user defined settings.
    1693789 * @uses Text_Diff
     
    1699795 * @return string Empty string if strings are equivalent or HTML with differences.
    1700796 */
    1701797function wp_text_diff( $left_string, $right_string, $args = null ) {
    1702         $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
    1703         $args = wp_parse_args( $args, $defaults );
    1704 
    1705         if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) )
    1706                 require( ABSPATH . WPINC . '/wp-diff.php' );
    1707 
    1708         $left_string  = normalize_whitespace($left_string);
    1709         $right_string = normalize_whitespace($right_string);
    1710 
    1711         $left_lines  = split("\n", $left_string);
    1712         $right_lines = split("\n", $right_string);
    1713 
    1714         $text_diff = new Text_Diff($left_lines, $right_lines);
    1715         $renderer  = new WP_Text_Diff_Renderer_Table();
    1716         $diff = $renderer->render($text_diff);
    1717 
    1718         if ( !$diff )
    1719                 return '';
    1720 
    1721         $r  = "<table class='diff'>\n";
    1722         $r .= "<col class='ltype' /><col class='content' /><col class='ltype' /><col class='content' />";
    1723 
    1724         if ( $args['title'] || $args['title_left'] || $args['title_right'] )
    1725                 $r .= "<thead>";
    1726         if ( $args['title'] )
    1727                 $r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
    1728         if ( $args['title_left'] || $args['title_right'] ) {
    1729                 $r .= "<tr class='diff-sub-title'>\n";
    1730                 $r .= "\t<td></td><th>$args[title_left]</th>\n";
    1731                 $r .= "\t<td></td><th>$args[title_right]</th>\n";
    1732                 $r .= "</tr>\n";
    1733         }
    1734         if ( $args['title'] || $args['title_left'] || $args['title_right'] )
    1735                 $r .= "</thead>\n";
    1736 
    1737         $r .= "<tbody>\n$diff\n</tbody>\n";
    1738         $r .= "</table>";
    1739 
    1740         return $r;
     798        return apply_filters( 'pluggable-wp_text_diff', null, $left_string, $right_string, $args );
    1741799}
     800add_filter( 'pluggable-wp_text_diff', '_wp_text_diff', 10, 4 );
    1742801endif;
    1743802
    1744803?>
  • wp-includes/user.php

     
    130130}
    131131
    132132/**
     133 * Changes the current user by ID or name.
     134 *
     135 * This function should not be used directly. Use the pluggable version instead.
     136 * @see wp_set_current_user()
     137 *
     138 * Set $id to null and specify a name if you do not know a user's ID.
     139 *
     140 * Some WordPress functionality is based on the current user and not based on
     141 * the signed in user. Therefore, it opens the ability to edit and perform
     142 * actions on users who aren't signed in.
     143 *
     144 * @since 2.8.0
     145 * @global object $current_user The current user object which holds the user data.
     146 * @uses do_action() Calls 'set_current_user' hook after setting the current user.
     147 *
     148 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_set_current_user" filter.
     149 * @param int $id User ID
     150 * @param string $name User's username
     151 * @return WP_User Current user User object
     152 */
     153function _wp_set_current_user( $existing = null, $id, $name = '' ) {
     154        if ( null !== $existing )
     155                return $existing;
     156
     157        global $current_user;
     158
     159        if ( isset($current_user) && ($id == $current_user->ID) )
     160                return $current_user;
     161
     162        $current_user = new WP_User($id, $name);
     163
     164        setup_userdata($current_user->ID);
     165
     166        do_action('set_current_user');
     167
     168        return $current_user;
     169}
     170
     171/**
     172 * Retrieve the current user object.
     173 *
     174 * This function should not be used directly. Use the pluggable version instead.
     175 * @see wp_get_current_user()
     176 *
     177 * @since 2.8.0
     178 * @uses get_currentuserinfo() Populates the global user variables.
     179 *
     180 * @return WP_User Current user WP_User object
     181 */
     182function _wp_get_current_user() {
     183        global $current_user;
     184
     185        get_currentuserinfo();
     186
     187        return $current_user;
     188}
     189
     190/**
     191 * Populate global variables with information about the currently logged in user.
     192 *
     193 * Will set the current user, if the current user is not set. The current user
     194 * will be set to the logged in person. If no user is logged in, then it will
     195 * set the current user to 0, which is invalid and won't have any permissions.
     196 *
     197 * This function should not be used directly. Use the pluggable version instead.
     198 * @see get_currentuserinfo()
     199 *
     200 * @since 2.8.0
     201 * @uses $current_user Checks if the current user is set
     202 * @uses wp_validate_auth_cookie() Retrieves current logged in user.
     203 *
     204 * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set.
     205 */
     206function _get_currentuserinfo() {
     207        global $current_user;
     208
     209        if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST )
     210                return false;
     211
     212        if ( !empty($current_user) )
     213                return;
     214
     215        if ( !$user = wp_validate_auth_cookie() ) {
     216                if ( empty($_COOKIE[LOGGED_IN_COOKIE]) || !$user = wp_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in') ) {
     217                        wp_set_current_user(0);
     218                        return false;
     219                }
     220        }
     221
     222        wp_set_current_user($user);
     223}
     224
     225/**
     226 * Retrieve user info by user ID.
     227 *
     228 * This function should not be used directly. Use the pluggable version instead.
     229 * @see get_userdata()
     230 *
     231 * @since 2.8.0
     232 *
     233 * @param mixed $existing Any existing data provided by another function in the "pluggable-get_userdata" filter.
     234 * @param int $user_id User ID
     235 * @return bool|object False on failure, User DB row object
     236 */
     237function _get_userdata( $existing = null, $user_id ) {
     238        if ( null !== $existing )
     239                return $existing;
     240
     241        global $wpdb;
     242
     243        $user_id = absint($user_id);
     244        if ( $user_id == 0 )
     245                return false;
     246
     247        $user = wp_cache_get($user_id, 'users');
     248
     249        if ( $user )
     250                return $user;
     251
     252        if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id)) )
     253                return false;
     254
     255        _fill_user($user);
     256
     257        return $user;
     258}
     259
     260/**
     261 * Retrieve user info by a given field
     262 *
     263 * This function should not be used directly. Use the pluggable version instead.
     264 * @see get_user_by()
     265 *
     266 * @since 2.8.0
     267 *
     268 * @param mixed $existing Any existing data provided by another function in the "pluggable-get_user_by" filter.
     269 * @param string $field The field to retrieve the user with.  id | slug | email | login
     270 * @param int|string $value A value for $field.  A user ID, slug, email address, or login name.
     271 * @return bool|object False on failure, User DB row object
     272 */
     273function _get_user_by( $existing = null, $field, $value ) {
     274        if ( null !== $existing )
     275                return $existing;
     276
     277        global $wpdb;
     278
     279        switch ($field) {
     280                case 'id':
     281                        return get_userdata($value);
     282                        break;
     283                case 'slug':
     284                        $user_id = wp_cache_get($value, 'userslugs');
     285                        $field = 'user_nicename';
     286                        break;
     287                case 'email':
     288                        $user_id = wp_cache_get($value, 'useremail');
     289                        $field = 'user_email';
     290                        break;
     291                case 'login':
     292                        $value = sanitize_user( $value );
     293                        $user_id = wp_cache_get($value, 'userlogins');
     294                        $field = 'user_login';
     295                        break;
     296                default:
     297                        return false;
     298        }
     299
     300         if ( false !== $user_id )
     301                return get_userdata($user_id);
     302
     303        if ( !$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE $field = %s", $value) ) )
     304                return false;
     305
     306        _fill_user($user);
     307
     308        return $user;
     309}
     310
     311/**
     312 * Checks a user's login information and logs them in if it checks out.
     313 *
     314 * This function should not be used directly. Use the pluggable version instead.
     315 * @see wp_authenticate()
     316 *
     317 * @since 2.8.0
     318 *
     319 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_set_current_user" filter.
     320 * @param string $username User's username
     321 * @param string $password User's password
     322 * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object.
     323 */
     324function _wp_authenticate( $existing = null, $username, $password ) {
     325        if ( null !== $existing )
     326                return $existing;
     327
     328        $username = sanitize_user($username);
     329        $password = trim($password);
     330
     331        $user = apply_filters('authenticate', null, $username, $password);
     332
     333        if ( $user == null ) {
     334                // TODO what should the error message be? (Or would these even happen?)
     335                // Only needed if all authentication handlers fail to return anything.
     336                $user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
     337        }
     338
     339        $ignore_codes = array('empty_username', 'empty_password');
     340
     341        if ( is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) {
     342                do_action('wp_login_failed', $username);
     343        }
     344
     345        return $user;
     346}
     347
     348/**
     349 * Log the current user out.
     350 *
     351 * This function should not be used directly. Use the pluggable version instead.
     352 * @see wp_logout()
     353 *
     354 * @since 2.5.0
     355 */
     356function _wp_logout() {
     357        wp_clear_auth_cookie();
     358        do_action('wp_logout');
     359}
     360
     361/**
     362 * Validates authentication cookie.
     363 *
     364 * The checks include making sure that the authentication cookie is set and
     365 * pulling in the contents (if $cookie is not used).
     366 *
     367 * Makes sure the cookie is not expired. Verifies the hash in cookie is what is
     368 * should be and compares the two.
     369 *
     370 * This function should not be used directly. Use the pluggable version instead.
     371 * @see wp_validate_auth_cookie()
     372 *
     373 * @since 2.8.0
     374 *
     375 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_validate_auth_cookie" filter.
     376 * @param string $cookie Optional. If used, will validate contents instead of cookie's
     377 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
     378 * @return bool|int False if invalid cookie, User ID if valid.
     379 */
     380function _wp_validate_auth_cookie( $existing = null, $cookie = '', $scheme = '' ) {
     381        if ( null !== $existing )
     382                return $existing;
     383
     384        if ( ! $cookie_elements = wp_parse_auth_cookie( $cookie, $scheme ) ) {
     385                do_action('auth_cookie_malformed', $cookie, $scheme);
     386                return false;
     387        }
     388
     389        extract($cookie_elements, EXTR_OVERWRITE);
     390
     391        $expired = $expiration;
     392
     393        // Allow a grace period for POST and AJAX requests
     394        if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] )
     395                $expired += 3600;
     396
     397        // Quick check to see if an honest cookie has expired
     398        if ( $expired < time() ) {
     399                do_action('auth_cookie_expired', $cookie_elements);
     400                return false;
     401        }
     402
     403        $user = get_userdatabylogin($username);
     404        if ( ! $user ) {
     405                do_action('auth_cookie_bad_username', $cookie_elements);
     406                return false;
     407        }
     408
     409        $pass_frag = substr($user->user_pass, 8, 4);
     410
     411        $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);
     412        $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
     413
     414        if ( $hmac != $hash ) {
     415                do_action('auth_cookie_bad_hash', $cookie_elements);
     416                return false;
     417        }
     418
     419        do_action('auth_cookie_valid', $cookie_elements, $user);
     420
     421        return $user->ID;
     422}
     423
     424/**
     425 * Generate authentication cookie contents.
     426 *
     427 * This function should not be used directly. Use the pluggable version instead.
     428 * @see wp_generate_auth_cookie()
     429 *
     430 * @since 2.8.0
     431 * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID
     432 *              and expiration of cookie.
     433 *
     434 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_generate_auth_cookie" filter.
     435 * @param int $user_id User ID
     436 * @param int $expiration Cookie expiration in seconds
     437 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
     438 * @return string Authentication cookie contents
     439 */
     440function _wp_generate_auth_cookie( $existing = null, $user_id, $expiration, $scheme = 'auth' ) {
     441        if ( null !== $existing )
     442                return $existing;
     443
     444        $user = get_userdata($user_id);
     445
     446        $pass_frag = substr($user->user_pass, 8, 4);
     447
     448        $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);
     449        $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);
     450
     451        $cookie = $user->user_login . '|' . $expiration . '|' . $hash;
     452
     453        return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
     454}
     455
     456/**
     457 * Parse a cookie into its components
     458 *
     459 * This function should not be used directly. Use the pluggable version instead.
     460 * @see wp_parse_auth_cookie()
     461 *
     462 * @since 2.8.0
     463 *
     464 * @param mixed $existing Any existing data provided by another function in the "pluggable-wp_parse_auth_cookie" filter.
     465 * @param string $cookie
     466 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
     467 * @return array Authentication cookie components
     468 */
     469function _wp_parse_auth_cookie( $existing = null, $cookie = '', $scheme = '' ) {
     470        if ( null !== $existing )
     471                return $existing;
     472
     473        if ( empty($cookie) ) {
     474                switch ($scheme) {
     475                        case 'auth':
     476                                $cookie_name = AUTH_COOKIE;
     477                                break;
     478                        case 'secure_auth':
     479                                $cookie_name = SECURE_AUTH_COOKIE;
     480                                break;
     481                        case "logged_in":
     482                                $cookie_name = LOGGED_IN_COOKIE;
     483                                break;
     484                        default:
     485                                if ( is_ssl() ) {
     486                                        $cookie_name = SECURE_AUTH_COOKIE;
     487                                        $scheme = 'secure_auth';
     488                                } else {
     489                                        $cookie_name = AUTH_COOKIE;
     490                                        $scheme = 'auth';
     491                                }
     492                }
     493
     494                if ( empty($_COOKIE[$cookie_name]) )
     495                        return false;
     496                $cookie = $_COOKIE[$cookie_name];
     497        }
     498
     499        $cookie_elements = explode('|', $cookie);
     500        if ( count($cookie_elements) != 3 )
     501                return false;
     502
     503        list($username, $expiration, $hmac) = $cookie_elements;
     504
     505        return compact('username', 'expiration', 'hmac', 'scheme');
     506}
     507
     508/**
     509 * Sets the authentication cookies based User ID.
     510 *
     511 * The $remember parameter increases the time that the cookie will be kept. The
     512 * default the cookie is kept without remembering is two days. When $remember is
     513 * set, the cookies will be kept for 14 days or two weeks.
     514 *
     515 * This function should not be used directly. Use the pluggable version instead.
     516 * @see wp_set_auth_cookie()
     517 *
     518 * @since 2.8.0
     519 *
     520 * @param int $user_id User ID
     521 * @param bool $remember Whether to remember the user or not
     522 */
     523function _wp_set_auth_cookie( $user_id, $remember = false, $secure = '' ) {
     524        if ( $remember ) {
     525                $expiration = $expire = time() + apply_filters('auth_cookie_expiration', 1209600, $user_id, $remember);
     526        } else {
     527                $expiration = time() + apply_filters('auth_cookie_expiration', 172800, $user_id, $remember);
     528                $expire = 0;
     529        }
     530
     531        if ( '' === $secure )
     532                $secure = is_ssl() ? true : false;
     533
     534        if ( $secure ) {
     535                $auth_cookie_name = SECURE_AUTH_COOKIE;
     536                $scheme = 'secure_auth';
     537        } else {
     538                $auth_cookie_name = AUTH_COOKIE;
     539                $scheme = 'auth';
     540        }
     541
     542        $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme);
     543        $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in');
     544
     545        do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme);
     546        do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in');
     547
     548        // Set httponly if the php version is >= 5.2.0
     549        if ( version_compare(phpversion(), '5.2.0', 'ge') ) {
     550                setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true);
     551                setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true);
     552                setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, false, true);
     553                if ( COOKIEPATH != SITECOOKIEPATH )
     554                        setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, false, true);
     555        } else {
     556                $cookie_domain = COOKIE_DOMAIN;
     557                if ( !empty($cookie_domain) )
     558                        $cookie_domain .= '; HttpOnly';
     559                setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, $cookie_domain, $secure);
     560                setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, $cookie_domain, $secure);
     561                setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, $cookie_domain);
     562                if ( COOKIEPATH != SITECOOKIEPATH )
     563                        setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, $cookie_domain);
     564        }
     565}
     566
     567/**
     568 * Removes all of the cookies associated with authentication.
     569 *
     570 * This function should not be used directly. Use the pluggable version instead.
     571 * @see wp_clear_auth_cookie()
     572 *
     573 * @since 2.8.0
     574 */
     575function _wp_clear_auth_cookie() {
     576        do_action('clear_auth_cookie');
     577
     578        setcookie(AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
     579        setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
     580        setcookie(AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
     581        setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
     582        setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
     583        setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     584
     585        // Old cookies
     586        setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
     587        setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     588        setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
     589        setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     590
     591        // Even older cookies
     592        setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
     593        setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
     594        setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     595        setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
     596}
     597
     598/**
     599 * Checks if the current visitor is a logged in user.
     600 *
     601 * This function should not be used directly. Use the pluggable version instead.
     602 * @see is_user_logged_in()
     603 *
     604 * @since 2.8.0
     605 *
     606 * @return bool True if user is logged in, false if not logged in.
     607 */
     608function _is_user_logged_in() {
     609        $user = wp_get_current_user();
     610
     611        if ( $user->id == 0 )
     612                return false;
     613
     614        return true;
     615}
     616
     617/**
     618 * Checks if a user is logged in, if not it redirects them to the login page.
     619 *
     620 * This function should not be used directly. Use the pluggable version instead.
     621 * @see auth_redirect()
     622 *
     623 * @since 2.8.0
     624 */
     625function _auth_redirect() {
     626        if ( is_ssl() || force_ssl_admin() )
     627                $secure = true;
     628        else
     629                $secure = false;
     630
     631        // If https is required and request is http, redirect
     632        if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) {
     633                if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
     634                        wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
     635                        exit();
     636                } else {
     637                        wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
     638                        exit();
     639                }
     640        }
     641
     642        if ( $user_id = wp_validate_auth_cookie() ) {
     643                do_action('auth_redirect', $user_id);
     644
     645                // If the user wants ssl but the session is not ssl, redirect.
     646                if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) {
     647                        if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
     648                                wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']));
     649                                exit();
     650                        } else {
     651                                wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
     652                                exit();
     653                        }
     654                }
     655
     656                return;  // The cookie is good so we're done
     657        }
     658
     659        // The cookie is no good so force login
     660        nocache_headers();
     661
     662        if ( is_ssl() )
     663                $proto = 'https://';
     664        else
     665                $proto = 'http://';
     666
     667        $redirect = ( strpos($_SERVER['REQUEST_URI'], '/options.php') && wp_get_referer() ) ? wp_get_referer() : $proto . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
     668
     669        $login_url = wp_login_url($redirect);
     670
     671        wp_redirect($login_url);
     672        exit();
     673}
     674
     675/**
    133676 * Retrieve user data based on field.
    134677 *
    135678 * Use get_profile() will make a database query to get the value of the table
     
    191734        return true;
    192735}
    193736
     737/**
     738 * Updates the user's password with a new encrypted one.
     739 *
     740 * This function should not be used directly. Use the pluggable version instead.
     741 * @see wp_set_password()
     742 *
     743 * @since 2.8.0
     744 * @uses $wpdb WordPress database object for queries
     745 * @uses wp_hash_password() Used to encrypt the user's password before passing to the database
     746 *
     747 * @param string $password The plaintext new user password
     748 * @param int $user_id User ID
     749 */
     750function _wp_set_password( $password, $user_id ) {
     751        global $wpdb;
     752
     753        $hash = wp_hash_password($password);
     754        $wpdb->update($wpdb->users, array('user_pass' => $hash, 'user_activation_key' => ''), array('ID' => $user_id) );
     755
     756        wp_cache_delete($user_id, 'users');
     757}
     758
    194759//
    195760// User option functions
    196761//