PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.0.3
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.0.3
9.1.3 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 All 222 releases
wpvr / legacy / admin / classes / class-tour-preview-meta-box.php

class-tour-preview-meta-box.php in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 9.0.3, at legacy/admin/classes/class-tour-preview-meta-box.php

998 lines 46.1 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 * Preview meta box related functionalities
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_Tour_Preview extends WPVR_Meta_Box
14 {
15
16 /**
17 * @var string
18 * @since 8.0.0
19 */
20 protected $title = '';
21
22 /**
23 * Metabox ID
24 *
25 * @var string
26 * @since 8.0.0
27 */
28 protected $slug = '';
29
30 /**
31 * @var string
32 * @since 8.0.0
33 */
34 protected $post_type = '';
35
36 /**
37 * Metabox context
38 *
39 * @var string
40 * @since 8.0.0
41 */
42 protected $context = '';
43
44 /**
45 * Metabox priority
46 *
47 * @var string
48 * @since 8.0.0
49 */
50 protected $priority = '';
51
52
53 public function __construct($slug, $title, $post_type, $context, $priority)
54 {
55 if ($slug == '' || $context == '' || $priority == '') {
56 return;
57 }
58
59 if ($title == '') {
60 $this->title = ucfirst($slug);
61 }
62
63 if (empty($post_type)) {
64 return;
65 }
66
67 $this->title = $title;
68 $this->slug = $slug;
69 $this->post_type = $post_type;
70 $this->context = $context;
71 $this->priority = $priority;
72
73 add_action('add_meta_boxes', array($this, 'register'));
74 }
75
76
77 /**
78 * Register review custom meta box
79 *
80 * @param string $post_type
81 *
82 * @return void
83 * @since 8.0.0
84 */
85 public function register($post_type)
86 {
87 if ($post_type == $this->post_type) {
88 add_meta_box($this->slug, $this->title, array($this, 'render'), $post_type, $this->context, $this->priority);
89 }
90 }
91
92
93 /**
94 * Render custom meta box
95 *
96 * @param object $post
97 *
98 * @return void
99 * @since 8.0.0
100 */
101 public function render($post)
102 {
103 $post = '';
104 $id = '';
105 $postdata = array();
106 $post = get_post();
107 $id = $post->ID;
108
109 $postdata = get_post_meta($id, 'panodata', true);
110 $panoid = 'pano' . $id;
111
112 if (isset($postdata['vidid'])) {
113 ob_start();
114 ?>
115 <div class="iframe-wrapper">
116 <i class="fa fa-times" id="cross"></i>
117 <div id="custom-ifram" style="display: none;"></div>
118 <div id="<?php echo esc_attr( 'pano' . $id ); ?>" class="pano-wrap" style="height: 100%;">
119 <?php
120 if ( isset( $postdata['vidtype'] ) && $postdata['vidtype'] === 'youtube' && ! empty( $postdata['vidurl'] ) ) {
121 $format = new WPVR_Format();
122 $videodata = array(
123 'autoplay' => isset( $postdata['autoplay'] ) ? $postdata['autoplay'] : 'off',
124 'loop' => isset( $postdata['loop'] ) ? $postdata['loop'] : 'off',
125 );
126 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted internal preview markup includes script/style tags.
127 echo $format->prepare_youtube_video_preview( $postdata['vidurl'], $videodata );
128 } else {
129 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- stored tour preview markup is rendered as HTML.
130 echo $postdata['panoviddata'];
131 }
132 ?>
133 <?php if ( isset( $postdata['vidtype'] ) && $postdata['vidtype'] == 'selfhost') { ?>
134 <script>
135 videojs(<?php echo esc_js($postdata['vidid']); ?>, {
136 plugins: {
137 pannellum: {}
138 }
139 });
140 </script>
141 <?php } ?>
142 </div>
143 </div>
144 <?php
145 ob_end_flush();
146 } elseif (isset($postdata['streetviewdata'])) {
147 ob_start();
148 ?>
149 <div class="iframe-wrapper">
150 <i class="fa fa-times" id="cross"></i>
151 <div id="custom-ifram" style="display: none;">
152
153 </div>
154 <div id="<?php echo esc_attr( 'pano' . $id ); ?>" class="pano-wrap" style="height: 100%;">
155 <?php
156 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- stored street view markup is rendered as HTML.
157 echo $postdata['streetviewdata'];
158 ?>
159 </div>
160 </div>
161
162 <div class="rex-add-coordinates" style="text-align: center;">
163 <ul>
164 <li>
165 <div id="panodata" style="text-align: center; font-weight: bold;">
166 </div>
167 </li>
168 <li class="rex-hide-coordinates add-pitch">
169 <span class="rex-tooltiptext"><?php esc_html_e('Add This Position Into Active Hotspot', 'wpvr'); ?></span>
170 <i class="fa fa-plus toppitch"></i>
171 </li>
172 </ul>
173 </div>
174 <?php
175 ob_end_flush();
176 } elseif (isset($postdata['flat_image'])) {
177 ob_start();
178 ?>
179 <div class="iframe-wrapper">
180 <i class="fa fa-times" id="cross"></i>
181 <div id="custom-ifram" style="display: none;">
182
183 </div>
184 <div id="<?php echo esc_attr( 'pano' . $id ); ?>" class="pano-wrap" style="height: 100%;">
185 <img loading="lazy" src="<?php echo esc_url($postdata['flat_image_url']); ?>" style="width: 600px">
186 </div>
187 </div>
188
189 <div class="rex-add-coordinates" style="text-align: center;">
190 <ul>
191 <li>
192 <div id="panodata" style="text-align: center; font-weight: bold;">
193 </div>
194 </li>
195 <li class="rex-hide-coordinates add-pitch">
196 <span class="rex-tooltiptext"><?php esc_html_e('Add This Position Into Active Hotspot', 'wpvr'); ?></span>
197 <i class="fa fa-plus toppitch"></i>
198 </li>
199 </ul>
200 </div>
201 <?php
202 ob_end_flush();
203 } else {
204
205 $control = false;
206 if (isset($postdata['showControls'])) {
207 $control = $postdata['showControls'];
208 }
209
210 $compass = false;
211 if (isset($postdata['compass'])) {
212 $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
213 }
214 $mouseZoom = true;
215 if (isset($postdata['mouseZoom'])) {
216 $mouseZoom = $postdata['mouseZoom'] == 'on' || $postdata['mouseZoom'] === true ? true : false;
217 }
218 $draggable = true;
219 if (isset($postdata['draggable'])) {
220 $draggable = $postdata['draggable'] == 'on' || $postdata['draggable'] != null ? true : false;
221 }
222 $diskeyboard = false;
223 if (isset($postdata['diskeyboard'])) {
224 $diskeyboard = $postdata['diskeyboard'] == 'off' || $postdata['diskeyboard'] == null ? false : true;
225 }
226 $keyboardzoom = true;
227 if (isset($postdata['keyboardzoom'])) {
228 $keyboardzoom = $postdata['keyboardzoom'] == 'on' || $postdata['keyboardzoom'] != null ? true : false;
229 }
230 $autoload = false;
231 if (isset($postdata['autoLoad'])) {
232 // Pannellum requires strict boolean true (=== true) for autoLoad.
233 // Wizard-created tours store integer 1; cast to bool to ensure compatibility.
234 $autoload = (bool) $postdata['autoLoad'];
235 }
236
237 $default_scene = '';
238 if (isset($postdata['defaultscene'])) {
239 $default_scene = $postdata['defaultscene'];
240 }
241
242 $preview = '';
243 if (isset($postdata['preview'])) {
244 $preview = $postdata['preview'];
245 }
246
247 $autorotation = '';
248 if (isset($postdata["autoRotate"])) {
249 $autorotation = $postdata["autoRotate"];
250 }
251 $autorotationinactivedelay = '';
252 if (isset($postdata["autoRotateInactivityDelay"])) {
253 $autorotationinactivedelay = $postdata["autoRotateInactivityDelay"];
254 }
255 $autorotationstopdelay = '';
256 if (isset($postdata["autoRotateStopDelay"])) {
257 $autorotationstopdelay = $postdata["autoRotateStopDelay"];
258 }
259
260 $scene_fade_duration = '';
261 if (isset($postdata['scenefadeduration'])) {
262 $scene_fade_duration = $postdata['scenefadeduration'];
263 }
264
265 $default_global_zoom = '';
266 if (isset($postdata['hfov'])) {
267 $default_global_zoom = $postdata['hfov'];
268 }
269
270 $max_global_zoom = '';
271 if (isset($postdata['maxHfov'])) {
272 $max_global_zoom = $postdata['maxHfov'];
273 }
274
275 $min_global_zoom = '';
276 if (isset($postdata['minHfov'])) {
277 $min_global_zoom = $postdata['minHfov'];
278 }
279
280 $panodata = '';
281 if (isset($postdata['panodata'])) {
282 $panodata = $postdata['panodata'];
283 }
284
285 $floor_map_image = '';
286 $is_floor_enable = 'off';
287 if (isset($postdata['floor_plan_tour_enabler'])) {
288 $is_floor_enable = $postdata['floor_plan_tour_enabler'];
289 if ($is_floor_enable == 'on') {
290 $floor_map_image = $postdata['floor_plan_attachment_url'];
291 }
292 }
293
294 $default_data = array();
295 if ($default_global_zoom != '' && $max_global_zoom != '' && $min_global_zoom != '') {
296 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration, "hfov" => $default_global_zoom, "maxHfov" => $max_global_zoom, "minHfov" => $min_global_zoom);
297 } else {
298 $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration);
299 }
300
301 $scene_data = array();
302
303 if (!empty($panodata)) {
304 foreach ($panodata["scene-list"] as $panoscenes) {
305
306 $scene_ititle = '';
307 if (isset($panoscenes["scene-ititle"])) {
308 $scene_ititle = sanitize_text_field($panoscenes["scene-ititle"]);
309 }
310
311 $scene_author = '';
312 if (isset($panoscenes["scene-author"])) {
313 $scene_author = sanitize_text_field($panoscenes["scene-author"]);
314 }
315
316 $scene_vaov = 180;
317 if (isset($panoscenes["scene-vaov"])) {
318 $scene_vaov = (float)$panoscenes["scene-vaov"];
319 }
320
321 $scene_haov = 360;
322 if (isset($panoscenes["scene-haov"])) {
323 $scene_haov = (float)$panoscenes["scene-haov"];
324 }
325
326
327 $scene_vertical_offset = 0;
328 if (isset($panoscenes["scene-vertical-offset"])) {
329 $scene_vertical_offset = (float)$panoscenes["scene-vertical-offset"];
330 }
331
332 $default_scene_pitch = null;
333 if (isset($panoscenes["scene-pitch"])) {
334 $default_scene_pitch = (float)$panoscenes["scene-pitch"];
335 }
336
337 $default_scene_yaw = null;
338 if (isset($panoscenes["scene-yaw"])) {
339 $default_scene_yaw = (float)$panoscenes["scene-yaw"];
340 }
341
342 $scene_max_pitch = '';
343 if (isset($panoscenes["scene-maxpitch"])) {
344 $scene_max_pitch = (float)$panoscenes["scene-maxpitch"];
345 }
346
347
348 $scene_min_pitch = '';
349 if (isset($panoscenes["scene-minpitch"])) {
350 $scene_min_pitch = (float)$panoscenes["scene-minpitch"];
351 }
352
353
354 $scene_max_yaw = '';
355 if (isset($panoscenes["scene-maxyaw"])) {
356 $scene_max_yaw = (float)$panoscenes["scene-maxyaw"];
357 }
358
359
360 $scene_min_yaw = '';
361 if (isset($panoscenes["scene-minyaw"])) {
362 $scene_min_yaw = (float)$panoscenes["scene-minyaw"];
363 }
364
365
366 $default_zoom = 100;
367 if (isset($panoscenes["scene-zoom"]) && $panoscenes["scene-zoom"] != '') {
368 $default_zoom = (int)$panoscenes["scene-zoom"];
369 } else {
370 if ($default_global_zoom != '') {
371 $default_zoom = (int)$default_global_zoom;
372 }
373 }
374
375
376
377 $max_zoom = 120;
378 if (isset($panoscenes["scene-maxzoom"]) && $panoscenes["scene-maxzoom"] != '') {
379 $max_zoom = (int)$panoscenes["scene-maxzoom"];
380 } else {
381 if ($max_global_zoom != '') {
382 $max_zoom = (int)$max_global_zoom;
383 }
384 }
385
386
387
388
389 $min_zoom = 50;
390 if (isset($panoscenes["scene-minzoom"]) && $panoscenes["scene-minzoom"] != '') {
391 $min_zoom = (int)$panoscenes["scene-minzoom"];
392 } else {
393 if ($min_global_zoom != '') {
394 $min_zoom = (int)$min_global_zoom;
395 }
396 }
397
398 $hotspot_datas = array();
399 if (isset($panoscenes["hotspot-list"])) {
400 $hotspot_datas = $panoscenes["hotspot-list"];
401 }
402
403 $hotspots = array();
404 foreach ($hotspot_datas as $hotspot_data) {
405
406 $hotspot_scene_pitch = '';
407 if (isset($hotspot_data["hotspot-scene-pitch"])) {
408 $hotspot_scene_pitch = $hotspot_data["hotspot-scene-pitch"];
409 }
410 $hotspot_scene_yaw = '';
411 if (isset($hotspot_data["hotspot-scene-yaw"])) {
412 $hotspot_scene_yaw = $hotspot_data["hotspot-scene-yaw"];
413 }
414
415 $hotspot_type = $hotspot_data["hotspot-type"] !== 'scene' ? 'info' : $hotspot_data["hotspot-type"];
416 $hotspot_content = '';
417
418 ob_start();
419 do_action('wpvr_hotspot_content', $hotspot_data);
420 $hotspot_content = ob_get_clean();
421
422 if (!$hotspot_content) $hotspot_content = $hotspot_data["hotspot-content"];
423
424
425 $hotspot_info = array(
426 "text" => esc_html($hotspot_data["hotspot-title"]),
427 "pitch" => $hotspot_data["hotspot-pitch"],
428 "yaw" => $hotspot_data["hotspot-yaw"],
429 "type" => $hotspot_type,
430 "URL" => $hotspot_data["hotspot-url"],
431 "clickHandlerArgs" => sanitize_content_preserve_styles($hotspot_content, ($hotspot_data['hotspot-type'] ?? '') === 'fluent_form'),
432 "createTooltipArgs" => sanitize_content_preserve_styles($hotspot_data["hotspot-hover"] ?? '', false),
433 "sceneId" => $hotspot_data["hotspot-scene"],
434 "targetPitch" => (float)$hotspot_scene_pitch,
435 "targetYaw" => (float)$hotspot_scene_yaw
436 );
437 array_push($hotspots, $hotspot_info);
438 if (empty($hotspot_data["hotspot-scene"])) {
439 unset($hotspot_info['targetPitch']);
440 unset($hotspot_info['targetYaw']);
441 }
442 }
443
444 $scene_info = array();
445
446
447 if ($panoscenes["scene-type"] == 'cubemap') {
448 $pano_type = 'cubemap';
449 $pano_attachment = array(
450 $panoscenes["scene-attachment-url-face0"],
451 $panoscenes["scene-attachment-url-face1"],
452 $panoscenes["scene-attachment-url-face2"],
453 $panoscenes["scene-attachment-url-face3"],
454 $panoscenes["scene-attachment-url-face4"],
455 $panoscenes["scene-attachment-url-face5"]
456 );
457
458 $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, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, "hotSpots" => $hotspots);
459 } else {
460 $scene_info = array("type" => $panoscenes["scene-type"], "panorama" => $panoscenes["scene-attachment-url"], "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, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, "hotSpots" => $hotspots);
461 }
462
463
464
465 if (isset($panoscenes["ptyscene"])) {
466 if ($panoscenes["ptyscene"] == "off") {
467 unset($scene_info['pitch']);
468 unset($scene_info['yaw']);
469 }
470 }
471
472 if (empty($panoscenes["scene-ititle"])) {
473 unset($scene_info['title']);
474 }
475 if (empty($panoscenes["scene-author"])) {
476 unset($scene_info['author']);
477 }
478
479 if (empty($scene_vaov)) {
480 unset($scene_info['vaov']);
481 }
482
483 if (empty($scene_haov)) {
484 unset($scene_info['haov']);
485 }
486
487 if (empty($scene_vertical_offset)) {
488 unset($scene_info['vOffset']);
489 }
490
491 if (isset($panoscenes["cvgscene"])) {
492 if ($panoscenes["cvgscene"] == "off") {
493 unset($scene_info['maxPitch']);
494 unset($scene_info['minPitch']);
495 }
496 }
497
498 if (empty($panoscenes["scene-maxpitch"])) {
499 unset($scene_info['maxPitch']);
500 }
501
502 if (empty($panoscenes["scene-minpitch"])) {
503 unset($scene_info['minPitch']);
504 }
505
506 if (isset($panoscenes["chgscene"])) {
507 if ($panoscenes["chgscene"] == "off") {
508 unset($scene_info['maxYaw']);
509 unset($scene_info['minYaw']);
510 }
511 }
512 if (empty($panoscenes["scene-maxyaw"])) {
513 unset($scene_info['maxYaw']);
514 }
515
516 if (empty($panoscenes["scene-minyaw"])) {
517 unset($scene_info['minYaw']);
518 }
519
520 $scene_array = array();
521 $scene_array = array(
522 $panoscenes["scene-id"] => $scene_info
523 );
524 $scene_data[$panoscenes["scene-id"]] = $scene_info;
525 }
526 }
527
528 $pano_id_array = array();
529 $pano_id_array = array("panoid" => $panoid);
530 $pano_response = array();
531 $pano_response = array("autoLoad" => $autoload, "showControls" => $control, 'compass' => $compass, 'mouseZoom' => $mouseZoom, 'draggable' => $draggable, 'disableKeyboardCtrl' => $diskeyboard, 'keyboardZoom' => $keyboardzoom, "preview" => $preview, "autoRotate" => $autorotation, "autoRotateInactivityDelay" => $autorotationinactivedelay, "autoRotateStopDelay" => $autorotationstopdelay, "default" => $default_data, "scenes" => $scene_data);
532
533 if (empty($autorotation)) {
534 unset($pano_response['autoRotate']);
535 unset($pano_response['autoRotateInactivityDelay']);
536 unset($pano_response['autoRotateStopDelay']);
537 }
538 if (empty($autorotationinactivedelay)) {
539 unset($pano_response['autoRotateInactivityDelay']);
540 }
541 if (empty($autorotationstopdelay)) {
542 unset($pano_response['autoRotateStopDelay']);
543 }
544
545 $response = array();
546 $response = array($pano_id_array, $pano_response);
547 if (!empty($response)) {
548 $response = json_encode($response);
549 }
550 $floor_list_pointer_position = isset($postdata['floor_plan_pointer_position']) ? $postdata['floor_plan_pointer_position'] : '';
551 $calltoaction = isset($postdata['calltoaction']) ? $postdata['calltoaction']: 'off';
552 $buttontext = isset($postdata['buttontext']) ? $postdata['buttontext']: 'Click Here';
553 $buttonurl = isset($postdata['buttonurl']) ? $postdata['buttonurl']: '';
554 $calltoactionbutton_css = isset($postdata['calltoactionbutton']) ? $postdata['calltoactionbutton']: '';
555 $floor_list_pointer_position_object= array();
556 if(is_array($floor_list_pointer_position)){
557 foreach ($floor_list_pointer_position as $item) {
558 $floor_list_pointer_position_object[] = (object)$item;
559 }
560 $floor_list_pointer_position = $floor_list_pointer_position_object;
561 }
562 ob_start();
563 ?>
564
565 <div class="iframe-wrapper">
566 <i class="fa fa-times" id="cross"></i>
567 <?php if (!apply_filters('is_wpvr_pro_active', false)) : // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound ?>
568 <div class="wpvr-pro-preview-watermark" id="wpvr-pro-preview-watermark" style="display:none;">
569 <span><?php esc_html_e('PRO PREVIEW', 'wpvr'); ?></span>
570 </div>
571
572 <!-- Pro Preview: Feature mockup overlays (Option B) -->
573 <div class="wpvr-pro-mockup wpvr-pro-mockup--gallery" id="wpvr-pro-mockup-gallery" style="display:none;">
574 <div class="wpvr-pro-mockup-gallery__bar">
575 <span class="wpvr-pro-mockup-gallery__toggle">
576 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
577 </span>
578 <div class="wpvr-pro-mockup-gallery__thumbs">
579 <div class="wpvr-pro-mockup-gallery__thumb"></div>
580 <div class="wpvr-pro-mockup-gallery__thumb"></div>
581 <div class="wpvr-pro-mockup-gallery__thumb"></div>
582 <div class="wpvr-pro-mockup-gallery__thumb"></div>
583 </div>
584 <span class="wpvr-pro-mockup-gallery__label"><?php esc_html_e('Scene Gallery', 'wpvr'); ?></span>
585 </div>
586 </div>
587
588 <div class="wpvr-pro-mockup wpvr-pro-mockup--navigation" id="wpvr-pro-mockup-navigation" style="display:none;">
589 <span class="wpvr-pro-mockup-navigation__icon">
590 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
591 </span>
592 <span class="wpvr-pro-mockup-navigation__list">
593 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 1', 'wpvr'); ?></span>
594 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 2', 'wpvr'); ?></span>
595 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 3', 'wpvr'); ?></span>
596 </span>
597 </div>
598
599 <div class="wpvr-pro-mockup wpvr-pro-mockup--audio" id="wpvr-pro-mockup-audio" style="display:none;">
600 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>
601 <span><?php esc_html_e('Background Music', 'wpvr'); ?></span>
602 </div>
603
604 <div class="wpvr-pro-mockup wpvr-pro-mockup--gyro" id="wpvr-pro-mockup-gyro" style="display:none;">
605 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/></svg>
606 <span><?php esc_html_e('Gyroscope — Active on mobile', 'wpvr'); ?></span>
607 </div>
608 <?php endif; ?>
609 <div id="custom-ifram" style="display: none;"></div>
610 <div id="<?php echo esc_attr( 'pano' . $id ); ?>" class="pano-wrap" style="direction:ltr; height: 100%">
611 <?php if ($is_floor_enable == 'on') { ?>
612 <div class="wpvr-floor-preview outfit">
613 <div class="wpvr-floor-preview-inner">
614 <img loading="lazy" src="<?php echo esc_url($floor_map_image); ?>" alt="">
615 <?php foreach ( $floor_list_pointer_position as $pointer_position ) {
616 echo sprintf(
617 '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" id="%1$s" data-top="%2$s" data-left="%3$s" style="%4$s">%5$s</div>',
618 esc_attr( $pointer_position->id ),
619 esc_attr( $pointer_position->data_top ),
620 esc_attr( $pointer_position->data_left ),
621 esc_attr( $pointer_position->style ),
622 esc_html( $pointer_position->text )
623 );
624 }
625 ?>
626 </div>
627 </div>
628 <button class="flooplan-toggle">
629 <i class="far fa-map"></i>
630 </button>
631
632 <?php } ?>
633 </div>
634
635 </div>
636
637 <div class="rex-add-coordinates" style="text-align: center;">
638 <ul>
639 <li>
640 <div id="panodata" style="text-align: center; font-weight: bold;">
641
642 </div>
643 </li>
644 <li class="rex-hide-coordinates add-pitch">
645 <span class="rex-tooltiptext"><?php esc_html_e('Add This Position Into Active Hotspot', 'wpvr'); ?></span>
646 <i class="fa fa-plus toppitch"></i>
647 </li>
648 </ul>
649
650 <div class="scene-gallery vrowl-carousel" style="direction:ltr;">
651
652 </div>
653
654 </div>
655
656 <?php
657 ob_end_flush();
658 /**
659 * Nasim
660 * include alert modal
661 */
662
663 $is_pro = apply_filters('is_wpvr_pro_active',false); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
664
665 $pro = (bool) $is_pro;
666 ?>
667
668 <script>
669 var response = <?php echo wp_json_encode( json_decode( $response, true ) ); ?>;
670 var scenes = response[1];
671 var is_pro = <?php echo wp_json_encode( $pro ); ?>;
672
673 if (scenes) {
674 jQuery.each(scenes.scenes, function(i) {
675 jQuery.each(scenes.scenes[i]['hotSpots'], function(key, val) {
676 if (val["clickHandlerArgs"]) {
677 const hasTextContent = val["clickHandlerArgs"].replace(/<[^>]*>/g, '').trim() !== '';
678 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(val["clickHandlerArgs"]);
679 const hasOtherContent = val["clickHandlerArgs"].replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
680
681 if (hasTextContent || hasMediaContent || hasOtherContent) {
682 val["clickHandlerFunc"] = function(div, args) { if (typeof wpvrhotspot === "function") { wpvrhotspot(div, args); } else if (typeof window.wpvrhotspot === "function") { window.wpvrhotspot(div, args); } };
683 }
684 }
685 if (val["createTooltipArgs"]) {
686 const hasTextContent = val["createTooltipArgs"].replace(/<[^>]*>/g, '').trim() !== '';
687 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(val["createTooltipArgs"]);
688 const hasOtherContent = val["createTooltipArgs"].replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
689
690 if (hasTextContent || hasMediaContent || hasOtherContent) {
691 val["createTooltipFunc"] = function(div, args) { if (typeof wpvrtooltip === "function") { wpvrtooltip(div, args); } else if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };
692 }
693 }
694 });
695 });
696 }
697 if (scenes) {
698 jQuery('.scene-gallery').empty();
699
700 jQuery.each(scenes.scenes, function(key, val) {
701 if (val.type == 'cubemap') {
702 var img_data = val.cubeMap[0];
703 } else {
704 var img_data = val.panorama;
705 }
706 jQuery('.scene-gallery').append('<ul style="width:150px;"><li class="owlscene owl' + key + '">' + key + '</li><li title="Click to view scene"><img loading="lazy" class="scctrl" id="' + key + '_gallery" src="' + img_data + '"></li></ul>');
707 });
708 }
709
710 if (response[1]['scenes'] != "") {
711 var panoshow = pannellum.viewer(response[0]["panoid"], scenes);
712 var autoLoad = <?php echo json_encode($autoload); ?>;
713 if (!autoLoad) {
714 jQuery('.pnlm-controls-container').hide();
715 }
716
717 panoshow.on('load', function(){
718 jQuery('.pnlm-controls-container').show();
719 });
720
721 if (scenes.autoRotate) {
722 panoshow.on('load', function() {
723 setTimeout(function() {
724 panoshow.startAutoRotate(scenes.autoRotate, 0);
725 }, 3000);
726 });
727 panoshow.on('scenechange', function() {
728 setTimeout(function() {
729 panoshow.startAutoRotate(scenes.autoRotate, 0);
730 }, 3000);
731 });
732 }
733
734 if (scenes) {
735 jQuery.each(scenes.scenes, function(key, val) {
736 document.getElementById('' + key + '_gallery').addEventListener('click', function(e) {
737 jQuery('.owl-item').removeClass('marked');
738 jQuery(this).closest('.owl-item').addClass('marked');
739 if (panoshow.getScene() !== key) {
740 panoshow.loadScene(key);
741 }
742 activateSceneTab(key);
743 });
744 });
745 }
746
747 }
748 function activateSceneTab(sceneId){
749 jQuery(".scene-nav ul li span").each(function() {
750 var sceneTab = jQuery(this);
751 var dataHrefValue = sceneTab.attr("data-href");
752 var scenePanel = jQuery(dataHrefValue);
753 var currentScene = scenePanel.find('input.sceneid').val();
754
755 if(sceneId == currentScene){
756 jQuery([sceneTab.parent()[0], scenePanel[0]])
757 .addClass('active')
758 .siblings('.active')
759 .removeClass('active');
760 jQuery('#wpvr_active_scenes').val(sceneTab.data('index'));
761 return false;
762 }
763 });
764 }
765
766 function wpvrSanitizeHtml(rawHtml) {
767 if (!rawHtml || typeof rawHtml !== 'string') return '';
768 var clean = rawHtml.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
769 try {
770 var parser = new DOMParser();
771 var doc = parser.parseFromString(clean, 'text/html');
772 var elements = doc.body.querySelectorAll('*');
773 for (var i = 0; i < elements.length; i++) {
774 var el = elements[i];
775 var tag = el.tagName.toLowerCase();
776 if (['script', 'object', 'embed', 'applet', 'link', 'meta', 'base'].indexOf(tag) !== -1) {
777 el.parentNode && el.parentNode.removeChild(el);
778 continue;
779 }
780 var attrs = el.attributes;
781 for (var a = attrs.length - 1; a >= 0; a--) {
782 var attrName = attrs[a].name.toLowerCase();
783 var attrVal = attrs[a].value;
784 if (attrName.indexOf('on') === 0) {
785 el.removeAttribute(attrs[a].name);
786 } else if (['href', 'src', 'action', 'formaction', 'xlink:href'].indexOf(attrName) !== -1) {
787 if (/^\s*(javascript|vbscript|data:text\/html):/i.test(attrVal)) {
788 el.removeAttribute(attrs[a].name);
789 }
790 }
791 }
792 }
793 return doc.body.innerHTML;
794 } catch (e) {
795 return clean.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '').replace(/\s*on\w+\s*=\s*[^\s>]+/gi, '');
796 }
797 }
798
799 function wpvrhotspot(hotSpotDiv, args) {
800 var argst = typeof args === 'string' ? args.replace(/\\/g, '') : '';
801 argst = wpvrSanitizeHtml(argst);
802 jQuery("#custom-ifram").html(argst);
803 jQuery("#custom-ifram").fadeToggle();
804 jQuery(".iframe-wrapper").toggleClass("show-modal");
805 jQuery('button.ff-btn.ff-btn-submit.ff-btn-md').prop('disabled', true);
806
807 //------add to cart button------
808 jQuery('.wpvr-product-container p.add_to_cart_inline a.button').wrap('<span class="wpvr-cart-wrap"></span>');
809 }
810
811 function wpvrtooltip(hotSpotDiv, args) {
812 hotSpotDiv.classList.add('custom-tooltip');
813 var span = document.createElement('p');
814 var cleanTooltip = typeof args === 'string' ? args.replace(/\\/g, "") : '';
815 span.innerHTML = wpvrSanitizeHtml(cleanTooltip);
816 hotSpotDiv.appendChild(span);
817 span.style.marginLeft = -(span.scrollWidth - hotSpotDiv.offsetWidth) / 2 + 'px';
818 span.style.marginTop = -span.scrollHeight - 12 + 'px';
819 const style = document.createElement('style');
820 style.textContent = `
821 .table, .table td, .table th {
822 border: 1px solid #dee2e6;
823 border-collapse: collapse;
824 padding: 8px;
825 }
826 `;
827 document.head.appendChild(style);
828 }
829
830 jQuery(document).ready(function($) {
831 jQuery("#cross").on("click", function(e) {
832 e.preventDefault();
833 jQuery("#custom-ifram").fadeOut();
834 jQuery(".iframe-wrapper").removeClass("show-modal");
835 jQuery('iframe').attr('src', $('iframe').attr('src'));
836 });
837 });
838
839
840
841
842
843 jQuery(document).ready(function($) {
844 $(document).on("click",".outfit img",function(e) {
845 // var sceneinfo = jQuery(".hotspotscene").html();
846 var dot_count = $(".floor-plan-pointer").length;
847 // var pano_scenes = scenes.scenes;
848 var pano_scenes = jQuery('.scene-setup').repeaterVal();
849 pano_scenes = pano_scenes['scene-list']
850
851 var top_offset = $(this).offset().top - $(window).scrollTop();
852 var left_offset = $(this).offset().left - $(window).scrollLeft();
853
854 var top_px = Math.round((e.clientY - top_offset - 12));
855 var left_px = Math.round((e.clientX - left_offset - 12));
856
857 var top_perc = top_px / $(this).height() * 100;
858 var left_perc = left_px / $(this).width() * 100;
859 var options = "";
860 for(var i in pano_scenes) {
861 var sceneId = pano_scenes[i]['scene-id']
862 if(sceneId != ''){
863 options += '<option value="'+sceneId+'">'+sceneId+'</option>';
864 }
865 }
866 var is_backgroud = $(".floor-plan-background-custom-color").val();
867 var background_color
868 if(is_backgroud != ''){
869 background_color = is_backgroud;
870 }else{
871 background_color = '#cca92c'
872 }
873
874 var dot = '<div class="floor-plan-pointer" id="pointer-'+(dot_count + 1)+'" data-top="'+top_perc+'%" data-left="'+ left_perc +'%" style="background : '+background_color+';top: ' + top_perc + '%; left: ' + left_perc + '%; ">' + (dot_count + 1) + '</div>';
875
876 var li_content = '<li><label for="floor-plan">Pointer - '+(dot_count + 1)+':</label><select name="plan'+(dot_count + 1)+'" class="floor_plan_scene_option">'+options+'</select><button class="plan-delete" data-id="'+(dot_count + 1)+'"><i class="fas fa-trash-alt"></i></button></li>';
877
878 $(dot).hide().appendTo($(this).parent()).fadeIn(350);
879 $(li_content).hide().appendTo('.floor-plan-pointer-list > ul').fadeIn(350);
880
881 if(is_pro) {
882 $(".floor-plan-pointer").draggable({
883 containment: ".outfit",
884 stop: function(event, ui) {
885 var new_left_perc = parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%";
886 var new_top_perc = parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%";
887 var output = 'Top: ' + parseInt(new_top_perc) + '%, Left: ' + parseInt(new_left_perc) + '%';
888
889 $(this).css("left", parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
890 $(this).css("top", parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
891
892 $(this).attr('data-top', parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
893 $(this).attr('data-left', parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
894 }
895 });
896 }
897
898 });
899 if(is_pro) {
900 $(".floor-plan-pointer").draggable({
901 containment: ".outfit",
902 stop: function(event, ui) {
903 var new_left_perc = parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%";
904 var new_top_perc = parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%";
905 var output = 'Top: ' + parseInt(new_top_perc) + '%, Left: ' + parseInt(new_left_perc) + '%';
906
907 $(this).css("left", parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
908 $(this).css("top", parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
909
910 $(this).attr('data-top', parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
911 $(this).attr('data-left', parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
912 }
913 });
914 }
915 });
916
917
918 jQuery(document).on("click",".flooplan-toggle",function(e) {
919 e.preventDefault();
920 jQuery('.wpvr-floor-preview').slideToggle();
921 });
922
923
924 jQuery(document).on("click", ".plan-delete", function(e) {
925 e.preventDefault();
926
927 var $li = jQuery(this).closest("li");
928 var dataId = jQuery(this).attr("data-id");
929
930 // Remove corresponding pointer
931 jQuery('#pointer-' + dataId).remove();
932
933 // Add class to trigger CSS animation
934 $li.addClass("removing");
935
936 // Remove the element after animation ends
937 setTimeout(function() {
938 $li.remove();
939
940 // Re-index pointers
941 jQuery(".floor-plan-pointer").each(function(index) {
942 var number = index + 1;
943 jQuery(this).text(number);
944 jQuery(this).attr("id", "pointer-" + number);
945 });
946
947 // Re-index list items
948 jQuery(".floor-plan-pointer-list ul li").each(function(index) {
949 var number = index + 1;
950 jQuery(this).children("label").text('Pointer - ' + number);
951 jQuery(this).children("select").attr('name', "plan-" + number);
952 jQuery(this).children(".plan-delete").attr('data-id', number);
953 });
954
955 }, 300); // match CSS transition duration
956 });
957
958
959 </script>
960 <?php } ?>
961
962
963 <div class="wpvr-use-shortcode">
964 <?php
965 $post = get_post();
966 $id = $post->ID;
967 $slug = $post->post_name;
968 $postdata = get_post_meta($post->ID, 'panodata', true);
969 ?>
970 <div class="shortcode-wrapper">
971
972 <div class="single-shortcode classic">
973
974 <div class="field-wapper">
975 <!-- Start preview button -->
976 <button id="panolenspreview" class="panolenspreview wpvr_preview_button"><?php esc_html_e('Preview', 'wpvr'); ?></button>
977 <!-- <button id="panolenssave" class="panolenssave wpvr_preview_button">--><?php //echo __('Save', 'wpvr'); ?><!--</button>-->
978 <!-- End preview button -->
979 <div class="shortcode-field">
980
981 <p class="copycode" id="copy-shortcode">[wpvr id="<?php echo esc_html($id); ?>"]</p>
982
983 <span id="wpvr-copy-shortcode" class="wpvr-copy-shortcode">
984 <img loading="lazy" src="<?php echo esc_url( WPVR_PLUGIN_DIR_URL . 'admin/icon/copy.png' ); ?>" alt="icon" />
985 </span>
986
987 </div>
988
989 <span id="wpvr-copied-notice" class="wpvr-copied-notice"></span>
990
991 </div>
992 </div>
993
994 </div>
995 </div>
996 <?php }
997 }
998