1730 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option(). |
1743 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option(). |
1731 * We want to reverse this for the plain text arena of emails. |
1744 * We want to reverse this for the plain text arena of emails. |
1732 */ |
1745 */ |
1733 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
1746 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
1734 $comment_content = wp_specialchars_decode( $comment->comment_content ); |
1747 $comment_content = wp_specialchars_decode( $comment->comment_content ); |
1735 |
|
1736 switch ( $comment->comment_type ) { |
|
1737 case 'trackback': |
|
1738 /* translators: %s: Post title. */ |
|
1739 $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1740 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1741 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1742 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1743 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1744 /* translators: %s: Comment text. */ |
|
1745 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1746 $notify_message .= __( 'You can see all trackbacks on this post here:' ) . "\r\n"; |
|
1747 /* translators: Trackback notification email subject. 1: Site title, 2: Post title. */ |
|
1748 $subject = sprintf( __( '[%1$s] Trackback: "%2$s"' ), $blogname, $post->post_title ); |
|
1749 break; |
|
1750 |
|
1751 case 'pingback': |
|
1752 /* translators: %s: Post title. */ |
|
1753 $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1754 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1755 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1756 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1757 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1758 /* translators: %s: Comment text. */ |
|
1759 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1760 $notify_message .= __( 'You can see all pingbacks on this post here:' ) . "\r\n"; |
|
1761 /* translators: Pingback notification email subject. 1: Site title, 2: Post title. */ |
|
1762 $subject = sprintf( __( '[%1$s] Pingback: "%2$s"' ), $blogname, $post->post_title ); |
|
1763 break; |
|
1764 |
|
1765 default: // Comments. |
|
1766 /* translators: %s: Post title. */ |
|
1767 $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1768 /* translators: 1: Comment author's name, 2: Comment author's IP address, 3: Comment author's hostname. */ |
|
1769 $notify_message .= sprintf( __( 'Author: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1770 /* translators: %s: Comment author email. */ |
|
1771 $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; |
|
1772 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1773 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1774 |
|
1775 if ( $comment->comment_parent && user_can( $post->post_author, 'edit_comment', $comment->comment_parent ) ) { |
|
1776 /* translators: Comment moderation. %s: Parent comment edit URL. */ |
|
1777 $notify_message .= sprintf( __( 'In reply to: %s' ), admin_url( "comment.php?action=editcomment&c={$comment->comment_parent}#wpbody-content" ) ) . "\r\n"; |
|
1778 } |
|
1779 |
|
1780 /* translators: %s: Comment text. */ |
|
1781 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1782 $notify_message .= __( 'You can see all comments on this post here:' ) . "\r\n"; |
|
1783 /* translators: Comment notification email subject. 1: Site title, 2: Post title. */ |
|
1784 $subject = sprintf( __( '[%1$s] Comment: "%2$s"' ), $blogname, $post->post_title ); |
|
1785 break; |
|
1786 } |
|
1787 |
|
1788 $notify_message .= get_permalink( $comment->comment_post_ID ) . "#comments\r\n\r\n"; |
|
1789 /* translators: %s: Comment URL. */ |
|
1790 $notify_message .= sprintf( __( 'Permalink: %s' ), get_comment_link( $comment ) ) . "\r\n"; |
|
1791 |
|
1792 if ( user_can( $post->post_author, 'edit_comment', $comment->comment_ID ) ) { |
|
1793 if ( EMPTY_TRASH_DAYS ) { |
|
1794 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1795 $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1796 } else { |
|
1797 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1798 $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1799 } |
|
1800 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1801 $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1802 } |
|
1803 |
1748 |
1804 $wp_email = 'wordpress@' . preg_replace( '#^www\.#', '', wp_parse_url( network_home_url(), PHP_URL_HOST ) ); |
1749 $wp_email = 'wordpress@' . preg_replace( '#^www\.#', '', wp_parse_url( network_home_url(), PHP_URL_HOST ) ); |
1805 |
1750 |
1806 if ( '' === $comment->comment_author ) { |
1751 if ( '' === $comment->comment_author ) { |
1807 $from = "From: \"$blogname\" <$wp_email>"; |
1752 $from = "From: \"$blogname\" <$wp_email>"; |
1821 if ( isset( $reply_to ) ) { |
1766 if ( isset( $reply_to ) ) { |
1822 $message_headers .= $reply_to . "\n"; |
1767 $message_headers .= $reply_to . "\n"; |
1823 } |
1768 } |
1824 |
1769 |
1825 /** |
1770 /** |
1826 * Filters the comment notification email text. |
|
1827 * |
|
1828 * @since 1.5.2 |
|
1829 * |
|
1830 * @param string $notify_message The comment notification email text. |
|
1831 * @param string $comment_id Comment ID as a numeric string. |
|
1832 */ |
|
1833 $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment->comment_ID ); |
|
1834 |
|
1835 /** |
|
1836 * Filters the comment notification email subject. |
|
1837 * |
|
1838 * @since 1.5.2 |
|
1839 * |
|
1840 * @param string $subject The comment notification email subject. |
|
1841 * @param string $comment_id Comment ID as a numeric string. |
|
1842 */ |
|
1843 $subject = apply_filters( 'comment_notification_subject', $subject, $comment->comment_ID ); |
|
1844 |
|
1845 /** |
|
1846 * Filters the comment notification email headers. |
1771 * Filters the comment notification email headers. |
1847 * |
1772 * |
1848 * @since 1.5.2 |
1773 * @since 1.5.2 |
1849 * |
1774 * |
1850 * @param string $message_headers Headers for the comment notification email. |
1775 * @param string $message_headers Headers for the comment notification email. |
1851 * @param string $comment_id Comment ID as a numeric string. |
1776 * @param string $comment_id Comment ID as a numeric string. |
1852 */ |
1777 */ |
1853 $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment->comment_ID ); |
1778 $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment->comment_ID ); |
1854 |
1779 |
1855 foreach ( $emails as $email ) { |
1780 foreach ( $emails as $email ) { |
|
1781 $user = get_user_by( 'email', $email ); |
|
1782 |
|
1783 if ( $user ) { |
|
1784 $switched_locale = switch_to_user_locale( $user->ID ); |
|
1785 } else { |
|
1786 $switched_locale = switch_to_locale( get_locale() ); |
|
1787 } |
|
1788 |
|
1789 switch ( $comment->comment_type ) { |
|
1790 case 'trackback': |
|
1791 /* translators: %s: Post title. */ |
|
1792 $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1793 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1794 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1795 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1796 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1797 /* translators: %s: Comment text. */ |
|
1798 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1799 $notify_message .= __( 'You can see all trackbacks on this post here:' ) . "\r\n"; |
|
1800 /* translators: Trackback notification email subject. 1: Site title, 2: Post title. */ |
|
1801 $subject = sprintf( __( '[%1$s] Trackback: "%2$s"' ), $blogname, $post->post_title ); |
|
1802 break; |
|
1803 |
|
1804 case 'pingback': |
|
1805 /* translators: %s: Post title. */ |
|
1806 $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1807 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1808 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1809 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1810 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1811 /* translators: %s: Comment text. */ |
|
1812 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1813 $notify_message .= __( 'You can see all pingbacks on this post here:' ) . "\r\n"; |
|
1814 /* translators: Pingback notification email subject. 1: Site title, 2: Post title. */ |
|
1815 $subject = sprintf( __( '[%1$s] Pingback: "%2$s"' ), $blogname, $post->post_title ); |
|
1816 break; |
|
1817 |
|
1818 default: // Comments. |
|
1819 /* translators: %s: Post title. */ |
|
1820 $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; |
|
1821 /* translators: 1: Comment author's name, 2: Comment author's IP address, 3: Comment author's hostname. */ |
|
1822 $notify_message .= sprintf( __( 'Author: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1823 /* translators: %s: Comment author email. */ |
|
1824 $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; |
|
1825 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1826 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1827 |
|
1828 if ( $comment->comment_parent && user_can( $post->post_author, 'edit_comment', $comment->comment_parent ) ) { |
|
1829 /* translators: Comment moderation. %s: Parent comment edit URL. */ |
|
1830 $notify_message .= sprintf( __( 'In reply to: %s' ), admin_url( "comment.php?action=editcomment&c={$comment->comment_parent}#wpbody-content" ) ) . "\r\n"; |
|
1831 } |
|
1832 |
|
1833 /* translators: %s: Comment text. */ |
|
1834 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1835 $notify_message .= __( 'You can see all comments on this post here:' ) . "\r\n"; |
|
1836 /* translators: Comment notification email subject. 1: Site title, 2: Post title. */ |
|
1837 $subject = sprintf( __( '[%1$s] Comment: "%2$s"' ), $blogname, $post->post_title ); |
|
1838 break; |
|
1839 } |
|
1840 |
|
1841 $notify_message .= get_permalink( $comment->comment_post_ID ) . "#comments\r\n\r\n"; |
|
1842 /* translators: %s: Comment URL. */ |
|
1843 $notify_message .= sprintf( __( 'Permalink: %s' ), get_comment_link( $comment ) ) . "\r\n"; |
|
1844 |
|
1845 if ( user_can( $post->post_author, 'edit_comment', $comment->comment_ID ) ) { |
|
1846 if ( EMPTY_TRASH_DAYS ) { |
|
1847 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1848 $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1849 } else { |
|
1850 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1851 $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1852 } |
|
1853 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1854 $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n"; |
|
1855 } |
|
1856 |
|
1857 /** |
|
1858 * Filters the comment notification email text. |
|
1859 * |
|
1860 * @since 1.5.2 |
|
1861 * |
|
1862 * @param string $notify_message The comment notification email text. |
|
1863 * @param string $comment_id Comment ID as a numeric string. |
|
1864 */ |
|
1865 $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment->comment_ID ); |
|
1866 |
|
1867 /** |
|
1868 * Filters the comment notification email subject. |
|
1869 * |
|
1870 * @since 1.5.2 |
|
1871 * |
|
1872 * @param string $subject The comment notification email subject. |
|
1873 * @param string $comment_id Comment ID as a numeric string. |
|
1874 */ |
|
1875 $subject = apply_filters( 'comment_notification_subject', $subject, $comment->comment_ID ); |
|
1876 |
1856 wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
1877 wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
1857 } |
1878 |
1858 |
1879 if ( $switched_locale ) { |
1859 if ( $switched_locale ) { |
1880 restore_previous_locale(); |
1860 restore_previous_locale(); |
1881 } |
1861 } |
1882 } |
1862 |
1883 |
1863 return true; |
1884 return true; |
1864 } |
1885 } |
1865 endif; |
1886 endif; |
1922 * We want to reverse this for the plain text arena of emails. |
1941 * We want to reverse this for the plain text arena of emails. |
1923 */ |
1942 */ |
1924 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
1943 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
1925 $comment_content = wp_specialchars_decode( $comment->comment_content ); |
1944 $comment_content = wp_specialchars_decode( $comment->comment_content ); |
1926 |
1945 |
1927 switch ( $comment->comment_type ) { |
|
1928 case 'trackback': |
|
1929 /* translators: %s: Post title. */ |
|
1930 $notify_message = sprintf( __( 'A new trackback on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
1931 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
1932 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1933 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1934 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1935 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1936 $notify_message .= __( 'Trackback excerpt: ' ) . "\r\n" . $comment_content . "\r\n\r\n"; |
|
1937 break; |
|
1938 |
|
1939 case 'pingback': |
|
1940 /* translators: %s: Post title. */ |
|
1941 $notify_message = sprintf( __( 'A new pingback on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
1942 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
1943 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1944 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1945 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1946 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1947 $notify_message .= __( 'Pingback excerpt: ' ) . "\r\n" . $comment_content . "\r\n\r\n"; |
|
1948 break; |
|
1949 |
|
1950 default: // Comments. |
|
1951 /* translators: %s: Post title. */ |
|
1952 $notify_message = sprintf( __( 'A new comment on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
1953 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
1954 /* translators: 1: Comment author's name, 2: Comment author's IP address, 3: Comment author's hostname. */ |
|
1955 $notify_message .= sprintf( __( 'Author: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1956 /* translators: %s: Comment author email. */ |
|
1957 $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; |
|
1958 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1959 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1960 |
|
1961 if ( $comment->comment_parent ) { |
|
1962 /* translators: Comment moderation. %s: Parent comment edit URL. */ |
|
1963 $notify_message .= sprintf( __( 'In reply to: %s' ), admin_url( "comment.php?action=editcomment&c={$comment->comment_parent}#wpbody-content" ) ) . "\r\n"; |
|
1964 } |
|
1965 |
|
1966 /* translators: %s: Comment text. */ |
|
1967 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
1968 break; |
|
1969 } |
|
1970 |
|
1971 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1972 $notify_message .= sprintf( __( 'Approve it: %s' ), admin_url( "comment.php?action=approve&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
1973 |
|
1974 if ( EMPTY_TRASH_DAYS ) { |
|
1975 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1976 $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
1977 } else { |
|
1978 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1979 $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
1980 } |
|
1981 |
|
1982 /* translators: Comment moderation. %s: Comment action URL. */ |
|
1983 $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
1984 |
|
1985 $notify_message .= sprintf( |
|
1986 /* translators: Comment moderation. %s: Number of comments awaiting approval. */ |
|
1987 _n( |
|
1988 'Currently %s comment is waiting for approval. Please visit the moderation panel:', |
|
1989 'Currently %s comments are waiting for approval. Please visit the moderation panel:', |
|
1990 $comments_waiting |
|
1991 ), |
|
1992 number_format_i18n( $comments_waiting ) |
|
1993 ) . "\r\n"; |
|
1994 $notify_message .= admin_url( 'edit-comments.php?comment_status=moderated#wpbody-content' ) . "\r\n"; |
|
1995 |
|
1996 /* translators: Comment moderation notification email subject. 1: Site title, 2: Post title. */ |
|
1997 $subject = sprintf( __( '[%1$s] Please moderate: "%2$s"' ), $blogname, $post->post_title ); |
|
1998 $message_headers = ''; |
1946 $message_headers = ''; |
1999 |
1947 |
2000 /** |
1948 /** |
2001 * Filters the list of recipients for comment moderation emails. |
1949 * Filters the list of recipients for comment moderation emails. |
2002 * |
1950 * |
2006 * @param int $comment_id Comment ID. |
1954 * @param int $comment_id Comment ID. |
2007 */ |
1955 */ |
2008 $emails = apply_filters( 'comment_moderation_recipients', $emails, $comment_id ); |
1956 $emails = apply_filters( 'comment_moderation_recipients', $emails, $comment_id ); |
2009 |
1957 |
2010 /** |
1958 /** |
2011 * Filters the comment moderation email text. |
|
2012 * |
|
2013 * @since 1.5.2 |
|
2014 * |
|
2015 * @param string $notify_message Text of the comment moderation email. |
|
2016 * @param int $comment_id Comment ID. |
|
2017 */ |
|
2018 $notify_message = apply_filters( 'comment_moderation_text', $notify_message, $comment_id ); |
|
2019 |
|
2020 /** |
|
2021 * Filters the comment moderation email subject. |
|
2022 * |
|
2023 * @since 1.5.2 |
|
2024 * |
|
2025 * @param string $subject Subject of the comment moderation email. |
|
2026 * @param int $comment_id Comment ID. |
|
2027 */ |
|
2028 $subject = apply_filters( 'comment_moderation_subject', $subject, $comment_id ); |
|
2029 |
|
2030 /** |
|
2031 * Filters the comment moderation email headers. |
1959 * Filters the comment moderation email headers. |
2032 * |
1960 * |
2033 * @since 2.8.0 |
1961 * @since 2.8.0 |
2034 * |
1962 * |
2035 * @param string $message_headers Headers for the comment moderation email. |
1963 * @param string $message_headers Headers for the comment moderation email. |
2036 * @param int $comment_id Comment ID. |
1964 * @param int $comment_id Comment ID. |
2037 */ |
1965 */ |
2038 $message_headers = apply_filters( 'comment_moderation_headers', $message_headers, $comment_id ); |
1966 $message_headers = apply_filters( 'comment_moderation_headers', $message_headers, $comment_id ); |
2039 |
1967 |
2040 foreach ( $emails as $email ) { |
1968 foreach ( $emails as $email ) { |
|
1969 $user = get_user_by( 'email', $email ); |
|
1970 |
|
1971 if ( $user ) { |
|
1972 $switched_locale = switch_to_user_locale( $user->ID ); |
|
1973 } else { |
|
1974 $switched_locale = switch_to_locale( get_locale() ); |
|
1975 } |
|
1976 |
|
1977 switch ( $comment->comment_type ) { |
|
1978 case 'trackback': |
|
1979 /* translators: %s: Post title. */ |
|
1980 $notify_message = sprintf( __( 'A new trackback on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
1981 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
1982 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1983 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1984 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1985 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1986 $notify_message .= __( 'Trackback excerpt: ' ) . "\r\n" . $comment_content . "\r\n\r\n"; |
|
1987 break; |
|
1988 |
|
1989 case 'pingback': |
|
1990 /* translators: %s: Post title. */ |
|
1991 $notify_message = sprintf( __( 'A new pingback on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
1992 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
1993 /* translators: 1: Trackback/pingback website name, 2: Website IP address, 3: Website hostname. */ |
|
1994 $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
1995 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
1996 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
1997 $notify_message .= __( 'Pingback excerpt: ' ) . "\r\n" . $comment_content . "\r\n\r\n"; |
|
1998 break; |
|
1999 |
|
2000 default: // Comments. |
|
2001 /* translators: %s: Post title. */ |
|
2002 $notify_message = sprintf( __( 'A new comment on the post "%s" is waiting for your approval' ), $post->post_title ) . "\r\n"; |
|
2003 $notify_message .= get_permalink( $comment->comment_post_ID ) . "\r\n\r\n"; |
|
2004 /* translators: 1: Comment author's name, 2: Comment author's IP address, 3: Comment author's hostname. */ |
|
2005 $notify_message .= sprintf( __( 'Author: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
|
2006 /* translators: %s: Comment author email. */ |
|
2007 $notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n"; |
|
2008 /* translators: %s: Trackback/pingback/comment author URL. */ |
|
2009 $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; |
|
2010 |
|
2011 if ( $comment->comment_parent ) { |
|
2012 /* translators: Comment moderation. %s: Parent comment edit URL. */ |
|
2013 $notify_message .= sprintf( __( 'In reply to: %s' ), admin_url( "comment.php?action=editcomment&c={$comment->comment_parent}#wpbody-content" ) ) . "\r\n"; |
|
2014 } |
|
2015 |
|
2016 /* translators: %s: Comment text. */ |
|
2017 $notify_message .= sprintf( __( 'Comment: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; |
|
2018 break; |
|
2019 } |
|
2020 |
|
2021 /* translators: Comment moderation. %s: Comment action URL. */ |
|
2022 $notify_message .= sprintf( __( 'Approve it: %s' ), admin_url( "comment.php?action=approve&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
2023 |
|
2024 if ( EMPTY_TRASH_DAYS ) { |
|
2025 /* translators: Comment moderation. %s: Comment action URL. */ |
|
2026 $notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
2027 } else { |
|
2028 /* translators: Comment moderation. %s: Comment action URL. */ |
|
2029 $notify_message .= sprintf( __( 'Delete it: %s' ), admin_url( "comment.php?action=delete&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
2030 } |
|
2031 |
|
2032 /* translators: Comment moderation. %s: Comment action URL. */ |
|
2033 $notify_message .= sprintf( __( 'Spam it: %s' ), admin_url( "comment.php?action=spam&c={$comment_id}#wpbody-content" ) ) . "\r\n"; |
|
2034 |
|
2035 $notify_message .= sprintf( |
|
2036 /* translators: Comment moderation. %s: Number of comments awaiting approval. */ |
|
2037 _n( |
|
2038 'Currently %s comment is waiting for approval. Please visit the moderation panel:', |
|
2039 'Currently %s comments are waiting for approval. Please visit the moderation panel:', |
|
2040 $comments_waiting |
|
2041 ), |
|
2042 number_format_i18n( $comments_waiting ) |
|
2043 ) . "\r\n"; |
|
2044 $notify_message .= admin_url( 'edit-comments.php?comment_status=moderated#wpbody-content' ) . "\r\n"; |
|
2045 |
|
2046 /* translators: Comment moderation notification email subject. 1: Site title, 2: Post title. */ |
|
2047 $subject = sprintf( __( '[%1$s] Please moderate: "%2$s"' ), $blogname, $post->post_title ); |
|
2048 |
|
2049 /** |
|
2050 * Filters the comment moderation email text. |
|
2051 * |
|
2052 * @since 1.5.2 |
|
2053 * |
|
2054 * @param string $notify_message Text of the comment moderation email. |
|
2055 * @param int $comment_id Comment ID. |
|
2056 */ |
|
2057 $notify_message = apply_filters( 'comment_moderation_text', $notify_message, $comment_id ); |
|
2058 |
|
2059 /** |
|
2060 * Filters the comment moderation email subject. |
|
2061 * |
|
2062 * @since 1.5.2 |
|
2063 * |
|
2064 * @param string $subject Subject of the comment moderation email. |
|
2065 * @param int $comment_id Comment ID. |
|
2066 */ |
|
2067 $subject = apply_filters( 'comment_moderation_subject', $subject, $comment_id ); |
|
2068 |
2041 wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
2069 wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
2042 } |
2070 |
2043 |
2071 if ( $switched_locale ) { |
2044 if ( $switched_locale ) { |
2072 restore_previous_locale(); |
2045 restore_previous_locale(); |
2073 } |
2046 } |
2074 } |
2047 |
2075 |
2048 return true; |
2076 return true; |
2049 } |
2077 } |
2050 endif; |
2078 endif; |
2436 return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); |
2492 return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); |
2437 } |
2493 } |
2438 |
2494 |
2439 static $duplicated_keys; |
2495 static $duplicated_keys; |
2440 if ( null === $duplicated_keys ) { |
2496 if ( null === $duplicated_keys ) { |
2441 $duplicated_keys = array( |
2497 $duplicated_keys = array(); |
2442 'put your unique phrase here' => true, |
|
2443 ); |
|
2444 |
|
2445 /* |
|
2446 * translators: This string should only be translated if wp-config-sample.php is localized. |
|
2447 * You can check the localized release package or |
|
2448 * https://i18n.svn.wordpress.org/<locale code>/branches/<wp version>/dist/wp-config-sample.php |
|
2449 */ |
|
2450 $duplicated_keys[ __( 'put your unique phrase here' ) ] = true; |
|
2451 |
2498 |
2452 foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) { |
2499 foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) { |
2453 foreach ( array( 'KEY', 'SALT' ) as $second ) { |
2500 foreach ( array( 'KEY', 'SALT' ) as $second ) { |
2454 if ( ! defined( "{$first}_{$second}" ) ) { |
2501 if ( ! defined( "{$first}_{$second}" ) ) { |
2455 continue; |
2502 continue; |
2456 } |
2503 } |
2457 $value = constant( "{$first}_{$second}" ); |
2504 $value = constant( "{$first}_{$second}" ); |
2458 $duplicated_keys[ $value ] = isset( $duplicated_keys[ $value ] ); |
2505 $duplicated_keys[ $value ] = isset( $duplicated_keys[ $value ] ); |
2459 } |
2506 } |
2460 } |
2507 } |
|
2508 |
|
2509 $duplicated_keys['put your unique phrase here'] = true; |
|
2510 |
|
2511 /* |
|
2512 * translators: This string should only be translated if wp-config-sample.php is localized. |
|
2513 * You can check the localized release package or |
|
2514 * https://i18n.svn.wordpress.org/<locale code>/branches/<wp version>/dist/wp-config-sample.php |
|
2515 */ |
|
2516 $duplicated_keys[ __( 'put your unique phrase here' ) ] = true; |
|
2517 } |
|
2518 |
|
2519 /* |
|
2520 * Determine which options to prime. |
|
2521 * |
|
2522 * If the salt keys are undefined, use a duplicate value or the |
|
2523 * default `put your unique phrase here` value the salt will be |
|
2524 * generated via `wp_generate_password()` and stored as a site |
|
2525 * option. These options will be primed to avoid repeated |
|
2526 * database requests for undefined salts. |
|
2527 */ |
|
2528 $options_to_prime = array(); |
|
2529 foreach ( array( 'auth', 'secure_auth', 'logged_in', 'nonce' ) as $key ) { |
|
2530 foreach ( array( 'key', 'salt' ) as $second ) { |
|
2531 $const = strtoupper( "{$key}_{$second}" ); |
|
2532 if ( ! defined( $const ) || true === $duplicated_keys[ constant( $const ) ] ) { |
|
2533 $options_to_prime[] = "{$key}_{$second}"; |
|
2534 } |
|
2535 } |
|
2536 } |
|
2537 |
|
2538 if ( ! empty( $options_to_prime ) ) { |
|
2539 /* |
|
2540 * Also prime `secret_key` used for undefined salting schemes. |
|
2541 * |
|
2542 * If the scheme is unknown, the default value for `secret_key` will be |
|
2543 * used too for the salt. This should rarely happen, so the option is only |
|
2544 * primed if other salts are undefined. |
|
2545 * |
|
2546 * At this point of execution it is known that a database call will be made |
|
2547 * to prime salts, so the `secret_key` option can be primed regardless of the |
|
2548 * constants status. |
|
2549 */ |
|
2550 $options_to_prime[] = 'secret_key'; |
|
2551 wp_prime_site_option_caches( $options_to_prime ); |
2461 } |
2552 } |
2462 |
2553 |
2463 $values = array( |
2554 $values = array( |
2464 'key' => '', |
2555 'key' => '', |
2465 'salt' => '', |
2556 'salt' => '', |
2502 } |
2593 } |
2503 endif; |
2594 endif; |
2504 |
2595 |
2505 if ( ! function_exists( 'wp_hash' ) ) : |
2596 if ( ! function_exists( 'wp_hash' ) ) : |
2506 /** |
2597 /** |
2507 * Gets hash of given string. |
2598 * Gets the hash of the given string. |
|
2599 * |
|
2600 * The default algorithm is md5 but can be changed to any algorithm supported by |
|
2601 * `hash_hmac()`. Use the `hash_hmac_algos()` function to check the supported |
|
2602 * algorithms. |
2508 * |
2603 * |
2509 * @since 2.0.3 |
2604 * @since 2.0.3 |
|
2605 * @since 6.8.0 The `$algo` parameter was added. |
|
2606 * |
|
2607 * @throws InvalidArgumentException if the hashing algorithm is not supported. |
2510 * |
2608 * |
2511 * @param string $data Plain text to hash. |
2609 * @param string $data Plain text to hash. |
2512 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce). |
2610 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce). |
|
2611 * @param string $algo Hashing algorithm to use. Default: 'md5'. |
2513 * @return string Hash of $data. |
2612 * @return string Hash of $data. |
2514 */ |
2613 */ |
2515 function wp_hash( $data, $scheme = 'auth' ) { |
2614 function wp_hash( $data, $scheme = 'auth', $algo = 'md5' ) { |
2516 $salt = wp_salt( $scheme ); |
2615 $salt = wp_salt( $scheme ); |
2517 |
2616 |
2518 return hash_hmac( 'md5', $data, $salt ); |
2617 // Ensure the algorithm is supported by the hash_hmac function. |
|
2618 if ( ! in_array( $algo, hash_hmac_algos(), true ) ) { |
|
2619 throw new InvalidArgumentException( |
|
2620 sprintf( |
|
2621 /* translators: 1: Name of a cryptographic hash algorithm. 2: List of supported algorithms. */ |
|
2622 __( 'Unsupported hashing algorithm: %1$s. Supported algorithms are: %2$s' ), |
|
2623 $algo, |
|
2624 implode( ', ', hash_hmac_algos() ) |
|
2625 ) |
|
2626 ); |
|
2627 } |
|
2628 |
|
2629 return hash_hmac( $algo, $data, $salt ); |
2519 } |
2630 } |
2520 endif; |
2631 endif; |
2521 |
2632 |
2522 if ( ! function_exists( 'wp_hash_password' ) ) : |
2633 if ( ! function_exists( 'wp_hash_password' ) ) : |
2523 /** |
2634 /** |
2524 * Creates a hash (encrypt) of a plain text password. |
2635 * Creates a hash of a plain text password. |
2525 * |
2636 * |
2526 * For integration with other applications, this function can be overwritten to |
2637 * For integration with other applications, this function can be overwritten to |
2527 * instead use the other package password checking algorithm. |
2638 * instead use the other package password hashing algorithm. |
2528 * |
2639 * |
2529 * @since 2.5.0 |
2640 * @since 2.5.0 |
2530 * |
2641 * @since 6.8.0 The password is now hashed using bcrypt by default instead of phpass. |
2531 * @global PasswordHash $wp_hasher PHPass object. |
2642 * |
|
2643 * @global PasswordHash $wp_hasher phpass object. |
2532 * |
2644 * |
2533 * @param string $password Plain text user password to hash. |
2645 * @param string $password Plain text user password to hash. |
2534 * @return string The hash string of the password. |
2646 * @return string The hash string of the password. |
2535 */ |
2647 */ |
2536 function wp_hash_password( $password ) { |
2648 function wp_hash_password( |
|
2649 #[\SensitiveParameter] |
|
2650 $password |
|
2651 ) { |
2537 global $wp_hasher; |
2652 global $wp_hasher; |
2538 |
2653 |
2539 if ( empty( $wp_hasher ) ) { |
2654 if ( ! empty( $wp_hasher ) ) { |
|
2655 return $wp_hasher->HashPassword( trim( $password ) ); |
|
2656 } |
|
2657 |
|
2658 if ( strlen( $password ) > 4096 ) { |
|
2659 return '*'; |
|
2660 } |
|
2661 |
|
2662 /** |
|
2663 * Filters the hashing algorithm to use in the password_hash() and password_needs_rehash() functions. |
|
2664 * |
|
2665 * The default is the value of the `PASSWORD_BCRYPT` constant which means bcrypt is used. |
|
2666 * |
|
2667 * **Important:** The only password hashing algorithm that is guaranteed to be available across PHP |
|
2668 * installations is bcrypt. If you use any other algorithm you must make sure that it is available on |
|
2669 * the server. The `password_algos()` function can be used to check which hashing algorithms are available. |
|
2670 * |
|
2671 * The hashing options can be controlled via the {@see 'wp_hash_password_options'} filter. |
|
2672 * |
|
2673 * Other available constants include: |
|
2674 * |
|
2675 * - `PASSWORD_ARGON2I` |
|
2676 * - `PASSWORD_ARGON2ID` |
|
2677 * - `PASSWORD_DEFAULT` |
|
2678 * |
|
2679 * @since 6.8.0 |
|
2680 * |
|
2681 * @param string $algorithm The hashing algorithm. Default is the value of the `PASSWORD_BCRYPT` constant. |
|
2682 */ |
|
2683 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT ); |
|
2684 |
|
2685 /** |
|
2686 * Filters the options passed to the password_hash() and password_needs_rehash() functions. |
|
2687 * |
|
2688 * The default hashing algorithm is bcrypt, but this can be changed via the {@see 'wp_hash_password_algorithm'} |
|
2689 * filter. You must ensure that the options are appropriate for the algorithm in use. |
|
2690 * |
|
2691 * @since 6.8.0 |
|
2692 * |
|
2693 * @param array $options Array of options to pass to the password hashing functions. |
|
2694 * By default this is an empty array which means the default |
|
2695 * options will be used. |
|
2696 * @param string $algorithm The hashing algorithm in use. |
|
2697 */ |
|
2698 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm ); |
|
2699 |
|
2700 // Algorithms other than bcrypt don't need to use pre-hashing. |
|
2701 if ( PASSWORD_BCRYPT !== $algorithm ) { |
|
2702 return password_hash( $password, $algorithm, $options ); |
|
2703 } |
|
2704 |
|
2705 // Use SHA-384 to retain entropy from a password that's longer than 72 bytes, and a `wp-sha384` key for domain separation. |
|
2706 $password_to_hash = base64_encode( hash_hmac( 'sha384', trim( $password ), 'wp-sha384', true ) ); |
|
2707 |
|
2708 // Add a prefix to facilitate distinguishing vanilla bcrypt hashes. |
|
2709 return '$wp' . password_hash( $password_to_hash, $algorithm, $options ); |
|
2710 } |
|
2711 endif; |
|
2712 |
|
2713 if ( ! function_exists( 'wp_check_password' ) ) : |
|
2714 /** |
|
2715 * Checks a plaintext password against a hashed password. |
|
2716 * |
|
2717 * Note that this function may be used to check a value that is not a user password. |
|
2718 * A plugin may use this function to check a password of a different type, and there |
|
2719 * may not always be a user ID associated with the password. |
|
2720 * |
|
2721 * For integration with other applications, this function can be overwritten to |
|
2722 * instead use the other package password hashing algorithm. |
|
2723 * |
|
2724 * @since 2.5.0 |
|
2725 * @since 6.8.0 Passwords in WordPress are now hashed with bcrypt by default. A |
|
2726 * password that wasn't hashed with bcrypt will be checked with phpass. |
|
2727 * |
|
2728 * @global PasswordHash $wp_hasher phpass object. Used as a fallback for verifying |
|
2729 * passwords that were hashed with phpass. |
|
2730 * |
|
2731 * @param string $password Plaintext password. |
|
2732 * @param string $hash Hash of the password to check against. |
|
2733 * @param string|int $user_id Optional. ID of a user associated with the password. |
|
2734 * @return bool False, if the $password does not match the hashed password. |
|
2735 */ |
|
2736 function wp_check_password( |
|
2737 #[\SensitiveParameter] |
|
2738 $password, |
|
2739 $hash, |
|
2740 $user_id = '' |
|
2741 ) { |
|
2742 global $wp_hasher; |
|
2743 |
|
2744 if ( strlen( $hash ) <= 32 ) { |
|
2745 // Check the hash using md5 regardless of the current hashing mechanism. |
|
2746 $check = hash_equals( $hash, md5( $password ) ); |
|
2747 } elseif ( ! empty( $wp_hasher ) ) { |
|
2748 // Check the password using the overridden hasher. |
|
2749 $check = $wp_hasher->CheckPassword( $password, $hash ); |
|
2750 } elseif ( strlen( $password ) > 4096 ) { |
|
2751 // Passwords longer than 4096 characters are not supported. |
|
2752 $check = false; |
|
2753 } elseif ( str_starts_with( $hash, '$wp' ) ) { |
|
2754 // Check the password using the current prefixed hash. |
|
2755 $password_to_verify = base64_encode( hash_hmac( 'sha384', $password, 'wp-sha384', true ) ); |
|
2756 $check = password_verify( $password_to_verify, substr( $hash, 3 ) ); |
|
2757 } elseif ( str_starts_with( $hash, '$P$' ) ) { |
|
2758 // Check the password using phpass. |
2540 require_once ABSPATH . WPINC . '/class-phpass.php'; |
2759 require_once ABSPATH . WPINC . '/class-phpass.php'; |
2541 // By default, use the portable hash from phpass. |
2760 $check = ( new PasswordHash( 8, true ) )->CheckPassword( $password, $hash ); |
2542 $wp_hasher = new PasswordHash( 8, true ); |
2761 } else { |
2543 } |
2762 // Check the password using compat support for any non-prefixed hash. |
2544 |
2763 $check = password_verify( $password, $hash ); |
2545 return $wp_hasher->HashPassword( trim( $password ) ); |
2764 } |
2546 } |
2765 |
2547 endif; |
2766 /** |
2548 |
2767 * Filters whether the plaintext password matches the hashed password. |
2549 if ( ! function_exists( 'wp_check_password' ) ) : |
2768 * |
2550 /** |
2769 * @since 2.5.0 |
2551 * Checks the plaintext password against the encrypted Password. |
2770 * @since 6.8.0 Passwords are now hashed with bcrypt by default. |
2552 * |
2771 * Old passwords may still be hashed with phpass or md5. |
2553 * Maintains compatibility between old version and the new cookie authentication |
2772 * |
2554 * protocol using PHPass library. The $hash parameter is the encrypted password |
2773 * @param bool $check Whether the passwords match. |
2555 * and the function compares the plain text password when encrypted similarly |
2774 * @param string $password The plaintext password. |
2556 * against the already encrypted password to see if they match. |
2775 * @param string $hash The hashed password. |
2557 * |
2776 * @param string|int $user_id Optional ID of a user associated with the password. |
2558 * For integration with other applications, this function can be overwritten to |
2777 * Can be empty. |
2559 * instead use the other package password checking algorithm. |
2778 */ |
2560 * |
2779 return apply_filters( 'check_password', $check, $password, $hash, $user_id ); |
2561 * @since 2.5.0 |
2780 } |
2562 * |
2781 endif; |
2563 * @global PasswordHash $wp_hasher PHPass object used for checking the password |
2782 |
2564 * against the $hash + $password. |
2783 if ( ! function_exists( 'wp_password_needs_rehash' ) ) : |
2565 * @uses PasswordHash::CheckPassword |
2784 /** |
2566 * |
2785 * Checks whether a password hash needs to be rehashed. |
2567 * @param string $password Plaintext user's password. |
2786 * |
2568 * @param string $hash Hash of the user's password to check against. |
2787 * Passwords are hashed with bcrypt using the default cost. A password hashed in a prior version |
2569 * @param string|int $user_id Optional. User ID. |
2788 * of WordPress may still be hashed with phpass and will need to be rehashed. If the default cost |
2570 * @return bool False, if the $password does not match the hashed password. |
2789 * or algorithm is changed in PHP or WordPress then a password hashed in a previous version will |
2571 */ |
2790 * need to be rehashed. |
2572 function wp_check_password( $password, $hash, $user_id = '' ) { |
2791 * |
|
2792 * Note that, just like wp_check_password(), this function may be used to check a value that is |
|
2793 * not a user password. A plugin may use this function to check a password of a different type, |
|
2794 * and there may not always be a user ID associated with the password. |
|
2795 * |
|
2796 * @since 6.8.0 |
|
2797 * |
|
2798 * @global PasswordHash $wp_hasher phpass object. |
|
2799 * |
|
2800 * @param string $hash Hash of a password to check. |
|
2801 * @param string|int $user_id Optional. ID of a user associated with the password. |
|
2802 * @return bool Whether the hash needs to be rehashed. |
|
2803 */ |
|
2804 function wp_password_needs_rehash( $hash, $user_id = '' ) { |
2573 global $wp_hasher; |
2805 global $wp_hasher; |
2574 |
2806 |
2575 // If the hash is still md5... |
2807 if ( ! empty( $wp_hasher ) ) { |
2576 if ( strlen( $hash ) <= 32 ) { |
2808 return false; |
2577 $check = hash_equals( $hash, md5( $password ) ); |
2809 } |
2578 if ( $check && $user_id ) { |
|
2579 // Rehash using new hash. |
|
2580 wp_set_password( $password, $user_id ); |
|
2581 $hash = wp_hash_password( $password ); |
|
2582 } |
|
2583 |
|
2584 /** |
|
2585 * Filters whether the plaintext password matches the encrypted password. |
|
2586 * |
|
2587 * @since 2.5.0 |
|
2588 * |
|
2589 * @param bool $check Whether the passwords match. |
|
2590 * @param string $password The plaintext password. |
|
2591 * @param string $hash The hashed password. |
|
2592 * @param string|int $user_id User ID. Can be empty. |
|
2593 */ |
|
2594 return apply_filters( 'check_password', $check, $password, $hash, $user_id ); |
|
2595 } |
|
2596 |
|
2597 /* |
|
2598 * If the stored hash is longer than an MD5, |
|
2599 * presume the new style phpass portable hash. |
|
2600 */ |
|
2601 if ( empty( $wp_hasher ) ) { |
|
2602 require_once ABSPATH . WPINC . '/class-phpass.php'; |
|
2603 // By default, use the portable hash from phpass. |
|
2604 $wp_hasher = new PasswordHash( 8, true ); |
|
2605 } |
|
2606 |
|
2607 $check = $wp_hasher->CheckPassword( $password, $hash ); |
|
2608 |
2810 |
2609 /** This filter is documented in wp-includes/pluggable.php */ |
2811 /** This filter is documented in wp-includes/pluggable.php */ |
2610 return apply_filters( 'check_password', $check, $password, $hash, $user_id ); |
2812 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT ); |
|
2813 |
|
2814 /** This filter is documented in wp-includes/pluggable.php */ |
|
2815 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm ); |
|
2816 |
|
2817 $prefixed = str_starts_with( $hash, '$wp' ); |
|
2818 |
|
2819 if ( ( PASSWORD_BCRYPT === $algorithm ) && ! $prefixed ) { |
|
2820 // If bcrypt is in use and the hash is not prefixed then it needs to be rehashed. |
|
2821 $needs_rehash = true; |
|
2822 } else { |
|
2823 // Otherwise check the hash minus its prefix if necessary. |
|
2824 $hash_to_check = $prefixed ? substr( $hash, 3 ) : $hash; |
|
2825 $needs_rehash = password_needs_rehash( $hash_to_check, $algorithm, $options ); |
|
2826 } |
|
2827 |
|
2828 /** |
|
2829 * Filters whether the password hash needs to be rehashed. |
|
2830 * |
|
2831 * @since 6.8.0 |
|
2832 * |
|
2833 * @param bool $needs_rehash Whether the password hash needs to be rehashed. |
|
2834 * @param string $hash The password hash. |
|
2835 * @param string|int $user_id Optional. ID of a user associated with the password. |
|
2836 */ |
|
2837 return apply_filters( 'password_needs_rehash', $needs_rehash, $hash, $user_id ); |
2611 } |
2838 } |
2612 endif; |
2839 endif; |
2613 |
2840 |
2614 if ( ! function_exists( 'wp_generate_password' ) ) : |
2841 if ( ! function_exists( 'wp_generate_password' ) ) : |
2615 /** |
2842 /** |