exists() && 'bricks' === get_template()) { require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'bricks/bricks.php'; } /** * Currently plugin version. * Start at version 1.0.0 and use SemVer - https://semver.org * Rename this for your plugin and update it as you release new versions. */ define( 'WPVR_WEBHOOK_URL', sanitize_url( 'https://rextheme.com/?mailmint=1&route=webhook&topic=contact&hash=bbd19901-6d42-4ae5-a7a8-01eb1013c553' ) ); if ( ! defined( 'WPVR_TELEMETRY_API_KEY' ) ) { define( 'WPVR_TELEMETRY_API_KEY', 'phc_amk3VQz1P5ZqZOMRRoWM1B41QMFpf3hu8pg7yRfzSXW' ); } if ( ! defined( 'WPVR_TELEMETRY_API_SECRET' ) ) { define( 'WPVR_TELEMETRY_API_SECRET', 'sec_dfb2ab8e84391ae7a0f9' ); } if ( ! defined( 'WPVR_TELEMETRY_HOST' ) ) { define( 'WPVR_TELEMETRY_HOST', 'https://eu.i.posthog.com' ); } if ( ! function_exists( 'activate_wpvr' ) ) { /** * The code that runs during plugin activation. * This action is documented in includes/class-wpvr-activator.php */ function activate_wpvr() { require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'includes/class-wpvr-activator.php'; Wpvr_Activator::activate(); // Trigger plugin activation tracking do_action( 'wpvr_plugin_activated' ); } } if ( ! function_exists( 'deactivate_wpvr' ) ) { /** * The code that runs during plugin deactivation. * This action is documented in includes/class-wpvr-deactivator.php */ function deactivate_wpvr() { require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'includes/class-wpvr-deactivator.php'; Wpvr_Deactivator::deactivate(); // Trigger plugin deactivation tracking do_action( 'wpvr_plugin_deactivated' ); } } register_activation_hook( WPVR_FILE, 'activate_wpvr' ); register_deactivation_hook( WPVR_FILE, 'deactivate_wpvr' ); /** * The core plugin class that is used to define internationalization, * admin-specific hooks, and public-facing site hooks. */ require WPVR_PLUGIN_LEGACY_DIR_PATH . 'includes/class-wpvr.php'; // Include banner classes require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'admin/classes/class-wpvr-occasion-banner.php'; require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'admin/classes/class-wpvr-sells-notification-bar.php'; require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'admin/classes/class-wpvr-first-tour-banner.php'; require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'admin/classes/class-wpvr-onboarding-notice.php'; require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'admin/classes/class-wpvr-new-user-tour.php'; if ( defined( 'WPB_VC_VERSION' ) ) { require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'builders/wpbakery/wpvr-loader.php'; if ( class_exists( 'Vc_Manager' ) ) { require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'builders/wpbakery/wpvr-element.php'; } } /** * Begins execution of the plugin. * * Since everything within the plugin is registered via hooks, * then kicking off the plugin from this point in the file does * not affect the page life cycle. * * @since 7.3.6 */ function run_wpvr() { $plugin = new Wpvr(); $plugin->run(); // new Tracker(); // black friday banner class initialization // new WPVR_Special_Occasion_Banner( // 'halloween_deal_2025', // '2025-10-01 00:00:01', // '2025-11-05 23:59:59' // ); if (!defined('WPVR_PRO_VERSION') && 'no' === get_option('wpvr_sell_eid_ul_fitr_2026_notification_bar', 'no')) { new WPVR_Notification_Bar( 'Eid_Ul_Fitr_2026', '2026-03-16 00:00:00', '2026-03-24 23:59:59' ); } // Initialize first tour banner new WPVR_First_Tour_Banner(); // Initialize listing-page onboarding notice ("Remind me later" flow) new WPVR_Onboarding_Notice(); // Auto-launch guided tour for truly-new users on the Add New Tour page. new WPVR_New_User_Tour(); // Pro preview banner (shown via JS when free user toggles Advanced Controls) if (!defined('WPVR_PRO_VERSION')) { add_action('admin_notices', 'wpvr_render_pro_preview_banner', 11); } } run_wpvr(); /** * Render Pro preview banner as admin notice. * Hidden by default; shown via JS when free user toggles Advanced Controls. * * @since 8.5.44 */ function wpvr_render_pro_preview_banner() { $screen = get_current_screen(); if (!$screen || $screen->id !== 'wpvr_item') { return; } ?>
'off', 'panDownSwitch' => 'off', 'panLeftSwitch' => 'off', 'panRightSwitch' => 'off', 'panZoomInSwitch' => 'off', 'panZoomOutSwitch' => 'off', 'panFullscreenSwitch' => 'off', 'gyroscopeSwitch' => 'off', 'backToHomeSwitch' => 'off', ) ); $gyro_enabled = isset( $postdata['gyro'] ) && in_array( $postdata['gyro'], array( true, 1, '1', 'on' ), true ); $gyro_button_enabled = function_exists( 'wpvr_isMobileDevice' ) && wpvr_isMobileDevice() && $gyro_enabled && 'on' === $custom_control['gyroscopeSwitch']; $custom_navigation_enabled = $gyro_button_enabled; foreach ( array( 'panupSwitch', 'panDownSwitch', 'panLeftSwitch', 'panRightSwitch', 'panZoomInSwitch', 'panZoomOutSwitch', 'panFullscreenSwitch', 'backToHomeSwitch', ) as $switch ) { if ( 'on' === $custom_control[ $switch ] ) { $custom_navigation_enabled = true; break; } } if ( $custom_navigation_enabled ) { return $html; } $pano_id = 'pano' . absint( $id ); $sprites_url = esc_url( WPVR_PLUGIN_PUBLIC_DIR_URL . 'lib/pannellum/src/css/img/sprites.svg' ); $html .= ''; return $html; } } add_filter( 'wpvr_generate_tour_layout_html', 'wpvr_restore_modern_layout_default_controls', 20, 3 ); if ( ! function_exists( 'wpvr_render_scene_info_row' ) ) { /** * Keep scene title and author metadata aligned for every tour layout. * * WP VR Pro can replace the Pannellum asset registered by the Free plugin and * adds Modern layout CSS at priority 10. This late, tour-scoped layer keeps * both Pannellum copies and both layouts consistent without modifying Pro. * * @param string $html Generated tour HTML. * @param array $postdata Saved tour settings. * @param int $id Tour post ID. * * @return string * @since 9.0.0 */ function wpvr_render_scene_info_row( $html, $postdata, $id ) { if ( preg_match( '/id=[\'"](pano' . absint( $id ) . '(?:_\d+)?)[\'"]/', $html, $m ) ) { $pano_id = $m[1]; } else { $pano_id = 'pano' . absint( $id ); } $pano_id_json = wp_json_encode( $pano_id ); $by_label = wp_json_encode( __( 'By', 'wpvr' ) ); $tour_layout = is_array( $postdata['tourLayout'] ?? null ) ? ( $postdata['tourLayout']['layout'] ?? 'default' ) : ( $postdata['tourLayout'] ?? 'default' ); $is_classic_layout = wp_json_encode( 'layout1' !== $tour_layout ); $html .= ' '; return $html; } } add_filter( 'wpvr_generate_tour_layout_html', 'wpvr_render_scene_info_row', 30, 3 ); if ( ! function_exists( 'wpvr_render_explainer_button' ) ) { /** * Render the WPVR explainer button independently. * * @param array|null $custom_control * @param array $postdata * @param bool $is_pro * @param bool $autoload * @param string $explainer_right * @param int|string $id * * @return string * @since 8.5.63 */ function wpvr_render_explainer_button( $custom_control, $postdata, $is_pro, $autoload, $explainer_right, $id ) { $html = ''; $explainer_enabled = isset( $postdata['explainerSwitch'] ) && in_array( $postdata['explainerSwitch'], array( true, 1, '1', 'on' ), true ); $explainer_icon = 'fa fa-video'; $explainer_color = '#f7fffb'; if ( isset( $custom_control ) ) { $explainer_icon = isset( $custom_control['explainerIcon'] ) ? $custom_control['explainerIcon'] : $explainer_icon; $explainer_color = isset( $custom_control['explainerColor'] ) ? $custom_control['explainerColor'] : $explainer_color; } elseif ( isset( $postdata['customcontrol'] ) ) { $raw_control = wpvr_parse_custom_control( $postdata['customcontrol'] ); $explainer_icon = isset( $raw_control['explainerIcon'] ) ? $raw_control['explainerIcon'] : $explainer_icon; $explainer_color = isset( $raw_control['explainerColor'] ) ? $raw_control['explainerColor'] : $explainer_color; } $pro_license_status = get_option( 'wpvr_edd_license_status' ); if ( $explainer_enabled && $pro_license_status === 'valid' && $is_pro ) { $explainer_style = empty( $postdata['explainerContent'] ) ? 'pointer-events: none; opacity: 0.5;' : ''; // Initial display:none to prevent flash for non-autoload tours. $initial_display = ! $autoload ? 'display:none; ' : ''; $html .= ''; } return $html; } } // Linno telemetry integration function wpvr_block() { wp_register_script( 'wpvr-block', plugins_url('build/index.build.js', __FILE__), array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor') ); if (is_admin()) { wp_enqueue_style( 'gutyblocks/guty-block', plugins_url('src/view.css', __FILE__), array() ); } if (function_exists('register_block_type')) { register_block_type('wpvr/wpvr-block', array( 'attributes' => array( 'id' => array( 'type' => 'string', 'default' => '0', ), 'width' => array( 'type' => 'string', 'default' => '600', ), 'width_unit' => array( 'type' => 'string', 'default' => 'px', ), 'height' => array( 'type' => 'string', 'default' => '400', ), 'height_unit' => array( 'type' => 'string', 'default' => 'px', ), 'mobile_height' => array( 'type' => 'string', 'default' => '300', ), 'mobile_height_unit' => array( 'type' => 'string', 'default' => 'px', ), 'radius' => array( 'type' => 'string', 'default' => '0', ), 'radius_unit' => array( 'type' => 'string', 'default' => 'px', ), 'border_width' => array( 'type' => 'string', 'default' => '0', ), 'border_style' => array( 'type' => 'string', 'default' => 'none', ), 'border_color' => array( 'type' => 'string', 'default' => '', ), ), 'editor_script' => 'wpvr-block', 'render_callback' => 'wpvr_block_render', )); } } add_action('init', 'wpvr_block'); function wpvr_block_render($attributes) { $id = isset($attributes['id']) ? (int) $attributes['id'] : 0; if (!$id) { return '