Control Comments
Overview
Control comment support and related WordPress admin UI from one snippet.
By default, comments are disabled globally, disabled for posts and pages, and removed from public post types unless comments are explicitly allowed. The snippet also removes comment output, the Comments admin menu, the recent comments dashboard widget, the admin bar comments node, and direct access to the comments screen when comments are disabled.
Change the top-level constants in the procedural snippet, or the class constants in the OOP variant, when a site needs comments enabled for posts or pages.
Variants
- Procedural
- OOP
<?php
/**
* Control comment behavior and related admin UI.
*/
const MAC_COMMENTS_ENABLED = false;
const MAC_COMMENTS_ENABLE_POSTS = false;
const MAC_COMMENTS_ENABLE_PAGES = false;
/**
* Check whether comments are allowed for a post.
*/
if ( ! function_exists( 'mac_comments_allowed_for_post' ) ) {
function mac_comments_allowed_for_post( int $post_id ): bool {
if ( ! MAC_COMMENTS_ENABLED ) {
return false;
}
$post_type = (string) get_post_type( $post_id );
return match ( $post_type ) {
'post' => MAC_COMMENTS_ENABLE_POSTS,
'page' => MAC_COMMENTS_ENABLE_PAGES,
default => post_type_supports( $post_type, 'comments' ),
};
}
}
/**
* Check whether comments are supported anywhere.
*/
if ( ! function_exists( 'mac_any_comments_supported' ) ) {
function mac_any_comments_supported(): bool {
if ( MAC_COMMENTS_ENABLED && ( MAC_COMMENTS_ENABLE_POSTS || MAC_COMMENTS_ENABLE_PAGES ) ) {
return true;
}
foreach ( get_post_types( ['public' => true], 'names' ) as $post_type ) {
if ( ! in_array( $post_type, ['post', 'page'], true )
&& post_type_supports( $post_type, 'comments' )
) {
return true;
}
}
return false;
}
}
/**
* Filter comment and ping open state.
*/
if ( ! function_exists( 'mac_filter_comments_open' ) ) {
function mac_filter_comments_open( bool $open, int|WP_Post|null $post ): bool {
if ( ! MAC_COMMENTS_ENABLED ) {
return false;
}
$post_id = is_object( $post ) ? (int) $post->ID : (int) $post;
if ( $post_id <= 0 ) {
return false;
}
return mac_comments_allowed_for_post( $post_id );
}
}
add_filter( 'comments_open', 'mac_filter_comments_open', 10, 2 );
add_filter( 'pings_open', 'mac_filter_comments_open', 10, 2 );
/**
* Hide existing comments when disallowed.
*/
if ( ! function_exists( 'mac_filter_comments_array' ) ) {
function mac_filter_comments_array( array $comments, int $post_id ): array {
if ( ! MAC_COMMENTS_ENABLED || ! mac_comments_allowed_for_post( $post_id ) ) {
return [];
}
return $comments;
}
}
add_filter( 'comments_array', 'mac_filter_comments_array', 10, 2 );
/**
* Remove comment support from post types.
*/
if ( ! function_exists( 'mac_enforce_comment_post_type_support' ) ) {
function mac_enforce_comment_post_type_support(): void {
foreach ( get_post_types( ['public' => true], 'names' ) as $post_type ) {
$allow = match ( $post_type ) {
'post' => MAC_COMMENTS_ENABLED && MAC_COMMENTS_ENABLE_POSTS,
'page' => MAC_COMMENTS_ENABLED && MAC_COMMENTS_ENABLE_PAGES,
default => MAC_COMMENTS_ENABLED && post_type_supports( $post_type, 'comments' ),
};
if ( ! $allow ) {
remove_post_type_support( $post_type, 'comments' );
remove_post_type_support( $post_type, 'trackbacks' );
}
}
}
}
add_action( 'init', 'mac_enforce_comment_post_type_support', 20 );
/**
* Remove Comments admin menu entry.
*/
if ( ! function_exists( 'mac_remove_comments_admin_menu' ) ) {
function mac_remove_comments_admin_menu(): void {
if ( ! MAC_COMMENTS_ENABLED || ! mac_any_comments_supported() ) {
remove_menu_page( 'edit-comments.php' );
}
}
}
add_action( 'admin_menu', 'mac_remove_comments_admin_menu', 99 );
add_action( 'network_admin_menu', 'mac_remove_comments_admin_menu', 99 );
/**
* Remove Comments dashboard widget.
*/
if ( ! function_exists( 'mac_remove_comments_dashboard_widget' ) ) {
function mac_remove_comments_dashboard_widget(): void {
if ( ! MAC_COMMENTS_ENABLED || ! mac_any_comments_supported() ) {
remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
}
}
}
add_action( 'wp_dashboard_setup', 'mac_remove_comments_dashboard_widget', 20 );
/**
* Remove Comments admin bar node.
*/
if ( ! function_exists( 'mac_remove_comments_admin_bar_node' ) ) {
function mac_remove_comments_admin_bar_node( WP_Admin_Bar $bar ): void {
if ( ! is_admin_bar_showing() ) {
return;
}
if ( ! MAC_COMMENTS_ENABLED || ! mac_any_comments_supported() ) {
$bar->remove_node( 'comments' );
}
}
}
add_action( 'admin_bar_menu', 'mac_remove_comments_admin_bar_node', 100 );
/**
* Block direct access to comments screens.
*/
if ( ! function_exists( 'mac_block_comments_screen' ) ) {
function mac_block_comments_screen(): void {
if ( ! MAC_COMMENTS_ENABLED || ! mac_any_comments_supported() ) {
wp_safe_redirect( admin_url( 'index.php' ) );
exit;
}
}
}
add_action( 'load-edit-comments.php', 'mac_block_comments_screen' );
<?php
/**
* Control comment behavior and related admin UI.
*
* Hard-coded defaults:
* - Comments disabled globally
* - Disabled for posts and pages
* - CPTs only allowed if they explicitly support comments (none by default)
*
* @package mac-core
*/
declare(strict_types=1);
namespace MacCore\Services\Core;
use MacCore\Contracts\Service;
use WP_Admin_Bar;
use WP_Post;
final class ControlComments implements Service
{
/**
* Master switch.
*/
private const ENABLED = false;
/**
* Per-type switches.
*/
private const ENABLE_POSTS = false;
private const ENABLE_PAGES = false;
public function register(): void
{
// Enforce open/closed state.
\add_filter( 'comments_open', [$this, 'filter_comments_open'], 10, 2 );
\add_filter( 'pings_open', [$this, 'filter_comments_open'], 10, 2 );
// Hide existing comments output when disallowed.
\add_filter( 'comments_array', [$this, 'filter_comments_array'], 10, 2 );
// Remove comment support from post types.
\add_action( 'init', [$this, 'enforce_post_type_support'], 20 );
// Admin UI cleanup.
\add_action( 'admin_menu', [$this, 'cleanup_admin_menu'], 99 );
\add_action( 'network_admin_menu', [$this, 'cleanup_admin_menu'], 99 );
\add_action( 'wp_dashboard_setup', [$this, 'cleanup_dashboard'], 20 );
\add_action( 'admin_bar_menu', [$this, 'cleanup_admin_bar'], 100 );
// Block direct access to comments screens when disabled.
\add_action( 'load-edit-comments.php', [$this, 'block_comments_screen'] );
}
public function filter_comments_open( bool $open, int|WP_Post|null $post ): bool
{
if ( ! self::ENABLED ) {
return false;
}
$post_id = \is_object( $post ) ? (int) $post->ID : (int) $post;
if ( $post_id <= 0 ) {
return false;
}
return $this->is_allowed_for_post( $post_id );
}
public function filter_comments_array( array $comments, int $post_id ): array
{
if ( ! self::ENABLED || ! $this->is_allowed_for_post( $post_id ) ) {
return [];
}
return $comments;
}
public function enforce_post_type_support(): void
{
foreach ( \get_post_types( ['public' => true], 'names' ) as $post_type ) {
$allow = match ( $post_type ) {
'post' => self::ENABLED && self::ENABLE_POSTS,
'page' => self::ENABLED && self::ENABLE_PAGES,
default => self::ENABLED && \post_type_supports( $post_type, 'comments' ),
};
if ( ! $allow ) {
\remove_post_type_support( $post_type, 'comments' );
\remove_post_type_support( $post_type, 'trackbacks' );
}
}
}
public function cleanup_admin_menu(): void
{
if ( ! self::ENABLED || ! $this->any_comments_supported() ) {
\remove_menu_page( 'edit-comments.php' );
}
}
public function cleanup_dashboard(): void
{
if ( ! self::ENABLED || ! $this->any_comments_supported() ) {
\remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
}
}
public function cleanup_admin_bar( WP_Admin_Bar $bar ): void
{
if ( ! \is_admin_bar_showing() ) {
return;
}
if ( ! self::ENABLED || ! $this->any_comments_supported() ) {
$bar->remove_node( 'comments' );
}
}
public function block_comments_screen(): void
{
if ( ! self::ENABLED || ! $this->any_comments_supported() ) {
\wp_safe_redirect( \admin_url( 'index.php' ) );
exit;
}
}
private function is_allowed_for_post( int $post_id ): bool
{
if ( ! self::ENABLED ) {
return false;
}
$post_type = (string) \get_post_type( $post_id );
return match ( $post_type ) {
'post' => self::ENABLE_POSTS,
'page' => self::ENABLE_PAGES,
default => \post_type_supports( $post_type, 'comments' ),
};
}
private function any_comments_supported(): bool
{
if ( self::ENABLED && ( self::ENABLE_POSTS || self::ENABLE_PAGES ) ) {
return true;
}
foreach ( \get_post_types( ['public' => true], 'names' ) as $post_type ) {
if ( ! \in_array( $post_type, ['post', 'page'], true )
&& \post_type_supports( $post_type, 'comments' )
) {
return true;
}
}
return false;
}
}