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

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

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