Skip to content

Instantly share code, notes, and snippets.

@abuyoyo
Created January 13, 2020 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abuyoyo/91a890f337a3a4b34f35d97f034621d0 to your computer and use it in GitHub Desktop.
Save abuyoyo/91a890f337a3a4b34f35d97f034621d0 to your computer and use it in GitHub Desktop.
WP-Admin-Notice-Register - POC plugin
<?php
/**
* Plugin Name: WP-Admin-Notice-Register
* Description: POC plugin. Slow deprecation of 'admin_notices' in favor of a notice registration API.
* Version: 0.1
*/
if ( ! defined('ABSPATH') )
wp_die( 'No soup for you!' );
/**
* Hook onto (deprecated) 'admin_notices' - very early (-1).
* Collect all admin_notice
* Remove all callbacks from 'admin_notices'
*
* ob_get/execute all 'admin_notice' callbacks - render to string
* Enqueue notices onto our new hook 'admin_notie_register' using wp_admin_enqueue_notice() API
*
*/
add_action( 'admin_notices', 'wp_admin_notice_collector', -1 );
function wp_admin_notice_collector(){
global $wp_filter;
$hook_name = 'admin_notices';
$admin_notice_hook = $wp_filter[$hook_name];
$next = $admin_notice_hook->next();
$the_ = $next;
$callbacks = $admin_notice_hook->callbacks;
/**
* run over all callbacks on 'admin_notices'
* ob_get_content()
* remove_filter() from 'admin_notices'
*
* add notice as HTML using our API
*/
foreach ( $admin_notice_hook->callbacks as $priority => $callbacks ){
foreach ($callbacks as $the_){
// Don't remove our own functions from 'admin_notices'
if ( $the_['function']=='wp_admin_notice_collector' )// && $priority == -1
continue;
if ($the_['function']=='do_admin_notice_register')// && $priority == 9000
continue;
$args = [];
$num_args = count( $args );
ob_start();
// Avoid the array_slice if possible.
if ( $the_['accepted_args'] == 0 ) {
$value = call_user_func( $the_['function'] );
} elseif ( $the_['accepted_args'] >= $num_args ) {
$value = call_user_func_array( $the_['function'], $args );
} else {
$value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int) $the_['accepted_args'] ) );
}
$notice_content = ob_get_clean();
// Only enqueue callbacks that printed messages
if ( ! empty($notice_content) ){
wp_admin_enqueue_notice($notice_content, 'html', null, $priority-1);
}
remove_filter( $hook_name, $the_['function'], $priority );
}
}
}
/**
* Add our new 'admin_notice_register' to the end of (deprecated) 'admin_notices'
*
* When converting from plugin to core:
*
* In wp-admin/admin-header.php
* we will need to replace:
*
* do_action( 'admin_notices' );
* do_action( 'user_admin_notices' );
* do_action( 'network_admin_notices' );
* do_action( 'all_admin_notices' );
*
* with:
*
* do_action('admin_notice_register');
*
* Hooks 'admin_notices' etc. should still exist (deprecated) for old plugins to hook their callbacks on.
* But we will not trigger do_action() for them.
*/
add_action( 'admin_notices', 'do_admin_notice_register', 9000 ); // arbitrary number - we're removing all else anyway :P
function do_admin_notice_register(){
do_action( 'admin_notice_register' );
}
/**
* Our new API function
*
* Wrap/format notice as html wp admin notice
* add notice to 'admin_notice_register' hook
*
* Internals are unimportant.
* This is just a POC
*
* This should be expanded to use a global class
* like so:
*
* global $wp_notice_manager
*
* $wp_notice_manager->add_notice()
* $wp_notice_manager->_render()
* ...
* etc.
*
*/
function wp_admin_notice_register( $msg, $type='info', $dismissible=false, $priority=10 ){
if ( $type == 'html' ){
$notice = $msg;
}else{
switch ($type){
case 'info':
case 'eror':
case 'success':
$notice_class = "notice-$type";
break;
default:
$notice_class = '';
}
$notice = sprintf(
'<div class="notice %s %s"><p>%s</p></div>',
$notice_class,
$dismissible ? 'is-dismissible' : '',
$msg
);
}
add_action('admin_notice_register',function()use($notice){echo $notice;},$priority);
}
/**
* Our new API function
* Wrapper function (alternative API)
*/
function wp_admin_enqueue_notice( $msg, $type='info', $dismissible=false, $priority=10 ){
wp_admin_notice_register($msg, $type, $dismissible, $priority);
}
// Test our API functions
wp_admin_notice_register( 'wp_admin_notice_register WORKS!', 'success', true);
wp_admin_enqueue_notice( 'wp_admin_enqueue_notice works TOO!');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment