utils-log.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. // Logging + admin-notice utility for the plugin.
  3. defined('ABSPATH') || exit;
  4. class UtilsLog {
  5. const NOTICE_TRANSIENT_PREFIX = 'studiou_wc_ops_notices_';
  6. const NOTICE_TTL = 300; // 5 minutes — survives slow redirects.
  7. public static function init() {
  8. add_action('admin_notices', array(__CLASS__, 'render_notices'));
  9. }
  10. public static function log($message) {
  11. if (defined('WP_DEBUG') && WP_DEBUG) {
  12. if (is_array($message) || is_object($message)) {
  13. error_log('[studiou-wc-ord-print-statuses] ' . print_r($message, true));
  14. } else {
  15. error_log('[studiou-wc-ord-print-statuses] ' . $message);
  16. }
  17. }
  18. }
  19. /**
  20. * Queue an admin notice for the current user.
  21. * Notices survive the redirect that follows bulk actions and imports.
  22. *
  23. * @param string $message Plain text. Tags are HTML-escaped at render
  24. * time (esc_html). Callers should pre-format
  25. * any user-controlled content with esc_html
  26. * themselves if they need to keep markup such
  27. * as <code>.
  28. * @param string $type One of: info, success, warning, error.
  29. */
  30. public static function message($message, $type = 'info') {
  31. $user_id = get_current_user_id();
  32. if (!$user_id) {
  33. return;
  34. }
  35. $allowed = array('info', 'success', 'warning', 'error');
  36. if (!in_array($type, $allowed, true)) {
  37. $type = 'info';
  38. }
  39. $key = self::NOTICE_TRANSIENT_PREFIX . $user_id;
  40. $notices = get_transient($key);
  41. if (!is_array($notices)) {
  42. $notices = array();
  43. }
  44. $notices[] = array('message' => (string) $message, 'type' => $type);
  45. set_transient($key, $notices, self::NOTICE_TTL);
  46. }
  47. public static function render_notices() {
  48. $user_id = get_current_user_id();
  49. if (!$user_id) {
  50. return;
  51. }
  52. $key = self::NOTICE_TRANSIENT_PREFIX . $user_id;
  53. $notices = get_transient($key);
  54. if (!is_array($notices) || empty($notices)) {
  55. return;
  56. }
  57. delete_transient($key);
  58. foreach ($notices as $notice) {
  59. $type = isset($notice['type']) ? $notice['type'] : 'info';
  60. $message = isset($notice['message']) ? $notice['message'] : '';
  61. // Tight escape — notice messages are plain text in every
  62. // current call site. Switching to esc_html (was wp_kses_post)
  63. // narrows the trust boundary at the API edge: callers can no
  64. // longer accidentally smuggle HTML through the notice queue.
  65. printf(
  66. '<div class="notice notice-%1$s is-dismissible"><p>%2$s</p></div>',
  67. esc_attr($type),
  68. esc_html($message)
  69. );
  70. }
  71. }
  72. }