exists() && 'bricks' === get_template()) {
require_once plugin_dir_path(__FILE__) . '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_VERSION', '8.5.72');
define('WPVR_FILE', __FILE__);
define("WPVR_PLUGIN_DIR_URL", plugin_dir_url(__FILE__));
define("WPVR_PLUGIN_DIR_PATH", plugin_dir_path(__FILE__));
define("WPVR_PLUGIN_PUBLIC_DIR_URL", plugin_dir_url(__FILE__) . 'public/');
define('WPVR_BASE', plugin_basename(WPVR_FILE));
define('WPVR_DEV_MODE', false);
define('WPVR_JS_PATH', plugin_dir_url(__FILE__) . 'admin/js/');
define('WPVR_CSS_PATH', plugin_dir_url(__FILE__) . 'admin/css/');
define('WPVR_ASSET_PATH', plugin_dir_url(__FILE__) . 'admin/');
define( 'WPVR_WEBHOOK_URL', sanitize_url( 'https://rextheme.com/?mailmint=1&route=webhook&topic=contact&hash=bbd19901-6d42-4ae5-a7a8-01eb1013c553' ) );
define('WPVR_TELEMETRY_API_KEY', 'phc_amk3VQz1P5ZqZOMRRoWM1B41QMFpf3hu8pg7yRfzSXW');
define('WPVR_TELEMETRY_API_SECRET', 'sec_dfb2ab8e84391ae7a0f9');
define('WPVR_TELEMETRY_HOST', 'https://eu.i.posthog.com');
/**
* The code that runs during plugin activation.
* This action is documented in includes/class-wpvr-activator.php
*/
function activate_wpvr()
{
require_once plugin_dir_path(__FILE__) . 'includes/class-wpvr-activator.php';
Wpvr_Activator::activate();
// Trigger plugin activation tracking
do_action( 'wpvr_plugin_activated' );
}
/**
* The code that runs during plugin deactivation.
* This action is documented in includes/class-wpvr-deactivator.php
*/
function deactivate_wpvr()
{
require_once plugin_dir_path(__FILE__) . 'includes/class-wpvr-deactivator.php';
Wpvr_Deactivator::deactivate();
// Trigger plugin deactivation tracking
do_action( 'wpvr_plugin_deactivated' );
}
register_activation_hook(__FILE__, 'activate_wpvr');
register_deactivation_hook(__FILE__, 'deactivate_wpvr');
/**
* The core plugin class that is used to define internationalization,
* admin-specific hooks, and public-facing site hooks.
*/
require plugin_dir_path(__FILE__) . 'includes/class-wpvr.php';
// Include banner classes
require_once plugin_dir_path(__FILE__) . 'admin/classes/class-wpvr-occasion-banner.php';
require_once plugin_dir_path(__FILE__) . 'admin/classes/class-wpvr-sells-notification-bar.php';
require_once plugin_dir_path(__FILE__) . 'admin/classes/class-wpvr-first-tour-banner.php';
require_once plugin_dir_path(__FILE__) . 'admin/classes/class-wpvr-onboarding-notice.php';
require_once plugin_dir_path(__FILE__) . 'admin/classes/class-wpvr-new-user-tour.php';
// Include telemetry class
require_once plugin_dir_path(__FILE__) . 'includes/class-wpvr-linno-telemetry.php';
if ( defined( 'WPB_VC_VERSION' ) ) {
require_once plugin_dir_path( __FILE__ ) . 'builders/wpbakery/wpvr-loader.php';
if ( class_exists( 'Vc_Manager' ) ) {
require_once plugin_dir_path( __FILE__ ) . '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;
}
?>
';
$html .= '
';
$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',
),
'border_width' => array(
'type' => 'string',
'default' => '0px',
),
'border_style' => array(
'type' => 'string',
'default' => 'none',
),
'border_color' => array(
'type' => 'string',
'default' => 'none',
),
'radius_unit' => array(
'type' => 'string',
'default' => 'px',
),
'content' => array(
'type' => 'string',
'source' => 'html',
'default' => ''
),
),
'editor_script' => 'wpvr-block',
'render_callback' => 'wpvr_block_render',
));
}
}
add_action('init', 'wpvr_block');
/**
* Enqueue frontend scripts for a given tour type from a render callback.
* Called during the_content — footer scripts still fire after, so $in_footer=true works.
* CSS is loaded globally by enqueue_styles(); only JS is gated here.
*
* @param string $tour_type 'scene' | 'video' | 'streetview'
*/
function wpvr_enqueue_frontend_scripts( $tour_type ) {
static $localized = false;
$pub = WPVR_PLUGIN_PUBLIC_DIR_URL;
$ver = WPVR_VERSION;
if ( 'video' === $tour_type ) {
wp_enqueue_script( 'videojs-js', $pub . 'js/video.js', array(), $ver, true );
wp_enqueue_script( 'videojsvr-js', $pub . 'lib/videojs-vr/videojs-vr.js', array( 'videojs-js' ), $ver, true );
wp_enqueue_script( 'panellium-js', $pub . 'lib/pannellum/src/js/pannellum.js', array(), $ver, true );
wp_enqueue_script( 'panelliumlib-js', $pub . 'lib/pannellum/src/js/libpannellum.js', array( 'panellium-js' ), $ver, true );
wp_enqueue_script( 'panelliumvid-js', $pub . 'lib/pannellum/src/js/videojs-pannellum-plugin.js', array( 'videojs-js', 'videojsvr-js', 'panellium-js', 'panelliumlib-js' ), $ver, true );
} elseif ( 'scene' === $tour_type ) {
wp_enqueue_script( 'panellium-js', $pub . 'lib/pannellum/src/js/pannellum.js', array(), $ver, true );
wp_enqueue_script( 'panelliumlib-js', $pub . 'lib/pannellum/src/js/libpannellum.js', array( 'panellium-js' ), $ver, true );
wp_enqueue_script( 'owl-js', $pub . 'js/owl.carousel.js', array( 'jquery' ), $ver, true );
}
// 'streetview' is an iframe only — no extra scripts needed
wp_enqueue_script( 'jquery_cookie', $pub . 'js/jquery.cookie.js', array( 'jquery' ), $ver, true );
wp_enqueue_script( 'wpvr', $pub . 'js/wpvr-public.js', array( 'jquery', 'jquery_cookie' ), $ver, true );
if ( ! $localized ) {
$localized = true;
$wpvr_frontend_notice = get_option( 'wpvr_frontend_notice' );
wp_localize_script( 'wpvr', 'wpvr_public', array(
'notice_active' => $wpvr_frontend_notice,
'notice' => $wpvr_frontend_notice ? sanitize_text_field( get_option( 'wpvr_frontend_notice_area' ) ) : '',
'is_pro_active' => is_plugin_active( 'wpvr-pro/wpvr-pro.php' ),
'is_license_active' => get_option( 'wpvr_edd_license_status' ) === 'valid',
'dis_on_hover' => get_option( 'dis_on_hover' ) === 'true',
'mobile_hotspot_tip' => get_option( 'wpvr_mobile_hotspot_tip' ) === 'true',
) );
}
do_action( 'wpvr_enqueue_frontend_scripts', $tour_type );
}
function wpvr_block_render($attributes)
{
if (isset($attributes['id'])) {
$id = $attributes['id'];
} else {
$id = 0;
}
do_action('rex_wpvr_embadded_tour', $id);
$memberpress_active = defined('MEPR_VERSION');
$rcp_active = is_plugin_active( 'restrict-content-pro/restrict-content-pro.php' );
if (($memberpress_active || $rcp_active ) && apply_filters('is_wpvr_pro_active', false)) {
if (!is_user_logged_in()) {
return esc_html__('You need to log in to access this content.', 'wpvr');
}
$user_id = get_current_user_id();
$allowed_access = false;
// Get saved membership levels from post meta
$allowed_membership_levels = get_post_meta($id, '_wpvr_allowed_roles_levels', true);
if ( isset($allowed_membership_levels) && 'none' !== $allowed_membership_levels ) {
if (!is_array($allowed_membership_levels)) {
$allowed_membership_levels = array($allowed_membership_levels);
}
// Check MemberPress Access
if ($memberpress_active) {
$user = new MeprUser($user_id);
$active_memberships = $user->active_product_subscriptions();
if (array_intersect($allowed_membership_levels, $active_memberships) ) {
$allowed_access = true;
}
}
// Check Restrict Content Pro Access
if ($rcp_active) {
$user_rcp_memberships = rcp_get_customer_memberships($user_id);
foreach ($user_rcp_memberships as $membership) {
$rcp_access_level = array(
$membership->get_object_id()
);
if (array_intersect($allowed_membership_levels, $rcp_access_level) ) {
$allowed_access = true;
break;
}
}
}
} else {
// If no membership restriction is set, allow access by default
$allowed_access = true;
}
if (!$allowed_access) {
return esc_html__('You do not have access to this content.', 'wpvr');
}
}
if (isset($attributes['width'])) {
$width = $attributes['width'];
}
if (isset($attributes['width_unit'])) {
$width_unit = $attributes['width_unit'];
}
if (isset($attributes['height'])) {
$height = $attributes['height'];
}
if (isset($attributes['height_unit'])) {
$height_unit = $attributes['height_unit'];
}
if (isset($attributes['mobile_height'])) {
$mobile_height = $attributes['mobile_height'];
}
if (isset($attributes['mobile_height_unit'])) {
$mobile_height_unit = $attributes['mobile_height_unit'];
}
if (isset($attributes['radius']) && isset($attributes['radius_unit'])) {
$radius = $attributes['radius'] . $attributes['radius_unit'];
}
$border_style = '';
if (isset($attributes['border_width'], $attributes['border_style'], $attributes['border_color'])) {
$border_style = $attributes['border_width'] . 'px ' . $attributes['border_style'] . ' ' . $attributes['border_color'];
}
if (isset($attributes['className'])) {
$className = $attributes['className'];
} else {
$className = '';
}
$get_post = get_post_status($id);
if ($get_post !== 'publish') {
return esc_html__('Oops! It seems like this post isn\'t published yet. Stay tuned for updates!', 'wpvr');
}
if (post_password_required($id)) {
return get_the_password_form();
}
$postdata = get_post_meta($id, 'panodata', true);
$panoid = 'pano' . $id;
$panoid2 = 'pano2' . $id;
if (!isset($postdata) || empty($postdata)) {
return wp_kses(
__('Oops! It seems that you have not selected any tour yet. Please select a tour from the dropdown of WPVR block. ', 'wpvr'),
['br' => []]
);
}
if (isset($postdata['streetviewdata'])) {
if (empty($width)) {
$width = '600px';
}
if (empty($height)) {
$height = '400px';
}
$streetviewurl = $postdata['streetviewurl'];
$html = '';
$html .= '
';
}
//===Scene navigation Control===//
/**
* Generic Form Handler
* Renders a generic form with modal functionality if enabled in post data
*
* @param array $postdata Array containing form configuration data
* @param string $id Unique identifier for the form instance
* @return string $html Generated HTML content
*/
// Check if generic form is enabled and validate the setting
if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on' && 'valid' == $status && $is_pro) {
// Process shortcode with fallback handling
$shortcode_content = '';
if (isset($postdata["genericformshortcode"]) && !empty(trim($postdata["genericformshortcode"]))) {
$shortcode_content = do_shortcode( $postdata["genericformshortcode"] );
} else {
$shortcode_content = '
No shortcode found.
';
}
// Generate the form trigger button
$html .= '
';
$html .= '
';
$html .= '
';
// Generate the modal form container
$html .= '
';
// Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on"
if ($floor_plan_direction_indicator === "on") {
$html .= '';
}
$html .= '