PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 8.5.77
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v8.5.77
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
wpvr / admin / classes / class-wpvr-scene.php

class-wpvr-scene.php in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 8.5.77, at admin/classes/class-wpvr-scene.php

3,333 lines 169.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit; // Exit if accessed directly
3 /**
4 * Responsible for managing Scene tab on Setup meta box
5 *
6 * @link http://rextheme.com/
7 * @since 8.0.0
8 *
9 * @package Wpvr
10 * @subpackage Wpvr/admin/classes
11 */
12
13 class WPVR_Scene {
14
15 /**
16 * Instance of WPVR_Hotspot class
17 *
18 * @var object
19 * @since 8.0.0
20 */
21 protected $hotspot;
22
23 /**
24 * Instance of WPVR_Format class
25 *
26 * @var object
27 * @since 8.0.0
28 */
29 protected $format;
30
31 /**
32 * Instance of WPVR_Validator class
33 *
34 * @var object
35 * @since 8.0.0
36 */
37 private $validator;
38
39 /**
40 * Number of scene or hotspot item
41 *
42 * @var integer
43 * @since 8.0.0
44 */
45 protected $data_limit;
46
47 /**
48 * Pro version license status
49 *
50 * @var string
51 * @since 8.0.0
52 */
53 protected $status;
54
55
56 function __construct()
57 {
58 $this->hotspot = new WPVR_Hotspot();
59 $this->format = new WPVR_Format();
60 $this->validator = new WPVR_Validator();
61
62 $this->status = apply_filters( 'check_pro_license_status', $this->status );
63
64 if ($this->status !== false && $this->status == 'valid') {
65 $this->data_limit = 999999999;
66 } else {
67 $this->data_limit = 5;
68 }
69 }
70
71 /**
72 * Render Scene Settings Content
73 *
74 * @param array $postdata
75 *
76 * @return void
77 * @since 8.0.0
78 */
79 public function render_scene($postdata)
80 {
81 ob_start();
82 ?>
83
84 <!-- Scene and Hotspot repeater -->
85 <div class="scene-setup rex-pano-sub-tabs" data-limit="<?php echo esc_attr( $this->data_limit + 1 ); ?>">
86 <?php $this->render_scene_repeater_list($postdata); ?>
87 </div>
88
89 <?php
90 // ob_end_flush();
91 }
92
93
94 /**
95 * Render scene setup data repeater list
96 *
97 * @param array $postdata
98 *
99 * @return void
100 * @since 8.0.0
101 */
102 private function render_scene_repeater_list($postdata)
103 {
104 ob_start();
105 ?>
106 <nav class="rex-pano-tab-nav rex-pano-nav-menu scene-nav">
107 <?php $this->render_nav_menu($postdata); // Will render scene navigation bar ?>
108 </nav>
109
110 <div data-repeater-list="scene-list" class="rex-pano-tab-content">
111
112 <!-- Default empty repeater -->
113 <div data-repeater-item class="single-scene rex-pano-tab" data-title="0" id="scene-0">
114 <?php $this->render_default_repeater_item(); ?>
115 </div>
116 <!-- Empty repeater end -->
117
118 <?php $s = 1; $firstvalue = reset($postdata['panodata']["scene-list"]);
119 foreach ($postdata['panodata']["scene-list"] as $pano_scene) { ?>
120
121 <div data-repeater-item class="single-scene rex-pano-tab <?php if($pano_scene['scene-id'] == $firstvalue['scene-id']) { echo esc_attr('active'); }; ?>" data-title="1" id="scene-<?php echo esc_attr( $s ); ?>">
122 <?php $this->render_repeater_item_with_panodata($pano_scene, $s); ?>
123 </div>
124
125 <?php $s++; } ?>
126 </div>
127 <?php
128 // ob_end_flush();
129 }
130
131
132 /**
133 * Render scene nav menu
134 *
135 * @param array $postdata
136 *
137 * @return void
138 * @since 8.0.0
139 */
140 private function render_nav_menu($postdata)
141 {
142 ob_start();
143 ?>
144 <ul>
145 <?php $i = 1; $firstvalue = reset($postdata['panodata']["scene-list"]);
146 foreach ($postdata['panodata']["scene-list"] as $pano_scene) { ?>
147
148 <li class="<?php if ($pano_scene['scene-id'] == $firstvalue['scene-id']) {echo 'active';};?>">
149 <span data-index="<?php echo esc_attr( $i ); ?>" data-href="#scene-<?php echo esc_attr( $i ); ?>">
150 <i class="fa fa-image"></i>
151 </span>
152 </li>
153
154 <?php $i++; } ?>
155 <li class="add" data-repeater-create><span><i class="fa fa-plus-circle"></i></span></li>
156 </ul>
157 <?php
158 ob_end_flush();
159 }
160
161
162 /**
163 * Render repeater item for default scene
164 *
165 * @param int $data_limit
166 *
167 * @return void
168 * @since 8.0.0
169 */
170 private function render_default_repeater_item()
171 {
172 ob_start();
173 ?>
174 <div class="active_scene_id"><p></p></div>
175 <div class="scene-content">
176 <?php $this->render_default_repeater_item_scene_content(); ?>
177 </div>
178
179 <!-- hotspot setup -->
180 <div class="hotspot-setup rex-pano-sub-tabs" data-limit="<?php echo esc_attr( $this->data_limit ); ?>">
181 <?php $this->hotspot->render_hotspot($s = 0, $h =1)?>
182 </div>
183 <button data-repeater-delete type="button" title="Delete Scene" class="delete-scene"><i class="far fa-trash-alt"></i></button>
184 <?php
185 ob_end_flush();
186 }
187
188
189 /**
190 * Render repeater items while scene has panaromic data
191 *
192 * @param array $pano_scene
193 * @param int $s scene number increment var
194 *
195 * @return void
196 * @since 8.0.0
197 */
198 private function render_repeater_item_with_panodata($pano_scene, $s)
199 {
200 ob_start();
201 ?>
202 <div class="active_scene_id"><p></p></div>
203 <div class="scene-content">
204 <!--
205 - Render repeater item scene content
206 - If scene has panaromic data
207 -->
208 <?php $this->render_repeater_scene_content_with_data($pano_scene); ?>
209 </div>
210 <!--
211 - Render repeater item hotspot content
212 -->
213 <?php $this->render_repeater_item_hotspot_content($pano_scene, $s); ?>
214
215 <button data-repeater-delete type="button" title="Delete Scene" class="delete-scene"><i class="far fa-trash-alt"></i></button>
216 <?php
217 ob_end_flush();
218 }
219
220
221 /**
222 * Render scene content for default repeater item
223 *
224 * @return void
225 * @since 8.0.0
226 */
227 private function render_default_repeater_item_scene_content()
228 {
229 ob_start();
230 ?>
231
232 <h6 class="title"><i class="fa fa-cog"></i> <?php esc_html_e('Scene Settings','wpvr'); ?> </h6>
233
234 <div class="scene-left">
235 <?php WPVR_Meta_Field::render_scene_left_fields_empty_panodata(); ?>
236 </div>
237
238 <div class="scene-right">
239 <?php do_action( 'wpvr_pro_scene_empty_right_fields' ) ?>
240 </div>
241
242 <?php
243 ob_end_flush();
244 }
245
246
247 /**
248 * Render repeater item scene content is scene has panaromic data
249 *
250 * @param mixed $dscene
251 * @param mixed $scene_id
252 * @param mixed $scene_photo
253 *
254 * @return void
255 * @since 8.0.0
256 */
257 private function render_repeater_scene_content_with_data($pano_scene)
258 {
259 ob_start();
260 ?>
261 <h6 class="title"><i class="fa fa-cog"></i> <?php esc_html_e('Scene Settings','wpvr'); ?> </h6>
262
263 <div class="scene-left">
264 <?php WPVR_Meta_Field::render_scene_left_fields_with_panodata($pano_scene) ;?>
265 </div>
266
267 <div class="scene-right">
268 <?php do_action( 'wpvr_pro_scene_right_fields', $pano_scene ) ?>
269 </div>
270
271
272 <?php
273 ob_end_flush();
274 }
275
276
277 /**
278 * Render repeater item hotspot content
279 *
280 * @param array $pano_hotspots
281 * @param int $data_limit
282 * @param int $s
283 *
284 * @return void
285 * @since 8.0.0
286 */
287 private function render_repeater_item_hotspot_content($pano_scene, $s)
288 {
289 if (!empty($pano_scene['hotspot-list'])) { ?>
290 <div class="hotspot-setup rex-pano-sub-tabs" data-limit="<?php echo esc_attr( $this->data_limit ); ?>">
291
292 <?php $this->hotspot->render_hotspot_with_panodata($pano_scene['hotspot-list'], $s); //Render hotspot while scene has hotspot data ?>
293
294 </div>
295 <?php } else { ?>
296 <div class="hotspot-setup rex-pano-sub-tabs" data-limit="<?php echo esc_attr( $this->data_limit ); ?>">
297
298 <?php $this->hotspot->render_hotspot($s, $h = 1); //Render hotspot while scene has no hotspot data ?>
299
300 </div>
301 <?php }
302 }
303
304
305 /**
306 * Update post meta data
307 *
308 * @param integer $postid
309 * @param integer $panoid
310 * @param boolean $is_publish_action
311 *
312 * @return void
313 * @since 8.0.0
314 */
315 public function wpvr_update_meta_box($postid, $panoid, $is_publish_action = false)
316 {
317 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
318 if ( ! wp_verify_nonce( $nonce, 'wpvr' ) ) {
319 wp_die( 'Permission denied.' );
320 }
321 $panodata = $this->format->prepare_panodata(isset($_POST['panodata']) ? wp_unslash( $_POST['panodata'] ) : ''); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
322 $default_scene = $this->format->prepare_default_scene($panodata);
323 $previewtext = isset($_POST['previewtext']) ? $this->validator->preview_text_validation(wp_unslash( $_POST['previewtext'] )) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
324
325 $gzoom = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['gzoom'] ));
326 $default_global_zoom = '';
327 $max_global_zoom = '';
328 $min_global_zoom = '';
329 if ($gzoom == 'on') {
330 $default_global_zoom = isset($_POST['dzoom']) ? wp_unslash( $_POST['dzoom'] ) : '';
331 $max_global_zoom = isset($_POST['maxzoom']) ? wp_unslash( $_POST['maxzoom'] ) : '';
332 $min_global_zoom = isset($_POST['minzoom']) ? wp_unslash( $_POST['minzoom'] ) : '';
333 }
334
335 $custom_control = isset($_POST['customcontrol']) ? wp_unslash( $_POST['customcontrol'] ) : null;
336
337 $vrgallery = $this->format->set_checkbox_value(@wp_unslash( $_POST['vrgallery'] ));
338 $vrgallery_title = $this->format->set_checkbox_value(@wp_unslash( $_POST['vrgallery_title'] ));
339 $vrgallery_display = $this->format->set_checkbox_value(@wp_unslash( $_POST['vrgallery_display'] ));
340 $vrgallery_icon_size = $this->format->set_checkbox_value(@wp_unslash( $_POST['vrgallery_icon_size'] ));
341
342 $mouseZoom = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['mouseZoom'] ));
343 $draggable = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['draggable'] ));
344 $diskeyboard = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['diskeyboard'] ));
345 $keyboardzoom = $this->format->set_checkbox_value(@wp_unslash( $_POST['keyboardzoom'] ));
346 $compass = $this->format->set_checkbox_on_value(@wp_unslash( $_POST['compass'] ));
347 //===Gyroscopre control===//
348 $gyro = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['gyro'] ));
349 if ($gyro == 'on') {
350 if (!is_ssl()) {
351 wp_send_json_error('<p><span>Warning:</span> Please add SSL to enable Gyroscope for WP VR. </p>');
352 die();
353 }
354 $gyro = true;
355 $deviceorientationcontrol = $this->format->set_checkbox_value(@wp_unslash( $_POST['deviceorientationcontrol'] ));
356 } else {
357 $gyro = false;
358 $deviceorientationcontrol = false;
359 }
360 //===Gyroscopre control===//
361
362 $autoload = $this->format->set_checkbox_value(isset($_POST['autoload']) ? wp_unslash( $_POST['autoload'] ) : '');
363 $control = $this->format->set_checkbox_value(isset($_POST['control']) ? wp_unslash( $_POST['control'] ) : '');
364
365 $scene_fade_duration = isset($_POST['scenefadeduration']) ? sanitize_text_field(wp_unslash( $_POST['scenefadeduration'] )) : '';
366 $preview = isset($_POST['preview']) ? esc_url(wp_unslash( $_POST['preview'] )) : '';
367 $rotation = isset($_POST['rotation']) ? sanitize_text_field(wp_unslash( $_POST['rotation'] )) : '';
368 $autorotation = isset($_POST['autorotation']) ? sanitize_text_field(wp_unslash( $_POST['autorotation'] )) : '';
369
370 $autorotationinactivedelay = isset($_POST['autorotationinactivedelay']) ? sanitize_text_field(wp_unslash( $_POST['autorotationinactivedelay'] )) : '';
371 $autorotationstopdelay = isset($_POST['autorotationstopdelay']) ? sanitize_text_field(wp_unslash( $_POST['autorotationstopdelay'] )) : '';
372
373 //===generic form===//
374 $genericform = sanitize_text_field(isset($_POST['genericform']) ? wp_unslash( $_POST['genericform'] ) : 'off');
375 $genericformshortcode = isset($_POST['genericformshortcode']) ? sanitize_text_field(wp_unslash( $_POST['genericformshortcode'] )) : '' ;
376 //===generic form===//
377
378
379 if(isset($_POST['rotation']) && sanitize_text_field(wp_unslash( $_POST['rotation'] )) === 'on' ) {
380 $this->validator->basic_setting_validation($autorotationinactivedelay, $autorotationstopdelay); // Basic setting error control and validation //
381 }
382
383 //===Company Logo===//
384 $cpLogoSwitch = isset($_POST['cpLogoSwitch']) ? wp_unslash( $_POST['cpLogoSwitch'] ) : 'off';
385 $cpLogoImg = isset($_POST['cpLogoImg']) ? wp_unslash( $_POST['cpLogoImg'] ) : '';
386 $cpLogoContent = isset($_POST['cpLogoContent']) ? sanitize_text_field(wp_unslash( $_POST['cpLogoContent'] )) : '';
387 //===Company Logo===//
388
389 //===Explainer video===//
390 $explainerSwitch = isset($_POST['explainerSwitch']) ? wp_unslash( $_POST['explainerSwitch'] ) : 'off';
391 $explainerContent = '';
392 $explainerContent = isset($_POST['explainerContent']) ? wp_unslash( $_POST['explainerContent'] ) : '';
393 //===Explainer video===//
394
395
396 $scene_fade_duration = '';
397 $scene_fade_duration = isset($_POST['scenefadeduration']) ? sanitize_text_field(wp_unslash( $_POST['scenefadeduration'] )) : '';
398
399 // Only validate when publishing, not when saving drafts
400 if ($is_publish_action) {
401 $this->validator->scene_validation($panodata); // Scene content error control and validation //
402
403 $this->validator->empty_scene_validation($panodata); // Empty scene content error control and validation //
404
405 $this->validator->duplicate_hotspot_validation($panodata); // Duplicate error control and validation //
406 }
407
408 $panodata = $this->format->remove_empty_scene_and_hotspot($panodata); // Remove Empty scene and hotspot //
409
410 //===audio===//
411 $bg_music = isset($_POST['bg_music']) ? sanitize_text_field(wp_unslash( $_POST['bg_music'] )) : 'off';
412 $bg_music_url = isset($_POST['bg_music_url']) ? esc_url_raw(wp_unslash( $_POST['bg_music_url'] )) : '';
413 $autoplay_bg_music = isset($_POST['autoplay_bg_music']) ? sanitize_text_field(wp_unslash( $_POST['autoplay_bg_music'] )) : 'off';
414 $loop_bg_music = isset($_POST['loop_bg_music']) ? sanitize_text_field(wp_unslash( $_POST['loop_bg_music'] )) : 'off';
415 if ($bg_music == 'on') {
416 if (empty($bg_music_url)) {
417 wp_send_json_error('<p><span>Warning:</span> Please add an audio file as you enabled audio for this tour </p>');
418 die();
419 }
420 }
421 //===audio===//
422 $advanced_control = array(
423 'keyboardzoom' => $keyboardzoom,
424 'diskeyboard' => $diskeyboard,
425 'draggable' => $draggable,
426 'mouseZoom' => $mouseZoom,
427 'gyro' => $gyro,
428 'deviceorientationcontrol' => $deviceorientationcontrol,
429 'compass' => $compass,
430 'vrgallery' => $vrgallery,
431 'vrgallery_title' => $vrgallery_title,
432 'vrgallery_display' => $vrgallery_display,
433 'vrgallery_icon_size' => $vrgallery_icon_size,
434 'bg_music' => $bg_music,
435 'bg_music_url' => $bg_music_url,
436 'autoplay_bg_music' => $autoplay_bg_music,
437 'loop_bg_music' => $loop_bg_music,
438 'cpLogoSwitch' => $cpLogoSwitch,
439 'cpLogoImg' => $cpLogoImg,
440 'cpLogoContent' => $cpLogoContent,
441 'hfov' => $default_global_zoom,
442 'maxHfov' => $max_global_zoom,
443 'minHfov' => $min_global_zoom,
444 'explainerSwitch' => $explainerSwitch,
445 'explainerContent' => $explainerContent,
446 );
447
448 $pano_array = array();
449 $pano_array = array(
450 "panoid" => $panoid,
451 "autoLoad" => $autoload,
452 "showControls" => $control,
453 "customcontrol" => $custom_control,
454 "autoRotate" => $autorotation,
455 "autoRotateInactivityDelay" => $autorotationinactivedelay,
456 "autoRotateStopDelay" => $autorotationstopdelay,
457 "genericform" => $genericform,
458 "genericformshortcode" => $genericformshortcode,
459 "preview" => $preview,
460 "defaultscene" => $default_scene,
461 "scenefadeduration" => $scene_fade_duration,
462 "panodata" => $panodata,
463 "previewtext" => $previewtext);
464 $pano_array = apply_filters( 'prepare_scene_pano_array_with_pro_version', $pano_array, $_POST, $advanced_control );
465 $pano_array = $this->format->prepare_rotation_wrapper_data($pano_array, $rotation);
466 // Prepare tour rotation wrapper data /
467 update_post_meta($postid, 'panodata', $pano_array);
468 do_action( 'wpvr_hotspot_saved', $postid, $pano_array );
469 $response = array(
470 'success' => true,
471 'data' => array(
472 'post_ID' => $postid,
473 'post_status' => get_post_status($postid)
474 )
475 );
476
477 do_action( 'wpvr_tour_settings_saved', $postid );
478
479
480 /**
481 * Delete orphaned analytics data
482 *
483 * @param integer $postid POST ID
484 *
485 * @return void
486 * @since 8.5.16
487 */
488 do_action('wpvr_pro_delete_orphaned_analytics_data', $postid);
489
490 wp_send_json($response);
491 die();
492
493 }
494
495
496 /**
497 * Allow iframe but disallow script tags in user input
498 * @since 8.5.16
499 */
500 public function wpvr_sanitize_iframe_only( $input ) {
501 // Start with standard allowed post HTML (p, a, strong, etc.)
502 $allowed_tags = wp_kses_allowed_html( 'post' );
503
504 // Explicitly allow <iframe> with specific safe attributes
505 $allowed_tags['iframe'] = array(
506 'src' => true,
507 'width' => true,
508 'height' => true,
509 'title' => true,
510 'frameborder' => true,
511 'allow' => true,
512 'allowfullscreen' => true,
513 'referrerpolicy' => true,
514 );
515
516 // Sanitize input
517 return wp_kses( $input, $allowed_tags );
518 }
519
520
521
522 /**
523 * Responsible for showing Scene Preview
524 *
525 * @param string $panoid
526 * @param string $panovideo
527 *
528 * @return wp_send_json_success
529 * @since 8.0.0
530 */
531 public function wpvr_scene_preview($panoid, $panovideo)
532 {
533 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
534 if ( ! wp_verify_nonce( $nonce, 'wpvr' ) ) {
535 wp_die( 'Permission denied.' );
536 }
537 $panodata = $this->format->prepare_panodata( isset( $_POST['panodata'] ) ? wp_unslash( $_POST['panodata'] ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
538
539 $control = $this->format->set_checkbox_value(wp_unslash( $_POST['control'] ));
540 $autoload = $this->format->set_checkbox_value(wp_unslash( $_POST['autoload'] ));
541
542 $compass = $this->format->set_checkbox_on_value(@wp_unslash( $_POST['compass'] ));
543 $mouseZoom = $this->format->set_checkbox_value(@wp_unslash( $_POST['mouseZoom'] ));
544 $draggable = $this->format->set_checkbox_value(wp_unslash( $_POST['draggable'] ) ?? null);
545 $gzoom = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['gzoom'] ));
546 $diskeyboard = $this->format->set_checkbox_value(@wp_unslash( $_POST['diskeyboard'] ));
547 $keyboardzoom = $this->format->set_checkbox_value(@wp_unslash( $_POST['keyboardzoom'] ));
548
549 $gyro = $this->format->set_checkbox_on_value(@wp_unslash( $_POST['gyro'] ));
550 $deviceorientationcontrol = $this->format->set_checkbox_value(@wp_unslash( $_POST['deviceorientationcontrol'] ));
551
552 $floor_plan_enabler = $this->format->set_pro_checkbox_value(@wp_unslash( $_POST['wpvr_floor_plan_enabler'] ));
553 $floor_plan_image = isset($_POST['wpvr_floor_plan_image']) ? wp_unslash( $_POST['wpvr_floor_plan_image'] ) : '';
554
555 $scene_fade_duration = sanitize_text_field(wp_unslash( $_POST['scenefadeduration'] ));
556 $preview = esc_url(wp_unslash( $_POST['preview'] ));
557
558 $default_scene = '';
559
560 $rotation = sanitize_text_field(wp_unslash( $_POST['rotation'] ));
561 $autorotation = sanitize_text_field(wp_unslash( $_POST['autorotation'] ));
562 $autorotationinactivedelay = sanitize_text_field(wp_unslash( $_POST['autorotationinactivedelay'] ));
563 $autorotationstopdelay = sanitize_text_field(wp_unslash( $_POST['autorotationstopdelay'] ));
564
565 $default_global_zoom = '';
566 $max_global_zoom = '';
567 $min_global_zoom = '';
568 if ($gzoom == 'on') {
569 $default_global_zoom = wp_unslash( $_POST['dzoom'] );
570 $max_global_zoom = wp_unslash( $_POST['maxzoom'] );
571 $min_global_zoom = wp_unslash( $_POST['minzoom'] );
572 }
573
574 $default_scene = $this->format->prepare_default_scene($panodata);
575
576 if(isset($_POST['rotation']) && sanitize_text_field(wp_unslash( $_POST['rotation'] )) === 'on' ) {
577 $this->validator->basic_setting_validation($autorotationinactivedelay, $autorotationstopdelay); // Basic setting error control and validation //
578 }
579 $this->validator->scene_validation($panodata); // Scene content error control and validation //
580
581 $this->validator->empty_scene_validation($panodata); // Empty scene content error control and validation //
582
583 $this->validator->duplicate_hotspot_validation($panodata);
584 if($floor_plan_enabler == 'on'){
585 $this->validator->empty_floor_plan_image_validation($floor_plan_image);
586 }
587
588 $default_data = array();
589 if ($gzoom == 'on') {
590 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration, "hfov" => $default_global_zoom, "maxHfov" => $max_global_zoom, "minHfov" => $min_global_zoom);
591 } else {
592 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration);
593 }
594
595 $scene_data = $this->format->prepare_scene_data_for_preview($panodata);
596
597
598 $pano_id_array = array();
599 $pano_id_array = array("panoid" => $panoid);
600 $pano_response = array();
601 $pano_response = array("autoLoad" => $autoload, "defaultZoom" => $default_global_zoom, "minZoom" => $min_global_zoom, "maxZoom" => $max_global_zoom, "showControls" => $control, "compass" => $compass, "orientationOnByDefault" => $deviceorientationcontrol, "mouseZoom" => $mouseZoom, "draggable" => $draggable, "disableKeyboardCtrl" => $diskeyboard, 'keyboardZoom' => $keyboardzoom, "preview" => $preview, "autoRotate" => $autorotation, "autoRotateInactivityDelay" => $autorotationinactivedelay, "autoRotateStopDelay" => $autorotationstopdelay, "default" => $default_data, "scenes" => $scene_data);
602
603 $pano_response = $this->format->prepare_rotation_wrapper_data($pano_response, $rotation);
604
605 $is_pro = apply_filters('is_wpvr_pro_active',false);
606 $status = get_option('wpvr_edd_license_status');
607 $pano_floor_plan = array();
608 $call_to_action = array();
609 if ($status !== false && 'valid' == $status && $is_pro) {
610 $pano_floor_plan = array(
611 "floor_plan_tour_enabler" => $floor_plan_enabler,
612 "floor_plan_attachment_url" => $floor_plan_image
613 );
614 if ( 'on' === $floor_plan_enabler ) {
615 do_action( 'wpvr_floor_plan_configured', $postid, $pano_floor_plan );
616 }
617 $call_to_action = array(
618 'button_enable' =>sanitize_text_field(wp_unslash( $_POST['callToAction'] )),
619 'button_text' =>sanitize_text_field(wp_unslash( $_POST['buttontext'] )),
620 'button_url' =>sanitize_text_field(wp_unslash( $_POST['buttonurl'] ))
621 );
622 }
623
624 $response = array();
625 $response = array($pano_id_array, $pano_response, $panovideo,$pano_floor_plan,$call_to_action);
626 wp_send_json_success($response);
627 }
628
629
630 /**
631 * Render shortcode for scene and hotspot post data
632 *
633 * @param array $postdata
634 * @param string $panoid
635 * @param integer $id
636 * @param mixed $radius
637 * @param mixed $width
638 * @param mixed $height
639 *
640 * @return string
641 * @since 8.0.0
642 */
643 public function render_scene_shortcode($postdata, $panoid, $id, $radius, $width, $height, $mobile_height)
644 {
645 if (
646 ( isset( $_GET['bricks'] ) && wp_unslash( $_GET['bricks'] ) === 'run' ) ||
647 ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['action'] ) && wp_unslash( $_REQUEST['action'] ) === 'bricks_render_element' ) ||
648 ( defined('REST_REQUEST') && REST_REQUEST && isset($_SERVER['REQUEST_URI']) && strpos( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/wp-json/bricks/v1/render_element') !== false )
649 ) {
650 return esc_html__('Bricks Editor Mode - WPVR Preview is not available.', 'wpvr');
651 }
652
653 do_action('rex_wpvr_embadded_tour', $id);
654
655 $control = false;
656 if (isset($postdata['showControls'])) {
657 $control = $postdata['showControls'];
658 }
659
660 if ($control) {
661 if (isset($postdata['customcontrol']) && is_array($postdata['customcontrol'])) {
662 $custom_control = $postdata['customcontrol'];
663 $custom_control['gyroSwitch'] = isset($postdata['gyro']) && $postdata['gyro'] ? 'on' : 'off';
664 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") {
665 $control = false;
666 }
667 }
668 }
669
670 $vrgallery = false;
671 if (isset($postdata['vrgallery'])) {
672 $vrgallery = $postdata['vrgallery'];
673 }
674
675 $vrgallery_title = false;
676 if (isset($postdata['vrgallery_title'])) {
677 $vrgallery_title = $postdata['vrgallery_title'];
678 }
679
680 $vrgallery_display = false;
681 if (isset($postdata['vrgallery_display'])) {
682 $vrgallery_display = $postdata['vrgallery_display'];
683 }
684 $vrgallery_icon_size = false;
685 if (isset($postdata['vrgallery_icon_size'])) {
686 $vrgallery_icon_size = $postdata['vrgallery_icon_size'];
687 }
688 $gyro = false;
689 $gyro_orientation = false;
690 if (isset($postdata['gyro'])) {
691 $gyro = $postdata['gyro'];
692 if (isset($postdata['deviceorientationcontrol'])) {
693 $gyro_orientation = $postdata['deviceorientationcontrol'];
694 }
695 }
696 //== Floor plan handle ==//
697 $floor_plan_enable = 'off';
698 $floor_plan_image = '';
699 if (isset($postdata['floor_plan_tour_enabler']) && $postdata['floor_plan_tour_enabler'] == 'on'){
700 $floor_plan_enable = $postdata['floor_plan_tour_enabler'];
701 if(isset($postdata['floor_plan_attachment_url']) && !empty($postdata['floor_plan_attachment_url'])){
702 $floor_plan_image = $postdata['floor_plan_attachment_url'];
703 }
704 }
705
706 $compass = false;
707 $audio_right = "5px";
708 if (isset($postdata['compass'])) {
709 $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
710 if ($compass) {
711 $audio_right = "60px";
712 }
713 }
714 $floor_map_right = "25px";
715 if((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')){
716 $floor_map_right = "85px";
717 }elseif(isset($postdata['compass']) && $postdata['compass'] == 'on'){
718 $floor_map_right = "55px";
719 }elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
720 $floor_map_right = "25px";
721 }
722
723
724 //===explainer handle===//
725
726 $explainer_right = "10px";
727 if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ( $floor_plan_enable == 'on' && !empty($floor_plan_image) ) ) {
728 $explainer_right = "130px";
729 } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on' && ($floor_plan_enable == 'on' && !empty($floor_plan_image) )) {
730 $explainer_right = "100px";
731 } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image) )) {
732 $explainer_right = "55px";
733 } elseif((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') ) {
734 $explainer_right = "80px";
735 }elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
736 $explainer_right = "55px";
737 } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
738 $explainer_right = "30px";
739 } elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image) ) {
740 $explainer_right = "70px";
741 }
742
743
744 $enable_cardboard = '';
745 $is_cardboard = get_option('wpvr_cardboard_disable');
746 if(wpvr_isMobileDevice() && $is_cardboard == 'true' ){
747 $enable_cardboard = 'enable-cardboard';
748 $audio_right = "73px";
749 if (isset($postdata['compass'])) {
750 $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
751 if ($compass) {
752 $audio_right = "130px";
753 }
754 }
755 //===Floor plan handle===//
756 $floor_map_right = "60px";
757 if((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')){
758 $floor_map_right = "150px";
759 }elseif(isset($postdata['compass']) && $postdata['compass'] == 'on'){
760 $floor_map_right = "120px";
761 }elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
762 $floor_map_right = "90px";
763 }
764
765 //===explainer handle===//
766 $explainer_right = "65px";
767
768 if ((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
769 $explainer_right = "150px";
770 } elseif((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ($floor_plan_enable == 'on' && !empty($floor_plan_image) )) {
771 $explainer_right = "180px";
772 } elseif (isset($postdata['compass']) && $postdata['compass'] == true && ($floor_plan_enable == 'on' && !empty($floor_plan_image) )) {
773 $explainer_right = "150px";
774 } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image) )) {
775 $explainer_right = "120px";
776 }elseif (isset($postdata['compass']) && $postdata['compass'] == true) {
777 $explainer_right = "130px";
778 } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
779 $explainer_right = "90px";
780 }elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image) ) {
781 $explainer_right = "90px";
782 }
783 }
784
785 //===explainer handle===//
786
787 $mouseZoom = true;
788 if (isset($postdata['mouseZoom'])) {
789 if($postdata['mouseZoom'] == "off") {
790 $mouseZoom = false;
791 }
792 else {
793 $mouseZoom = true;
794 }
795 }
796
797 $draggable = true;
798 if (isset($postdata['draggable'])) {
799 $draggable = $postdata['draggable'] == 'off' || $postdata['draggable'] == null ? false : true;
800 }
801
802 $diskeyboard = false;
803 if (isset($postdata['diskeyboard'])) {
804 $diskeyboard = $postdata['diskeyboard'] == 'off' || $postdata['diskeyboard'] == null ? false : true;
805 }
806
807 $keyboardzoom = true;
808 if (isset($postdata['keyboardzoom'])) {
809 $keyboardzoom = $postdata['keyboardzoom'];
810 }
811
812 $autoload = false;
813
814 if (isset($postdata['autoLoad'])) {
815 $autoload = $postdata['autoLoad'];
816 }
817
818 $default_scene = '';
819 if (isset($postdata['defaultscene'])) {
820 $default_scene = $postdata['defaultscene'];
821 }
822
823 $default_global_zoom = '';
824 if (isset($postdata['hfov'])) {
825 $default_global_zoom = $postdata['hfov'];
826 }
827
828 $max_global_zoom = '';
829 if (isset($postdata['maxHfov'])) {
830 $max_global_zoom = $postdata['maxHfov'];
831 }
832
833 $min_global_zoom = '';
834 if (isset($postdata['minHfov'])) {
835 $min_global_zoom = $postdata['minHfov'];
836 }
837
838 $preview = '';
839 if (isset($postdata['preview'])) {
840 $preview = $postdata['preview'];
841 }
842
843 $autorotation = '';
844 if (isset($postdata["autoRotate"])) {
845 $autorotation = $postdata["autoRotate"];
846 }
847 $autorotationinactivedelay = '';
848 if (isset($postdata["autoRotateInactivityDelay"])) {
849 $autorotationinactivedelay = $postdata["autoRotateInactivityDelay"];
850 }
851 $autorotationstopdelay = '';
852 if (isset($postdata["autoRotateStopDelay"])) {
853 $autorotationstopdelay = $postdata["autoRotateStopDelay"];
854 }
855
856 $scene_fade_duration = '';
857 if (isset($postdata['scenefadeduration'])) {
858 $scene_fade_duration = $postdata['scenefadeduration'];
859 }
860
861 $panodata = '';
862 if (isset($postdata['panodata'])) {
863 $panodata = $postdata['panodata'];
864 }
865
866 $hotspoticoncolor = '#00b4ff';
867 $hotspotblink = 'on';
868 $default_data = array();
869 if ($default_global_zoom != '' && $max_global_zoom != '' && $min_global_zoom != '') {
870 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration, "hfov" => $default_global_zoom, "maxHfov" => $max_global_zoom, "minHfov" => $min_global_zoom);
871 } else {
872 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration);
873 }
874
875 $scene_data = array();
876
877 if (!empty($panodata["scene-list"])) {
878 foreach ($panodata["scene-list"] as $panoscenes) {
879 $scene_ititle = '';
880 if (isset($panoscenes["scene-ititle"])) {
881 $scene_ititle = sanitize_text_field($panoscenes["scene-ititle"]);
882 }
883
884 $scene_author = '';
885 if (isset($panoscenes["scene-author"])) {
886 $scene_author = sanitize_text_field($panoscenes["scene-author"]);
887 }
888
889 $scene_author_url = '';
890 if (isset($panoscenes["scene-author-url"])) {
891 $scene_author_url = esc_url($panoscenes["scene-author-url"]);
892 }
893
894 $scene_vaov = 180;
895 if (isset($panoscenes["scene-vaov"])) {
896 $scene_vaov = (float)$panoscenes["scene-vaov"];
897 }
898
899 $scene_haov = 360;
900 if (isset($panoscenes["scene-haov"])) {
901 $scene_haov = (float)$panoscenes["scene-haov"];
902 }
903
904
905 $scene_vertical_offset = 0;
906 if (isset($panoscenes["scene-vertical-offset"])) {
907 $scene_vertical_offset = (float)$panoscenes["scene-vertical-offset"];
908 }
909
910 $default_scene_pitch = null;
911 if (isset($panoscenes["scene-pitch"])) {
912 $default_scene_pitch = (float)$panoscenes["scene-pitch"];
913 }
914
915 $default_scene_yaw = null;
916 if (isset($panoscenes["scene-yaw"])) {
917 $default_scene_yaw = (float)$panoscenes["scene-yaw"];
918 }
919
920 $scene_max_pitch = '';
921 if (isset($panoscenes["scene-maxpitch"])) {
922 $scene_max_pitch = (float)$panoscenes["scene-maxpitch"];
923 }
924
925
926 $scene_min_pitch = '';
927 if (isset($panoscenes["scene-minpitch"])) {
928 $scene_min_pitch = (float)$panoscenes["scene-minpitch"];
929 }
930
931
932 $scene_max_yaw = '';
933 if (isset($panoscenes["scene-maxyaw"])) {
934 $scene_max_yaw = (float)$panoscenes["scene-maxyaw"];
935 }
936
937
938 $scene_min_yaw = '';
939 if (isset($panoscenes["scene-minyaw"])) {
940 $scene_min_yaw = (float)$panoscenes["scene-minyaw"];
941 }
942
943 $default_zoom = 100;
944 if (isset($panoscenes["scene-zoom"]) && $panoscenes["scene-zoom"] != "") {
945 $default_zoom = $panoscenes["scene-zoom"];
946 } else {
947 if ($default_global_zoom != '') {
948 $default_zoom = (int)$default_global_zoom;
949 }
950 }
951
952
953 $max_zoom = 120;
954 if (isset($panoscenes["scene-maxzoom"]) && $panoscenes["scene-maxzoom"] != '') {
955 $max_zoom = (int)$panoscenes["scene-maxzoom"];
956 } else {
957 if ($max_global_zoom != '') {
958 $max_zoom = (int)$max_global_zoom;
959 }
960 }
961
962
963
964 $min_zoom = 50;
965 if (isset($panoscenes["scene-minzoom"]) && $panoscenes["scene-minzoom"] != '') {
966 $min_zoom = (int)$panoscenes["scene-minzoom"];
967 } else {
968 if ($min_global_zoom != '') {
969 $min_zoom = (int)$min_global_zoom;
970 }
971 }
972
973
974 $hotspot_datas = array();
975 if (isset($panoscenes["hotspot-list"])) {
976 $hotspot_datas = $panoscenes["hotspot-list"];
977 }
978
979 $hotspots = array();
980
981
982 foreach ($hotspot_datas as $hotspot_data) {
983 $status = get_option('wpvr_edd_license_status');
984 if ($status !== false && $status == 'valid') {
985 if (isset($hotspot_data["hotspot-customclass-pro"]) && $hotspot_data["hotspot-customclass-pro"] != 'none') {
986 $hotspot_data['hotspot-customclass'] = $hotspot_data["hotspot-customclass-pro"] . ' custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot_data['hotspot-title']);
987 }
988 if (isset($hotspot_data['hotspot-blink'])) {
989 $hotspotblink = $hotspot_data['hotspot-blink'];
990 }
991 }
992 $hotspot_scene_pitch = '';
993 if (isset($hotspot_data["hotspot-scene-pitch"])) {
994 $hotspot_scene_pitch = $hotspot_data["hotspot-scene-pitch"];
995 }
996 $hotspot_scene_yaw = '';
997 if (isset($hotspot_data["hotspot-scene-yaw"])) {
998 $hotspot_scene_yaw = $hotspot_data["hotspot-scene-yaw"];
999 }
1000
1001 $hotspot_type = $hotspot_data["hotspot-type"] !== 'scene' ? 'info' : $hotspot_data["hotspot-type"];
1002 $hotspot_content = '';
1003
1004 ob_start();
1005 do_action('wpvr_hotspot_content', $hotspot_data);
1006 $hotspot_content = ob_get_clean();
1007
1008 if (!$hotspot_content) {
1009 $hotspot_content = $hotspot_data["hotspot-content"];
1010 }
1011
1012 if (isset($hotspot_data["wpvr_url_open"][0])) {
1013 $wpvr_url_open = $hotspot_data["wpvr_url_open"][0];
1014 } else {
1015 $wpvr_url_open = "off";
1016 }
1017 $on_hover_content = preg_replace_callback(
1018 '/<p>\s*(<img[^>]*>)\s*<br>\s*<\/p>/i',
1019 function ($matches) {
1020 return $matches[1];
1021 },
1022 $hotspot_data['hotspot-hover'] ?? ''
1023 );
1024
1025
1026 if('fluent_form' !== $hotspot_data["hotspot-type"]){
1027 $on_hover_content = $this->sanitize_content_preserve_styles($on_hover_content ?? '');
1028 $on_click_content = preg_replace_callback('/<img[^>]*>/', "replace_callback", $hotspot_content ?? '');
1029 $on_click_content = $this->sanitize_content_preserve_styles($on_click_content ?? '');
1030 }else{
1031 $on_hover_content = $on_hover_content ?? '';
1032 $on_click_content = $hotspot_content ?? '';
1033 }
1034
1035 $hotspot_shape = 'round';
1036 if (isset($hotspot_data["hotspot-customclass-pro"]) && $hotspot_data["hotspot-customclass-pro"] != 'none') {
1037 $hotspot_shape = isset($hotspot_data["hotspot-shape"]) ? $hotspot_data["hotspot-shape"] : 'round';
1038 }
1039 $hotspot_data_for_on_click=[];
1040 if( ('info' === $hotspot_type || 'fluent_form' === $hotspot_data["hotspot-type"]) && !empty($on_click_content)){
1041 $hotspot_data_for_on_click = [
1042 'on_click_content' => $on_click_content,
1043 'tour_id' => $id,
1044 'scene_id' => $panoscenes['scene-id'],
1045 'hotspot_id' => sanitize_html_class($hotspot_data['hotspot-title']),
1046 ];
1047 } elseif('info' === $hotspot_type && !empty($hotspot_data["hotspot-url"])){
1048 $hotspot_data_for_on_click = [
1049 'on_click_content' => '',
1050 'tour_id' => $id,
1051 'scene_id' => $panoscenes['scene-id'],
1052 'hotspot_id' => sanitize_html_class($hotspot_data['hotspot-title']),
1053 ];
1054 }
1055
1056 $hotspot_info = array(
1057 "text" => esc_html(sanitize_text_field($hotspot_data["hotspot-title"])),
1058 "pitch" => $hotspot_data["hotspot-pitch"],
1059 "yaw" => $hotspot_data["hotspot-yaw"],
1060 "type" => $hotspot_type,
1061 "cssClass" => $hotspot_data["hotspot-customclass"],
1062 "URL" => $hotspot_data["hotspot-url"],
1063 "wpvr_url_open" => $wpvr_url_open,
1064 "clickHandlerArgs" => $hotspot_data_for_on_click,
1065 'createTooltipArgs' => !empty(trim($on_hover_content)) ? trim($on_hover_content) : '',
1066 "sceneId" => $hotspot_data["hotspot-scene"],
1067 "targetPitch" => (float)$hotspot_scene_pitch,
1068 "targetYaw" => (float)$hotspot_scene_yaw,
1069 'hotspot_type' => $hotspot_data['hotspot-type'],
1070 'hotspot_target' => 'notBlank',
1071 'hotspot_shape' => $hotspot_shape,
1072 );
1073 $hotspot_info['URL'] = ($hotspot_data['hotspot-type'] === 'fluent_form' || $hotspot_data['hotspot-type'] === 'wc_product') ? '' : $hotspot_info['URL'];
1074
1075 if ($hotspot_data["hotspot-customclass"] == 'none' || $hotspot_data["hotspot-customclass"] == '') {
1076 unset($hotspot_info["cssClass"]);
1077 }
1078 if (empty($hotspot_data["hotspot-scene"])) {
1079 unset($hotspot_info['targetPitch']);
1080 unset($hotspot_info['targetYaw']);
1081 }
1082 array_push($hotspots, $hotspot_info);
1083 }
1084
1085 $device_scene = $panoscenes['scene-attachment-url'];
1086 $mobile_media_resize = get_option('mobile_media_resize');
1087 $file_accessible = ini_get('allow_url_fopen');
1088 if ($mobile_media_resize == "true" && $device_scene ) {
1089 if ($file_accessible == "1") {
1090 $image_info = getimagesize($device_scene);
1091 if ( isset($image_info[0]) && $image_info[0] > 4096) {
1092 $src_to_id_for_mobile = '';
1093 $src_to_id_for_desktop = '';
1094 if (wpvr_isMobileDevice()) {
1095 $src_to_id_for_mobile = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1096 if ($src_to_id_for_mobile) {
1097 $mobile_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'wpvr_mobile');
1098 if ($mobile_scene[3]) {
1099 $device_scene = $mobile_scene[0];
1100 }
1101 }
1102 } else {
1103 $src_to_id_for_desktop = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1104 if ($src_to_id_for_desktop) {
1105 $desktop_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'full');
1106 if (isset($desktop_scene[0])) {
1107 $device_scene = $desktop_scene[0];
1108 }
1109 }
1110 }
1111 }
1112 }
1113 }
1114
1115 $scene_info = array();
1116
1117 if ($panoscenes["scene-type"] == 'cubemap') {
1118 $pano_attachment = array(
1119 $panoscenes["scene-attachment-url-face0"],
1120 $panoscenes["scene-attachment-url-face1"],
1121 $panoscenes["scene-attachment-url-face2"],
1122 $panoscenes["scene-attachment-url-face3"],
1123 $panoscenes["scene-attachment-url-face4"],
1124 $panoscenes["scene-attachment-url-face5"]
1125 );
1126
1127 $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);
1128 } else {
1129 $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);
1130 }
1131
1132
1133 if (isset($panoscenes["ptyscene"])) {
1134 if ($panoscenes["ptyscene"] == "off") {
1135 unset($scene_info['pitch']);
1136 unset($scene_info['yaw']);
1137 }
1138 }
1139
1140 if (empty($panoscenes["scene-ititle"])) {
1141 unset($scene_info['title']);
1142 }
1143 if (empty($panoscenes["scene-author"])) {
1144 unset($scene_info['author']);
1145 }
1146 if (empty($panoscenes["scene-author-url"])) {
1147 unset($scene_info['authorURL']);
1148 }
1149
1150 if (empty($scene_vaov)) {
1151 unset($scene_info['vaov']);
1152 }
1153
1154 if (empty($scene_haov)) {
1155 unset($scene_info['haov']);
1156 }
1157
1158 if (empty($scene_vertical_offset)) {
1159 unset($scene_info['vOffset']);
1160 }
1161
1162 if (isset($panoscenes["cvgscene"])) {
1163 if ($panoscenes["cvgscene"] == "off") {
1164 unset($scene_info['maxPitch']);
1165 unset($scene_info['minPitch']);
1166 }
1167 }
1168 if (empty($panoscenes["scene-maxpitch"])) {
1169 unset($scene_info['maxPitch']);
1170 }
1171
1172 if (empty($panoscenes["scene-minpitch"])) {
1173 unset($scene_info['minPitch']);
1174 }
1175
1176 if (isset($panoscenes["chgscene"])) {
1177 if ($panoscenes["chgscene"] == "off") {
1178 unset($scene_info['maxYaw']);
1179 unset($scene_info['minYaw']);
1180 }
1181 }
1182 if (empty($panoscenes["scene-maxyaw"])) {
1183 unset($scene_info['maxYaw']);
1184 }
1185
1186 if (empty($panoscenes["scene-minyaw"])) {
1187 unset($scene_info['minYaw']);
1188 }
1189
1190 // if (isset($panoscenes["czscene"])) {
1191 // if ($panoscenes["czscene"] == "off") {
1192 // unset($scene_info['hfov']);
1193 // unset($scene_info['maxHfov']);
1194 // unset($scene_info['minHfov']);
1195 // }
1196 // }
1197
1198 $scene_array = array();
1199 $scene_array = array(
1200 $panoscenes["scene-id"] => $scene_info
1201 );
1202 $scene_data[$panoscenes["scene-id"]] = $scene_info;
1203 }
1204 }
1205
1206 $pano_id_array = array();
1207 $pano_id_array = array("panoid" => $panoid);
1208 $pano_response = array();
1209 $pano_response = array("autoLoad" => $autoload, "showControls" => $control, "orientationSupport" => 'false', "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);
1210 if (empty($autorotation)) {
1211 unset($pano_response['autoRotate']);
1212 unset($pano_response['autoRotateInactivityDelay']);
1213 unset($pano_response['autoRotateStopDelay']);
1214 }
1215 if (empty($autorotationinactivedelay)) {
1216 unset($pano_response['autoRotateInactivityDelay']);
1217 }
1218 if (empty($autorotationstopdelay)) {
1219 unset($pano_response['autoRotateStopDelay']);
1220 }
1221 $response = array();
1222 $response = array($pano_id_array, $pano_response);
1223 if (!empty($response)) {
1224 $response = json_encode($response);
1225 }
1226
1227
1228 if (empty($width)) {
1229 $width = '600px';
1230 }
1231 if (empty($height)) {
1232 $height = '400px';
1233 }
1234 $foreground_color = '#fff';
1235 $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1236 $rgb = wpvr_HTMLToRGB($hotspoticoncolor);
1237 $hsl = wpvr_RGBToHSL($rgb);
1238 if ($hsl->lightness > 200) {
1239 $foreground_color = '#000000';
1240 } else {
1241 $foreground_color = '#fff';
1242 }
1243 $html = '';
1244
1245 $html .= '<style>';
1246 if ($width == 'embed') {
1247 $html .= 'body{
1248 overflow: hidden;
1249 }';
1250 }
1251 $status = get_option('wpvr_edd_license_status');
1252 if ($status !== false && $status == 'valid') {
1253 if(isset($postdata['customcss_enable']) && $postdata['customcss_enable'] == 'on'){
1254 $html .= isset($postdata['customcss']) ? $postdata['customcss'] : '';
1255 }
1256 }
1257 $panoid2 = 'pano2'.$id;
1258 $status = get_option('wpvr_edd_license_status');
1259 if ($status !== false && $status == 'valid') {
1260 foreach ($panodata['scene-list'] as $panoscenes){
1261
1262 foreach($panoscenes['hotspot-list'] as $hotspot){
1263 if (isset($hotspot['hotspot-customclass-color-icon-value']) && !empty($hotspot['hotspot-customclass-color-icon-value'])) {
1264 $hotspoticoncolor = $hotspot['hotspot-customclass-color-icon-value'];
1265 } else {
1266 $hotspoticoncolor = "#00b4ff";
1267 }
1268 $hotspot_border = '';
1269 if(isset($hotspot['hotspot-border']) && $hotspot['hotspot-border'] == 'on'){
1270 $border_width = $hotspot['hotspot-border-width'];
1271 $border_color = $hotspot['hotspot-border-color'];
1272 $border_style = $hotspot['hotspot-border-style'];
1273 $hotspot_border = 'border: '.$border_width.'px '.$border_style.' '.$border_color.';';
1274 }
1275 $hotspot_background_color = 'background-color: ' . $hotspoticoncolor . ';';
1276 $hotspot_animation = ' animation: icon-pulse' . $panoid . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1277 '. $hotspot_border.'';
1278 $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1279 if (isset($hotspot["hotspot-customclass-pro"]) && $hotspot["hotspot-customclass-pro"] != 'none') {
1280 $border_radius = ' border-radius: 100%;';
1281 $hotspot_shape = isset($hotspot["hotspot-shape"]) ? $hotspot["hotspot-shape"] : 'round';
1282 if($hotspot_shape === 'square'){
1283 $border_radius = '';
1284 }
1285 if ($hotspot_shape === 'hexagon') {
1286 $border_radius = '';
1287 $hotspot_background_color = 'background-color: transparent;';
1288 $hotspot_animation = '';
1289 }
1290
1291 if(isset($hotspot['hotspot-custom-icon-color-value']) && !empty($hotspot['hotspot-custom-icon-color-value'])){
1292 $foreground_color = $hotspot['hotspot-custom-icon-color-value'];
1293 }
1294
1295 $html .= '#' . $panoid . ' div.pnlm-hotspot-base.fas.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1296 #' . $panoid . ' div.pnlm-hotspot-base.fab.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1297 #' . $panoid . ' div.pnlm-hotspot-base.fa-solid.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1298 #' . $panoid . ' div.pnlm-hotspot-base.fa.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1299 #' . $panoid . ' div.pnlm-hotspot-base.far.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).' {
1300 display: block !important;
1301 '.$hotspot_background_color.'
1302 color: ' . $foreground_color . ';
1303 '.$border_radius.'
1304 width: 30px;
1305 height: 30px;
1306 font-size: 16px;
1307 line-height: 30px;
1308 '.$hotspot_animation.'
1309 }';
1310
1311 if($hotspot_shape === 'hexagon'){
1312
1313 $html .= '#' . $panoid . ' .custom-' . $id . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' .hexagon-wrapper svg path {
1314 fill: ' . $hotspoticoncolor . ';
1315 }';
1316
1317 $html .= '#' . $panoid . ' .custom-' . $id . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . '.pnlm-tooltip:after{
1318 content: "";
1319 position: absolute;
1320 left: 50%;
1321 top: 50%;
1322 transform: translate(-50%, -50%);
1323 width: 85%;
1324 height: 85%;
1325 animation: icon-pulse' . $panoid . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1326 border-radius: 100%;
1327 z-index: -2;
1328 }';
1329
1330 }
1331
1332 $html .= '#' . $panoid2 . ' div.pnlm-hotspot-base.fas.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1333 #' . $panoid2 . ' div.pnlm-hotspot-base.fab.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1334 #' . $panoid2 . ' div.pnlm-hotspot-base.fa-solid.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1335 #' . $panoid2 . ' div.pnlm-hotspot-base.fa.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).',
1336 #' . $panoid2 . ' div.pnlm-hotspot-base.far.custom-' . $id.'-' . $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']).' {
1337 display: block !important;
1338 '.$hotspot_background_color.'
1339 color: ' . $foreground_color . ';
1340 '.$border_radius.'
1341 width: 30px;
1342 height: 30px;
1343 font-size: 16px;
1344 line-height: 30px;
1345 '.$hotspot_animation.'
1346 }';
1347 }
1348 if (isset($hotspot['hotspot-blink'])) {
1349 $hotspotblink = $hotspot['hotspot-blink'];
1350 if ($hotspotblink == 'on') {
1351 $html .= '@-webkit-keyframes icon-pulse' .$panoid .'-'. $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']) .' {
1352 0% {
1353 box-shadow: 0 0 0 0px rgba(' . $pulse_color[0] . ', 1);
1354 }
1355 100% {
1356 box-shadow: 0 0 0 10px rgba(' . $pulse_color[0] . ', 0);
1357 }
1358 }
1359 @keyframes icon-pulse' . $panoid . ' {
1360 0% {
1361 box-shadow: 0 0 0 0px rgba(' . $pulse_color[0] . ', 1);
1362 }
1363 100% {
1364 box-shadow: 0 0 0 10px rgba(' . $pulse_color[0] . ', 0);
1365 }
1366 }';
1367 $html .= '@-webkit-keyframes icon-pulse' .$panoid2 .'-'. $panoscenes['scene-id'] .'-'. sanitize_html_class($hotspot['hotspot-title']) .' {
1368 0% {
1369 box-shadow: 0 0 0 0px rgba(' . $pulse_color[0] . ', 1);
1370 }
1371 100% {
1372 box-shadow: 0 0 0 10px rgba(' . $pulse_color[0] . ', 0);
1373 }
1374 }
1375 @keyframes icon-pulse' . $panoid . ' {
1376 0% {
1377 box-shadow: 0 0 0 0px rgba(' . $pulse_color[0] . ', 1);
1378 }
1379 100% {
1380 box-shadow: 0 0 0 10px rgba(' . $pulse_color[0] . ', 0);
1381 }
1382 }';
1383 }
1384 }
1385
1386 }
1387
1388 }
1389
1390 }
1391
1392 $status = get_option('wpvr_edd_license_status');
1393 if ($status !== false && $status == 'valid') {
1394 if (!$gyro) {
1395 $html .= '#' . $panoid . ' div.pnlm-orientation-button {
1396 display: none;
1397 }';
1398 }
1399 } else {
1400 $html .= '#' . $panoid . ' div.pnlm-orientation-button {
1401 display: none;
1402 }';
1403 }
1404 $floor_plan_custom_color = isset($postdata['floor_plan_custom_color']) ? $postdata['floor_plan_custom_color'] : '#cca92c';
1405 $foreground_color_pointer = '#fff';
1406 if($floor_plan_custom_color != ''){
1407 $pointer_pulse = wpvr_hex2rgb($floor_plan_custom_color);
1408 $floor_rgb = wpvr_HTMLToRGB($floor_plan_custom_color);
1409 $floor_hsl = wpvr_RGBToHSL($floor_rgb);
1410 if ($floor_hsl->lightness > 200) {
1411 $foreground_color_pointer = '#000000';
1412 }
1413 $html .= '
1414 .wpvr-floor-map .floor-plan-pointer.add-pulse:before {
1415 border: 17px solid '.$floor_plan_custom_color.';
1416 }
1417 @-webkit-keyframes pulse {
1418 0% {
1419 -webkit-box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0.7);
1420 }
1421 70% {
1422 -webkit-box-shadow: 0 0 0 10px rgba('.$pointer_pulse[0].', 0);
1423 }
1424 100% {
1425 -webkit-box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0);
1426 }
1427 }
1428 @keyframes pulse {
1429 0% {
1430 -moz-box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0.7);
1431 box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0.7);
1432 }
1433 70% {
1434 -moz-box-shadow: 0 0 0 10px rgba('.$pointer_pulse[0].', 0);
1435 box-shadow: 0 0 0 10px rgba('.$pointer_pulse[0].', 0);
1436 }
1437 100% {
1438 -moz-box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0);
1439 box-shadow: 0 0 0 0 rgba('.$pointer_pulse[0].', 0);
1440 }
1441 }';
1442 }
1443
1444 $html .= '</style>';
1445
1446
1447 $scene_animation = isset($postdata['sceneAnimation']) ? $postdata['sceneAnimation'] : 'off';
1448
1449 if( $scene_animation === 'on' && is_plugin_active( 'wpvr-pro/wpvr-pro.php' ) ) {
1450 $animation_type = isset($postdata['sceneAnimationName']) ? $postdata['sceneAnimationName'] : 'none';
1451 $animationDuration = isset($postdata['sceneAnimationTransitionDuration']) ? $postdata['sceneAnimationTransitionDuration'] : '500ms';
1452 $animationDelay = isset($postdata['sceneAnimationTransitionDelay']) ? $postdata['sceneAnimationTransitionDelay'] : '0ms';
1453 $animation_css = apply_filters('wpvr_tour_scene_animation',$animation_type,$animationDuration,$animationDelay,$postdata,$id);
1454 $html .= $animation_css;
1455 }
1456
1457 if ($width == 'fullwidth') {
1458 $width = "100%";
1459 }
1460
1461 if (wpvr_isMobileDevice()) {
1462 $html .= '<div id="master-container" class="wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $mobile_height . '; border-radius:' . $radius . '; direction:ltr; ">';
1463 } else {
1464 $html .= '<div id="master-container" class="wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $height . '; border-radius:' . $radius . '; direction:ltr; ">';
1465 }
1466 $is_pro = apply_filters('is_wpvr_pro_active',false);
1467 $status = get_option('wpvr_edd_license_status');
1468 $is_cardboard = get_option('wpvr_cardboard_disable');
1469 if ($status !== false && 'valid' == $status && $is_pro && wpvr_isMobileDevice() && $is_cardboard == 'true' ) {
1470 $html .= '<button class="fullscreen-button">';
1471 $html .= '<span class="expand">';
1472 $html .= '<i class="fas fa-expand" aria-hidden="true"></i>';
1473 $html .= '</span>';
1474
1475 $html .= '<span class="compress">';
1476 $html .= '<i class="fas fa-minimize" aria-hidden="true"></i>';
1477 $html .= '</span>';
1478 $html .= '</button>';
1479 $embed_mode = '';
1480 if($width == "embed"){
1481 $embed_mode = "vr-embade-mode";
1482 }
1483 $html .= '<label class="wpvr-cardboard-switcher '.$embed_mode.'">
1484 <input type="checkbox" class="vr_mode_change' . $id . '" name="vr_mode_change" value="off">
1485 <span class="switcher-box">
1486 <span class="normal-mode-tooltip">Normal VR Mode</span>
1487 <svg width="78" height="60" viewBox="0 0 78 60" fill="none" xmlns="http://www.w3.org/2000/svg">
1488 <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"/>
1489 </svg>
1490 </span>
1491 </label>';
1492
1493 }
1494
1495 if ($width == 'fullwidth') {
1496 if (wpvr_isMobileDevice()) {
1497 $html .= '<div class="cardboard-vrfullwidth vrfullwidth">';
1498 $html .= '<div id="pano2' . $id . '" class="pano-wrap pano-left cardboard-half" style="width: 49%!important; border-radius:' . $radius . ' text-align:center; direction:ltr;" ><div id="center-pointer2' . $id . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1499 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style="width: 100%; text-align:center; direction:ltr; border-radius:' . $radius . '" >';
1500 } else {
1501 $html .= '<div id="pano2' . $id . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . $radius . '"><div id="center-pointer2' . $id . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1502 if ($radius) {
1503 $html .= '<div id="pano' . $id . '" class="pano-wrap vrfullwidth" style=" text-align:center; height: ' . $height . '; border-radius:' . $radius . '; direction:ltr;" >';
1504 } else {
1505 $html .= '<div id="pano' . $id . '" class="pano-wrap vrfullwidth" style=" text-align:center; height: ' . $height . '; direction:ltr;" >';
1506 }
1507 }
1508 } elseif ($width == 'embed') {
1509 $html .= '<div class="cardboard-vrembed vrembed">';
1510 $html .= '<div id="pano2' . $id . '" class="pano-wrap pano-left" style=" width: 49%!important; text-align:center; direction:ltr;" ><div id="center-pointer2' . $id . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1511 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style=" text-align:center; direction:ltr;" >';
1512 } else {
1513 if (wpvr_isMobileDevice()) {
1514 $html .= '<div id="pano2' . $id . '" class="pano-wrap pano-left cardboard-half" style="width: 49%; border-radius:' . $radius . '"><div id="center-pointer2' . $id . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1515 if ($radius) {
1516 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style=" width: 100%; border-radius:' . $radius . ';">';
1517 } else {
1518 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style=" width: 100%; ">';
1519 }
1520 } else {
1521 $html .= '<div id="pano2' . $id . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . $radius . '"><div id="center-pointer2' . $id . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1522
1523 if ($radius) {
1524 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style="width: 100%; border-radius:' . $radius . ';">';
1525 } else {
1526 $html .= '<div id="pano' . $id . '" class="pano-wrap pano-right" style="width: 100%;">';
1527 }
1528 }
1529 }
1530 // Vr mode transction scene to scene
1531 if ($status !== false && 'valid' == $status && $is_pro) {
1532 $html .= '<div id="center-pointer' . $id . '" class="vr-pointer-container" style="display:none"><span class="center-pointer"></span></div>';
1533 }
1534 $social_logo_top = '';
1535 //===company logo===//
1536 if (isset($postdata['cpLogoSwitch'])) {
1537 $cpLogoImg = $postdata['cpLogoImg'];
1538 $cpLogoContent = $postdata['cpLogoContent'];
1539 if ($postdata['cpLogoSwitch'] == 'on' && 'valid' == $status && $is_pro) {
1540 $html .= '<div id="cp-logo-controls">';
1541 $html .= '<div class="cp-logo-ctrl" id="cp-logo">';
1542 if ($cpLogoImg) {
1543 $social_logo_top = '50px';
1544 $html .= '<img loading="lazy" src="' . $cpLogoImg . '" alt="Company Logo">';
1545 }
1546
1547 if ($cpLogoContent) {
1548 $html .= '<div class="cp-info">' . esc_attr($cpLogoContent) . '</div>';
1549 }
1550 $html .= '</div>';
1551 $html .= '</div>';
1552 }
1553 }
1554 //===company logo ends===//
1555
1556 //===Generic Form===//
1557 if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on' && 'valid' == $status && $is_pro) {
1558 // Process shortcode with fallback handling
1559 $shortcode_content = '';
1560 if (isset($postdata["genericformshortcode"]) && !empty(trim($postdata["genericformshortcode"]))) {
1561 $shortcode_content = do_shortcode( $postdata["genericformshortcode"] );
1562 } else {
1563 $shortcode_content = '<p class="error-message">No shortcode found.</p>';
1564 }
1565
1566 // Generate the form trigger button
1567 $html .= '<div class="generic_form_button" id="generic_form_button_' . esc_attr($id) . '">';
1568 $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>';
1569 $html .= '</div>';
1570
1571 // Generate the modal form container
1572 $html .= '<div class="wpvr-generic-form" id="wpvr-generic-form' . esc_attr($id) . '" style="display: none">';
1573 $html .= '<span class="close-generic-form"><i class="fa fa-times"></i></span>';
1574 $html .= '<div class="generic-form-container">' . $shortcode_content . '</div>';
1575 $html .= '</div>';
1576 }
1577 //===Generic Form ends===//
1578
1579 //===Background Tour===//
1580 if (isset($postdata['bg_tour_enabler'])) {
1581
1582 $bg_tour_enabler = $postdata['bg_tour_enabler'];
1583 if ($bg_tour_enabler == 'on') {
1584 $bg_tour_navmenu = $postdata['bg_tour_navmenu'] ?? 'off';
1585 $bg_tour_title = $postdata['bg_tour_title'] ?? '';
1586 $bg_tour_subtitle = $postdata['bg_tour_subtitle'] ?? '';
1587
1588 if ($bg_tour_navmenu == 'on') {
1589 $menuLocations = get_nav_menu_locations();
1590 if (!empty($menuLocations['primary'])) {
1591 $menuID = $menuLocations['primary'];
1592 $primaryNav = wp_get_nav_menu_items($menuID);
1593 $html .= '<ul class="wpvr-navbar-container">';
1594 foreach ($primaryNav as $primaryNav_key => $primaryNav_value) {
1595 if ($primaryNav_value->menu_item_parent == "0") {
1596 $html .= '<li>';
1597 $html .= '<a href="' . $primaryNav_value->url . '">' . $primaryNav_value->title . '</a>';
1598 $html .= '<ul class="wpvr-navbar-dropdown">';
1599 foreach ($primaryNav as $pm_key => $pm_value) {
1600 if ($pm_value->menu_item_parent == $primaryNav_value->ID) {
1601 $html .= '<li>';
1602 $html .= '<a href="' . $pm_value->url . '">' . $pm_value->title . '</a>';
1603 $html .= '</li>';
1604 }
1605 }
1606 $html .= '</ul>';
1607 $html .= '</li>';
1608 }
1609 }
1610 $html .= '</ul>';
1611 }
1612 }
1613 if($is_pro && 'valid' == $status ){
1614 $html .= '<div class="wpvr-home-content">';
1615 $html .= '<div class="wpvr-home-title">' . $bg_tour_title . '</div>';
1616 $html .= '<div class="wpvr-home-subtitle">' . $bg_tour_subtitle . '</div>';
1617 $html .= '</div>';
1618 }
1619 }
1620 }
1621 //===Background Tour End===//
1622
1623 //===Custom Control===//
1624 if (isset($custom_control)) {
1625 if ($custom_control['panZoomInSwitch'] == "on" || $custom_control['panZoomOutSwitch'] == "on" || ( $custom_control['gyroSwitch'] == "on" && $custom_control['gyroscopeSwitch'] == "on") || $custom_control['backToHomeSwitch'] == "on") {
1626 $html .= '<div id="zoom-in-out-controls' . $id . '" class="zoom-in-out-controls">';
1627
1628 if ($custom_control['backToHomeSwitch'] == "on" && 'valid' == $status && $is_pro) {
1629 $html .= '<div class="ctrl" id="backToHome' . $id . '"><i class="' . $custom_control['backToHomeIcon'] . '" style="color:' . $custom_control['backToHomeColor'] . ';"></i></div>';
1630 }
1631
1632 if ($custom_control['panZoomInSwitch'] == "on" && 'valid' == $status && $is_pro) {
1633 $html .= '<div class="ctrl" id="zoom-in' . $id . '"><i class="' . $custom_control['panZoomInIcon'] . '" style="color:' . $custom_control['panZoomInColor'] . ';"></i></div>';
1634 }
1635
1636 if ($custom_control['panZoomOutSwitch'] == "on" && 'valid' == $status && $is_pro) {
1637 $html .= '<div class="ctrl" id="zoom-out' . $id . '"><i class="' . $custom_control['panZoomOutIcon'] . '" style="color:' . $custom_control['panZoomOutColor'] . ';"></i></div>';
1638 }
1639 if ($custom_control['gyroSwitch'] == "on" && $custom_control['gyroscopeSwitch'] == "on" && 'valid' == $status && $is_pro) {
1640 $html .= '<div class="ctrl" id="gyroscope' . $id . '" ><i class="' . $custom_control['gyroscopeIcon'] . '" id="' . $custom_control['gyroscopeIcon'] . '" style="color:' . $custom_control['gyroscopeColor'] . ';"></i></div>';
1641 }
1642 $html .= '</div>';
1643 }
1644 //===zoom in out Control===//
1645
1646 if (($custom_control['panupSwitch'] == "on" || $custom_control['panDownSwitch'] == "on" || $custom_control['panLeftSwitch'] == "on" || $custom_control['panRightSwitch'] == "on" || $custom_control['panFullscreenSwitch'] == "on" ) && 'valid' == $status && $is_pro) {
1647 //===Custom Control===//
1648 $html .= '<div class="controls" id="controls' . $id . '">';
1649
1650 if ($custom_control['panupSwitch'] == "on") {
1651 $html .= '<div class="ctrl pan-up" id="pan-up' . $id . '"><i class="' . $custom_control['panupIcon'] . '" style="color:' . $custom_control['panupColor'] . ';"></i></div>';
1652 }
1653
1654 if ($custom_control['panDownSwitch'] == "on") {
1655 $html .= '<div class="ctrl pan-down" id="pan-down' . $id . '"><i class="' . $custom_control['panDownIcon'] . '" style="color:' . $custom_control['panDownColor'] . ';"></i></div>';
1656 }
1657
1658 if ($custom_control['panLeftSwitch'] == "on") {
1659 $html .= '<div class="ctrl pan-left" id="pan-left' . $id . '"><i class="' . $custom_control['panLeftIcon'] . '" style="color:' . $custom_control['panLeftColor'] . ';"></i></div>';
1660 }
1661
1662 if ($custom_control['panRightSwitch'] == "on") {
1663 $html .= '<div class="ctrl pan-right" id="pan-right' . $id . '"><i class="' . $custom_control['panRightIcon'] . '" style="color:' . $custom_control['panRightColor'] . ';"></i></div>';
1664 }
1665
1666 if ($custom_control['panFullscreenSwitch'] == "on") {
1667 $html .= '<div class="ctrl fullscreen" id="fullscreen' . $id . '"><i class="' . $custom_control['panFullscreenIcon'] . '" style="color:' . $custom_control['panFullscreenColor'] . ';"></i></div>';
1668 }
1669 $html .= '</div>';
1670 }
1671 }
1672 //===Custom Control===//
1673
1674 //===explainer button===//
1675 $html .= wpvr_render_explainer_button(
1676 isset( $custom_control ) ? $custom_control : null,
1677 $postdata,
1678 $is_pro,
1679 $autoload,
1680 $explainer_right,
1681 $id
1682 );
1683 //===explainer button end===//
1684
1685 //===Floor map button===//
1686 $status = get_option('wpvr_edd_license_status');
1687 if ($status !== false && 'valid' == $status && $is_pro){
1688 if ($floor_plan_enable == "on" && !empty($floor_plan_image)) {
1689 $html .= '<div class="floor_map_button" id="floor_map_button_' . $id . '" style="right:'.$floor_map_right.'">';
1690 $html .= '<div class="ctrl" id="floor_map_target_' . $id . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>';
1691 $html .= '</div>';
1692 }
1693 }
1694 //===floor map button===//
1695
1696 if ($vrgallery && 'valid' == $status && $is_pro ) {
1697 //===Carousal setup===//
1698 $size = '';
1699 if($vrgallery_icon_size){
1700 $size = 'vrg-icon-size-large';
1701 }
1702 $html .= '<div id="vrgcontrols' . $id . '" class="vrgcontrols">';
1703
1704 $html .= '<div class="vrgctrl' . $id . ' vrbounce '.$size.'">';
1705 $html .= '</div>';
1706 $html .= '</div>';
1707
1708 $html .= '<div id="sccontrols' . $id . '" class="scene-gallery vrowl-carousel owl-theme ">';
1709 if (isset($panodata["scene-list"])) {
1710 foreach ($panodata["scene-list"] as $panoscenes) {
1711 $scene_key = $panoscenes['scene-id'];
1712
1713 if ($vrgallery_title == 'on') {
1714 $scene_key_title = isset($panoscenes['scene-ititle']) ? sanitize_text_field($panoscenes['scene-ititle']) : '';
1715 } else {
1716 $scene_key_title = "";
1717 }
1718
1719 if ($panoscenes['scene-type'] == 'cubemap') {
1720 $img_src_url = $panoscenes['scene-attachment-url-face0'];
1721 } else {
1722 $img_src_url = $panoscenes['scene-attachment-url'];
1723 }
1724
1725 $src_to_id = attachment_url_to_postid($img_src_url);
1726 $thumbnail_array = wp_get_attachment_image_src($src_to_id, 'thumbnail');
1727 if ($thumbnail_array) {
1728 $thumbnail = $thumbnail_array[0];
1729 } else {
1730 $thumbnail = $img_src_url;
1731 }
1732
1733 if( isset($postdata['tourLayout']['layout']) && 'layout1' !== $postdata['tourLayout']['layout']) {
1734 $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>';
1735 }else {
1736 $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>';
1737 }
1738 }
1739 }
1740
1741 $html .= '</div>';
1742
1743 $html .= '
1744 <div class="owl-nav wpvr_slider_nav">
1745 <button type="button" role="presentation" class="owl-prev wpvr_owl_prev">
1746 <div class="nav-btn prev-slide"><i class="fa fa-angle-left"></i></div>
1747 </button>
1748 <button type="button" role="presentation" class="owl-next wpvr_owl_next">
1749 <div class="nav-btn next-slide"><i class="fa fa-angle-right"></i></div>
1750 </button>
1751 </div>
1752 ';
1753
1754 //===Carousal setup end===//
1755 }
1756
1757 //===Call TO action Button===//
1758 $bg_music = isset($postdata['bg_music']) ? $postdata['bg_music'] : 'off';
1759 $bg_music_url = isset($postdata['bg_music_url']) ? $postdata['bg_music_url'] : '';
1760 $autoplay_bg_music = isset($postdata['autoplay_bg_music']) ? $postdata['autoplay_bg_music'] : 'off';
1761 $loop_bg_music = isset($postdata['loop_bg_music']) ? $postdata['loop_bg_music'] : 'off';
1762
1763 $bg_loop = ($loop_bg_music === 'on') ? 'loop' : '';
1764 $autoplay_attr = ($autoplay_bg_music === 'on') ? 'autoplay' : '';
1765 $audio_muted_attr = ($autoplay_bg_music === 'on') ? 'muted' : '';
1766 $audio_icon_class = 'fa-volume-mute'; // Always start with mute icon
1767
1768 if ($bg_music === 'on' && 'valid' == $status && $is_pro) {
1769 $html .= '<div id="adcontrol' . esc_attr( $id ) . '" class="adcontrol" style="right:' . esc_attr( $audio_right ) . '">';
1770 $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 . '>
1771 <source src="' . esc_url($bg_music_url) . '" type="audio/mpeg">
1772 Your browser does not support the audio element.
1773 </audio>';
1774 $html .= '<button onclick="playPause' . esc_attr($id) . '()" class="ctrl audio_control" id="audio_control' . esc_attr($id) . '">
1775 <i id="vr-volume' . esc_attr($id) . '" class="wpvrvolumeicon' . esc_attr($id) . ' fas ' . esc_attr($audio_icon_class) . '" style="color:#fff;"></i>
1776 </button>';
1777 $html .= '</div>';
1778 }
1779 //===Explainer video section===//
1780 $explainerContent = "";
1781 if (isset($postdata['explainerContent'])) {
1782 $explainerContent = $this->wpvr_sanitize_iframe_only($postdata['explainerContent']);
1783 }
1784 $html .= '<div class="explainer" id="explainer' . $id . '" style="display: none">';
1785 $html .= '<span class="close-explainer-video"><i class="fa fa-times"></i></span>';
1786 $html .= '' . $explainerContent . '';
1787 $html .= '</div>';
1788 //===Explainer video section End===//
1789
1790 //===Scene navigation Control===//
1791 if (isset($postdata['scene_navigation']) && $postdata['scene_navigation'] === 'on' && 'valid' == $status && $is_pro) {
1792 $html .= '<style>
1793 #et-boc .et-l .pnlm-controls-container,
1794 .pnlm-controls-container{
1795 top: 33px;
1796 }
1797
1798 #et-boc .et-l .zoom-in-out-controls,
1799 .zoom-in-out-controls {
1800 top: 37px;
1801 }
1802 </style>';
1803 $html .= '<div id="custom-scene-navigation' . $id . '" class="custom-scene-navigation">
1804 <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>
1805 </div>
1806
1807 <div id="custom-scene-navigation-nav' . $id . '" class="custom-scene-navigation-nav">
1808 <ul></ul>
1809 </div>
1810 ';
1811 }
1812 //===Scene navigation Control===//
1813
1814
1815 if( 'embed' === $width){
1816 if(WPVR_Helper::is_enable_social_share($postdata) === 'on'){
1817 $html .= '<div id="wpvr-social-share-bg-box'.$id.'" class="wpvr-social-share-bg-box" style="top:'.$social_logo_top.'">
1818 <span class="share-btn-svg"><svg fill="none" viewBox="0 0 24 24" width="24" height="24" ><path fill="#1F1CF4" d="M18.4 2.4a3.2 3.2 0 00-3.2 3.2 3.2 3.2 0 00.075.67L8.01 9.901A3.2 3.2 0 005.6 8.8a3.2 3.2 0 101.325 6.112 3.2 3.2 0 001.086-.812l7.261 3.632a3.2 3.2 0 101.803-2.242c-.415.189-.786.466-1.085.81l-7.261-3.63A3.2 3.2 0 008.8 12a3.2 3.2 0 00-.075-.667L15.991 7.7a3.2 3.2 0 002.41 1.1 3.2 3.2 0 100-6.4z"/></svg></span>
1819 <nav class="wpvr-share-nav">
1820 '.WPVR_Helper::social_media_share_links_display_in_embed(home_url().'/?embed_page='. $id).'
1821 </nav>
1822 </div>';
1823 }
1824 }
1825 //===Floor plan section===//
1826 $floor_map_image = "";
1827 $floor_map_pointer = array();
1828 $floor_map_scene_id = '';
1829 $floor_plan_custom_color = '#cca92c';
1830 $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on';
1831
1832 if (isset($postdata['floor_plan_attachment_url'])) {
1833 $floor_map_image = $postdata['floor_plan_attachment_url'];
1834 $floor_map_pointer = $postdata['floor_plan_pointer_position'];
1835 $floor_map_scene_id = $postdata['floor_plan_data_list'];
1836 $floor_plan_custom_color = $postdata['floor_plan_custom_color'];
1837 }
1838 $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $id . '" style="display: none">';
1839 $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>';
1840 $html .= '<img loading="lazy" src="'.$floor_map_image.'">';
1841 foreach($floor_map_pointer as $key=> $pointer_position){
1842 $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id = "'.$floor_map_scene_id[$key]->value.'" id="'.$pointer_position->id.'" data-top="'.$pointer_position->data_top.'" data-left="'.$pointer_position->data_left.'" style="'.$pointer_position->style.'">
1843 <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1844 <circle cx="12" cy="12" r="11.5" stroke="'.$floor_plan_custom_color.'"/>
1845 <circle cx="12" cy="12" r="5" fill="'.$foreground_color_pointer.'"/>
1846 </svg>';
1847
1848 // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on"
1849 if ($floor_plan_direction_indicator === "on") {
1850 $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg">
1851 <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)"/>
1852 <defs>
1853 <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse">
1854 <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/>
1855 <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/>
1856 </linearGradient>
1857 </defs>
1858 </svg>';
1859 }
1860 $html .= '</div>';
1861 }
1862 $html .= '</div>';
1863 //===Floor plan section===//
1864
1865 $html .= '<div class="wpvr-hotspot-tweak-contents-wrapper" style="display: none">';
1866 $html .= '<i class="fa fa-times cross" data-id="' . $id . '"></i>';
1867 $html .= '<div class="wpvr-hotspot-tweak-contents-flex">';
1868 $html .= '<div class="wpvr-hotspot-tweak-contents">';
1869 ob_start();
1870 do_action('wpvr_hotspot_tweak_contents', $scene_data);
1871 $hotspot_content = ob_get_clean();
1872 $html .= $hotspot_content;
1873 $html .= '</div>';
1874 $html .= '</div>';
1875 $html .= '</div>';
1876
1877 $html .= '<div class="custom-ifram-wrapper" style="display: none;">';
1878 $html .= '<i class="fa fa-times cross" data-id="' . $id . '"></i>';
1879
1880 $html .= '<div class="custom-ifram-flex">';
1881 $html .= '<div class="custom-ifram">';
1882 $html .= '</div>';
1883 $html .= '</div>';
1884 $html .= '</div>';
1885
1886 $html .= '</div>';
1887 $html .= '</div>';
1888 if( "embed" == $width ){
1889 $html .= '</div>';
1890 }
1891
1892
1893 if ($status !== false && 'valid' == $status && $is_pro) {
1894 $call_to_action = isset($postdata['calltoaction']) ? $postdata['calltoaction'] : 'off';
1895 if( 'on' == $call_to_action){
1896 $buttontext = isset($postdata['buttontext']) ? $postdata['buttontext'] : '';
1897 $buttonurl = isset($postdata['buttonurl']) ? $postdata['buttonurl'] : '';
1898 $cta_btn_style = isset($postdata['button_configuration']) ? $postdata['button_configuration'] : array();
1899
1900 $button_open_new_tab = isset($cta_btn_style['button_open_new_tab']) ? $cta_btn_style['button_open_new_tab'] : "off";
1901 $target = '_self';
1902 $button_position = isset($cta_btn_style['button_position']) ? $cta_btn_style['button_position'] : "";
1903 $background_color = isset($cta_btn_style['button_background_color']) ? $cta_btn_style['button_background_color'] : "";
1904 $color = isset($cta_btn_style['button_font_color']) ? $cta_btn_style['button_font_color'] : "";
1905 $font_size = isset($cta_btn_style['button_font_size']) ? $cta_btn_style['button_font_size'] : "";
1906 $font_weight = isset($cta_btn_style['button_font_weight']) ? $cta_btn_style['button_font_weight'] : "";
1907 $text_align = isset($cta_btn_style['button_alignment']) ? $cta_btn_style['button_alignment'] : "";
1908 $text_transform = isset($cta_btn_style['button_transform']) ? $cta_btn_style['button_transform'] : "";
1909 $font_style = isset($cta_btn_style['button_text_style']) ? $cta_btn_style['button_text_style'] : "";
1910 $text_decoration = isset($cta_btn_style['button_text_decoration']) ? $cta_btn_style['button_text_decoration'] : "";
1911 $line_height = isset($cta_btn_style['button_line_height']) ? $cta_btn_style['button_line_height'] : "";
1912 $letter_spacing = isset($cta_btn_style['button_letter_spacing']) ? $cta_btn_style['button_letter_spacing'] : "";
1913 $word_spacing = isset($cta_btn_style['button_word_spacing']) ? $cta_btn_style['button_word_spacing'] : "";
1914
1915 $border_width = isset($cta_btn_style['button_border_width']) ? $cta_btn_style['button_border_width'] : "";
1916 $border_style = isset($cta_btn_style['button_border_style']) ? $cta_btn_style['button_border_style'] : "";
1917 $border_color = isset($cta_btn_style['button_border_color']) ? $cta_btn_style['button_border_color'] : "";
1918 $border_radius = isset($cta_btn_style['button_border_radius']) ? $cta_btn_style['button_border_radius'] : "";
1919
1920 $button_pt = isset($cta_btn_style['button_pt']) ? $cta_btn_style['button_pt'] : "";
1921 $button_pr = isset($cta_btn_style['button_pr']) ? $cta_btn_style['button_pr'] : "";
1922 $button_pb = isset($cta_btn_style['button_pb']) ? $cta_btn_style['button_pb'] : "";
1923 $button_pl = isset($cta_btn_style['button_pl']) ? $cta_btn_style['button_pl'] : "";
1924
1925 if($button_open_new_tab == 'on'){
1926 $target = '_blank';
1927 }
1928 $style = 'background-color: '.$background_color.';
1929 color: '.$color.';
1930 font-size: '.$font_size.'px;
1931 font-weight: '.$font_weight.';
1932 text-align: center;
1933 display: inline-block;
1934 text-transform: '.$text_transform.';
1935 font-style: '.$font_style.';
1936 text-decoration: '.$text_decoration.';
1937 line-height: '.$line_height.';
1938 letter-spacing: '.$letter_spacing.'px;
1939 word-spacing: '.$word_spacing.'px;
1940 border: '.$border_width.'px '.$border_style.' '.$border_color.';
1941 border-radius: '.$border_radius.'px;
1942 padding: '.$button_pt.'px '.$button_pr.'px '.$button_pb.'px '.$button_pl.'px;
1943 ';
1944 $html .= '<div class="wpvr-call-to-action-button position-'.$text_align.'" style="max-width:' . $width.'">
1945 <a href="'.$buttonurl.'" style="'.$style.'" target="'.$target.'">'.$buttontext.'</a>
1946 </div>';
1947
1948 }
1949 }
1950
1951
1952 //script started
1953 $html .= '<script>';
1954 if (isset($postdata['bg_music']) && $bg_music == 'on' && 'valid' == $status && $is_pro) {
1955 $html .= '
1956 var x' . $id . ' = document.getElementById("vrAudio' . $id . '");
1957 var playing' . $id . ' = false;
1958 var autoplaySupported' . $id . ' = false;
1959 var alertShown' . $id . ' = false;
1960 var autoplayChecked' . $id . ' = false;
1961
1962 function playPause' . $id . '() {
1963 if (playing' . $id . ') {
1964 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
1965 x' . $id . '.pause();
1966 jQuery("#audio_control' . $id . '").attr("data-play", "off");
1967 playing' . $id . ' = false;
1968 } else {
1969 x' . $id . '.muted = false;
1970 x' . $id . '.play().then(function() {
1971 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
1972 jQuery("#audio_control' . $id . '").attr("data-play", "on");
1973 playing' . $id . ' = true;
1974 }).catch(function(e) {
1975 console.log("Play failed:", e);
1976 });
1977 }
1978 }
1979
1980 function audionEnd' . $id . '() {
1981 playing' . $id . ' = false;
1982 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
1983 jQuery("#audio_control' . $id . '").attr("data-play", "off");
1984 }
1985
1986 x' . $id . '.addEventListener("ended", audionEnd' . $id . ');';
1987
1988 if ($autoplay_bg_music == 'on') {
1989 $html .= '
1990
1991 x' . $id . '.addEventListener("loadeddata", function() {
1992 if (!autoplayChecked' . $id . ') {
1993 checkAutoplayStatus' . $id . '();
1994 }
1995 });
1996
1997 x' . $id . '.addEventListener("canplay", function() {
1998 if (!autoplayChecked' . $id . ') {
1999 checkAutoplayStatus' . $id . '();
2000 }
2001 });
2002
2003 x' . $id . '.addEventListener("canplaythrough", function() {
2004 if (!autoplayChecked' . $id . ') {
2005 checkAutoplayStatus' . $id . '();
2006 }
2007 });
2008
2009 setTimeout(function() {
2010 if (!autoplayChecked' . $id . ') {
2011 checkAutoplayStatus' . $id . '();
2012 }
2013 }, 1000);
2014
2015 x' . $id . '.addEventListener("play", function() {
2016 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2017 jQuery("#audio_control' . $id . '").attr("data-play", "on");
2018 playing' . $id . ' = true;
2019 });
2020
2021 x' . $id . '.addEventListener("pause", function() {
2022 if (!playing' . $id . ') {
2023 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2024 jQuery("#audio_control' . $id . '").attr("data-play", "off");
2025 }
2026 });
2027
2028 function checkAutoplayStatus' . $id . '() {
2029 autoplayChecked' . $id . ' = true;
2030
2031 x' . $id . '.muted = true;
2032 var playPromise = x' . $id . '.play();
2033
2034 if (playPromise !== undefined) {
2035 playPromise.then(function () {
2036 if (x' . $id . '.muted || x' . $id . '.volume === 0) {
2037 handleAutoplayBlocked' . $id . '();
2038 } else {
2039 autoplaySupported' . $id . ' = true;
2040 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2041 jQuery("#audio_control' . $id . '").attr("data-play", "on");
2042 playing' . $id . ' = true;
2043 }
2044 }).catch(function () {
2045 handleAutoplayBlocked' . $id . '();
2046 });
2047 } else {
2048 setTimeout(function () {
2049 if (x' . $id . '.paused || x' . $id . '.currentTime === 0) {
2050 handleAutoplayBlocked' . $id . '();
2051 } else {
2052 autoplaySupported' . $id . ' = true;
2053 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2054 jQuery("#audio_control' . $id . '").attr("data-play", "on");
2055 playing' . $id . ' = true;
2056 }
2057 }, 300);
2058 }
2059 }
2060
2061 function handleAutoplayBlocked' . $id . '() {
2062 autoplaySupported' . $id . ' = false;
2063 if (!alertShown' . $id . ') {
2064 alert("Autoplay is not supported in your browser. Please click the audio button to play music.");
2065 alertShown' . $id . ' = true;
2066 }
2067
2068 x' . $id . '.pause();
2069 x' . $id . '.currentTime = 0;
2070 x' . $id . '.muted = true;
2071
2072 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2073 jQuery("#audio_control' . $id . '").attr("data-play", "off");
2074
2075 document.getElementById("pano' . $id . '").addEventListener("click", musicPlay' . $id . ');
2076 document.addEventListener("touchstart", musicPlay' . $id . ', { once: true });
2077 document.addEventListener("click", musicPlay' . $id . ', { once: true });
2078 }
2079
2080 function musicPlay' . $id . '() {
2081 x' . $id . '.muted = false;
2082 var playPromise = x' . $id . '.play();
2083
2084 if (playPromise !== undefined) {
2085 playPromise.then(function () {
2086 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2087 jQuery("#audio_control' . $id . '").attr("data-play", "on");
2088 playing' . $id . ' = true;
2089 }).catch(function(e) {
2090 console.log("Play failed:", e);
2091 });
2092 } else {
2093 setTimeout(function () {
2094 if (!x' . $id . '.paused) {
2095 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2096 jQuery("#audio_control' . $id . '").attr("data-play", "on");
2097 playing' . $id . ' = true;
2098 }
2099 }, 100);
2100 }
2101
2102 document.getElementById("pano' . $id . '").removeEventListener("click", musicPlay' . $id . ');
2103 document.removeEventListener("touchstart", musicPlay' . $id . ');
2104 document.removeEventListener("click", musicPlay' . $id . ');
2105 }
2106 ';
2107 }
2108 }
2109 $html .= '(function ($) {';
2110 $html .= 'jQuery(document).ready(function() {';
2111 $html .= 'var response = ' . $response . ';';
2112 $html .= 'var scenes = response[1];';
2113 $html .= 'if(scenes) {';
2114 $html .= 'var scenedata = scenes.scenes;';
2115 $html .= 'for(var i in scenedata) {';
2116 $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2117 $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2118 $html .= 'if(scenehotspot[i].type === "info") {';
2119 $html .= ' scenehotspot[i]["clickHandlerFunc"] = wpvrhotspot;';
2120 $html .= '} else if(scenehotspot[i].type === "scene") {';
2121 $html .= ' scenehotspot[i]["clickHandlerArgs"] = scenehotspot[i]["text"];';
2122 $status = get_option('wpvr_edd_license_status');
2123 if ($status !== false && $status == 'valid') {
2124 $html .='if(wpvr_public.is_pro_active) {';
2125 $html .= ' scenehotspot[i]["clickHandlerFunc"] = wpvrhotspotscene;';
2126 $html .='}';
2127 }
2128 $html .= '}';
2129
2130 if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2131 } else {
2132 $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2133 $html .= 'scenehotspot[i]["createTooltipFunc"] = wpvrtooltip;';
2134 $html .= '}';
2135 }
2136
2137 $html .= '}';
2138 $html .= '}';
2139 $html .= '}';
2140 $html .= 'var panoshow' . $id . ' = pannellum.viewer(response[0]["panoid"], scenes);';
2141 $html .= '
2142
2143 if(!wpvr_public.is_pro_active || !wpvr_public.is_license_active) {
2144 panoshow' . $id . '.on("load", function() {
2145 jQuery(".pnlm-panorama-info").hide();
2146 jQuery(".pnlm-compass").hide();
2147 });
2148
2149 panoshow' . $id . '.on("scenechange", function() {
2150 jQuery(".pnlm-panorama-info").hide();
2151 jQuery(".pnlm-compass").hide();
2152 });
2153 }';
2154 //===Dplicate mode only for vr mode===//
2155 $response2 = json_decode($response);
2156 $response2[1]->compass = false;
2157 $response2[1]->autoRotate = false;
2158 $response = json_encode($response2);
2159 $html .= 'var response_duplicate = ' . $response . ';';
2160 $html .= 'var scenes_duplicate = response_duplicate[1];';
2161
2162 $html .= 'if(scenes_duplicate) {';
2163 $html .= 'var scenedata = scenes_duplicate.scenes;';
2164 $html .= 'for(var i in scenedata) {';
2165 $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2166 $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2167 $html .= 'if(scenehotspot[i]["clickHandlerArgs"] != "") {';
2168 $html .= 'scenehotspot[i]["clickHandlerFunc"] = wpvrhotspot;';
2169 $html .= '}';
2170 if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2171 } else {
2172 $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2173 $html .= 'scenehotspot[i]["createTooltipFunc"] = wpvrtooltip;';
2174 $html .= '}';
2175 }
2176 $html .= '}';
2177 $html .= '}';
2178 $html .= '}';
2179
2180 $is_pro = apply_filters('is_wpvr_pro_active',false);
2181 $status = get_option('wpvr_edd_license_status');
2182 $html .= 'var vr_mode = "off";';
2183 if ($status !== false && 'valid' == $status && $is_pro) {
2184 $html .= 'var panoshow2' . $id . ' = pannellum.viewer("pano2' . $id . '", scenes_duplicate);';
2185 // Show Cardboard Mode in Tour
2186 $html .= '
2187 var tim;
2188 var im = 0;
2189 var active_scene = "'.$default_scene.'";
2190 var c_time;
2191 c_time = new Date();
2192 var timer = c_time.getTime() + 2000;
2193 function panoShowCardBoardOnTrigger(data){
2194 if(scenes_duplicate) {
2195 var scenedata = scenes_duplicate.scenes;
2196 for(var i in scenedata) {
2197 if(active_scene === i) {
2198 var scenehotspot = scenedata[i].hotSpots;
2199 for(var j in scenehotspot) {
2200 var plusFiveYaw = Math.round(scenehotspot[j].yaw) + 5;
2201 var minusFiveYaw = Math.round(scenehotspot[j].yaw) - 5;
2202 var plusFivePitch = Math.round(scenehotspot[j].pitch) + 5;
2203 var minusFivePitch = Math.round(scenehotspot[j].pitch) - 5;
2204 var firstCondition = ( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ;
2205 var secCondition = (Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw);
2206 if(( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ){
2207 if((Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw)){
2208 jQuery(".center-pointer").addClass("wpvr-pluse-effect")
2209 var getScene = scenehotspot[j].sceneId;
2210 if(scenehotspot[j].type == "scene"){
2211 panoshow' . $id . '.loadScene(getScene);
2212 panoshow2' . $id . '.loadScene(getScene);
2213 // var inside_current_time_object = new Date();
2214 // var inside_timer = inside_current_time_object.getTime();
2215 // if(inside_timer > timer) {
2216 // panoshow' . $id . '.loadScene(getScene);
2217 // panoshow2' . $id . '.loadScene(getScene);
2218 // jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2219 // }
2220 }else{
2221 jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2222 }
2223 }
2224 else {
2225 jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2226 c_time = new Date();
2227 timer = c_time.getTime() + 2000;
2228 }
2229 }
2230 else {
2231 c_time = new Date();
2232 timer = c_time.getTime() + 2000;
2233 }
2234 }
2235 }
2236 }
2237 }
2238 };
2239 function vrDeviseOrientation(){
2240 var data = {
2241 pitch: panoshow' . $id . '.getPitch(),
2242 yaw: panoshow' . $id . '.getYaw(),
2243 };
2244 panoShowCardBoardOnTrigger(data);
2245 }';
2246 $html .= '
2247 function requestFullScreen(){
2248 var elem = document.getElementById("master-container");
2249 if (elem.requestFullscreen) {
2250 elem.requestFullscreen();
2251 } else if (elem.webkitRequestFullscreen) { /* Safari */
2252 elem.webkitRequestFullscreen();
2253 } else if (elem.msRequestFullscreen) { /* IE11 */
2254 elem.msRequestFullscreen();
2255 }
2256 }
2257 function requestExitFullscreen(){
2258 var elem = document.getElementById("master-container");
2259 if (document.exitFullscreen) {
2260 document.exitFullscreen();
2261 } else if (document.webkitExitFullscreen) { /* Safari */
2262 document.webkitExitFullscreen();
2263 } else if (document.msExitFullscreen) { /* IE11 */
2264 document.msExitFullscreen();
2265 }
2266 }
2267 jQuery(document).on("click",".fullscreen-button .expand",function() {
2268 jQuery(this).hide()
2269 jQuery(this).parent().find(".compress").show()
2270 requestFullScreen()
2271 });
2272 jQuery(document).on("click",".fullscreen-button .compress",function() {
2273 jQuery(this).hide()
2274 jQuery(this).parent().find(".expand").show()
2275 requestExitFullscreen()
2276 screen.orientation.unlock();
2277 });
2278 let onLoadAnalytics = false;
2279 let sceneLoadAnalytics = false;
2280
2281 function storeAnalyticsData(data) {
2282 if (typeof wpvrAnalyticsObj !== "undefined" && wpvr_public.is_pro_active) {
2283 jQuery.ajax({
2284 url: wpvrAnalyticsObj.ajaxUrl,
2285 type: "POST",
2286 data: {
2287 action: "store_scene_hotspot_data",
2288 scene_id: data.scene_id,
2289 tour_id: data.tour_id,
2290 type: data.type,
2291 hotspot_id: data.hotspot_id || "",
2292 user_agent: navigator.userAgent,
2293 device_type: getDeviceType() || "desktop",
2294 nonce: wpvrAnalyticsObj.nonce,
2295 },
2296 success: function (response) {
2297 console.log("Data stored successfully");
2298 },
2299 error: function (error) {
2300 console.log("Error in storing data");
2301 }
2302 });
2303 } else {
2304 console.warn("Analytics object not available or pro not active");
2305 }
2306 }
2307 function getDeviceType() {
2308 const userAgent = navigator.userAgent.toLowerCase();
2309 if (/mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)) {
2310 return "mobile";
2311 } else if (/tablet|ipad/i.test(userAgent)) {
2312 return "tablet";
2313 } else {
2314 return "desktop";
2315 }
2316 }
2317 panoshow' . $id . '.on("scenechange", function(scene) {
2318 onLoadAnalytics = true;
2319 sceneLoadAnalytics = true;
2320 let scene_id = scene;
2321 let tour_id = ' . $id . ';
2322 let type = "scene";
2323 let hotspot_id = "";
2324 let user_agent = navigator.userAgent;
2325 let device_type = getDeviceType() ? getDeviceType() : "desktop";
2326 storeAnalyticsData({
2327 scene_id: scene_id,
2328 tour_id: tour_id,
2329 type: type,
2330 hotspot_id: hotspot_id,
2331 user_agent: user_agent,
2332 device_type: device_type,
2333 });
2334 });
2335 panoshow' . $id . '.on("load", function() {
2336 let scene_id = panoshow' . $id . '.getScene();
2337 let tour_id = ' . $id . ';
2338 let type = "scene";
2339 let hotspot_id = "";
2340 let user_agent = navigator.userAgent;
2341 let device_type = getDeviceType() ? getDeviceType() : "desktop";
2342 if(!onLoadAnalytics && !sceneLoadAnalytics) {
2343 storeAnalyticsData({
2344 scene_id: scene_id,
2345 tour_id: tour_id,
2346 type: type,
2347 hotspot_id: hotspot_id,
2348 user_agent: user_agent,
2349 device_type: device_type,
2350 });
2351 }
2352 });
2353 function wpvrhotspotscene(hotSpotDiv, args) {
2354 onLoadAnalytics = true;
2355 let scene_id = panoshow' . $id . '.getScene();
2356 let tour_id = ' . $id . ';
2357 let type = "hotspot";
2358 let hotspot_id = args;
2359 let user_agent = navigator.userAgent;
2360 let device_type = getDeviceType() ? getDeviceType() : "desktop";
2361 storeAnalyticsData({
2362 scene_id: scene_id,
2363 tour_id: tour_id,
2364 type: type,
2365 hotspot_id: hotspot_id,
2366 user_agent: user_agent,
2367 device_type: device_type
2368 });
2369 }
2370 ';
2371 $html .= 'panoshow' . $id . '.on("scenechange", function (scene){
2372 jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2373 active_scene = scene;
2374 // if(localStorage.getItem("vr_mode") == "on") {
2375 if(vr_mode == "on") {
2376 jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2377 jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2378 }
2379 });
2380 var compassBlock = "";
2381 var infoBlock = "";
2382 jQuery(document).on("click",".vr_mode_change' . $id . '",function (){
2383 jQuery("#pano2' . $id . ' .pnlm-load-button").trigger("click");
2384 jQuery("#pano' . $id . ' .pnlm-load-button").trigger("click");
2385 var getValue = jQuery(this).val();
2386 var getParent = jQuery(this).parent().parent();
2387 var compass = getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display");
2388 var panoInfo = getParent.find("#pano' . $id . ' .pnlm-panorama-info").css("display");
2389 if(compass == "block"){
2390 compassBlock = "block";
2391 }
2392 if(panoInfo == "block"){
2393 infoBlock = "block";
2394 }
2395 if (getValue == "off") {
2396 requestFullScreen()
2397 screen.orientation.lock("landscape-primary").then(function() {
2398 }).catch(function(error) {
2399 alert("VR Glass Mode not supported in this device");
2400 });
2401 // localStorage.setItem("vr_mode", "on");
2402 vr_mode = "on";
2403 jQuery(".vr-mode-title").show();
2404 jQuery(this).val("on");
2405 getParent.find("#pano2' . $id . '").css({
2406 "opacity": "1",
2407 "visibility": "visible",
2408 "position": "relative",
2409 });
2410 gyroSwitch = true;
2411 panoshow' . $id . '.startOrientation();
2412 panoshow2' . $id . '.startOrientation();
2413 panoshow2' . $id . '.setPitch(panoshow' . $id . '.getPitch(), 0);
2414 panoshow2' . $id . '.setYaw(panoshow' . $id . '.getYaw(), 0);
2415 getParent.find(".pano-wrap").addClass("wpvr-cardboard-disable-event");
2416 getParent.find("#pano' .$id. ' #zoom-in-out-controls'.$id.'").hide();
2417 getParent.find("#pano' .$id. ' #controls'.$id.'").hide();
2418 getParent.find("#pano' .$id. ' #explainer_button_'.$id. '").hide();
2419 getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").hide();
2420 getParent.find("#pano' .$id. ' #floor_map_button_'.$id.'").hide();
2421 getParent.find("#pano' .$id. ' #vrgcontrols'.$id.'").hide();
2422 getParent.find("#pano' .$id. ' #sccontrols'.$id.'").hide();
2423 getParent.find("#pano' .$id. ' #adcontrol'.$id.'").hide();
2424 getParent.find("#pano' .$id. ' .owl-nav.wpvr_slider_nav").hide();
2425 getParent.find("#pano' .$id. ' #cp-logo-controls").hide();
2426 getParent.find("#pano' .$id. ' #wpvr-social-share-bg-box'.$id.'").hide();
2427 getParent.find("#pano2' . $id . ' .pnlm-controls-container").hide();
2428 getParent.find("#pano' . $id . ' .pnlm-controls-container").hide();
2429 getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
2430 getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
2431 getParent.find("#pano2' . $id . ' .pnlm-panorama-info").hide();
2432 getParent.find("#pano' . $id . ' .pnlm-panorama-info").hide();
2433 getParent.find("#pano' . $id . '").addClass("cardboard-half");
2434 getParent.find("#center-pointer' . $id . '").show();
2435 getParent.find(".fullscreen-button").hide();
2436 getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").hide();
2437 if (window.DeviceOrientationEvent) {
2438 window.addEventListener("deviceorientation", vrDeviseOrientation);
2439 }
2440 panoshow' . $id . '.on("zoomchange", function (data){
2441 panoshow2' . $id . '.setHfov(data, 0);
2442 });
2443 panoshow2' . $id . '.on("zoomchange", function (data){
2444 panoshow' . $id . '.setHfov(data, 0);
2445 });
2446 jQuery(document).on("click","#pano2' . $id . '",function(event) {
2447 panoshow' . $id . '.startOrientation();
2448 panoshow2' . $id . '.startOrientation();
2449 });
2450 jQuery(document).on("click","#pano' . $id . '",function(event) {
2451 panoshow' . $id . '.startOrientation();
2452 panoshow2' . $id . '.startOrientation();
2453 });
2454 panoshow' . $id . '.on("mousemove", function (data){
2455 panoshow2' . $id . '.setPitch(data.pitch, 0);
2456 panoshow2' . $id . '.setYaw(data.yaw, 0);
2457 panoShowCardBoardOnTrigger(data);
2458 });
2459 panoshow2' . $id . '.on("mousemove", function (data){
2460 panoshow' . $id . '.setPitch(data.pitch, 0);
2461 panoshow' . $id . '.setYaw(data.yaw, 0);
2462 panoShowCardBoardOnTrigger(data);
2463 });
2464 panoshow' . $id . '.on("touchmove", function (data){
2465 panoshow' . $id . '.stopOrientation();
2466 panoshow2' . $id . '.stopOrientation();
2467 panoshow2' . $id . '.setPitch(data.pitch, 0);
2468 panoshow2' . $id . '.setYaw(data.yaw, 0);
2469 panoShowCardBoardOnTrigger(data);
2470 });
2471 panoshow2' . $id . '.on("touchmove", function (data){
2472 panoshow' . $id . '.stopOrientation();
2473 panoshow2' . $id . '.stopOrientation();
2474 panoshow' . $id . '.setPitch(data.pitch, 0);
2475 panoshow' . $id . '.setYaw(data.yaw, 0);
2476 panoShowCardBoardOnTrigger(data);
2477 });
2478 } else if(getValue == "on") {
2479 screen.orientation.unlock();
2480 requestExitFullscreen();
2481 // localStorage.setItem("vr_mode", "off");
2482 vr_mode = "off";
2483 jQuery(".vr-mode-title").hide();
2484 jQuery(this).val("off");
2485 getParent.find("#pano2' . $id . '").css({
2486 "opacity": "0",
2487 "visibility": "hidden",
2488 "position": "absolute",
2489 });
2490 getParent.find(".pano-wrap").removeClass("wpvr-cardboard-disable-event");
2491 getParent.find("#pano' .$id. ' #zoom-in-out-controls'.$id.'").show();
2492 getParent.find("#pano' .$id. ' #controls'.$id.'").show();
2493 getParent.find("#pano' .$id. ' #explainer_button_'.$id. '").show();
2494 getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").show();
2495 getParent.find("#pano' .$id. ' #floor_map_button_'.$id.'").show();
2496 getParent.find("#pano2' . $id . ' .pnlm-controls-container").show();
2497 getParent.find("#pano' . $id . ' .pnlm-controls-container").show();
2498 getParent.find("#pano' .$id. ' #vrgcontrols'.$id.'").show();
2499 getParent.find("#pano' .$id. ' #sccontrols'.$id.'").hide();
2500 getParent.find("#pano' .$id. ' #adcontrol'.$id.'").show();
2501 getParent.find("#pano' .$id. ' .owl-nav.wpvr_slider_nav").hide();
2502 getParent.find("#pano' .$id. ' #cp-logo-controls").show();
2503 getParent.find("#pano' .$id. ' #wpvr-social-share-bg-box'.$id.'").show();
2504 getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").show();
2505 if(compassBlock == "block"){
2506 getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
2507 getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
2508 }
2509 if(infoBlock == "block"){
2510 getParent.find("#pano2' . $id . ' .pnlm-panorama-info").show();
2511 getParent.find("#pano' . $id . ' .pnlm-panorama-info").show();
2512 }
2513 getParent.find("#pano' . $id . '").removeClass("cardboard-half");
2514 getParent.find("#center-pointer' . $id . '").hide();
2515 getParent.find(".fullscreen-button").hide();
2516 panoshow' . $id . '.off("mousemove");
2517 panoshow' . $id . '.off("touchmove");
2518 panoshow2' . $id . '.off("mousemove");
2519 panoshow2' . $id . '.off("touchmove");
2520 if (window.DeviceOrientationEvent) {
2521 window.removeEventListener("deviceorientation", vrDeviseOrientation);
2522 }
2523 }
2524 });';
2525 $html .= 'panoshow2' . $id . '.on("load", function (){
2526 // if(localStorage.getItem("vr_mode") == "off") {
2527 if( vr_mode == "off") {
2528 jQuery(".vr-mode-title").hide();
2529 }
2530 else {
2531 jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2532 jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
2533 jQuery("#pano2' . $id . ' .pnlm-panorama-info").hide();
2534 jQuery("#pano' . $id . ' .pnlm-panorama-info").hide();
2535 jQuery(".vr-mode-title").show();
2536 }
2537 });';
2538 }
2539 //=== end Dplicate mode only for vr mode===//
2540 $html .= 'jQuery("#pano' . $id . ' .wpvr-floor-map .floor-plan-pointer").on("click",function(){
2541 var scene_id = jQuery(this).attr("scene_id");
2542 panoshow' . $id . '.loadScene(scene_id)
2543 jQuery(".floor-plan-pointer").removeClass("add-pulse")
2544 jQuery(this).addClass("add-pulse")
2545 });';
2546 if ($scene_animation == 'on' && is_plugin_active('wpvr-pro/wpvr-pro.php')) {
2547 $animation_type = $postdata['sceneAnimationName'] ?? 'none';
2548 $animationDuration = $postdata['sceneAnimationTransitionDuration'] ?? '500ms';
2549 $animationDelay = $postdata['sceneAnimationTransitionDelay'] ?? '0ms';
2550 $animation_js = apply_filters('wpvr_scene_animation_js', $id, $animation_type, $animationDuration, $animationDelay);
2551 if (!empty($animation_js)) {
2552 $html .= $animation_js;
2553 $html .= 'panoshow' . $id . '.on("load", function (scene){
2554 if (typeof changeScene === "function") {
2555 changeScene();
2556 } else {
2557 console.warn("changeScene function is not defined.");
2558 }
2559 });';
2560 }
2561 }
2562
2563 $html .= 'panoshow' . $id . '.on("mousemove", function (data){
2564 jQuery(".add-pulse").css({"transform":"rotate("+data.yaw+"deg)"});
2565 });
2566 ';
2567 $status = get_option('wpvr_edd_license_status');
2568 if ($status !== false && 'valid' == $status && $is_pro){
2569 $html .= 'panoshow' . $id . '.on("scenechange", function (scene){
2570 jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2571 jQuery(".floor-plan-pointer").each(function(index ,element){
2572 var scene_id = jQuery(this).attr("scene_id");
2573 if( active_scene == scene_id ){
2574 jQuery(".floor-plan-pointer").removeClass("add-pulse")
2575 jQuery(this).addClass("add-pulse")
2576 }
2577 });
2578 });';
2579 $html .= 'panoshow' . $id . '.on("load", function (){
2580 if(jQuery(".floor-plan-pointer").length > 0){
2581 jQuery(".floor-plan-pointer").each(function(index ,element){
2582 var scene_id = jQuery(this).attr("scene_id");
2583 if( active_scene == scene_id ){
2584 jQuery(".floor-plan-pointer").removeClass("add-pulse")
2585 jQuery(this).addClass("add-pulse")
2586 }
2587 });
2588 }
2589 });';
2590 }
2591 if ($status !== false && 'valid' == $status && $is_pro){
2592 $scene_navigation_content_type = isset($postdata['scene_navigation_content_type']) ? $postdata['scene_navigation_content_type'] : 'scene_id';
2593 $html .= 'jQuery("#pano' . $id . ' .custom-scene-navigation").on("click", function() {
2594 jQuery("#custom-scene-navigation-nav' . $id . ' ul").empty();
2595 if (scenes) {
2596 var scene_navigation_content_type = "' . $scene_navigation_content_type . '";
2597 var sceneList = scenes.scenes;
2598 var getScene = panoshow' . $id . '.getScene();
2599 for (const key in sceneList) {
2600 let title;
2601 if (scene_navigation_content_type === "scene_title") {
2602 if (sceneList[key].title) {
2603 title = sceneList[key].title;
2604 } else {
2605 if (title == "" || title == undefined) {
2606 if (sceneList[key].panorama) {
2607 title = getImageNameWithoutExtension(sceneList[key].panorama);
2608 }
2609 }
2610 }
2611 } else if (scene_navigation_content_type === "scene_image_name") {
2612 if (sceneList[key].panorama) {
2613 title = getImageNameWithoutExtension(sceneList[key].panorama);
2614 }
2615 } else {
2616 title = key;
2617 }
2618 if (sceneList.hasOwnProperty(key)) {
2619 let ulElement = document.querySelector("#custom-scene-navigation-nav' . $id . ' ul");
2620 if (ulElement) {
2621 let liElement = document.createElement("li");
2622 liElement.className = "scene-navigation-list" + (key === getScene ? " active" : "");
2623 liElement.setAttribute("scene_id", key);
2624 liElement.textContent = title;
2625 ulElement.appendChild(liElement);
2626 }
2627 }
2628 }
2629 jQuery("#custom-scene-navigation-nav' . $id . '").toggleClass("visible");
2630 }
2631 });';
2632 $html .='function getImageNameWithoutExtension(imageUrl) {
2633 // Split the URL by "/"
2634 var parts = imageUrl.split("/");
2635 // Get the last part which contains the image name
2636 var imageNameWithExtension = parts[parts.length - 1];
2637 // Split the image name by period (.)
2638 var imageNameParts = imageNameWithExtension.split(".");
2639 // Remove the last part (which is the extension) and join the remaining parts
2640 var imageNameWithoutExtension = imageNameParts.slice(0, -1).join(".");
2641 // Return the image name without extension
2642 return imageNameWithoutExtension;
2643 }';
2644 $html .= '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 var scene_key = jQuery(this).attr("scene_id");
2649 panoshow' . $id . '.loadScene(scene_key);
2650 }
2651 });';
2652 }
2653 $html .= 'const node = document.querySelector(".add-pulse");
2654 panoshow' . $id . '.on("compasschange", function (data){
2655 // const node = document.querySelector(".add-pulse");
2656 // node.style.transform = data;
2657 // jQuery(".add-pulse").css({"transform":data});
2658 });';
2659 $html .= 'panoshow' . $id . '.on("load", function (){
2660 // if(localStorage.getItem("vr_mode") == "off") {
2661 if(vr_mode == "off") {
2662 jQuery(".vr-mode-title").hide();
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 setTimeout(() => {
2671 window.dispatchEvent(new Event("resize"));
2672 }, 200);
2673 if (jQuery("#pano' . $id . '").children().children(".pnlm-panorama-info:visible").length > 0) {
2674 jQuery("#controls' . $id . '").css("bottom", "80px");
2675 }
2676 else {
2677 jQuery("#controls' . $id . '").css("bottom", "5px");
2678 }
2679 });';
2680 $html .= 'panoshow' . $id . '.on("render", function (){
2681 window.dispatchEvent(new Event("resize"));
2682 });';
2683 $html .= 'if (scenes.autoRotate) {
2684 panoshow' . $id . '.on("load", function (){
2685 setTimeout(function(){ panoshow' . $id . '.startAutoRotate(scenes.autoRotate, 0); }, 3000);
2686 });
2687 panoshow' . $id . '.on("scenechange", function (){
2688 setTimeout(function(){ panoshow' . $id . '.startAutoRotate(scenes.autoRotate, 0); }, 3000);
2689 });
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 .= 'jQuery(document).on("click","#' . $scene_key_gallery . '",function() {
2711 panoshow' . $id . '.loadScene("' . $scene_key . '");
2712 });';
2713 }
2714 }
2715 }
2716 //===Custom Control===//
2717 if (isset($custom_control)) {
2718 if ($custom_control['panupSwitch'] == "on" && 'valid' == $status && $is_pro) {
2719 $html .= 'document.getElementById("pan-up' . $id . '").addEventListener("click", function(e) {';
2720 $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() + 10);';
2721 $html .= '});';
2722 }
2723 if ($custom_control['panDownSwitch'] == "on" && 'valid' == $status && $is_pro) {
2724 $html .= 'document.getElementById("pan-down' . $id . '").addEventListener("click", function(e) {';
2725 $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() - 10);';
2726 $html .= '});';
2727 }
2728 if ($custom_control['panLeftSwitch'] == "on" && 'valid' == $status && $is_pro) {
2729 $html .= 'document.getElementById("pan-left' . $id . '").addEventListener("click", function(e) {';
2730 $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() - 10);';
2731 $html .= '});';
2732 }
2733 if ($custom_control['panRightSwitch'] == "on" && 'valid' == $status && $is_pro) {
2734 $html .= 'document.getElementById("pan-right' . $id . '").addEventListener("click", function(e) {';
2735 $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() + 10);';
2736 $html .= '});';
2737 }
2738 if ($custom_control['panZoomInSwitch'] == "on") {
2739 $html .= 'document.getElementById("zoom-in' . $id . '").addEventListener("click", function(e) {';
2740 $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() - 10);';
2741 $html .= '});';
2742 }
2743 if ($custom_control['panZoomOutSwitch'] == "on") {
2744 $html .= 'document.getElementById("zoom-out' . $id . '").addEventListener("click", function(e) {';
2745 $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() + 10);';
2746 $html .= '});';
2747 }
2748 if ($custom_control['panFullscreenSwitch'] == "on" && 'valid' == $status && $is_pro) {
2749 $html .= 'document.getElementById("fullscreen' . $id . '").addEventListener("click", function(e) {';
2750 $html .= 'panoshow' . $id . '.toggleFullscreen();';
2751 $html .= '});';
2752 $html .= '(function() {';
2753 $html .= 'function wpvrFsChange' . $id . '() {';
2754 $html .= 'var fsIcon = document.querySelector("#fullscreen' . $id . ' i");';
2755 $html .= 'if (!fsIcon) return;';
2756 $html .= 'if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) {';
2757 $html .= 'fsIcon.classList.remove("fa-expand"); fsIcon.classList.add("fa-minimize");';
2758 $html .= '} else {';
2759 $html .= 'fsIcon.classList.remove("fa-minimize"); fsIcon.classList.add("fa-expand");';
2760 $html .= '}';
2761 $html .= '}';
2762 $html .= 'document.addEventListener("fullscreenchange", wpvrFsChange' . $id . ');';
2763 $html .= 'document.addEventListener("webkitfullscreenchange", wpvrFsChange' . $id . ');';
2764 $html .= 'document.addEventListener("mozfullscreenchange", wpvrFsChange' . $id . ');';
2765 $html .= 'document.addEventListener("MSFullscreenChange", wpvrFsChange' . $id . ');';
2766 $html .= '})();';
2767 }
2768 if ($custom_control['backToHomeSwitch'] == "on" && 'valid' == $status && $is_pro) {
2769 $html .= 'document.getElementById("backToHome' . $id . '").addEventListener("click", function(e) {';
2770 $html .= 'panoshow' . $id . '.loadScene("' . $default_scene . '");';
2771 $html .= '});';
2772 }
2773 if ($custom_control['gyroSwitch'] == "on" && $custom_control['gyroscopeSwitch'] == "on" && 'valid' == $status && $is_pro) {
2774 $html .= '
2775 var element = document.getElementById("gyroscope' . $id . '");
2776 var gyroSwitch = true;
2777 var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
2778 var permissionGranted = false;
2779
2780 function requestOrientationPermission() {
2781 if (isIOS) {
2782 if (typeof DeviceOrientationEvent.requestPermission === "function") {
2783 DeviceOrientationEvent.requestPermission()
2784 .then(function(state) {
2785 if (state === "granted") {
2786 permissionGranted = true;
2787 startOrientation();
2788 } else {
2789 element.children[0].style.color = "red";
2790 gyroSwitch = false;
2791 alert("Permission to use motion sensors was denied.");
2792 }
2793 })
2794 .catch(function(error) {
2795 element.children[0].style.color = "red";
2796 gyroSwitch = false;
2797 console.error("Error requesting device orientation permission:", error);
2798 });
2799 }
2800 } else {
2801 startOrientation();
2802 }
2803 }
2804
2805 function startOrientation() {
2806 panoshow' . $id . '.startOrientation();
2807 element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2808 gyroSwitch = true;
2809 }
2810
2811 panoshow' . $id . '.on("load", function() {
2812 if (!isIOS || permissionGranted) {
2813 if (gyroSwitch) {
2814 startOrientation();
2815 } else {
2816 panoshow' . $id . '.stopOrientation();
2817 element.children[0].style.color = "red";
2818 }
2819 }
2820 });
2821
2822 panoshow' . $id . '.on("scenechange", function() {
2823 if (!isIOS || permissionGranted) {
2824 if (panoshow' . $id . '.isOrientationActive()) {
2825 element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2826 } else {
2827 element.children[0].style.color = "red";
2828 }
2829 }
2830 });
2831
2832 panoshow' . $id . '.on("touchstart", function() {
2833 if (!isIOS || permissionGranted) {
2834 if (panoshow' . $id . '.isOrientationActive()) {
2835 gyroSwitch = true;
2836 element.children[0].style.color = "'.$custom_control['gyroscopeColor'].'";
2837 } else {
2838 gyroSwitch = false;
2839 element.children[0].style.color = "red";
2840 }
2841 }
2842 });';
2843
2844 $html .= 'document.getElementById("gyroscope' . $id . '").addEventListener("click", function(e) {
2845 var element = document.getElementById("gyroscope' . $id . '");
2846 if (isIOS && typeof DeviceOrientationEvent.requestPermission === "function" && !permissionGranted) {
2847 requestOrientationPermission();
2848 } else {
2849 if (panoshow' . $id . '.isOrientationActive()) {
2850 panoshow' . $id . '.stopOrientation();
2851 gyroSwitch = false;
2852 element.children[0].style.color = "red";
2853 } else {
2854 startOrientation();
2855 }
2856 }
2857 });';
2858 }
2859 }
2860 $angle_up = '<i class="fa fa-angle-up"></i>';
2861 $angle_down = '<i class="fa fa-angle-down"></i>';
2862 $sin_qout = "'";
2863
2864 //===Explainer Script===//
2865
2866 if ($autoplay_bg_music == 'on') {
2867 $html .= 'jQuery(document).on("click","#explainer_button_' . $id . '",function() {
2868 jQuery("#explainer' . $id . '").slideToggle();
2869 playing' . $id . ' = false;
2870 var x' . $id . ' = document.getElementById("vrAudio' . $id . '");
2871 jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up");
2872 jQuery("#vr-volume' . $id . '").addClass("fas fa-volume-mute");
2873 x' . $id . '.pause();
2874 });
2875 jQuery(document).on("click",".close-explainer-video",function() {
2876 jQuery(this).parent(".explainer").hide();
2877 var el_src = jQuery(".vr-iframe").attr("src");
2878 jQuery(".vr-iframe").attr("src", el_src);
2879 });';
2880 } else {
2881 $html .= 'jQuery(document).on("click","#explainer_button_' . $id . '",function() {
2882 jQuery("#explainer' . $id . '").slideToggle(function(){
2883 var $explainerVideoId = jQuery("#explainer' . $id . '");
2884 var $explainerVideoIframe = $explainerVideoId.find("iframe");
2885 var explainerVideoIframSrc = $explainerVideoIframe.attr("src");
2886 $explainerVideoIframe.attr("src", "");
2887 $explainerVideoIframe.attr("src", explainerVideoIframSrc);
2888 });
2889 });
2890 jQuery(document).on("click", ".close-explainer-video", function() {
2891 var $explainer = jQuery(this).parent(".explainer");
2892 var $iframe = $explainer.find("iframe");
2893 var el_src = $iframe.attr("src");
2894 $iframe.attr("src", "");
2895 $explainer.hide();
2896 $iframe.attr("src", el_src);
2897 });';
2898 }
2899
2900 $html .= '
2901 jQuery(document).on("click","#pano' . $id . '",function(event) {
2902 var isActiveModal = event.target.closest(".custom-ifram-wrapper");
2903 var isForm = event.target.closest(".wpvr-hotspot-tweak-contents");
2904 var isHotspot = event.target.closest(".pnlm-hotspot-base");
2905 if( isActiveModal == null && isForm == null && isHotspot == null){
2906 jQuery(".custom-ifram-wrapper .custom-ifram").empty();
2907 jQuery(".custom-ifram-wrapper").hide();
2908 jQuery(this).removeClass("show-modal");
2909 jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide("show-modal");
2910 }else if(isForm != null){
2911 jQuery(this).addClass("show-modal");
2912 }
2913 });';
2914
2915 //===Explainer Script End===//
2916
2917 //===generic form script===//
2918 if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on') {
2919 $html .= '
2920 jQuery(document).on("click","#generic_form_button_' . $id . '",function() {
2921 jQuery("#wpvr-generic-form' . $id . '").fadeToggle();
2922 });
2923
2924 jQuery(document).on("click",".close-generic-form",function() {
2925 jQuery(this).parent(".wpvr-generic-form").fadeOut()
2926 });
2927 ';
2928 }
2929 //===generic from script===//
2930
2931 //===Floor map Script===//
2932 $html .= 'jQuery(document).on("click","#floor_map_button_' . $id . '",function() {
2933 jQuery("#wpvr-floor-map' . $id . '").toggle().removeClass("fullwindow");
2934 });
2935 jQuery(document).on("dblclick","#wpvr-floor-map' . $id . '",function(){
2936 jQuery(this).addClass("fullwindow");
2937 jQuery(this).parents(".pano-wrap").addClass("show-modal");
2938 });
2939 jQuery(document).on("click",".close-floor-map-plan",function() {
2940 jQuery(this).parent(".wpvr-floor-map").hide();
2941 jQuery(this).parent(".wpvr-floor-map").removeClass("fullwindow");
2942 jQuery(this).parents(".pano-wrap").removeClass("show-modal");
2943 });';
2944 //===Floor map Script End===//
2945
2946 if ($vrgallery_display) {
2947
2948 if (!$autoload) {
2949 $html .= 'jQuery(document).ready(function($){
2950 jQuery("#sccontrols' . $id . '").hide();
2951 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2952 jQuery("#sccontrols' . $id . '").hide();
2953 jQuery("#pano' . $id . ' .wpvr_slider_nav").hide();
2954 });';
2955 $html .= 'var slide' . $id . ' = "down";
2956 jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
2957 if (slide' . $id . ' == "up") {
2958 jQuery(".vrgctrl' . $id . '").empty();
2959 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
2960 slide' . $id . ' = "down";
2961 jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
2962 jQuery("#sccontrols' . $id . '").slideToggle(function(){
2963 if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
2964 if (jQuery(this).is(":visible")) {
2965 jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
2966 "display": "flex",
2967 "justify-content": "center",
2968 "align-items": "center",
2969 "gap": "15px"
2970 });
2971 }
2972 }
2973 if (jQuery(".bricks-is-frontend").length) {
2974 if (jQuery(this).is(":visible")) {
2975 jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
2976 "display": "flex",
2977 "justify-content": "center",
2978 "align-items": "center"
2979 });
2980 }
2981 }
2982 });
2983 }
2984 else {
2985 jQuery(".vrgctrl' . $id . '").empty();
2986 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
2987 slide' . $id . ' = "up";
2988 jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
2989 jQuery("#sccontrols' . $id . '").slideToggle(function(){
2990 if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
2991 if (jQuery(this).is(":visible")) {
2992 jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
2993 "display": "flex",
2994 "justify-content": "center",
2995 "align-items": "center",
2996 "gap": "15px"
2997 });
2998 }
2999 }
3000 if (jQuery(".bricks-is-frontend").length) {
3001 if (jQuery(this).is(":visible")) {
3002 jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3003 "display": "flex",
3004 "justify-content": "center",
3005 "align-items": "center"
3006 });
3007 }
3008 }
3009 });
3010 }
3011 });';
3012 } else {
3013 $html .= 'jQuery(document).ready(function($){
3014 jQuery("#sccontrols' . $id . '").show();
3015 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3016 jQuery("#pano' . $id . ' .wpvr_slider_nav").show();
3017 });';
3018 $html .= 'var slide' . $id . ' = "down";
3019 jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
3020 if (slide' . $id . ' == "up") {
3021 jQuery(".vrgctrl' . $id . '").empty();
3022 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3023 slide' . $id . ' = "down";
3024 } else {
3025 jQuery(".vrgctrl' . $id . '").empty();
3026 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3027 slide' . $id . ' = "up";
3028 }
3029 jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3030 jQuery("#sccontrols' . $id . '").slideToggle(function(){
3031 if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3032 if (jQuery(this).is(":visible")) {
3033 jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3034 "display": "flex",
3035 "justify-content": "center",
3036 "align-items": "center",
3037 "gap": "15px"
3038 });
3039 }
3040 }
3041 if (jQuery(".bricks-is-frontend").length) {
3042 if (jQuery(this).is(":visible")) {
3043 jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3044 "display": "flex",
3045 "justify-content": "center",
3046 "align-items": "center"
3047 });
3048 }
3049 }
3050 });
3051 });';
3052 }
3053 } else {
3054 $html .= 'jQuery(document).ready(function($){
3055 jQuery("#sccontrols' . $id . '").hide();
3056 jQuery("#pano' . $id . ' .wpvr_slider_nav").hide();
3057 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3058 });';
3059 $html .= 'var slide' . $id . ' = "down";
3060 jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
3061 if (slide' . $id . ' == "up") {
3062 jQuery(".vrgctrl' . $id . '").empty();
3063 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3064 slide' . $id . ' = "down";
3065 }
3066 else {
3067 jQuery(".vrgctrl' . $id . '").empty();
3068 jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3069 slide' . $id . ' = "up";
3070 }
3071 jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3072 jQuery("#sccontrols' . $id . '").slideToggle(function(){
3073 if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3074 if (jQuery(this).is(":visible")) {
3075 jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3076 "display": "flex",
3077 "justify-content": "center",
3078 "align-items": "center",
3079 "gap": "15px"
3080 });
3081 }
3082 }
3083 if (jQuery(".bricks-is-frontend").length) {
3084 if (jQuery(this).is(":visible")) {
3085 jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3086 "display": "flex",
3087 "justify-content": "center",
3088 "align-items": "center"
3089 });
3090 }
3091 }
3092 });
3093 });';
3094 }
3095 if (!$autoload) {
3096 $html .= 'jQuery(document).ready(function(){
3097 jQuery("#controls' . $id . '").hide();
3098 jQuery("#zoom-in-out-controls' . $id . '").hide();
3099 jQuery("#adcontrol' . $id . '").hide();
3100 jQuery("#explainer_button_' . $id . '").hide();
3101 jQuery("#generic_form_button_' . $id . '").hide();
3102 jQuery("#floor_map_button_' . $id . '").hide();
3103 jQuery("#vrgcontrols' . $id . '").hide();
3104 jQuery("#cp-logo-controls").hide();
3105 jQuery(".custom-scene-navigation").hide();
3106 jQuery("#pano' . $id . '").find(".pnlm-panorama-info").hide();
3107 });';
3108 if ($vrgallery_display) {
3109 $html .= 'var load_once = "true";';
3110 $html .= 'panoshow' . $id . '.on("load", function (){
3111 if (load_once == "true") {
3112 load_once = "false";
3113 jQuery("#sccontrols' . $id . '").slideToggle(function(){
3114 if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3115 if (jQuery(this).is(":visible")) {
3116 jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css("display", "flex");
3117 }
3118 }
3119 if (jQuery(".bricks-is-frontend").length) {
3120 if (jQuery(this).is(":visible")) {
3121 jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3122 "display": "flex",
3123 "justify-content": "center",
3124 "align-items": "center"
3125 });
3126 }
3127 }
3128 });
3129 jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3130 }
3131 });';
3132 }
3133 $html .= 'panoshow' . $id . '.on("load", function (){
3134 jQuery("#controls' . $id . '").show();
3135 jQuery("#zoom-in-out-controls' . $id . '").show();
3136 jQuery("#adcontrol' . $id . '").show();
3137 jQuery("#explainer_button_' . $id . '").show();
3138 jQuery("#generic_form_button_' . $id . '").show();
3139 jQuery("#floor_map_button_' . $id . '").show();
3140 jQuery("#vrgcontrols' . $id . '").show();
3141 jQuery("#cp-logo-controls").show();
3142 jQuery(".custom-scene-navigation").show();
3143 jQuery("#pano' . $id . '").find(".pnlm-panorama-info").show();
3144 });';
3145 }
3146
3147 //==Old code working properly==//
3148
3149 $previeword = "Click to Load Panorama";
3150 if (isset($postdata['previewtext']) && $postdata['previewtext'] != '') {
3151 $previeword = $postdata['previewtext'];
3152 }
3153 $html .= 'jQuery(".elementor-tab-title").click(function(){
3154 var element_id;
3155 var pano_id;
3156 var element_id = this.id;
3157 element_id = element_id.split("-");
3158 element_id = element_id[3];
3159 jQuery("#elementor-tab-content-"+element_id).find("#master-container").children("div").eq(1).addClass("awwww");
3160 var pano_id = jQuery(".awwww").attr("id");
3161 jQuery("#elementor-tab-content-"+element_id).find("#master-container").children("div").eq(1).removeClass("awwww");;
3162 if (pano_id != undefined) {
3163 pano_id = pano_id.split("o");
3164 pano_id = pano_id[1];
3165 if (pano_id == "' . $id . '") {
3166 jQuery("#pano' . $id . '").children(".pnlm-render-container").remove();
3167 jQuery("#pano' . $id . '").children(".pnlm-ui").remove();
3168 panoshow' . $id . ' = pannellum.viewer(response[0]["panoid"], scenes);
3169 jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '")
3170 setTimeout(function() {
3171 // panoshow' . $id . '.loadScene("' . $default_scene . '");
3172 window.dispatchEvent(new Event("resize"));
3173 if (jQuery("#pano' . $id . '").children().children(".pnlm-panorama-info:visible").length > 0) {
3174 jQuery("#controls' . $id . '").css("bottom", "55px");
3175 } else {
3176 jQuery("#controls' . $id . '").css("bottom", "5px");
3177 }
3178 }, 200);
3179 }
3180 }
3181 });';
3182 $html .= 'jQuery(".geodir-tab-head dd, #vr-tour-tab").click(function(){
3183 jQuery("#pano' . $id . '").children(".pnlm-render-container").remove();
3184 jQuery("#pano' . $id . '").children(".pnlm-ui").remove();
3185 panoshow' . $id . ' = pannellum.viewer(response[0]["panoid"], scenes);
3186 setTimeout(function() {
3187 panoshow' . $id . '.loadScene("' . $default_scene . '");
3188 window.dispatchEvent(new Event("resize"));
3189 if (jQuery("#pano' . $id . '").children().children(".pnlm-panorama-info:visible").length > 0) {
3190 jQuery("#controls' . $id . '").css("bottom", "55px");
3191 }
3192 else {
3193 jQuery("#controls' . $id . '").css("bottom", "5px");
3194 }
3195 }, 200);
3196 });';
3197 if (isset($previeword) && $previeword != '') {
3198 $html .= '
3199 jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '")
3200 ';
3201 }
3202 if ($default_global_zoom != '' || $max_global_zoom != '' || $min_global_zoom != '') {
3203 $html .= 'jQuery(".globalzoom").val("on").change();';
3204 }
3205
3206 $html .= 'jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseenter", function(){
3207 jQuery(this).attr("title", jQuery(this).text());
3208 });
3209 jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseleave", function(){
3210 jQuery(this).removeAttr("title");
3211 });';
3212 $html .= '});';
3213 $html .= '})(jQuery);';
3214 $html .= '</script>';
3215 $tour_data = [];
3216 if(defined("WPVR_PRO_VERSION")){
3217 $tour_data = array(
3218 'explainerControlSwitch' => ( isset( $custom_control['explainerSwitch'] ) && $custom_control['explainerSwitch'] === 'on' ) ? 'on' : 'off',
3219 'floor_plan_enable' => $floor_plan_enable ?? '',
3220 'floor_plan_image' => $floor_plan_image ?? '',
3221 'custom_control' => $custom_control ?? '',
3222 );
3223 }
3224 ob_start();
3225 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3226 echo $html;
3227 $output = ob_get_clean();
3228 return apply_filters('wpvr_generate_tour_layout_html', $output ,$postdata ,$id, $tour_data);
3229 }
3230
3231 function replace_callback($matches){
3232 foreach ($matches as $match){
3233 return str_replace('<img','<img decoding="async"',$match);
3234 }
3235
3236 }
3237
3238 private function sanitize_content_preserve_styles($content) {
3239 // Decode HTML entities first (in case content was encoded in database)
3240 $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
3241
3242 // Escape <script> blocks to display as text instead of removing them
3243 $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) {
3244 return esc_html($matches[0]); // Convert to plain text
3245 }, $content);
3246
3247 // Strip dangerous URL-based attributes
3248 $content = preg_replace('/(href|action|formaction)\s*=\s*["\']?\s*(javascript|vbscript|data|about):/i', '$1=""', $content);
3249
3250 // Escape inline event handlers (onclick, onhover, etc.) to display as text
3251 $content = preg_replace_callback('/\s*(on\w+)\s*=\s*(["\'])([^"\']*)\2/i', function($matches) {
3252 // Escape the attribute value but keep the attribute name visible as text
3253 return ' ' . esc_html($matches[1]) . '=' . $matches[2] . esc_html($matches[3]) . $matches[2];
3254 }, $content);
3255 $content = preg_replace_callback('/\s*(on\w+)\s*=\s*([^>\s]+)/i', function($matches) {
3256 // Handle unquoted event handlers
3257 return ' ' . esc_html($matches[1]) . '=' . esc_html($matches[2]);
3258 }, $content);
3259
3260 // Remove all unsafe embedded/interactive elements except iframe
3261 $content = preg_replace('/<(object|embed|applet|frame|frameset|meta|link|base|form|input|button|textarea|select|option)\b[^>]*>/i', '', $content);
3262 $content = preg_replace('/<\/(object|embed|applet|frame|frameset|meta|link|base|form|input|button|textarea|select|option)>/i', '', $content);
3263
3264 // Clean style attributes safely
3265 $content = preg_replace_callback('/style\s*=\s*["\']([^"\']*)["\']/', function($matches) {
3266 $style = $matches[1];
3267 $style = preg_replace('/expression\s*\(/i', '', $style);
3268 $style = preg_replace('/(javascript|vbscript|data|about)\s*:/i', '', $style);
3269 $style = preg_replace('/url\s*\(\s*["\']?\s*(javascript|vbscript|data):/i', '', $style);
3270 $style = preg_replace('/behavior\s*:/i', '', $style);
3271 $style = preg_replace('/-moz-binding\s*:/i', '', $style);
3272 return 'style="' . esc_attr($style) . '"';
3273 }, $content);
3274
3275 // Sanitize <style> blocks
3276 $content = preg_replace_callback('/<style\b[^>]*>(.*?)<\/style>/si', function($matches) {
3277 $css = $matches[1];
3278 $css = preg_replace('/(expression|javascript|vbscript|data|about)\s*:/i', '', $css);
3279 $css = preg_replace('/url\s*\(\s*["\']?\s*(javascript|vbscript|data):/i', '', $css);
3280 $css = preg_replace('/behavior\s*:/i', '', $css);
3281 $css = preg_replace('/-moz-binding\s*:/i', '', $css);
3282 return '<style>' . esc_html($css) . '</style>';
3283 }, $content);
3284
3285 // Allow iframes from safe sources only (e.g., YouTube, Vimeo)
3286 $allowed_tags = wp_kses_allowed_html('post');
3287 $allowed_tags['iframe'] = [
3288 'src' => true,
3289 'width' => true,
3290 'height' => true,
3291 'frameborder' => true,
3292 'allowfullscreen' => true,
3293 'class' => true,
3294 'style' => true,
3295 'title' => true,
3296 'allow' => true,
3297 'name' => true,
3298 'referrerpolicy' => true,
3299 'loading' => true,
3300 'sandbox' => true,
3301 ];
3302 $allowed_tags['img'] = [
3303 'src' => true,
3304 'alt' => true,
3305 'title' => true,
3306 'width' => true,
3307 'height' => true,
3308 'class' => true,
3309 'id' => true,
3310 'style' => true,
3311 'loading' => true,
3312 'srcset' => true,
3313 'sizes' => true,
3314 ];
3315
3316 // Apply wp_kses() to keep only allowed tags/attributes
3317 $content = wp_kses($content, $allowed_tags);
3318
3319 // Finally, validate iframe src for security (allow https only, block javascript: etc.)
3320 $content = preg_replace_callback('/<iframe[^>]+src=["\']([^"\']+)["\'][^>]*>(?:<\/iframe>)?/i', function($matches) {
3321 $src = $matches[1];
3322 // Allow any https:// or http:// URL, but block javascript:, data:, vbscript:, etc.
3323 if (preg_match('/^(https?:)?\/\//i', $src) && !preg_match('/^(javascript|data|vbscript|about):/i', $src)) {
3324 return $matches[0]; // keep safe iframe
3325 }
3326 // Strip unsafe iframe
3327 return '';
3328 }, $content);
3329
3330 return $content;
3331 }
3332
3333 }