. * @param string $type One of: info, success, warning, error. */ public static function message($message, $type = 'info') { $user_id = get_current_user_id(); if (!$user_id) { return; } $allowed = array('info', 'success', 'warning', 'error'); if (!in_array($type, $allowed, true)) { $type = 'info'; } $key = self::NOTICE_TRANSIENT_PREFIX . $user_id; $notices = get_transient($key); if (!is_array($notices)) { $notices = array(); } $notices[] = array('message' => (string) $message, 'type' => $type); set_transient($key, $notices, self::NOTICE_TTL); } public static function render_notices() { $user_id = get_current_user_id(); if (!$user_id) { return; } $key = self::NOTICE_TRANSIENT_PREFIX . $user_id; $notices = get_transient($key); if (!is_array($notices) || empty($notices)) { return; } delete_transient($key); foreach ($notices as $notice) { $type = isset($notice['type']) ? $notice['type'] : 'info'; $message = isset($notice['message']) ? $notice['message'] : ''; // Tight escape — notice messages are plain text in every // current call site. Switching to esc_html (was wp_kses_post) // narrows the trust boundary at the API edge: callers can no // longer accidentally smuggle HTML through the notice queue. printf( '

%2$s

', esc_attr($type), esc_html($message) ); } } }