Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/wp-includes/class-walker-comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $
add_filter( 'comment_text', array( $this, 'filter_comment_text' ), 40, 2 );
}

if ( ( 'pingback' === $comment->comment_type || 'trackback' === $comment->comment_type ) && $args['short_ping'] ) {
$is_ping = $comment_type_object && $comment_type_object->is_ping;

if ( $is_ping && $args['short_ping'] ) {
ob_start();
$this->ping( $comment, $depth, $args );
$output .= ob_get_clean();
Expand Down
14 changes: 14 additions & 0 deletions src/wp-includes/class-wp-comment-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ final class WP_Comment_Type {
*/
public $render_callback = null;

/**
* Whether the comment type represents a ping (a notification from another site)
* rather than a human-authored comment.
*
* Ping types (such as `pingback` and `trackback`) are grouped together by
* {@see separate_comments()} and rendered with the compact ping markup by
* {@see Walker_Comment}. Default false.
*
* @since 7.1.0
* @var bool
*/
public $is_ping = false;

/**
* Whether the comment type is hierarchical.
*
Expand Down Expand Up @@ -208,6 +221,7 @@ public function set_props( $args ) {
'internal' => false,
'show_ui' => null,
'render_callback' => null,
'is_ping' => false,
'_builtin' => false,
);

Expand Down
10 changes: 9 additions & 1 deletion src/wp-includes/comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ function create_initial_comment_types() {
'singular_name' => __( 'Pingback' ),
),
'public' => true,
'is_ping' => true,
'_builtin' => true,
)
);
Expand All @@ -315,6 +316,7 @@ function create_initial_comment_types() {
'singular_name' => __( 'Trackback' ),
),
'public' => true,
'is_ping' => true,
'_builtin' => true,
)
);
Expand Down Expand Up @@ -367,6 +369,10 @@ function create_initial_comment_types() {
* excluded from default public-facing contexts. Default false.
* @type bool $show_ui Whether to generate and allow a UI for managing this comment
* type in the admin. Default is value of $public.
* @type bool $is_ping Whether the comment type represents a ping (a notification from
* another site) rather than a human-authored comment. Ping types are
* grouped together by separate_comments() and rendered with compact
* ping markup by Walker_Comment. Default false.
* @type callable $render_callback Callback used to render a comment of this type in comment
* lists. Receives the same arguments as the `callback` argument
* of wp_list_comments() (the comment, the arguments, and the
Expand Down Expand Up @@ -1256,7 +1262,9 @@ function separate_comments( &$comments ) {

$comments_by_type[ $type ][] = &$comments[ $i ];

if ( 'trackback' === $type || 'pingback' === $type ) {
$comment_type_object = get_comment_type_object( $type );

if ( $comment_type_object && $comment_type_object->is_ping ) {
$comments_by_type['pings'][] = &$comments[ $i ];
}
}
Expand Down
108 changes: 108 additions & 0 deletions tests/phpunit/tests/comment/separateComments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

/**
* @group comment
*
* @covers ::separate_comments
*/
class Tests_Comment_SeparateComments extends WP_UnitTestCase {

/**
* Comment post ID.
*
* @var int
*/
private static $post_id;

public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$post_id = $factory->post->create();
}

/**
* Builds a comment of the given type on the shared post.
*
* @param string $comment_type Comment type slug.
* @return WP_Comment The created comment object.
*/
private function make_comment( $comment_type ) {
return get_comment(
self::factory()->comment->create(
array(
'comment_post_ID' => self::$post_id,
'comment_type' => $comment_type,
)
)
);
}

/**
* The standard buckets are always present, even when empty.
*
* @ticket 35214
*/
public function test_default_buckets_are_always_present() {
$comments = array();
$separated = separate_comments( $comments );

$this->assertArrayHasKey( 'comment', $separated );
$this->assertArrayHasKey( 'trackback', $separated );
$this->assertArrayHasKey( 'pingback', $separated );
$this->assertArrayHasKey( 'pings', $separated );
}

/**
* Built-in pingbacks and trackbacks are grouped into the 'pings' bucket.
*
* @ticket 35214
*/
public function test_built_in_pings_are_grouped_into_pings_bucket() {
$comments = array(
$this->make_comment( 'comment' ),
$this->make_comment( 'pingback' ),
$this->make_comment( 'trackback' ),
);

$separated = separate_comments( $comments );

$this->assertCount( 1, $separated['comment'] );
$this->assertCount( 1, $separated['pingback'] );
$this->assertCount( 1, $separated['trackback'] );
$this->assertCount( 2, $separated['pings'] );
}

/**
* A registered comment type marked as a ping is grouped into 'pings'.
*
* @ticket 35214
*/
public function test_registered_ping_type_is_grouped_into_pings_bucket() {
register_comment_type( 'webmention', array( 'is_ping' => true ) );

$comments = array( $this->make_comment( 'webmention' ) );

$separated = separate_comments( $comments );

$this->assertCount( 1, $separated['webmention'] );
$this->assertCount( 1, $separated['pings'] );

unregister_comment_type( 'webmention' );
}

/**
* A registered comment type that is not a ping stays out of the 'pings' bucket.
*
* @ticket 35214
*/
public function test_non_ping_type_is_not_grouped_into_pings_bucket() {
register_comment_type( 'review' );

$comments = array( $this->make_comment( 'review' ) );

$separated = separate_comments( $comments );

$this->assertCount( 1, $separated['review'] );
$this->assertCount( 0, $separated['pings'] );

unregister_comment_type( 'review' );
}
}
16 changes: 16 additions & 0 deletions tests/phpunit/tests/comment/types.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ public function test_built_in_note_type_is_internal_and_non_public() {
$this->assertFalse( $note->public );
}

/**
* @ticket 35214
*/
public function test_built_in_ping_types_are_marked_as_pings() {
$this->assertTrue( get_comment_type_object( 'pingback' )->is_ping );
$this->assertTrue( get_comment_type_object( 'trackback' )->is_ping );
}

/**
* @ticket 35214
*/
public function test_built_in_non_ping_types_are_not_marked_as_pings() {
$this->assertFalse( get_comment_type_object( 'comment' )->is_ping );
$this->assertFalse( get_comment_type_object( 'note' )->is_ping );
}

/**
* @ticket 35214
*/
Expand Down
112 changes: 112 additions & 0 deletions tests/phpunit/tests/comment/walker.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,118 @@ public function test_explicit_callback_takes_precedence_over_render_callback() {
unregister_comment_type( 'review' );
}

/**
* A registered ping type renders with the compact ping markup when short_ping is on.
*
* @ticket 35214
*/
public function test_registered_ping_type_renders_as_ping() {
register_comment_type( 'webmention', array( 'is_ping' => true ) );

$comment_id = self::factory()->comment->create(
array(
'comment_post_ID' => $this->post_id,
'comment_type' => 'webmention',
'comment_content' => 'A webmention body',
'comment_approved' => '1',
)
);

$output = $this->render_comments(
array( get_comment( $comment_id ) ),
array( 'short_ping' => true )
);

// The compact ping markup prints the "Pingback:" label and omits the comment body.
$this->assertStringContainsString( 'Pingback:', $output );
$this->assertStringNotContainsString( 'A webmention body', $output );

unregister_comment_type( 'webmention' );
}

/**
* The built-in pingback type still renders with the compact ping markup.
*
* Guards the refactor from hard-coded `pingback`/`trackback` string checks to
* the `is_ping` flag: built-in ping rendering must remain unchanged.
*
* @ticket 35214
*/
public function test_built_in_pingback_still_renders_as_ping() {
$comment_id = self::factory()->comment->create(
array(
'comment_post_ID' => $this->post_id,
'comment_type' => 'pingback',
'comment_content' => 'A pingback body',
'comment_approved' => '1',
)
);

$output = $this->render_comments(
array( get_comment( $comment_id ) ),
array( 'short_ping' => true )
);

$this->assertStringContainsString( 'Pingback:', $output );
$this->assertStringNotContainsString( 'A pingback body', $output );
}

/**
* A ping type renders its full markup (not the compact ping) when short_ping is off.
*
* @ticket 35214
*/
public function test_ping_type_renders_full_markup_when_short_ping_disabled() {
register_comment_type( 'webmention', array( 'is_ping' => true ) );

$comment_id = self::factory()->comment->create(
array(
'comment_post_ID' => $this->post_id,
'comment_type' => 'webmention',
'comment_content' => 'A webmention body',
'comment_approved' => '1',
)
);

$output = $this->render_comments(
array( get_comment( $comment_id ) ),
array( 'short_ping' => false )
);

// With short_ping off the full markup is rendered, including the comment body.
$this->assertStringContainsString( 'A webmention body', $output );

unregister_comment_type( 'webmention' );
}

/**
* A non-ping type is never rendered as a ping, even with short_ping enabled.
*
* @ticket 35214
*/
public function test_non_ping_type_is_not_rendered_as_ping_with_short_ping() {
register_comment_type( 'review' );

$comment_id = self::factory()->comment->create(
array(
'comment_post_ID' => $this->post_id,
'comment_type' => 'review',
'comment_content' => 'A review body',
'comment_approved' => '1',
)
);

$output = $this->render_comments(
array( get_comment( $comment_id ) ),
array( 'short_ping' => true )
);

$this->assertStringContainsString( 'A review body', $output );
$this->assertStringNotContainsString( 'Pingback:', $output );

unregister_comment_type( 'review' );
}

/**
* Built-in comment types without a render_callback render normally.
*
Expand Down
12 changes: 12 additions & 0 deletions tests/phpunit/tests/comment/wpCommentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ public function test_instance_defaults() {
$this->assertTrue( $comment_type->show_ui );
$this->assertFalse( $comment_type->hierarchical );
$this->assertNull( $comment_type->render_callback );
$this->assertFalse( $comment_type->is_ping );
}

/**
* @ticket 35214
*
* @covers ::set_props
*/
public function test_is_ping_is_stored() {
$comment_type = new WP_Comment_Type( 'foo', array( 'is_ping' => true ) );

$this->assertTrue( $comment_type->is_ping );
}

/**
Expand Down
Loading