Skip to content

Instantly share code, notes, and snippets.

@christianwach
Last active April 24, 2024 18:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianwach/c30d2972d1807ad9a04dff1db971b7cd to your computer and use it in GitHub Desktop.
Save christianwach/c30d2972d1807ad9a04dff1db971b7cd to your computer and use it in GitHub Desktop.
A WordPress plugin that suppresses nagging admin notices from various plugins.
<?php
/**
* Plugin Name: Suppress Admin Notices
* Plugin URI: https://gist.github.com/christianwach/c30d2972d1807ad9a04dff1db971b7cd
* Description: Stop that damn nagging!
* Version: 1.0.1
* Author: Christian Wach
* Author URI: https://haystack.co.uk
*
* @package CMW_Suppress_Notices
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* Suppress Admin Notices Class.
*
* A class that holds plugin functionality.
*
* @since 1.0
*/
class CMW_Suppress_Admin_Notices {
/**
* Constructor.
*
* @since 1.0
*/
public function __construct() {
$this->set_constants();
$this->register_hooks();
}
/**
* Sets constants.
*
* @since 1.0
*/
private function set_constants() {
/*
* Disable nag notices.
*
* This is a voluntary constant that some plugin or theme authors may implement.
* When set to "true", it should hide admin notices that may be considered bothersome
* by webmasters. Its effectiveness depends on whether or not it is implemented.
*
* @see https://developer.wordpress.org/reference/hooks/admin_notices/#comment-5163
*/
if ( ! defined( 'DISABLE_NAG_NOTICES' ) ) {
define( 'DISABLE_NAG_NOTICES', true );
}
}
/**
* Registers hooks.
*
* @since 1.0
*/
private function register_hooks() {
// Stop the Fail2Ban nag.
add_action( 'admin_init', [ $this, 'notice_fail2ban_suppress' ], 100 );
// Stop the Kadence nag.
add_action( 'admin_init', [ $this, 'notice_kadence_suppress' ], 100 );
// Stop the Groups nag.
add_action( 'admin_init', [ $this, 'notice_groups_suppress' ], 100 );
// Stop the Members nag.
add_action( 'admin_init', [ $this, 'notice_members_suppress' ], 100 );
// Stop the Ultimate Member review nag.
add_filter( 'option_um_hidden_admin_notices', [ $this, 'notice_ultimate_member_suppress' ], 100, 2 );
// TODO: AIOSEO Nag screens.
}
// -------------------------------------------------------------------------
/**
* Removes the Fail2Ban nag.
*
* @since 1.0.1
*/
public function notice_fail2ban_suppress() {
// Bail if Fail2Ban isn't activated.
if ( ! defined( 'WP_FAIL2BAN_VER' ) ) {
return;
}
// Bail if we can't find the Freemius function.
if ( ! function_exists( 'org\lecklider\charles\wordpress\wp_fail2ban\wf_fs' ) ) {
return;
}
// Remove the Fail2Ban "trial promotion" nag.
org\lecklider\charles\wordpress\wp_fail2ban\wf_fs()->add_filter( 'show_admin_notice', [ $this, 'notice_fail2ban_filter' ], 10, 2 );
}
/**
* Filters the Fail2Ban Freemius nag.
*
* @since 1.0.1
*
* @param bool $show
* @param array $msg {
* @var string $message The actual message.
* @var string $title An optional message title.
* @var string $type The type of the message ('success', 'update', 'warning', 'promotion').
* @var string $id The unique identifier of the message.
* @var string $manager_id The unique identifier of the notices manager. For plugins it would be the plugin's slug, for themes - `<slug>-theme`.
* @var string $plugin The product's title.
* @var string $wp_user_id An optional WP user ID that this admin notice is for.
* }
*/
public function notice_fail2ban_filter( $show, $msg ) {
// Remove the trial promotion nag.
if ( 'trial_promotion' === $msg['id'] ) {
$show = false;
}
// --<
return $show;
}
/**
* Removes the Kadence nag.
*
* @since 1.0
*/
public function notice_kadence_suppress() {
// Bail if Kadence isn't present.
if ( ! defined( 'KADENCE_VERSION' ) ) {
return;
}
// Get offending component.
$instance = \Kadence\Theme::instance();
if ( ! isset( $instance->components['base_support'] ) ) {
return;
}
// Remove the admin notice.
remove_action( 'admin_notices', [ $instance->components['base_support'], 'kadence_starter_templates_notice' ] );
}
/**
* Removes the Groups nag.
*
* @since 1.0
*/
public function notice_groups_suppress() {
// Bail if Groups isn't activated.
if ( ! defined( 'GROUPS_CORE_VERSION' ) ) {
return;
}
// Remove the admin notice.
if ( class_exists( 'Groups_Admin_Notice' ) ) {
remove_action( 'admin_notices', [ 'Groups_Admin_Notice', 'admin_notices' ] );
}
}
/**
* Removes the Members nag.
*
* @since 1.0
*/
public function notice_members_suppress() {
// Bail if Members isn't activated.
if ( ! function_exists( 'members_plugin' ) ) {
return;
}
// Remove its callback the hard way.
$this->filter_anon_object_remove( 'admin_notices', 'Members\ReviewPrompt', 'review_notice' );
}
/**
* Removes the Ultimate Member review nag.
*
* @since 1.0
*/
public function notice_ultimate_member_suppress( $value, $option ) {
// If there's nothing in the option, just return the review.
if ( empty( $value ) || ! is_array( $value ) ) {
return [ 'reviews_notice' ];
}
// If there are existing hidden notices, append the review.
if ( is_array( $value ) && ! in_array( 'reviews_notice', $value ) ) {
$value[] = 'reviews_notice';
}
// --<
return $value;
}
// -------------------------------------------------------------------------
/**
* Removes an Anonymous Object filter.
*
* @since 1.0
*
* @param string $tag The hook name.
* @param string $class The class name.
* @param string $method The method name.
* @param integer $priority Optional. Hook priority. Defaults to 10.
* @return bool
*/
public function filter_anon_object_remove( $tag, $class, $method, $priority = 10 ) {
// Bail if no filters of the kind we're looking for are present.
if ( ! isset( $GLOBALS['wp_filter'][$tag][$priority] ) ) {
return false;
}
// Grab the ones we want.
$filters = $GLOBALS['wp_filter'][$tag][$priority];
// Right, down to business.
foreach ( $filters as $callback ) {
if ( is_array( $callback['function'] ) && is_a( $callback['function'][0], $class ) && $method === $callback['function'][1] ) {
return remove_filter( $tag, $callback['function'], $priority );
}
}
// Fallback.
return false;
}
/**
* Removes a Closure filter.
*
* @since 1.0
*
* @param string $tag The hook name.
* @param string $filename The absolute path of the file containing the Closure.
* @param integer $priority Optional. Hook priority. Defaults to 10.
* @return bool
*/
public function filter_closure_remove( $tag, $filename, $priority = 10 ) {
// Bail if no filters of the kind we're looking for are present.
if ( ! isset( $GLOBALS['wp_filter'][$tag][$priority] ) ) {
return false;
}
// Grab the ones we want.
$filters = $GLOBALS['wp_filter'][$tag][$priority];
// Right, down to business.
foreach ( $filters as $callback ) {
if ( ! is_array( $callback['function'] ) && ( $callback['function'] instanceof Closure ) ) {
$reflection = new ReflectionFunction( $callback['function'] );
if ( false !== strpos( $reflection->getFileName(), $filename ) ) {
return remove_filter( $tag, $callback['function'], $priority );
}
}
}
// Fallback.
return false;
}
}
/**
* Gets a reference to this plugin.
*
* @since 1.0
*
* @return CMW_Suppress_Admin_Notices $plugin The plugin reference.
*/
function cmw_suppress_admin_notices() {
// Return instance.
static $plugin;
if ( ! isset( $plugin ) ) {
$plugin = new CMW_Suppress_Admin_Notices();
}
return $plugin;
}
// Bootstrap plugin.
cmw_suppress_admin_notices();
// -----------------------------------------------------------------------------
// Legacy global scope functions.
// -----------------------------------------------------------------------------
/**
* Legacy global scope function that removes an Anonymous Object filter.
*
* @since 0.1
*/
function cmw_remove_anon_object_filter( $tag, $class, $method, $priority = 10 ) {
return cmw_suppress_admin_notices()->filter_anon_object_remove( $tag, $class, $method, $priority );
}
/**
* Legacy global scope function that removes a Closure filter.
*
* @since 0.1
*/
function cmw_remove_closure_filter( $tag, $filename, $priority = 10 ) {
return cmw_suppress_admin_notices()->filter_closure_remove( $tag, $filename, $priority );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment