PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.1
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.1
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.1.1, at legacy/admin/classes/class-tour-preview-meta-box.php

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