-
-
Save gschoppe/dd7d12577974166529ea0139f1f53939 to your computer and use it in GitHub Desktop.
Implements a standardized messaging system that allows admin notices to be passed across page redirects. usage: add_filter( 'wp_persistent_notices', function( $notices ) { $notices[] = array( 'type' => 'error', 'message' => "Houston, we have a problem!" ); return $notices;
} );
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if( !defined( 'ABSPATH' ) ) { die(); } // Include in all php files, to prevent direct execution | |
/** | |
* Class Name : WP Persistent Notices | |
* Description : Implements a Standardized messaging system that allows admin messages to be passed across page redirects. | |
* Class URI : http://gschoppe.com/wordpress/pass-wordpress-admin-notices-across-page-redirects/ | |
* Version : 1.0.0 | |
* Author : Greg Schoppe | |
* Author URI : http://gschoppe.com | |
* License: GPL-2.0+ | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt | |
**/ | |
if( !class_exists( 'WP_Persistent_Notices' ) ) { | |
class WP_Persistent_Notices { // replace ClassName with the name of your class | |
private static $_this; | |
private $session_var = 'wp_persistent_notices'; | |
private $max_age; | |
private $default_notice; | |
private $notices; | |
public static function Instance() { | |
static $instance = null; | |
if ( $instance === null ) { | |
$instance = new self(); | |
} | |
return $instance; | |
} | |
private function __construct() { | |
$this->max_age = max( intval( ini_get( 'max_execution_time' ) ) * 2, 30 ); | |
$this->notices = array(); | |
$this->default_notice = array( | |
'id' => '', | |
'type' => 'info', | |
'custom_class' => '', | |
'message' => '', | |
'dismissible' => false, | |
'html' => '', | |
'location' => 'default' | |
); | |
add_action( 'admin_init' , array( $this, 'admin_init' ) ); | |
add_action( 'admin_notices' , array( $this, 'render_notices' ) ); | |
add_action( 'wp_ajax_get_persistent_notices', array( $this, 'ajax_get_notices' ) ); | |
add_action( 'shutdown' , array( $this, 'save_notices' ) ); | |
} | |
public function admin_init() { | |
// add a filter and that returns true to replace or prevent the session initialization functionality | |
if( !apply_filters( 'wp_persistent_notices_replace_initialization', false ) ) { | |
session_start(); | |
} | |
} | |
public function add_notice( $notice = array() ) { | |
if( !is_array( $notice ) ) { | |
$notice = array( | |
'message' => $notice | |
); | |
} | |
$notice = array_merge( $this->default_notice, $notice ); | |
$notice['created'] = time(); | |
$this->notices[] = $notice; | |
return true; | |
} | |
public function render_notices( $location = 'default' ) { | |
if( !$location ) { | |
$location = 'default'; | |
} | |
if( defined( 'DOING_AJAX' ) && DOING_AJAX ) { | |
return; | |
} | |
$notices = $this->retrieve_notices( $location ); | |
$output_array = array(); | |
foreach ( $notices as $notice ) { | |
if( !is_array( $notice ) ) { | |
$notice = array( | |
'message' => $notice | |
); | |
} | |
if( $notice['html'] ) { | |
$output_array[] = wp_kses_post( $notice['html'] ); | |
} elseif( $notice['message'] ) { | |
$notice = array_merge( $this->default_notice, $notice ); | |
$id = ''; | |
if( $notice['id'] ) { | |
$id = ' id="wp-persistent-notice-' . sanitize_title( $id ) . '"'; | |
} | |
$type = ''; | |
if( $notice['type'] ) { | |
$type = ' notice-' . sanitize_title( $notice['type'] ); | |
} | |
$cclass = ''; | |
if( $notice['custom_class'] ) { | |
$cclass = ' ' . sanitize_title( $notice['custom_class'] ); | |
} | |
$dismissible = ''; | |
if( $notice['dismissible'] ) { | |
$dismissible = ' is-dismissible'; | |
} | |
$class = ' class="notice' . $type . $cclass . $dismissible . '"'; | |
$message = wp_kses_post( $notice['message'] ); | |
$output_array[] = sprintf( '<div%1$s%2$s><p>%3$s</p></div>', $id, $class, $message ); | |
} | |
} | |
echo implode( "\n", $output_array ); | |
} | |
public function ajax_get_notices() { | |
$location = 'default'; | |
if( isset( $_GET['location'] ) && $_GET['location'] ) { | |
$location = $_GET['location']; | |
} | |
if( isset( $_POST['location'] ) && $_POST['location'] ) { | |
$location = $_POST['location']; | |
} | |
$notices = $this->retrieve_notices( $location ); | |
echo json_encode( $notices ); | |
wp_die(); | |
} | |
public function save_notices() { | |
$notices = $this->retrieve_notices( 'all' ); | |
if ( isset( $notices ) ) { | |
// add a filter that returns true to replace the notice saving functionality | |
if( apply_filters( 'wp_persistent_notices_replace_save_notices', false, $notices ) !== true ) { | |
$_SESSION[ $this->session_var ] = $notices; | |
} | |
} | |
} | |
private function retrieve_notices( $location = 'default' ) { | |
// note: once a notice is retrieved, it's gone | |
$notices = array(); | |
// add a filter that returns true to prevent retrieving messages on specific pages | |
if( !apply_filters( 'wp_persistent_notices_prevent_retrieval', false ) ) { | |
// add a filter that returns notices or empty array() to replace the session retrieval functionality | |
$raw_notices = apply_filters( 'wp_persistent_notices_replace_retrieve_notices', false ); | |
if( $raw_notices === false ) { | |
$raw_notices = array(); | |
if( isset( $_SESSION[ $this->session_var ] ) && is_array( $_SESSION[ $this->session_var ] ) ) { | |
$session_notices = $_SESSION[ $this->session_var ]; | |
if( is_array( $session_notices ) ) { | |
$raw_notices = $session_notices; | |
} | |
} | |
} | |
$raw_notices += $this->notices; | |
$raw_notices = apply_filters( 'wp_persistent_notices', $raw_notices ); | |
// clear all places notices are stored | |
unset( $_SESSION[ $this->session_var ] ); | |
$this->notices = array(); | |
remove_all_filters( 'wp_persistent_notices' ); | |
$notices = array(); | |
// filter for age and location | |
foreach( $raw_notices as $notice ) { | |
if( !isset( $notice['created'] ) || !$notice['created'] ) { | |
$notice['created'] = time(); | |
} else { | |
if( time() - $notice['created'] > $this->max_age ) { | |
continue; | |
} | |
} | |
if( $location == 'all' || $notice['location'] == $location ) { | |
$notices[] = $notice; | |
} else { | |
$this->notices[] = $notice; | |
} | |
} | |
// attach a filter that returns true to disable grouping notices | |
if( !apply_filters( 'wp_persistent_notices_display_ungrouped', false ) ) { | |
usort( $notices, array( $this, 'compare_notices' ) ); | |
} | |
} | |
return $notices; | |
} | |
private function compare_notices( $a, $b ) { | |
// attach a filter that returns an integer { -1, 0, 1 } to replace comparison function | |
$compare = apply_filters( 'wp_persistent_notices_replace_comparison', false, $a, $b ); | |
if( $compare !== false ) { | |
return $compare; | |
} | |
// if one of them doesn't have a type | |
if( !isset( $a['type'] ) ) { | |
if( !isset( $b['type'] ) ) { | |
return 0; | |
} | |
return -1; | |
} | |
// if types are equal | |
if( $a['type'] == $b['type'] ) { | |
return 0; | |
} | |
// give a weight to each type | |
$test = array( $a['type'], $b['type'] ); | |
$results = array(); | |
foreach( $test as $val ) { | |
$i = false; | |
switch( $val ) { | |
case 'error': | |
$i = apply_filters( 'wp_persistent_notices_sort_error_weight', 0 ); | |
break; | |
case 'warning': | |
$i = apply_filters( 'wp_persistent_notices_sort_warning_weight', 5 ); | |
break; | |
case 'success': | |
$i = apply_filters( 'wp_persistent_notices_sort_success_weight', 10 ); | |
break; | |
case 'info': | |
$i = apply_filters( 'wp_persistent_notices_sort_info_weight', 15 ); | |
break; | |
default: | |
// use the val to determine weight | |
$i = apply_filters( 'wp_persistent_notices_sort_custom_weight', 20, $val ); | |
} | |
$results[] = $i; | |
} | |
return ( $results[0] - $results[1] ); | |
} | |
} | |
WP_Persistent_Notices::Instance(); | |
if( !function_exists( 'add_persistent_notice' ) ) { | |
function add_persistent_notice( $notice ) { | |
$cl = WP_Persistent_Notices::Instance(); | |
return $cl->add_notice( $notice ); | |
} | |
} | |
if( !function_exists( 'render_persistent_notices' ) ) { | |
function render_persistent_notices( $location = 'default' ) { | |
$cl = WP_Persistent_Notices::Instance(); | |
return $cl->render_notices( $location ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You're right. My code is not for general purpose WordPress usage.
It is for system usage when some central thing goes wrong: e.g. "Google API is not reachable" in wp-cron, or "All editors, please prepare for release!"