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

1,018 lines 47.2 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 $is_fluent_form = ($hotspot_data['hotspot-type'] ?? '') === 'fluent_form';
436 if ($is_fluent_form) {
437 if ($hotspot_content) {
438 $hotspot_content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $hotspot_content);
439 }
440 } else {
441 if (!$hotspot_content) $hotspot_content = $hotspot_data["hotspot-content"] ?? '';
442 }
443
444
445 $hotspot_info = array(
446 "text" => esc_html($hotspot_data["hotspot-title"]),
447 "pitch" => $hotspot_data["hotspot-pitch"],
448 "yaw" => $hotspot_data["hotspot-yaw"],
449 "type" => $hotspot_type,
450 "URL" => $hotspot_data["hotspot-url"],
451 "clickHandlerArgs" => sanitize_content_preserve_styles($hotspot_content, $is_fluent_form),
452 "createTooltipArgs" => sanitize_content_preserve_styles($hotspot_data["hotspot-hover"] ?? '', false),
453 "sceneId" => $hotspot_data["hotspot-scene"],
454 "targetPitch" => (float)$hotspot_scene_pitch,
455 "targetYaw" => (float)$hotspot_scene_yaw
456 );
457 array_push($hotspots, $hotspot_info);
458 if (empty($hotspot_data["hotspot-scene"])) {
459 unset($hotspot_info['targetPitch']);
460 unset($hotspot_info['targetYaw']);
461 }
462 }
463
464 $scene_info = array();
465
466
467 if ($panoscenes["scene-type"] == 'cubemap') {
468 $pano_type = 'cubemap';
469 $pano_attachment = array(
470 $panoscenes["scene-attachment-url-face0"],
471 $panoscenes["scene-attachment-url-face1"],
472 $panoscenes["scene-attachment-url-face2"],
473 $panoscenes["scene-attachment-url-face3"],
474 $panoscenes["scene-attachment-url-face4"],
475 $panoscenes["scene-attachment-url-face5"]
476 );
477
478 $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);
479 } else {
480 $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);
481 }
482
483
484
485 if (isset($panoscenes["ptyscene"])) {
486 if ($panoscenes["ptyscene"] == "off") {
487 unset($scene_info['pitch']);
488 unset($scene_info['yaw']);
489 }
490 }
491
492 if (empty($panoscenes["scene-ititle"])) {
493 unset($scene_info['title']);
494 }
495 if (empty($panoscenes["scene-author"])) {
496 unset($scene_info['author']);
497 }
498
499 if (empty($scene_vaov)) {
500 unset($scene_info['vaov']);
501 }
502
503 if (empty($scene_haov)) {
504 unset($scene_info['haov']);
505 }
506
507 if (empty($scene_vertical_offset)) {
508 unset($scene_info['vOffset']);
509 }
510
511 if (isset($panoscenes["cvgscene"])) {
512 if ($panoscenes["cvgscene"] == "off") {
513 unset($scene_info['maxPitch']);
514 unset($scene_info['minPitch']);
515 }
516 }
517
518 if (empty($panoscenes["scene-maxpitch"])) {
519 unset($scene_info['maxPitch']);
520 }
521
522 if (empty($panoscenes["scene-minpitch"])) {
523 unset($scene_info['minPitch']);
524 }
525
526 if (isset($panoscenes["chgscene"])) {
527 if ($panoscenes["chgscene"] == "off") {
528 unset($scene_info['maxYaw']);
529 unset($scene_info['minYaw']);
530 }
531 }
532 if (empty($panoscenes["scene-maxyaw"])) {
533 unset($scene_info['maxYaw']);
534 }
535
536 if (empty($panoscenes["scene-minyaw"])) {
537 unset($scene_info['minYaw']);
538 }
539
540 $scene_array = array();
541 $scene_array = array(
542 $panoscenes["scene-id"] => $scene_info
543 );
544 $scene_data[$panoscenes["scene-id"]] = $scene_info;
545 }
546 }
547
548 $pano_id_array = array();
549 $pano_id_array = array("panoid" => $panoid);
550 $pano_response = array();
551 $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);
552
553 if (empty($autorotation)) {
554 unset($pano_response['autoRotate']);
555 unset($pano_response['autoRotateInactivityDelay']);
556 unset($pano_response['autoRotateStopDelay']);
557 }
558 if (empty($autorotationinactivedelay)) {
559 unset($pano_response['autoRotateInactivityDelay']);
560 }
561 if (empty($autorotationstopdelay)) {
562 unset($pano_response['autoRotateStopDelay']);
563 }
564
565 $response = array();
566 $response = array($pano_id_array, $pano_response);
567 if (!empty($response)) {
568 $response = json_encode($response);
569 }
570 $floor_list_pointer_position = isset($postdata['floor_plan_pointer_position']) ? $postdata['floor_plan_pointer_position'] : '';
571 $calltoaction = isset($postdata['calltoaction']) ? $postdata['calltoaction']: 'off';
572 $buttontext = isset($postdata['buttontext']) ? $postdata['buttontext']: 'Click Here';
573 $buttonurl = isset($postdata['buttonurl']) ? $postdata['buttonurl']: '';
574 $calltoactionbutton_css = isset($postdata['calltoactionbutton']) ? $postdata['calltoactionbutton']: '';
575 $floor_list_pointer_position_object= array();
576 if(is_array($floor_list_pointer_position)){
577 foreach ($floor_list_pointer_position as $item) {
578 $floor_list_pointer_position_object[] = (object)$item;
579 }
580 $floor_list_pointer_position = $floor_list_pointer_position_object;
581 }
582 ob_start();
583 ?>
584
585 <div class="iframe-wrapper">
586 <i class="fa fa-times" id="cross"></i>
587 <?php if (!apply_filters('is_wpvr_pro_active', false)) : // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound ?>
588 <div class="wpvr-pro-preview-watermark" id="wpvr-pro-preview-watermark" style="display:none;">
589 <span><?php esc_html_e('PRO PREVIEW', 'wpvr'); ?></span>
590 </div>
591
592 <!-- Pro Preview: Feature mockup overlays (Option B) -->
593 <div class="wpvr-pro-mockup wpvr-pro-mockup--gallery" id="wpvr-pro-mockup-gallery" style="display:none;">
594 <div class="wpvr-pro-mockup-gallery__bar">
595 <span class="wpvr-pro-mockup-gallery__toggle">
596 <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>
597 </span>
598 <div class="wpvr-pro-mockup-gallery__thumbs">
599 <div class="wpvr-pro-mockup-gallery__thumb"></div>
600 <div class="wpvr-pro-mockup-gallery__thumb"></div>
601 <div class="wpvr-pro-mockup-gallery__thumb"></div>
602 <div class="wpvr-pro-mockup-gallery__thumb"></div>
603 </div>
604 <span class="wpvr-pro-mockup-gallery__label"><?php esc_html_e('Scene Gallery', 'wpvr'); ?></span>
605 </div>
606 </div>
607
608 <div class="wpvr-pro-mockup wpvr-pro-mockup--navigation" id="wpvr-pro-mockup-navigation" style="display:none;">
609 <span class="wpvr-pro-mockup-navigation__icon">
610 <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>
611 </span>
612 <span class="wpvr-pro-mockup-navigation__list">
613 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 1', 'wpvr'); ?></span>
614 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 2', 'wpvr'); ?></span>
615 <span class="wpvr-pro-mockup-navigation__item"><?php esc_html_e('Scene 3', 'wpvr'); ?></span>
616 </span>
617 </div>
618
619 <div class="wpvr-pro-mockup wpvr-pro-mockup--audio" id="wpvr-pro-mockup-audio" style="display:none;">
620 <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>
621 <span><?php esc_html_e('Background Music', 'wpvr'); ?></span>
622 </div>
623
624 <div class="wpvr-pro-mockup wpvr-pro-mockup--gyro" id="wpvr-pro-mockup-gyro" style="display:none;">
625 <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>
626 <span><?php esc_html_e('Gyroscope — Active on mobile', 'wpvr'); ?></span>
627 </div>
628 <?php endif; ?>
629 <div id="custom-ifram" style="display: none;"></div>
630 <div id="<?php echo esc_attr( 'pano' . $id ); ?>" class="pano-wrap" style="direction:ltr; height: 100%">
631 <?php if ($is_floor_enable == 'on') { ?>
632 <div class="wpvr-floor-preview outfit">
633 <div class="wpvr-floor-preview-inner">
634 <img loading="lazy" src="<?php echo esc_url($floor_map_image); ?>" alt="">
635 <?php foreach ( $floor_list_pointer_position as $pointer_position ) {
636 echo sprintf(
637 '<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>',
638 esc_attr( $pointer_position->id ),
639 esc_attr( $pointer_position->data_top ),
640 esc_attr( $pointer_position->data_left ),
641 esc_attr( $pointer_position->style ),
642 esc_html( $pointer_position->text )
643 );
644 }
645 ?>
646 </div>
647 </div>
648 <button class="flooplan-toggle">
649 <i class="far fa-map"></i>
650 </button>
651
652 <?php } ?>
653 </div>
654
655 </div>
656
657 <div class="rex-add-coordinates" style="text-align: center;">
658 <ul>
659 <li>
660 <div id="panodata" style="text-align: center; font-weight: bold;">
661
662 </div>
663 </li>
664 <li class="rex-hide-coordinates add-pitch">
665 <span class="rex-tooltiptext"><?php esc_html_e('Add This Position Into Active Hotspot', 'wpvr'); ?></span>
666 <i class="fa fa-plus toppitch"></i>
667 </li>
668 </ul>
669
670 <div class="scene-gallery vrowl-carousel" style="direction:ltr;">
671
672 </div>
673
674 </div>
675
676 <?php
677 ob_end_flush();
678 /**
679 * Nasim
680 * include alert modal
681 */
682
683 $is_pro = apply_filters('is_wpvr_pro_active',false); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
684
685 $pro = (bool) $is_pro;
686 ?>
687
688 <script>
689 var response = <?php echo wp_json_encode( json_decode( $response, true ) ); ?>;
690 var scenes = response[1];
691 var is_pro = <?php echo wp_json_encode( $pro ); ?>;
692
693 if (scenes) {
694 jQuery.each(scenes.scenes, function(i) {
695 jQuery.each(scenes.scenes[i]['hotSpots'], function(key, val) {
696 if (val["clickHandlerArgs"]) {
697 const hasTextContent = val["clickHandlerArgs"].replace(/<[^>]*>/g, '').trim() !== '';
698 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(val["clickHandlerArgs"]);
699 const hasOtherContent = val["clickHandlerArgs"].replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
700
701 if (hasTextContent || hasMediaContent || hasOtherContent) {
702 val["clickHandlerFunc"] = function(div, args) { if (typeof wpvrhotspot === "function") { wpvrhotspot(div, args); } else if (typeof window.wpvrhotspot === "function") { window.wpvrhotspot(div, args); } };
703 }
704 }
705 if (val["createTooltipArgs"]) {
706 const hasTextContent = val["createTooltipArgs"].replace(/<[^>]*>/g, '').trim() !== '';
707 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(val["createTooltipArgs"]);
708 const hasOtherContent = val["createTooltipArgs"].replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
709
710 if (hasTextContent || hasMediaContent || hasOtherContent) {
711 val["createTooltipFunc"] = function(div, args) { if (typeof wpvrtooltip === "function") { wpvrtooltip(div, args); } else if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };
712 }
713 }
714 });
715 });
716 }
717 if (scenes) {
718 jQuery('.scene-gallery').empty();
719
720 jQuery.each(scenes.scenes, function(key, val) {
721 if (val.type == 'cubemap') {
722 var img_data = val.cubeMap[0];
723 } else {
724 var img_data = val.panorama;
725 }
726 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>');
727 });
728 }
729
730 if (response[1]['scenes'] != "") {
731 var panoshow = pannellum.viewer(response[0]["panoid"], scenes);
732 var autoLoad = <?php echo json_encode($autoload); ?>;
733 if (!autoLoad) {
734 jQuery('.pnlm-controls-container').hide();
735 }
736
737 panoshow.on('load', function(){
738 jQuery('.pnlm-controls-container').show();
739 });
740
741 if (scenes.autoRotate) {
742 panoshow.on('load', function() {
743 setTimeout(function() {
744 panoshow.startAutoRotate(scenes.autoRotate, 0);
745 }, 3000);
746 });
747 panoshow.on('scenechange', function() {
748 setTimeout(function() {
749 panoshow.startAutoRotate(scenes.autoRotate, 0);
750 }, 3000);
751 });
752 }
753
754 if (scenes) {
755 jQuery.each(scenes.scenes, function(key, val) {
756 document.getElementById('' + key + '_gallery').addEventListener('click', function(e) {
757 jQuery('.owl-item').removeClass('marked');
758 jQuery(this).closest('.owl-item').addClass('marked');
759 if (panoshow.getScene() !== key) {
760 panoshow.loadScene(key);
761 }
762 activateSceneTab(key);
763 });
764 });
765 }
766
767 }
768 function activateSceneTab(sceneId){
769 jQuery(".scene-nav ul li span").each(function() {
770 var sceneTab = jQuery(this);
771 var dataHrefValue = sceneTab.attr("data-href");
772 var scenePanel = jQuery(dataHrefValue);
773 var currentScene = scenePanel.find('input.sceneid').val();
774
775 if(sceneId == currentScene){
776 jQuery([sceneTab.parent()[0], scenePanel[0]])
777 .addClass('active')
778 .siblings('.active')
779 .removeClass('active');
780 jQuery('#wpvr_active_scenes').val(sceneTab.data('index'));
781 return false;
782 }
783 });
784 }
785
786 function wpvrSanitizeHtml(rawHtml) {
787 if (!rawHtml || typeof rawHtml !== 'string') return '';
788 var clean = rawHtml.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
789 try {
790 var parser = new DOMParser();
791 var doc = parser.parseFromString(clean, 'text/html');
792 var elements = doc.body.querySelectorAll('*');
793 for (var i = 0; i < elements.length; i++) {
794 var el = elements[i];
795 var tag = el.tagName.toLowerCase();
796 if (['script', 'object', 'embed', 'applet', 'link', 'meta', 'base'].indexOf(tag) !== -1) {
797 el.parentNode && el.parentNode.removeChild(el);
798 continue;
799 }
800 var attrs = el.attributes;
801 for (var a = attrs.length - 1; a >= 0; a--) {
802 var attrName = attrs[a].name.toLowerCase();
803 var attrVal = attrs[a].value;
804 if (attrName.indexOf('on') === 0) {
805 el.removeAttribute(attrs[a].name);
806 } else if (['href', 'src', 'action', 'formaction', 'xlink:href'].indexOf(attrName) !== -1) {
807 if (/^\s*(javascript|vbscript|data:text\/html):/i.test(attrVal)) {
808 el.removeAttribute(attrs[a].name);
809 }
810 }
811 }
812 }
813 return doc.body.innerHTML;
814 } catch (e) {
815 return clean.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '').replace(/\s*on\w+\s*=\s*[^\s>]+/gi, '');
816 }
817 }
818
819 function wpvrhotspot(hotSpotDiv, args) {
820 var argst = typeof args === 'string' ? args.replace(/\\/g, '') : '';
821 argst = wpvrSanitizeHtml(argst);
822 jQuery("#custom-ifram").html(argst);
823 jQuery("#custom-ifram").fadeToggle();
824 jQuery(".iframe-wrapper").toggleClass("show-modal");
825 jQuery('button.ff-btn.ff-btn-submit.ff-btn-md').prop('disabled', true);
826
827 //------add to cart button------
828 jQuery('.wpvr-product-container p.add_to_cart_inline a.button').wrap('<span class="wpvr-cart-wrap"></span>');
829 }
830
831 function wpvrtooltip(hotSpotDiv, args) {
832 hotSpotDiv.classList.add('custom-tooltip');
833 var span = document.createElement('p');
834 var cleanTooltip = typeof args === 'string' ? args.replace(/\\/g, "") : '';
835 span.innerHTML = wpvrSanitizeHtml(cleanTooltip);
836 hotSpotDiv.appendChild(span);
837 span.style.marginLeft = -(span.scrollWidth - hotSpotDiv.offsetWidth) / 2 + 'px';
838 span.style.marginTop = -span.scrollHeight - 12 + 'px';
839 const style = document.createElement('style');
840 style.textContent = `
841 .table, .table td, .table th {
842 border: 1px solid #dee2e6;
843 border-collapse: collapse;
844 padding: 8px;
845 }
846 `;
847 document.head.appendChild(style);
848 }
849
850 jQuery(document).ready(function($) {
851 jQuery("#cross").on("click", function(e) {
852 e.preventDefault();
853 jQuery("#custom-ifram").fadeOut();
854 jQuery(".iframe-wrapper").removeClass("show-modal");
855 jQuery('iframe').attr('src', $('iframe').attr('src'));
856 });
857 });
858
859
860
861
862
863 jQuery(document).ready(function($) {
864 $(document).on("click",".outfit img",function(e) {
865 // var sceneinfo = jQuery(".hotspotscene").html();
866 var dot_count = $(".floor-plan-pointer").length;
867 // var pano_scenes = scenes.scenes;
868 var pano_scenes = jQuery('.scene-setup').repeaterVal();
869 pano_scenes = pano_scenes['scene-list']
870
871 var top_offset = $(this).offset().top - $(window).scrollTop();
872 var left_offset = $(this).offset().left - $(window).scrollLeft();
873
874 var top_px = Math.round((e.clientY - top_offset - 12));
875 var left_px = Math.round((e.clientX - left_offset - 12));
876
877 var top_perc = top_px / $(this).height() * 100;
878 var left_perc = left_px / $(this).width() * 100;
879 var options = "";
880 for(var i in pano_scenes) {
881 var sceneId = pano_scenes[i]['scene-id']
882 if(sceneId != ''){
883 options += '<option value="'+sceneId+'">'+sceneId+'</option>';
884 }
885 }
886 var is_backgroud = $(".floor-plan-background-custom-color").val();
887 var background_color
888 if(is_backgroud != ''){
889 background_color = is_backgroud;
890 }else{
891 background_color = '#cca92c'
892 }
893
894 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>';
895
896 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>';
897
898 $(dot).hide().appendTo($(this).parent()).fadeIn(350);
899 $(li_content).hide().appendTo('.floor-plan-pointer-list > ul').fadeIn(350);
900
901 if(is_pro) {
902 $(".floor-plan-pointer").draggable({
903 containment: ".outfit",
904 stop: function(event, ui) {
905 var new_left_perc = parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%";
906 var new_top_perc = parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%";
907 var output = 'Top: ' + parseInt(new_top_perc) + '%, Left: ' + parseInt(new_left_perc) + '%';
908
909 $(this).css("left", parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
910 $(this).css("top", parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
911
912 $(this).attr('data-top', parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
913 $(this).attr('data-left', parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
914 }
915 });
916 }
917
918 });
919 if(is_pro) {
920 $(".floor-plan-pointer").draggable({
921 containment: ".outfit",
922 stop: function(event, ui) {
923 var new_left_perc = parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%";
924 var new_top_perc = parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%";
925 var output = 'Top: ' + parseInt(new_top_perc) + '%, Left: ' + parseInt(new_left_perc) + '%';
926
927 $(this).css("left", parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
928 $(this).css("top", parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
929
930 $(this).attr('data-top', parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
931 $(this).attr('data-left', parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
932 }
933 });
934 }
935 });
936
937
938 jQuery(document).on("click",".flooplan-toggle",function(e) {
939 e.preventDefault();
940 jQuery('.wpvr-floor-preview').slideToggle();
941 });
942
943
944 jQuery(document).on("click", ".plan-delete", function(e) {
945 e.preventDefault();
946
947 var $li = jQuery(this).closest("li");
948 var dataId = jQuery(this).attr("data-id");
949
950 // Remove corresponding pointer
951 jQuery('#pointer-' + dataId).remove();
952
953 // Add class to trigger CSS animation
954 $li.addClass("removing");
955
956 // Remove the element after animation ends
957 setTimeout(function() {
958 $li.remove();
959
960 // Re-index pointers
961 jQuery(".floor-plan-pointer").each(function(index) {
962 var number = index + 1;
963 jQuery(this).text(number);
964 jQuery(this).attr("id", "pointer-" + number);
965 });
966
967 // Re-index list items
968 jQuery(".floor-plan-pointer-list ul li").each(function(index) {
969 var number = index + 1;
970 jQuery(this).children("label").text('Pointer - ' + number);
971 jQuery(this).children("select").attr('name', "plan-" + number);
972 jQuery(this).children(".plan-delete").attr('data-id', number);
973 });
974
975 }, 300); // match CSS transition duration
976 });
977
978
979 </script>
980 <?php } ?>
981
982
983 <div class="wpvr-use-shortcode">
984 <?php
985 $post = get_post();
986 $id = $post->ID;
987 $slug = $post->post_name;
988 $postdata = get_post_meta($post->ID, 'panodata', true);
989 ?>
990 <div class="shortcode-wrapper">
991
992 <div class="single-shortcode classic">
993
994 <div class="field-wapper">
995 <!-- Start preview button -->
996 <button id="panolenspreview" class="panolenspreview wpvr_preview_button"><?php esc_html_e('Preview', 'wpvr'); ?></button>
997 <!-- <button id="panolenssave" class="panolenssave wpvr_preview_button">--><?php //echo __('Save', 'wpvr'); ?><!--</button>-->
998 <!-- End preview button -->
999 <div class="shortcode-field">
1000
1001 <p class="copycode" id="copy-shortcode">[wpvr id="<?php echo esc_html($id); ?>"]</p>
1002
1003 <span id="wpvr-copy-shortcode" class="wpvr-copy-shortcode">
1004 <img loading="lazy" src="<?php echo esc_url( WPVR_PLUGIN_DIR_URL . 'admin/icon/copy.png' ); ?>" alt="icon" />
1005 </span>
1006
1007 </div>
1008
1009 <span id="wpvr-copied-notice" class="wpvr-copied-notice"></span>
1010
1011 </div>
1012 </div>
1013
1014 </div>
1015 </div>
1016 <?php }
1017 }
1018