Ticket #8833: 8833.5.patch
| File 8833.5.patch, 124.8 KB (added by Viper007Bond, 4 years ago) |
|---|
-
wp-includes/functions.php
37 37 if( 'U' == $dateformatstring ) 38 38 return $i; 39 39 40 if ( $translate )41 return date_i18n( $dateformatstring, $i );40 if ( $translate ) 41 return date_i18n( $dateformatstring, $i ); 42 42 else 43 return date( $dateformatstring, $i );43 return date( $dateformatstring, $i ); 44 44 } 45 45 46 46 /** … … 1694 1694 } 1695 1695 1696 1696 /** 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 */ 1711 function _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 */ 1735 function _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 */ 1768 function _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 /** 1697 1781 * Retrieve URL with nonce added to URL query. 1698 1782 * 1699 1783 * @package WordPress … … 1755 1839 } 1756 1840 1757 1841 /** 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 */ 1884 function _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 */ 1970 function _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 */ 1995 function _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 */ 2036 function _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 **/ 2080 function _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 */ 2107 function _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 /** 1758 2142 * Retrieve or display referer hidden field for forms. 1759 2143 * 1760 2144 * The referer link is the current Request URI from the server super global. The … … 1837 2221 } 1838 2222 1839 2223 /** 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 */ 2238 function _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 */ 2265 function _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 */ 2299 function _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 **/ 2334 function _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 **/ 2376 function _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 /** 1840 2399 * Recursive directory creation based on full path. 1841 2400 * 1842 2401 * Will attempt to set permissions on folders. … … 3146 3705 return $structure; 3147 3706 } 3148 3707 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 */ 3748 function _wp_mail( $existing = null, $to, $subject, $message, $headers = '', $attachments = array() ) { 3749 if ( null !== $existing ) 3750 return $existing; 3149 3751 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 */ 3955 function _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 */ 4042 function _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 */ 4112 function _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 */ 4132 function _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 */ 4184 function _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 3150 4229 ?> -
wp-includes/general-template.php
2013 2013 return apply_filters( "get_the_generator_{$type}", $gen, $type ); 2014 2014 } 2015 2015 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 */ 2031 function _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&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 .= '&d=' . urlencode( $default ); 2099 2100 $rating = get_option('avatar_rating'); 2101 if ( !empty( $rating ) ) 2102 $out .= "&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 2016 2112 ?> -
wp-includes/pluggable.php
19 19 * @param string $name Optional. The user's username 20 20 * @return object returns wp_set_current_user() 21 21 */ 22 function set_current_user( $id, $name = '') {23 return wp_set_current_user( $id, $name);22 function set_current_user( $id, $name = '' ) { 23 return wp_set_current_user( $id, $name ); 24 24 } 25 25 endif; 26 26 … … 30 30 * 31 31 * Set $id to null and specify a name if you do not know a user's ID. 32 32 * 33 * Some WordPress functionality is based on the current user and not based on 34 * the signed in user. Therefore, it opens the ability to edit and perform 35 * actions on users who aren't signed in. 33 * @see _wp_set_current_user() 36 34 * 37 35 * @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.40 36 * 41 37 * @param int $id User ID 42 38 * @param string $name User's username 43 39 * @return WP_User Current user User object 44 40 */ 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; 41 function wp_set_current_user( $id, $name = '' ) { 42 return apply_filters( 'pluggable-wp_set_current_user', null, $id, $name ); 58 43 } 44 add_filter( 'pluggable-wp_set_current_user', '_wp_set_current_user', 10, 3 ); 59 45 endif; 60 46 61 47 if ( !function_exists('wp_get_current_user') ) : 62 48 /** 63 49 * Retrieve the current user object. 64 50 * 51 * @see _wp_get_current_user() 52 * 65 53 * @since 2.0.3 66 54 * 67 55 * @return WP_User Current user WP_User object 68 56 */ 69 57 function 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 ); 75 59 } 60 add_filter( 'pluggable-wp_get_current_user', '_wp_get_current_user' ); 76 61 endif; 77 62 78 63 if ( !function_exists('get_currentuserinfo') ) : 79 64 /** 80 65 * Populate global variables with information about the currently logged in user. 81 66 * 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() 85 68 * 86 69 * @since 0.71 87 * @uses $current_user Checks if the current user is set88 * @uses wp_validate_auth_cookie() Retrieves current logged in user.89 70 * 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. 91 72 */ 92 73 function get_currentuserinfo() { 93 global $current_user; 94 95 if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) 96 return false; 97 98 if ( ! empty($current_user) ) 99 return; 100 101 if ( ! $user = wp_validate_auth_cookie() ) { 102 if ( empty($_COOKIE[LOGGED_IN_COOKIE]) || !$user = wp_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in') ) { 103 wp_set_current_user(0); 104 return false; 105 } 106 } 107 108 wp_set_current_user($user); 74 return apply_filters( 'pluggable-get_currentuserinfo', null ); 109 75 } 76 add_filter( 'pluggable-get_currentuserinfo', '_get_currentuserinfo' ); 110 77 endif; 111 78 112 79 if ( !function_exists('get_userdata') ) : 113 80 /** 114 81 * Retrieve user info by user ID. 115 82 * 83 * @see _get_userdata() 84 * 116 85 * @since 0.71 117 86 * 118 87 * @param int $user_id User ID 119 88 * @return bool|object False on failure, User DB row object 120 89 */ 121 90 function get_userdata( $user_id ) { 122 global $wpdb; 123 124 $user_id = absint($user_id); 125 if ( $user_id == 0 ) 126 return false; 127 128 $user = wp_cache_get($user_id, 'users'); 129 130 if ( $user ) 131 return $user; 132 133 if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id)) ) 134 return false; 135 136 _fill_user($user); 137 138 return $user; 91 return apply_filters( 'pluggable-get_userdata', null, $user_id ); 139 92 } 93 add_filter( 'pluggable-get_userdata', '_get_userdata', 10, 2 ); 140 94 endif; 141 95 142 96 if ( !function_exists('get_user_by') ) : 143 97 /** 144 98 * Retrieve user info by a given field 145 99 * 100 * @see _get_user_by() 101 * 146 102 * @since 2.8.0 147 103 * 148 104 * @param string $field The field to retrieve the user with. id | slug | email | login 149 105 * @param int|string $value A value for $field. A user ID, slug, email address, or login name. 150 106 * @return bool|object False on failure, User DB row object 151 107 */ 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; 108 function get_user_by( $field, $value ) { 109 return apply_filters( 'pluggable-get_user_by', null, $field, $value ); 185 110 } 111 add_filter( 'pluggable-get_user_by', '_get_user_by', 10, 3 ); 186 112 endif; 187 113 188 114 if ( !function_exists('get_userdatabylogin') ) : … … 194 120 * @param string $user_login User's username 195 121 * @return bool|object False on failure, User DB row object 196 122 */ 197 function get_userdatabylogin( $user_login) {198 return get_user_by( 'login', $user_login);123 function get_userdatabylogin( $user_login ) { 124 return get_user_by( 'login', $user_login ); 199 125 } 200 126 endif; 201 127 … … 208 134 * @param string $email User's email address 209 135 * @return bool|object False on failure, User DB row object 210 136 */ 211 function get_user_by_email( $email) {212 return get_user_by( 'email', $email);137 function get_user_by_email( $email ) { 138 return get_user_by( 'email', $email ); 213 139 } 214 140 endif; 215 141 … … 217 143 /** 218 144 * Send mail, similar to PHP's mail 219 145 * 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() 223 147 * 224 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from225 * creating a from address like 'Name <email@address.com>' when both are set. If226 * just 'wp_mail_from' is set, then just the email address will be used with no227 * 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 the231 * 'wp_mail_content_type' filter.232 *233 * The default charset is based on the charset used on the blog. The charset can234 * be set using the 'wp_mail_charset' filter.235 *236 148 * @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 charset242 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to243 * phpmailer object.244 * @uses PHPMailer245 * @246 149 * 247 150 * @param string $to Email address to send message 248 151 * @param string $subject Email subject … … 252 155 * @return bool Whether the email contents were sent successfully. 253 156 */ 254 157 function 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 ); 443 159 } 160 add_filter( 'pluggable-wp_mail', '_wp_mail', 10, 6 ); 444 161 endif; 445 162 446 163 if ( !function_exists('wp_authenticate') ) : 447 164 /** 448 165 * Checks a user's login information and logs them in if it checks out. 449 166 * 167 * @see _wp_authenticate() 168 * 450 169 * @since 2.5.0 451 170 * 452 171 * @param string $username User's username 453 172 * @param string $password User's password 454 173 * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object. 455 174 */ 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; 175 function wp_authenticate( $username, $password ) { 176 return apply_filters( 'pluggable-wp_authenticate', null, $username, $password ); 475 177 } 178 add_filter( 'pluggable-wp_authenticate', '_wp_authenticate', 10, 3 ); 476 179 endif; 477 180 478 181 if ( !function_exists('wp_logout') ) : 479 182 /** 480 183 * Log the current user out. 481 184 * 185 * @see _wp_logout() 186 * 482 187 * @since 2.5.0 483 188 */ 484 189 function wp_logout() { 485 wp_clear_auth_cookie(); 486 do_action('wp_logout'); 190 do_action( 'pluggable-wp_logout' ); 487 191 } 192 add_action( 'pluggable-wp_logout', '_wp_logout' ); 488 193 endif; 489 194 490 195 if ( !function_exists('wp_validate_auth_cookie') ) : 491 196 /** 492 197 * Validates authentication cookie. 493 198 * 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() 496 200 * 497 * Makes sure the cookie is not expired. Verifies the hash in cookie is what is498 * should be and compares the two.499 *500 201 * @since 2.5 501 202 * 502 203 * @param string $cookie Optional. If used, will validate contents instead of cookie's 503 204 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 504 205 * @return bool|int False if invalid cookie, User ID if valid. 505 206 */ 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; 207 function wp_validate_auth_cookie( $cookie = '', $scheme = '' ) { 208 return apply_filters( 'pluggable-wp_validate_auth_cookie', null, $cookie, $scheme ); 545 209 } 210 add_filter( 'pluggable-wp_validate_auth_cookie', '_wp_validate_auth_cookie', 10, 3 ); 546 211 endif; 547 212 548 213 if ( !function_exists('wp_generate_auth_cookie') ) : 549 214 /** 550 215 * Generate authentication cookie contents. 551 216 * 217 * @see _wp_generate_auth_cookie() 218 * 552 219 * @since 2.5 553 * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID554 * and expiration of cookie.555 220 * 556 221 * @param int $user_id User ID 557 222 * @param int $expiration Cookie expiration in seconds 558 223 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 559 224 * @return string Authentication cookie contents 560 225 */ 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); 226 function wp_generate_auth_cookie( $user_id, $expiration, $scheme = 'auth' ) { 227 return apply_filters( 'pluggable-wp_generate_auth_cookie', null, $user_id, $expiration, $scheme ); 572 228 } 229 add_filter( 'pluggable-wp_generate_auth_cookie', '_wp_generate_auth_cookie', 10, 4 ); 573 230 endif; 574 231 575 232 if ( !function_exists('wp_parse_auth_cookie') ) : 576 233 /** 577 234 * Parse a cookie into its components 578 235 * 236 * @see _wp_parse_auth_cookie() 237 * 579 238 * @since 2.7 580 239 * 581 240 * @param string $cookie 582 241 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in 583 242 * @return array Authentication cookie components 584 243 */ 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'); 244 function wp_parse_auth_cookie( $cookie = '', $scheme = '' ) { 245 return apply_filters( 'pluggable-wp_parse_auth_cookie', null, $cookie, $scheme ); 619 246 } 247 add_filter( 'pluggable-wp_parse_auth_cookie', '_wp_parse_auth_cookie', 10, 3 ); 620 248 endif; 621 249 622 250 if ( !function_exists('wp_set_auth_cookie') ) : … … 627 255 * default the cookie is kept without remembering is two days. When $remember is 628 256 * set, the cookies will be kept for 14 days or two weeks. 629 257 * 258 * @see _wp_set_auth_cookie() 259 * 630 260 * @since 2.5 631 261 * 632 262 * @param int $user_id User ID 633 263 * @param bool $remember Whether to remember the user or not 634 264 */ 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 } 265 function wp_set_auth_cookie( $user_id, $remember = false, $secure = '' ) { 266 do_action( 'pluggable-wp_set_auth_cookie', $user_id, $remember, $secure ); 677 267 } 268 add_action( 'pluggable-wp_set_auth_cookie', '_wp_set_auth_cookie', 10, 3 ); 678 269 endif; 679 270 680 271 if ( !function_exists('wp_clear_auth_cookie') ) : 681 272 /** 682 273 * Removes all of the cookies associated with authentication. 683 274 * 275 * @see _wp_clear_auth_cookie() 276 * 684 277 * @since 2.5 685 278 */ 686 279 function 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' ); 707 281 } 282 add_action( 'pluggable-wp_clear_auth_cookie', '_wp_clear_auth_cookie' ); 708 283 endif; 709 284 710 285 if ( !function_exists('is_user_logged_in') ) : 711 286 /** 712 287 * Checks if the current visitor is a logged in user. 713 288 * 289 * @see _is_user_logged_in() 290 * 714 291 * @since 2.0.0 715 292 * 716 293 * @return bool True if user is logged in, false if not logged in. 717 294 */ 718 295 function 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 ); 725 297 } 298 add_filter( 'pluggable-is_user_logged_in', '_is_user_logged_in' ); 726 299 endif; 727 300 728 301 if ( !function_exists('auth_redirect') ) : 729 302 /** 730 303 * Checks if a user is logged in, if not it redirects them to the login page. 731 304 * 305 * @see _auth_redirect() 306 * 732 307 * @since 1.5 733 308 */ 734 309 function 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' ); 784 311 } 312 add_action( 'pluggable-auth_redirect', '_auth_redirect' ); 785 313 endif; 786 314 787 315 if ( !function_exists('check_admin_referer') ) : … … 790 318 * 791 319 * To avoid security exploits. 792 320 * 321 * @see _check_admin_referer() 322 * 793 323 * @since 1.2.0 794 * @uses do_action() Calls 'check_admin_referer' on $action.795 324 * 796 325 * @param string $action Action nonce 797 326 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) 798 327 */ 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; 328 function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) { 329 return apply_filters( 'pluggable-check_admin_referer', null, $action, $query_arg ); 330 } 331 add_filter( 'pluggable-check_admin_referer', '_check_admin_referer', 10, 3 ); 332 endif; 810 333 811 334 if ( !function_exists('check_ajax_referer') ) : 812 335 /** 813 336 * Verifies the AJAX request to prevent processing requests external of the blog. 814 337 * 338 * @see _check_ajax_referer() 339 * 815 340 * @since 2.0.3 816 341 * 817 342 * @param string $action Action nonce 818 343 * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) 819 344 */ 820 345 function 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 ); 834 347 } 348 add_filter( 'pluggable-check_admin_referer', '_check_ajax_referer', 10, 4 ); 835 349 endif; 836 350 837 351 if ( !function_exists('wp_redirect') ) : 838 352 /** 839 * Redirects to another page , with a workaround for the IIS Set-Cookie bug.353 * Redirects to another page. 840 354 * 841 * @link http://support.microsoft.com/kb/q176113/ 355 * @see _wp_redirect() 356 * 842 357 * @since 1.5.1 843 * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.844 358 * 845 359 * @param string $location The path to redirect to 846 360 * @param int $status Status code to use 847 361 * @return bool False if $location is not set 848 362 */ 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 } 363 function wp_redirect( $location, $status = 302 ) { 364 return apply_filters( 'pluggable-wp_redirect', null, $location, $status ); 867 365 } 366 add_filter( 'pluggable-wp_redirect', '_wp_redirect', 10, 3 ); 868 367 endif; 869 368 870 369 if ( !function_exists('wp_sanitize_redirect') ) : 871 370 /** 872 371 * Sanitizes a URL for use in a redirect. 873 372 * 373 * @see _wp_sanitize_redirect() 374 * 874 375 * @since 2.3 875 376 * 876 377 * @return string redirect-sanitized URL 877 378 **/ 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; 379 function wp_sanitize_redirect( $location ) { 380 return apply_filters( 'pluggable-wp_sanitize_redirect', null, $location ); 895 381 } 382 add_filter( 'pluggable-wp_sanitize_redirect', '_wp_sanitize_redirect', 10, 2 ); 896 383 endif; 897 384 898 385 if ( !function_exists('wp_safe_redirect') ) : … … 907 394 * instead. This prevents malicious redirects which redirect to another host, 908 395 * but only used in a few places. 909 396 * 397 * @see _wp_safe_redirect() 398 * 910 399 * @since 2.3 911 400 * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing 912 401 * WordPress host string and $location host string. 913 402 * 914 403 * @return void Does not return anything 915 404 **/ 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); 405 function wp_safe_redirect( $location, $status = 302 ) { 406 do_action( 'pluggable-wp_safe_redirect', $location, $status ); 937 407 } 408 add_action( 'pluggable-wp_safe_redirect', '_wp_safe_redirect', 10, 2 ); 938 409 endif; 939 410 940 if ( ! function_exists('wp_notify_postauthor') ) :411 if ( !function_exists('wp_notify_postauthor') ) : 941 412 /** 942 413 * Notify an author of a comment/trackback/pingback to one of their posts. 943 414 * 415 * @see _wp_notify_postauthor() 416 * 944 417 * @since 1.0.0 945 418 * 946 419 * @param int $comment_id Comment ID 947 420 * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback' 948 421 * @return bool False if user email does not exist. True on completion. 949 422 */ 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; 423 function wp_notify_postauthor( $comment_id, $comment_type = '' ) { 424 return apply_filters( 'pluggable-wp_notify_postauthor', null, $comment_id, $comment_type ); 1019 425 } 426 add_filter( 'pluggable-wp_notify_postauthor', '_wp_notify_postauthor', 10, 3 ); 1020 427 endif; 1021 428 1022 429 if ( !function_exists('wp_notify_moderator') ) : 1023 430 /** 1024 431 * Notifies the moderator of the blog about a new comment that is awaiting approval. 1025 432 * 433 * @see _wp_notify_moderator() 434 * 1026 435 * @since 1.0 1027 * @uses $wpdb1028 436 * 1029 437 * @param int $comment_id Comment ID 1030 438 * @return bool Always returns true 1031 439 */ 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; 440 function wp_notify_moderator( $comment_id ) { 441 return apply_filters( 'pluggable-wp_notify_moderator', null, $comment_id ); 1088 442 } 443 add_filter( 'pluggable-wp_notify_moderator', '_wp_notify_moderator', 10, 2 ); 1089 444 endif; 1090 445 1091 446 if ( !function_exists('wp_password_change_notification') ) : 1092 447 /** 1093 448 * Notify the blog admin of a user changing password, normally via email. 1094 449 * 450 * @see _wp_password_change_notification() 451 * 1095 452 * @since 2.7 1096 453 * 1097 454 * @param object $user User Object 1098 455 */ 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 } 456 function wp_password_change_notification( &$user ) { 457 do_action( 'pluggable-wp_password_change_notification', $user ); 1106 458 } 459 add_action( 'pluggable-wp_password_change_notification', '_wp_password_change_notification' ); 1107 460 endif; 1108 461 1109 462 if ( !function_exists('wp_new_user_notification') ) : 1110 463 /** 1111 464 * Notify the blog admin of a new user, normally via email. 1112 465 * 466 * @see _wp_new_user_notification() 467 * 1113 468 * @since 2.0 1114 469 * 1115 470 * @param int $user_id User ID 1116 471 * @param string $plaintext_pass Optional. The user's plaintext password 1117 472 */ 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 473 function wp_new_user_notification( $user_id, $plaintext_pass = '' ) { 474 do_action( 'pluggable-wp_new_user_notification', $user_id, $plaintext_pass ); 1139 475 } 476 add_action( 'pluggable-wp_new_user_notification', '_wp_new_user_notification', 10, 2 ); 1140 477 endif; 1141 478 1142 479 if ( !function_exists('wp_nonce_tick') ) : 1143 480 /** 1144 481 * Get the time-dependent variable for nonce creation. 1145 482 * 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() 1148 484 * 1149 485 * @since 2.5 1150 486 * 1151 487 * @return int 1152 488 */ 1153 489 function 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 ); 1157 491 } 492 add_filter( 'pluggable-wp_nonce_tick', '_wp_nonce_tick' ); 1158 493 endif; 1159 494 1160 495 if ( !function_exists('wp_verify_nonce') ) : … … 1164 499 * The user is given an amount of time to use the token, so therefore, since the 1165 500 * UID and $action remain the same, the independent variable is the time. 1166 501 * 502 * @see _wp_verify_nonce() 503 * 1167 504 * @since 2.0.3 1168 505 * 1169 506 * @param string $nonce Nonce that was used in the form to verify 1170 507 * @param string|int $action Should give context to what is taking place and be the same when nonce was created. 1171 508 * @return bool Whether the nonce check passed or failed. 1172 509 */ 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; 510 function wp_verify_nonce( $nonce, $action = -1 ) { 511 return apply_filters( 'pluggable-wp_verify_nonce', null, $nonce, $action ); 1187 512 } 513 add_filter( 'pluggable-wp_verify_nonce', '_wp_verify_nonce', 10, 3 ); 1188 514 endif; 1189 515 1190 516 if ( !function_exists('wp_create_nonce') ) : 1191 517 /** 1192 518 * Creates a random, one time use token. 1193 519 * 520 * @see _wp_create_nonce() 521 * 1194 522 * @since 2.0.3 1195 523 * 1196 524 * @param string|int $action Scalar value to add context to the nonce. 1197 525 * @return string The one use form token 1198 526 */ 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); 527 function wp_create_nonce( $action = -1 ) { 528 return apply_filters( 'pluggable-wp_create_nonce', null, $action ); 1206 529 } 530 add_filter( 'pluggable-wp_create_nonce', '_wp_create_nonce', 10, 2 ); 1207 531 endif; 1208 532 1209 533 if ( !function_exists('wp_salt') ) : 1210 534 /** 1211 535 * Get salt to add to hashes to help prevent attacks. 1212 536 * 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() 1217 538 * 1218 * The secret key in the database is randomly generated and will be appended to1219 * the secret key that is in wp-config.php file in some instances. It is1220 * 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 the1223 * SECRET_KEY defined in the wp-config.php already. You will want to change the1224 * value in it because hackers will know what it is. If you have upgraded to1225 * WordPress 2.5 or later version from a version before WordPress 2.5, then you1226 * 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 you1230 * need an example, then you can have a1231 * {@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 of1238 * common dictionary strings. The added values makes it harder to crack if given1239 * salt string is not weak.1240 *1241 539 * @since 2.5 1242 540 * @link https://api.wordpress.org/secret-key/1.1/ Create a Secret Key for wp-config.php 1243 541 * 1244 542 * @return string Salt value from either 'SECRET_KEY' or 'secret' option 1245 543 */ 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); 544 function wp_salt( $scheme = 'auth' ) { 545 return apply_filters( 'pluggable-wp_salt', null, $scheme ); 1312 546 } 547 add_filter( 'pluggable-wp_salt', '_wp_salt', 10, 2 ); 1313 548 endif; 1314 549 1315 550 if ( !function_exists('wp_hash') ) : 1316 551 /** 1317 552 * Get hash of given string. 1318 553 * 554 * @see _wp_hash() 555 * 1319 556 * @since 2.0.3 1320 * @uses wp_salt() Get WordPress salt1321 557 * 1322 558 * @param string $data Plain text to hash 1323 559 * @return string Hash of $data 1324 560 */ 1325 function wp_hash($data, $scheme = 'auth') { 1326 $salt = wp_salt($scheme); 1327 1328 return hash_hmac('md5', $data, $salt); 561 function wp_hash( $data, $scheme = 'auth' ) { 562 return apply_filters( 'pluggable-wp_hash', null, $data, $scheme ); 1329 563 } 564 add_filter( 'pluggable-wp_hash', '_wp_hash', 10, 3 ); 1330 565 endif; 1331 566 1332 567 if ( !function_exists('wp_hash_password') ) : … … 1336 571 * For integration with other applications, this function can be overwritten to 1337 572 * instead use the other package password checking algorithm. 1338 573 * 574 * @see _wp_hash_password() 575 * 1339 576 * @since 2.5 1340 577 * @global object $wp_hasher PHPass object 1341 578 * @uses PasswordHash::HashPassword … … 1343 580 * @param string $password Plain text user password to hash 1344 581 * @return string The hash string of the password 1345 582 */ 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); 583 function wp_hash_password( $password ) { 584 return apply_filters( 'pluggable-wp_hash_password', null, $password ); 1356 585 } 586 add_filter( 'pluggable-wp_hash_password', '_wp_hash_password', 10, 2 ); 1357 587 endif; 1358 588 1359 589 if ( !function_exists('wp_check_password') ) : 1360 590 /** 1361 * Checks the plaintext password against the encrypted Password.591 * Checks the plaintext password against the encrypted password. 1362 592 * 1363 * Maintains compatibility between old version and the new cookie authentication1364 * protocol using PHPass library. The $hash parameter is the encrypted password1365 * and the function compares the plain text password when encypted similarly1366 * against the already encrypted password to see if they match.1367 *1368 593 * For integration with other applications, this function can be overwritten to 1369 594 * instead use the other package password checking algorithm. 1370 595 * 596 * @see _wp_check_password() 597 * 1371 598 * @since 2.5 1372 599 * @global object $wp_hasher PHPass object used for checking the password 1373 600 * against the $hash + $password … … 1377 604 * @param string $hash Hash of the user's password to check against. 1378 605 * @return bool False, if the $password does not match the hashed password 1379 606 */ 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); 607 function wp_check_password( $password, $hash, $user_id = '' ) { 608 return apply_filters( 'pluggable-wp_check_password', null, $password, $hash, $user_id ); 1406 609 } 610 add_filter( 'pluggable-wp_check_password', '_wp_check_password', 10, 4 ); 1407 611 endif; 1408 612 1409 613 if ( !function_exists('wp_generate_password') ) : 1410 614 /** 1411 * Generates a random password drawn from the defined set of characters.615 * Generates a random password. 1412 616 * 617 * @see _wp_generate_password() 618 * 1413 619 * @since 2.5 1414 620 * 1415 621 * @param int $length The length of password to generate 1416 622 * @param bool $special_chars Whether to include standard special characters 1417 623 * @return string The random password 1418 624 **/ 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; 625 function wp_generate_password( $length = 12, $special_chars = true ) { 626 return apply_filters( 'pluggable-wp_generate_password', null, $length, $special_chars ); 1428 627 } 628 add_filter( 'pluggable-wp_generate_password', '_wp_generate_password', 10, 3 ); 1429 629 endif; 1430 630 1431 631 if ( !function_exists('wp_rand') ) : 1432 /**632 /** 1433 633 * Generates a random number 1434 634 * 635 * @see _wp_rand() 636 * 1435 637 * @since 2.6.2 1436 638 * 1437 639 * @param int $min Lower limit for the generated number (optional, default is 0) … … 1439 641 * @return int A random number between min and max 1440 642 */ 1441 643 function 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 ); 1470 645 } 646 add_filter( 'pluggable-wp_rand', '_wp_rand', 10, 3 ); 1471 647 endif; 1472 648 1473 649 if ( !function_exists('wp_set_password') ) : … … 1477 653 * For integration with other applications, this function can be overwritten to 1478 654 * instead use the other package password checking algorithm. 1479 655 * 656 * @see _wp_set_password() 657 * 1480 658 * @since 2.5 1481 659 * @uses $wpdb WordPress database object for queries 1482 660 * @uses wp_hash_password() Used to encrypt the user's password before passing to the database … … 1485 663 * @param int $user_id User ID 1486 664 */ 1487 665 function 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 ); 1494 667 } 668 add_action( 'pluggable-wp_set_password', '_wp_set_password', 10, 2 ); 1495 669 endif; 1496 670 1497 671 if ( !function_exists( 'get_avatar' ) ) : 1498 672 /** 1499 673 * Retrieve the avatar for a user who provided a user ID or email address. 1500 674 * 675 * @see _get_avatar() 676 * 1501 677 * @since 2.5 1502 678 * @param int|string|object $id_or_email A user ID, email address, or comment object 1503 679 * @param int $size Size of the avatar image … … 1506 682 * @return string <img> tag for the user's avatar 1507 683 */ 1508 684 function 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&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 .= '&d=' . urlencode( $default ); 1573 1574 $rating = get_option('avatar_rating'); 1575 if ( !empty( $rating ) ) 1576 $out .= "&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 ); 1584 686 } 687 add_filter( 'pluggable-get_avatar', '_get_avatar', 10, 5 ); 1585 688 endif; 1586 689 1587 690 if ( !function_exists('wp_setcookie') ) : … … 1658 761 * @param bool $deprecated Not used 1659 762 * @return bool False on login failure, true on successful check 1660 763 */ 1661 function wp_login( $username, $password, $deprecated = '') {764 function wp_login( $username, $password, $deprecated = '' ) { 1662 765 global $error; 1663 766 1664 767 $user = wp_authenticate($username, $password); … … 1679 782 * HTML, so the primary use is for displaying the changes. If the two strings 1680 783 * are equivalent, then an empty string will be returned. 1681 784 * 1682 * The arguments supported and can be changed are listed below.785 * @see _wp_text_diff() 1683 786 * 1684 * 'title' : Default is an empty string. Titles the diff in a manner compatible1685 * with the output.1686 * 'title_left' : Default is an empty string. Change the HTML to the left of the1687 * title.1688 * 'title_right' : Default is an empty string. Change the HTML to the right of1689 * the title.1690 *1691 787 * @since 2.6 1692 788 * @see wp_parse_args() Used to change defaults to user defined settings. 1693 789 * @uses Text_Diff … … 1699 795 * @return string Empty string if strings are equivalent or HTML with differences. 1700 796 */ 1701 797 function 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 ); 1741 799 } 800 add_filter( 'pluggable-wp_text_diff', '_wp_text_diff', 10, 4 ); 1742 801 endif; 1743 802 1744 803 ?> -
wp-includes/user.php
130 130 } 131 131 132 132 /** 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 */ 153 function _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 */ 182 function _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 */ 206 function _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 */ 237 function _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 */ 273 function _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 */ 324 function _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 */ 356 function _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 */ 380 function _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 */ 440 function _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 */ 469 function _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 */ 523 function _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 */ 575 function _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 */ 608 function _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 */ 625 function _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 /** 133 676 * Retrieve user data based on field. 134 677 * 135 678 * Use get_profile() will make a database query to get the value of the table … … 191 734 return true; 192 735 } 193 736 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 */ 750 function _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 194 759 // 195 760 // User option functions 196 761 //
