PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.2.12
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.2.12
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Core / SetupWizard.php

SetupWizard.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.2.12, at includes/Core/SetupWizard.php

207 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Setup Wizard (Onboarding) Class File.
4 *
5 * Registers a standalone, full-screen onboarding wizard under its own
6 * top-level "Setup Wizard" menu. The UI is rendered by the existing admin
7 * React SPA via the `nx-setup-wizard` route.
8 *
9 * @package NotificationX\Core
10 */
11
12 namespace NotificationX\Core;
13
14 use NotificationX\Admin\Admin;
15 use NotificationX\GetInstance;
16
17 /**
18 * @method static SetupWizard get_instance($args = null)
19 */
20 class SetupWizard {
21
22 /**
23 * Instance of SetupWizard
24 *
25 * @var SetupWizard
26 */
27 use GetInstance;
28
29 /**
30 * Page slug for the wizard.
31 */
32 const PAGE = 'nx-setup-wizard';
33
34 /**
35 * Option key that marks onboarding as finished/skipped.
36 */
37 const COMPLETED_OPTION = 'nx_onboarding_completed';
38
39 /**
40 * Initially Invoked when initialized.
41 */
42 public function __construct() {
43 add_action( 'admin_menu', [ $this, 'menu' ], 35 );
44 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_preview_styles' ] );
45 add_filter( 'admin_body_class', [ $this, 'body_class' ] );
46 add_filter( 'nx_rest_miscellaneous', [ $this, 'handle_actions' ], 10, 2 );
47 add_filter( 'nx_builder_configs', [ $this, 'add_status_to_context' ], 10, 1 );
48 }
49
50 /**
51 * Register the "Setup Wizard" submenu under the NotificationX menu.
52 *
53 * Rendered by Admin::views() (the same React SPA root) so the
54 * `nx-setup-wizard` route can take over the full screen.
55 *
56 * @return void
57 */
58 public function menu() {
59 add_submenu_page(
60 'nx-admin',
61 __( 'Setup Wizard', 'notificationx' ),
62 __( 'Setup Wizard', 'notificationx' ),
63 'read_notificationx',
64 self::PAGE,
65 [ Admin::get_instance(), 'views' ],
66 30
67 );
68 }
69
70 /**
71 * Load the real frontend notification stylesheet on the wizard page so the
72 * Welcome-screen "Live Preview" renders the actual popup/bar/announcement
73 * designs 1:1. The frontend CSS is fully scoped (no global resets), so it
74 * is safe to load inside wp-admin.
75 *
76 * @param string $hook
77 * @return void
78 */
79 public function enqueue_preview_styles( $hook ) {
80 if ( 'notificationx_page_' . self::PAGE !== $hook ) {
81 return;
82 }
83 wp_enqueue_style(
84 'notificationx-public',
85 Helper::file( 'public/css/frontend.css', true ),
86 [],
87 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context.
88 apply_filters( 'nx_frontend_css_version', NOTIFICATIONX_VERSION ),
89 'all'
90 );
91 }
92
93 /**
94 * Add a body class on the wizard page so the SPA can render a
95 * full-screen layout (covering the WP sidebar / admin bar).
96 *
97 * @param string $classes
98 * @return string
99 */
100 public function body_class( $classes ) {
101 if ( $this->is_wizard_page() ) {
102 $classes .= ' nx-setup-wizard-active';
103 }
104 return $classes;
105 }
106
107 /**
108 * Whether the current admin request is the wizard page.
109 *
110 * @return bool
111 */
112 protected function is_wizard_page() {
113 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
114 return is_admin() && isset( $_GET['page'] ) && self::PAGE === sanitize_key( wp_unslash( $_GET['page'] ) );
115 }
116
117 /**
118 * Handle the `complete_setup_wizard` miscellaneous REST action.
119 *
120 * Returning a non-null value makes the /miscellaneous endpoint respond
121 * with `{ success: true }`.
122 *
123 * @param mixed $result
124 * @param array $params
125 * @return mixed
126 */
127 public function handle_actions( $result, $params ) {
128 if ( isset( $params['action'] ) ) {
129 if ( 'complete_setup_wizard' === $params['action'] ) {
130 return $this->complete( $params );
131 }
132 if ( 'setup_wizard_optin' === $params['action'] ) {
133 return $this->optin_tracking();
134 }
135 }
136 return $result;
137 }
138
139 /**
140 * Opt the site into WP Insights usage tracking and send the data to the
141 * insights API immediately. Triggered when the user proceeds past the
142 * Welcome step — the in-card notice states that proceeding consents to
143 * collecting the admin email to personalise the setup.
144 *
145 * @return bool
146 */
147 public function optin_tracking() {
148 if ( ! current_user_can( 'read_notificationx' ) ) {
149 return false;
150 }
151 if (
152 class_exists( '\NotificationX\Admin\PluginInsights' )
153 && method_exists( '\NotificationX\Admin\PluginInsights', 'optin' )
154 ) {
155 \NotificationX\Admin\PluginInsights::get_instance( NOTIFICATIONX_FILE )->optin( true );
156 }
157 return true;
158 }
159
160 /**
161 * Mark onboarding as completed (also used when skipped) so the wizard
162 * is not auto-launched again, and persist the collected choices.
163 *
164 * @param array $params
165 * @return bool
166 */
167 public function complete( $params = [] ) {
168 if ( ! current_user_can( 'read_notificationx' ) ) {
169 return false;
170 }
171
172 $goals = [];
173 if ( ! empty( $params['goals'] ) ) {
174 $goals = array_filter( array_map( 'sanitize_key', explode( ',', $params['goals'] ) ) );
175 }
176
177 $data = [
178 'business_type' => isset( $params['business_type'] ) ? sanitize_key( $params['business_type'] ) : '',
179 'goals' => array_values( $goals ),
180 'completed_at' => current_time( 'mysql' ),
181 ];
182 update_option( 'nx_onboarding_data', $data );
183
184 return update_option( self::COMPLETED_OPTION, true );
185 }
186
187 /**
188 * Whether onboarding has already been completed/skipped.
189 *
190 * @return bool
191 */
192 public static function is_completed() {
193 return (bool) get_option( self::COMPLETED_OPTION, false );
194 }
195
196 /**
197 * Expose onboarding status to the admin React app.
198 *
199 * @param array $data
200 * @return array
201 */
202 public function add_status_to_context( $data ) {
203 $data['onboarding_completed'] = self::is_completed();
204 return $data;
205 }
206 }
207