0

I've enabled a plugin that sets an admin notice saying the cron is not running. This is not true - I'm just using an actual cron triggered via WP CLI as opposed to WP's poor man so there is no need for this message.

Unfortunately it looks like there is no hook to alter admin messages before they are rendered, but is there a way to filter messages that contain a certain string and stop them from being displayed?

4
  • Note that some plugins don't use the hooks and actions to output admin notices, you might be better off trying to unhook/disable the message you're trying to eliminate, rather than trying to remove all messages that contain a certain string – Tom J Nowell Oct 8 '18 at 14:20
  • How can a module add an admin notice without hooking into the admin_notices action? Any example plugins? – Felix Eve Oct 8 '18 at 14:22
  • My understanding is that if you put an admin notice in your code halfway down the page, JS will hoist it up into the correct location, likely as a backwards compat thing. Eitherway the solution you're asking how to implement is a patch over the real problem, it would be better to prevent it showing the notice in the first place rather than hiding it away via code. Have you contacted the plugin author? – Tom J Nowell Oct 8 '18 at 16:33
  • Thanks for the info @TomJNowell, did not realize that. What a shame there is not just one API endpoint for all messages. Seems like a bit of a mess really! Plugin's authors solution was just to comment out that line of code however hacking third party plugins is just not a real option. So for now I think this is the best option available. – Felix Eve Oct 9 '18 at 7:29
0

Yes, this is possible (but a pain).

Admin messages are creating when Wordpress runs this line in admin-header.php:

do_action( 'admin_notices' );

The action called before this one is:

do_action( 'in_admin_header' );

So, we can hook in there and run some code to make some changes to filter out messages before Wordpress can render them.

First create a new action to bind to the 'in_admin_header' event:

add_action('in_admin_header', 'admin_mods_disable_some_admin_notices');

When a plugin wants to display an admin message they add an admin_notices's callback. It would be sensible if these actions returned the HTML to display as opposed to just printing it, however this is not the case, so we'll need to loop over all the callbacks and set an output buffer for each to collect the generated HTML and then check if that contains a forbidden string. It it does then we can unbind that modules admin_notices callback.

For example:

function admin_mods_disable_some_admin_notices() {

    // This global object is used to store all plugins callbacks for different hooks
    global $wp_filter;

    // Here we define the strings that we don't want to appear in any messages
    $forbidden_message_strings = [
        'The WP scheduler doesn\'t seem to be running correctly for Newsletter'
    ];

    // Now we can loop over each of the admin_notice callbacks
    foreach($wp_filter['admin_notices'] as $weight => $callbacks) {

        foreach($callbacks as $name => $details) {

            // Start an output buffer and call the callback
            ob_start();
            call_user_func($details['function']);
            $message = ob_get_clean();

            // Check if this contains our forbidden string
            foreach($forbidden_message_strings as $forbidden_string) {
                if(strpos($message, $forbidden_string) !== FALSE) {

                     // Found it - under this callback
                     $wp_filter['admin_notices']->remove_filter('admin_notices', $details['function'], $weight);
                }
            }

        }

    }
}

Wordpress could really do with implementing something like Druapl's render arrays to make doing stuff like this much easier.

LIMITATIONS:

As Tom J Nowell pointed out plugins can just spit out HTML at any point and WP javascript will move them to the top of the screen. Not having one API endpoint to add all admin notices make it pretty much impossible to reliably alter all admin messages. However, using this method you can at least target any plugins that utilize the admin_notices action.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.