is_wizard_page() ) { $classes .= ' nx-setup-wizard-active'; } return $classes; } /** * Whether the current admin request is the wizard page. * * @return bool */ protected function is_wizard_page() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return is_admin() && isset( $_GET['page'] ) && self::PAGE === sanitize_key( wp_unslash( $_GET['page'] ) ); } /** * Handle the `complete_setup_wizard` miscellaneous REST action. * * Returning a non-null value makes the /miscellaneous endpoint respond * with `{ success: true }`. * * @param mixed $result * @param array $params * @return mixed */ public function handle_actions( $result, $params ) { if ( isset( $params['action'] ) ) { if ( 'complete_setup_wizard' === $params['action'] ) { return $this->complete( $params ); } if ( 'setup_wizard_optin' === $params['action'] ) { return $this->optin_tracking(); } } return $result; } /** * Record the user's opt-in to WP Insights usage tracking and send the data * to the insights API immediately. Triggered when the user proceeds past * the Welcome step — the in-card notice states that proceeding consents to * collecting the admin email to personalise the setup. * * The wizard no longer decides *whether* data is collected: collection is * enabled from the backend on activation regardless of this flow (see * {@see \NotificationX\Admin\PluginInsights::is_tracking_allowed()}). * This only stores the explicit consent state and sends immediately. * * @return bool */ public function optin_tracking() { if ( ! current_user_can( 'read_notificationx' ) ) { return false; } if ( class_exists( '\NotificationX\Admin\PluginInsights' ) && method_exists( '\NotificationX\Admin\PluginInsights', 'optin' ) ) { \NotificationX\Admin\PluginInsights::get_instance( NOTIFICATIONX_FILE )->optin( true ); } return true; } /** * Mark onboarding as completed (also used when skipped) so the wizard * is not auto-launched again, and persist the collected choices. * * @param array $params * @return bool */ public function complete( $params = [] ) { if ( ! current_user_can( 'read_notificationx' ) ) { return false; } $goals = []; if ( ! empty( $params['goals'] ) ) { $goals = array_filter( array_map( 'sanitize_key', explode( ',', $params['goals'] ) ) ); } $data = [ 'business_type' => isset( $params['business_type'] ) ? sanitize_key( $params['business_type'] ) : '', 'goals' => array_values( $goals ), 'completed_at' => current_time( 'mysql' ), ]; update_option( 'nx_onboarding_data', $data ); return update_option( self::COMPLETED_OPTION, true ); } /** * Whether onboarding has already been completed/skipped. * * @return bool */ public static function is_completed() { return (bool) get_option( self::COMPLETED_OPTION, false ); } /** * Expose onboarding status to the admin React app. * * @param array $data * @return array */ public function add_status_to_context( $data ) { $data['onboarding_completed'] = self::is_completed(); return $data; } }