Ticket #36901: 36901.7.diff
File 36901.7.diff, 11.4 KB (added by , 8 years ago) |
---|
-
src/wp-includes/comment.php
586 586 * Validates whether this comment is allowed to be made. 587 587 * 588 588 * @since 2.0.0 589 * @since 4.7.0 The `$avoid_die` parameter was added. 589 590 * 590 591 * @global wpdb $wpdb WordPress database abstraction object. 591 592 * 592 * @param array $commentdata Contains information on the comment 593 * @return int|string Signifies the approval status (0|1|'spam') 593 * @param array $commentdata Contains information on the comment. 594 * @param boolean $avoid_die Should errors be returned as WP_Error objects 595 * instead of executing wp_die()? Default false. 596 * @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam'). 597 * If $avoid_die is true, unallowed comments return a WP_Error. 594 598 */ 595 function wp_allow_comment( $commentdata ) {599 function wp_allow_comment( $commentdata, $avoid_die = false ) { 596 600 global $wpdb; 597 601 598 602 // Simple duplicate check … … 637 641 * @param array $commentdata Comment data. 638 642 */ 639 643 do_action( 'comment_duplicate_trigger', $commentdata ); 640 if ( wp_doing_ajax() ) { 641 die( __('Duplicate comment detected; it looks as though you’ve already said that!') ); 644 if ( true === $avoid_die ) { 645 return new WP_Error( 'comment_duplicate', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 ); 646 } else { 647 if ( wp_doing_ajax() ) { 648 die( __('Duplicate comment detected; it looks as though you’ve already said that!') ); 649 } 650 651 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 ); 642 652 } 643 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );644 653 } 645 654 646 655 /** … … 649 658 * Allows checking for comment flooding. 650 659 * 651 660 * @since 2.3.0 661 * @since 4.7.0 The `$avoid_die` parameter was added. 652 662 * 653 663 * @param string $comment_author_IP Comment author's IP address. 654 664 * @param string $comment_author_email Comment author's email. 655 665 * @param string $comment_date_gmt GMT date the comment was posted. 666 * @param boolean $avoid_die Prevent executing wp_die() or die() 667 * if a comment flood is occuring. 656 668 */ 657 669 do_action( 658 670 'check_comment_flood', 659 671 $commentdata['comment_author_IP'], 660 672 $commentdata['comment_author_email'], 661 $commentdata['comment_date_gmt'] 673 $commentdata['comment_date_gmt'], 674 $avoid_die 662 675 ); 663 676 677 /** 678 * Filters whether a comment is part of a comment flood or not. 679 * 680 * @since 4.7.0 681 * 682 * @param boolean $is_flood Is a comment flooding occurring? 683 * Default is false. 684 * @param string $commentdata['comment_author_IP'] Comment author's IP address. 685 * @param string $commentdata['comment_author_email'] Comment author's email. 686 * @param string $commentdata['comment_date_gmt'] GMT date the comment was posted. 687 * @param boolean $avoid_die Prevent executing wp_die() or die() 688 * if a comment flood is occuring. 689 */ 690 $is_flood = apply_filters( 691 'wp_is_comment_flood', 692 false, 693 $commentdata['comment_author_IP'], 694 $commentdata['comment_author_email'], 695 $commentdata['comment_date_gmt'], 696 $avoid_die 697 ); 698 699 if ( $is_flood ) { 700 return new WP_Error( 'comment_flood', __( 'You are posting comments too quickly. Slow down.' ), 429 ); 701 } 702 664 703 if ( ! empty( $commentdata['user_id'] ) ) { 665 704 $user = get_userdata( $commentdata['user_id'] ); 666 705 $post_author = $wpdb->get_var( $wpdb->prepare( … … 713 752 } 714 753 715 754 /** 755 * Hooks WP's native database-based comment-flood check. 756 * 757 * @since 2.3.0 758 * @since 4.7.0 Converted to be an add_filter() wrapper. 759 */ 760 function check_comment_flood_db() { 761 add_filter( 'wp_is_comment_flood', 'wp_check_comment_flood', 10, 5 ); 762 } 763 764 /** 716 765 * Check whether comment flooding is occurring. 717 766 * 718 767 * Won't run, if current user can manage options, so to not block 719 768 * administrators. 720 769 * 721 * @since 2.3.0770 * @since 4.7.0 722 771 * 723 772 * @global wpdb $wpdb WordPress database abstraction object. 724 773 * 725 * @param string $ip Comment IP. 726 * @param string $email Comment author email address. 727 * @param string $date MySQL time string. 774 * @param boolean $is_flood Is a comment flooding occurring? 775 * @param string $ip Comment IP. 776 * @param string $email Comment author email address. 777 * @param string $date MySQL time string. 778 * @param boolean $avoid_die Prevent executing wp_die() or die() if a 779 * comment flood is occuring. Default is false. 780 * @return boolean|WP_Error True or a WP_Error if a comment flood is occuring, 781 * otherwise false. 728 782 */ 729 function check_comment_flood_db( $ip, $email, $date ) { 783 function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) { 784 730 785 global $wpdb; 786 787 if ( true === $is_flood ) { 788 return $is_flood; 789 } 790 731 791 // don't throttle admins or moderators 732 792 if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) { 733 return ;793 return false; 734 794 } 735 795 $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); 736 796 … … 772 832 * @param int $time_newcomment Timestamp of when the new comment was posted. 773 833 */ 774 834 do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment ); 835 if ( true === $avoid_die ) { 836 return true; 837 } else { 838 if ( wp_doing_ajax() ) { 839 die( __('You are posting comments too quickly. Slow down.') ); 840 } 775 841 776 if ( wp_doing_ajax() ) 777 die( __('You are posting comments too quickly. Slow down.') ); 778 779 wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 ); 842 wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 ); 843 } 780 844 } 781 845 } 846 847 return false; 782 848 } 783 849 784 850 /** … … 1722 1788 * 1723 1789 * @since 1.5.0 1724 1790 * @since 4.3.0 'comment_agent' and 'comment_author_IP' can be set via `$commentdata`. 1791 * @since 4.7.0 The `$avoid_die` parameter was added. 1725 1792 * 1726 1793 * @see wp_insert_comment() 1727 1794 * @global wpdb $wpdb WordPress database abstraction object. … … 1745 1812 * @type string $comment_author_IP Comment author IP address in IPv4 format. Default is the value of 1746 1813 * 'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request. 1747 1814 * } 1748 * @return int|false The ID of the comment on success, false on failure. 1815 * @param boolean $avoid_die Should errors be returned as WP_Error objects instead of 1816 * executing wp_die()? Default false. 1817 * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure. 1749 1818 */ 1750 function wp_new_comment( $commentdata ) {1819 function wp_new_comment( $commentdata, $avoid_die = false ) { 1751 1820 global $wpdb; 1752 1821 1753 1822 if ( isset( $commentdata['user_ID'] ) ) { … … 1796 1865 1797 1866 $commentdata = wp_filter_comment($commentdata); 1798 1867 1799 $commentdata['comment_approved'] = wp_allow_comment($commentdata); 1868 $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die ); 1869 if ( is_wp_error( $commentdata['comment_approved'] ) ) { 1870 return $commentdata['comment_approved']; 1871 } 1800 1872 1801 1873 $comment_ID = wp_insert_comment($commentdata); 1802 1874 if ( ! $comment_ID ) { … … 1810 1882 1811 1883 $commentdata = wp_filter_comment( $commentdata ); 1812 1884 1813 $commentdata['comment_approved'] = wp_allow_comment( $commentdata ); 1885 $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die ); 1886 if ( is_wp_error( $commentdata['comment_approved'] ) ) { 1887 return $commentdata['comment_approved']; 1888 } 1814 1889 1815 1890 $comment_ID = wp_insert_comment( $commentdata ); 1816 1891 if ( ! $comment_ID ) { … … 2932 3007 'user_ID' 2933 3008 ); 2934 3009 2935 $comment_id = wp_new_comment( wp_slash( $commentdata ) ); 3010 $comment_id = wp_new_comment( wp_slash( $commentdata ), true ); 3011 if ( is_wp_error( $comment_id ) ) { 3012 return $comment_id; 3013 } 3014 2936 3015 if ( ! $comment_id ) { 2937 3016 return new WP_Error( 'comment_save_error', __( '<strong>ERROR</strong>: The comment could not be saved. Please try again later.' ), 500 ); 2938 3017 } 2939 3018 2940 3019 return get_comment( $comment_id ); 2941 2942 3020 } -
src/wp-includes/default-filters.php
197 197 add_filter( 'teeny_mce_before_init', '_mce_set_direction' ); 198 198 add_filter( 'pre_kses', 'wp_pre_kses_less_than' ); 199 199 add_filter( 'sanitize_title', 'sanitize_title_with_dashes', 10, 3 ); 200 add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 3);200 add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 ); 201 201 add_filter( 'comment_flood_filter', 'wp_throttle_comment_flood', 10, 3 ); 202 202 add_filter( 'pre_comment_content', 'wp_rel_nofollow', 15 ); 203 203 add_filter( 'comment_email', 'antispambot' ); -
tests/phpunit/tests/comment-submission.php
714 714 return $commentdata; 715 715 } 716 716 717 /** 718 * @ticket 36901 719 */ 720 public function test_submitting_duplicate_comments() { 721 $post = self::factory()->post->create_and_get( array( 722 'post_status' => 'publish', 723 ) ); 724 $data = array( 725 'comment_post_ID' => $post->ID, 726 'comment' => 'Did I say that?', 727 'author' => 'Repeat myself', 728 'email' => 'mail@example.com', 729 ); 730 $first_comment = wp_handle_comment_submission( $data ); 731 $second_comment = wp_handle_comment_submission( $data ); 732 $this->assertWPError( $second_comment ); 733 $this->assertSame( 'comment_duplicate', $second_comment->get_error_code() ); 734 } 735 736 /** 737 * @ticket 36901 738 */ 739 public function test_comments_flood() { 740 $post = self::factory()->post->create_and_get( array( 741 'post_status' => 'publish', 742 ) ); 743 $data = array( 744 'comment_post_ID' => $post->ID, 745 'comment' => 'Did I say that?', 746 'author' => 'Repeat myself', 747 'email' => 'mail@example.com', 748 ); 749 $first_comment = wp_handle_comment_submission( $data ); 750 751 $data['comment'] = 'Wow! I am quick!'; 752 $second_comment = wp_handle_comment_submission( $data ); 753 754 $this->assertWPError( $second_comment ); 755 $this->assertSame( 'comment_flood', $second_comment->get_error_code() ); 756 } 757 758 /** 759 * @ticket 36901 760 */ 761 public function test_comments_flood_user_is_admin() { 762 $user = self::factory()->user->create_and_get( array( 763 'role' => 'administrator', 764 ) ); 765 wp_set_current_user( $user->ID ); 766 767 $post = self::factory()->post->create_and_get( array( 768 'post_status' => 'publish', 769 ) ); 770 $data = array( 771 'comment_post_ID' => $post->ID, 772 'comment' => 'Did I say that?', 773 'author' => 'Repeat myself', 774 'email' => 'mail@example.com', 775 ); 776 $first_comment = wp_handle_comment_submission( $data ); 777 778 $data['comment'] = 'Wow! I am quick!'; 779 $second_comment = wp_handle_comment_submission( $data ); 780 781 $this->assertNotWPError( $second_comment ); 782 $this->assertEquals( $post->ID, $second_comment->comment_post_ID ); 783 } 717 784 }