id ) { return false; } // 3. Must be a NEW post (no post ID = creating, not editing). // When editing an existing tour, $_GET['post'] is set. if ( isset( $_GET['post'] ) && absint( wp_unslash($_GET['post']) ) > 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return false; } // 4. Admins only. if ( ! current_user_can( 'manage_options' ) ) { return false; } // 5. If a real tour was ever created on this site → existing user, skip. if ( get_option( WPVR_Onboarding_Notice::OPT_HAS_EVER_CREATED ) ) { return false; } // 6. If the setup wizard was completed → skip (they already built a tour). if ( get_option( WPVR_Onboarding_Notice::OPT_WIZARD_DONE ) ) { return false; } // 7. If the guided tour was already dismissed / completed → skip. if ( get_option( self::OPT_DISMISSED ) ) { return false; } return true; } /* ----------------------------------------------------------------------- * Asset enqueueing * --------------------------------------------------------------------- */ /** * Enqueue Shepherd assets and localize the auto-start flag when needed. */ public function maybe_enqueue() { if ( ! $this->should_launch() ) { return; } $plugin_url = WPVR_ASSET_PATH; // already defined as plugin_url . 'admin/' // --- CSS --- wp_enqueue_style( 'wpvr-shepherd-css', $plugin_url . 'lib/shepherd/css/shepherd-theme-arrows-plain-buttons.css', array(), WPVR_VERSION ); wp_enqueue_style( 'wpvr-tour-guide-css', $plugin_url . 'lib/shepherd/css/wpvr-tour-guide.min.css', array(), WPVR_VERSION ); // --- JS --- wp_enqueue_script( 'wpvr-tether-js', $plugin_url . 'lib/shepherd/tether/tether.js', array(), WPVR_VERSION, true ); wp_enqueue_script( 'wpvr-shepherd-js', $plugin_url . 'lib/shepherd/tether-shepherd/shepherd.js', array( 'wpvr-tether-js' ), WPVR_VERSION, true ); wp_enqueue_script( 'wpvr-tour-guide', $plugin_url . 'js/wpvr-tour-guide.js', array( 'jquery', 'wpvr-tether-js', 'wpvr-shepherd-js' ), WPVR_VERSION, true ); // Translations already used by the tour guide script. $tour_guide_translation = new WPVR_Tour_Guide_Translation(); wp_localize_script( 'wpvr-tour-guide', 'wpvr_tour_guide_obj', array( 'Tour_Guide_Translation' => $tour_guide_translation->get_translatable_string(), 'step1_bg_image' => plugins_url( 'admin/icon/first-step-bg.png', WPVR_FILE ), 'next_button_arrow' => plugins_url( 'admin/icon/next-button-arrow.png', WPVR_FILE ), ) ); // Auto-start config + dismiss endpoint. wp_localize_script( 'wpvr-tour-guide', 'wpvr_new_user_tour', array( 'autoStart' => true, 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( self::AJAX_DISMISS ), 'action' => self::AJAX_DISMISS, ) ); } /* ----------------------------------------------------------------------- * AJAX handler * --------------------------------------------------------------------- */ /** * Permanently dismiss the guided tour so it never auto-fires again. */ public function handle_dismiss() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); return; } $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, self::AJAX_DISMISS ) ) { wp_send_json_error( array( 'message' => 'Invalid nonce' ), 400 ); return; } update_option( self::OPT_DISMISSED, '1', false ); wp_send_json_success( array( 'message' => 'Tour dismissed' ) ); } }