PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.12 1.1.11 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 All 36 releases
desktop-mode / includes / first-run / nudge.php

nudge.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.12, at includes/first-run/nudge.php

203 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — the activation nudge.
4 *
5 * A dismissible admin notice on the Dashboard and Plugins screens,
6 * for administrators, while nobody on the site has turned OpenStation
7 * on and the install is young. The welcome dialog
8 * (`includes/welcome-dialog.php`) is the first touch; this is the
9 * second, quieter one for the same admin after they dismissed the
10 * modal, and it lives where plugin admins actually look. Both stop
11 * the moment anyone on the site enables.
12 *
13 * It is a Core admin notice and not a shell surface because, by
14 * definition, the shell is not running for the people it targets.
15 * Dismissal persists through the seen-intros registry (slug
16 * `activation-nudge`) via the same REST route the welcome dialog
17 * uses — Core's `is-dismissible` is client-only and would bring the
18 * notice back on the next load.
19 *
20 * @package OpenStation
21 */
22
23 defined( 'ABSPATH' ) || exit;
24
25 /** Slug stored in `desktop_mode_seen_intros` when "Not now" is clicked. */
26 const OPENSTATION_ACTIVATION_NUDGE_INTRO_SLUG = 'activation-nudge';
27
28 /** The nudge stops on its own once the install is this old. */
29 const OPENSTATION_ACTIVATION_NUDGE_MAX_AGE_DAYS = 14;
30
31 /**
32 * Screens the nudge may appear on: the Dashboard and Plugins, plus
33 * their network-admin twins.
34 *
35 * @return string[]
36 */
37 function openstation_activation_nudge_screens() {
38 return array( 'dashboard', 'plugins', 'dashboard-network', 'plugins-network' );
39 }
40
41 /**
42 * Decides whether the nudge renders on the current request.
43 *
44 * Every gate has to hold:
45 *
46 * 1. The user can `activate_plugins` — the nudge is addressed to the
47 * person who installed the plugin, not to every account.
48 * 2. OpenStation is not enabled for this user.
49 * 3. Nobody on the site has ever enabled it (`openstation_first_enabled_at`
50 * absent). The nudge is about an install that never activated; one
51 * enabled user is an activated install.
52 * 4. The install stamp is real (`via: activation`) and under
53 * {@see OPENSTATION_ACTIVATION_NUDGE_MAX_AGE_DAYS} old. A backfilled
54 * stamp belongs to an old install, and old installs are not nagged.
55 * 5. The screen is one of {@see openstation_activation_nudge_screens()}.
56 * 6. The request is not chromeless (an iframe inside the shell).
57 * 7. The user has not clicked "Not now".
58 * 8. The welcome dialog is not rendering on this same request. The
59 * nudge is the second touch, for after the modal has been
60 * dismissed; on the first admin load both passed their gates, and
61 * "Plugin activated" came with a modal, a notice and a row action
62 * all asking for the same click.
63 * 9. The `openstation_show_activation_nudge` filter agrees.
64 *
65 * @return bool
66 */
67 function openstation_should_show_activation_nudge() {
68 if ( ! is_user_logged_in() || ! current_user_can( 'activate_plugins' ) ) {
69 return false;
70 }
71 if ( openstation_is_enabled() ) {
72 return false;
73 }
74 if ( null !== openstation_get_first_enabled_stamp() ) {
75 return false;
76 }
77 $age = openstation_install_age_days();
78 if ( null === $age || $age >= OPENSTATION_ACTIVATION_NUDGE_MAX_AGE_DAYS ) {
79 return false;
80 }
81 $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
82 if ( ! $screen || ! in_array( $screen->id, openstation_activation_nudge_screens(), true ) ) {
83 return false;
84 }
85 if ( openstation_is_chromeless_request() ) {
86 return false;
87 }
88 $user_id = get_current_user_id();
89 if ( openstation_has_seen_intro( $user_id, OPENSTATION_ACTIVATION_NUDGE_INTRO_SLUG ) ) {
90 return false;
91 }
92 // Asked of the dialog's own gate rather than of its seen-slug: a
93 // site that filters the dialog off never records the slug, and the
94 // nudge would then wait for a dismissal that cannot happen.
95 if ( function_exists( 'openstation_should_show_welcome_dialog' ) && openstation_should_show_welcome_dialog() ) {
96 return false;
97 }
98
99 /**
100 * Filters whether the activation nudge renders for the current
101 * user on the current request. Every earlier gate (capability,
102 * site never enabled, install age, screen, seen-state, no welcome
103 * dialog on this request) has already passed when this fires.
104 *
105 * @param bool $show Whether to render the notice. Default true.
106 * @param int $user_id Current user ID.
107 */
108 return (bool) apply_filters( 'openstation_show_activation_nudge', true, $user_id );
109 }
110
111 /**
112 * The notice's inner markup: one sentence and two actions.
113 *
114 * @return string HTML.
115 */
116 function openstation_activation_nudge_markup() {
117 $portal_url = openstation_portal_url();
118
119 $message = sprintf(
120 '<strong>%s</strong> %s',
121 esc_html__( 'OpenStation is installed but not turned on.', 'desktop-mode' ),
122 esc_html__( 'It changes wp-admin only for the people who turn it on.', 'desktop-mode' )
123 );
124
125 $actions = sprintf(
126 '<p class="os-activation-nudge__actions"><a class="button button-primary" href="%1$s">%2$s</a> <button type="button" class="button-link os-activation-nudge__dismiss">%3$s</button></p>',
127 esc_url( $portal_url ),
128 esc_html__( 'Turn on OpenStation', 'desktop-mode' ),
129 esc_html__( 'Not now', 'desktop-mode' )
130 );
131
132 return '<p>' . $message . '</p>' . $actions;
133 }
134
135 /**
136 * Prints the nudge on `admin_notices` / `network_admin_notices`.
137 *
138 * `wp_admin_notice()` when Core has it; the same `div.notice` markup
139 * by hand on older versions (the plugin supports 6.0). The "Not now"
140 * button carries a small inline script that POSTs the slug to the
141 * seen-intros route and removes the notice, exactly as the welcome
142 * dialog does.
143 *
144 * @return void
145 */
146 function openstation_render_activation_nudge() {
147 if ( ! openstation_should_show_activation_nudge() ) {
148 return;
149 }
150
151 $markup = openstation_activation_nudge_markup();
152 if ( function_exists( 'wp_admin_notice' ) ) {
153 wp_admin_notice(
154 $markup,
155 array(
156 'type' => 'info',
157 'id' => 'os-activation-nudge',
158 'additional_classes' => array( 'os-activation-nudge' ),
159 'paragraph_wrap' => false,
160 )
161 );
162 } else {
163 echo '<div id="os-activation-nudge" class="notice notice-info os-activation-nudge">' . $markup . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built from escaped parts in openstation_activation_nudge_markup().
164 }
165
166 $rest_url = esc_url_raw( rest_url( 'desktop-mode/v1/intros/seen' ) );
167 $rest_nonce = wp_create_nonce( 'wp_rest' );
168 ?>
169 <style id="os-activation-nudge-style">
170 .os-activation-nudge__actions { margin: 0.5em 0 0.75em; }
171 .os-activation-nudge__actions .button-link { margin-left: 8px; }
172 </style>
173 <script id="os-activation-nudge-script">
174 ( function () {
175 var notice = document.getElementById( 'os-activation-nudge' );
176 if ( ! notice ) {
177 return;
178 }
179 var dismiss = notice.querySelector( '.os-activation-nudge__dismiss' );
180 if ( ! dismiss ) {
181 return;
182 }
183 dismiss.addEventListener( 'click', function () {
184 notice.remove();
185 try {
186 fetch( <?php echo wp_json_encode( $rest_url ); ?>, {
187 method: 'POST',
188 credentials: 'same-origin',
189 headers: {
190 'Content-Type': 'application/json',
191 'X-WP-Nonce': <?php echo wp_json_encode( $rest_nonce ); ?>
192 },
193 body: JSON.stringify( { slug: <?php echo wp_json_encode( OPENSTATION_ACTIVATION_NUDGE_INTRO_SLUG ); ?> } )
194 } ).catch( function () {} );
195 } catch ( e ) {}
196 } );
197 } )();
198 </script>
199 <?php
200 }
201 add_action( 'admin_notices', 'openstation_render_activation_nudge' );
202 add_action( 'network_admin_notices', 'openstation_render_activation_nudge' );
203