PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.6
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.6
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / includes / plugin-notices.php

plugin-notices.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.6, at includes/plugin-notices.php

151 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A small, opt-in allowlist of well-known *library* admin notices that render
4 * globally (so they repeat in every desktop window) and can be re-derived from
5 * authoritative state. Unlike arbitrary plugin `admin_notices` — which we
6 * deliberately leave alone — these are shared
7 * libraries bundled across many plugins, common enough to warrant a targeted
8 * case. Each entry is detached in-window and surfaced once in the shell, the
9 * same pattern as the core notices.
10 *
11 * @since 0.9.6
12 * @package DesktopMode
13 */
14
15 defined( 'ABSPATH' ) || exit;
16
17 /**
18 * The allowlisted plugin/library notices for the current user, as shell
19 * descriptors (same shape as `desktop_mode_get_core_notices()`).
20 *
21 * @since 0.9.6
22 *
23 * @return array<int,array{id:string,title:string,message:string,actionLabel:string,actionUrl:string}>
24 */
25 function desktop_mode_get_plugin_notices() {
26 $builders = array(
27 'desktop_mode_plugin_notice_action_scheduler',
28 );
29
30 $notices = array();
31 foreach ( $builders as $builder ) {
32 $notice = $builder();
33 if ( $notice ) {
34 $notices[] = $notice;
35 }
36 }
37
38 /**
39 * Filters the allowlisted plugin/library notices surfaced once in the
40 * desktop shell. Return an empty array to suppress them all, or unset
41 * individual entries by `id`.
42 *
43 * @since 0.9.6
44 *
45 * @param array $notices List of notice descriptors.
46 */
47 return apply_filters( 'desktop_mode_plugin_notices', $notices );
48 }
49
50 /**
51 * Action Scheduler's "N past-due actions found" warning — bundled by
52 * WooCommerce, Jetpack, and many other plugins, and printed globally on
53 * `admin_notices` (with no throttle while past-due actions exist, so it
54 * repeats in every window). Re-derived here from Action Scheduler's own store,
55 * mirroring `ActionScheduler_AdminView::check_pastdue_actions()` including its
56 * filters, so the count matches what Action Scheduler would show.
57 *
58 * @since 0.9.6
59 *
60 * @return array|null
61 */
62 function desktop_mode_plugin_notice_action_scheduler() {
63 if ( ! class_exists( 'ActionScheduler_Store' ) || ! function_exists( 'as_get_datetime_object' ) ) {
64 return null;
65 }
66
67 // Capability gate — mirrors `action_scheduler_check_pastdue_actions`.
68 if ( ! apply_filters( 'action_scheduler_check_pastdue_actions', current_user_can( 'manage_options' ) ) ) {
69 return null;
70 }
71
72 $threshold_seconds = (int) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS );
73 $threshold_min = (int) apply_filters( 'action_scheduler_pastdue_actions_min', 1 );
74
75 // A third party can preempt Action Scheduler's own check; when it does the
76 // count is opaque, so mirror Action Scheduler and don't surface.
77 if ( ! is_null( apply_filters( 'action_scheduler_pastdue_actions_check_pre', null ) ) ) {
78 return null;
79 }
80
81 $query_args = array(
82 'date' => as_get_datetime_object( time() - $threshold_seconds ),
83 'status' => ActionScheduler_Store::STATUS_PENDING,
84 'per_page' => $threshold_min,
85 );
86
87 $count = (int) ActionScheduler_Store::instance()->query_actions( $query_args, 'count' );
88
89 $check = (bool) apply_filters(
90 'action_scheduler_pastdue_actions_check',
91 $count >= $threshold_min,
92 $count,
93 $threshold_seconds,
94 $threshold_min
95 );
96 if ( ! $check ) {
97 return null;
98 }
99
100 $url = add_query_arg(
101 array(
102 'page' => 'action-scheduler',
103 'status' => 'past-due',
104 'order' => 'asc',
105 ),
106 admin_url( 'tools.php' )
107 );
108
109 return array(
110 'id' => 'action-scheduler-pastdue',
111 'title' => __( 'Scheduled Actions', 'desktop-mode' ),
112 'message' => sprintf(
113 /* translators: %d: number of past-due scheduled actions. */
114 _n(
115 'Action Scheduler: %d past-due action found; something may be wrong.',
116 'Action Scheduler: %d past-due actions found; something may be wrong.',
117 $count,
118 'desktop-mode'
119 ),
120 $count
121 ),
122 'actionLabel' => __( 'View actions', 'desktop-mode' ),
123 'actionUrl' => $url,
124 );
125 }
126
127 /**
128 * Detaches the allowlisted plugin/library notices inside chromeless iframes so
129 * they don't repeat in every window — the shell surfaces each once (see
130 * `desktop_mode_get_plugin_notices()`).
131 *
132 * @since 0.9.6
133 */
134 function desktop_mode_chromeless_suppress_plugin_notices() {
135 if ( ! desktop_mode_is_chromeless_request() ) {
136 return;
137 }
138
139 // Action Scheduler registers the notice as an instance method on its
140 // `ActionScheduler_AdminView` singleton (during `init`, before this runs).
141 // Detect the actual priority it registered at rather than assuming 10.
142 if ( class_exists( 'ActionScheduler_AdminView' ) ) {
143 $callback = array( ActionScheduler_AdminView::instance(), 'maybe_check_pastdue_actions' );
144 $priority = has_action( 'admin_notices', $callback );
145 if ( false !== $priority ) {
146 remove_action( 'admin_notices', $callback, $priority );
147 }
148 }
149 }
150 add_action( 'admin_init', 'desktop_mode_chromeless_suppress_plugin_notices' );
151