WordPress.org

Make WordPress Core

Ticket #8833: 8833.3.patch

File 8833.3.patch, 124.8 KB (added by Viper007Bond, 5 years ago)

Working as far as I can tell, needs testing and feedback

  • 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//