Make WordPress Core

Ticket #34059: 34059.4.diff

File 34059.4.diff, 26.1 KB (added by johnbillion, 8 years ago)
  • src/wp-comments-post.php

     
    1717
    1818nocache_headers();
    1919
    20 $comment_post_ID = isset($_POST['comment_post_ID']) ? (int) $_POST['comment_post_ID'] : 0;
    21 
    22 $post = get_post($comment_post_ID);
    23 
    24 if ( empty( $post->comment_status ) ) {
    25         /**
    26          * Fires when a comment is attempted on a post that does not exist.
    27          *
    28          * @since 1.5.0
    29          *
    30          * @param int $comment_post_ID Post ID.
    31          */
    32         do_action( 'comment_id_not_found', $comment_post_ID );
    33         exit;
    34 }
    35 
    36 // get_post_status() will get the parent status for attachments.
    37 $status = get_post_status($post);
    38 
    39 $status_obj = get_post_status_object($status);
    40 
    41 if ( ! comments_open( $comment_post_ID ) ) {
    42         /**
    43          * Fires when a comment is attempted on a post that has comments closed.
    44          *
    45          * @since 1.5.0
    46          *
    47          * @param int $comment_post_ID Post ID.
    48          */
    49         do_action( 'comment_closed', $comment_post_ID );
    50         wp_die( __( 'Sorry, comments are closed for this item.' ), 403 );
    51 } elseif ( 'trash' == $status ) {
    52         /**
    53          * Fires when a comment is attempted on a trashed post.
    54          *
    55          * @since 2.9.0
    56          *
    57          * @param int $comment_post_ID Post ID.
    58          */
    59         do_action( 'comment_on_trash', $comment_post_ID );
    60         exit;
    61 } elseif ( ! $status_obj->public && ! $status_obj->private ) {
    62         /**
    63          * Fires when a comment is attempted on a post in draft mode.
    64          *
    65          * @since 1.5.1
    66          *
    67          * @param int $comment_post_ID Post ID.
    68          */
    69         do_action( 'comment_on_draft', $comment_post_ID );
    70         exit;
    71 } elseif ( post_password_required( $comment_post_ID ) ) {
    72         /**
    73          * Fires when a comment is attempted on a password-protected post.
    74          *
    75          * @since 2.9.0
    76          *
    77          * @param int $comment_post_ID Post ID.
    78          */
    79         do_action( 'comment_on_password_protected', $comment_post_ID );
    80         exit;
    81 } else {
    82         /**
    83          * Fires before a comment is posted.
    84          *
    85          * @since 2.8.0
    86          *
    87          * @param int $comment_post_ID Post ID.
    88          */
    89         do_action( 'pre_comment_on_post', $comment_post_ID );
    90 }
    91 
    92 $comment_author       = ( isset( $_POST['author'] ) && is_string( $_POST['author'] ) ) ? trim( strip_tags( $_POST['author'] ) ) : null;
    93 $comment_author_email = ( isset( $_POST['email'] ) && is_string( $_POST['email'] ) ) ? trim( $_POST['email'] ) : null;
    94 $comment_author_url   = ( isset( $_POST['url'] ) && is_string( $_POST['url'] ) ) ? trim( $_POST['url'] ) : null;
    95 $comment_content      = ( isset( $_POST['comment'] ) && is_string( $_POST['comment'] ) ) ? trim( $_POST['comment'] ) : null;
    96 
    97 // If the user is logged in
    98 $user = wp_get_current_user();
    99 if ( $user->exists() ) {
    100         if ( empty( $user->display_name ) )
    101                 $user->display_name=$user->user_login;
    102         $comment_author       = wp_slash( $user->display_name );
    103         $comment_author_email = wp_slash( $user->user_email );
    104         $comment_author_url   = wp_slash( $user->user_url );
    105         if ( current_user_can( 'unfiltered_html' ) ) {
    106                 if ( ! isset( $_POST['_wp_unfiltered_html_comment'] )
    107                         || ! wp_verify_nonce( $_POST['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID )
    108                 ) {
    109                         kses_remove_filters(); // start with a clean slate
    110                         kses_init_filters(); // set up the filters
    111                 }
    112         }
    113 } else {
    114         if ( get_option( 'comment_registration' ) || 'private' == $status ) {
    115                 wp_die( __( 'Sorry, you must be logged in to post a comment.' ), 403 );
     20$comment = wp_handle_comment_post( wp_unslash( $_POST ) );
     21if ( is_wp_error( $comment ) ) {
     22        $data = $comment->get_error_data();
     23        if ( ! empty( $data ) ) {
     24                wp_die( $comment->get_error_message(), $data );
     25        } else {
     26                exit;
    11627        }
    11728}
    11829
    119 $comment_type = '';
    120 
    121 if ( get_option('require_name_email') && !$user->exists() ) {
    122         if ( 6 > strlen( $comment_author_email ) || '' == $comment_author ) {
    123                 wp_die( __( '<strong>ERROR</strong>: please fill the required fields (name, email).' ), 200 );
    124         } elseif ( ! is_email( $comment_author_email ) ) {
    125                 wp_die( __( '<strong>ERROR</strong>: please enter a valid email address.' ), 200 );
    126         }
    127 }
    128 
    129 if ( '' == $comment_content ) {
    130         wp_die( __( '<strong>ERROR</strong>: please type a comment.' ), 200 );
    131 }
    132 
    133 $comment_parent = isset($_POST['comment_parent']) ? absint($_POST['comment_parent']) : 0;
    134 
    135 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
    136 
    137 $comment_id = wp_new_comment( $commentdata );
    138 if ( ! $comment_id ) {
    139         wp_die( __( "<strong>ERROR</strong>: The comment could not be saved. Please try again later." ) );
    140 }
    141 
    142 $comment = get_comment( $comment_id );
     30$user = wp_get_current_user();
    14331
    14432/**
    14533 * Perform other actions when comment cookies are set.
     
    15139 */
    15240do_action( 'set_comment_cookies', $comment, $user );
    15341
    154 $location = empty($_POST['redirect_to']) ? get_comment_link( $comment ) : $_POST['redirect_to'] . '#comment-' . $comment_id;
     42$location = empty( $_POST['redirect_to'] ) ? get_comment_link( $comment ) : $_POST['redirect_to'] . '#comment-' . $comment->comment_ID;
    15543
    15644/**
    15745 * Filter the location URI to send the commenter after posting.
  • tests/phpunit/tests/comments-post.php

     
     1<?php
     2
     3/**
     4 * @group comment
     5 */
     6class Tests_Comments_Post extends WP_UnitTestCase {
     7
     8        function setUp() {
     9                parent::setUp();
     10                require_once ABSPATH . WPINC . '/class-phpass.php';
     11        }
     12
     13        function tearDown() {
     14                wp_set_current_user( 0 );
     15                parent::tearDown();
     16        }
     17
     18        public function test_posting_comment_to_invalid_post_returns_error() {
     19
     20                $error = 'comment_id_not_found';
     21
     22                $this->assertSame( 0, did_action( $error ) );
     23
     24                $data = array(
     25                        'comment_post_ID' => 0,
     26                );
     27                $comment = wp_handle_comment_post( $data );
     28
     29                $this->assertSame( 1, did_action( $error ) );
     30                $this->assertWPError( $comment );
     31                $this->assertSame( $error, $comment->get_error_code() );
     32
     33        }
     34
     35        public function test_posting_comment_to_post_with_closed_comments_returns_error() {
     36
     37                $error = 'comment_closed';
     38
     39                $this->assertSame( 0, did_action( $error ) );
     40
     41                $post = $this->factory->post->create_and_get( array(
     42                        'comment_status' => 'closed',
     43                ) );
     44                $data = array(
     45                        'comment_post_ID' => $post->ID,
     46                );
     47                $comment = wp_handle_comment_post( $data );
     48
     49                $this->assertSame( 1, did_action( $error ) );
     50                $this->assertWPError( $comment );
     51                $this->assertSame( $error, $comment->get_error_code() );
     52
     53        }
     54
     55        public function test_posting_comment_to_trashed_post_returns_error() {
     56
     57                $error = 'comment_on_trash';
     58
     59                $this->assertSame( 0, did_action( $error ) );
     60
     61                $post = $this->factory->post->create_and_get();
     62                wp_trash_post( $post );
     63                $data = array(
     64                        'comment_post_ID' => $post->ID,
     65                );
     66                $comment = wp_handle_comment_post( $data );
     67
     68                $this->assertSame( 1, did_action( $error ) );
     69                $this->assertWPError( $comment );
     70                $this->assertSame( $error, $comment->get_error_code() );
     71
     72        }
     73
     74        public function test_posting_comment_to_draft_post_returns_error() {
     75
     76                $error = 'comment_on_draft';
     77
     78                $this->assertSame( 0, did_action( $error ) );
     79
     80                $post = $this->factory->post->create_and_get( array(
     81                        'post_status' => 'draft',
     82                ) );
     83                $data = array(
     84                        'comment_post_ID' => $post->ID,
     85                );
     86                $comment = wp_handle_comment_post( $data );
     87
     88                $this->assertSame( 1, did_action( $error ) );
     89                $this->assertWPError( $comment );
     90                $this->assertSame( $error, $comment->get_error_code() );
     91
     92        }
     93
     94        public function test_posting_comment_to_scheduled_post_returns_error() {
     95
     96                // Same error as commenting on a draft
     97                $error = 'comment_on_draft';
     98
     99                $this->assertSame( 0, did_action( $error ) );
     100
     101                $post = $this->factory->post->create_and_get( array(
     102                        'post_date' => date( 'Y-m-d H:i:s', strtotime( '+1 day' ) ),
     103                ) );
     104
     105                $this->assertSame( 'future', $post->post_status );
     106
     107                $data = array(
     108                        'comment_post_ID' => $post->ID,
     109                );
     110                $comment = wp_handle_comment_post( $data );
     111
     112                $this->assertSame( 1, did_action( $error ) );
     113                $this->assertWPError( $comment );
     114                $this->assertSame( $error, $comment->get_error_code() );
     115
     116        }
     117
     118        public function test_posting_comment_to_password_required_post_returns_error() {
     119
     120                $error = 'comment_on_password_protected';
     121
     122                $this->assertSame( 0, did_action( $error ) );
     123
     124                $post = $this->factory->post->create_and_get( array(
     125                        'post_password' => 'password',
     126                ) );
     127                $data = array(
     128                        'comment_post_ID' => $post->ID,
     129                );
     130                $comment = wp_handle_comment_post( $data );
     131
     132                $this->assertSame( 1, did_action( $error ) );
     133                $this->assertWPError( $comment );
     134                $this->assertSame( $error, $comment->get_error_code() );
     135
     136        }
     137
     138        public function test_posting_comment_to_password_protected_post_succeeds() {
     139
     140                $password = 'password';
     141                $hasher   = new PasswordHash( 8, true );
     142
     143                $_COOKIE['wp-postpass_' . COOKIEHASH] = $hasher->HashPassword( $password );
     144
     145                $post = $this->factory->post->create_and_get( array(
     146                        'post_password' => $password,
     147                ) );
     148                $data = array(
     149                        'comment_post_ID' => $post->ID,
     150                        'comment'         => 'Comment',
     151                        'author'          => 'Comment Author',
     152                        'email'           => 'comment@example.org',
     153                );
     154                $comment = wp_handle_comment_post( $data );
     155
     156                unset( $_COOKIE['wp-postpass_' . COOKIEHASH] );
     157
     158                $this->assertNotWPError( $comment );
     159                $this->assertInstanceOf( 'WP_Comment', $comment );
     160
     161        }
     162
     163        public function test_posting_valid_comment_as_logged_in_user_succeeds() {
     164
     165                $user = $this->factory->user->create_and_get( array(
     166                        'user_url' => 'http://user.example.org'
     167                ) );
     168
     169                wp_set_current_user( $user->ID );
     170
     171                $post = $this->factory->post->create_and_get();
     172                $data = array(
     173                        'comment_post_ID' => $post->ID,
     174                        'comment'         => 'Comment',
     175                );
     176                $comment = wp_handle_comment_post( $data );
     177
     178                $this->assertNotWPError( $comment );
     179                $this->assertInstanceOf( 'WP_Comment', $comment );
     180
     181                $this->assertSame( 'Comment', $comment->comment_content);
     182                $this->assertSame( $user->display_name, $comment->comment_author );
     183                $this->assertSame( $user->user_email, $comment->comment_author_email );
     184                $this->assertSame( $user->user_url, $comment->comment_author_url );
     185
     186        }
     187
     188        public function test_posting_valid_comment_anonymously_succeeds() {
     189
     190                $post = $this->factory->post->create_and_get();
     191                $data = array(
     192                        'comment_post_ID' => $post->ID,
     193                        'comment'         => 'Comment',
     194                        'author'          => 'Comment Author',
     195                        'email'           => 'comment@example.org',
     196                        'url'             => 'user.example.org'
     197                );
     198                $comment = wp_handle_comment_post( $data );
     199
     200                $this->assertNotWPError( $comment );
     201                $this->assertInstanceOf( 'WP_Comment', $comment );
     202
     203                $this->assertSame( 'Comment', $comment->comment_content);
     204                $this->assertSame( 'Comment Author', $comment->comment_author );
     205                $this->assertSame( 'comment@example.org', $comment->comment_author_email );
     206                $this->assertSame( 'http://user.example.org', $comment->comment_author_url );
     207
     208        }
     209
     210        public function test_posting_comment_anonymously_to_private_post_returns_error() {
     211
     212                $error = 'not_logged_in';
     213
     214                $post = $this->factory->post->create_and_get( array(
     215                        'post_status' => 'private',
     216                ) );
     217                $data = array(
     218                        'comment_post_ID' => $post->ID,
     219                );
     220                $comment = wp_handle_comment_post( $data );
     221
     222                $this->assertFalse( is_user_logged_in() );
     223                $this->assertWPError( $comment );
     224                $this->assertSame( $error, $comment->get_error_code() );
     225
     226        }
     227
     228        public function test_posting_comment_to_own_private_post_succeeds() {
     229
     230                $user = $this->factory->user->create_and_get();
     231
     232                wp_set_current_user( $user->ID );
     233
     234                $post = $this->factory->post->create_and_get( array(
     235                        'post_status' => 'private',
     236                        'post_author' => $user->ID,
     237                ) );
     238                $data = array(
     239                        'comment_post_ID' => $post->ID,
     240                        'comment'         => 'Comment',
     241                );
     242                $comment = wp_handle_comment_post( $data );
     243
     244                $this->assertTrue( current_user_can( 'read_post', $post->ID ) );
     245                $this->assertNotWPError( $comment );
     246                $this->assertInstanceOf( 'WP_Comment', $comment );
     247
     248        }
     249
     250        public function test_posting_comment_to_accessible_private_post_succeeds() {
     251
     252                $author = $this->factory->user->create_and_get( array(
     253                        'role' => 'author',
     254                ) );
     255                $user = $this->factory->user->create_and_get( array(
     256                        'role' => 'editor',
     257                ) );
     258
     259                wp_set_current_user( $user->ID );
     260
     261                $post = $this->factory->post->create_and_get( array(
     262                        'post_status' => 'private',
     263                        'post_author' => $author->ID,
     264                ) );
     265                $data = array(
     266                        'comment_post_ID' => $post->ID,
     267                        'comment'         => 'Comment',
     268                );
     269                $comment = wp_handle_comment_post( $data );
     270
     271                $this->assertTrue( current_user_can( 'read_post', $post->ID ) );
     272                $this->assertNotWPError( $comment );
     273                $this->assertInstanceOf( 'WP_Comment', $comment );
     274
     275        }
     276
     277        public function test_anonymous_user_cannot_comment_unfiltered_html() {
     278
     279                $post = $this->factory->post->create_and_get();
     280                $data = array(
     281                        'comment_post_ID' => $post->ID,
     282                        'comment'         => 'Comment <script>alert(document.cookie);</script>',
     283                        'author'          => 'Comment Author',
     284                        'email'           => 'comment@example.org',
     285                );
     286                $comment = wp_handle_comment_post( $data );
     287
     288                $this->assertNotWPError( $comment );
     289                $this->assertInstanceOf( 'WP_Comment', $comment );
     290                $this->assertNotContains( '<script', $comment->comment_content );
     291
     292        }
     293
     294        public function test_unprivileged_user_cannot_comment_unfiltered_html() {
     295
     296                $user = $this->factory->user->create_and_get( array(
     297                        'role' => 'author',
     298                ) );
     299                wp_set_current_user( $user->ID );
     300
     301                $this->assertFalse( current_user_can( 'unfiltered_html' ) );
     302
     303                $post = $this->factory->post->create_and_get();
     304                $data = array(
     305                        'comment_post_ID' => $post->ID,
     306                        'comment'         => 'Comment <script>alert(document.cookie);</script>',
     307                );
     308                $comment = wp_handle_comment_post( $data );
     309
     310                $this->assertNotWPError( $comment );
     311                $this->assertInstanceOf( 'WP_Comment', $comment );
     312                $this->assertNotContains( '<script', $comment->comment_content );
     313
     314        }
     315
     316        public function test_unprivileged_user_cannot_comment_unfiltered_html_even_with_valid_nonce() {
     317
     318                $user = $this->factory->user->create_and_get( array(
     319                        'role' => 'author',
     320                ) );
     321                wp_set_current_user( $user->ID );
     322
     323                $this->assertFalse( current_user_can( 'unfiltered_html' ) );
     324
     325                $post   = $this->factory->post->create_and_get();
     326                $action = 'unfiltered-html-comment_' . $post->ID;
     327                $nonce  = wp_create_nonce( $action );
     328
     329                $this->assertNotFalse( wp_verify_nonce( $nonce, $action ) );
     330
     331                $data = array(
     332                        'comment_post_ID'             => $post->ID,
     333                        'comment'                     => 'Comment <script>alert(document.cookie);</script>',
     334                        '_wp_unfiltered_html_comment' => $nonce,
     335                );
     336                $comment = wp_handle_comment_post( $data );
     337
     338                $this->assertNotWPError( $comment );
     339                $this->assertInstanceOf( 'WP_Comment', $comment );
     340                $this->assertNotContains( '<script', $comment->comment_content );
     341
     342        }
     343
     344        public function test_privileged_user_can_comment_unfiltered_html_with_valid_nonce() {
     345
     346                $this->assertFalse( defined( 'DISALLOW_UNFILTERED_HTML' ) );
     347
     348                $user = $this->factory->user->create_and_get( array(
     349                        'role' => 'editor',
     350                ) );
     351
     352                if ( is_multisite() ) {
     353                        // In multisite, only Super Admins can post unfiltered HTML
     354                        $this->assertFalse( user_can( $user->ID, 'unfiltered_html' ) );
     355                        grant_super_admin( $user->ID );
     356                }
     357
     358                wp_set_current_user( $user->ID );
     359
     360                $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     361
     362                $post   = $this->factory->post->create_and_get();
     363                $action = 'unfiltered-html-comment_' . $post->ID;
     364                $nonce  = wp_create_nonce( $action );
     365
     366                $this->assertNotFalse( wp_verify_nonce( $nonce, $action ) );
     367
     368                $data = array(
     369                        'comment_post_ID'             => $post->ID,
     370                        'comment'                     => 'Comment <script>alert(document.cookie);</script>',
     371                        '_wp_unfiltered_html_comment' => $nonce,
     372                );
     373                $comment = wp_handle_comment_post( $data );
     374
     375                $this->assertNotWPError( $comment );
     376                $this->assertInstanceOf( 'WP_Comment', $comment );
     377                $this->assertContains( '<script', $comment->comment_content );
     378
     379        }
     380
     381        public function test_privileged_user_cannot_comment_unfiltered_html_without_valid_nonce() {
     382
     383                $user = $this->factory->user->create_and_get( array(
     384                        'role' => 'editor',
     385                ) );
     386
     387                if ( is_multisite() ) {
     388                        // In multisite, only Super Admins can post unfiltered HTML
     389                        $this->assertFalse( user_can( $user->ID, 'unfiltered_html' ) );
     390                        grant_super_admin( $user->ID );
     391                }
     392
     393                wp_set_current_user( $user->ID );
     394
     395                $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     396
     397                $post   = $this->factory->post->create_and_get();
     398                $data = array(
     399                        'comment_post_ID' => $post->ID,
     400                        'comment'         => 'Comment <script>alert(document.cookie);</script>',
     401                );
     402                $comment = wp_handle_comment_post( $data );
     403
     404                $this->assertNotWPError( $comment );
     405                $this->assertInstanceOf( 'WP_Comment', $comment );
     406                $this->assertNotContains( '<script', $comment->comment_content );
     407
     408        }
     409
     410        public function test_posting_comment_as_anonymous_user_when_registration_required_returns_error() {
     411
     412                $error = 'not_logged_in';
     413
     414                $_comment_registration = get_option( 'comment_registration' );
     415                update_option( 'comment_registration', '1' );
     416
     417                $post = $this->factory->post->create_and_get();
     418                $data = array(
     419                        'comment_post_ID' => $post->ID,
     420                );
     421                $comment = wp_handle_comment_post( $data );
     422
     423                update_option( 'comment_registration', $_comment_registration );
     424
     425                $this->assertWPError( $comment );
     426                $this->assertSame( $error, $comment->get_error_code() );
     427
     428        }
     429
     430        public function test_posting_comment_with_no_name_when_name_email_required_returns_error() {
     431
     432                $error = 'require_name_email';
     433
     434                $_require_name_email = get_option( 'require_name_email' );
     435                update_option( 'require_name_email', '1' );
     436
     437                $post = $this->factory->post->create_and_get();
     438                $data = array(
     439                        'comment_post_ID' => $post->ID,
     440                        'comment'         => 'Comment',
     441                        'email'           => 'comment@example.org',
     442                );
     443                $comment = wp_handle_comment_post( $data );
     444
     445                update_option( 'require_name_email', $_require_name_email );
     446
     447                $this->assertWPError( $comment );
     448                $this->assertSame( $error, $comment->get_error_code() );
     449
     450        }
     451
     452        public function test_posting_comment_with_no_email_when_name_email_required_returns_error() {
     453
     454                $error = 'require_name_email';
     455
     456                $_require_name_email = get_option( 'require_name_email' );
     457                update_option( 'require_name_email', '1' );
     458
     459                $post = $this->factory->post->create_and_get();
     460                $data = array(
     461                        'comment_post_ID' => $post->ID,
     462                        'comment'         => 'Comment',
     463                        'author'          => 'Comment Author',
     464                );
     465                $comment = wp_handle_comment_post( $data );
     466
     467                update_option( 'require_name_email', $_require_name_email );
     468
     469                $this->assertWPError( $comment );
     470                $this->assertSame( $error, $comment->get_error_code() );
     471
     472        }
     473
     474        public function test_posting_comment_with_invalid_email_when_name_email_required_returns_error() {
     475
     476                $error = 'require_valid_email';
     477
     478                $_require_name_email = get_option( 'require_name_email' );
     479                update_option( 'require_name_email', '1' );
     480
     481                $post = $this->factory->post->create_and_get();
     482                $data = array(
     483                        'comment_post_ID' => $post->ID,
     484                        'comment'         => 'Comment',
     485                        'author'          => 'Comment Author',
     486                        'email'           => 'not_an_email',
     487                );
     488                $comment = wp_handle_comment_post( $data );
     489
     490                update_option( 'require_name_email', $_require_name_email );
     491
     492                $this->assertWPError( $comment );
     493                $this->assertSame( $error, $comment->get_error_code() );
     494
     495        }
     496
     497        public function test_posting_comment_with_no_comment_content_returns_error() {
     498
     499                $error = 'require_valid_comment';
     500
     501                $post = $this->factory->post->create_and_get();
     502                $data = array(
     503                        'comment_post_ID' => $post->ID,
     504                        'comment'         => '',
     505                        'author'          => 'Comment Author',
     506                        'email'           => 'comment@example.org',
     507                );
     508                $comment = wp_handle_comment_post( $data );
     509
     510                $this->assertWPError( $comment );
     511                $this->assertSame( $error, $comment->get_error_code() );
     512
     513        }
     514
     515}
  • src/wp-includes/comment-functions.php

     
    25502550
    25512551        return $open;
    25522552}
     2553
     2554/**
     2555 * Handles the submission of a comment, usually posted to wp-comments-post.php via a comment form.
     2556 *
     2557 * @param array $comment_data {
     2558 *     Comment data.
     2559 *
     2560 *     @type string|int $comment_post_ID             The ID of the post that relates to the comment.
     2561 *     @type string     $author                      The name of the comment author.
     2562 *     @type string     $email                       The comment author email address.
     2563 *     @type string     $url                         The comment author URL.
     2564 *     @type string     $comment                     The content of the comment.
     2565 *     @type string|int $comment_parent              The ID of this comment's parent, if any. Default 0.
     2566 *     @type string     $_wp_unfiltered_html_comment The nonce value for allowing unfiltered HTML.
     2567 * }
     2568 * @return WP_Comment|WP_Error A WP_Comment object on success, a WP_Error object on failure.
     2569 */
     2570function wp_handle_comment_post( $comment_data ) {
     2571
     2572        $comment_post_ID = isset( $comment_data['comment_post_ID'] )
     2573                ? (int) $comment_data['comment_post_ID']
     2574                : 0;
     2575        $comment_author = ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) )
     2576                ? trim( strip_tags( $comment_data['author'] ) )
     2577                : null;
     2578        $comment_author_email = ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) )
     2579                ? trim( $comment_data['email'] )
     2580                : null;
     2581        $comment_author_url = ( isset( $comment_data['url'] ) && is_string( $comment_data['url'] ) )
     2582                ? trim( $comment_data['url'] )
     2583                : null;
     2584        $comment_content = ( isset( $comment_data['comment'] ) && is_string( $comment_data['comment'] ) )
     2585                ? trim( $comment_data['comment'] )
     2586                : null;
     2587        $comment_parent = isset( $comment_data['comment_parent'] )
     2588                ? absint( $comment_data['comment_parent'] )
     2589                : 0;
     2590        $_wp_unfiltered_html_comment = ( isset( $comment_data['_wp_unfiltered_html_comment'] ) && is_string( $comment_data['_wp_unfiltered_html_comment'] ) )
     2591                ? trim( $comment_data['_wp_unfiltered_html_comment'] )
     2592                : null;
     2593
     2594        $post = get_post( $comment_post_ID );
     2595
     2596        if ( empty( $post->comment_status ) ) {
     2597
     2598                /**
     2599                 * Fires when a comment is attempted on a post that does not exist.
     2600                 *
     2601                 * @since 1.5.0
     2602                 *
     2603                 * @param int $comment_post_ID Post ID.
     2604                 */
     2605                do_action( 'comment_id_not_found', $comment_post_ID );
     2606
     2607                return new WP_Error( 'comment_id_not_found' );
     2608
     2609        }
     2610
     2611        // get_post_status() will get the parent status for attachments.
     2612        $status = get_post_status( $post );
     2613
     2614        $status_obj = get_post_status_object( $status );
     2615
     2616        if ( ! comments_open( $comment_post_ID ) ) {
     2617
     2618                /**
     2619                 * Fires when a comment is attempted on a post that has comments closed.
     2620                 *
     2621                 * @since 1.5.0
     2622                 *
     2623                 * @param int $comment_post_ID Post ID.
     2624                 */
     2625                do_action( 'comment_closed', $comment_post_ID );
     2626
     2627                return new WP_Error( 'comment_closed', __( 'Sorry, comments are closed for this item.' ), 403 );
     2628
     2629        } elseif ( 'trash' == $status ) {
     2630
     2631                /**
     2632                 * Fires when a comment is attempted on a trashed post.
     2633                 *
     2634                 * @since 2.9.0
     2635                 *
     2636                 * @param int $comment_post_ID Post ID.
     2637                 */
     2638                do_action( 'comment_on_trash', $comment_post_ID );
     2639
     2640                return new WP_Error( 'comment_on_trash' );
     2641
     2642        } elseif ( ! $status_obj->public && ! $status_obj->private ) {
     2643
     2644                /**
     2645                 * Fires when a comment is attempted on a post in draft mode.
     2646                 *
     2647                 * @since 1.5.1
     2648                 *
     2649                 * @param int $comment_post_ID Post ID.
     2650                 */
     2651                do_action( 'comment_on_draft', $comment_post_ID );
     2652
     2653                return new WP_Error( 'comment_on_draft' );
     2654
     2655        } elseif ( post_password_required( $comment_post_ID ) ) {
     2656
     2657                /**
     2658                 * Fires when a comment is attempted on a password-protected post.
     2659                 *
     2660                 * @since 2.9.0
     2661                 *
     2662                 * @param int $comment_post_ID Post ID.
     2663                 */
     2664                do_action( 'comment_on_password_protected', $comment_post_ID );
     2665
     2666                return new WP_Error( 'comment_on_password_protected' );
     2667
     2668        } else {
     2669
     2670                /**
     2671                 * Fires before a comment is posted.
     2672                 *
     2673                 * @since 2.8.0
     2674                 *
     2675                 * @param int $comment_post_ID Post ID.
     2676                 */
     2677                do_action( 'pre_comment_on_post', $comment_post_ID );
     2678
     2679        }
     2680
     2681        // If the user is logged in
     2682        $user = wp_get_current_user();
     2683        if ( $user->exists() ) {
     2684                if ( empty( $user->display_name ) ) {
     2685                        $user->display_name=$user->user_login;
     2686                }
     2687                $comment_author       = $user->display_name;
     2688                $comment_author_email = $user->user_email;
     2689                $comment_author_url   = $user->user_url;
     2690                if ( current_user_can( 'unfiltered_html' ) ) {
     2691                        if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] )
     2692                                || ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID )
     2693                        ) {
     2694                                kses_remove_filters(); // start with a clean slate
     2695                                kses_init_filters(); // set up the filters
     2696                        }
     2697                }
     2698        } else {
     2699                if ( get_option( 'comment_registration' ) || 'private' == $status ) {
     2700                        return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to post a comment.' ), 403 );
     2701                }
     2702        }
     2703
     2704        $comment_type = '';
     2705
     2706        if ( get_option( 'require_name_email' ) && ! $user->exists() ) {
     2707                if ( 6 > strlen( $comment_author_email ) || '' == $comment_author ) {
     2708                        return new WP_Error( 'require_name_email', __( '<strong>ERROR</strong>: please fill the required fields (name, email).' ), 200 );
     2709                } elseif ( ! is_email( $comment_author_email ) ) {
     2710                        return new WP_Error( 'require_valid_email', __( '<strong>ERROR</strong>: please enter a valid email address.' ), 200 );
     2711                }
     2712        }
     2713
     2714        if ( '' == $comment_content ) {
     2715                return new WP_Error( 'require_valid_comment', __( '<strong>ERROR</strong>: please type a comment.' ), 200 );
     2716        }
     2717
     2718        $commentdata = compact(
     2719                'comment_post_ID',
     2720                'comment_author',
     2721                'comment_author_email',
     2722                'comment_author_url',
     2723                'comment_content',
     2724                'comment_type',
     2725                'comment_parent',
     2726                'user_ID'
     2727        );
     2728
     2729        $comment_id = wp_new_comment( wp_slash( $commentdata ) );
     2730        if ( ! $comment_id ) {
     2731                return new WP_Error( 'comment_save_error', __( '<strong>ERROR</strong>: The comment could not be saved. Please try again later.' ), 500 );
     2732        }
     2733
     2734        return get_comment( $comment_id );
     2735
     2736}