Hiding the comments.
More feedback, less feedback
The last version of the plugin is able to send and receive clicks on the “I’d like this” button but, beside the comments table, there is no quick and easy way for a post author to look up the feedback at a glance.
I will add two pieces of code to the plugin to:
- hide the plugin generated comments from the comments list
- show the post author a meta box to see which idea liked among the ones proposed on the post
Hiding the comments
Thanks to the WordPress filter mechanism filtering the comments table displayed on the back-end admin screen is easy.
I’ve set up a service provider to take care of it and registered it in the bootstrap.php
file of the plugin
class idlikethis_ServiceProviders_CommentsTable extends tad_DI52_ServiceProvider
{
/**
* Binds and sets up implementations.
*/
public function register()
{
$this->container->bind('idlikethis_Comments_TableContextInterface', 'idlikethis_Comments_TableContext');
$this->container->bind('idlikethis_Comments_TableFilterInterface', 'idlikethis_Comments_TableFilter');
add_filter('pre_get_comments', array($this->container->resolve('idlikethis_Comments_TableFilterInterface'), 'on_pre_get_comments'), 10, 1);
}
/**
* Binds and sets up implementations at boot time.
*/
public function boot()
{
// TODO: Implement boot() method.
}
}
To filter the view the idlikethis_Comments_TableFilter
class will modify the type__not_in
query variable using the pre_get_comments
filter.
To make sure such an intervention will be made on the comments edit screen only I will provide the class a context: a concrete implementation of the idlikethis_Comments_TableContextInterface
interface.
This class is a mere adapter that I will not cover, as such, with tests; the function of an object modeling the context is to decouple the idlikethis_Comments_TableFilter
class from its surroundings and make future iterations easier.
The adapter class code itself is hence trivial
class idlikethis_Comments_TableContext implements idlikethis_Comments_TableContextInterface
{
/**
* Whether the current context is an admin comments edit screen or not.
*
* @return bool
*/
public function is_comments_edit_screen()
{
$current_screen = get_current_screen();
return is_admin() && $current_screen && $current_screen->base == 'edit-comments';
}
}
A quick test scaffold for the filtering class
wpcept generate:wpunit wpunit "idlikethis\Comments\TableFilter"
and the code to fill it
namespace idlikethis\Comments;
use idlikethis_Comments_TableFilter as TableFilter;
class TableFilterTest extends \Codeception\TestCase\WPTestCase
{
/**
* @var idlikethis_Comments_TableContextInterface
*/
protected $context;
protected $types;
public function setUp()
{
// before
parent::setUp();
// your set up methods here
$this->types = 'some-commment-type';
$this->context = $this->prophesize('idlikethis_Comments_TableContextInterface');
}
public function tearDown()
{
// your tear down methods here
// then
parent::tearDown();
}
/**
* @test
* it should be instantiatable
*/
public function it_should_be_instantiatable()
{
$sut = $this->make_instance();
$this->assertInstanceOf('idlikethis_Comments_TableFilter', $sut);
}
/**
* @test
* it should not add the type__not_in query var if not the right context
*/
public function it_should_not_add_the_types_not_in_query_var_if_not_the_right_context()
{
$this->context->is_comments_edit_screen()->willReturn(false);
$sut = $this->make_instance();
$query = $this->getMockBuilder('WP_Comment_Query')->disableOriginalConstructor()->getMock();
$query->query_vars = [];
$query->query_vars['type__not_in'] = [];
$sut->on_pre_get_comments($query);
$this->assertEmpty($query->query_vars['type__not_in']);
}
/**
* @test
* it should not add the type__not_in query var if types empty
*/
public function it_should_not_add_the_types_not_in_query_var_if_types_empty()
{
$this->types = [];
$this->context->is_comments_edit_screen()->willReturn(true);
$sut = $this->make_instance();
$query = $this->getMockBuilder('WP_Comment_Query')->disableOriginalConstructor()->getMock();
$query->query_vars = [];
$query->query_vars['type__not_in'] = [];
$sut->on_pre_get_comments($query);
$this->assertEmpty($query->query_vars['type__not_in']);
}
/**
* @test
* it should add the type__not_in query var
*/
public function it_should_add_the_type_not_in_query_var()
{
$this->context->is_comments_edit_screen()->willReturn(true);
$sut = $this->make_instance();
$query = $this->getMockBuilder('WP_Comment_Query')->disableOriginalConstructor()->getMock();
$query->query_vars = [];
$query->query_vars['type__not_in'] = [];
$sut->on_pre_get_comments($query);
$this->assertEquals((array)$this->types, $query->query_vars['type__not_in']);
}
/**
* @test
* it should preserve existing type exclusions
*/
public function it_should_preserve_existing_type_exclusions()
{
$this->context->is_comments_edit_screen()->willReturn(true);
$sut = $this->make_instance();
$query = $this->getMockBuilder('WP_Comment_Query')->disableOriginalConstructor()->getMock();
$query->query_vars = [];
$query->query_vars['type__not_in'] = ['some-other-type'];
$sut->on_pre_get_comments($query);
$this->assertEquals(array_merge(['some-other-type'], (array)$this->types), $query->query_vars['type__not_in']);
}
private function make_instance()
{
return new TableFilter($this->types, $this->context->reveal());
}
}
The final TableFilter
class code is as follows
class idlikethis_Comments_TableFilter implements idlikethis_Comments_TableFilterInterface
{
/**
* @var string
*/
protected $comment_type;
/**
* @var idlikethis_Comments_TableContextInterface
*/
private $context;
/**
* idlikethis_Comments_TableFilter constructor.
* @param string $comment_type
* @param idlikethis_Comments_TableContextInterface $context
*/
public function __construct($comment_type = 'idlikethis', idlikethis_Comments_TableContextInterface $context)
{
$this->comment_type = $comment_type;
$this->context = $context;
}
/**
* Sets some query var parameters on the comments query before comments are fetched.
*
* @param WP_Comment_Query $query
* @return void
*/
public function on_pre_get_comments(WP_Comment_Query $query)
{
if (!$this->context->is_comments_edit_screen()) {
return;
}
$old = isset($query->query_vars['type__not_in']) ? (array)$query->query_vars['type__not_in'] : array();
$query->query_vars['type__not_in'] = array_merge($old, (array)$this->comment_type);
}
}
On GitHub
The code current to this post is on GitHub.
Next
The meta box next!