PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.2
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.2
9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 8.5.4 All 221 releases
← All changes | wpvr.php +468 -3318 8.5.389.1.2 View file →
@@ -1,6 +1,8 @@
1 1 <?php
2 2
3 +use RexTheme\WPVR\Tracker\WPVRLinnoTelemetry;
4 +
3 5 /**
4 6 * The plugin bootstrap file
5 7 *
6 8 * This file is read by WordPress to generate the plugin information in the plugin
@@ -12,13 +14,13 @@
12 14 * @since 7.3.6
13 15 * @package Wpvr
14 16 *
15 17 * @wordpress-plugin
16 - * Plugin Name: WP VR
18 + * Plugin Name: WP VR - 360 Panorama and Virtual Tour Builder
17 19 * Plugin URI: https://rextheme.com/wpvr/
18 - * Description: WP VR - 360 Panorama and virtual tour creator for WordPress is a customized panaroma & virtual builder tool for WordPress Website.
19 - * Version: 8.5.38
20 - * Tested up to: 6.8.2
20 + * Description: WP VR - 360 Panorama and virtual tour creator is a customized panaroma & virtual builder tool for your website.
21 + * Version: 9.1.2
22 + * Tested up to: 7.1
21 23 * Author: Rextheme
22 24 * Author URI: http://rextheme.com/
23 25 * License: GPL-2.0+
24 26 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
@@ -30,3486 +32,634 @@
30 32 if (!defined('WPINC')) {
31 33 die;
32 34 }
33 35
34 -require plugin_dir_path(__FILE__) . 'elementor/elementor.php';
35 -
36 -if ( wp_get_theme('bricks')->exists() && 'bricks' === get_template()) {
37 - require_once plugin_dir_path(__FILE__) . 'bricks/bricks.php';
38 -}
39 -
40 -/**
41 - * Currently plugin version.
42 - * Start at version 1.0.0 and use SemVer - https://semver.org
43 - * Rename this for your plugin and update it as you release new versions.
44 - */
45 -define('WPVR_VERSION', '8.5.38');
36 +define('WPVR_VERSION', '9.1.2');
46 37 define('WPVR_FILE', __FILE__);
47 -define("WPVR_PLUGIN_DIR_URL", plugin_dir_url(__FILE__));
48 -define("WPVR_PLUGIN_DIR_PATH", plugin_dir_path(__FILE__));
49 -define("WPVR_PLUGIN_PUBLIC_DIR_URL", plugin_dir_url(__FILE__) . 'public/');
38 +define("WPVR_PLUGIN_DIR_URL", plugin_dir_url(__FILE__).'legacy/');
39 +define("WPVR_PLUGIN_DIR_PATH", plugin_dir_path(__FILE__).'legacy/');
40 +define("WPVR_PLUGIN_LEGACY_DIR_PATH", plugin_dir_path(__FILE__) . 'legacy/');
41 +define("WPVR_PLUGIN_PUBLIC_DIR_URL", plugin_dir_url(__FILE__) . 'legacy/public/');
50 42 define('WPVR_BASE', plugin_basename(WPVR_FILE));
51 43 define('WPVR_DEV_MODE', false);
52 -define('WPVR_JS_PATH', plugin_dir_url(__FILE__) . 'admin/js/');
53 -define('WPVR_ASSET_PATH', plugin_dir_url(__FILE__) . 'admin/');
54 -define( 'WPVR_WEBHOOK_URL', sanitize_url( 'https://rextheme.com/?mailmint=1&route=webhook&topic=contact&hash=bbd19901-6d42-4ae5-a7a8-01eb1013c553' ) );
44 +define('WPVR_JS_PATH', plugin_dir_url(__FILE__) . 'legacy/admin/js/');
45 +define('WPVR_CSS_PATH', plugin_dir_url(__FILE__) . 'legacy/admin/css/');
46 +define('WPVR_ASSET_PATH', plugin_dir_url(__FILE__) . 'legacy/admin/');
55 47
56 -/**
57 - * The code that runs during plugin activation.
58 - * This action is documented in includes/class-wpvr-activator.php
59 - */
60 -function activate_wpvr()
61 -{
62 - require_once plugin_dir_path(__FILE__) . 'includes/class-wpvr-activator.php';
63 - Wpvr_Activator::activate();
48 +$wpvr_composer_autoload = plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
49 +if ( file_exists( $wpvr_composer_autoload ) ) {
50 + require_once $wpvr_composer_autoload;
51 +}
64 52
65 - // Trigger plugin activation tracking
66 - do_action( 'wpvr_plugin_activated' );
53 +if ( ! defined( 'WPVR_TELEMETRY_API_KEY' ) ) {
54 + define( 'WPVR_TELEMETRY_API_KEY', 'phc_amk3VQz1P5ZqZOMRRoWM1B41QMFpf3hu8pg7yRfzSXW' );
67 55 }
68 -
69 -/**
70 - * The code that runs during plugin deactivation.
71 - * This action is documented in includes/class-wpvr-deactivator.php
72 - */
73 -function deactivate_wpvr()
74 -{
75 - require_once plugin_dir_path(__FILE__) . 'includes/class-wpvr-deactivator.php';
76 - Wpvr_Deactivator::deactivate();
56 +if ( ! defined( 'WPVR_TELEMETRY_API_SECRET' ) ) {
57 + define( 'WPVR_TELEMETRY_API_SECRET', 'sec_dfb2ab8e84391ae7a0f9' );
77 58 }
78 -
79 -register_activation_hook(__FILE__, 'activate_wpvr');
80 -register_deactivation_hook(__FILE__, 'deactivate_wpvr');
81 -
82 -/**
83 - * The core plugin class that is used to define internationalization,
84 - * admin-specific hooks, and public-facing site hooks.
85 - */
86 -require plugin_dir_path(__FILE__) . 'includes/class-wpvr.php';
87 -use Wpvr\Admin\Tracking\Tracker;
88 -
89 -/**
90 - * Begins execution of the plugin.
91 - *
92 - * Since everything within the plugin is registered via hooks,
93 - * then kicking off the plugin from this point in the file does
94 - * not affect the page life cycle.
95 - *
96 - * @since 7.3.6
97 - */
98 -function run_wpvr()
99 -{
100 -
101 - $plugin = new Wpvr();
102 - $plugin->run();
103 -// new Tracker();
104 -
105 - // black friday banner class initialization
106 - new WPVR_Special_Occasion_Banner(
107 - '4th_of_july_deal_2025',
108 - '2025-07-02 00:00:01',
109 - '2025-07-14 23:59:59'
110 - );
111 -
112 - // if (!defined('WPVR_PRO_VERSION') && 'no' === get_option('wpvr_sell_notification_bar', 'no')) {
113 - // new WPVR_Notification_Bar();
114 - // }
115 -
116 -
59 +if ( ! defined( 'WPVR_TELEMETRY_HOST' ) ) {
60 + define( 'WPVR_TELEMETRY_HOST', 'https://eu.i.posthog.com' );
117 61 }
118 -run_wpvr();
119 62
63 +if ( ! function_exists( 'activate_wpvr' ) ) {
64 + /**
65 + * The code that runs during plugin activation.
66 + */
67 + function activate_wpvr() {
68 + require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'includes/class-wpvr-activator.php';
69 + Wpvr_Activator::activate();
120 70
121 -/**
122 - * Array information checker
123 - *
124 - * @param mixed $needle
125 - * @param mixed $haystack
126 - * @param bool $strict
127 - *
128 - * @return bool
129 - * @since 7.3.6
130 - */
131 -function wpvr_in_array_r($needle, $haystack, $strict = false)
132 -{
133 - foreach ($haystack as $item) {
134 - if ((($strict ? $item === $needle : $item == $needle)) || is_array($item) && wpvr_in_array_r($needle, $item, $strict)) {
135 - return true;
136 - }
71 + // Trigger plugin activation tracking
72 + do_action( 'wpvr_plugin_activated' );
137 73 }
138 - return false;
139 74 }
140 75
76 +if ( ! function_exists( 'deactivate_wpvr' ) ) {
77 + /**
78 + * The code that runs during plugin deactivation.
79 + */
80 + function deactivate_wpvr() {
81 + require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'includes/class-wpvr-deactivator.php';
82 + Wpvr_Deactivator::deactivate();
141 83
142 -/**
143 - * Initialize the plugin tracker
144 - *
145 - * @return void
146 - * @since 7.3.6
147 - */
148 -function appsero_init_tracker_wpvr()
149 -{
150 - if (!class_exists('Appsero\Client')) {
151 - require_once __DIR__ . '/appsero/src/Client.php';
84 + // Trigger plugin deactivation tracking
85 + do_action( 'wpvr_plugin_deactivated' );
152 86 }
153 - $client = new Appsero\Client('cab9761e-b067-4824-9c71-042df5d58598', 'WP VR', __FILE__);
154 -
155 - // Active insights
156 - $client->insights()->init();
157 87 }
158 88
159 -appsero_init_tracker_wpvr();
89 +register_activation_hook( WPVR_FILE, 'activate_wpvr' );
90 +register_deactivation_hook( WPVR_FILE, 'deactivate_wpvr' );
160 91
92 +if ( class_exists( WPVRLinnoTelemetry::class ) ) {
93 + new WPVRLinnoTelemetry();
94 +}
161 95
162 -function wpvr_block()
163 -{
164 - wp_register_script(
165 - 'wpvr-block',
166 - plugins_url('build/index.build.js', __FILE__),
167 - array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor')
168 - );
169 -
170 - if (is_admin()) {
171 - wp_enqueue_style(
172 - 'gutyblocks/guty-block',
173 - plugins_url('src/view.css', __FILE__),
174 - array()
175 - );
96 +if ( ! function_exists( 'wpvr_is_pro_active' ) ) {
97 + /**
98 + * Return the effective WP VR Pro entitlement state.
99 + *
100 + * A loaded Pro plugin alone is not enough; its license must also be valid.
101 + */
102 + function wpvr_is_pro_active(): bool {
103 + return defined( 'WPVR_PRO_VERSION' )
104 + && get_option( 'wpvr_edd_license_status' ) === 'valid'
105 + && (bool) apply_filters( 'is_wpvr_pro_active', false );
176 106 }
177 -
178 -
179 - if (function_exists('register_block_type')) {
180 - register_block_type('wpvr/wpvr-block', array(
181 - 'attributes' => array(
182 - 'id' => array(
183 - 'type' => 'string',
184 - 'default' => '0',
185 - ),
186 - 'width' => array(
187 - 'type' => 'string',
188 - 'default' => '600',
189 - ),
190 - 'width_unit' => array(
191 - 'type' => 'string',
192 - 'default' => 'px',
193 - ),
194 - 'height' => array(
195 - 'type' => 'string',
196 - 'default' => '400',
197 - ),
198 - 'height_unit' => array(
199 - 'type' => 'string',
200 - 'default' => 'px',
201 - ),
202 - 'mobile_height' => array(
203 - 'type' => 'string',
204 - 'default' => '300',
205 - ),
206 - 'mobile_height_unit' => array(
207 - 'type' => 'string',
208 - 'default' => 'px',
209 - ),
210 - 'radius' => array(
211 - 'type' => 'string',
212 - 'default' => '0',
213 - ),
214 - 'border_width' => array(
215 - 'type' => 'string',
216 - 'default' => '0px',
217 - ),
218 - 'border_style' => array(
219 - 'type' => 'string',
220 - 'default' => 'none',
221 - ),
222 - 'border_color' => array(
223 - 'type' => 'string',
224 - 'default' => 'none',
225 - ),
226 - 'radius_unit' => array(
227 - 'type' => 'string',
228 - 'default' => 'px',
229 - ),
230 - 'content' => array(
231 - 'type' => 'string',
232 - 'source' => 'html',
233 - 'default' => '<script> </script>'
234 - ),
235 - ),
236 - 'editor_script' => 'wpvr-block',
237 - 'render_callback' => 'wpvr_block_render',
238 - ));
239 - }
240 107 }
241 108
242 -add_action('init', 'wpvr_block');
243 -
244 -function wpvr_block_render($attributes)
245 -{
246 - if (isset($attributes['id'])) {
247 - $id = $attributes['id'];
248 - } else {
249 - $id = 0;
250 - }
251 -
252 - do_action('rex_wpvr_embadded_tour', $id, 'shortcode');
253 -
254 - $memberpress_active = defined('MEPR_VERSION');
255 - $rcp_active = is_plugin_active( 'restrict-content-pro/restrict-content-pro.php' );
256 -
257 - if (($memberpress_active || $rcp_active ) && apply_filters('is_wpvr_pro_active', false)) {
258 -
259 - if (!is_user_logged_in()) {
260 - return esc_html__('You need to log in to access this content.', 'wpvr');
109 +if ( ! function_exists( 'wpvr_get_effective_panodata' ) ) {
110 + /**
111 + * Build a runtime-only Free-plan view of saved tour data.
112 + *
113 + * The stored meta is never changed, so reactivating Pro restores every value.
114 + * Also normalizes values written by newer editor clients to the legacy
115 + * string format expected by the shared preview and shortcode renderers.
116 + */
117 + function wpvr_get_effective_panodata( array $postdata ): array {
118 + if ( isset( $postdata['scene_navigation'] ) ) {
119 + $postdata['scene_navigation'] = in_array( $postdata['scene_navigation'], [ true, 1, '1', 'on' ], true ) ? 'on' : 'off';
261 120 }
262 121
263 - $user_id = get_current_user_id();
264 - $allowed_access = false;
265 -
266 - // Get saved membership levels from post meta
267 - $allowed_membership_levels = get_post_meta($id, '_wpvr_allowed_roles_levels', true);
268 - if ( isset($allowed_membership_levels) && 'none' !== $allowed_membership_levels ) {
269 - if (!is_array($allowed_membership_levels)) {
270 - $allowed_membership_levels = array($allowed_membership_levels);
271 - }
272 -
273 - // Check MemberPress Access
274 - if ($memberpress_active) {
275 - $user = new MeprUser($user_id);
276 - $active_memberships = $user->active_product_subscriptions();
277 - if (array_intersect($allowed_membership_levels, $active_memberships) ) {
278 - $allowed_access = true;
279 - }
280 - }
281 -
282 - // Check Restrict Content Pro Access
283 - if ($rcp_active) {
284 - $user_rcp_memberships = rcp_get_customer_memberships($user_id);
285 - foreach ($user_rcp_memberships as $membership) {
286 - $rcp_access_level = array(
287 - $membership->get_object_id()
288 - );
289 - if (array_intersect($allowed_membership_levels, $rcp_access_level) ) {
290 - $allowed_access = true;
291 - break;
292 - }
293 - }
294 - }
295 - } else {
296 - // If no membership restriction is set, allow access by default
297 - $allowed_access = true;
122 + if ( isset( $postdata['autoLoad'] ) ) {
123 + $postdata['autoLoad'] = in_array( $postdata['autoLoad'], [ true, 1, '1', 'on', 'true' ], true );
298 124 }
299 125
300 - if (!$allowed_access) {
301 - return esc_html__('You do not have access to this content.', 'wpvr');
126 + if ( wpvr_is_pro_active() ) {
127 + return $postdata;
302 128 }
303 - }
304 129
305 -
306 - if (isset($attributes['width'])) {
307 - $width = $attributes['width'];
308 - }
309 - if (isset($attributes['width_unit'])) {
310 - $width_unit = $attributes['width_unit'];
311 - }
312 - if (isset($attributes['height'])) {
313 - $height = $attributes['height'];
314 - }
315 - if (isset($attributes['height_unit'])) {
316 - $height_unit = $attributes['height_unit'];
317 - }
318 - if (isset($attributes['mobile_height'])) {
319 - $mobile_height = $attributes['mobile_height'];
320 - }
321 - if (isset($attributes['mobile_height_unit'])) {
322 - $mobile_height_unit = $attributes['mobile_height_unit'];
323 - }
324 - if (isset($attributes['radius']) && isset($attributes['radius_unit'])) {
325 - $radius = $attributes['radius'] . $attributes['radius_unit'];
326 - }
327 - $border_style = '';
328 - if (isset($attributes['border_width'], $attributes['border_style'], $attributes['border_color'])) {
329 - $border_style = $attributes['border_width'] . 'px ' . $attributes['border_style'] . ' ' . $attributes['border_color'];
330 - }
331 -
332 - if (isset($attributes['className'])) {
333 - $className = $attributes['className'];
334 - } else {
335 - $className = '';
336 - }
337 - $get_post = get_post_status($id);
338 - if ($get_post !== 'publish') {
339 - return esc_html__('Oops! It seems like this post isn\'t published yet. Stay tuned for updates!', 'wpvr');
340 - }
341 - if (post_password_required($id)) {
342 - return get_the_password_form();
343 - }
344 - $postdata = get_post_meta($id, 'panodata', true);
345 - $panoid = 'pano' . $id;
346 - $panoid2 = 'pano2' . $id;
347 - if (!isset($postdata) || empty($postdata)) {
348 - return wp_kses(
349 - __('Oops! It seems that you have not selected any tour yet. Please select a tour from the dropdown of WPVR block.<br>', 'wpvr'),
350 - ['br' => []]
351 - );
352 - }
353 - if (isset($postdata['streetviewdata'])) {
354 - if (empty($width)) {
355 - $width = '600px';
130 + $false_keys = [
131 + 'gyro', 'deviceorientationcontrol', 'compass', 'vrgallery',
132 + 'vrgallery_title', 'vrgallery_icon_size', 'vrgallery_display',
133 + ];
134 + foreach ( $false_keys as $key ) {
135 + $postdata[ $key ] = false;
356 136 }
357 - if (empty($height)) {
358 - $height = '400px';
359 - }
360 - $streetviewurl = $postdata['streetviewurl'];
361 - $html = '';
362 - $html .= '<div class="vr-streetview ' . esc_attr( $className ) . '" style="text-align: center; max-width:100%; width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; height:' . esc_attr( $height ) . esc_attr( $height_unit ) . '; margin: 0 auto;">';
363 - $html .= '<iframe src="' . esc_url( $streetviewurl ) . '" frameborder="0" style="border:0; width:100px; height:100%;" allowfullscreen=""></iframe>';
364 - $html .= '</div>';
365 137
366 - return $html;
367 - }
368 - $is_pro = apply_filters('is_wpvr_pro_active', false);
369 -
370 - if (isset($postdata['vidid'])) {
371 - if (empty($width)) {
372 - $width = '600';
138 + $off_keys = [
139 + 'scene_navigation', 'sceneAnimation', 'bg_music',
140 + 'autoplay_bg_music', 'loop_bg_music', 'explainerSwitch',
141 + 'cpLogoSwitch', 'genericform', 'calltoaction', 'customcss_enable',
142 + 'floorplan-enabled', 'floorplan-compass',
143 + 'floor_plan_tour_enabler', 'floor_plan_direction_indicator',
144 + 'bg_tour_enabler', 'video-autoplay', 'video-loop',
145 + ];
146 + foreach ( $off_keys as $key ) {
147 + $postdata[ $key ] = 'off';
373 148 }
374 - if (empty($height)) {
375 - $height = '400';
376 - }
377 - $videourl = $postdata['vidurl'];
378 149
379 - $videourl = $postdata['vidurl'];
380 - $autoplay = 'off';
381 - if (isset($postdata['autoplay'])) {
382 - $autoplay = $postdata['autoplay'];
383 - }
384 - $loop = 'off';
385 - if (isset($postdata['loop'])) {
386 - $loop = $postdata['loop'];
387 - }
150 + $postdata['tourLayout'] = [
151 + 'layout' => 'default',
152 + 'layout_icon_bg_color' => '#5a536e',
153 + 'layout_icon_color' => '#ffffff',
154 + ];
155 + $postdata['draggable'] = true;
156 + $postdata['mouseZoom'] = true;
157 + $postdata['diskeyboard'] = false;
158 + $postdata['keyboardzoom'] = true;
159 + $postdata['hfov'] = '';
160 + $postdata['maxHfov'] = '';
161 + $postdata['minHfov'] = '';
162 + $postdata['cpLogoImg'] = '';
163 + $postdata['cpLogoContent'] = '';
388 164
389 - if (strpos($videourl, 'youtube') > 0 || strpos($videourl, 'youtu') > 0) {
390 - $explodeid = '';
391 - $explodeid = explode("=", $videourl);
392 - $foundid = '';
393 - $muted = '&mute=1';
394 -
395 - if ($autoplay == 'on') {
396 - $autoplay = '&autoplay=1';
397 - } else {
398 - $autoplay = '';
399 - }
400 -
401 - if ($loop == 'on') {
402 - $loop = '&loop=1';
403 - } else {
404 - $loop = '';
405 - }
406 -
407 - if (strpos($videourl, 'youtu') > 0) {
408 - $explodeid = explode("/", $videourl);
409 - $foundid = $explodeid[3] . '?' . $autoplay . $loop;
410 - $expdata = $explodeid[3];
411 - } else {
412 - $foundid = $explodeid[1] . '?' . $autoplay . $loop;
413 - $expdata = $explodeid[1];
414 - }
415 -
416 - $playlist = '&playlist=' . $expdata;
417 - $playlist = str_replace("?feature=shared", "", $playlist);
418 -
419 -
420 - $html = '';
421 - $html .= '<div class="' . esc_attr($className) . '" style="text-align:center; max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height:' . esc_attr($height) . esc_attr($height_unit) . '; border-radius: ' . esc_attr($radius) . '; margin: 0 auto;">';
422 -
423 - // Compatibility check script
424 - $html .= '<script>
425 - function wpvr_check_360_support() {
426 - var support = {
427 - supported: false,
428 - fullySupported: false,
429 - webgl: false,
430 - orientation: false,
431 - gyroscope: false,
432 - touch: false,
433 - browser: "unknown",
434 - isMobile: false,
435 - isIPhone: false,
436 - details: []
437 - };
438 -
439 - support.isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
440 - support.isIPhone = /iPhone/i.test(navigator.userAgent);
441 - if (support.isMobile) support.details.push("Mobile device detected");
442 - if (support.isIPhone) support.details.push("iPhone detected");
443 -
444 - var ua = navigator.userAgent;
445 - if (/^((?!chrome|android).)*safari/i.test(ua)) {
446 - support.browser = "safari";
447 - support.details.push("Safari browser detected");
448 - } else if (ua.indexOf("Chrome") > -1) {
449 - support.browser = "chrome";
450 - support.details.push("Chrome browser detected");
451 - } else if (ua.indexOf("Firefox") > -1) {
452 - support.browser = "firefox";
453 - support.details.push("Firefox browser detected");
454 - } else if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) {
455 - support.browser = "ie";
456 - support.details.push("Internet Explorer detected");
457 - } else if (ua.indexOf("Edge") > -1 || ua.indexOf("Edg") > -1) {
458 - support.browser = "edge";
459 - support.details.push("Edge browser detected");
460 - } else if (ua.indexOf("Opera") > -1 || ua.indexOf("OPR") > -1) {
461 - support.browser = "opera";
462 - support.details.push("Opera browser detected");
463 - }
464 -
465 - try {
466 - var canvas = document.createElement("canvas");
467 - support.webgl = !!(window.WebGLRenderingContext &&
468 - (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")));
469 - support.details.push(support.webgl ? "WebGL supported" : "WebGL not supported");
470 - } catch (e) {
471 - support.webgl = false;
472 - support.details.push("WebGL detection error: " + e.message);
473 - }
474 -
475 - support.orientation = !!(window.DeviceOrientationEvent);
476 - support.details.push(support.orientation ? "Device Orientation API supported" : "Device Orientation API not supported");
477 -
478 - support.gyroscope = !!window.Gyroscope;
479 - support.details.push(support.gyroscope ? "Gyroscope supported" : "Gyroscope not supported");
480 -
481 - support.touch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
482 - support.details.push(support.touch ? "Touch supported" : "Touch not supported");
483 -
484 - support.supported = support.webgl;
485 - support.fullySupported = support.webgl && ((support.isMobile && support.orientation) || !support.isMobile);
486 -
487 - if (support.browser === "safari" && support.isIPhone) {
488 - support.browserWarning = "iPhone has limited support for 360 videos in browser. The experience may not be optimal.";
489 - support.fullySupported = false;
490 - } else if (support.browser === "ie") {
491 - support.browserWarning = "Internet Explorer has limited support for 360 videos.";
492 - support.fullySupported = false;
493 - } else if (!support.supported) {
494 - support.browserWarning = "Your browser does not support 360° videos. Use Chrome or Firefox with WebGL.";
495 - }
496 -
497 - return support;
498 - }
499 - </script>';
500 -
501 - $random_id = 'video-container-' . rand(10000, 99999);
502 - $html .= '<div id="' . $random_id . '-container" style="position:relative; width:100%; height:100%;">';
503 -
504 - // Compatibility check screen (initially hidden for all, will show only for iPhone)
505 - $html .= '<div id="' . $random_id . '-compatibility-check" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:#f9f9f9; border-radius:' . esc_attr( $radius ) . ';">
506 - <div style="margin-bottom:20px; text-align:center;">
507 - <div class="wpvr-loading-spinner" style="border:5px solid #f3f3f3; border-top:5px solid #3498db; border-radius:50%; width:50px; height:50px; margin:0 auto 15px; animation:wpvr-spin 1s linear infinite;"></div>
508 - <p style="margin:0;">Checking browser compatibility...</p>
509 - </div>
510 - </div>';
511 -
512 - // Spinner animation
513 - $html .= '<style>@keyframes wpvr-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>';
514 -
515 - // Iframe (initial display set to block)
516 - $html .= '<div id="' . $random_id . '-frame" class="' . esc_attr($className) . '" style="display:block; max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height:' . esc_attr($height) . esc_attr($height_unit) . '; border-radius: ' . esc_attr($radius) . '; margin: 0 auto;">';
517 - $html .= '<iframe id="' . $random_id . '-iframe" src="https://www.youtube.com/embed/' . rawurlencode(sanitize_text_field($expdata)) . '?rel=0&modestbranding=1' . esc_attr($loop) . '&autohide=1' . esc_attr($muted) . '&showinfo=0&controls=1' . esc_attr($autoplay) . esc_attr($playlist) . '&enablejsapi=1" width="100%" height="100%" style="border-radius: ' . esc_attr($radius) . ';" frameborder="0" allowfullscreen allow="accelerometer; gyroscope; picture-in-picture"></iframe>';
518 - $html .= '</div>';
519 -
520 - // Permission request (mobile only)
521 - $html .= '<div id="' . $random_id . '-permission-request" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:rgba(0,0,0,0.7); color:white; text-align:center; border-radius:' . $radius . ';">';
522 - $html .= '<p style="font-size:16px; margin:0 20px 15px;">For the best 360° video experience on mobile</p>';
523 - $html .= '<button id="' . $random_id . '-permission-button" style="padding:10px 15px; background-color:#0085ba; color:#fff; border:none; border-radius:4px; cursor:pointer;">Allow motion and orientation access</button>';
524 - $html .= '</div>';
525 -
526 - // Browser warning
527 - $html .= '<div id="' . $random_id . '-browser-warning" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:rgba(0,0,0,0.7); color:white; text-align:center; border-radius:' . $radius . ';">';
528 - $html .= '<p id="' . $random_id . '-warning-text" style="font-size:16px; margin:0 20px 5px;"></p>';
529 - $html .= '<p style="font-size:14px; margin:5px 20px 15px;">For the best experience, use Chrome or Firefox.</p>';
530 - $html .= '<button id="' . $random_id . '-browser-continue" style="padding:10px 15px; background-color:#0085ba; color:#fff; border:none; border-radius:4px; cursor:pointer;">Continue Anyway</button>';
531 - $html .= '</div>';
532 -
533 - // Main script
534 - $html .= '<script>
535 - document.addEventListener("DOMContentLoaded", function() {
536 - var supportInfo = wpvr_check_360_support();
537 - var compatibilityCheck = document.getElementById("' . $random_id . '-compatibility-check");
538 - var frameContainer = document.getElementById("' . $random_id . '-frame");
539 - var warning = document.getElementById("' . $random_id . '-browser-warning");
540 - var warningText = document.getElementById("' . $random_id . '-warning-text");
541 - var continueBtn = document.getElementById("' . $random_id . '-browser-continue");
542 -
543 - // Only show compatibility check and warning for iPhone
544 - if (supportInfo.isIPhone) {
545 - // Hide the iframe initially for iPhone
546 - frameContainer.style.display = "none";
547 -
548 - // Show compatibility check for iPhone
549 - compatibilityCheck.style.display = "flex";
550 -
551 - // After delay, hide compatibility check and show warning
552 - setTimeout(function() {
553 - compatibilityCheck.style.display = "none";
554 - warningText.textContent = supportInfo.browserWarning || "Your browser may not fully support 360° videos.";
555 - warning.style.display = "flex";
556 -
557 - continueBtn.addEventListener("click", function() {
558 - warning.style.display = "none";
559 -
560 - if (supportInfo.fullySupported && supportInfo.isMobile) {
561 - document.getElementById("' . $random_id . '-permission-request").style.display = "flex";
562 - document.getElementById("' . $random_id . '-permission-button").addEventListener("click", function() {
563 - requestDevicePermissions();
564 - });
565 - } else {
566 - showVideo();
567 - }
568 - });
569 - }, 1000);
570 - } else {
571 - // For non-iPhone devices, directly initialize the player
572 - initializeYouTubePlayer();
573 - }
574 -
575 - function requestDevicePermissions() {
576 - try {
577 - if (typeof DeviceOrientationEvent !== "undefined" &&
578 - typeof DeviceOrientationEvent.requestPermission === "function") {
579 - DeviceOrientationEvent.requestPermission().then(function(response) {
580 - if (response === "granted") {
581 - if (typeof DeviceMotionEvent !== "undefined" &&
582 - typeof DeviceMotionEvent.requestPermission === "function") {
583 - DeviceMotionEvent.requestPermission().then(showVideo).catch(showVideo);
584 - } else {
585 - showVideo();
586 - }
587 - } else {
588 - showVideo();
589 - }
590 - }).catch(showVideo);
591 - } else {
592 - showVideo();
593 - }
594 - } catch (e) {
595 - showVideo();
596 - }
597 - }
598 -
599 - function showVideo() {
600 - document.getElementById("' . $random_id . '-permission-request").style.display = "none";
601 - frameContainer.style.display = "block";
602 - initializeYouTubePlayer();
603 - }
604 -
605 - function initializeYouTubePlayer() {
606 - if (window.YT) {
607 - initPlayer();
608 - } else {
609 - var tag = document.createElement("script");
610 - tag.src = "https://www.youtube.com/iframe_api";
611 - var firstScriptTag = document.getElementsByTagName("script")[0];
612 - firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
613 - window.onYouTubeIframeAPIReady = initPlayer;
614 - }
615 -
616 - function initPlayer() {
617 - new YT.Player("' . $random_id . '-iframe", {
618 - events: {
619 - "onReady": function(event) {}
620 - }
621 - });
622 - }
623 - }
624 - });
625 - </script>';
626 -
627 - $html .= '</div>'; // Close container
628 - $html .= '</div>'; // Close outer wrapper
629 - } else {
630 - $html = '';
631 - $html .= '<div id="pano' . esc_attr($id) . '" class="pano-wrap ' . esc_attr($className) . '" style="max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height: ' . esc_attr($height) . esc_attr($height_unit) . '; border-radius:' . esc_attr($radius) . '; margin: 0 auto;">';
632 - $html .= '<div style="width:100%; height:100%; border-radius: ' . esc_attr($radius) . ';">' . $postdata['panoviddata'] . '</div>';
633 -
634 - $html .= '
635 - <style>
636 - .video-js {
637 - border-radius:' . $radius . ';
638 - }
639 - .video-js canvas{
640 - border-radius:' . $radius . ';
641 - }
642 - #pano' . $id . ' .vjs-poster {
643 - border-radius: ' . $radius . ';
644 - }
645 - </style>
646 -
647 - ';
648 -
649 - // $html .= '<script>';
650 - // $html .= 'videojs(' . $postdata['vidid'] . ', {';
651 - // $html .= 'plugins: {';
652 - // $html .= 'pannellum: {}';
653 - // $html .= '}';
654 - // $html .= '});';
655 - // $html .= '</script>';
656 - $html .= '</div>';
657 -
658 - //video js vr setup //
659 - $html .= '<script>';
660 - $html .= '
661 - (function (window, videojs) {
662 - var player = window.player = videojs("' . $postdata['vidid'] . '");
663 - player.mediainfo = player.mediainfo || {};
664 - player.mediainfo.projection = "equirectangular";
665 -
666 - // AUTO is the default and looks at mediainfo
667 - var vr = window.vr = player.vr({ projection: "AUTO", debug: true, forceCardboard: false, antialias: false });
668 - }(window, window.videojs));
669 -
670 - ';
671 - $html .= '</script>';
672 - //video js vr end //
165 + if ( ( $postdata['tour-type'] ?? '' ) === 'street-view' || isset( $postdata['streetviewdata'] ) ) {
166 + $postdata['tour-type'] = 'image';
167 + $postdata['streetview'] = 'off';
168 + $postdata['streetviewurl'] = '';
169 + unset( $postdata['streetviewdata'] );
673 170 }
674 - return $html;
675 - }
676 171
677 - $control = false;
678 - if (isset($postdata['showControls'])) {
679 - $control = $postdata['showControls'];
680 - }
681 -
682 - if ($control) {
683 - if (isset($postdata['customcontrol'])) {
684 - $custom_control = $postdata['customcontrol'];
685 - if ($custom_control['panupSwitch'] == "on" || $custom_control['panDownSwitch'] == "on" || $custom_control['panLeftSwitch'] == "on" || $custom_control['panRightSwitch'] == "on" || $custom_control['panZoomInSwitch'] == "on" || $custom_control['panZoomOutSwitch'] == "on" || $custom_control['panFullscreenSwitch'] == "on" || $custom_control['gyroscopeSwitch'] == "on" || $custom_control['backToHomeSwitch'] == "on") {
686 - $control = false;
687 - }
172 + $custom_control = isset( $postdata['customcontrol'] ) && is_array( $postdata['customcontrol'] )
173 + ? $postdata['customcontrol']
174 + : [];
175 + foreach ( [
176 + 'panupSwitch', 'panDownSwitch', 'panLeftSwitch', 'panRightSwitch',
177 + 'panZoomInSwitch', 'panZoomOutSwitch', 'panFullscreenSwitch',
178 + 'gyroscopeSwitch', 'backToHomeSwitch',
179 + ] as $key ) {
180 + $custom_control[ $key ] = 'off';
688 181 }
689 - }
182 + $postdata['customcontrol'] = $custom_control;
690 183
691 - $floor_plan_enable = 'off';
692 - $floor_plan_image = '';
693 - if (isset($postdata['floor_plan_tour_enabler']) && $postdata['floor_plan_tour_enabler'] == 'on') {
694 - $floor_plan_enable = $postdata['floor_plan_tour_enabler'];
695 - if (isset($postdata['floor_plan_attachment_url']) && !empty($postdata['floor_plan_attachment_url'])) {
696 - $floor_plan_image = $postdata['floor_plan_attachment_url'];
697 - }
698 - }
699 -
700 - $vrgallery = false;
701 - if (isset($postdata['vrgallery'])) {
702 - $vrgallery = $postdata['vrgallery'];
703 - }
704 -
705 - $vrgallery_title = false;
706 - if (isset($postdata['vrgallery_title'])) {
707 - $vrgallery_title = $postdata['vrgallery_title'];
708 - }
709 -
710 - $vrgallery_display = false;
711 - if (isset($postdata['vrgallery_display'])) {
712 - $vrgallery_display = $postdata['vrgallery_display'];
713 - }
714 - $vrgallery_icon_size = false;
715 - if (isset($postdata['vrgallery_icon_size'])) {
716 - $vrgallery_icon_size = $postdata['vrgallery_icon_size'];
717 - }
718 -
719 - $gyro = false;
720 - $gyro_orientation = false;
721 - if (isset($postdata['gyro'])) {
722 - $gyro = $postdata['gyro'];
723 - if (isset($postdata['deviceorientationcontrol'])) {
724 - $gyro_orientation = $postdata['deviceorientationcontrol'];
725 - }
726 - }
727 -
728 - $compass = false;
729 - $audio_right = "5px";
730 - if (isset($postdata['compass'])) {
731 - $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
732 - if ($compass) {
733 - $audio_right = "60px";
734 - }
735 - }
736 - $floor_map_right = "10px";
737 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
738 - $floor_map_right = "85px";
739 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
740 - $floor_map_right = "55px";
741 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
742 - $floor_map_right = "25px";
743 - }
744 -
745 - //===explainer handle===//
746 -
747 - //===explainer handle===//
748 - $explainer_right = "10px";
749 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
750 - $explainer_right = "130px";
751 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on' && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
752 - $explainer_right = "100px";
753 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
754 - $explainer_right = "60px";
755 - } elseif ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
756 - $explainer_right = "80px";
757 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
758 - $explainer_right = "55px";
759 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
760 - $explainer_right = "30px";
761 - } elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image)) {
762 - $explainer_right = "40px";
763 - }
764 - $enable_cardboard = '';
765 - $is_cardboard = get_option('wpvr_cardboard_disable');
766 - if (wpvr_isMobileDevice() && $is_cardboard == 'true') {
767 - $enable_cardboard = 'enable-cardboard';
768 - $audio_right = "73px";
769 - if (isset($postdata['compass'])) {
770 - $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
771 - if ($compass) {
772 - $audio_right = "130px";
773 - }
774 - }
775 -
776 - $floor_map_right = "60px";
777 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
778 - $floor_map_right = "150px";
779 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
780 - $floor_map_right = "120px";
781 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
782 - $floor_map_right = "90px";
783 - }
784 -
785 - //===explainer handle===//
786 -
787 - $explainer_right = "65px";
788 -
789 - if ((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
790 - $explainer_right = "150px";
791 - } elseif ((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
792 - $explainer_right = "180px";
793 - } elseif (isset($postdata['compass']) && $postdata['compass'] == true && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
794 - $explainer_right = "150px";
795 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
796 - $explainer_right = "120px";
797 - } elseif (isset($postdata['compass']) && $postdata['compass'] == true) {
798 - $explainer_right = "130px";
799 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
800 - $explainer_right = "90px";
801 - } elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image)) {
802 - $explainer_right = "90px";
803 - }
804 - }
805 -
806 - //===explainer handle===//
807 -
808 - $mouseZoom = true;
809 - if (isset($postdata['mouseZoom'])) {
810 - if ($postdata['mouseZoom'] == "off") {
811 - $mouseZoom = false;
812 - } else {
813 - $mouseZoom = true;
814 - }
815 - }
816 -
817 - $draggable = true;
818 - if (isset($postdata['draggable'])) {
819 - $draggable = $postdata['draggable'] == 'on' || $postdata['draggable'] != null ? true : false;
820 - if ($postdata['draggable'] === 'off') {
821 - $draggable = false;
822 - }
823 - }
824 - $diskeyboard = false;
825 - if (isset($postdata['diskeyboard'])) {
826 - $diskeyboard = $postdata['diskeyboard'] == 'off' || $postdata['diskeyboard'] == null ? false : true;
827 - }
828 -
829 - $keyboardzoom = true;
830 - if (isset($postdata['keyboardzoom'])) {
831 - $keyboardzoom = $postdata['keyboardzoom'];
832 - }
833 -
834 - $autoload = false;
835 -
836 - if (isset($postdata['autoLoad'])) {
837 - $autoload = $postdata['autoLoad'];
838 - }
839 -
840 - $default_scene = '';
841 - if (isset($postdata['defaultscene'])) {
842 - $default_scene = $postdata['defaultscene'];
843 - }
844 -
845 - $preview = '';
846 - if (isset($postdata['preview'])) {
847 - $preview = $postdata['preview'];
848 - }
849 -
850 - $autorotation = '';
851 - if (isset($postdata["autoRotate"])) {
852 - $autorotation = $postdata["autoRotate"];
853 - }
854 - $autorotationinactivedelay = '';
855 - if (isset($postdata["autoRotateInactivityDelay"])) {
856 - $autorotationinactivedelay = $postdata["autoRotateInactivityDelay"];
857 - }
858 - $autorotationstopdelay = '';
859 - if (isset($postdata["autoRotateStopDelay"])) {
860 - $autorotationstopdelay = $postdata["autoRotateStopDelay"];
861 - }
862 -
863 - $scene_fade_duration = '';
864 - if (isset($postdata['scenefadeduration'])) {
865 - $scene_fade_duration = $postdata['scenefadeduration'];
866 - }
867 -
868 - $panodata = array();
869 - if (isset($postdata['panodata'])) {
870 - $panodata = $postdata['panodata'];
871 - }
872 -
873 - $default_zoom_global = 100;
874 - if (isset($postdata['hfov']) && $postdata['hfov'] != '') {
875 - $default_zoom_global = $postdata['hfov'];
876 - }
877 -
878 - $min_zoom_global = 50;
879 - if (isset($postdata['minHfov']) && $postdata['minHfov'] != '') {
880 - $min_zoom_global = $postdata['minHfov'];
881 - }
882 -
883 - $max_zoom_global = 120;
884 - if (isset($postdata['maxHfov']) && $postdata['maxHfov'] != '') {
885 - $max_zoom_global = $postdata['maxHfov'];
886 - }
887 -
888 - $hotspoticoncolor = '#00b4ff';
889 - $hotspotblink = 'on';
890 - $default_data = array();
891 - $default_data = array('firstScene' => $default_scene, 'sceneFadeDuration' => $scene_fade_duration, 'hfov' => $default_zoom_global, 'maxHfov' => $max_zoom_global, 'minHfov' => $min_zoom_global);
892 - $scene_data = array();
893 - if (is_array($panodata) && isset($panodata['scene-list'])) {
894 - if (!empty($panodata['scene-list'])) {
895 - foreach ($panodata['scene-list'] as $panoscenes) {
896 - $scene_ititle = '';
897 - if (isset($panoscenes["scene-ititle"])) {
898 - $scene_ititle = sanitize_text_field($panoscenes["scene-ititle"]);
184 + if ( isset( $postdata['panodata']['scene-list'] ) && is_array( $postdata['panodata']['scene-list'] ) ) {
185 + foreach ( $postdata['panodata']['scene-list'] as &$scene ) {
186 + if ( ! is_array( $scene ) ) {
187 + continue;
899 188 }
900 189
901 - $scene_author = '';
902 - if (isset($panoscenes["scene-author"])) {
903 - $scene_author = sanitize_text_field($panoscenes["scene-author"]);
190 + if ( ( $scene['scene-type'] ?? 'equirectangular' ) === 'cubemap' ) {
191 + $scene['scene-type'] = 'equirectangular';
904 192 }
905 193
906 - $scene_author_url = '';
907 - if (isset($panoscenes["scene-author-url"])) {
908 - $scene_author_url = sanitize_text_field($panoscenes["scene-author-url"]);
194 + foreach ( [ 'ptyscene', 'cvgscene', 'chgscene', 'czscene' ] as $key ) {
195 + $scene[ $key ] = 'off';
909 196 }
910 -
911 - $scene_vaov = 180;
912 - if (isset($panoscenes["scene-vaov"])) {
913 - $scene_vaov = (float)$panoscenes["scene-vaov"];
197 + foreach ( [
198 + 'scene-author', 'scene-author-url', 'scene-vaov', 'scene-haov',
199 + 'scene-vertical-offset', 'scene-pitch', 'scene-yaw',
200 + 'scene-maxpitch', 'scene-minpitch', 'scene-maxyaw', 'scene-minyaw',
201 + 'scene-zoom', 'scene-maxzoom', 'scene-minzoom',
202 + ] as $key ) {
203 + $scene[ $key ] = '';
914 204 }
915 -
916 - $scene_haov = 360;
917 - if (isset($panoscenes["scene-haov"])) {
918 - $scene_haov = (float)$panoscenes["scene-haov"];
205 + for ( $face = 0; $face < 6; $face++ ) {
206 + $scene[ 'scene-attachment-url-face' . $face ] = '';
919 207 }
920 208
921 - $scene_vertical_offset = 0;
922 - if (isset($panoscenes["scene-vertical-offset"])) {
923 - $scene_vertical_offset = (float)$panoscenes["scene-vertical-offset"];
924 - }
925 -
926 - $default_scene_pitch = null;
927 - if (isset($panoscenes["scene-pitch"])) {
928 - $default_scene_pitch = (float)$panoscenes["scene-pitch"];
929 - }
930 -
931 - $default_scene_yaw = null;
932 - if (isset($panoscenes["scene-yaw"])) {
933 - $default_scene_yaw = (float)$panoscenes["scene-yaw"];
934 - }
935 -
936 - $scene_max_pitch = '';
937 - if (isset($panoscenes["scene-maxpitch"])) {
938 - $scene_max_pitch = (float)$panoscenes["scene-maxpitch"];
939 - }
940 -
941 -
942 - $scene_min_pitch = '';
943 - if (isset($panoscenes["scene-minpitch"])) {
944 - $scene_min_pitch = (float)$panoscenes["scene-minpitch"];
945 - }
946 -
947 -
948 - $scene_max_yaw = '';
949 - if (isset($panoscenes["scene-maxyaw"])) {
950 - $scene_max_yaw = (float)$panoscenes["scene-maxyaw"];
951 - }
952 -
953 -
954 - $scene_min_yaw = '';
955 - if (isset($panoscenes["scene-minyaw"])) {
956 - $scene_min_yaw = (float)$panoscenes["scene-minyaw"];
957 - }
958 -
959 - $default_zoom = 100;
960 - if (isset($panoscenes["scene-zoom"]) && $panoscenes["scene-zoom"] != '') {
961 - $default_zoom = (int)$panoscenes["scene-zoom"];
962 - } else {
963 - if ($default_zoom_global != '') {
964 - $default_zoom = (int)$default_zoom_global;
965 - }
966 - }
967 -
968 -
969 - $max_zoom = 120;
970 - if (isset($panoscenes["scene-maxzoom"]) && $panoscenes["scene-maxzoom"] != '') {
971 - $max_zoom = (int)$panoscenes["scene-maxzoom"];
972 - } else {
973 - if ($max_zoom_global != '') {
974 - $max_zoom = (int)$max_zoom_global;
975 - }
976 - }
977 -
978 - $min_zoom = 120;
979 - if (isset($panoscenes["scene-minzoom"]) && $panoscenes["scene-minzoom"] != '') {
980 - $min_zoom = (int)$panoscenes["scene-minzoom"];
981 - } else {
982 - if ($min_zoom_global != '') {
983 - $min_zoom = (int)$min_zoom_global;
984 - }
985 - }
986 -
987 - $hotspot_datas = array();
988 - if (isset($panoscenes['hotspot-list'])) {
989 - $hotspot_datas = $panoscenes['hotspot-list'];
990 - }
991 -
992 - $hotspots = array();
993 -
994 - foreach ($hotspot_datas as $hotspot_data) {
995 - $status = get_option('wpvr_edd_license_status');
996 - if ($status !== false && $status == 'valid') {
997 -
998 - if (isset($hotspot_data["hotspot-customclass-pro"]) && $hotspot_data["hotspot-customclass-pro"] != 'none') {
999 - $hotspot_data['hotspot-customclass'] = $hotspot_data["hotspot-customclass-pro"] . ' custom-' . $id . '-' . $panoscenes['scene-id'] . '-' . $hotspot_data['hotspot-title'];
209 + if ( isset( $scene['hotspot-list'] ) && is_array( $scene['hotspot-list'] ) ) {
210 + foreach ( $scene['hotspot-list'] as &$hotspot ) {
211 + if ( ! is_array( $hotspot ) ) {
212 + continue;
1000 213 }
1001 - if (isset($hotspot_data['hotspot-blink'])) {
1002 - $hotspotblink = $hotspot_data['hotspot-blink'];
1003 - }
214 + $hotspot['hotspot-customclass-pro'] = 'none';
215 + $hotspot['hotspot-blink'] = 'off';
216 + $hotspot['hotspot-shape'] = 'round';
217 + $hotspot['hotspot-border'] = 'off';
218 + $hotspot['hotspot-scene-pitch'] = '';
219 + $hotspot['hotspot-scene-yaw'] = '';
1004 220 }
1005 - $hotspot_scene_pitch = '';
1006 - if (isset($hotspot_data["hotspot-scene-pitch"])) {
1007 - $hotspot_scene_pitch = $hotspot_data["hotspot-scene-pitch"];
1008 - }
1009 - $hotspot_scene_yaw = '';
1010 - if (isset($hotspot_data["hotspot-scene-yaw"])) {
1011 - $hotspot_scene_yaw = $hotspot_data["hotspot-scene-yaw"];
1012 - }
1013 -
1014 - $hotspot_type = $hotspot_data["hotspot-type"] !== 'scene' ? 'info' : $hotspot_data["hotspot-type"];
1015 - $hotspot_content = '';
1016 -
1017 - ob_start();
1018 - do_action('wpvr_hotspot_content', $hotspot_data);
1019 - $hotspot_content = ob_get_clean();
1020 -
1021 - if (!$hotspot_content) {
1022 - $hotspot_content = $hotspot_data["hotspot-content"];
1023 - }
1024 -
1025 - if (isset($hotspot_data["wpvr_url_open"][0])) {
1026 - $wpvr_url_open = $hotspot_data["wpvr_url_open"][0];
1027 - } else {
1028 - $wpvr_url_open = "off";
1029 - }
1030 - $on_hover_content = preg_replace_callback(
1031 - '/<p>\s*(<img[^>]*>)\s*<br>\s*<\/p>/i',
1032 - function ($matches) {
1033 - return $matches[1];
1034 - },
1035 - $hotspot_data['hotspot-hover'] ?? ''
1036 - );
1037 - $on_hover_content = sanitize_content_preserve_styles($on_hover_content ?? '');
1038 - $on_click_content = preg_replace_callback('/<img[^>]*>/', "replace_callback", $hotspot_content ?? '');
1039 - $hotspot_shape = 'round';
1040 - if (isset($hotspot_data["hotspot-customclass-pro"]) && $hotspot_data["hotspot-customclass-pro"] != 'none') {
1041 - $hotspot_shape = isset($hotspot_data["hotspot-shape"]) ? $hotspot_data["hotspot-shape"] : 'round';
1042 - }
1043 -
1044 - $hotspot_data_for_on_click=[];
1045 - if('info' === $hotspot_type && !empty($on_click_content)){
1046 - $hotspot_data_for_on_click = [
1047 - 'on_click_content' => $on_click_content,
1048 - 'tour_id' => $id,
1049 - 'scene_id' => $panoscenes['scene-id'],
1050 - 'hotspot_id' => $hotspot_data['hotspot-title'],
1051 - ];
1052 - } elseif('info' === $hotspot_type && !empty($hotspot_data["hotspot-url"])){
1053 - $hotspot_data_for_on_click = [
1054 - 'on_click_content' => '',
1055 - 'tour_id' => $id,
1056 - 'scene_id' => $panoscenes['scene-id'],
1057 - 'hotspot_id' => $hotspot_data['hotspot-title'],
1058 - ];
1059 - }
1060 -
1061 - $hotspot_info = array(
1062 - 'text' => $hotspot_data['hotspot-title'],
1063 - 'pitch' => $hotspot_data['hotspot-pitch'],
1064 - 'yaw' => $hotspot_data['hotspot-yaw'],
1065 - 'type' => $hotspot_type,
1066 - 'cssClass' => $hotspot_data['hotspot-customclass'],
1067 - 'URL' => $hotspot_data['hotspot-url'],
1068 - "wpvr_url_open" => $wpvr_url_open,
1069 - "clickHandlerArgs" => $hotspot_data_for_on_click,
1070 - 'createTooltipArgs' => !empty(trim($on_hover_content)) ? trim($on_hover_content) : '',
1071 - "sceneId" => $hotspot_data["hotspot-scene"],
1072 - "targetPitch" => (float)$hotspot_scene_pitch,
1073 - "targetYaw" => (float)$hotspot_scene_yaw,
1074 - 'hotspot_type' => $hotspot_data['hotspot-type'],
1075 - 'hotspot_shape' => $hotspot_shape,
1076 - );
1077 -
1078 - $hotspot_info['URL'] = ($hotspot_data['hotspot-type'] === 'fluent_form' || $hotspot_data['hotspot-type'] === 'wc_product') ? '' : $hotspot_info['URL'];
1079 -
1080 - if ($hotspot_data["hotspot-customclass"] == 'none' || $hotspot_data["hotspot-customclass"] == '') {
1081 - unset($hotspot_info["cssClass"]);
1082 - }
1083 - if (empty($hotspot_data["hotspot-scene"])) {
1084 - unset($hotspot_info['targetPitch']);
1085 - unset($hotspot_info['targetYaw']);
1086 - }
1087 - array_push($hotspots, $hotspot_info);
221 + unset( $hotspot );
1088 222 }
1089 -
1090 - $device_scene = $panoscenes['scene-attachment-url'];
1091 - $mobile_media_resize = get_option('mobile_media_resize');
1092 - $file_accessible = ini_get('allow_url_fopen');
1093 - if ($mobile_media_resize == "true" && $device_scene) {
1094 - if ($file_accessible == "1") {
1095 - $image_info = getimagesize($device_scene);
1096 - if ($image_info && $image_info[0] > 4096) {
1097 - $src_to_id_for_mobile = '';
1098 - $src_to_id_for_desktop = '';
1099 - if (wpvr_isMobileDevice()) {
1100 - $src_to_id_for_mobile = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1101 - if ($src_to_id_for_mobile) {
1102 - $mobile_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'wpvr_mobile');
1103 - if ($mobile_scene[3]) {
1104 - $device_scene = $mobile_scene[0];
1105 - }
1106 - }
1107 - } else {
1108 - $src_to_id_for_desktop = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1109 - if ($src_to_id_for_desktop) {
1110 - $desktop_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'full');
1111 - if ($desktop_scene && $desktop_scene[0]) {
1112 - $device_scene = $desktop_scene[0];
1113 - }
1114 - }
1115 - }
1116 - }
1117 - }
1118 - }
1119 -
1120 - $scene_info = array();
1121 -
1122 - if ($panoscenes["scene-type"] == 'cubemap') {
1123 - $pano_type = 'cubemap';
1124 - $pano_attachment = array(
1125 - $panoscenes["scene-attachment-url-face0"],
1126 - $panoscenes["scene-attachment-url-face1"],
1127 - $panoscenes["scene-attachment-url-face2"],
1128 - $panoscenes["scene-attachment-url-face3"],
1129 - $panoscenes["scene-attachment-url-face4"],
1130 - $panoscenes["scene-attachment-url-face5"]
1131 - );
1132 -
1133 - $scene_info = array('type' => $panoscenes['scene-type'], 'cubeMap' => $pano_attachment, "pitch" => $default_scene_pitch, "maxPitch" => $scene_max_pitch, "minPitch" => $scene_min_pitch, "maxYaw" => $scene_max_yaw, "minYaw" => $scene_min_yaw, "yaw" => $default_scene_yaw, "hfov" => $default_zoom, "maxHfov" => $max_zoom, "minHfov" => $min_zoom, "title" => $scene_ititle, "author" => $scene_author, "authorURL" => $scene_author_url, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, 'hotSpots' => $hotspots);
1134 - } else {
1135 - $scene_info = array('type' => $panoscenes['scene-type'], 'panorama' => $device_scene, "pitch" => $default_scene_pitch, "maxPitch" => $scene_max_pitch, "minPitch" => $scene_min_pitch, "maxYaw" => $scene_max_yaw, "minYaw" => $scene_min_yaw, "yaw" => $default_scene_yaw, "hfov" => $default_zoom, "maxHfov" => $max_zoom, "minHfov" => $min_zoom, "title" => $scene_ititle, "author" => $scene_author, "authorURL" => $scene_author_url, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, 'hotSpots' => $hotspots);
1136 - }
1137 -
1138 -
1139 -
1140 - if (isset($panoscenes["ptyscene"])) {
1141 - if ($panoscenes["ptyscene"] == "off") {
1142 - unset($scene_info['pitch']);
1143 - unset($scene_info['yaw']);
1144 - }
1145 - }
1146 -
1147 - if (empty($panoscenes["scene-ititle"])) {
1148 - unset($scene_info['title']);
1149 - }
1150 - if (empty($panoscenes["scene-author"])) {
1151 - unset($scene_info['author']);
1152 - }
1153 - if (empty($panoscenes["scene-author-url"])) {
1154 - unset($scene_info['authorURL']);
1155 - }
1156 -
1157 - if (empty($scene_vaov)) {
1158 - unset($scene_info['vaov']);
1159 - }
1160 -
1161 - if (empty($scene_haov)) {
1162 - unset($scene_info['haov']);
1163 - }
1164 -
1165 - if (empty($scene_vertical_offset)) {
1166 - unset($scene_info['vOffset']);
1167 - }
1168 -
1169 - if (isset($panoscenes["cvgscene"])) {
1170 - if ($panoscenes["cvgscene"] == "off") {
1171 - unset($scene_info['maxPitch']);
1172 - unset($scene_info['minPitch']);
1173 - }
1174 - }
1175 - if (empty($panoscenes["scene-maxpitch"])) {
1176 - unset($scene_info['maxPitch']);
1177 - }
1178 -
1179 - if (empty($panoscenes["scene-minpitch"])) {
1180 - unset($scene_info['minPitch']);
1181 - }
1182 -
1183 - if (isset($panoscenes["chgscene"])) {
1184 - if ($panoscenes["chgscene"] == "off") {
1185 - unset($scene_info['maxYaw']);
1186 - unset($scene_info['minYaw']);
1187 - }
1188 - }
1189 - if (empty($panoscenes["scene-maxyaw"])) {
1190 - unset($scene_info['maxYaw']);
1191 - }
1192 -
1193 - if (empty($panoscenes["scene-minyaw"])) {
1194 - unset($scene_info['minYaw']);
1195 - }
1196 -
1197 - // if (isset($panoscenes["czscene"])) {
1198 - // if ($panoscenes["czscene"] == "off") {
1199 - // unset($scene_info['hfov']);
1200 - // unset($scene_info['maxHfov']);
1201 - // unset($scene_info['minHfov']);
1202 - // }
1203 - // }
1204 -
1205 - $scene_array = array();
1206 - $scene_array = array(
1207 - $panoscenes['scene-id'] => $scene_info
1208 - );
1209 -
1210 - $scene_data[$panoscenes['scene-id']] = $scene_info;
1211 223 }
224 + unset( $scene );
1212 225 }
1213 - }
1214 - $pano_id_array = array();
1215 - $pano_id_array = array('panoid' => $panoid);
1216 - $pano_response = array();
1217 - $pano_response = array('autoLoad' => $autoload, 'showControls' => $control, 'compass' => $compass, 'orientationOnByDefault' => $gyro_orientation, 'mouseZoom' => $mouseZoom, 'draggable' => $draggable, 'disableKeyboardCtrl' => $diskeyboard, 'keyboardZoom' => $keyboardzoom, "preview" => $preview, "autoRotate" => $autorotation, "autoRotateInactivityDelay" => $autorotationinactivedelay, "autoRotateStopDelay" => $autorotationstopdelay, 'default' => $default_data, 'scenes' => $scene_data);
1218 - if (empty($autorotation)) {
1219 - unset($pano_response['autoRotate']);
1220 - unset($pano_response['autoRotateInactivityDelay']);
1221 - unset($pano_response['autoRotateStopDelay']);
1222 - }
1223 - if (empty($autorotationinactivedelay)) {
1224 - unset($pano_response['autoRotateInactivityDelay']);
1225 - }
1226 - if (empty($autorotationstopdelay)) {
1227 - unset($pano_response['autoRotateStopDelay']);
1228 - }
1229 226
1230 - $response = array();
1231 - $response = array($pano_id_array, $pano_response);
1232 - if (!empty($response)) {
1233 - $response = json_encode($response);
227 + return $postdata;
1234 228 }
1235 - if (empty($width)) {
1236 - $width = '600';
1237 - }
1238 - if (empty($height)) {
1239 - $height = '400';
1240 - }
1241 - if ('fullwidth' == $width) {
1242 - $width = "100%";
1243 - }
229 +}
1244 230
1245 - $foreground_color = '#fff';
1246 - $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1247 - $rgb = wpvr_HTMLToRGB($hotspoticoncolor);
1248 - $hsl = wpvr_RGBToHSL($rgb);
1249 - if ($hsl->lightness > 200) {
1250 - $foreground_color = '#000000';
1251 - } else {
1252 - $foreground_color = '#fff';
1253 - }
1254 -
1255 - $class = 'myclass';
1256 - $html = 'test';
1257 - $html = '';
1258 - $html .= '<style>';
1259 - if ($width == 'embed') {
1260 - $html .= 'body{
1261 - overflow: hidden;
1262 - }';
1263 - }
1264 - $status = get_option('wpvr_edd_license_status');
1265 - $status = get_option('wpvr_edd_license_status');
1266 - if ($status !== false && $status == 'valid') {
1267 - if (isset($postdata['customcss_enable']) && $postdata['customcss_enable'] == 'on') {
1268 - $html .= isset($postdata['customcss']) ? $postdata['customcss'] : '';
231 +if ( ! function_exists( 'wpvr_tour_uses_pro_features' ) ) {
232 + /**
233 + * Determine whether a saved tour contains enabled WP VR Pro features.
234 + *
235 + * @param mixed $postdata Saved tour data.
236 + * @return bool
237 + */
238 + function wpvr_tour_uses_pro_features( $postdata ) {
239 + if ( ! is_array( $postdata ) ) {
240 + return false;
1269 241 }
1270 - }
1271 - if ($status !== false && $status == 'valid') {
1272 - if (is_array($panodata) && isset($panodata['scene-list'])) {
1273 - foreach ($panodata['scene-list'] as $panoscenes) {
1274 242
1275 - foreach ($panoscenes['hotspot-list'] as $hotspot) {
1276 - if (isset($hotspot['hotspot-customclass-color-icon-value']) && !empty($hotspot['hotspot-customclass-color-icon-value'])) {
1277 - $hotspoticoncolor = $hotspot['hotspot-customclass-color-icon-value'];
1278 - } else {
1279 - $hotspoticoncolor = "#00b4ff";
1280 - }
1281 - $hotspot_border = '';
1282 - if(isset($hotspot['hotspot-border']) && $hotspot['hotspot-border'] == 'on'){
1283 - $border_width = $hotspot['hotspot-border-width'];
1284 - $border_color = $hotspot['hotspot-border-color'];
1285 - $border_style = $hotspot['hotspot-border-style'];
1286 -
1287 - $hotspot_border = 'border: '.$border_width.'px '.$border_style.' '.$border_color.';';
1288 - }
1289 - $hotspot_background_color = 'background-color: ' . $hotspoticoncolor . ';';
1290 - $hotspot_animation = ' animation: icon-pulse' . $panoid . '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1291 - '. $hotspot_border.'';
243 + $is_on = static function ( $value ) {
244 + return in_array( $value, array( true, 1, '1', 'on', 'true' ), true );
245 + };
1292 246
1293 -
1294 - $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1295 - if (isset($hotspot["hotspot-customclass-pro"]) && $hotspot["hotspot-customclass-pro"] != 'none') {
1296 - $border_radius = ' border-radius: 100%;';
1297 - $hotspot_shape = isset($hotspot["hotspot-shape"]) ? $hotspot["hotspot-shape"] : 'round';
1298 - if($hotspot_shape === 'square'){
1299 - $border_radius = '';
1300 - }
1301 - if ($hotspot_shape === 'hexagon') {
1302 - $border_radius = '';
1303 - $hotspot_background_color = 'background-color: transparent;';
1304 - $hotspot_animation = '';
1305 - }
1306 -
1307 - if(isset($hotspot['hotspot-custom-icon-color-value']) && !empty($hotspot['hotspot-custom-icon-color-value'])){
1308 - $foreground_color = $hotspot['hotspot-custom-icon-color-value'];
1309 - }
1310 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fas.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1311 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fab.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1312 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fa.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1313 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fa-solid.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1314 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.far.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' {
1315 - display: block !important;
1316 - '.$hotspot_background_color.'
1317 - color: ' . $foreground_color . ';
1318 - '.$border_radius.'
1319 - width: 30px;
1320 - height: 30px;
1321 - font-size: 16px;
1322 - line-height: 30px;
1323 - '.$hotspot_animation.'
1324 - }';
1325 - if($hotspot_shape === 'hexagon'){
1326 -
1327 - $html .= '#' . esc_attr( $panoid ) . ' .custom-' . esc_attr( $id ) . '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' .hexagon-wrapper svg path {
1328 - fill: ' . $hotspoticoncolor . ';
1329 - }';
1330 -
1331 - $html .= '#' . esc_attr( $panoid ) . ' .custom-' . esc_attr( $id ) . '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . '.pnlm-tooltip:after{
1332 - content: "";
1333 - position: absolute;
1334 - left: 50%;
1335 - top: 50%;
1336 - transform: translate(-50%, -50%);
1337 - width: 85%;
1338 - height: 85%;
1339 - animation: icon-pulse' . esc_attr( $panoid ) . '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1340 - border-radius: 100%;
1341 - z-index: -2;
1342 - }';
1343 -
1344 - }
1345 - $html .= '#' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fas.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1346 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fab.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1347 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fa-solid.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1348 - #' . esc_attr( $panoid2) . ' div.pnlm-hotspot-base.fa.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ',
1349 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.far.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' {
1350 - display: block !important;
1351 - '.esc_attr( $hotspot_background_color).'
1352 - color: ' . esc_attr( $foreground_color) . ';
1353 - '.esc_attr( $border_radius).'
1354 - width: 30px;
1355 - height: 30px;
1356 - font-size: 16px;
1357 - line-height: 30px;
1358 - '.esc_attr( $hotspot_animation).'
1359 - }';
1360 - }
1361 - if (isset($hotspot['hotspot-blink'])) {
1362 - $hotspotblink = $hotspot['hotspot-blink'];
1363 - if ($hotspotblink == 'on') {
1364 - $html .= '@-webkit-keyframes icon-pulse' . esc_attr( $panoid) . '-' . $panoscenes['scene-id'] . '-' . $hotspot['hotspot-title'] . ' {
1365 - 0% {
1366 - box-shadow: 0 0 0 0px rgba(' . esc_attr( $pulse_color[0]) . ', 1);
1367 - }
1368 - 100% {
1369 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pulse_color[0]) . ', 0);
1370 - }
1371 - }
1372 - @keyframes icon-pulse' . esc_attr( $panoid) . ' {
1373 - 0% {
1374 - box-shadow: 0 0 0 0px rgba(' . esc_attr( $pulse_color[0]) . ', 1);)
1375 - }
1376 - 100% {
1377 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pulse_color[0] ). ', 0);
1378 - }
1379 - }';
1380 - }
1381 - }
1382 - }
1383 - }
247 + if (
248 + isset( $postdata['streetviewdata'] )
249 + || ( isset( $postdata['streetview'] ) && $is_on( $postdata['streetview'] ) )
250 + || ! empty( $postdata['streetviewurl'] )
251 + ) {
252 + return true;
1384 253 }
1385 - }
1386 254
1387 - $status = get_option('wpvr_edd_license_status');
1388 - if ($status !== false && $status == 'valid') {
1389 - if (!$gyro) {
1390 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-orientation-button {
1391 - display: none;
1392 - }';
1393 - }
1394 - } else {
1395 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-orientation-button {
1396 - display: none;
1397 - }';
1398 - }
1399 - $floor_plan_custom_color = isset($postdata['floor_plan_custom_color']) ? $postdata['floor_plan_custom_color'] : '#cca92c';
1400 - $foreground_color_pointer = '#fff';
1401 - if ($floor_plan_custom_color != '') {
1402 - $pointer_pulse = wpvr_hex2rgb($floor_plan_custom_color);
1403 - $floor_rgb = wpvr_HTMLToRGB($floor_plan_custom_color);
1404 - $floor_hsl = wpvr_RGBToHSL($floor_rgb);
1405 - if ($floor_hsl->lightness > 200) {
1406 - $foreground_color_pointer = '#000000';
1407 - }
1408 - $html .= '
1409 - .wpvr-floor-map .floor-plan-pointer.add-pulse:before {
1410 - border: 17px solid ' . esc_attr( $floor_plan_custom_color ) . ';
255 + foreach ( array(
256 + 'bg_tour_enabler', 'floorplan-enabled', 'floor_plan_tour_enabler',
257 + 'floor_plan_compass', 'floor_plan_direction_indicator',
258 + 'gyro', 'deviceorientationcontrol', 'compass', 'vrgallery',
259 + 'vrgallery_title', 'vrgallery_icon_size', 'vrgallery_display',
260 + 'scene_navigation', 'sceneAnimation', 'bg_music',
261 + 'autoplay_bg_music', 'loop_bg_music', 'explainerSwitch',
262 + 'cpLogoSwitch', 'genericform', 'calltoaction', 'customcss_enable',
263 + ) as $key ) {
264 + if ( isset( $postdata[ $key ] ) && $is_on( $postdata[ $key ] ) ) {
265 + return true;
1411 266 }
1412 - @-webkit-keyframes pulse {
1413 - 0% {
1414 - -webkit-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1415 - }
1416 - 70% {
1417 - -webkit-box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1418 - }
1419 - 100% {
1420 - -webkit-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1421 - }
1422 - }
1423 - @keyframes pulse {
1424 - 0% {
1425 - -moz-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1426 - box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1427 - }
1428 - 70% {
1429 - -moz-box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1430 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1431 - }
1432 - 100% {
1433 - -moz-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1434 - box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1435 - }
1436 - }';
1437 - }
1438 - $html .= '</style>';
1439 -
1440 - $scene_animation = isset($postdata['sceneAnimation']) ? $postdata['sceneAnimation'] : 'off';
1441 -
1442 - if( $scene_animation === 'on'){
1443 - $animation_type = isset($postdata['sceneAnimationName']) ? $postdata['sceneAnimationName'] : 'none';
1444 - $animationDuration = isset($postdata['sceneAnimationTransitionDuration']) ? $postdata['sceneAnimationTransitionDuration'] : '500ms';
1445 - $animationDelay = isset($postdata['sceneAnimationTransitionDelay']) ? $postdata['sceneAnimationTransitionDelay'] : '0ms';
1446 - $animation_css = apply_filters('wpvr_tour_scene_animation',$animation_type,$animationDuration, $animationDelay, $postdata,$id);
1447 - $html .= $animation_css;
1448 - }
1449 -
1450 - if (wpvr_isMobileDevice()) {
1451 - $html .= '<div id="master-container" class="wpvr-cardboard ' . esc_attr( $className ) . ' ' . esc_attr( $enable_cardboard ) . ' " style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; width: 100%; height: ' . esc_attr( $mobile_height ) . esc_attr( $mobile_height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr; border : ' . esc_attr( $border_style ) . ' ">';
1452 - } else {
1453 - $html .= '<div id="master-container" class="wpvr-cardboard ' . esc_attr( $className ) . ' ' . esc_attr( $enable_cardboard ) . '" style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; width: 100%; height: ' . esc_attr( $height ) . esc_attr( $height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr; border : ' . esc_attr( $border_style ) . '">';
1454 - }
1455 - $status = get_option('wpvr_edd_license_status');
1456 - $is_cardboard = get_option('wpvr_cardboard_disable');
1457 - if ($status !== false && 'valid' == $status && $is_pro && wpvr_isMobileDevice() && $is_cardboard == 'true') {
1458 - $html .= '<button class="fullscreen-button">';
1459 - $html .= '<span class="expand">';
1460 - $html .= '<i class="fa fa-expand" aria-hidden="true"></i>';
1461 - $html .= '</span>';
1462 -
1463 - $html .= '<span class="compress">';
1464 - $html .= '<i class="fa fa-compress" aria-hidden="true"></i>';
1465 - $html .= '</span>';
1466 - $html .= '</button>';
1467 - $html .= '<label class="wpvr-cardboard-switcher">
1468 - <input type="checkbox" class="vr_mode_change' . $id . '" name="vr_mode_change" value="off">
1469 - <span class="switcher-box">
1470 - <span class="normal-mode-tooltip">Normal VR Mode</span>
1471 - <svg width="78" height="60" viewBox="0 0 78 60" fill="none" xmlns="http://www.w3.org/2000/svg">
1472 - <path d="M42.25 21.4286C42.25 22.2811 41.9076 23.0986 41.2981 23.7014C40.6886 24.3042 39.862 24.6429 39 24.6429C38.138 24.6429 37.3114 24.3042 36.7019 23.7014C36.0924 23.0986 35.75 22.2811 35.75 21.4286C35.75 20.5761 36.0924 19.7585 36.7019 19.1557C37.3114 18.5529 38.138 18.2143 39 18.2143C39.862 18.2143 40.6886 18.5529 41.2981 19.1557C41.9076 19.7585 42.25 20.5761 42.25 21.4286ZM19.5 30C18.9254 30 18.3743 30.2258 17.9679 30.6276C17.5616 31.0295 17.3333 31.5745 17.3333 32.1429C17.3333 32.7112 17.5616 33.2562 17.9679 33.6581C18.3743 34.06 18.9254 34.2857 19.5 34.2857H28.1667C28.7413 34.2857 29.2924 34.06 29.6987 33.6581C30.1051 33.2562 30.3333 32.7112 30.3333 32.1429C30.3333 31.5745 30.1051 31.0295 29.6987 30.6276C29.2924 30.2258 28.7413 30 28.1667 30H19.5ZM47.6667 32.1429C47.6667 31.5745 47.8949 31.0295 48.3013 30.6276C48.7076 30.2258 49.2587 30 49.8333 30H58.5C59.0746 30 59.6257 30.2258 60.0321 30.6276C60.4384 31.0295 60.6667 31.5745 60.6667 32.1429C60.6667 32.7112 60.4384 33.2562 60.0321 33.6581C59.6257 34.06 59.0746 34.2857 58.5 34.2857H49.8333C49.2587 34.2857 48.7076 34.06 48.3013 33.6581C47.8949 33.2562 47.6667 32.7112 47.6667 32.1429ZM32.5 0C31.9254 0 31.3743 0.225765 30.9679 0.627629C30.5616 1.02949 30.3333 1.57454 30.3333 2.14286V8.57143H18.4167C14.8693 8.57183 11.4528 9.89617 8.84994 12.2798C6.24706 14.6634 4.64954 17.9306 4.37667 21.4286H2.16667C1.59203 21.4286 1.04093 21.6543 0.634602 22.0562C0.228273 22.4581 0 23.0031 0 23.5714V36.4286C0 36.9969 0.228273 37.5419 0.634602 37.9438C1.04093 38.3457 1.59203 38.5714 2.16667 38.5714H4.33333V46.0714C4.33333 49.7655 5.81711 53.3083 8.45825 55.9204C11.0994 58.5325 14.6815 60 18.4167 60H25.3933C29.1269 59.9986 32.7071 58.5311 35.347 55.92L37.921 53.3786C38.0618 53.2393 38.229 53.1288 38.4131 53.0534C38.5971 52.978 38.7943 52.9392 38.9935 52.9392C39.1927 52.9392 39.3899 52.978 39.5739 53.0534C39.758 53.1288 39.9252 53.2393 40.066 53.3786L42.6357 55.92C45.2766 58.5322 48.8586 59.9998 52.5937 60H59.5833C63.3185 60 66.9006 58.5325 69.5418 55.9204C72.1829 53.3083 73.6667 49.7655 73.6667 46.0714V38.5714H75.8333C76.408 38.5714 76.9591 38.3457 77.3654 37.9438C77.7717 37.5419 78 36.9969 78 36.4286V23.5714C78 23.0031 77.7717 22.4581 77.3654 22.0562C76.9591 21.6543 76.408 21.4286 75.8333 21.4286H73.6233C73.3505 17.9306 71.753 14.6634 69.1501 12.2798C66.5472 9.89617 63.1307 8.57183 59.5833 8.57143H47.6667V2.14286C47.6667 1.57454 47.4384 1.02949 47.0321 0.627629C46.6257 0.225765 46.0746 0 45.5 0H32.5ZM69.3333 22.5V46.0714C69.3333 48.6289 68.3061 51.0816 66.4776 52.89C64.6491 54.6983 62.1692 55.7143 59.5833 55.7143H52.5937C50.0093 55.7132 47.5311 54.6973 45.7037 52.89L43.1297 50.3486C42.5864 49.8108 41.9413 49.3842 41.2312 49.0931C40.5211 48.8021 39.76 48.6522 38.9913 48.6522C38.2227 48.6522 37.4616 48.8021 36.7515 49.0931C36.0414 49.3842 35.3963 49.8108 34.853 50.3486L32.2833 52.89C30.4559 54.6973 27.9777 55.7132 25.3933 55.7143H18.4167C15.8308 55.7143 13.3509 54.6983 11.5224 52.89C9.6939 51.0816 8.66667 48.6289 8.66667 46.0714V22.5C8.66667 19.9426 9.6939 17.4899 11.5224 15.6815C13.3509 13.8731 15.8308 12.8571 18.4167 12.8571H59.5833C62.1692 12.8571 64.6491 13.8731 66.4776 15.6815C68.3061 17.4899 69.3333 19.9426 69.3333 22.5Z" fill="#216DF0"/>
1473 - </svg>
1474 - </span>
1475 - </label>';
1476 - }
1477 -
1478 - if ($width == 'fullwidth') {
1479 - if (wpvr_isMobileDevice()) {
1480 - $html .= '<div class="cardboard-vrfullwidth vrfullwidth">';
1481 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left cardboard-half" style="width: 49%!important; border-radius:' . esc_attr( $radius ). ' ;text-align:center; direction:ltr;" ><div id="center-pointer2' . esc_attr( $id ). '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1482 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style="width: 100%; text-align:center; direction:ltr; border-radius:' . esc_attr( $radius ) . '" >';
1483 - } else {
1484 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';"><div id="center-pointer2' . esc_attr( $id ). '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1485 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap vrfullwidth" style=" text-align:center; height: ' . esc_attr( $height ) . esc_attr( $height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr;" >';
1486 267 }
1487 - } else {
1488 - if (wpvr_isMobileDevice()) {
1489 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left cardboard-half" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';">
1490 - <div id="center-pointer2' . esc_attr( $id ) . '" class="vr-pointer-container">
1491 - <span class="center-pointer"></span>
1492 - </div>
1493 - </div>';
1494 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style=" width: 100%; border-radius:' . esc_attr( $radius ) . ';">';
1495 - } else {
1496 268
1497 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';"><div id="center-pointer2' . esc_attr( $id ) . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1498 -
1499 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style="width: 100%; border-radius:' . esc_attr( $radius ) . ';">';
269 + if (
270 + ! empty( $postdata['hfov'] )
271 + || ! empty( $postdata['maxHfov'] )
272 + || ! empty( $postdata['minHfov'] )
273 + ) {
274 + return true;
1500 275 }
1501 - }
1502 - // Vr mode transction scene to scene
1503 - if ($status !== false && 'valid' == $status && $is_pro && wpvr_isMobileDevice() && $is_cardboard == 'true') {
1504 - $html .= '<div id="center-pointer' . esc_attr( $id ) . '" class="vr-pointer-container" style="display:none"><span class="center-pointer"></span></div>';
1505 - }
1506 276
1507 -
1508 - //===company logo===//
1509 - if (isset($postdata['cpLogoSwitch'])) {
1510 - $cpLogoImg = $postdata['cpLogoImg'];
1511 - $cpLogoContent = $postdata['cpLogoContent'];
1512 - if ($postdata['cpLogoSwitch'] == 'on') {
1513 - $html .= '<div id="cp-logo-controls">';
1514 - $html .= '<div class="cp-logo-ctrl" id="cp-logo">';
1515 - if ($cpLogoImg) {
1516 - $html .= '<img loading="lazy" src="' . esc_attr( $cpLogoImg ) . '" alt="Company Logo">';
1517 - }
1518 -
1519 - if ($cpLogoContent) {
1520 - $html .= '<div class="cp-info">' . esc_attr( $cpLogoContent ) . '</div>';
1521 - }
1522 - $html .= '</div>';
1523 - $html .= '</div>';
277 + $tour_layout = isset( $postdata['tourLayout'] ) ? $postdata['tourLayout'] : 'default';
278 + $tour_layout = is_array( $tour_layout )
279 + ? ( isset( $tour_layout['layout'] ) ? $tour_layout['layout'] : 'default' )
280 + : $tour_layout;
281 + if ( $tour_layout !== '' && $tour_layout !== 'default' ) {
282 + return true;
1524 283 }
1525 - }
1526 - //===company logo ends===//
1527 284
1528 - //===Background Tour===//
1529 - if (isset($postdata['bg_tour_enabler'])) {
1530 -
1531 - $bg_tour_enabler = $postdata['bg_tour_enabler'];
1532 - if ($bg_tour_enabler == 'on') {
1533 - $bg_tour_navmenu = $postdata['bg_tour_navmenu'] ?? 'off';
1534 - $bg_tour_title = $postdata['bg_tour_title'] ?? '';
1535 - $bg_tour_subtitle = $postdata['bg_tour_subtitle'] ?? '';
1536 -
1537 - if ($bg_tour_navmenu == 'on') {
1538 - $menuLocations = get_nav_menu_locations();
1539 - $menuID = $menuLocations['primary'];
1540 - $primaryNav = wp_get_nav_menu_items($menuID);
1541 -
1542 - if ($primaryNav) {
1543 - $html .= '<div class="wpvr-navbar-container">';
1544 - foreach ($primaryNav as $primaryNav_key => $primaryNav_value) {
1545 - if ($primaryNav_value->menu_item_parent == "0") {
1546 - $html .= '<li>';
1547 - $html .= '<a href="' . esc_url( $primaryNav_value->url ) . '">' . esc_attr( $primaryNav_value->title ) . '</a>';
1548 - $html .= '<ul class="wpvr-navbar-dropdown">';
1549 - foreach ($primaryNav as $pm_key => $pm_value) {
1550 - if ($pm_value->menu_item_parent == $primaryNav_value->ID) {
1551 - $html .= '<li>';
1552 - $html .= '<a href="' . esc_url( $pm_value->url ) . '">' . esc_attr( $pm_value->title ) . '</a>';
1553 - $html .= '</li>';
1554 - }
1555 - }
1556 - $html .= '</ul>';
1557 - $html .= '</li>';
1558 - }
1559 - }
1560 - $html .= '</div>';
1561 - }
285 + $custom_control = isset( $postdata['customcontrol'] ) && is_array( $postdata['customcontrol'] )
286 + ? $postdata['customcontrol']
287 + : array();
288 + foreach ( array(
289 + 'panupSwitch', 'panDownSwitch', 'panLeftSwitch', 'panRightSwitch',
290 + 'panZoomInSwitch', 'panZoomOutSwitch', 'panFullscreenSwitch',
291 + 'gyroscopeSwitch', 'backToHomeSwitch',
292 + ) as $key ) {
293 + if ( isset( $custom_control[ $key ] ) && $is_on( $custom_control[ $key ] ) ) {
294 + return true;
1562 295 }
1563 -
1564 - $html .= '<div class="wpvr-home-content">';
1565 - $html .= '<div class="wpvr-home-title">' . esc_attr( $bg_tour_title ) . '</div>';
1566 - $html .= '<div class="wpvr-home-subtitle">' . esc_attr( $bg_tour_subtitle ) . '</div>';
1567 - $html .= '</div>';
1568 296 }
1569 - }
1570 - //===Background Tour End===//
1571 297
1572 - //===Custom Control===//
1573 - if (isset($custom_control)) {
1574 - if ($custom_control['panZoomInSwitch'] == "on" || $custom_control['panZoomOutSwitch'] == "on" || $custom_control['gyroscopeSwitch'] == "on" || $custom_control['backToHomeSwitch'] == "on") {
1575 - $html .= '<div id="zoom-in-out-controls' . esc_attr( $id ) . '" class="zoom-in-out-controls">';
1576 -
1577 - if ($custom_control['backToHomeSwitch'] == "on") {
1578 - $html .= '<div class="ctrl" id="backToHome' . esc_attr( $id ) . '"><i class="' . $custom_control['backToHomeIcon'] . '" style="color:' . esc_attr( $custom_control['backToHomeColor'] ) . ';"></i></div>';
1579 - }
1580 -
1581 - if ($custom_control['panZoomInSwitch'] == "on") {
1582 - $html .= '<div class="ctrl" id="zoom-in' . esc_attr( $id ) . '"><i class="' . $custom_control['panZoomInIcon'] . '" style="color:' . esc_attr( $custom_control['panZoomInColor'] ) . ';"></i></div>';
1583 - }
1584 -
1585 - if ($custom_control['panZoomOutSwitch'] == "on") {
1586 - $html .= '<div class="ctrl" id="zoom-out' . esc_attr( $id ) . '"><i class="' . $custom_control['panZoomOutIcon'] . '" style="color:' . esc_attr( $custom_control['panZoomOutColor'] ) . ';"></i></div>';
1587 - }
1588 -
1589 - if ($custom_control['gyroscopeSwitch'] == "on") {
1590 - $html .= '<div class="ctrl" id="gyroscope' . esc_attr( $id ) . '"><i class="' . $custom_control['gyroscopeIcon'] . '" style="color:' . esc_attr( $custom_control['gyroscopeColor'] ) . ';"></i></div>';
1591 - }
1592 -
1593 - $html .= '</div>';
298 + $scenes = isset( $postdata['panodata']['scene-list'] ) ? $postdata['panodata']['scene-list'] : array();
299 + if ( ! is_array( $scenes ) ) {
300 + return false;
1594 301 }
1595 - //===zoom in out Control===//
1596 302
1597 - if ($custom_control['panupSwitch'] == "on" || $custom_control['panDownSwitch'] == "on" || $custom_control['panLeftSwitch'] == "on" || $custom_control['panRightSwitch'] == "on" || $custom_control['panFullscreenSwitch'] == "on") {
303 + $pro_scene_fields = array(
304 + 'scene-vaov', 'scene-haov', 'scene-vertical-offset', 'scene-pitch',
305 + 'scene-yaw', 'scene-maxpitch', 'scene-minpitch', 'scene-maxyaw',
306 + 'scene-minyaw', 'scene-zoom', 'scene-maxzoom', 'scene-minzoom',
307 + );
1598 308
1599 - //===Custom Control===//
1600 - $html .= '<div class="controls" id="controls' . esc_attr( $id ) . '">';
1601 -
1602 - if ($custom_control['panupSwitch'] == "on") {
1603 - $html .= '<div class="ctrl pan-up" id="pan-up' . esc_attr( $id ) . '"><i class="' . $custom_control['panupIcon'] . '" style="color:' . esc_attr( $custom_control['panupColor'] ) . ';"></i></div>';
309 + foreach ( $scenes as $scene ) {
310 + if ( ! is_array( $scene ) ) {
311 + continue;
1604 312 }
1605 313
1606 - if ($custom_control['panDownSwitch'] == "on") {
1607 - $html .= '<div class="ctrl pan-down" id="pan-down' . esc_attr( $id ) . '"><i class="' . $custom_control['panDownIcon'] . '" style="color:' . esc_attr( $custom_control['panDownColor'] ) . ';"></i></div>';
314 + if ( isset( $scene['scene-type'] ) && 'cubemap' === $scene['scene-type'] ) {
315 + return true;
1608 316 }
1609 317
1610 - if ($custom_control['panLeftSwitch'] == "on") {
1611 - $html .= '<div class="ctrl pan-left" id="pan-left' . esc_attr( $id ) . '"><i class="' . $custom_control['panLeftIcon'] . '" style="color:' . esc_attr( $custom_control['panLeftColor'] ) . ';"></i></div>';
318 + foreach ( array( 'ptyscene', 'cvgscene', 'chgscene', 'czscene' ) as $key ) {
319 + if ( isset( $scene[ $key ] ) && $is_on( $scene[ $key ] ) ) {
320 + return true;
321 + }
1612 322 }
1613 323
1614 - if ($custom_control['panRightSwitch'] == "on") {
1615 - $html .= '<div class="ctrl pan-right" id="pan-right' . esc_attr( $id ) . '"><i class="' . $custom_control['panRightIcon'] . '" style="color:' . esc_attr( $custom_control['panRightColor'] ) . ';"></i></div>';
324 + foreach ( $pro_scene_fields as $key ) {
325 + if ( isset( $scene[ $key ] ) && '' !== $scene[ $key ] && null !== $scene[ $key ] ) {
326 + return true;
327 + }
1616 328 }
1617 329
1618 - if ($custom_control['panFullscreenSwitch'] == "on") {
1619 - $html .= '<div class="ctrl fullscreen" id="fullscreen' . esc_attr( $id ) . '"><i class="' . $custom_control['panFullscreenIcon'] . '" style="color:' . esc_attr( $custom_control['panFullscreenColor'] ) . ';"></i></div>';
330 + $hotspots = isset( $scene['hotspot-list'] ) ? $scene['hotspot-list'] : array();
331 + if ( ! is_array( $hotspots ) ) {
332 + continue;
1620 333 }
1621 - $html .= '</div>';
1622 - }
1623 334
1624 - //===explainer button===//
1625 - $explainerControlSwitch = '';
1626 - if (isset($custom_control['explainerSwitch'])) {
1627 - $explainerControlSwitch = $custom_control['explainerSwitch'];
1628 - }
1629 - if ($custom_control['explainerSwitch'] == "on") {
1630 - $explainer_style = empty($postdata['explainerContent']) || ( isset( $postdata['explainerSwitch'] ) && 'off' === $postdata['explainerSwitch'] )? 'pointer-events: none; opacity: 0.5;' : '';
1631 - $html .= '<div class="explainer_button" id="explainer_button_' . esc_attr( $id ) . '" style="right:' . esc_attr( $explainer_right ) . '; ' . esc_attr( $explainer_style ) . '">';
1632 - $html .= '<div class="ctrl" id="explainer_target_' . esc_attr( $id ) . '"><i class="' . $custom_control['explainerIcon'] . '" style="color:' . esc_attr( $custom_control['explainerColor'] ) . ';"></i></div>';
1633 - $html .= '</div>';
1634 - }
1635 -
1636 - //===explainer button===//
1637 -
1638 - }
1639 - //===Custom Control===//
1640 -
1641 - //===Scene navigation Control===//
1642 - if (isset($postdata['scene_navigation']) && $postdata['scene_navigation'] === 'on') {
1643 - $html .= '<style>
1644 - #et-boc .et-l .pnlm-controls-container,
1645 - .pnlm-controls-container{
1646 - top: 33px;
335 + foreach ( $hotspots as $hotspot ) {
336 + if ( ! is_array( $hotspot ) ) {
337 + continue;
1647 338 }
1648 -
1649 - #et-boc .et-l .zoom-in-out-controls,
1650 - .zoom-in-out-controls {
1651 - top: 37px;
1652 - }
1653 - </style>';
1654 - $html .= '<div id="custom-scene-navigation' . esc_attr( $id ) . '" class="custom-scene-navigation">
1655 - <span class="hamburger-menu"><svg width="16" height="10" fill="none" viewBox="0 0 22 15" xmlns="http://www.w3.org/2000/svg"><rect width="21.177" height="2.647" fill="#f7fffb" rx="1.324"/><rect width="21.177" height="2.647" y="6.177" fill="#f7fffb" rx="1.324"/><rect width="21.177" height="2.647" y="12.352" fill="#f7fffb" rx="1.324"/></svg></span>
1656 - </div>
1657 -
1658 - <div id="custom-scene-navigation-nav' . esc_attr( $id ) . '" class="custom-scene-navigation-nav">
1659 - <ul></ul>
1660 - </div>
1661 - ';
1662 - }
1663 339
1664 - //===Scene navigation Control===//
1665 -
1666 - /**
1667 - * Generic Form Handler
1668 - * Renders a generic form with modal functionality if enabled in post data
1669 - *
1670 - * @param array $postdata Array containing form configuration data
1671 - * @param string $id Unique identifier for the form instance
1672 - * @return string $html Generated HTML content
1673 - */
1674 -
1675 - // Check if generic form is enabled and validate the setting
1676 - if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on') {
1677 -
1678 - // $shortcode_val = isset($postdata["genericformshortcode"]) && $postdata["genericformshortcode"] !== "" ? do_shortcode($postdata["genericformshortcode"]) : "No shortcode found or shortcode is empty";
1679 -
1680 - // Process shortcode with fallback handling
1681 - $shortcode_content = '';
1682 - if (isset($postdata["genericformshortcode"]) && !empty(trim($postdata["genericformshortcode"]))) {
1683 - $shortcode_content = do_shortcode($postdata["genericformshortcode"]);
1684 - } else {
1685 - $shortcode_content = '<p class="error-message">No shortcode found.</p>';
1686 - }
1687 -
1688 - // Generate the form trigger button
1689 - $html .= '<div class="generic_form_button" id="generic_form_button_' . esc_attr( $id ) . '">';
1690 - $html .= '<div class="generic-form-icon" title ="Generic Form" id="generic_form_target_' . esc_attr( $id ) . '"><i class="fab fa-wpforms" style="color:#f7fffb;"></i></div>';
1691 - $html .= '</div>';
1692 -
1693 - // Generate the modal form container
1694 - $html .= '<div class="wpvr-generic-form" id="wpvr-generic-form' . esc_attr( $id ) . '" style="display: none">';
1695 - $html .= '<span class="close-generic-form"><i class="fa fa-times"></i></span>';
1696 - $html .= '<div class="generic-form-container">' . $shortcode_content . '</div>';
1697 - $html .= '</div>';
1698 - }
1699 - //=====custom generic form=====//
1700 -
1701 - //===Floor map button===//
1702 - $status = get_option('wpvr_edd_license_status');
1703 - if ($status !== false && 'valid' == $status && $is_pro) {
1704 - if ($floor_plan_enable == "on" && !empty($floor_plan_image)) {
1705 - $html .= '<div class="floor_map_button" id="floor_map_button_' . esc_attr( $id ) . '" style="right:' . esc_attr( $floor_map_right ) . '">';
1706 - $html .= '<div class="ctrl" id="floor_map_target_' . esc_attr( $id ) . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>';
1707 - $html .= '</div>';
1708 - }
1709 - }
1710 -
1711 - //===floor map button===//
1712 - if ($vrgallery) {
1713 - //===Carousal setup===//
1714 - $size = '';
1715 - if ($vrgallery_icon_size) {
1716 - $size = 'vrg-icon-size-large';
1717 - }
1718 - $html .= '<div id="vrgcontrols' . esc_attr( $id ) . '" class="vrgcontrols">';
1719 -
1720 - $html .= '<div class="vrgctrl' . esc_attr( $id ) . ' vrbounce ' . esc_attr( $size ) . '">';
1721 - $html .= '</div>';
1722 - $html .= '</div>';
1723 -
1724 - $html .= '<div id="sccontrols' . esc_attr( $id ) . '" class="scene-gallery vrowl-carousel owl-theme">';
1725 - if (isset($panodata["scene-list"])) {
1726 - foreach ($panodata["scene-list"] as $panoscenes) {
1727 - $scene_key = $panoscenes['scene-id'];
1728 - if ($vrgallery_title == 'on') {
1729 - $scene_key_title = $panoscenes['scene-ititle'];
1730 - // $scene_key_title = $panoscenes['scene-id'];
1731 - } else {
1732 - $scene_key_title = "";
340 + if (
341 + ( ! empty( $hotspot['hotspot-customclass-pro'] ) && 'none' !== $hotspot['hotspot-customclass-pro'] )
342 + || ( ! empty( $hotspot['hotspot-shape'] ) && 'round' !== $hotspot['hotspot-shape'] )
343 + || ( isset( $hotspot['hotspot-border'] ) && $is_on( $hotspot['hotspot-border'] ) )
344 + || ! empty( $hotspot['hotspot-scene-pitch'] )
345 + || ! empty( $hotspot['hotspot-scene-yaw'] )
346 + || ( isset( $hotspot['hotspot-scene-entry-point-mode'] ) && 'custom' === $hotspot['hotspot-scene-entry-point-mode'] )
347 + ) {
348 + return true;
1733 349 }
1734 -
1735 - if ($panoscenes['scene-type'] == 'cubemap') {
1736 - $img_src_url = $panoscenes['scene-attachment-url-face0'];
1737 - } else {
1738 - $img_src_url = $panoscenes['scene-attachment-url'];
1739 - }
1740 -
1741 -
1742 - $src_to_id = attachment_url_to_postid($img_src_url);
1743 - $thumbnail_array = wp_get_attachment_image_src($src_to_id, 'thumbnail');
1744 - if ($thumbnail_array) {
1745 - $thumbnail = $thumbnail_array[0];
1746 - } else {
1747 - $thumbnail = $img_src_url;
1748 - }
1749 - if( isset($postdata['tourLayout']['layout']) && 'layout1' !== $postdata['tourLayout']['layout']) {
1750 - $html .= '<ul><li title="Double click to view scene"><span class="scene-title" title="' . esc_attr($scene_key_title) . '"> ' . $scene_key_title . '</span><img loading="lazy" class="scctrl" id="' . $scene_key . '_gallery_' . $id . '" src="' . $thumbnail . '"></li></ul>';
1751 - }else {
1752 - $html .= '<ul><li title="Double click to view scene"><img loading="lazy" class="scctrl" id="' . $scene_key . '_gallery_' . $id . '" src="' . $thumbnail . '"><span class="scene-title" title="' . esc_attr($scene_key_title) . '">' . $scene_key_title . '</span></li></ul>';
1753 - }
1754 350 }
1755 351 }
1756 - $html .= '</div>';
1757 - $html .= '
1758 - <div class="owl-nav wpvr_slider_nav">
1759 - <button type="button" role="presentation" class="owl-prev wpvr_owl_prev">
1760 - <div class="nav-btn prev-slide"><i class="fa fa-angle-left"></i></div>
1761 - </button>
1762 - <button type="button" role="presentation" class="owl-next wpvr_owl_next">
1763 - <div class="nav-btn next-slide"><i class="fa fa-angle-right"></i></div>
1764 - </button>
1765 - </div>
1766 - ';
1767 - //===Carousal setup end===//
1768 - }
1769 352
1770 - $bg_music = isset($postdata['bg_music']) ? $postdata['bg_music'] : 'off';
1771 - $bg_music_url = isset($postdata['bg_music_url']) ? $postdata['bg_music_url'] : '';
1772 - $autoplay_bg_music = isset($postdata['autoplay_bg_music']) ? $postdata['autoplay_bg_music'] : 'off';
1773 - $loop_bg_music = isset($postdata['loop_bg_music']) ? $postdata['loop_bg_music'] : 'off';
1774 -
1775 - $bg_loop = ($loop_bg_music === 'on') ? 'loop' : '';
1776 - $autoplay_attr = ($autoplay_bg_music === 'on') ? 'autoplay' : '';
1777 - $audio_muted_attr = ($autoplay_bg_music === 'on') ? 'muted' : '';
1778 - $audio_icon_class = 'fa-volume-mute'; // Always start with mute icon
1779 -
1780 - if ($bg_music === 'on') {
1781 - $html .= '<div id="adcontrol' . esc_attr( $id ) . '" class="adcontrol" style="right:' . esc_attr( $audio_right ) . '">';
1782 - $html .= '<audio id="vrAudio' . esc_attr($id) . '" class="vrAudioDefault" data-autoplay="' . esc_attr($autoplay_bg_music) . '" onended="audionEnd' . esc_attr($id) . '()" ' . $autoplay_attr . ' ' . $audio_muted_attr . ' ' . $bg_loop . '>
1783 - <source src="' . esc_url($bg_music_url) . '" type="audio/mpeg">
1784 - Your browser does not support the audio element.
1785 - </audio>';
1786 - $html .= '<button onclick="playPause' . esc_attr($id) . '()" class="ctrl audio_control" id="audio_control' . esc_attr($id) . '">
1787 - <i id="vr-volume' . esc_attr($id) . '" class="wpvrvolumeicon' . esc_attr($id) . ' fas ' . esc_attr($audio_icon_class) . '" style="color:#fff;"></i>
1788 - </button>';
1789 - $html .= '</div>';
353 + return false;
1790 354 }
355 +}
1791 356
1792 - //===Explainer video section===//
1793 - $explainerContent = "";
1794 - if (isset($postdata['explainerContent'])) {
1795 - $explainerContent = $postdata['explainerContent'];
1796 - }
1797 - $html .= '<div class="explainer" id="explainer' . esc_attr( $id ) . '" style="display: none">';
1798 - $html .= '<span class="close-explainer-video"><i class="fa fa-times"></i></span>';
1799 - $html .= '' . $explainerContent . '';
1800 - $html .= '</div>';
1801 - //===Explainer video section End===//
357 +if ( ! function_exists( 'wpvr_get_pro_feature_tour_ids' ) ) {
358 + /**
359 + * Return IDs of tours that use at least one enabled Pro feature.
360 + *
361 + * @return array
362 + */
363 + function wpvr_get_pro_feature_tour_ids() {
364 + static $tour_ids = null;
1802 365
1803 - //===Floor plan section===//
1804 - $floor_map_image = "";
1805 - $floor_map_pointer = array();
1806 - $floor_map_scene_id = '';
1807 - $floor_plan_custom_color = '#cca92c';
1808 -
1809 - if (isset($postdata['floor_plan_attachment_url'])) {
1810 - $floor_map_image = $postdata['floor_plan_attachment_url'];
1811 - $floor_map_pointer = $postdata['floor_plan_pointer_position'];
1812 - $floor_map_scene_id = $postdata['floor_plan_data_list'];
1813 - $floor_plan_custom_color = $postdata['floor_plan_custom_color'];
1814 - }
1815 - $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $id . '" style="display: none">';
1816 - $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>';
1817 - $html .= '<img loading="lazy" src="' . $floor_map_image . '">';
1818 -
1819 - foreach ($floor_map_pointer as $key => $pointer_position) {
1820 - $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id = "' . esc_attr( $floor_map_scene_id[$key]->value ) . '" id="' . esc_attr( $pointer_position->id ) . '" data-top="' . esc_attr( $pointer_position->data_top ) . '" data-left="' . esc_attr( $pointer_position->data_left ) . '" style="' . esc_attr( $pointer_position->style ) . '">
1821 -
1822 - <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1823 - <circle cx="12" cy="12" r="11.5" stroke="' . esc_attr( $floor_plan_custom_color ) . '"/>
1824 - <circle cx="12" cy="12" r="5" fill="' . esc_attr( $foreground_color_pointer ) . '"/>
1825 - </svg>
1826 - <svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg">
1827 - <path d="M0.454054 1.32433L11.7683 34.3243C11.9069 34.7285 12.287 35 12.7143 35H41.2857C41.713 35 42.0931 34.7285 42.2317 34.3243L53.5459 1.32432C53.7685 0.675257 53.2862 0 52.6 0H1.4C0.713843 0 0.231517 0.675258 0.454054 1.32433Z" fill="url(#paint0_linear_1_10)"/>
1828 - <defs>
1829 - <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse">
1830 - <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/>
1831 - <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/>
1832 - </linearGradient>
1833 - </defs>
1834 - </svg>
1835 -
1836 - </div>';
1837 - }
1838 - $html .= '</div>';
1839 - //===Floor plan section===//
1840 -
1841 - $html .= '<div class="wpvr-hotspot-tweak-contents-wrapper" style="display: none">';
1842 - $html .= '<i class="fa fa-times cross" data-id="' . esc_attr( $id ) . '"></i>';
1843 - $html .= '<div class="wpvr-hotspot-tweak-contents-flex">';
1844 - $html .= '<div class="wpvr-hotspot-tweak-contents">';
1845 - ob_start();
1846 - do_action('wpvr_hotspot_tweak_contents', $scene_data);
1847 - $hotspot_content = ob_get_clean();
1848 - $html .= $hotspot_content;
1849 - $html .= '</div>';
1850 - $html .= '</div>';
1851 - $html .= '</div>';
1852 -
1853 - $html .= '<div class="custom-ifram-wrapper" style="display: none;">';
1854 - $html .= '<i class="fa fa-times cross" data-id="' . esc_attr( $id ) . '"></i>';
1855 - $html .= '<div class="custom-ifram-flex">';
1856 - $html .= '<div class="custom-ifram">';
1857 - $html .= '</div>';
1858 - $html .= '</div>';
1859 - $html .= '</div>';
1860 - $html .= '</div>';
1861 - $html .= '</div>';
1862 -
1863 -
1864 - if ("fullwidth" == $width) {
1865 - $html .= '</div>';
1866 - }
1867 - if ($status !== false && 'valid' == $status && $is_pro) {
1868 - $call_to_action = isset($postdata['calltoaction']) ? $postdata['calltoaction'] : 'off';
1869 - if ('on' == $call_to_action) {
1870 - $buttontext = isset($postdata['buttontext']) ? $postdata['buttontext'] : '';
1871 - $buttonurl = isset($postdata['buttonurl']) ? $postdata['buttonurl'] : '';
1872 - $cta_btn_style = isset($postdata['button_configuration']) ? $postdata['button_configuration'] : array();
1873 -
1874 - $button_open_new_tab = isset($cta_btn_style['button_open_new_tab']) ? $cta_btn_style['button_open_new_tab'] : "off";
1875 - $target = '_self';
1876 - $button_position = isset($cta_btn_style['button_position']) ? $cta_btn_style['button_position'] : "";
1877 - $background_color = isset($cta_btn_style['button_background_color']) ? $cta_btn_style['button_background_color'] : "";
1878 - $color = isset($cta_btn_style['button_font_color']) ? $cta_btn_style['button_font_color'] : "";
1879 - $font_size = isset($cta_btn_style['button_font_size']) ? $cta_btn_style['button_font_size'] : "";
1880 - $font_weight = isset($cta_btn_style['button_font_weight']) ? $cta_btn_style['button_font_weight'] : "";
1881 - $text_align = isset($cta_btn_style['button_alignment']) ? $cta_btn_style['button_alignment'] : "";
1882 - $text_transform = isset($cta_btn_style['button_transform']) ? $cta_btn_style['button_transform'] : "";
1883 - $font_style = isset($cta_btn_style['button_text_style']) ? $cta_btn_style['button_text_style'] : "";
1884 - $text_decoration = isset($cta_btn_style['button_text_decoration']) ? $cta_btn_style['button_text_decoration'] : "";
1885 - $line_height = isset($cta_btn_style['button_line_height']) ? $cta_btn_style['button_line_height'] : "";
1886 - $letter_spacing = isset($cta_btn_style['button_letter_spacing']) ? $cta_btn_style['button_letter_spacing'] : "";
1887 - $word_spacing = isset($cta_btn_style['button_word_spacing']) ? $cta_btn_style['button_word_spacing'] : "";
1888 -
1889 - $border_width = isset($cta_btn_style['button_border_width']) ? $cta_btn_style['button_border_width'] : "";
1890 - $border_style = isset($cta_btn_style['button_border_style']) ? $cta_btn_style['button_border_style'] : "";
1891 - $border_color = isset($cta_btn_style['button_border_color']) ? $cta_btn_style['button_border_color'] : "";
1892 - $border_radius = isset($cta_btn_style['button_border_radius']) ? $cta_btn_style['button_border_radius'] : "";
1893 -
1894 - $button_pt = isset($cta_btn_style['button_pt']) ? $cta_btn_style['button_pt'] : "";
1895 - $button_pr = isset($cta_btn_style['button_pr']) ? $cta_btn_style['button_pr'] : "";
1896 - $button_pb = isset($cta_btn_style['button_pb']) ? $cta_btn_style['button_pb'] : "";
1897 - $button_pl = isset($cta_btn_style['button_pl']) ? $cta_btn_style['button_pl'] : "";
1898 -
1899 - if ($button_open_new_tab == 'on') {
1900 - $target = '_blank';
1901 - }
1902 - $style = 'background-color: ' . esc_attr( $background_color ) . ';
1903 - color: ' . esc_attr( $color ) . ';
1904 - font-size: ' . esc_attr( $font_size ) . 'px;
1905 - font-weight: ' . esc_attr( $font_weight ) . ';
1906 - text-align: center;
1907 - display: inline-block;
1908 - text-transform: ' . esc_attr( $text_transform ) . ';
1909 - font-style: ' . esc_attr( $font_style ) . ';
1910 - text-decoration: ' . esc_attr( $text_decoration ) . ';
1911 - line-height: ' . esc_attr( $line_height ) . ';
1912 - letter-spacing: ' . esc_attr( $letter_spacing ) . 'px;
1913 - word-spacing: ' . esc_attr( $word_spacing ) . 'px;
1914 - border: ' . esc_attr( $border_width ) . 'px ' . esc_attr( $border_style ) . ' ' . esc_attr( $border_color ) . ';
1915 - border-radius: ' . esc_attr( $border_radius ). 'px;
1916 - padding: ' . esc_attr( $button_pt ) . 'px ' . esc_attr( $button_pr ) . 'px ' . esc_attr( $button_pb ) . 'px ' . esc_attr( $button_pl ) . 'px;
1917 - ';
1918 - $html .= '<div class="wpvr-call-to-action-button position-' . esc_attr( $text_align ) . '" style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '">
1919 - <a href="' . esc_url( $buttonurl ) . '" style="' . esc_attr( $style ) . '" target="' . esc_attr( $target ) . '">' . esc_attr( $buttontext ) . '</a>
1920 - </div>';
366 + if ( is_array( $tour_ids ) ) {
367 + return $tour_ids;
1921 368 }
1922 - }
1923 369
1924 - //script started
370 + $tour_ids = array();
371 + $posts = get_posts( array(
372 + 'post_type' => 'wpvr_item',
373 + 'post_status' => 'any',
374 + 'posts_per_page' => -1,
375 + 'fields' => 'ids',
376 + 'no_found_rows' => true,
377 + 'update_post_meta_cache' => true,
378 + 'update_post_term_cache' => false,
379 + ) );
1925 380
1926 - $html .= '<script>';
1927 - if (isset($postdata['bg_music']) && $bg_music == 'on') {
1928 - $html .= '
1929 - var x' . $id . ' = document.getElementById("vrAudio' . $id . '");
1930 - var playing' . $id . ' = false;
1931 - var autoplaySupported' . $id . ' = false;
1932 - var alertShown' . $id . ' = false;
1933 - var autoplayChecked' . $id . ' = false;
1934 -
1935 - function playPause' . $id . '() {
1936 - if (playing' . $id . ') {
1937 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
1938 - x' . $id . '.pause();
1939 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
1940 - playing' . $id . ' = false;
1941 - } else {
1942 - x' . $id . '.muted = false;
1943 - x' . $id . '.play().then(function() {
1944 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
1945 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
1946 - playing' . $id . ' = true;
1947 - }).catch(function(e) {
1948 - console.log("Play failed:", e);
1949 - });
1950 - }
381 + foreach ( $posts as $tour_id ) {
382 + $postdata = get_post_meta( (int) $tour_id, 'panodata', true );
383 + if ( wpvr_tour_uses_pro_features( $postdata ) ) {
384 + $tour_ids[] = (int) $tour_id;
1951 385 }
1952 -
1953 - function audionEnd' . $id . '() {
1954 - playing' . $id . ' = false;
1955 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
1956 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
1957 - }
1958 -
1959 - x' . $id . '.addEventListener("ended", audionEnd' . $id . ');';
1960 -
1961 - if ($autoplay_bg_music == 'on') {
1962 - $html .= '
1963 -
1964 - x' . $id . '.addEventListener("loadeddata", function() {
1965 - if (!autoplayChecked' . $id . ') {
1966 - checkAutoplayStatus' . $id . '();
1967 - }
1968 - });
1969 -
1970 - x' . $id . '.addEventListener("canplay", function() {
1971 - if (!autoplayChecked' . $id . ') {
1972 - checkAutoplayStatus' . $id . '();
1973 - }
1974 - });
1975 -
1976 - x' . $id . '.addEventListener("canplaythrough", function() {
1977 - if (!autoplayChecked' . $id . ') {
1978 - checkAutoplayStatus' . $id . '();
1979 - }
1980 - });
1981 -
1982 - setTimeout(function() {
1983 - if (!autoplayChecked' . $id . ') {
1984 - checkAutoplayStatus' . $id . '();
1985 - }
1986 - }, 1000);
1987 -
1988 - x' . $id . '.addEventListener("play", function() {
1989 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
1990 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
1991 - playing' . $id . ' = true;
1992 - });
1993 -
1994 - x' . $id . '.addEventListener("pause", function() {
1995 - if (!playing' . $id . ') {
1996 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
1997 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
1998 - }
1999 - });
2000 -
2001 - function checkAutoplayStatus' . $id . '() {
2002 - autoplayChecked' . $id . ' = true;
2003 -
2004 - x' . $id . '.muted = true;
2005 - var playPromise = x' . $id . '.play();
2006 -
2007 - if (playPromise !== undefined) {
2008 - playPromise.then(function () {
2009 - if (x' . $id . '.muted || x' . $id . '.volume === 0) {
2010 - handleAutoplayBlocked' . $id . '();
2011 - } else {
2012 - autoplaySupported' . $id . ' = true;
2013 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2014 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2015 - playing' . $id . ' = true;
2016 - }
2017 - }).catch(function () {
2018 - handleAutoplayBlocked' . $id . '();
2019 - });
2020 - } else {
2021 - setTimeout(function () {
2022 - if (x' . $id . '.paused || x' . $id . '.currentTime === 0) {
2023 - handleAutoplayBlocked' . $id . '();
2024 - } else {
2025 - autoplaySupported' . $id . ' = true;
2026 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2027 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2028 - playing' . $id . ' = true;
2029 - }
2030 - }, 300);
2031 - }
2032 - }
2033 -
2034 - function handleAutoplayBlocked' . $id . '() {
2035 - autoplaySupported' . $id . ' = false;
2036 - if (!alertShown' . $id . ') {
2037 - alert("Autoplay is not supported in your browser. Please click the audio button to play music.");
2038 - alertShown' . $id . ' = true;
2039 - }
2040 -
2041 - x' . $id . '.pause();
2042 - x' . $id . '.currentTime = 0;
2043 - x' . $id . '.muted = true;
2044 -
2045 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2046 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
2047 -
2048 - document.getElementById("pano' . $id . '").addEventListener("click", musicPlay' . $id . ');
2049 - document.addEventListener("touchstart", musicPlay' . $id . ', { once: true });
2050 - document.addEventListener("click", musicPlay' . $id . ', { once: true });
2051 - }
2052 -
2053 - function musicPlay' . $id . '() {
2054 - x' . $id . '.muted = false;
2055 - var playPromise = x' . $id . '.play();
2056 -
2057 - if (playPromise !== undefined) {
2058 - playPromise.then(function () {
2059 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2060 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2061 - playing' . $id . ' = true;
2062 - }).catch(function(e) {
2063 - console.log("Play failed:", e);
2064 - });
2065 - } else {
2066 - setTimeout(function () {
2067 - if (!x' . $id . '.paused) {
2068 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2069 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2070 - playing' . $id . ' = true;
2071 - }
2072 - }, 100);
2073 - }
2074 -
2075 - document.getElementById("pano' . $id . '").removeEventListener("click", musicPlay' . $id . ');
2076 - document.removeEventListener("touchstart", musicPlay' . $id . ');
2077 - document.removeEventListener("click", musicPlay' . $id . ');
2078 - }
2079 - ';
2080 386 }
2081 - }
2082 - $html .= 'jQuery(document).ready(function() {';
2083 - $html .= 'var response = ' . $response . ';';
2084 - $html .= 'var scenes = response[1];';
2085 - $html .= 'if(scenes) {';
2086 - $html .= 'var scenedata = scenes.scenes;';
2087 - $html .= 'for(var i in scenedata) {';
2088 - $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2089 - $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2090 - $html .= 'if(scenehotspot[i].type === "info") {';
2091 - $html .= ' scenehotspot[i]["clickHandlerFunc"] = wpvrhotspot;';
2092 - $html .= '} else if(scenehotspot[i].type === "scene") {';
2093 - $html .= ' scenehotspot[i]["clickHandlerArgs"] = scenehotspot[i]["text"];';
2094 - $html .='if(wpvr_public.is_pro_active) {';
2095 - $html .= ' scenehotspot[i]["clickHandlerFunc"] = wpvrhotspotscene;';
2096 - $html .='}';
2097 - $html .= '}';
2098 - if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2099 - } else {
2100 - $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2101 - $html .= 'scenehotspot[i]["createTooltipFunc"] = wpvrtooltip;';
2102 - $html .= '}';
2103 - }
2104 - $html .= '}';
2105 - $html .= '}';
2106 - $html .= '}';
2107 - $html .= 'var panoshow' . $id . ' = pannellum.viewer(response[0]["panoid"], scenes);';
2108 387
2109 -
2110 - //===Dplicate mode only for vr mode===//
2111 - $response2 = json_decode($response);
2112 - $response2[1]->compass = false;
2113 - $response2[1]->autoRotate = false;
2114 - $response = json_encode($response2);
2115 - $html .= 'var response_duplicate = ' . $response . ';';
2116 - $html .= 'var scenes_duplicate = response_duplicate[1];';
2117 -
2118 - $html .= 'if(scenes_duplicate) {';
2119 - $html .= 'var scenedata = scenes_duplicate.scenes;';
2120 - $html .= 'for(var i in scenedata) {';
2121 - $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2122 - $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2123 - $html .= 'if(scenehotspot[i]["clickHandlerArgs"] != "") {';
2124 - $html .= 'scenehotspot[i]["clickHandlerFunc"] = wpvrhotspot;';
2125 - $html .= '}';
2126 - if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2127 - } else {
2128 - $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2129 - $html .= 'scenehotspot[i]["createTooltipFunc"] = wpvrtooltip;';
2130 - $html .= '}';
388 + return $tour_ids;
2131 389 }
2132 - $html .= '}';
2133 - $html .= '}';
2134 - $html .= '}';
2135 - $html .= 'var vr_mode = "off";';
2136 - $status = get_option('wpvr_edd_license_status');
2137 - if ($status !== false && 'valid' == $status && $is_pro) {
2138 - $html .= 'var panoshow2' . $id . ' = pannellum.viewer("pano2' . $id . '", scenes_duplicate);';
390 +}
2139 391
2140 - // Show Cardboard Mode in Tour
2141 - $html .= '
2142 - var tim;
2143 - var im = 0;
2144 - var active_scene = "' . $default_scene . '";
2145 - var c_time;
2146 - c_time = new Date();
2147 - var timer = c_time.getTime() + 2000;
2148 - function panoShowCardBoardOnTrigger(data){
2149 - if(scenes_duplicate) {
2150 - var scenedata = scenes_duplicate.scenes;
2151 - for(var i in scenedata) {
2152 - if(active_scene === i) {
2153 - var scenehotspot = scenedata[i].hotSpots;
2154 - for(var j in scenehotspot) {
2155 - var plusFiveYaw = Math.round(scenehotspot[j].yaw) + 5;
2156 - var minusFiveYaw = Math.round(scenehotspot[j].yaw) - 5;
2157 - var plusFivePitch = Math.round(scenehotspot[j].pitch) + 5;
2158 - var minusFivePitch = Math.round(scenehotspot[j].pitch) - 5;
2159 - var firstCondition = ( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ;
2160 - var secCondition = (Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw);
2161 - if(( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ){
2162 - if((Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw)){
2163 - jQuery(".center-pointer").addClass("wpvr-pluse-effect")
2164 - var getScene = scenehotspot[j].sceneId;
2165 - if(scenehotspot[j].type == "scene"){
2166 - panoshow' . $id . '.loadScene(getScene);
2167 - panoshow2' . $id . '.loadScene(getScene);
2168 -// var inside_current_time_object = new Date();
2169 -// var inside_timer = inside_current_time_object.getTime();
2170 -// if(inside_timer > timer) {
2171 -// panoshow' . $id . '.loadScene(getScene);
2172 -// panoshow2' . $id . '.loadScene(getScene);
2173 -// jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2174 -// }
2175 - }else{
2176 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2177 - }
2178 - }
2179 - else {
2180 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2181 - c_time = new Date();
2182 - timer = c_time.getTime() + 2000;
2183 - }
2184 - }
2185 - else {
2186 - c_time = new Date();
2187 - timer = c_time.getTime() + 2000;
2188 - }
2189 - }
2190 - }
2191 - }
2192 - }
2193 - };
2194 -
2195 - function vrDeviseOrientation(){
2196 - var data = {
2197 - pitch: panoshow' . $id . '.getPitch(),
2198 - yaw: panoshow' . $id . '.getYaw(),
2199 - };
2200 - panoShowCardBoardOnTrigger(data);
2201 - }
2202 - ';
2203 - $html .= '
2204 -
2205 - function requestFullScreen(){
2206 - var elem = document.getElementById("master-container");
2207 - if (elem.requestFullscreen) {
2208 - elem.requestFullscreen();
2209 - } else if (elem.webkitRequestFullscreen) { /* Safari */
2210 - elem.webkitRequestFullscreen();
2211 - } else if (elem.msRequestFullscreen) { /* IE11 */
2212 - elem.msRequestFullscreen();
2213 - }
2214 - }
2215 - function requestExitFullscreen(){
2216 - var elem = document.getElementById("master-container");
2217 - if (document.exitFullscreen) {
2218 - document.exitFullscreen();
2219 - } else if (document.webkitExitFullscreen) { /* Safari */
2220 - document.webkitExitFullscreen();
2221 - } else if (document.msExitFullscreen) { /* IE11 */
2222 - document.msExitFullscreen();
2223 - }
2224 - }
2225 - jQuery(document).on("click",".fullscreen-button .expand",function() {
2226 - jQuery(this).hide()
2227 - jQuery(this).parent().find(".compress").show()
2228 - requestFullScreen()
2229 - screen.orientation.lock("landscape-primary")
2230 - .then(function() {
2231 - })
2232 - .catch(function(error) {
2233 - alert("Not Supported for this devise");
2234 - });
2235 -
2236 - });
2237 - jQuery(document).on("click",".fullscreen-button .compress",function() {
2238 - jQuery(this).hide()
2239 - jQuery(this).parent().find(".expand").show()
2240 - requestExitFullscreen()
2241 - screen.orientation.unlock();
2242 -
2243 - });
2244 -
2245 - let onLoadAnalytics = false;
2246 - let sceneLoadAnalytics = false;
2247 - function storeAnalyticsData(data) {
2248 - if(wpvr_public.is_pro_active) {
2249 - jQuery.ajax({
2250 - url: wpvrAnalyticsObj.ajaxUrl,
2251 - type: "POST",
2252 - data: {
2253 - action: "store_scene_hotspot_data",
2254 - scene_id: data.scene_id,
2255 - tour_id: data.tour_id,
2256 - type: data.type,
2257 - hotspot_id: data.hotspot_id || "",
2258 - user_agent: navigator.userAgent,
2259 - device_type: getDeviceType() || "desktop",
2260 - nonce: wpvrAnalyticsObj.nonce,
2261 - },
2262 - success: function (response) {
2263 - console.log("Data stored successfully");
2264 - },
2265 - error: function (error) {
2266 - console.log("Error in storing data");
2267 - }
2268 - });
2269 - }
2270 - }
2271 -
2272 - function getDeviceType() {
2273 - const userAgent = navigator.userAgent.toLowerCase();
2274 -
2275 - if (/mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)) {
2276 - return "mobile";
2277 - } else if (/tablet|ipad/i.test(userAgent)) {
2278 - return "tablet";
2279 - } else {
2280 - return "desktop";
2281 - }
2282 - }
2283 -
2284 - panoshow' . $id . '.on("scenechange", function(scene) {
2285 - onLoadAnalytics = true;
2286 - sceneLoadAnalytics = true;
2287 - let scene_id = scene;
2288 - let tour_id = ' . $id . ';
2289 - let type = "scene";
2290 - let hotspot_id = "";
2291 - let user_agent = navigator.userAgent;
2292 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2293 - storeAnalyticsData({
2294 - scene_id: scene_id,
2295 - tour_id: tour_id,
2296 - type: type,
2297 - hotspot_id: hotspot_id,
2298 - user_agent: user_agent,
2299 - device_type: device_type,
2300 - });
2301 - });
2302 -
2303 - panoshow' . $id . '.on("load", function() {
2304 - let scene_id = panoshow' . $id . '.getScene();
2305 - let tour_id = ' . $id . ';
2306 - let type = "scene";
2307 - let hotspot_id = "";
2308 - let user_agent = navigator.userAgent;
2309 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2310 - if(!onLoadAnalytics && !sceneLoadAnalytics){
2311 - storeAnalyticsData({
2312 - scene_id: scene_id,
2313 - tour_id: tour_id,
2314 - type: type,
2315 - hotspot_id: hotspot_id,
2316 - user_agent: user_agent,
2317 - device_type: device_type,
2318 - });
2319 - }
2320 - })
2321 -
2322 - function wpvrhotspotscene(hotSpotDiv, args) {
2323 - onLoadAnalytics = true;
2324 - let scene_id = panoshow' . $id . '.getScene();
2325 - let tour_id = ' . $id . ';
2326 - let type = "hotspot";
2327 - let hotspot_id = args;
2328 - let user_agent = navigator.userAgent;
2329 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2330 - storeAnalyticsData({
2331 - scene_id: scene_id,
2332 - tour_id: tour_id,
2333 - type: type,
2334 - hotspot_id: hotspot_id,
2335 - user_agent: user_agent,
2336 - device_type: device_type
2337 - });
2338 - }
2339 -
2340 - ';
2341 -
2342 - $html .= '
2343 - panoshow' . $id . '.on("scenechange", function (scene){
2344 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2345 - active_scene = scene;
2346 - });
2347 - var compassBlock = "";
2348 - var infoBlock = "";
2349 - var getValue = "";
2350 - jQuery(document).on("click",".vr_mode_change' . $id . '",function (){
2351 -
2352 - jQuery("#pano2' . $id . ' .pnlm-load-button").trigger("click");
2353 - jQuery("#pano' . $id . ' .pnlm-load-button").trigger("click");
2354 -
2355 - getValue = jQuery(this).val();
2356 - var getParent = jQuery(this).parent().parent();
2357 - var fullWidthParent = getParent.parent();
2358 - var compass = getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display");
2359 - var panoInfo = getParent.find("#pano' . $id . ' .pnlm-panorama-info").css("display");
2360 - if(compass == "block"){
2361 - compassBlock = "block";
2362 - }
2363 - if(panoInfo == "block"){
2364 - infoBlock = "block";
2365 - }
2366 - if (getValue == "off") {
2367 - requestFullScreen()
2368 - screen.orientation.lock("landscape-primary")
2369 - .then(function() {
2370 - })
2371 - .catch(function(error) {
2372 - alert("VR Glass Mode not supported in this device");
2373 - });
2374 - getParent.find(".pano-wrap").addClass("wpvr-cardboard-disable-event");
2375 - // localStorage.setItem("vr_mode", "on");
2376 - vr_mode = "on";
2377 - jQuery(".vr-mode-title").show();
2378 - jQuery(this).val("on");
2379 - getParent.find("#pano2' . $id . '").css({
2380 - "opacity": "1",
2381 - "visibility": "visible",
2382 - "position": "relative",
2383 - });
2384 - gyroSwitch = true;
2385 - panoshow' . $id . '.startOrientation();
2386 - panoshow2' . $id . '.startOrientation();
2387 - panoshow2' . $id . '.setPitch(panoshow' . $id . '.getPitch(), 0);
2388 - panoshow2' . $id . '.setYaw(panoshow' . $id . '.getYaw(), 0);
2389 - getParent.find("#pano' . $id . ' #zoom-in-out-controls' . $id . '").hide();
2390 - getParent.find("#pano' . $id . ' #controls' . $id . '").hide();
2391 - getParent.find("#pano' . $id . ' #explainer_button_' . $id . '").hide();
2392 - getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").hide();
2393 - getParent.find("#pano' . $id . ' #floor_map_button_' . $id . '").hide();
2394 - getParent.find("#pano' . $id . ' #vrgcontrols' . $id . '").hide();
2395 - getParent.find("#pano' . $id . ' #sccontrols' . $id . '").hide();
2396 - getParent.find("#pano' . $id . ' #adcontrol' . $id . '").hide();
2397 - getParent.find("#pano' . $id . ' .owl-nav.wpvr_slider_nav").hide();
2398 - getParent.find("#pano' . $id . ' #cp-logo-controls").hide();
2399 -
2400 - getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").hide();
2401 -
2402 - getParent.find("#pano2' . $id . ' .pnlm-controls-container").hide();
2403 - getParent.find("#pano' . $id . ' .pnlm-controls-container").hide();
2404 -
2405 - getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
2406 - getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
2407 -
2408 - getParent.find("#pano2' . $id . ' .pnlm-panorama-info").hide();
2409 - getParent.find("#pano' . $id . ' .pnlm-panorama-info").hide();
2410 - getParent.find("#pano' . $id . '").addClass("cardboard-half");
2411 -
2412 - getParent.find("#center-pointer' . $id . '").show();
2413 - getParent.find(".fullscreen-button").hide();
2414 -
2415 -
2416 - if (window.DeviceOrientationEvent) {
2417 - window.addEventListener("deviceorientation", vrDeviseOrientation);
2418 - }
2419 -
2420 - panoshow' . $id . '.on("mousemove", function (data){
2421 - panoshow2' . $id . '.setPitch(data.pitch, 0);
2422 - panoshow2' . $id . '.setYaw(data.yaw, 0);
2423 - panoShowCardBoardOnTrigger(data);
2424 -
2425 - });
2426 - panoshow2' . $id . '.on("mousemove", function (data){
2427 - panoshow2' . $id . '.setPitch(data.pitch, 0);
2428 - panoshow' . $id . '.setYaw(data.yaw, 0);
2429 - panoShowCardBoardOnTrigger(data);
2430 -
2431 - });
2432 -
2433 - panoshow' . $id . '.on("zoomchange", function (data){
2434 - panoshow2' . $id . '.setHfov(data, 0);
2435 - });
2436 -
2437 - panoshow2' . $id . '.on("zoomchange", function (data){
2438 - panoshow' . $id . '.setHfov(data, 0);
2439 - });
2440 -
2441 - panoshow' . $id . '.on("touchmove", function (data){
2442 - panoshow' . $id . '.stopOrientation();
2443 - panoshow2' . $id . '.stopOrientation();
2444 - panoshow2' . $id . '.setPitch(data.pitch, 0);
2445 - panoshow2' . $id . '.setYaw(data.yaw, 0);
2446 - panoShowCardBoardOnTrigger(data);
2447 -
2448 - });
2449 -
2450 - panoshow2' . $id . '.on("touchmove", function (data){
2451 - panoshow' . $id . '.stopOrientation();
2452 - panoshow2' . $id . '.stopOrientation();
2453 - panoshow' . $id . '.setPitch(data.pitch, 0);
2454 - panoshow' . $id . '.setYaw(data.yaw, 0);
2455 - panoShowCardBoardOnTrigger(data);
2456 -
2457 - });
2458 -
2459 - }
2460 - else if(getValue == "on") {
2461 - screen.orientation.unlock();
2462 - requestExitFullscreen();
2463 - // localStorage.setItem("vr_mode", "off");
2464 - vr_mode = "off";
2465 - jQuery(".vr-mode-title").hide();
2466 - jQuery(this).val("off");
2467 - getParent.find("#pano2' . $id . '").css({
2468 - "opacity": "0",
2469 - "visibility": "hidden",
2470 - "position": "absolute",
2471 - });
2472 - panoshow' . $id . '.stopOrientation();
2473 - panoshow2' . $id . '.stopOrientation();
2474 - getParent.find(".pano-wrap").removeClass("wpvr-cardboard-disable-event");
2475 - getParent.find("#pano' . $id . ' #zoom-in-out-controls' . $id . '").show();
2476 - getParent.find("#pano' . $id . ' #controls' . $id . '").show();
2477 - getParent.find("#pano' . $id . ' #explainer_button_' . $id . '").show();
2478 - getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").show();
2479 - getParent.find("#pano' . $id . ' #floor_map_button_' . $id . '").show();
2480 -
2481 - getParent.find("#pano2' . $id . ' .pnlm-controls-container").show();
2482 - getParent.find("#pano' . $id . ' .pnlm-controls-container").show();
2483 - getParent.find("#pano' . $id . ' #vrgcontrols' . $id . '").show();
2484 - getParent.find("#pano' . $id . ' #sccontrols' . $id . '").hide();
2485 - getParent.find("#pano' . $id . ' #adcontrol' . $id . '").show();
2486 - getParent.find("#pano' . $id . ' .owl-nav.wpvr_slider_nav").hide();
2487 - getParent.find("#pano' . $id . ' #cp-logo-controls").show();
2488 - getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").show();
2489 -
2490 - if(compassBlock == "block"){
2491 - getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
2492 - getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
2493 - }
2494 - if(infoBlock == "block"){
2495 - getParent.find("#pano2' . $id . ' .pnlm-panorama-info").show();
2496 - getParent.find("#pano' . $id . ' .pnlm-panorama-info").show();
2497 - }
2498 -
2499 - getParent.find("#pano' . $id . '").removeClass("cardboard-half");
2500 - getParent.find("#center-pointer' . $id . '").hide();
2501 - getParent.find(".fullscreen-button").hide();
2502 - panoshow' . $id . '.off("mousemove");
2503 - panoshow' . $id . '.off("touchmove");
2504 - panoshow2' . $id . '.off("mousemove");
2505 - panoshow2' . $id . '.off("touchmove");
2506 - if (window.DeviceOrientationEvent) {
2507 - window.removeEventListener("deviceorientation", vrDeviseOrientation);
2508 - }
2509 - }
2510 - });';
2511 -
2512 - $html .= 'panoshow2' . $id . '.on("load", function (){
2513 -// if(localStorage.getItem("vr_mode") == "off") {
2514 - if( vr_mode == "off") {
2515 - jQuery(".vr-mode-title").hide();
2516 - }
2517 - else {
2518 - jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2519 - jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2520 - jQuery("#pano2' . $id . ' .pnlm-panorama-info").hide();
2521 - jQuery("#pano' . $id . ' .pnlm-panorama-info").hide();
2522 - jQuery(".vr-mode-title").show();
2523 - }
2524 - });';
392 +if ( ! function_exists( 'wpvr_has_pro_feature_tours' ) ) {
393 + function wpvr_has_pro_feature_tours() {
394 + return ! empty( wpvr_get_pro_feature_tour_ids() );
2525 395 }
396 +}
2526 397
2527 - $html .= 'jQuery("#pano' . $id . ' .wpvr-floor-map .floor-plan-pointer").on("click",function(){
2528 - var scene_id = jQuery(this).attr("scene_id");
2529 - panoshow' . $id . '.loadScene(scene_id)
2530 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
2531 - jQuery(this).addClass("add-pulse")
2532 - });';
2533 -
2534 - if ($scene_animation == 'on') {
2535 - $animation_js = apply_filters('wpvr_scene_animation_js', $id, $animation_type, $animationDuration, $animationDelay);
2536 - if (!empty($animation_js)) {
2537 - $html .= $animation_js;
2538 - $html .= 'panoshow' . $id . '.on("load", function (scene){
2539 - if (typeof changeScene === "function") {
2540 - changeScene();
2541 - } else {
2542 - console.warn("changeScene function is not defined.");
2543 - }
2544 - });';
398 +if ( ! function_exists( 'wpvr_enqueue_license_notice_assets' ) ) {
399 + /**
400 + * Enqueue the global license notice styles while Pro is installed and inactive.
401 + *
402 + * @return void
403 + */
404 + function wpvr_enqueue_license_notice_assets() {
405 + if (
406 + ! is_admin()
407 + || ! defined( 'WPVR_PRO_VERSION' )
408 + || wpvr_is_pro_active()
409 + ) {
410 + return;
2545 411 }
2546 - }
2547 412
2548 -
2549 - $html .= '
2550 - panoshow' . $id . '.on("mousemove", function (data){
2551 - jQuery(".add-pulse").css({"transform":"rotate("+data.yaw+"deg)"});
2552 - });
2553 -';
2554 -
2555 -
2556 -
2557 - $status = get_option('wpvr_edd_license_status');
2558 - if ($status !== false && 'valid' == $status && $is_pro) {
2559 - $html .= 'panoshow' . $id . '.on("scenechange", function (scene){
2560 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2561 - jQuery(".floor-plan-pointer").each(function(index ,element){
2562 - var scene_id = jQuery(this).attr("scene_id");
2563 - if( active_scene == scene_id ){
2564 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
2565 - jQuery(this).addClass("add-pulse")
2566 - }
2567 - });
2568 -
2569 - });';
2570 - $html .= 'panoshow' . $id . '.on("load", function (){
2571 - if(jQuery(".floor-plan-pointer").length > 0){
2572 - jQuery(".floor-plan-pointer").each(function(index ,element){
2573 - var scene_id = jQuery(this).attr("scene_id");
2574 - if( active_scene == scene_id ){
2575 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
2576 - jQuery(this).addClass("add-pulse")
2577 - }
2578 - });
2579 - }
2580 - });';
413 + wp_enqueue_style(
414 + 'wpvr-license-notice-fontawesome',
415 + WPVR_PLUGIN_DIR_URL . 'admin/lib/fontawesome/css/all.css',
416 + array(),
417 + WPVR_VERSION
418 + );
419 + wp_enqueue_style(
420 + 'wpvr-license-notice',
421 + WPVR_PLUGIN_DIR_URL . 'admin/css/wpvr-license-notice.css',
422 + array( 'wpvr-license-notice-fontawesome' ),
423 + WPVR_VERSION
424 + );
425 + wp_enqueue_script(
426 + 'wpvr-license-notice',
427 + WPVR_PLUGIN_DIR_URL . 'admin/js/wpvr-license-notice.js',
428 + array(),
429 + WPVR_VERSION,
430 + true
431 + );
2581 432 }
433 +}
2582 434
2583 - if ($status !== false && 'valid' == $status && $is_pro) {
2584 - $scene_navigation_content_type = isset($postdata['scene_navigation_content_type']) ? $postdata['scene_navigation_content_type'] : 'scene_id';
2585 - $html .= '
2586 - jQuery("#pano' . $id . ' .custom-scene-navigation").on("click",function(){
2587 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").empty()
2588 - if(scenes){
2589 - var scene_navigation_content_type = ' . "'" . $scene_navigation_content_type . "'" . ';
2590 - var sceneList = scenes.scenes;
2591 - var getScene = panoshow' . $id . '.getScene();
2592 - for (const key in sceneList) {
2593 - let title;
2594 - if (scene_navigation_content_type === "scene_title") {
2595 - if (sceneList[key].title) {
2596 - title = sceneList[key].title;
2597 -
2598 - }else{
2599 - if(title == "" || title == undefined){
2600 - if (sceneList[key].panorama) {
2601 - title = getImageNameWithoutExtension(sceneList[key].panorama);
2602 - }
2603 - }
2604 - }
2605 - } else if (scene_navigation_content_type === "scene_image_name") {
2606 - if (sceneList[key].panorama) {
2607 - title = getImageNameWithoutExtension(sceneList[key].panorama);
2608 - }
2609 - } else {
2610 - title = key;
2611 - }
2612 - if (sceneList.hasOwnProperty(key)) {
2613 - if( key === getScene){
2614 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").append("<li class=\"scene-navigation-list active\" scene_id= " + key + " >" + title + "</li>");
2615 - }else{
2616 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").append("<li class=\"scene-navigation-list\" scene_id= " + key + " >" + title + "</li>");
2617 - }
2618 - }
2619 - }
2620 - }
2621 - jQuery("#custom-scene-navigation-nav' . $id . '").toggleClass("visible");
2622 - });
2623 - ';
435 +add_action( 'admin_enqueue_scripts', 'wpvr_enqueue_license_notice_assets', 10 );
2624 436
2625 - $html .= 'function getImageNameWithoutExtension(imageUrl) {
2626 - // Split the URL by "/"
2627 - var parts = imageUrl.split("/");
2628 -
2629 - // Get the last part which contains the image name
2630 - var imageNameWithExtension = parts[parts.length - 1];
2631 -
2632 - // Split the image name by period (.)
2633 - var imageNameParts = imageNameWithExtension.split(".");
2634 -
2635 - // Remove the last part (which is the extension) and join the remaining parts
2636 - var imageNameWithoutExtension = imageNameParts.slice(0, -1).join(".");
2637 -
2638 - // Return the image name without extension
2639 - return imageNameWithoutExtension;
2640 - }';
2641 -
2642 -
2643 - $html .= '
2644 - jQuery("#pano' . $id . ' #custom-scene-navigation-nav' . $id . ' ul").on("click", "li.scene-navigation-list", function() {
2645 - if (scenes) {
2646 - jQuery(this).siblings("li").removeClass("active");
2647 - jQuery(this).addClass("active");
2648 -
2649 - var scene_key = jQuery(this).attr("scene_id");
2650 - panoshow' . $id . '.loadScene(scene_key);
2651 - }
2652 - });
2653 - ';
2654 - }
2655 -
2656 - //Duplicate mode only for vr mode end===//
2657 - $html .= 'panoshow' . $id . '.on("load", function (){
2658 -
2659 -// if(localStorage.getItem("vr_mode") == "off") {
2660 - if( vr_mode == "off") {
2661 - jQuery(".vr-mode-title").hide();
2662 - }
2663 - else {
2664 - jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2665 - jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2666 - jQuery("#pano2' . $id . ' .pnlm-panorama-info").hide();
2667 - jQuery("#pano' . $id . ' .pnlm-panorama-info").hide();
2668 - jQuery(".vr-mode-title").show();
2669 - }
2670 -
2671 -
2672 - if (jQuery("#pano' . $id . '").children().children(".pnlm-panorama-info:visible").length > 0) {
2673 - jQuery("#controls' . $id . '").css("bottom", "55px");
2674 - }
2675 - else {
2676 - jQuery("#controls' . $id . '").css("bottom", "5px");
2677 - }
2678 - });';
2679 -
2680 -
2681 - $html .= '
2682 - if (scenes.autoRotate) {
2683 - panoshow' . $id . '.on("load", function (){
2684 - setTimeout(function(){ panoshow' . $id . '.startAutoRotate(scenes.autoRotate, 0); }, 3000);
2685 - });
2686 - panoshow' . $id . '.on("scenechange", function (){
2687 - setTimeout(function(){ panoshow' . $id . '.startAutoRotate(scenes.autoRotate, 0); }, 3000);
2688 - });
437 +if ( ! function_exists( 'wpvr_render_pro_feature_fallback_notice' ) ) {
438 + /**
439 + * Render the global Pro license notice and explain the saved-tour fallback.
440 + *
441 + * @return void
442 + */
443 + function wpvr_render_pro_feature_fallback_notice() {
444 + if (
445 + ! is_admin()
446 + || ! current_user_can( 'edit_posts' )
447 + || ! defined( 'WPVR_PRO_VERSION' )
448 + || wpvr_is_pro_active()
449 + ) {
450 + return;
2689 451 }
2690 - ';
2691 - $html .= 'var touchtime = 0;';
2692 - if ($vrgallery) {
2693 - if (isset($panodata["scene-list"])) {
2694 - foreach ($panodata["scene-list"] as $panoscenes) {
2695 - $scene_key = $panoscenes['scene-id'];
2696 - $scene_key_gallery = $panoscenes['scene-id'] . '_gallery_' . $id;
2697 - $img_src_url = $panoscenes['scene-attachment-url'];
2698 - // $html .= 'document.getElementById("' . $scene_key_gallery . '").addEventListener("click", function(e) { ';
2699 - // $html .= 'if (touchtime == 0) {';
2700 - // $html .= 'touchtime = new Date().getTime();';
2701 - // $html .= '} else {';
2702 - // $html .= 'if (((new Date().getTime()) - touchtime) < 800) {';
2703 - // $html .= 'panoshow' . $id . '.loadScene("' . $scene_key . '");';
2704 - // $html .= 'touchtime = 0;';
2705 - // $html .= '} else {';
2706 - // $html .= 'touchtime = new Date().getTime();';
2707 - // $html .= '}';
2708 - // $html .= '}';
2709 - // $html .= '});';
2710 - $html .= '
2711 - jQuery(document).on("click","#' . $scene_key_gallery . '",function() {
2712 - panoshow' . $id . '.loadScene("' . $scene_key . '");
2713 - });
2714 - ';
2715 - }
2716 - }
2717 - }
2718 452
453 + $status = strtolower( (string) get_option( 'wpvr_edd_license_status', 'no' ) );
454 + $needs_activation = in_array( $status, array( '', 'no' ), true );
2719 455
2720 -
2721 - //===Custom Control===//
2722 - if (isset($custom_control)) {
2723 - if ($custom_control['panupSwitch'] == "on") {
2724 - $html .= 'document.getElementById("pan-up' . $id . '").addEventListener("click", function(e) {';
2725 - $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() + 10);';
2726 - $html .= '});';
456 + if ( ! $needs_activation && ! wpvr_has_pro_feature_tours() ) {
457 + return;
2727 458 }
2728 459
2729 - if ($custom_control['panDownSwitch'] == "on") {
2730 - $html .= 'document.getElementById("pan-down' . $id . '").addEventListener("click", function(e) {';
2731 - $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() - 10);';
2732 - $html .= '});';
2733 - }
2734 -
2735 - if ($custom_control['panLeftSwitch'] == "on") {
2736 - $html .= 'document.getElementById("pan-left' . $id . '").addEventListener("click", function(e) {';
2737 - $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() - 10);';
2738 - $html .= '});';
2739 - }
2740 -
2741 - if ($custom_control['panRightSwitch'] == "on") {
2742 - $html .= 'document.getElementById("pan-right' . $id . '").addEventListener("click", function(e) {';
2743 - $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() + 10);';
2744 - $html .= '});';
2745 - }
2746 -
2747 - if ($custom_control['panZoomInSwitch'] == "on") {
2748 - $html .= 'document.getElementById("zoom-in' . $id . '").addEventListener("click", function(e) {';
2749 - $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() - 10);';
2750 - $html .= '});';
2751 - }
2752 -
2753 - if ($custom_control['panZoomOutSwitch'] == "on") {
2754 - $html .= 'document.getElementById("zoom-out' . $id . '").addEventListener("click", function(e) {';
2755 - $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() + 10);';
2756 - $html .= '});';
2757 - }
2758 -
2759 - if ($custom_control['panFullscreenSwitch'] == "on") {
2760 - $html .= 'document.getElementById("fullscreen' . $id . '").addEventListener("click", function(e) {';
2761 - $html .= 'panoshow' . $id . '.toggleFullscreen();';
2762 - $html .= '});';
2763 - }
2764 -
2765 - if ($custom_control['backToHomeSwitch'] == "on") {
2766 - $html .= 'document.getElementById("backToHome' . $id . '").addEventListener("click", function(e) {';
2767 - $html .= 'panoshow' . $id . '.loadScene("' . $default_scene . '");';
2768 - $html .= '});';
2769 - }
2770 -
2771 - if ($custom_control['gyroscopeSwitch'] == "on") {
2772 - $html .= '
2773 - var element = document.getElementById("gyroscope' . $id . '");
2774 - var gyroSwitch = true;
2775 - var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
2776 - var permissionGranted = false;
2777 -
2778 - function requestOrientationPermission() {
2779 - if (isIOS) {
2780 - if (typeof DeviceOrientationEvent.requestPermission === "function") {
2781 - DeviceOrientationEvent.requestPermission()
2782 - .then(function(state) {
2783 - if (state === "granted") {
2784 - permissionGranted = true;
2785 - startOrientation();
2786 - } else {
2787 - element.children[0].style.color = "red";
2788 - gyroSwitch = false;
2789 - alert("Permission to use motion sensors was denied.");
2790 - }
2791 - })
2792 - .catch(function(error) {
2793 - element.children[0].style.color = "red";
2794 - gyroSwitch = false;
2795 - console.error("Error requesting device orientation permission:", error);
2796 - });
2797 - }
460 + if ( $needs_activation ) {
461 + $title = __( 'Please Activate your license key to enjoy the pro features for WPVR', 'wpvr' );
462 + $subtitle = '';
463 + $action_label = __( 'Activate', 'wpvr' );
464 + $action_url = admin_url( 'admin.php?page=wpvrpro' );
465 + $action_target = '';
466 + $action_icon = 'fa-key';
2798 467 } else {
2799 - startOrientation();
468 + $title = 'expired' === $status
469 + ? __( 'Your WPVR Pro license has expired.', 'wpvr' )
470 + : __( 'Your WPVR Pro license is not active.', 'wpvr' );
471 + $subtitle = __( 'Pro features are no longer available. Upgrade to Pro now to restore access to all premium features.', 'wpvr' );
472 + $action_label = __( 'Upgrade to Pro', 'wpvr' );
473 + $action_url = 'https://rextheme.com/your-account/#purchase';
474 + $action_target = ' target="_blank" rel="noopener noreferrer"';
475 + $action_icon = 'fa-crown';
2800 476 }
2801 - }
2802 477
2803 - function startOrientation() {
2804 - panoshow' . $id . '.startOrientation();
2805 - element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2806 - gyroSwitch = true;
2807 - }
2808 -
2809 - panoshow' . $id . '.on("load", function() {
2810 - if (!isIOS || permissionGranted) {
2811 - if (gyroSwitch) {
2812 - startOrientation();
2813 - } else {
2814 - panoshow' . $id . '.stopOrientation();
2815 - element.children[0].style.color = "red";
2816 - }
478 + $notice_classes = 'notice notice-error is-dismissible wpvr-license-fallback-notice';
479 + if ( '' === $subtitle ) {
480 + $notice_classes .= ' wpvr-license-fallback-notice--single-line';
2817 481 }
2818 - });
2819 482
2820 - panoshow' . $id . '.on("scenechange", function() {
2821 - if (!isIOS || permissionGranted) {
2822 - if (panoshow' . $id . '.isOrientationActive()) {
2823 - element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2824 - } else {
2825 - element.children[0].style.color = "red";
2826 - }
483 + echo '<div id="wpvr-license-fallback-notice" class="' . esc_attr( $notice_classes ) . '">';
484 + echo '<img class="wpvr-license-fallback-notice__icon" src="' . esc_url( WPVR_PLUGIN_DIR_URL . 'admin/images/wpvr-license-warning.svg' ) . '" width="20" height="19" alt="" aria-hidden="true">';
485 + echo '<div class="wpvr-license-fallback-notice__content">';
486 + echo '<p class="wpvr-license-fallback-notice__title">' . esc_html( $title ) . '</p>';
487 + if ( '' !== $subtitle ) {
488 + echo '<p class="wpvr-license-fallback-notice__subtitle">' . esc_html( $subtitle ) . '</p>';
2827 489 }
2828 - });
2829 -
2830 - panoshow' . $id . '.on("touchstart", function() {
2831 - if (!isIOS || permissionGranted) {
2832 - if (panoshow' . $id . '.isOrientationActive()) {
2833 - gyroSwitch = true;
2834 - element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2835 - } else {
2836 - gyroSwitch = false;
2837 - element.children[0].style.color = "red";
2838 - }
2839 - }
2840 - });';
2841 -
2842 - $html .= 'document.getElementById("gyroscope' . $id . '").addEventListener("click", function(e) {
2843 - var element = document.getElementById("gyroscope' . $id . '");
2844 - if (isIOS && typeof DeviceOrientationEvent.requestPermission === "function" && !permissionGranted) {
2845 - requestOrientationPermission();
2846 - } else {
2847 - if (panoshow' . $id . '.isOrientationActive()) {
2848 - panoshow' . $id . '.stopOrientation();
2849 - gyroSwitch = false;
2850 - element.children[0].style.color = "red";
2851 - } else {
2852 - startOrientation();
2853 - }
2854 - }
2855 - });';
2856 - }
490 + echo '</div>';
491 + echo '<a class="wpvr-license-fallback-notice__action" href="' . esc_url( $action_url ) . '"' . $action_target . '>';
492 + echo '<span class="wpvr-license-fallback-notice__action-icon fa-solid ' . esc_attr( $action_icon ) . '" aria-hidden="true"></span>';
493 + echo '<span>' . esc_html( $action_label ) . '</span>';
494 + echo '</a>';
495 + echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . esc_html__( 'Dismiss this notice.', 'wpvr' ) . '</span></button>';
496 + echo '</div>';
2857 497 }
498 +}
2858 499
2859 - $angle_up = '<i class="fa fa-angle-up"></i>';
2860 - $angle_down = '<i class="fa fa-angle-down"></i>';
2861 - $sin_qout = "'";
500 +add_action( 'admin_notices', 'wpvr_render_pro_feature_fallback_notice', 10 );
2862 501
2863 - //===Explainer Script===//
2864 - $html .= '
2865 - jQuery(document).on("click","#explainer_button_' . $id . '",function() {
2866 - jQuery("#explainer' . $id . '").slideToggle();
2867 - // jQuery(".explainer").slideToggle();
2868 - });
2869 -
2870 - jQuery(document).on("click",".close-explainer-video",function() {
2871 - jQuery(this).parent(".explainer").hide();
2872 - });
2873 - jQuery(document).on("click","#pano' . $id . '",function(event) {
2874 - var isActiveModal = event.target.closest(".custom-ifram-wrapper");
2875 - var isForm = event.target.closest(".wpvr-hotspot-tweak-contents");
2876 - if( isActiveModal == null && isForm == null){
2877 - jQuery(".custom-ifram-wrapper").hide();
2878 - jQuery(this).removeClass("show-modal");
2879 - jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide("show-modal");
2880 - }else if(isForm != null){
2881 - jQuery(this).addClass("show-modal");
502 +if ( ! function_exists( 'wpvr_add_pro_feature_tour_row_class' ) ) {
503 + /**
504 + * Add a class to affected tour rows while the Pro entitlement is inactive.
505 + *
506 + * @param array $classes Existing post classes.
507 + * @param array $class Additional classes supplied by WordPress.
508 + * @param int $post_id Post ID.
509 + * @return array
510 + */
511 + function wpvr_add_pro_feature_tour_row_class( $classes, $class = array(), $post_id = 0 ) {
512 + if (
513 + ! is_admin()
514 + || ! defined( 'WPVR_PRO_VERSION' )
515 + || wpvr_is_pro_active()
516 + || 'wpvr_item' !== get_post_type( $post_id )
517 + ) {
518 + return $classes;
2882 519 }
2883 - });
2884 520
2885 - ';
2886 - //===Explainer Script End===//
2887 -
2888 - //===generic form script===//
2889 - if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on') {
2890 - $html .= '
2891 - jQuery(document).on("click","#generic_form_button_' . $id . '",function() {
2892 - jQuery("#wpvr-generic-form' . $id . '").fadeToggle();
2893 - });
2894 -
2895 - jQuery(document).on("click",".close-generic-form",function() {
2896 - jQuery(this).parent(".wpvr-generic-form").fadeOut()
2897 - });
2898 - ';
2899 - }
2900 -
2901 - //===generic from script===//
2902 -
2903 - //===Floor map Script===//
2904 - $html .= '
2905 - jQuery(document).on("click","#floor_map_button_' . $id . '",function() {
2906 - jQuery("#wpvr-floor-map' . $id . '").toggle().removeClass("fullwindow");
2907 - });
2908 -
2909 - jQuery(document).on("dblclick","#wpvr-floor-map' . $id . '",function(){
2910 - jQuery(this).addClass("fullwindow");
2911 - jQuery(this).parents(".pano-wrap").addClass("show-modal");
2912 - });
2913 -
2914 - jQuery(document).on("click",".close-floor-map-plan",function() {
2915 - jQuery(this).parent(".wpvr-floor-map").hide();
2916 - jQuery(this).parent(".wpvr-floor-map").removeClass("fullwindow");
2917 - jQuery(this).parents(".pano-wrap").removeClass("show-modal");
2918 - });
2919 -
2920 - ';
2921 - //===Floor map Script End===//
2922 -
2923 - if ($vrgallery_display) {
2924 - if (!$autoload) {
2925 - $html .= '
2926 - jQuery(document).ready(function($){
2927 - jQuery("#sccontrols' . $id . '").hide();
2928 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2929 - jQuery("#sccontrols' . $id . '").hide();
2930 - jQuery(".wpvr_slider_nav").hide();
2931 - });
2932 - ';
2933 -
2934 - $html .= '
2935 - var slide' . $id . ' = "down";
2936 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
2937 -
2938 - if (slide' . $id . ' == "up") {
2939 - jQuery(".vrgctrl' . $id . '").empty();
2940 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2941 - slide' . $id . ' = "down";
2942 - jQuery(".wpvr_slider_nav").slideToggle();
2943 - jQuery("#sccontrols' . $id . '").slideToggle();
2944 - }
2945 - else {
2946 - jQuery(".vrgctrl' . $id . '").empty();
2947 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
2948 - slide' . $id . ' = "up";
2949 - jQuery(".wpvr_slider_nav").slideToggle();
2950 - jQuery("#sccontrols' . $id . '").slideToggle();
2951 - }
2952 - });
2953 - ';
2954 - } else {
2955 - $html .= '
2956 - jQuery(document).ready(function($){
2957 - jQuery("#sccontrols' . $id . '").show();
2958 - jQuery(".wpvr_slider_nav").show();
2959 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
2960 - });
2961 - ';
2962 -
2963 - $html .= '
2964 - var slide' . $id . ' = "down";
2965 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
2966 -
2967 - if (slide' . $id . ' == "up") {
2968 - jQuery(".vrgctrl' . $id . '").empty();
2969 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
2970 - slide' . $id . ' = "down";
2971 - }
2972 - else {
2973 - jQuery(".vrgctrl' . $id . '").empty();
2974 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2975 - slide' . $id . ' = "up";
2976 - }
2977 - jQuery(".wpvr_slider_nav").slideToggle();
2978 - jQuery("#sccontrols' . $id . '").slideToggle();
2979 - });
2980 - ';
521 + $postdata = get_post_meta( (int) $post_id, 'panodata', true );
522 + if ( wpvr_tour_uses_pro_features( $postdata ) ) {
523 + $classes[] = 'wpvr-pro-feature-tour';
2981 524 }
2982 - } else {
2983 - $html .= '
2984 - jQuery(document).ready(function($){
2985 - jQuery("#sccontrols' . $id . '").hide();
2986 - jQuery(".wpvr_slider_nav").hide();
2987 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2988 - });
2989 - ';
2990 525
2991 - $html .= '
2992 - var slide' . $id . ' = "down";
2993 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
2994 -
2995 - if (slide' . $id . ' == "up") {
2996 - jQuery(".vrgctrl' . $id . '").empty();
2997 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2998 - slide' . $id . ' = "down";
2999 - }
3000 - else {
3001 - jQuery(".vrgctrl' . $id . '").empty();
3002 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3003 - slide' . $id . ' = "up";
3004 - }
3005 - jQuery(".wpvr_slider_nav").slideToggle();
3006 - jQuery("#sccontrols' . $id . '").slideToggle();
3007 - });
3008 - ';
526 + return $classes;
3009 527 }
3010 -
3011 - if (!$autoload) {
3012 - $html .= '
3013 -
3014 - jQuery(document).ready(function(){
3015 - jQuery("#controls' . $id . '").hide();
3016 - jQuery("#zoom-in-out-controls' . $id . '").hide();
3017 - jQuery("#adcontrol' . $id . '").hide();
3018 - jQuery("#explainer_button_' . $id . '").hide();
3019 - jQuery("#generic_form_button_' . $id . '").hide();
3020 - jQuery("#floor_map_button_' . $id . '").hide();
3021 - jQuery("#vrgcontrols' . $id . '").hide();
3022 - jQuery("#cp-logo-controls").hide();
3023 - jQuery(".custom-scene-navigation").hide();
3024 - jQuery("#pano' . $id . '").find(".pnlm-panorama-info").hide();
3025 - });
3026 -
3027 - ';
3028 -
3029 - if ($vrgallery_display) {
3030 - $html .= 'var load_once = "true";';
3031 - $html .= 'panoshow' . $id . '.on("load", function (){
3032 - if (load_once == "true") {
3033 - load_once = "false";
3034 - jQuery("#sccontrols' . $id . '").slideToggle();
3035 - jQuery(".wpvr_slider_nav").slideToggle();
3036 - }
3037 - });';
3038 - }
3039 -
3040 - $html .= 'panoshow' . $id . '.on("load", function (){
3041 - jQuery("#controls' . $id . '").show();
3042 - jQuery("#zoom-in-out-controls' . $id . '").show();
3043 - jQuery("#adcontrol' . $id . '").show();
3044 - jQuery("#explainer_button_' . $id . '").show();
3045 - jQuery("#generic_form_button_' . $id . '").show();
3046 - jQuery("#floor_map_button_' . $id . '").show();
3047 - jQuery("#vrgcontrols' . $id . '").show();
3048 - jQuery("#cp-logo-controls").show();
3049 - jQuery(".custom-scene-navigation").show();
3050 - jQuery("#pano' . $id . '").find(".pnlm-panorama-info").show();
3051 - });';
3052 - }
3053 -
3054 - $previewText = $postdata['previewtext'] ?? 'Click To Load Panorama';
3055 - if ($previewText) {
3056 - $html .= '
3057 - jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previewText. '")
3058 - ';
3059 - } else {
3060 - $html .= '
3061 - jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("Click To Load Panorama")
3062 - ';
3063 - }
3064 -
3065 - $html .= 'jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseenter", function(){
3066 - jQuery(this).attr("title", jQuery(this).text());
3067 - });
3068 - jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseleave", function(){
3069 - jQuery(this).removeAttr("title");
3070 - });';
3071 - $html .= '});';
3072 -
3073 -
3074 -
3075 - $html .= '</script>';
3076 -
3077 - $tour_data = [];
3078 - if(defined("WPVR_PRO_VERSION")){
3079 - $tour_data = array(
3080 - 'explainerControlSwitch' => $explainerControlSwitch ?? false,
3081 - 'floor_plan_enable' => $floor_plan_enable ?? false,
3082 - 'floor_plan_image' => $floor_plan_image ?? '',
3083 - 'custom_control' => $custom_control ?? [],
3084 - );
3085 - }
3086 -
3087 - return apply_filters('wpvr_generate_tour_layout_html', $html ,$postdata ,$id, $tour_data);
3088 528 }
3089 529
3090 -function sanitize_content_preserve_styles($content) {
3091 - // Remove script tags completely
3092 - $content = preg_replace('/<script\b[^>]*>.*?<\/script>/si', '', $content);
530 +add_filter( 'post_class', 'wpvr_add_pro_feature_tour_row_class', 10, 3 );
3093 531
3094 - // Remove dangerous protocols
3095 - $content = preg_replace('/javascript:/i', '', $content);
3096 - $content = preg_replace('/vbscript:/i', '', $content);
3097 - $content = preg_replace('/data:/i', '', $content);
3098 - $content = preg_replace('/about:/i', '', $content);
532 +require_once plugin_dir_path( __FILE__ ) . 'src/Admin/UiModeSwitcher.php';
533 +\RexTheme\WPVR\Admin\UiModeSwitcher::init();
3099 534
3100 - // Remove all event handlers (onclick, onload, etc.)
3101 - $content = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $content);
3102 - $content = preg_replace('/\s*on\w+\s*=\s*[^>\s]+/i', '', $content);
535 +add_action( 'wp_ajax_wpvr_export_tour', 'wpvr_handle_export_tour' );
536 +/**
537 + * AJAX handler: return a signed URL for the Pro tour exporter.
538 + *
539 + * WPVR Pro creates and streams the ZIP through its admin-post endpoint. This
540 + * handler authorizes the New UI request and returns that endpoint URL.
541 + */
542 +function wpvr_handle_export_tour(): void {
543 + check_ajax_referer( 'wpvr_export_tour', 'nonce' );
3103 544
3104 - // Remove dangerous tags that can execute code
3105 - $content = preg_replace('/<(object|embed|applet|iframe|frame|frameset|meta|link|base|form|input|button|textarea|select|option)\b[^>]*>/i', '', $content);
3106 - $content = preg_replace('/<\/(object|embed|applet|iframe|frame|frameset|meta|link|base|form|input|button|textarea|select|option)>/i', '', $content);
545 + if ( ! current_user_can( 'edit_posts' ) ) {
546 + wp_send_json_error( [ 'message' => 'Insufficient permissions.' ], 403 );
547 + }
3107 548
3108 - // Sanitize CSS in style attributes - remove dangerous CSS functions
3109 - $content = preg_replace_callback('/style\s*=\s*["\']([^"\']*)["\']/', function($matches) {
3110 - $style = $matches[1];
549 + if ( ! wpvr_is_pro_active() ) {
550 + wp_send_json_error( [ 'message' => 'A valid WP VR Pro license is required.' ], 403 );
551 + }
3111 552
3112 - // Remove dangerous CSS functions
3113 - $style = preg_replace('/expression\s*\(/i', '', $style);
3114 - $style = preg_replace('/javascript:/i', '', $style);
3115 - $style = preg_replace('/vbscript:/i', '', $style);
3116 - $style = preg_replace('/data:/i', '', $style);
3117 - $style = preg_replace('/about:/i', '', $style);
3118 - $style = preg_replace('/url\s*\(\s*["\']?\s*javascript:/i', '', $style);
3119 - $style = preg_replace('/url\s*\(\s*["\']?\s*vbscript:/i', '', $style);
3120 - $style = preg_replace('/url\s*\(\s*["\']?\s*data:/i', '', $style);
3121 - $style = preg_replace('/import\s*["\']?\s*javascript:/i', '', $style);
3122 - $style = preg_replace('/behavior\s*:/i', '', $style);
3123 - $style = preg_replace('/-moz-binding\s*:/i', '', $style);
553 + $tour_id = isset( $_POST['tour_id'] ) ? absint( $_POST['tour_id'] ) : 0;
554 + if ( ! $tour_id ) {
555 + wp_send_json_error( [ 'message' => 'Missing tour ID.' ] );
556 + }
3124 557
3125 - return 'style="' . $style . '"';
3126 - }, $content);
558 + $post = get_post( $tour_id );
559 + if ( ! $post || $post->post_type !== 'wpvr_item' ) {
560 + wp_send_json_error( [ 'message' => 'Tour not found.' ] );
561 + }
3127 562
3128 - // Sanitize CSS in style tags
3129 - $content = preg_replace_callback('/<style\b[^>]*>(.*?)<\/style>/si', function($matches) {
3130 - $css = $matches[1];
563 + if ( ! current_user_can( 'edit_post', $tour_id ) ) {
564 + wp_send_json_error( [ 'message' => 'You are not allowed to export this tour.' ], 403 );
565 + }
3131 566
3132 - // Remove dangerous CSS functions
3133 - $css = preg_replace('/expression\s*\(/i', '', $css);
3134 - $css = preg_replace('/javascript:/i', '', $css);
3135 - $css = preg_replace('/vbscript:/i', '', $css);
3136 - $css = preg_replace('/data:/i', '', $css);
3137 - $css = preg_replace('/about:/i', '', $css);
3138 - $css = preg_replace('/url\s*\(\s*["\']?\s*javascript:/i', '', $css);
3139 - $css = preg_replace('/url\s*\(\s*["\']?\s*vbscript:/i', '', $css);
3140 - $css = preg_replace('/url\s*\(\s*["\']?\s*data:/i', '', $css);
3141 - $css = preg_replace('/import\s*["\']?\s*javascript:/i', '', $css);
3142 - $css = preg_replace('/behavior\s*:/i', '', $css);
3143 - $css = preg_replace('/-moz-binding\s*:/i', '', $css);
567 + $export_url = add_query_arg(
568 + [
569 + 'action' => 'wpvr_export_tour',
570 + 'post_id' => $tour_id,
571 + '_wpnonce' => wp_create_nonce( 'wpvr_export_tour_' . $tour_id ),
572 + ],
573 + admin_url( 'admin-post.php' )
574 + );
3144 575
3145 - return '<style>' . $css . '</style>';
3146 - }, $content);
3147 -
3148 - // Remove dangerous attributes from any tag
3149 - $content = preg_replace('/\s*srcdoc\s*=\s*["\'][^"\']*["\']/i', '', $content);
3150 - $content = preg_replace('/\s*formaction\s*=\s*["\'][^"\']*["\']/i', '', $content);
3151 - $content = preg_replace('/\s*action\s*=\s*["\'][^"\']*["\']/i', '', $content);
3152 -
3153 - // Clean up malformed HTML that might bypass filters
3154 - $content = preg_replace('/<[^>]*script[^>]*>/i', '', $content);
3155 - $content = preg_replace('/<[^>]*on\w+[^>]*>/i', '', $content);
3156 -
3157 - // Remove comments that might contain dangerous code
3158 - $content = preg_replace('/<!--.*?-->/s', '', $content);
3159 -
3160 - // Remove any remaining dangerous patterns
3161 - $content = preg_replace('/\beval\s*\(/i', '', $content);
3162 - $content = preg_replace('/\bsetTimeout\s*\(/i', '', $content);
3163 - $content = preg_replace('/\bsetInterval\s*\(/i', '', $content);
3164 -
3165 - // Final cleanup - remove any orphaned closing tags from removed elements
3166 - $content = preg_replace('/<\/(script|object|embed|applet|iframe|frame|frameset|meta|link|base|form|input|button|textarea|select|option)>/i', '', $content);
3167 - // Final pass with wp_kses_post for additional security
3168 - return wp_kses_post($content);
576 + wp_send_json_success( [ 'url' => $export_url ] );
3169 577 }
3170 578
3171 -function wpvr_hex2rgb($colour)
3172 -{
3173 - if (isset($colour[0]) && $colour[0] == '#') {
3174 - $colour = substr($colour, 1);
579 +/**
580 + * Ensure legacy Street View keys always exist in panodata.
581 + *
582 + * WPVR Pro reads these keys directly in classic editor screens. Tours created
583 + * through newer flows may miss them, which triggers PHP warnings.
584 + */
585 +function wpvr_backfill_legacy_streetview_keys() {
586 + if ( ! is_admin() ) {
587 + return;
3175 588 }
3176 - if (strlen($colour) == 6) {
3177 - list($r, $g, $b) = array($colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5]);
3178 - } elseif (strlen($colour) == 3) {
3179 - list($r, $g, $b) = array($colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2]);
3180 - } else {
3181 - return false;
3182 - }
3183 - $r = hexdec($r);
3184 - $g = hexdec($g);
3185 - $b = hexdec($b);
3186 - return array($r . ', ' . $g . ', ' . $b);
3187 -}
3188 589
3189 -function wpvr_HTMLToRGB($htmlCode)
3190 -{
3191 - $r = 0;
3192 - $g = 0;
3193 - $b = 0;
3194 - if (isset($htmlCode[0]) && $htmlCode[0] == '#') {
3195 - $htmlCode = substr($htmlCode, 1);
590 + $post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
591 + if ( ! $post_id ) {
592 + return;
3196 593 }
3197 594
3198 - if (strlen($htmlCode) == 3) {
3199 - $htmlCode = $htmlCode[0] . $htmlCode[0] . $htmlCode[1] . $htmlCode[1] . $htmlCode[2] . $htmlCode[2];
595 + $post = get_post( $post_id );
596 + if ( ! $post || $post->post_type !== 'wpvr_item' ) {
597 + return;
3200 598 }
3201 599
3202 - if (isset($htmlCode[0]) && isset($htmlCode[1])) {
3203 - $r = hexdec($htmlCode[0] . $htmlCode[1]);
600 + $panodata = get_post_meta( $post_id, 'panodata', true );
601 + if ( ! is_array( $panodata ) ) {
602 + return;
3204 603 }
3205 - if (isset($htmlCode[2]) && isset($htmlCode[3])) {
3206 - $g = hexdec($htmlCode[2] . $htmlCode[3]);
3207 - }
3208 - if (isset($htmlCode[4]) && isset($htmlCode[5])) {
3209 - $b = hexdec($htmlCode[4] . $htmlCode[5]);
3210 - }
3211 604
3212 - return $b + ($g << 0x8) + ($r << 0x10);
3213 -}
605 + $changed = false;
3214 606
3215 -function wpvr_RGBToHSL($RGB)
3216 -{
3217 - $r = 0xFF & ($RGB >> 0x10);
3218 - $g = 0xFF & ($RGB >> 0x8);
3219 - $b = 0xFF & $RGB;
3220 -
3221 - $r = ((float)$r) / 255.0;
3222 - $g = ((float)$g) / 255.0;
3223 - $b = ((float)$b) / 255.0;
3224 -
3225 - $maxC = max($r, $g, $b);
3226 - $minC = min($r, $g, $b);
3227 -
3228 - $l = ($maxC + $minC) / 2.0;
3229 -
3230 - if ($maxC == $minC) {
3231 - $s = 0;
3232 - $h = 0;
3233 - } else {
3234 - if ($l < .5) {
3235 - $s = ($maxC - $minC) / ($maxC + $minC);
3236 - } else {
3237 - $s = ($maxC - $minC) / (2.0 - $maxC - $minC);
3238 - }
3239 - if ($r == $maxC) {
3240 - $h = ($g - $b) / ($maxC - $minC);
3241 - }
3242 - if ($g == $maxC) {
3243 - $h = 2.0 + ($b - $r) / ($maxC - $minC);
3244 - }
3245 - if ($b == $maxC) {
3246 - $h = 4.0 + ($r - $g) / ($maxC - $minC);
3247 - }
3248 -
3249 - $h = $h / 6.0;
607 + if ( ! array_key_exists( 'streetview', $panodata ) ) {
608 + $panodata['streetview'] = 'off';
609 + $changed = true;
3250 610 }
3251 611
3252 - $h = (int)round(255.0 * $h);
3253 - $s = (int)round(255.0 * $s);
3254 - $l = (int)round(255.0 * $l);
3255 -
3256 - return (object) array('hue' => $h, 'saturation' => $s, 'lightness' => $l);
3257 -}
3258 -
3259 -add_action('rest_api_init', 'wpvr_rest_data_route');
3260 -function wpvr_rest_data_route()
3261 -{
3262 - register_rest_route('wpvr/v1', '/panodata/', array(
3263 - 'methods' => 'GET',
3264 - 'callback' => 'wpvr_rest_data_set',
3265 - 'permission_callback' => 'wpvr_rest_route_permission'
3266 - ));
3267 -}
3268 -
3269 -function wpvr_rest_route_permission()
3270 -{
3271 - return true;
3272 -}
3273 -
3274 -function wpvr_rest_data_set()
3275 -{
3276 - $query = new WP_Query(array(
3277 - 'post_type' => 'wpvr_item',
3278 - 'posts_per_page' => -1,
3279 - ));
3280 -
3281 - $wpvr_list = array();
3282 - $list_none = array('value' => 0, 'label' => 'None');
3283 - array_push($wpvr_list, $list_none);
3284 - while ($query->have_posts()) {
3285 - $query->the_post();
3286 - $title = mb_convert_encoding(get_the_title(), 'UTF-8', 'HTML-ENTITIES');
3287 - $post_id = get_the_ID();
3288 - $title = $post_id . ' : ' . $title;
3289 - $list_ob = array('value' => $post_id, 'label' => $title);
3290 - array_push($wpvr_list, $list_ob);
612 + if ( ! array_key_exists( 'streetviewurl', $panodata ) ) {
613 + $panodata['streetviewurl'] = '';
614 + $changed = true;
3291 615 }
3292 616
3293 - return $wpvr_list;
3294 -}
3295 -
3296 -function wpvr_isMobileDevice()
3297 -{
3298 - return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);
3299 -}
3300 -
3301 -function wpvr_directory()
3302 -{
3303 - $upload = wp_upload_dir();
3304 - $upload_dir = $upload['basedir'];
3305 - $upload_dir_temp = $upload_dir . '/wpvr/temp/';
3306 - if (!is_dir($upload_dir_temp)) {
3307 - wp_mkdir_p($upload_dir_temp, 0700);
617 + if ( $changed ) {
618 + update_post_meta( $post_id, 'panodata', $panodata );
3308 619 }
3309 620 }
3310 621
3311 -add_action('admin_init', 'wpvr_directory');
622 +add_action( 'load-post.php', 'wpvr_backfill_legacy_streetview_keys', 1 );
3312 623
624 +/**
625 + * Register a lightweight PSR-4 autoloader for src/ classes.
626 + */
627 +function wpvr_register_src_autoloader() {
628 + static $loaded = false;
3313 629
3314 -function wpvr_add_role_cap()
3315 -{
3316 - $editor_active = get_option('wpvr_editor_active');
3317 -
3318 - $author_active = get_option('wpvr_author_active');
3319 -
3320 - $admin = get_role('administrator');
3321 - $admin->add_cap('publish_wpvr_tour');
3322 - $admin->add_cap('edit_wpvr_tours');
3323 - $admin->add_cap('read_wpvr_tour');
3324 - $admin->add_cap('edit_wpvr_tour');
3325 - $admin->add_cap('edit_wpvr_tours');
3326 - $admin->add_cap('publish_wpvr_tours');
3327 - $admin->add_cap('publish_wpvr_tour');
3328 - $admin->add_cap('delete_wpvr_tour');
3329 - $admin->add_cap('edit_other_wpvr_tours');
3330 - $admin->add_cap('delete_other_wpvr_tours');
3331 -
3332 - if ($editor_active == "true") {
3333 - $editor = get_role('editor');
3334 - if ($editor) {
3335 - $editor->add_cap('publish_wpvr_tour');
3336 - $editor->add_cap('edit_wpvr_tours');
3337 - $editor->add_cap('read_wpvr_tour');
3338 - $editor->add_cap('edit_wpvr_tour');
3339 - $editor->add_cap('edit_wpvr_tours');
3340 - $editor->add_cap('publish_wpvr_tours');
3341 - $editor->add_cap('publish_wpvr_tour');
3342 - $editor->add_cap('delete_wpvr_tour');
3343 - $editor->add_cap('edit_other_wpvr_tours');
3344 - $editor->add_cap('delete_other_wpvr_tours');
3345 - }
3346 - } else {
3347 - $editor = get_role('editor');
3348 - if ($editor) {
3349 - $editor->remove_cap('publish_wpvr_tour');
3350 - $editor->remove_cap('edit_wpvr_tours');
3351 - $editor->remove_cap('read_wpvr_tour');
3352 - $editor->remove_cap('edit_wpvr_tour');
3353 - $editor->remove_cap('edit_wpvr_tours');
3354 - $editor->remove_cap('publish_wpvr_tours');
3355 - $editor->remove_cap('publish_wpvr_tour');
3356 - $editor->remove_cap('delete_wpvr_tour');
3357 - $editor->remove_cap('edit_other_wpvr_tours');
3358 - $editor->remove_cap('delete_other_wpvr_tours');
3359 - }
630 + if ( $loaded ) {
631 + return;
3360 632 }
3361 633
3362 - if ($author_active == "true") {
3363 - $author = get_role('author');
3364 - if ($author) {
3365 - $author->add_cap('read_wpvr_tour');
3366 - $author->add_cap('edit_wpvr_tour');
3367 - $author->add_cap('edit_wpvr_tours');
3368 - $author->add_cap('publish_wpvr_tours');
3369 - $author->add_cap('publish_wpvr_tour');
3370 - $author->add_cap('delete_wpvr_tour');
3371 - }
3372 - } else {
3373 - $author = get_role('author');
3374 - if ($author) {
3375 - $author->remove_cap('read_wpvr_tour');
3376 - $author->remove_cap('edit_wpvr_tour');
3377 - $author->remove_cap('edit_wpvr_tours');
3378 - $author->remove_cap('publish_wpvr_tours');
3379 - $author->remove_cap('publish_wpvr_tour');
3380 - $author->remove_cap('delete_wpvr_tour');
3381 - }
3382 - }
634 + spl_autoload_register(
635 + static function ( $class ) {
636 + $prefix = 'RexTheme\\WPVR\\';
3383 637
3384 - if(is_plugin_active( 'dokan-lite/dokan.php' ) || is_plugin_active( 'dokan-pro/dokan.php' )){
3385 - $dokan_vendor_active = get_option('dokan_vendor_active');
3386 -
3387 - if( 'true' === $dokan_vendor_active){
3388 - $seller = get_role('seller');
3389 - if ($seller) {
3390 - $seller->add_cap('read_wpvr_tour');
3391 - $seller->add_cap('edit_wpvr_tour');
3392 - $seller->add_cap('edit_wpvr_tours');
3393 - $seller->add_cap('publish_wpvr_tours');
3394 - $seller->add_cap('publish_wpvr_tour');
3395 - $seller->add_cap('delete_wpvr_tour');
638 + if ( strpos( $class, $prefix ) !== 0 ) {
639 + return;
3396 640 }
3397 - } else{
3398 - $seller = get_role('seller');
3399 - if ($seller) {
3400 - $seller->remove_cap('read_wpvr_tour');
3401 - $seller->remove_cap('edit_wpvr_tour');
3402 - $seller->remove_cap('edit_wpvr_tours');
3403 - $seller->remove_cap('publish_wpvr_tours');
3404 - $seller->remove_cap('publish_wpvr_tour');
3405 - $seller->remove_cap('delete_wpvr_tour');
3406 - }
3407 - }
3408 - }
3409 641
642 + $relative_class = substr( $class, strlen( $prefix ) );
643 + $file = plugin_dir_path( __FILE__ ) . 'src/' . str_replace( '\\', '/', $relative_class ) . '.php';
3410 644
3411 -}
3412 -
3413 -add_action('admin_init', 'wpvr_add_role_cap', 999);
3414 -
3415 -function wpvr_role_management_from_post_type($args, $post_type)
3416 -{
3417 - if ('wpvr_item' !== $post_type) {
3418 - return $args;
3419 - }
3420 -
3421 - $editor_active = get_option('wpvr_editor_active');
3422 - $author_active = get_option('wpvr_author_active');
3423 - $user = wp_get_current_user();
3424 -
3425 - if ($editor_active == "true") {
3426 - if (in_array('editor', (array) $user->roles)) {
3427 - $args['show_in_menu'] = true;
3428 - }
3429 - }
3430 -
3431 - if ($author_active == "true") {
3432 - if (in_array('author', (array) $user->roles)) {
3433 - $args['show_in_menu'] = true;
3434 - }
3435 - }
3436 -
3437 - if(is_plugin_active( 'dokan-lite/dokan.php' ) || is_plugin_active( 'dokan-pro/dokan.php' )){
3438 - $dokan_vendor_active = get_option('dokan_vendor_active');
3439 - if( 'true' === $dokan_vendor_active){
3440 - if (in_array('seller', (array) $user->roles)) {
3441 - $args['show_in_menu'] = true;
645 + if ( file_exists( $file ) ) {
646 + require_once $file;
3442 647 }
3443 648 }
649 + );
3444 650
3445 - }
3446 -
3447 - return $args;
651 + $loaded = true;
3448 652 }
3449 -add_filter('register_post_type_args', 'wpvr_role_management_from_post_type', 10, 2);
3450 653
3451 -function wpvr_cache_admin_notice()
3452 -{
3453 - $option = get_option('wpvr_warning');
3454 - if (!$option) {
3455 - ?>
3456 - <div class="notice notice-warning" id="wpvr-warning" style="position: relative;">
3457 - <p><?php _e('Since you have updated the plugin, please clear the browser cache for smooth functioning. Follow these steps if you are using <a href="https://support.google.com/accounts/answer/32050?co=GENIE.Platform%3DDesktop&hl=en" target="_blank">Google Chrome</a>, <a href="https://support.mozilla.org/en-US/kb/how-clear-firefox-cache" target="_blank">Mozilla Firefox</a>, <a href="https://clear-my-cache.com/en/apple-mac-os/safari.html" target="_blank">Safai</a> or <a href="https://support.microsoft.com/en-us/help/10607/microsoft-edge-view-delete-browser-history" target="_blank">Microsoft Edge</a>', 'wpvr'); ?></p>
3458 - <button type="button" id="wpvr-dismissible" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
3459 - </div>
3460 - <?php
3461 - }
3462 -}
3463 -// add_action('admin_notices', 'wpvr_cache_admin_notice');
654 +// UI/UX Mode Switch: legacy/classic or latest
655 +// Option: wpvr_ui_mode (default: legacy)
656 +wpvr_register_src_autoloader();
3464 657
3465 -//===Oxygen widget===//
3466 -add_action('plugins_loaded', function () {
3467 - if (!class_exists('OxyEl')) {
3468 - return;
3469 - }
3470 - require_once __DIR__ . '/oxygen/oxy-manager.php';
3471 -});
3472 -
3473 -add_action('init', 'wpvr_mobile_media_handle');
3474 -function wpvr_mobile_media_handle()
3475 -{
3476 - add_image_size('wpvr_mobile', 4096, 2048); //mobile
658 +$wpvr_ui_mode = get_option('wpvr_ui_mode', 'legacy');
659 +if ($wpvr_ui_mode === 'latest') {
660 + require_once plugin_dir_path(__FILE__) . 'src/Bootstrap.php';
661 + \RexTheme\WPVR\Bootstrap::init();
662 +} else {
663 + require_once plugin_dir_path(__FILE__) . 'legacy/wpvr.php';
664 + new \RexTheme\WPVR\Admin\Admin( false );
3477 665 }
3478 -
3479 -
3480 -add_action(
3481 -/**
3482 - * @param $api \VisualComposer\Modules\Api\Factory
3483 - */
3484 - 'vcv:api',
3485 - function ($api) {
3486 - $elementsToRegister = [
3487 - 'wpvrelement',
3488 - ];
3489 - $pluginBaseUrl = rtrim(plugins_url(basename(__DIR__)), '\\/');
3490 - /** @var \VisualComposer\Modules\Elements\ApiController $elementsApi */
3491 - $elementsApi = $api->elements;
3492 - foreach ($elementsToRegister as $tag) {
3493 - $manifestPath = __DIR__ . '/vc/' . $tag . '/manifest.json';
3494 - $elementBaseUrl = $pluginBaseUrl . '/vc/' . $tag;
3495 - $elementsApi->add($manifestPath, $elementBaseUrl);
3496 - }
3497 - }
3498 -);
3499 -
3500 -function wpvr_redirect_after_activation($plugin)
3501 -{
3502 - if ($plugin == plugin_basename(__FILE__)) {
3503 - $url = admin_url('admin.php?page=wpvr-setup-wizard');
3504 - $url = esc_url($url, FILTER_SANITIZE_URL);
3505 - exit(wp_safe_redirect($url));
3506 - }
3507 -}
3508 -//add_action('activated_plugin', 'wpvr_redirect_after_activation');
3509 -
3510 -function replace_callback($matches)
3511 -{
3512 - foreach ($matches as $match) {
3513 - return str_replace('<img', '<img decoding="async" ', $match);
3514 - }
3515 -}