PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.2.0
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.2.0
9.2.0 9.1.4 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 All 224 releases
← All changes | legacy/wpvr.php +213 -3155 9.0.3 → 9.2.0 View file →
@@ -7,8 +7,9 @@
7 7 die;
8 8 }
9 9
10 10 require WPVR_PLUGIN_LEGACY_DIR_PATH . 'elementor/elementor.php';
11 +require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'breakdance/breakdance.php';
11 12 if ( file_exists( dirname( WPVR_PLUGIN_LEGACY_DIR_PATH ) . '/vendor/autoload.php' ) ) {
12 13 require_once dirname( WPVR_PLUGIN_LEGACY_DIR_PATH ) . '/vendor/autoload.php';
13 14 } elseif ( file_exists( WPVR_PLUGIN_LEGACY_DIR_PATH . 'vendor/autoload.php' ) ) {
14 15 require_once WPVR_PLUGIN_LEGACY_DIR_PATH . 'vendor/autoload.php';
@@ -375,9 +376,13 @@
375 376 * @return string
376 377 * @since 9.0.0
377 378 */
378 379 function wpvr_render_scene_info_row( $html, $postdata, $id ) {
379 - $pano_id = 'pano' . absint( $id );
380 + if ( preg_match( '/id=[\'"](pano' . absint( $id ) . '(?:_\d+)?)[\'"]/', $html, $m ) ) {
381 + $pano_id = $m[1];
382 + } else {
383 + $pano_id = 'pano' . absint( $id );
384 + }
380 385 $pano_id_json = wp_json_encode( $pano_id );
381 386 $by_label = wp_json_encode( __( 'By', 'wpvr' ) );
382 387 $tour_layout = is_array( $postdata['tourLayout'] ?? null )
383 388 ? ( $postdata['tourLayout']['layout'] ?? 'default' )
@@ -383,9 +388,9 @@
383 388 ? ( $postdata['tourLayout']['layout'] ?? 'default' )
384 389 : ( $postdata['tourLayout'] ?? 'default' );
385 390 $is_classic_layout = wp_json_encode( 'layout1' !== $tour_layout );
386 391
387 - $html .= '<style id="wpvr-scene-info-' . esc_attr( $id ) . '">
392 + $html .= '<style id="wpvr-scene-info-' . esc_attr( $pano_id ) . '">
388 393 #' . esc_attr( $pano_id ) . ' .pnlm-panorama-info.wpvr-scene-info-row {
389 394 display: flex !important;
390 395 align-items: center !important;
391 396 justify-content: center !important;
@@ -481,9 +486,9 @@
481 486 padding-left: 7px !important;
482 487 }
483 488 }
484 489 </style>
485 - <script id="wpvr-scene-info-script-' . esc_attr( $id ) . '">
490 + <script id="wpvr-scene-info-script-' . esc_attr( $pano_id ) . '">
486 491 (function () {
487 492 var pano = document.getElementById(' . $pano_id_json . ');
488 493 var byLabel = ' . $by_label . ';
489 494
@@ -496,9 +501,9 @@
496 501 return;
497 502 }
498 503
499 504 var firstNode = author.firstChild;
500 - if (firstNode && firstNode.nodeType === 3) {
505 + if (firstNode ? firstNode.nodeType === 3 : false) {
501 506 var prefix = byLabel + " ";
502 507 if (firstNode.nodeValue.indexOf(prefix) === 0) {
503 508 firstNode.nodeValue = firstNode.nodeValue.slice(prefix.length);
504 509 }
@@ -524,10 +529,10 @@
524 529 }
525 530
526 531 var title = info.querySelector(".pnlm-title-box");
527 532 var author = info.querySelector(".pnlm-author-box");
528 - var hasTitle = !!(title && title.textContent.trim());
529 - var hasAuthor = !!(author && author.textContent.trim());
533 + var hasTitle = Boolean(title ? title.textContent.trim() : false);
534 + var hasAuthor = Boolean(author ? author.textContent.trim() : false);
530 535
531 536 if (hasTitle) {
532 537 title.setAttribute("title", title.textContent.trim());
533 538 } else if (title) {
@@ -572,8 +577,50 @@
572 577 }
573 578
574 579 add_filter( 'wpvr_generate_tour_layout_html', 'wpvr_render_scene_info_row', 30, 3 );
575 580
581 +if ( ! function_exists( 'wpvr_text_overlay_hex_to_rgba' ) ) {
582 + /**
583 + * Convert HEX color and opacity percentage to RGBA CSS string.
584 + *
585 + * Backward-compatibility wrapper for RexTheme\WPVR\Frontend\TextOverlayRenderer::hex_to_rgba().
586 + *
587 + * @param string $hex Hex color code.
588 + * @param float|int $opacity_percent Opacity 0-100.
589 + * @return string
590 + */
591 + function wpvr_text_overlay_hex_to_rgba( $hex, $opacity_percent = 55 ) {
592 + if ( class_exists( 'RexTheme\WPVR\Frontend\TextOverlayRenderer' ) ) {
593 + return \RexTheme\WPVR\Frontend\TextOverlayRenderer::hex_to_rgba( $hex, $opacity_percent );
594 + }
595 + return 'rgba(40, 30, 25, 0.55)';
596 + }
597 +}
598 +
599 +if ( ! function_exists( 'wpvr_render_frontend_text_overlays' ) ) {
600 + /**
601 + * Render the text overlay layer(s) on the frontend for each scene in the tour.
602 + *
603 + * Backward-compatibility wrapper for RexTheme\WPVR\Frontend\TextOverlayRenderer::render().
604 + *
605 + * @param string $html Generated tour HTML.
606 + * @param array $postdata Saved tour settings.
607 + * @param int $id Tour post ID.
608 + *
609 + * @return string
610 + */
611 + function wpvr_render_frontend_text_overlays( $html, $postdata, $id ) {
612 + if ( class_exists( 'RexTheme\WPVR\Frontend\TextOverlayRenderer' ) ) {
613 + return \RexTheme\WPVR\Frontend\TextOverlayRenderer::render( $html, $postdata, $id );
614 + }
615 + return $html;
616 + }
617 +}
618 +
619 +if ( class_exists( 'RexTheme\WPVR\Frontend\TextOverlayRenderer' ) ) {
620 + \RexTheme\WPVR\Frontend\TextOverlayRenderer::init();
621 +}
622 +
576 623 if ( ! function_exists( 'wpvr_render_explainer_button' ) ) {
577 624 /**
578 625 * Render the WPVR explainer button independently.
579 626 *
@@ -637,9 +684,8 @@
637 684 array()
638 685 );
639 686 }
640 687
641 -
642 688 if (function_exists('register_block_type')) {
643 689 register_block_type('wpvr/wpvr-block', array(
644 690 'attributes' => array(
645 691 'id' => array(
@@ -673,11 +719,15 @@
673 719 'radius' => array(
674 720 'type' => 'string',
675 721 'default' => '0',
676 722 ),
723 + 'radius_unit' => array(
724 + 'type' => 'string',
725 + 'default' => 'px',
726 + ),
677 727 'border_width' => array(
678 728 'type' => 'string',
679 - 'default' => '0px',
729 + 'default' => '0',
680 730 ),
681 731 'border_style' => array(
682 732 'type' => 'string',
683 733 'default' => 'none',
@@ -683,19 +733,10 @@
683 733 'default' => 'none',
684 734 ),
685 735 'border_color' => array(
686 736 'type' => 'string',
687 - 'default' => 'none',
737 + 'default' => '',
688 738 ),
689 - 'radius_unit' => array(
690 - 'type' => 'string',
691 - 'default' => 'px',
692 - ),
693 - 'content' => array(
694 - 'type' => 'string',
695 - 'source' => 'html',
696 - 'default' => '<script> </script>'
697 - ),
698 739 ),
699 740 'editor_script' => 'wpvr-block',
700 741 'render_callback' => 'wpvr_block_render',
701 742 ));
@@ -705,3133 +746,86 @@
705 746 add_action('init', 'wpvr_block');
706 747
707 748 function wpvr_block_render($attributes)
708 749 {
709 - if ( function_exists( 'wpvr_enqueue_frontend_scripts' ) ) {
710 - wpvr_enqueue_frontend_scripts( 'scene' );
750 + $id = isset($attributes['id']) ? (int) $attributes['id'] : 0;
751 + if (!$id) {
752 + return '<div class="wpvr-no-tour-selected">' . esc_html__('Please select a tour from the block settings panel.', 'wpvr') . '</div>';
711 753 }
712 - if (isset($attributes['id'])) {
713 - $id = $attributes['id'];
714 - } else {
715 - $id = 0;
716 - }
717 754
718 - do_action('rex_wpvr_embadded_tour', $id);
719 -
720 - $memberpress_active = defined('MEPR_VERSION');
721 - $rcp_active = is_plugin_active( 'restrict-content-pro/restrict-content-pro.php' );
722 -
723 - if (($memberpress_active || $rcp_active ) && apply_filters('is_wpvr_pro_active', false)) {
724 -
725 - if (!is_user_logged_in()) {
726 - return esc_html__('You need to log in to access this content.', 'wpvr');
727 - }
728 -
729 - $user_id = get_current_user_id();
730 - $allowed_access = false;
731 -
732 - // Get saved membership levels from post meta
733 - $allowed_membership_levels = get_post_meta($id, '_wpvr_allowed_roles_levels', true);
734 - if ( isset($allowed_membership_levels) && 'none' !== $allowed_membership_levels ) {
735 - if (!is_array($allowed_membership_levels)) {
736 - $allowed_membership_levels = array($allowed_membership_levels);
737 - }
738 -
739 - // Check MemberPress Access
740 - if ($memberpress_active) {
741 - $user = new MeprUser($user_id);
742 - $active_memberships = $user->active_product_subscriptions();
743 - if (array_intersect($allowed_membership_levels, $active_memberships) ) {
744 - $allowed_access = true;
745 - }
746 - }
747 -
748 - // Check Restrict Content Pro Access
749 - if ($rcp_active) {
750 - $user_rcp_memberships = rcp_get_customer_memberships($user_id);
751 - foreach ($user_rcp_memberships as $membership) {
752 - $rcp_access_level = array(
753 - $membership->get_object_id()
754 - );
755 - if (array_intersect($allowed_membership_levels, $rcp_access_level) ) {
756 - $allowed_access = true;
757 - break;
758 - }
759 - }
760 - }
761 - } else {
762 - // If no membership restriction is set, allow access by default
763 - $allowed_access = true;
764 - }
765 -
766 - if (!$allowed_access) {
767 - return esc_html__('You do not have access to this content.', 'wpvr');
768 - }
769 - }
770 -
771 -
772 - if (isset($attributes['width'])) {
773 - $width = $attributes['width'];
774 - }
775 - if (isset($attributes['width_unit'])) {
776 - $width_unit = $attributes['width_unit'];
777 - }
778 - if (isset($attributes['height'])) {
779 - $height = $attributes['height'];
780 - }
781 - if (isset($attributes['height_unit'])) {
782 - $height_unit = $attributes['height_unit'];
783 - }
784 - if (isset($attributes['mobile_height'])) {
785 - $mobile_height = $attributes['mobile_height'];
786 - }
787 - if (isset($attributes['mobile_height_unit'])) {
788 - $mobile_height_unit = $attributes['mobile_height_unit'];
789 - }
790 - if (isset($attributes['radius']) && isset($attributes['radius_unit'])) {
791 - $radius = $attributes['radius'] . $attributes['radius_unit'];
792 - }
793 - $border_style = '';
794 - if (isset($attributes['border_width'], $attributes['border_style'], $attributes['border_color'])) {
795 - $border_style = $attributes['border_width'] . 'px ' . $attributes['border_style'] . ' ' . $attributes['border_color'];
796 - }
797 -
798 - if (isset($attributes['className'])) {
799 - $className = $attributes['className'];
755 + $width = isset($attributes['width']) ? $attributes['width'] : '600';
756 + if ('fullwidth' === $width) {
757 + $width_str = 'fullwidth';
800 758 } else {
801 - $className = '';
802 - }
803 - $get_post = get_post_status($id);
804 - if ($get_post !== 'publish') {
805 - return esc_html__('Oops! It seems like this post isn\'t published yet. Stay tuned for updates!', 'wpvr');
806 - }
807 - if (post_password_required($id)) {
808 - return get_the_password_form();
809 - }
810 - $postdata = get_post_meta($id, 'panodata', true);
811 - $postdata = is_array( $postdata ) ? wpvr_get_effective_panodata( $postdata ) : [];
812 - $panoid = 'pano' . $id;
813 - $panoid2 = 'pano2' . $id;
814 - if (!isset($postdata) || empty($postdata)) {
815 - return wp_kses(
816 - __('Oops! It seems that you have not selected any tour yet. Please select a tour from the dropdown of WPVR block.<br>', 'wpvr'),
817 - ['br' => []]
818 - );
819 - }
820 - if (isset($postdata['streetviewdata'])) {
821 - if (empty($width)) {
822 - $width = '600px';
823 - }
824 - if (empty($height)) {
825 - $height = '400px';
826 - }
827 - $streetviewurl = $postdata['streetviewurl'];
828 - $html = '';
829 - $html .= '<div class="vr-streetview ' . esc_attr( $className ) . '" style="text-align: center; max-width:100%; width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; height:' . esc_attr( $height ) . esc_attr( $height_unit ) . '; margin: 0 auto;">';
830 - $html .= '<iframe src="' . esc_url( $streetviewurl ) . '" frameborder="0" style="border:0; width:100px; height:100%;" allowfullscreen=""></iframe>';
831 - $html .= '</div>';
832 -
833 - return $html;
834 - }
835 - $is_pro = apply_filters('is_wpvr_pro_active', false);
836 -
837 - if (isset($postdata['vidid'])) {
838 - if (empty($width)) {
839 - $width = '600';
840 - }
841 - if (empty($height)) {
842 - $height = '400';
843 - }
844 - $videourl = $postdata['vidurl'];
845 -
846 - $videourl = $postdata['vidurl'];
847 - $autoplay = 'off';
848 - if (isset($postdata['autoplay'])) {
849 - $autoplay = $postdata['autoplay'];
850 - }
851 - $loop = 'off';
852 - if (isset($postdata['loop'])) {
853 - $loop = $postdata['loop'];
854 - }
855 -
856 - if (strpos($videourl, 'youtube') > 0 || strpos($videourl, 'youtu') > 0) {
857 - $explodeid = '';
858 - $explodeid = explode("=", $videourl);
859 - $foundid = '';
860 - $muted = '&mute=1';
861 -
862 - if ($autoplay == 'on') {
863 - $autoplay = '&autoplay=1';
864 - } else {
865 - $autoplay = '';
866 - }
867 -
868 - if ($loop == 'on') {
869 - $loop = '&loop=1';
870 - } else {
871 - $loop = '';
872 - }
873 -
874 - if (strpos($videourl, 'youtu') > 0) {
875 - $explodeid = explode("/", $videourl);
876 - $foundid = $explodeid[3] . '?' . $autoplay . $loop;
877 - $expdata = $explodeid[3];
878 - } else {
879 - $foundid = $explodeid[1] . '?' . $autoplay . $loop;
880 - $expdata = $explodeid[1];
881 - }
882 -
883 - $playlist = '&playlist=' . $expdata;
884 - $playlist = str_replace("?feature=shared", "", $playlist);
885 -
886 -
887 - $html = '';
888 - $html .= '<div class="' . esc_attr($className) . '" style="text-align:center; max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height:' . esc_attr($height) . esc_attr($height_unit) . '; border-radius: ' . esc_attr($radius) . '; margin: 0 auto;">';
889 -
890 - // Compatibility check script
891 - $html .= '<script>
892 - function wpvr_check_360_support() {
893 - var support = {
894 - supported: false,
895 - fullySupported: false,
896 - webgl: false,
897 - orientation: false,
898 - gyroscope: false,
899 - touch: false,
900 - browser: "unknown",
901 - isMobile: false,
902 - isIPhone: false,
903 - details: []
904 - };
905 -
906 - support.isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
907 - support.isIPhone = /iPhone/i.test(navigator.userAgent);
908 - if (support.isMobile) support.details.push("Mobile device detected");
909 - if (support.isIPhone) support.details.push("iPhone detected");
910 -
911 - var ua = navigator.userAgent;
912 - if (/^((?!chrome|android).)*safari/i.test(ua)) {
913 - support.browser = "safari";
914 - support.details.push("Safari browser detected");
915 - } else if (ua.indexOf("Chrome") > -1) {
916 - support.browser = "chrome";
917 - support.details.push("Chrome browser detected");
918 - } else if (ua.indexOf("Firefox") > -1) {
919 - support.browser = "firefox";
920 - support.details.push("Firefox browser detected");
921 - } else if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) {
922 - support.browser = "ie";
923 - support.details.push("Internet Explorer detected");
924 - } else if (ua.indexOf("Edge") > -1 || ua.indexOf("Edg") > -1) {
925 - support.browser = "edge";
926 - support.details.push("Edge browser detected");
927 - } else if (ua.indexOf("Opera") > -1 || ua.indexOf("OPR") > -1) {
928 - support.browser = "opera";
929 - support.details.push("Opera browser detected");
930 - }
931 -
932 - try {
933 - var canvas = document.createElement("canvas");
934 - support.webgl = !!(window.WebGLRenderingContext &&
935 - (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")));
936 - support.details.push(support.webgl ? "WebGL supported" : "WebGL not supported");
937 - } catch (e) {
938 - support.webgl = false;
939 - support.details.push("WebGL detection error: " + e.message);
940 - }
941 -
942 - support.orientation = !!(window.DeviceOrientationEvent);
943 - support.details.push(support.orientation ? "Device Orientation API supported" : "Device Orientation API not supported");
944 -
945 - support.gyroscope = !!window.Gyroscope;
946 - support.details.push(support.gyroscope ? "Gyroscope supported" : "Gyroscope not supported");
947 -
948 - support.touch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
949 - support.details.push(support.touch ? "Touch supported" : "Touch not supported");
950 -
951 - support.supported = support.webgl;
952 - support.fullySupported = support.webgl && ((support.isMobile && support.orientation) || !support.isMobile);
953 -
954 - if (support.browser === "safari" && support.isIPhone) {
955 - support.browserWarning = "iPhone has limited support for 360 videos in browser. The experience may not be optimal.";
956 - support.fullySupported = false;
957 - } else if (support.browser === "ie") {
958 - support.browserWarning = "Internet Explorer has limited support for 360 videos.";
959 - support.fullySupported = false;
960 - } else if (!support.supported) {
961 - support.browserWarning = "Your browser does not support 360° videos. Use Chrome or Firefox with WebGL.";
962 - }
963 -
964 - return support;
965 - }
966 - </script>';
967 -
968 - $random_id = 'video-container-' . rand(10000, 99999);
969 - $html .= '<div id="' . $random_id . '-container" style="position:relative; width:100%; height:100%;">';
970 -
971 - // Compatibility check screen (initially hidden for all, will show only for iPhone)
972 - $html .= '<div id="' . $random_id . '-compatibility-check" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:#f9f9f9; border-radius:' . esc_attr( $radius ) . ';">
973 - <div style="margin-bottom:20px; text-align:center;">
974 - <div class="wpvr-loading-spinner" style="border:5px solid #f3f3f3; border-top:5px solid #3498db; border-radius:50%; width:50px; height:50px; margin:0 auto 15px; animation:wpvr-spin 1s linear infinite;"></div>
975 - <p style="margin:0;">Checking browser compatibility...</p>
976 - </div>
977 - </div>';
978 -
979 - // Spinner animation
980 - $html .= '<style>@keyframes wpvr-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>';
981 -
982 - // Iframe (initial display set to block)
983 - $html .= '<div id="' . $random_id . '-frame" class="' . esc_attr($className) . '" style="display:block; max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height:' . esc_attr($height) . esc_attr($height_unit) . '; border-radius: ' . esc_attr($radius) . '; margin: 0 auto;">';
984 - $html .= '<iframe id="' . $random_id . '-iframe" src="https://www.youtube.com/embed/' . rawurlencode(sanitize_text_field($expdata)) . '?rel=0&modestbranding=1' . esc_attr($loop) . '&autohide=1' . esc_attr($muted) . '&showinfo=0&controls=1' . esc_attr($autoplay) . esc_attr($playlist) . '&enablejsapi=1" width="100%" height="100%" style="border-radius: ' . esc_attr($radius) . ';" frameborder="0" allowfullscreen allow="accelerometer; gyroscope; picture-in-picture"></iframe>';
985 - $html .= '</div>';
986 -
987 - // Permission request (mobile only)
988 - $html .= '<div id="' . $random_id . '-permission-request" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:rgba(0,0,0,0.7); color:white; text-align:center; border-radius:' . esc_attr( $radius ) . ';">';
989 - $html .= '<p style="font-size:16px; margin:0 20px 15px;">For the best 360° video experience on mobile</p>';
990 - $html .= '<button id="' . $random_id . '-permission-button" style="padding:10px 15px; background-color:#0085ba; color:#fff; border:none; border-radius:4px; cursor:pointer;">Allow motion and orientation access</button>';
991 - $html .= '</div>';
992 -
993 - // Browser warning
994 - $html .= '<div id="' . $random_id . '-browser-warning" style="position:absolute; top:0; left:0; width:100%; height:100%; display:none; flex-direction:column; justify-content:center; align-items:center; background-color:rgba(0,0,0,0.7); color:white; text-align:center; border-radius:' . esc_attr( $radius ) . ';">';
995 - $html .= '<p id="' . $random_id . '-warning-text" style="font-size:16px; margin:0 20px 5px;"></p>';
996 - $html .= '<p style="font-size:14px; margin:5px 20px 15px;">For the best experience, use Chrome or Firefox.</p>';
997 - $html .= '<button id="' . $random_id . '-browser-continue" style="padding:10px 15px; background-color:#0085ba; color:#fff; border:none; border-radius:4px; cursor:pointer;">Continue Anyway</button>';
998 - $html .= '</div>';
999 -
1000 - // Main script
1001 - $html .= '<script>
1002 - document.addEventListener("DOMContentLoaded", function() {
1003 - var supportInfo = wpvr_check_360_support();
1004 - var compatibilityCheck = document.getElementById("' . $random_id . '-compatibility-check");
1005 - var frameContainer = document.getElementById("' . $random_id . '-frame");
1006 - var warning = document.getElementById("' . $random_id . '-browser-warning");
1007 - var warningText = document.getElementById("' . $random_id . '-warning-text");
1008 - var continueBtn = document.getElementById("' . $random_id . '-browser-continue");
1009 -
1010 - // Only show compatibility check and warning for iPhone
1011 - if (supportInfo.isIPhone) {
1012 - // Hide the iframe initially for iPhone
1013 - frameContainer.style.display = "none";
1014 -
1015 - // Show compatibility check for iPhone
1016 - compatibilityCheck.style.display = "flex";
1017 -
1018 - // After delay, hide compatibility check and show warning
1019 - setTimeout(function() {
1020 - compatibilityCheck.style.display = "none";
1021 - warningText.textContent = supportInfo.browserWarning || "Your browser may not fully support 360° videos.";
1022 - warning.style.display = "flex";
1023 -
1024 - continueBtn.addEventListener("click", function() {
1025 - warning.style.display = "none";
1026 -
1027 - if (supportInfo.fullySupported && supportInfo.isMobile) {
1028 - document.getElementById("' . $random_id . '-permission-request").style.display = "flex";
1029 - document.getElementById("' . $random_id . '-permission-button").addEventListener("click", function() {
1030 - requestDevicePermissions();
1031 - });
1032 - } else {
1033 - showVideo();
1034 - }
1035 - });
1036 - }, 1000);
1037 - } else {
1038 - // For non-iPhone devices, directly initialize the player
1039 - initializeYouTubePlayer();
1040 - }
1041 -
1042 - function requestDevicePermissions() {
1043 - try {
1044 - if (typeof DeviceOrientationEvent !== "undefined" &&
1045 - typeof DeviceOrientationEvent.requestPermission === "function") {
1046 - DeviceOrientationEvent.requestPermission().then(function(response) {
1047 - if (response === "granted") {
1048 - if (typeof DeviceMotionEvent !== "undefined" &&
1049 - typeof DeviceMotionEvent.requestPermission === "function") {
1050 - DeviceMotionEvent.requestPermission().then(showVideo).catch(showVideo);
1051 - } else {
1052 - showVideo();
1053 - }
1054 - } else {
1055 - showVideo();
1056 - }
1057 - }).catch(showVideo);
1058 - } else {
1059 - showVideo();
1060 - }
1061 - } catch (e) {
1062 - showVideo();
1063 - }
1064 - }
1065 -
1066 - function showVideo() {
1067 - document.getElementById("' . $random_id . '-permission-request").style.display = "none";
1068 - frameContainer.style.display = "block";
1069 - initializeYouTubePlayer();
1070 - }
1071 -
1072 - function initializeYouTubePlayer() {
1073 - if (window.YT) {
1074 - initPlayer();
1075 - } else {
1076 - var tag = document.createElement("script");
1077 - tag.src = "https://www.youtube.com/iframe_api";
1078 - var firstScriptTag = document.getElementsByTagName("script")[0];
1079 - firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1080 - window.onYouTubeIframeAPIReady = initPlayer;
1081 - }
1082 -
1083 - function initPlayer() {
1084 - new YT.Player("' . $random_id . '-iframe", {
1085 - events: {
1086 - "onReady": function(event) {}
1087 - }
1088 - });
1089 - }
1090 - }
1091 - });
1092 - </script>';
1093 -
1094 - $html .= '</div>'; // Close container
1095 - $html .= '</div>'; // Close outer wrapper
759 + $width_unit = isset($attributes['width_unit']) ? $attributes['width_unit'] : 'px';
760 + if (preg_match('/(px|%|vw|vh)$/', (string) $width)) {
761 + $width_str = $width;
1096 762 } else {
1097 - $html = '';
1098 - $html .= '<div id="pano' . esc_attr($id) . '" class="pano-wrap ' . esc_attr($className) . '" style="max-width:100%; width:' . esc_attr($width) . esc_attr($width_unit) . '; height: ' . esc_attr($height) . esc_attr($height_unit) . '; border-radius:' . esc_attr($radius) . '; margin: 0 auto;">';
1099 - $html .= '<div style="width:100%; height:100%; border-radius: ' . esc_attr($radius) . ';">' . wp_kses(
1100 - $postdata['panoviddata'],
1101 - array(
1102 - 'video' => array(
1103 - 'id' => array(),
1104 - 'class' => array(),
1105 - 'src' => array(),
1106 - 'controls' => array(),
1107 - 'autoplay' => array(),
1108 - 'loop' => array(),
1109 - 'muted' => array(),
1110 - 'poster' => array(),
1111 - 'preload' => array(),
1112 - 'width' => array(),
1113 - 'height' => array(),
1114 - 'style' => array(),
1115 - 'playsinline' => array(),
1116 - 'crossorigin' => array(),
1117 - 'data-*' => true,
1118 - ),
1119 - 'source' => array(
1120 - 'src' => array(),
1121 - 'type' => array(),
1122 - ),
1123 - 'track' => array(
1124 - 'kind' => array(),
1125 - 'src' => array(),
1126 - 'srclang' => array(),
1127 - 'label' => array(),
1128 - 'default' => array(),
1129 - ),
1130 - 'div' => array(
1131 - 'id' => array(),
1132 - 'class' => array(),
1133 - 'style' => array(),
1134 - 'data-*' => true,
1135 - ),
1136 - 'span' => array(
1137 - 'id' => array(),
1138 - 'class' => array(),
1139 - 'style' => array(),
1140 - ),
1141 - 'button' => array(
1142 - 'id' => array(),
1143 - 'class' => array(),
1144 - 'style' => array(),
1145 - 'type' => array(),
1146 - 'title' => array(),
1147 - ),
1148 - )
1149 - ) . '</div>';
1150 -
1151 - $html .= '
1152 - <style>
1153 - .video-js {
1154 - border-radius:' . esc_attr($radius) . ';
1155 - }
1156 - .video-js canvas{
1157 - border-radius:' . esc_attr($radius) . ';
1158 - }
1159 - #pano' . esc_attr($id) . ' .vjs-poster {
1160 - border-radius: ' . esc_attr($radius) . ';
1161 - }
1162 - </style>
1163 -
1164 - ';
1165 -
1166 - // $html .= '<script>';
1167 - // $html .= 'videojs(' . $postdata['vidid'] . ', {';
1168 - // $html .= 'plugins: {';
1169 - // $html .= 'pannellum: {}';
1170 - // $html .= '}';
1171 - // $html .= '});';
1172 - // $html .= '</script>';
1173 - $html .= '</div>';
1174 -
1175 - //video js vr setup //
1176 - $html .= '<script>';
1177 - $html .= '
1178 - (function (window, videojs) {
1179 - var player = window.player = videojs("' . $postdata['vidid'] . '");
1180 - player.mediainfo = player.mediainfo || {};
1181 - player.mediainfo.projection = "equirectangular";
1182 -
1183 - // AUTO is the default and looks at mediainfo
1184 - var vr = window.vr = player.vr({ projection: "AUTO", debug: true, forceCardboard: false, antialias: false });
1185 - }(window, window.videojs));
1186 -
1187 - ';
1188 - $html .= '</script>';
1189 - //video js vr end //
763 + $width_str = $width . $width_unit;
1190 764 }
1191 - return $html;
1192 765 }
1193 766
1194 - $control = false;
1195 - if (isset($postdata['showControls'])) {
1196 - $control = $postdata['showControls'];
767 + $height = isset($attributes['height']) ? $attributes['height'] : '400';
768 + $height_unit = isset($attributes['height_unit']) ? $attributes['height_unit'] : 'px';
769 + if (!preg_match('/(px|%|vw|vh)$/', (string) $height)) {
770 + $height .= $height_unit;
1197 771 }
1198 772
1199 - if ($control) {
1200 - if (isset($postdata['customcontrol'])) {
1201 - $custom_control = wpvr_parse_custom_control($postdata['customcontrol']);
1202 - $custom_control = wp_parse_args($custom_control, array(
1203 - 'panupSwitch' => 'off',
1204 - 'panDownSwitch' => 'off',
1205 - 'panLeftSwitch' => 'off',
1206 - 'panRightSwitch' => 'off',
1207 - 'panZoomInSwitch' => 'off',
1208 - 'panZoomOutSwitch' => 'off',
1209 - 'panFullscreenSwitch' => 'off',
1210 - 'gyroscopeSwitch' => 'off',
1211 - 'backToHomeSwitch' => 'off',
1212 - 'explainerSwitch' => 'off',
1213 - ));
1214 - $gyro_enabled = isset($postdata['gyro']) && in_array($postdata['gyro'], array(true, 1, '1', 'on'), true);
1215 - $custom_control['gyroSwitch'] = $gyro_enabled ? 'on' : 'off';
1216 - $gyro_button_enabled = wpvr_isMobileDevice() && $custom_control['gyroSwitch'] == "on" && $custom_control['gyroscopeSwitch'] == "on";
1217 - if ($custom_control['panupSwitch'] == "on" || $custom_control['panDownSwitch'] == "on" || $custom_control['panLeftSwitch'] == "on" || $custom_control['panRightSwitch'] == "on" || $custom_control['panZoomInSwitch'] == "on" || $custom_control['panZoomOutSwitch'] == "on" || $custom_control['panFullscreenSwitch'] == "on" || $gyro_button_enabled || $custom_control['backToHomeSwitch'] == "on") {
1218 - $control = false;
1219 - }
1220 - }
773 + $mobile_height = isset($attributes['mobile_height']) ? $attributes['mobile_height'] : '300';
774 + $mobile_height_unit = isset($attributes['mobile_height_unit']) ? $attributes['mobile_height_unit'] : 'px';
775 + if (!preg_match('/(px|%|vw|vh)$/', (string) $mobile_height)) {
776 + $mobile_height .= $mobile_height_unit;
1221 777 }
1222 778
1223 - $floor_plan_enable = 'off';
1224 - $floor_plan_image = '';
1225 - if (isset($postdata['floor_plan_tour_enabler']) && $postdata['floor_plan_tour_enabler'] == 'on') {
1226 - $floor_plan_enable = $postdata['floor_plan_tour_enabler'];
1227 - if (isset($postdata['floor_plan_attachment_url']) && !empty($postdata['floor_plan_attachment_url'])) {
1228 - $floor_plan_image = $postdata['floor_plan_attachment_url'];
1229 - }
779 + $radius = isset($attributes['radius']) ? $attributes['radius'] : '0';
780 + $radius_unit = isset($attributes['radius_unit']) ? $attributes['radius_unit'] : 'px';
781 + if (!preg_match('/(px|%|vw|vh)$/', (string) $radius)) {
782 + $radius .= $radius_unit;
1230 783 }
1231 784
1232 - $vrgallery = false;
1233 - if (isset($postdata['vrgallery'])) {
1234 - $vrgallery = $postdata['vrgallery'];
1235 - }
785 + $shortcode = sprintf(
786 + '[wpvr id="%d" width="%s" height="%s" mobile_height="%s" radius="%s"]',
787 + $id,
788 + esc_attr($width_str),
789 + esc_attr($height),
790 + esc_attr($mobile_height),
791 + esc_attr($radius)
792 + );
1236 793
1237 - $vrgallery_title = false;
1238 - if (isset($postdata['vrgallery_title'])) {
1239 - $vrgallery_title = $postdata['vrgallery_title'];
1240 - }
794 + $output = do_shortcode($shortcode);
1241 795
1242 - $vrgallery_display = false;
1243 - if (isset($postdata['vrgallery_display'])) {
1244 - $vrgallery_display = $postdata['vrgallery_display'];
796 + // Extract any <script> tags so they are not corrupted by wptexturize (which runs at priority 10 on the_content, after do_blocks at priority 9).
797 + $scripts = '';
798 + if (preg_match_all('/<script\b[^>]*>[\s\S]*?<\/script>/i', $output, $matches)) {
799 + $scripts = implode("\n", $matches[0]);
800 + $output = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $output);
1245 801 }
1246 - $vrgallery_icon_size = false;
1247 - if (isset($postdata['vrgallery_icon_size'])) {
1248 - $vrgallery_icon_size = $postdata['vrgallery_icon_size'];
1249 - }
1250 802
1251 - $gyro = false;
1252 - $gyro_orientation = false;
1253 - if (isset($postdata['gyro'])) {
1254 - $gyro = in_array($postdata['gyro'], array(true, 1, '1', 'on'), true);
1255 - if ($gyro && isset($postdata['deviceorientationcontrol'])) {
1256 - $gyro_orientation = in_array($postdata['deviceorientationcontrol'], array(true, 1, '1', 'on'), true);
1257 - }
1258 - }
1259 -
1260 - $compass = false;
1261 - $audio_right = "5px";
1262 - if (isset($postdata['compass'])) {
1263 - $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
1264 - if ($compass) {
1265 - $audio_right = "60px";
1266 - }
1267 - }
1268 - $floor_map_right = "25px";
1269 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
1270 - $floor_map_right = "85px";
1271 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
1272 - $floor_map_right = "55px";
1273 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
1274 - $floor_map_right = "25px";
1275 - }
1276 -
1277 - //===explainer handle===//
1278 -
1279 - //===explainer handle===//
1280 - $explainer_right = "10px";
1281 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1282 - $explainer_right = "130px";
1283 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on' && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1284 - $explainer_right = "100px";
1285 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1286 - $explainer_right = "55px";
1287 - } elseif ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
1288 - $explainer_right = "80px";
1289 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
1290 - $explainer_right = "55px";
1291 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
1292 - $explainer_right = "30px";
1293 - } elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image)) {
1294 - $explainer_right = "70px";
1295 - }
1296 - $enable_cardboard = '';
1297 - $is_cardboard = get_option('wpvr_cardboard_disable');
1298 - if (wpvr_isMobileDevice() && $is_cardboard == 'true') {
1299 - $enable_cardboard = 'enable-cardboard';
1300 - $audio_right = "73px";
1301 - if (isset($postdata['compass'])) {
1302 - $compass = $postdata['compass'] == 'on' || $postdata['compass'] != null ? true : false;
1303 - if ($compass) {
1304 - $audio_right = "130px";
1305 - }
1306 - }
1307 -
1308 - $floor_map_right = "60px";
1309 - if ((isset($postdata['compass']) && $postdata['compass'] == 'on') && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
1310 - $floor_map_right = "150px";
1311 - } elseif (isset($postdata['compass']) && $postdata['compass'] == 'on') {
1312 - $floor_map_right = "120px";
1313 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
1314 - $floor_map_right = "90px";
1315 - }
1316 -
1317 - //===explainer handle===//
1318 -
1319 - $explainer_right = "65px";
1320 -
1321 - if ((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on')) {
1322 - $explainer_right = "150px";
1323 - } elseif ((isset($postdata['compass']) && $postdata['compass'] == true) && (isset($postdata['bg_music']) && $postdata['bg_music'] == 'on') && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1324 - $explainer_right = "180px";
1325 - } elseif (isset($postdata['compass']) && $postdata['compass'] == true && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1326 - $explainer_right = "150px";
1327 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on" && ($floor_plan_enable == 'on' && !empty($floor_plan_image))) {
1328 - $explainer_right = "120px";
1329 - } elseif (isset($postdata['compass']) && $postdata['compass'] == true) {
1330 - $explainer_right = "130px";
1331 - } elseif (isset($postdata['bg_music']) && $postdata['bg_music'] == "on") {
1332 - $explainer_right = "90px";
1333 - } elseif ($floor_plan_enable == 'on' && !empty($floor_plan_image)) {
1334 - $explainer_right = "90px";
1335 - }
1336 - }
1337 -
1338 - //===explainer handle===//
1339 -
1340 - $mouseZoom = true;
1341 - if (isset($postdata['mouseZoom'])) {
1342 - if ($postdata['mouseZoom'] == "off") {
1343 - $mouseZoom = false;
803 + if (!empty($scripts)) {
804 + if (wp_doing_ajax() || (defined('REST_REQUEST') && REST_REQUEST)) {
805 + $output .= "\n" . $scripts;
1344 806 } else {
1345 - $mouseZoom = true;
807 + add_action('wp_footer', function() use ($scripts) {
808 + echo $scripts; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
809 + }, 20);
1346 810 }
1347 811 }
1348 812
1349 - $draggable = true;
1350 - if (isset($postdata['draggable'])) {
1351 - $draggable = ! in_array( $postdata['draggable'], array( 'off', 'false', false ), true );
813 + $border_css = '';
814 + if (!empty($attributes['border_width']) && !empty($attributes['border_style']) && 'none' !== $attributes['border_style']) {
815 + $border_width = rtrim((string) $attributes['border_width'], 'px') . 'px';
816 + $border_color = !empty($attributes['border_color']) ? $attributes['border_color'] : 'transparent';
817 + $border_css = 'border: ' . esc_attr($border_width . ' ' . $attributes['border_style'] . ' ' . $border_color) . ';';
1352 818 }
1353 - $diskeyboard = false;
1354 - if (isset($postdata['diskeyboard'])) {
1355 - $diskeyboard = ! in_array( $postdata['diskeyboard'], array( 'off', 'false', false ), true );
1356 - }
1357 819
1358 - $keyboardzoom = true;
1359 - if (isset($postdata['keyboardzoom'])) {
1360 - $keyboardzoom = ! in_array( $postdata['keyboardzoom'], array( 'off', 'false', false ), true );
1361 - }
820 + $class_name = !empty($attributes['className']) ? ' ' . esc_attr($attributes['className']) : '';
1362 821
1363 - $autoload = false;
1364 -
1365 - if (isset($postdata['autoLoad'])) {
1366 - $autoload = in_array( $postdata['autoLoad'], array( true, 1, '1', 'on', 'true' ), true );
822 + if ('' !== $border_css || '' !== $class_name) {
823 + $wrapper_style = $border_css ? ' style="' . $border_css . ' display: inline-block; width: 100%; max-width: ' . esc_attr('fullwidth' === $width_str ? '100%' : $width_str) . ';"' : '';
824 + return '<div class="wpvr-block-wrapper' . $class_name . '"' . $wrapper_style . '>' . $output . '</div>';
1367 825 }
1368 826
1369 - $default_scene = '';
1370 - if (isset($postdata['defaultscene'])) {
1371 - $default_scene = $postdata['defaultscene'];
1372 - }
1373 -
1374 - $preview = '';
1375 - if (isset($postdata['preview'])) {
1376 - $preview = $postdata['preview'];
1377 - }
1378 -
1379 - $autorotation = '';
1380 - if (isset($postdata["autoRotate"])) {
1381 - $autorotation = $postdata["autoRotate"];
1382 - }
1383 - $autorotationinactivedelay = '';
1384 - if (isset($postdata["autoRotateInactivityDelay"])) {
1385 - $autorotationinactivedelay = $postdata["autoRotateInactivityDelay"];
1386 - }
1387 - $autorotationstopdelay = '';
1388 - if (isset($postdata["autoRotateStopDelay"])) {
1389 - $autorotationstopdelay = $postdata["autoRotateStopDelay"];
1390 - }
1391 -
1392 - $scene_fade_duration = '';
1393 - if (isset($postdata['scenefadeduration'])) {
1394 - $scene_fade_duration = $postdata['scenefadeduration'];
1395 - }
1396 -
1397 - $panodata = array();
1398 - if (isset($postdata['panodata'])) {
1399 - $panodata = $postdata['panodata'];
1400 - }
1401 -
1402 - $show_scene_info = ( $postdata['scene-info-enabled'] ?? 'on' ) !== 'off';
1403 - $tour_layout = is_array( $postdata['tourLayout'] ?? null )
1404 - ? ( $postdata['tourLayout']['layout'] ?? 'default' )
1405 - : ( $postdata['tourLayout'] ?? 'default' );
1406 - $is_classic_layout = 'layout1' !== $tour_layout;
1407 -
1408 - $default_zoom_global = 100;
1409 - if (isset($postdata['hfov']) && $postdata['hfov'] != '') {
1410 - $default_zoom_global = $postdata['hfov'];
1411 - }
1412 -
1413 - $min_zoom_global = 50;
1414 - if (isset($postdata['minHfov']) && $postdata['minHfov'] != '') {
1415 - $min_zoom_global = $postdata['minHfov'];
1416 - }
1417 -
1418 - $max_zoom_global = 120;
1419 - if (isset($postdata['maxHfov']) && $postdata['maxHfov'] != '') {
1420 - $max_zoom_global = $postdata['maxHfov'];
1421 - }
1422 -
1423 - $hotspoticoncolor = '#00b4ff';
1424 - $hotspotblink = 'on';
1425 - $default_data = array();
1426 - $default_data = array('firstScene' => $default_scene, 'sceneFadeDuration' => $scene_fade_duration, 'hfov' => $default_zoom_global, 'maxHfov' => $max_zoom_global, 'minHfov' => $min_zoom_global);
1427 - $scene_data = array();
1428 - if (is_array($panodata) && isset($panodata['scene-list'])) {
1429 - if (!empty($panodata['scene-list'])) {
1430 - foreach ($panodata['scene-list'] as $panoscenes) {
1431 - $scene_ititle = '';
1432 - if (isset($panoscenes["scene-ititle"])) {
1433 - $scene_ititle = esc_html($panoscenes["scene-ititle"]);
1434 - }
1435 -
1436 - $scene_author = '';
1437 - if (isset($panoscenes["scene-author"])) {
1438 - $scene_author = esc_html($panoscenes["scene-author"]);
1439 - }
1440 -
1441 - $scene_author_url = '';
1442 - if (isset($panoscenes["scene-author-url"])) {
1443 - $scene_author_url = sanitize_text_field($panoscenes["scene-author-url"]);
1444 - }
1445 -
1446 - $scene_vaov = 180;
1447 - if (isset($panoscenes["scene-vaov"])) {
1448 - $scene_vaov = (float)$panoscenes["scene-vaov"];
1449 - }
1450 -
1451 - $scene_haov = 360;
1452 - if (isset($panoscenes["scene-haov"])) {
1453 - $scene_haov = (float)$panoscenes["scene-haov"];
1454 - }
1455 -
1456 - $scene_vertical_offset = 0;
1457 - if (isset($panoscenes["scene-vertical-offset"])) {
1458 - $scene_vertical_offset = (float)$panoscenes["scene-vertical-offset"];
1459 - }
1460 -
1461 - $default_scene_pitch = null;
1462 - if (isset($panoscenes["scene-pitch"])) {
1463 - $default_scene_pitch = (float)$panoscenes["scene-pitch"];
1464 - }
1465 -
1466 - $default_scene_yaw = null;
1467 - if (isset($panoscenes["scene-yaw"])) {
1468 - $default_scene_yaw = (float)$panoscenes["scene-yaw"];
1469 - }
1470 -
1471 - $scene_max_pitch = '';
1472 - if (isset($panoscenes["scene-maxpitch"])) {
1473 - $scene_max_pitch = (float)$panoscenes["scene-maxpitch"];
1474 - }
1475 -
1476 -
1477 - $scene_min_pitch = '';
1478 - if (isset($panoscenes["scene-minpitch"])) {
1479 - $scene_min_pitch = (float)$panoscenes["scene-minpitch"];
1480 - }
1481 -
1482 -
1483 - $scene_max_yaw = '';
1484 - if (isset($panoscenes["scene-maxyaw"])) {
1485 - $scene_max_yaw = (float)$panoscenes["scene-maxyaw"];
1486 - }
1487 -
1488 -
1489 - $scene_min_yaw = '';
1490 - if (isset($panoscenes["scene-minyaw"])) {
1491 - $scene_min_yaw = (float)$panoscenes["scene-minyaw"];
1492 - }
1493 -
1494 - $default_zoom = 100;
1495 - if (isset($panoscenes["scene-zoom"]) && $panoscenes["scene-zoom"] != '') {
1496 - $default_zoom = (int)$panoscenes["scene-zoom"];
1497 - } else {
1498 - if ($default_zoom_global != '') {
1499 - $default_zoom = (int)$default_zoom_global;
1500 - }
1501 - }
1502 -
1503 -
1504 - $max_zoom = 120;
1505 - if (isset($panoscenes["scene-maxzoom"]) && $panoscenes["scene-maxzoom"] != '') {
1506 - $max_zoom = (int)$panoscenes["scene-maxzoom"];
1507 - } else {
1508 - if ($max_zoom_global != '') {
1509 - $max_zoom = (int)$max_zoom_global;
1510 - }
1511 - }
1512 -
1513 - $min_zoom = 120;
1514 - if (isset($panoscenes["scene-minzoom"]) && $panoscenes["scene-minzoom"] != '') {
1515 - $min_zoom = (int)$panoscenes["scene-minzoom"];
1516 - } else {
1517 - if ($min_zoom_global != '') {
1518 - $min_zoom = (int)$min_zoom_global;
1519 - }
1520 - }
1521 -
1522 - $hotspot_datas = array();
1523 - if (isset($panoscenes['hotspot-list'])) {
1524 - $hotspot_datas = $panoscenes['hotspot-list'];
1525 - }
1526 -
1527 - $hotspots = array();
1528 -
1529 - foreach ($hotspot_datas as $hotspot_data) {
1530 - $status = get_option('wpvr_edd_license_status');
1531 - if ($status !== false && $status == 'valid') {
1532 -
1533 - if (isset($hotspot_data["hotspot-customclass-pro"]) && $hotspot_data["hotspot-customclass-pro"] != 'none') {
1534 - $hotspot_data['hotspot-customclass'] = $hotspot_data["hotspot-customclass-pro"] . ' custom-' . $id . '-' . $panoscenes['scene-id'] . '-' . $hotspot_data['hotspot-title'];
1535 - }
1536 - if (isset($hotspot_data['hotspot-blink'])) {
1537 - $hotspotblink = $hotspot_data['hotspot-blink'];
1538 - }
1539 - }
1540 - $hotspot_scene_pitch = '';
1541 - if (isset($hotspot_data["hotspot-scene-pitch"])) {
1542 - $hotspot_scene_pitch = $hotspot_data["hotspot-scene-pitch"];
1543 - }
1544 - $hotspot_scene_yaw = '';
1545 - if (isset($hotspot_data["hotspot-scene-yaw"])) {
1546 - $hotspot_scene_yaw = $hotspot_data["hotspot-scene-yaw"];
1547 - }
1548 -
1549 - $hotspot_type = $hotspot_data["hotspot-type"] !== 'scene' ? 'info' : $hotspot_data["hotspot-type"];
1550 - $hotspot_content = '';
1551 -
1552 - ob_start();
1553 - do_action('wpvr_hotspot_content', $hotspot_data);
1554 - $hotspot_content = ob_get_clean();
1555 -
1556 - if (!$hotspot_content) {
1557 - $hotspot_content = $hotspot_data["hotspot-content"];
1558 - }
1559 -
1560 - if (isset($hotspot_data["wpvr_url_open"][0])) {
1561 - $wpvr_url_open = $hotspot_data["wpvr_url_open"][0];
1562 - } else {
1563 - $wpvr_url_open = "off";
1564 - }
1565 - $on_hover_content = preg_replace_callback(
1566 - '/<p>\s*(<img[^>]*>)\s*<br>\s*<\/p>/i',
1567 - function ($matches) {
1568 - return $matches[1];
1569 - },
1570 - $hotspot_data['hotspot-hover'] ?? ''
1571 - );
1572 -
1573 - $is_fluent_form = isset($hotspot_data["hotspot-type"]) && 'fluent_form' === $hotspot_data["hotspot-type"];
1574 - $on_hover_content = sanitize_content_preserve_styles($on_hover_content ?? '', false);
1575 - $on_click_content = preg_replace_callback('/<img[^>]*>/', "replace_callback", $hotspot_content ?? '');
1576 - $on_click_content = sanitize_content_preserve_styles($on_click_content ?? '', $is_fluent_form);
1577 -
1578 -
1579 - // Shape is independent of the optional custom icon in the
1580 - // new editor, so it must always be included in the public
1581 - // hotspot configuration.
1582 - $hotspot_shape = isset( $hotspot_data['hotspot-shape'] )
1583 - && in_array( $hotspot_data['hotspot-shape'], [ 'round', 'square', 'hexagon' ], true )
1584 - ? $hotspot_data['hotspot-shape']
1585 - : 'round';
1586 -
1587 - $hotspot_data_for_on_click=[];
1588 - if( ('info' === $hotspot_type || 'fluent_form' === $hotspot_data["hotspot-type"] ) && !empty($on_click_content)){
1589 - $hotspot_data_for_on_click = [
1590 - 'on_click_content' => $on_click_content,
1591 - 'tour_id' => $id,
1592 - 'scene_id' => $panoscenes['scene-id'],
1593 - 'hotspot_id' => sanitize_html_class($hotspot_data['hotspot-title']),
1594 - ];
1595 - } elseif('info' === $hotspot_type && !empty($hotspot_data["hotspot-url"])){
1596 - $hotspot_data_for_on_click = [
1597 - 'on_click_content' => '',
1598 - 'tour_id' => $id,
1599 - 'scene_id' => $panoscenes['scene-id'],
1600 - 'hotspot_id' => sanitize_html_class($hotspot_data['hotspot-title']),
1601 - ];
1602 - }
1603 -
1604 - $hotspot_info = array(
1605 - 'text' => esc_html(sanitize_text_field($hotspot_data['hotspot-title'])),
1606 - 'pitch' => $hotspot_data['hotspot-pitch'],
1607 - 'yaw' => $hotspot_data['hotspot-yaw'],
1608 - 'type' => $hotspot_type,
1609 - 'cssClass' => $hotspot_data['hotspot-customclass'],
1610 - 'URL' => $hotspot_data['hotspot-url'],
1611 - "wpvr_url_open" => $wpvr_url_open,
1612 - "clickHandlerArgs" => $hotspot_data_for_on_click,
1613 - 'createTooltipArgs' => !empty(trim($on_hover_content)) ? trim($on_hover_content) : '',
1614 - "sceneId" => $hotspot_data["hotspot-scene"],
1615 - "targetPitch" => (float)$hotspot_scene_pitch,
1616 - "targetYaw" => (float)$hotspot_scene_yaw,
1617 - 'hotspot_type' => $hotspot_data['hotspot-type'],
1618 - 'hotspot_shape' => $hotspot_shape,
1619 - );
1620 -
1621 - $hotspot_info['URL'] = ($hotspot_data['hotspot-type'] === 'fluent_form' || $hotspot_data['hotspot-type'] === 'wc_product') ? '' : $hotspot_info['URL'];
1622 -
1623 - if ($hotspot_data["hotspot-customclass"] == 'none' || $hotspot_data["hotspot-customclass"] == '') {
1624 - unset($hotspot_info["cssClass"]);
1625 - }
1626 - if (empty($hotspot_data["hotspot-scene"])) {
1627 - unset($hotspot_info['targetPitch']);
1628 - unset($hotspot_info['targetYaw']);
1629 - }
1630 - array_push($hotspots, $hotspot_info);
1631 - }
1632 -
1633 - $device_scene = $panoscenes['scene-attachment-url'];
1634 - $mobile_media_resize = get_option('mobile_media_resize');
1635 - $file_accessible = ini_get('allow_url_fopen');
1636 - if ($mobile_media_resize == "true" && $device_scene) {
1637 - if ($file_accessible == "1") {
1638 - $image_info = getimagesize($device_scene);
1639 - if ($image_info && $image_info[0] > 4096) {
1640 - $src_to_id_for_mobile = '';
1641 - $src_to_id_for_desktop = '';
1642 - if (wpvr_isMobileDevice()) {
1643 - $src_to_id_for_mobile = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1644 - if ($src_to_id_for_mobile) {
1645 - $mobile_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'wpvr_mobile');
1646 - if ($mobile_scene[3]) {
1647 - $device_scene = $mobile_scene[0];
1648 - }
1649 - }
1650 - } else {
1651 - $src_to_id_for_desktop = attachment_url_to_postid($panoscenes['scene-attachment-url']);
1652 - if ($src_to_id_for_desktop) {
1653 - $desktop_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'full');
1654 - if ($desktop_scene && $desktop_scene[0]) {
1655 - $device_scene = $desktop_scene[0];
1656 - }
1657 - }
1658 - }
1659 - }
1660 - }
1661 - }
1662 -
1663 - $scene_info = array();
1664 -
1665 - if ($panoscenes["scene-type"] == 'cubemap') {
1666 - $pano_type = 'cubemap';
1667 - $pano_attachment = array(
1668 - $panoscenes["scene-attachment-url-face0"],
1669 - $panoscenes["scene-attachment-url-face1"],
1670 - $panoscenes["scene-attachment-url-face2"],
1671 - $panoscenes["scene-attachment-url-face3"],
1672 - $panoscenes["scene-attachment-url-face4"],
1673 - $panoscenes["scene-attachment-url-face5"]
1674 - );
1675 -
1676 - $scene_info = array('type' => $panoscenes['scene-type'], 'cubeMap' => $pano_attachment, "pitch" => $default_scene_pitch, "maxPitch" => $scene_max_pitch, "minPitch" => $scene_min_pitch, "maxYaw" => $scene_max_yaw, "minYaw" => $scene_min_yaw, "yaw" => $default_scene_yaw, "hfov" => $default_zoom, "maxHfov" => $max_zoom, "minHfov" => $min_zoom, "title" => $scene_ititle, "author" => $scene_author, "authorURL" => $scene_author_url, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, 'hotSpots' => $hotspots);
1677 - } else {
1678 - $scene_info = array('type' => $panoscenes['scene-type'], 'panorama' => $device_scene, "pitch" => $default_scene_pitch, "maxPitch" => $scene_max_pitch, "minPitch" => $scene_min_pitch, "maxYaw" => $scene_max_yaw, "minYaw" => $scene_min_yaw, "yaw" => $default_scene_yaw, "hfov" => $default_zoom, "maxHfov" => $max_zoom, "minHfov" => $min_zoom, "title" => $scene_ititle, "author" => $scene_author, "authorURL" => $scene_author_url, "vaov" => $scene_vaov, "haov" => $scene_haov, "vOffset" => $scene_vertical_offset, 'hotSpots' => $hotspots);
1679 - }
1680 -
1681 -
1682 -
1683 - if (isset($panoscenes["ptyscene"])) {
1684 - if ($panoscenes["ptyscene"] == "off") {
1685 - unset($scene_info['pitch']);
1686 - unset($scene_info['yaw']);
1687 - }
1688 - }
1689 -
1690 - if (!$show_scene_info || empty($panoscenes["scene-ititle"])) {
1691 - unset($scene_info['title']);
1692 - }
1693 - if (!$show_scene_info || empty($panoscenes["scene-author"])) {
1694 - unset($scene_info['author']);
1695 - }
1696 - if (!$show_scene_info || empty($panoscenes["scene-author-url"])) {
1697 - unset($scene_info['authorURL']);
1698 - }
1699 -
1700 - if (empty($scene_vaov)) {
1701 - unset($scene_info['vaov']);
1702 - }
1703 -
1704 - if (empty($scene_haov)) {
1705 - unset($scene_info['haov']);
1706 - }
1707 -
1708 - if (empty($scene_vertical_offset)) {
1709 - unset($scene_info['vOffset']);
1710 - }
1711 -
1712 - if (isset($panoscenes["cvgscene"])) {
1713 - if ($panoscenes["cvgscene"] == "off") {
1714 - unset($scene_info['maxPitch']);
1715 - unset($scene_info['minPitch']);
1716 - }
1717 - }
1718 - if (empty($panoscenes["scene-maxpitch"])) {
1719 - unset($scene_info['maxPitch']);
1720 - }
1721 -
1722 - if (empty($panoscenes["scene-minpitch"])) {
1723 - unset($scene_info['minPitch']);
1724 - }
1725 -
1726 - if (isset($panoscenes["chgscene"])) {
1727 - if ($panoscenes["chgscene"] == "off") {
1728 - unset($scene_info['maxYaw']);
1729 - unset($scene_info['minYaw']);
1730 - }
1731 - }
1732 - if (empty($panoscenes["scene-maxyaw"])) {
1733 - unset($scene_info['maxYaw']);
1734 - }
1735 -
1736 - if (empty($panoscenes["scene-minyaw"])) {
1737 - unset($scene_info['minYaw']);
1738 - }
1739 -
1740 - // if (isset($panoscenes["czscene"])) {
1741 - // if ($panoscenes["czscene"] == "off") {
1742 - // unset($scene_info['hfov']);
1743 - // unset($scene_info['maxHfov']);
1744 - // unset($scene_info['minHfov']);
1745 - // }
1746 - // }
1747 -
1748 - $scene_array = array();
1749 - $scene_array = array(
1750 - $panoscenes['scene-id'] => $scene_info
1751 - );
1752 -
1753 - $scene_data[$panoscenes['scene-id']] = $scene_info;
1754 - }
1755 - }
1756 - }
1757 - $pano_id_array = array();
1758 - $pano_id_array = array('panoid' => $panoid);
1759 - $pano_response = array();
1760 - $pano_response = array('autoLoad' => $autoload, 'showControls' => $control, 'compass' => $compass, 'orientationOnByDefault' => $gyro_orientation, 'mouseZoom' => $mouseZoom, 'draggable' => $draggable, 'disableKeyboardCtrl' => $diskeyboard, 'keyboardZoom' => $keyboardzoom, "preview" => $preview, "autoRotate" => $autorotation, "autoRotateInactivityDelay" => $autorotationinactivedelay, "autoRotateStopDelay" => $autorotationstopdelay, 'default' => $default_data, 'scenes' => $scene_data);
1761 - if (empty($autorotation)) {
1762 - unset($pano_response['autoRotate']);
1763 - unset($pano_response['autoRotateInactivityDelay']);
1764 - unset($pano_response['autoRotateStopDelay']);
1765 - }
1766 - if (empty($autorotationinactivedelay)) {
1767 - unset($pano_response['autoRotateInactivityDelay']);
1768 - }
1769 - if (empty($autorotationstopdelay)) {
1770 - unset($pano_response['autoRotateStopDelay']);
1771 - }
1772 -
1773 - $response = array();
1774 - $response = array($pano_id_array, $pano_response);
1775 - if (!empty($response)) {
1776 - $response = json_encode($response);
1777 - }
1778 - if (empty($width)) {
1779 - $width = '600';
1780 - }
1781 - if (empty($height)) {
1782 - $height = '400';
1783 - }
1784 - if ('fullwidth' == $width) {
1785 - $width = "100%";
1786 - }
1787 -
1788 - $foreground_color = '#fff';
1789 - $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1790 - $rgb = wpvr_HTMLToRGB($hotspoticoncolor);
1791 - $hsl = wpvr_RGBToHSL($rgb);
1792 - if ($hsl->lightness > 200) {
1793 - $foreground_color = '#000000';
1794 - } else {
1795 - $foreground_color = '#fff';
1796 - }
1797 -
1798 - $class = 'myclass';
1799 - $html = 'test';
1800 - $html = '';
1801 - $html .= '<style>';
1802 - if ($width == 'embed') {
1803 - $html .= 'body{
1804 - overflow: hidden;
1805 - }';
1806 - }
1807 - $status = get_option('wpvr_edd_license_status');
1808 - if ($status !== false && $status == 'valid') {
1809 - if (isset($postdata['customcss_enable']) && $postdata['customcss_enable'] == 'on') {
1810 - $html .= isset($postdata['customcss']) ? $postdata['customcss'] : '';
1811 - }
1812 - }
1813 - if ($status !== false && $status == 'valid') {
1814 - if (is_array($panodata) && isset($panodata['scene-list'])) {
1815 - foreach ($panodata['scene-list'] as $panoscenes) {
1816 -
1817 - foreach ($panoscenes['hotspot-list'] as $hotspot) {
1818 - if (isset($hotspot['hotspot-customclass-color-icon-value']) && !empty($hotspot['hotspot-customclass-color-icon-value'])) {
1819 - $hotspoticoncolor = $hotspot['hotspot-customclass-color-icon-value'];
1820 - } else {
1821 - $hotspoticoncolor = "#00b4ff";
1822 - }
1823 - $hotspot_border = '';
1824 - if(isset($hotspot['hotspot-border']) && $hotspot['hotspot-border'] == 'on'){
1825 - $border_width = $hotspot['hotspot-border-width'];
1826 - $border_color = $hotspot['hotspot-border-color'];
1827 - $border_style = $hotspot['hotspot-border-style'];
1828 -
1829 - $hotspot_border = 'border: '.$border_width.'px '.$border_style.' '.$border_color.';';
1830 - }
1831 - $hotspot_background_color = 'background-color: ' . $hotspoticoncolor . ';';
1832 - $hotspot_animation = ' animation: icon-pulse' . $panoid . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1833 - '. $hotspot_border.'';
1834 -
1835 -
1836 - $pulse_color = wpvr_hex2rgb($hotspoticoncolor);
1837 - if (isset($hotspot["hotspot-customclass-pro"]) && $hotspot["hotspot-customclass-pro"] != 'none') {
1838 - $border_radius = ' border-radius: 100%;';
1839 - $hotspot_shape = isset($hotspot["hotspot-shape"]) ? $hotspot["hotspot-shape"] : 'round';
1840 - if($hotspot_shape === 'square'){
1841 - $border_radius = '';
1842 - }
1843 - if ($hotspot_shape === 'hexagon') {
1844 - $border_radius = '';
1845 - $hotspot_background_color = 'background-color: transparent;';
1846 - $hotspot_animation = '';
1847 - }
1848 -
1849 - if(isset($hotspot['hotspot-custom-icon-color-value']) && !empty($hotspot['hotspot-custom-icon-color-value'])){
1850 - $foreground_color = $hotspot['hotspot-custom-icon-color-value'];
1851 - }
1852 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fas.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1853 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fab.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1854 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fa.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1855 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.fa-solid.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1856 - #' . esc_attr( $panoid ). ' div.pnlm-hotspot-base.far.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' {
1857 - display: block !important;
1858 - '.$hotspot_background_color.'
1859 - color: ' . $foreground_color . ';
1860 - '.$border_radius.'
1861 - width: 30px;
1862 - height: 30px;
1863 - font-size: 16px;
1864 - line-height: 30px;
1865 - '.$hotspot_animation.'
1866 - }';
1867 - if($hotspot_shape === 'hexagon'){
1868 -
1869 - $html .= '#' . esc_attr( $panoid ) . ' .custom-' . esc_attr( $id ) . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' .hexagon-wrapper svg path {
1870 - fill: ' . $hotspoticoncolor . ';
1871 - }';
1872 -
1873 - $html .= '#' . esc_attr( $panoid ) . ' .custom-' . esc_attr( $id ) . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . '.pnlm-tooltip:after{
1874 - content: "";
1875 - position: absolute;
1876 - left: 50%;
1877 - top: 50%;
1878 - transform: translate(-50%, -50%);
1879 - width: 85%;
1880 - height: 85%;
1881 - animation: icon-pulse' . esc_attr( $panoid ) . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' 1.5s infinite cubic-bezier(.25, 0, 0, 1);
1882 - border-radius: 100%;
1883 - z-index: -2;
1884 - }';
1885 -
1886 - }
1887 - $html .= '#' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fas.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1888 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fab.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1889 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.fa-solid.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1890 - #' . esc_attr( $panoid2) . ' div.pnlm-hotspot-base.fa.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ',
1891 - #' . esc_attr( $panoid2 ). ' div.pnlm-hotspot-base.far.custom-' . esc_attr( $id ). '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' {
1892 - display: block !important;
1893 - '.esc_attr( $hotspot_background_color).'
1894 - color: ' . esc_attr( $foreground_color) . ';
1895 - '.esc_attr( $border_radius).'
1896 - width: 30px;
1897 - height: 30px;
1898 - font-size: 16px;
1899 - line-height: 30px;
1900 - '.esc_attr( $hotspot_animation).'
1901 - }';
1902 - }
1903 - if (isset($hotspot['hotspot-blink'])) {
1904 - $hotspotblink = $hotspot['hotspot-blink'];
1905 - if ($hotspotblink == 'on') {
1906 - $html .= '@-webkit-keyframes icon-pulse' . esc_attr( $panoid) . '-' . $panoscenes['scene-id'] . '-' . sanitize_html_class($hotspot['hotspot-title']) . ' {
1907 - 0% {
1908 - box-shadow: 0 0 0 0px rgba(' . esc_attr( $pulse_color[0]) . ', 1);
1909 - }
1910 - 100% {
1911 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pulse_color[0]) . ', 0);
1912 - }
1913 - }
1914 - @keyframes icon-pulse' . esc_attr( $panoid) . ' {
1915 - 0% {
1916 - box-shadow: 0 0 0 0px rgba(' . esc_attr( $pulse_color[0]) . ', 1);)
1917 - }
1918 - 100% {
1919 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pulse_color[0] ). ', 0);
1920 - }
1921 - }';
1922 - }
1923 - }
1924 - }
1925 - }
1926 - }
1927 - }
1928 -
1929 - $status = get_option('wpvr_edd_license_status');
1930 - if ($status !== false && $status == 'valid') {
1931 - if (!$gyro) {
1932 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-orientation-button {
1933 - display: none;
1934 - }';
1935 - }
1936 - } else {
1937 - $html .= '#' . esc_attr( $panoid ). ' div.pnlm-orientation-button {
1938 - display: none;
1939 - }';
1940 - }
1941 - $floor_plan_custom_color = isset($postdata['floor_plan_custom_color']) ? $postdata['floor_plan_custom_color'] : '#cca92c';
1942 - $foreground_color_pointer = '#fff';
1943 - if ($floor_plan_custom_color != '') {
1944 - $pointer_pulse = wpvr_hex2rgb($floor_plan_custom_color);
1945 - $floor_rgb = wpvr_HTMLToRGB($floor_plan_custom_color);
1946 - $floor_hsl = wpvr_RGBToHSL($floor_rgb);
1947 - if ($floor_hsl->lightness > 200) {
1948 - $foreground_color_pointer = '#000000';
1949 - }
1950 - $html .= '
1951 - .wpvr-floor-map .floor-plan-pointer.add-pulse:before {
1952 - border: 17px solid ' . esc_attr( $floor_plan_custom_color ) . ';
1953 - }
1954 - @-webkit-keyframes pulse {
1955 - 0% {
1956 - -webkit-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1957 - }
1958 - 70% {
1959 - -webkit-box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1960 - }
1961 - 100% {
1962 - -webkit-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1963 - }
1964 - }
1965 - @keyframes pulse {
1966 - 0% {
1967 - -moz-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1968 - box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0.7);
1969 - }
1970 - 70% {
1971 - -moz-box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1972 - box-shadow: 0 0 0 10px rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1973 - }
1974 - 100% {
1975 - -moz-box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1976 - box-shadow: 0 0 0 0 rgba(' . esc_attr( $pointer_pulse[0] ) . ', 0);
1977 - }
1978 - }';
1979 - }
1980 - $html .= '</style>';
1981 -
1982 - $scene_animation = isset($postdata['sceneAnimation']) ? $postdata['sceneAnimation'] : 'off';
1983 - $scene_animation_enabled = in_array( $scene_animation, array( 'on', '1', 1, true ), true );
1984 -
1985 - if( $scene_animation_enabled && is_plugin_active( 'wpvr-pro/wpvr-pro.php' ) ) {
1986 - $animation_type = isset($postdata['sceneAnimationName']) ? $postdata['sceneAnimationName'] : 'none';
1987 - $animation_type = $animation_type === 'fade' ? 'fade_in' : $animation_type;
1988 - $animationDuration = isset($postdata['sceneAnimationTransitionDuration']) ? $postdata['sceneAnimationTransitionDuration'] : '500ms';
1989 - $animationDelay = isset($postdata['sceneAnimationTransitionDelay']) ? $postdata['sceneAnimationTransitionDelay'] : '0ms';
1990 - $animation_css = apply_filters('wpvr_tour_scene_animation',$animation_type,$animationDuration, $animationDelay, $postdata,$id);
1991 - $html .= $animation_css;
1992 - }
1993 -
1994 - if (wpvr_isMobileDevice()) {
1995 - $html .= '<div id="master-container" class="wpvr-cardboard ' . esc_attr( $className ) . ' ' . esc_attr( $enable_cardboard ) . ' " style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; width: 100%; height: ' . esc_attr( $mobile_height ) . esc_attr( $mobile_height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr; border : ' . esc_attr( $border_style ) . ' ">';
1996 - } else {
1997 - $html .= '<div id="master-container" class="wpvr-cardboard ' . esc_attr( $className ) . ' ' . esc_attr( $enable_cardboard ) . '" style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '; width: 100%; height: ' . esc_attr( $height ) . esc_attr( $height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr; border : ' . esc_attr( $border_style ) . '">';
1998 - }
1999 - $status = get_option('wpvr_edd_license_status');
2000 - $is_cardboard = get_option('wpvr_cardboard_disable');
2001 - if ($status !== false && 'valid' == $status && $is_pro && wpvr_isMobileDevice() && $is_cardboard == 'true') {
2002 - $html .= '<button class="fullscreen-button">';
2003 - $html .= '<span class="expand">';
2004 - $html .= '<i class="fas fa-expand" aria-hidden="true"></i>';
2005 - $html .= '</span>';
2006 -
2007 - $html .= '<span class="compress">';
2008 - $html .= '<i class="fas fa-minimize" aria-hidden="true"></i>';
2009 - $html .= '</span>';
2010 - $html .= '</button>';
2011 - $html .= '<label class="wpvr-cardboard-switcher">
2012 - <input type="checkbox" class="vr_mode_change' . $id . '" name="vr_mode_change" value="off">
2013 - <span class="switcher-box">
2014 - <span class="normal-mode-tooltip">Normal VR Mode</span>
2015 - <svg width="78" height="60" viewBox="0 0 78 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2016 - <path d="M42.25 21.4286C42.25 22.2811 41.9076 23.0986 41.2981 23.7014C40.6886 24.3042 39.862 24.6429 39 24.6429C38.138 24.6429 37.3114 24.3042 36.7019 23.7014C36.0924 23.0986 35.75 22.2811 35.75 21.4286C35.75 20.5761 36.0924 19.7585 36.7019 19.1557C37.3114 18.5529 38.138 18.2143 39 18.2143C39.862 18.2143 40.6886 18.5529 41.2981 19.1557C41.9076 19.7585 42.25 20.5761 42.25 21.4286ZM19.5 30C18.9254 30 18.3743 30.2258 17.9679 30.6276C17.5616 31.0295 17.3333 31.5745 17.3333 32.1429C17.3333 32.7112 17.5616 33.2562 17.9679 33.6581C18.3743 34.06 18.9254 34.2857 19.5 34.2857H28.1667C28.7413 34.2857 29.2924 34.06 29.6987 33.6581C30.1051 33.2562 30.3333 32.7112 30.3333 32.1429C30.3333 31.5745 30.1051 31.0295 29.6987 30.6276C29.2924 30.2258 28.7413 30 28.1667 30H19.5ZM47.6667 32.1429C47.6667 31.5745 47.8949 31.0295 48.3013 30.6276C48.7076 30.2258 49.2587 30 49.8333 30H58.5C59.0746 30 59.6257 30.2258 60.0321 30.6276C60.4384 31.0295 60.6667 31.5745 60.6667 32.1429C60.6667 32.7112 60.4384 33.2562 60.0321 33.6581C59.6257 34.06 59.0746 34.2857 58.5 34.2857H49.8333C49.2587 34.2857 48.7076 34.06 48.3013 33.6581C47.8949 33.2562 47.6667 32.7112 47.6667 32.1429ZM32.5 0C31.9254 0 31.3743 0.225765 30.9679 0.627629C30.5616 1.02949 30.3333 1.57454 30.3333 2.14286V8.57143H18.4167C14.8693 8.57183 11.4528 9.89617 8.84994 12.2798C6.24706 14.6634 4.64954 17.9306 4.37667 21.4286H2.16667C1.59203 21.4286 1.04093 21.6543 0.634602 22.0562C0.228273 22.4581 0 23.0031 0 23.5714V36.4286C0 36.9969 0.228273 37.5419 0.634602 37.9438C1.04093 38.3457 1.59203 38.5714 2.16667 38.5714H4.33333V46.0714C4.33333 49.7655 5.81711 53.3083 8.45825 55.9204C11.0994 58.5325 14.6815 60 18.4167 60H25.3933C29.1269 59.9986 32.7071 58.5311 35.347 55.92L37.921 53.3786C38.0618 53.2393 38.229 53.1288 38.4131 53.0534C38.5971 52.978 38.7943 52.9392 38.9935 52.9392C39.1927 52.9392 39.3899 52.978 39.5739 53.0534C39.758 53.1288 39.9252 53.2393 40.066 53.3786L42.6357 55.92C45.2766 58.5322 48.8586 59.9998 52.5937 60H59.5833C63.3185 60 66.9006 58.5325 69.5418 55.9204C72.1829 53.3083 73.6667 49.7655 73.6667 46.0714V38.5714H75.8333C76.408 38.5714 76.9591 38.3457 77.3654 37.9438C77.7717 37.5419 78 36.9969 78 36.4286V23.5714C78 23.0031 77.7717 22.4581 77.3654 22.0562C76.9591 21.6543 76.408 21.4286 75.8333 21.4286H73.6233C73.3505 17.9306 71.753 14.6634 69.1501 12.2798C66.5472 9.89617 63.1307 8.57183 59.5833 8.57143H47.6667V2.14286C47.6667 1.57454 47.4384 1.02949 47.0321 0.627629C46.6257 0.225765 46.0746 0 45.5 0H32.5ZM69.3333 22.5V46.0714C69.3333 48.6289 68.3061 51.0816 66.4776 52.89C64.6491 54.6983 62.1692 55.7143 59.5833 55.7143H52.5937C50.0093 55.7132 47.5311 54.6973 45.7037 52.89L43.1297 50.3486C42.5864 49.8108 41.9413 49.3842 41.2312 49.0931C40.5211 48.8021 39.76 48.6522 38.9913 48.6522C38.2227 48.6522 37.4616 48.8021 36.7515 49.0931C36.0414 49.3842 35.3963 49.8108 34.853 50.3486L32.2833 52.89C30.4559 54.6973 27.9777 55.7132 25.3933 55.7143H18.4167C15.8308 55.7143 13.3509 54.6983 11.5224 52.89C9.6939 51.0816 8.66667 48.6289 8.66667 46.0714V22.5C8.66667 19.9426 9.6939 17.4899 11.5224 15.6815C13.3509 13.8731 15.8308 12.8571 18.4167 12.8571H59.5833C62.1692 12.8571 64.6491 13.8731 66.4776 15.6815C68.3061 17.4899 69.3333 19.9426 69.3333 22.5Z" fill="#216DF0"/>
2017 - </svg>
2018 - </span>
2019 - </label>';
2020 - }
2021 -
2022 - if ($width == 'fullwidth') {
2023 - if (wpvr_isMobileDevice()) {
2024 - $html .= '<div class="cardboard-vrfullwidth vrfullwidth">';
2025 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left cardboard-half" style="width: 49%!important; border-radius:' . esc_attr( $radius ). ' ;text-align:center; direction:ltr;" ><div id="center-pointer2' . esc_attr( $id ). '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
2026 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style="width: 100%; text-align:center; direction:ltr; border-radius:' . esc_attr( $radius ) . '" >';
2027 - } else {
2028 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';"><div id="center-pointer2' . esc_attr( $id ). '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
2029 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap vrfullwidth" style=" text-align:center; height: ' . esc_attr( $height ) . esc_attr( $height_unit ) . '; border-radius:' . esc_attr( $radius ) . '; direction:ltr;" >';
2030 - }
2031 - } else {
2032 - if (wpvr_isMobileDevice()) {
2033 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left cardboard-half" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';">
2034 - <div id="center-pointer2' . esc_attr( $id ) . '" class="vr-pointer-container">
2035 - <span class="center-pointer"></span>
2036 - </div>
2037 - </div>';
2038 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style=" width: 100%; border-radius:' . esc_attr( $radius ) . ';">';
2039 - } else {
2040 -
2041 - $html .= '<div id="pano2' . esc_attr( $id ) . '" class="pano-wrap pano-left" style="width: 49%; border-radius:' . esc_attr( $radius ) . ';"><div id="center-pointer2' . esc_attr( $id ) . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
2042 -
2043 - $html .= '<div id="pano' . esc_attr( $id ) . '" class="pano-wrap pano-right" style="width: 100%; border-radius:' . esc_attr( $radius ) . ';">';
2044 - }
2045 - }
2046 - // Vr mode transction scene to scene
2047 - if ($status !== false && 'valid' == $status && $is_pro && wpvr_isMobileDevice() && $is_cardboard == 'true') {
2048 - $html .= '<div id="center-pointer' . esc_attr( $id ) . '" class="vr-pointer-container" style="display:none"><span class="center-pointer"></span></div>';
2049 - }
2050 -
2051 -
2052 - //===company logo===//
2053 - if (isset($postdata['cpLogoSwitch'])) {
2054 - $cpLogoImg = $postdata['cpLogoImg'] ?? '';
2055 - $cpLogoContent = $postdata['cpLogoContent'] ?? '';
2056 - if ($postdata['cpLogoSwitch'] == 'on' && 'valid' == $status && $is_pro) {
2057 - $html .= '<div id="cp-logo-controls">';
2058 - $html .= '<div class="cp-logo-ctrl" id="cp-logo">';
2059 - if ($cpLogoImg) {
2060 - $html .= '<img loading="lazy" src="' . esc_attr( $cpLogoImg ) . '" alt="Company Logo">';
2061 - }
2062 -
2063 - if ($cpLogoContent) {
2064 - $html .= '<div class="cp-info">' . esc_html( $cpLogoContent ) . '</div>';
2065 - }
2066 - $html .= '</div>';
2067 - $html .= '</div>';
2068 - }
2069 - }
2070 - //===company logo ends===//
2071 -
2072 - //===Background Tour===//
2073 - if (isset($postdata['bg_tour_enabler'])) {
2074 -
2075 - $bg_tour_enabler = $postdata['bg_tour_enabler'];
2076 - if ($bg_tour_enabler == 'on') {
2077 - $bg_tour_navmenu = $postdata['bg_tour_navmenu'] ?? 'off';
2078 - $bg_tour_title = $postdata['bg_tour_title'] ?? '';
2079 - $bg_tour_subtitle = $postdata['bg_tour_subtitle'] ?? '';
2080 -
2081 - if ($bg_tour_navmenu == 'on') {
2082 - $menuLocations = get_nav_menu_locations();
2083 - $menuID = $menuLocations['primary'];
2084 - $primaryNav = wp_get_nav_menu_items($menuID);
2085 -
2086 - if ($primaryNav) {
2087 - $html .= '<div class="wpvr-navbar-container">';
2088 - foreach ($primaryNav as $primaryNav_key => $primaryNav_value) {
2089 - if ($primaryNav_value->menu_item_parent == "0") {
2090 - $html .= '<li>';
2091 - $html .= '<a href="' . esc_url( $primaryNav_value->url ) . '">' . esc_attr( $primaryNav_value->title ) . '</a>';
2092 - $html .= '<ul class="wpvr-navbar-dropdown">';
2093 - foreach ($primaryNav as $pm_key => $pm_value) {
2094 - if ($pm_value->menu_item_parent == $primaryNav_value->ID) {
2095 - $html .= '<li>';
2096 - $html .= '<a href="' . esc_url( $pm_value->url ) . '">' . esc_attr( $pm_value->title ) . '</a>';
2097 - $html .= '</li>';
2098 - }
2099 - }
2100 - $html .= '</ul>';
2101 - $html .= '</li>';
2102 - }
2103 - }
2104 - $html .= '</div>';
2105 - }
2106 - }
2107 -
2108 - if($is_pro && 'valid' == $status ){
2109 - $html .= '<div class="wpvr-home-content">';
2110 - $html .= '<div class="wpvr-home-title">' . $bg_tour_title . '</div>';
2111 - $html .= '<div class="wpvr-home-subtitle">' . $bg_tour_subtitle . '</div>';
2112 - $html .= '</div>';
2113 - }
2114 - }
2115 - }
2116 - //===Background Tour End===//
2117 -
2118 - //===Custom Control===//
2119 - if (isset($custom_control)) {
2120 - $gyro_button_enabled = wpvr_isMobileDevice() && $custom_control['gyroSwitch'] == "on" && $custom_control['gyroscopeSwitch'] == "on";
2121 - if ($custom_control['panZoomInSwitch'] == "on" || $custom_control['panZoomOutSwitch'] == "on" || $gyro_button_enabled || $custom_control['backToHomeSwitch'] == "on") {
2122 - $html .= '<div id="zoom-in-out-controls' . esc_attr( $id ) . '" class="zoom-in-out-controls">';
2123 -
2124 - if ($custom_control['backToHomeSwitch'] == "on" && 'valid' == $status && $is_pro) {
2125 - $html .= '<div class="ctrl" id="backToHome' . esc_attr( $id ) . '"><i class="' . $custom_control['backToHomeIcon'] . '" style="color:' . esc_attr( $custom_control['backToHomeColor'] ) . ';"></i></div>';
2126 - }
2127 -
2128 - if ($custom_control['panZoomInSwitch'] == "on" && 'valid' == $status && $is_pro) {
2129 - $html .= '<div class="ctrl" id="zoom-in' . esc_attr( $id ) . '"><i class="' . $custom_control['panZoomInIcon'] . '" style="color:' . esc_attr( $custom_control['panZoomInColor'] ) . ';"></i></div>';
2130 - }
2131 -
2132 - if ($custom_control['panZoomOutSwitch'] == "on" && 'valid' == $status && $is_pro) {
2133 - $html .= '<div class="ctrl" id="zoom-out' . esc_attr( $id ) . '"><i class="' . $custom_control['panZoomOutIcon'] . '" style="color:' . esc_attr( $custom_control['panZoomOutColor'] ) . ';"></i></div>';
2134 - }
2135 -
2136 - if ($gyro_button_enabled && 'valid' == $status && $is_pro) {
2137 - $html .= '<div class="ctrl" id="gyroscope' . esc_attr( $id ) . '"><i class="' . $custom_control['gyroscopeIcon'] . '" style="color:' . esc_attr( $custom_control['gyroscopeColor'] ) . ';"></i></div>';
2138 - }
2139 -
2140 - $html .= '</div>';
2141 - }
2142 - //===zoom in out Control===//
2143 -
2144 - if ( ($custom_control['panupSwitch'] == "on" || $custom_control['panDownSwitch'] == "on" || $custom_control['panLeftSwitch'] == "on" || $custom_control['panRightSwitch'] == "on" || $custom_control['panFullscreenSwitch'] == "on" ) && 'valid' == $status && $is_pro) {
2145 -
2146 - //===Custom Control===//
2147 - $html .= '<div class="controls" id="controls' . esc_attr( $id ) . '">';
2148 -
2149 - if ($custom_control['panupSwitch'] == "on") {
2150 - $html .= '<div class="ctrl pan-up" id="pan-up' . esc_attr( $id ) . '"><i class="' . $custom_control['panupIcon'] . '" style="color:' . esc_attr( $custom_control['panupColor'] ) . ';"></i></div>';
2151 - }
2152 -
2153 - if ($custom_control['panDownSwitch'] == "on") {
2154 - $html .= '<div class="ctrl pan-down" id="pan-down' . esc_attr( $id ) . '"><i class="' . $custom_control['panDownIcon'] . '" style="color:' . esc_attr( $custom_control['panDownColor'] ) . ';"></i></div>';
2155 - }
2156 -
2157 - if ($custom_control['panLeftSwitch'] == "on") {
2158 - $html .= '<div class="ctrl pan-left" id="pan-left' . esc_attr( $id ) . '"><i class="' . $custom_control['panLeftIcon'] . '" style="color:' . esc_attr( $custom_control['panLeftColor'] ) . ';"></i></div>';
2159 - }
2160 -
2161 - if ($custom_control['panRightSwitch'] == "on") {
2162 - $html .= '<div class="ctrl pan-right" id="pan-right' . esc_attr( $id ) . '"><i class="' . $custom_control['panRightIcon'] . '" style="color:' . esc_attr( $custom_control['panRightColor'] ) . ';"></i></div>';
2163 - }
2164 -
2165 - if ($custom_control['panFullscreenSwitch'] == "on") {
2166 - $html .= '<div class="ctrl fullscreen" id="fullscreen' . esc_attr( $id ) . '"><i class="' . $custom_control['panFullscreenIcon'] . '" style="color:' . esc_attr( $custom_control['panFullscreenColor'] ) . ';"></i></div>';
2167 - }
2168 - $html .= '</div>';
2169 - }
2170 - }
2171 -
2172 - //===explainer button===//
2173 - $html .= wpvr_render_explainer_button(
2174 - isset( $custom_control ) ? $custom_control : null,
2175 - $postdata,
2176 - $is_pro,
2177 - $autoload,
2178 - $explainer_right,
2179 - $id
2180 - );
2181 - //===explainer button end===//
2182 -
2183 - //===Scene navigation Control===//
2184 - if (isset($postdata['scene_navigation']) && $postdata['scene_navigation'] === 'on' && 'valid' == $status && $is_pro) {
2185 - $scene_navigation_nav_class = 'custom-scene-navigation-nav' . ( $is_classic_layout ? ' wpvr-scene-navigation-nav--classic' : '' );
2186 - $html .= '<style>
2187 - #et-boc .et-l .pnlm-controls-container,
2188 - .pnlm-controls-container{
2189 - top: 33px;
2190 - }
2191 -
2192 - #et-boc .et-l .zoom-in-out-controls,
2193 - .zoom-in-out-controls {
2194 - top: 37px;
2195 - }
2196 - </style>';
2197 - $html .= '<div id="custom-scene-navigation' . esc_attr( $id ) . '" class="custom-scene-navigation">
2198 - <span class="hamburger-menu"><svg width="16" height="10" fill="none" viewBox="0 0 22 15" xmlns="http://www.w3.org/2000/svg"><rect width="21.177" height="2.647" fill="#f7fffb" rx="1.324"/><rect width="21.177" height="2.647" y="6.177" fill="#f7fffb" rx="1.324"/><rect width="21.177" height="2.647" y="12.352" fill="#f7fffb" rx="1.324"/></svg></span>
2199 - </div>
2200 -
2201 - <div id="custom-scene-navigation-nav' . esc_attr( $id ) . '" class="' . esc_attr( $scene_navigation_nav_class ) . '">
2202 - <ul></ul>
2203 - </div>
2204 - ';
2205 - }
2206 -
2207 - //===Scene navigation Control===//
2208 -
2209 - /**
2210 - * Generic Form Handler
2211 - * Renders a generic form with modal functionality if enabled in post data
2212 - *
2213 - * @param array $postdata Array containing form configuration data
2214 - * @param string $id Unique identifier for the form instance
2215 - * @return string $html Generated HTML content
2216 - */
2217 -
2218 - // Check if generic form is enabled and validate the setting
2219 - if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on' && 'valid' == $status && $is_pro) {
2220 -
2221 - // Process shortcode with fallback handling
2222 - $shortcode_content = '';
2223 - if (isset($postdata["genericformshortcode"]) && !empty(trim($postdata["genericformshortcode"]))) {
2224 - $shortcode_content = do_shortcode( $postdata["genericformshortcode"] );
2225 - } else {
2226 - $shortcode_content = '<p class="error-message">No shortcode found.</p>';
2227 - }
2228 -
2229 - // Generate the form trigger button
2230 - $generic_form_icon = isset($postdata['genericformicon']) ? (string) $postdata['genericformicon'] : 'fab fa-wpforms';
2231 - $generic_form_icon = implode(' ', array_filter(array_map('sanitize_html_class', preg_split('/\s+/', $generic_form_icon))));
2232 - $generic_form_icon = $generic_form_icon ?: 'fab fa-wpforms';
2233 - $generic_form_icon_color = sanitize_hex_color($postdata['genericformiconcolor'] ?? '') ?: '#f7fffb';
2234 - $html .= '<div class="generic_form_button" id="generic_form_button_' . esc_attr( $id ) . '">';
2235 - $html .= '<div class="generic-form-icon" title ="Generic Form" id="generic_form_target_' . esc_attr( $id ) . '"><i class="' . esc_attr( $generic_form_icon ) . '" style="color:' . esc_attr( $generic_form_icon_color ) . ';"></i></div>';
2236 - $html .= '</div>';
2237 -
2238 - // Generate the modal form container
2239 - $html .= '<div class="wpvr-generic-form" id="wpvr-generic-form' . esc_attr( $id ) . '" style="display: none">';
2240 - $html .= '<span class="close-generic-form"><i class="fa fa-times"></i></span>';
2241 - $html .= '<div class="generic-form-container">' . $shortcode_content . '</div>';
2242 - $html .= '</div>';
2243 - }
2244 - //=====custom generic form=====//
2245 -
2246 - //===Floor map button===//
2247 - $status = get_option('wpvr_edd_license_status');
2248 - if ($status !== false && 'valid' == $status && $is_pro) {
2249 - if ($floor_plan_enable == "on" && !empty($floor_plan_image)) {
2250 - $html .= '<div class="floor_map_button" id="floor_map_button_' . esc_attr( $id ) . '" style="right:' . esc_attr( $floor_map_right ) . '">';
2251 - $html .= '<div class="ctrl" id="floor_map_target_' . esc_attr( $id ) . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>';
2252 - $html .= '</div>';
2253 - }
2254 - }
2255 -
2256 - //===floor map button===//
2257 - if ($vrgallery && 'valid' == $status && $is_pro ) {
2258 - //===Carousal setup===//
2259 - $size = '';
2260 - if ($vrgallery_icon_size) {
2261 - $size = 'vrg-icon-size-large';
2262 - }
2263 - $html .= '<div id="vrgcontrols' . esc_attr( $id ) . '" class="vrgcontrols">';
2264 -
2265 - $html .= '<div class="vrgctrl' . esc_attr( $id ) . ' vrbounce ' . esc_attr( $size ) . '">';
2266 - $html .= '</div>';
2267 - $html .= '</div>';
2268 -
2269 - $tour_layout = is_array( $postdata['tourLayout'] ?? null )
2270 - ? ( $postdata['tourLayout']['layout'] ?? 'default' )
2271 - : ( $postdata['tourLayout'] ?? 'default' );
2272 - $gallery_layout_class = 'layout1' === $tour_layout
2273 - ? 'wpvr-gallery--modern'
2274 - : 'wpvr-gallery--classic';
2275 -
2276 - $html .= '<div id="sccontrols' . esc_attr( $id ) . '" class="scene-gallery vrowl-carousel owl-theme ' . esc_attr( $gallery_layout_class ) . '">';
2277 - if (isset($panodata["scene-list"])) {
2278 - foreach ($panodata["scene-list"] as $panoscenes) {
2279 - $scene_key = $panoscenes['scene-id'];
2280 - if ($vrgallery_title == 'on') {
2281 - $scene_key_title = isset($panoscenes['scene-ititle']) ? esc_html($panoscenes['scene-ititle']) : '';
2282 - } else {
2283 - $scene_key_title = "";
2284 - }
2285 -
2286 - if ($panoscenes['scene-type'] == 'cubemap') {
2287 - $img_src_url = $panoscenes['scene-attachment-url-face0'];
2288 - } else {
2289 - $img_src_url = $panoscenes['scene-attachment-url'];
2290 - }
2291 -
2292 -
2293 - $src_to_id = attachment_url_to_postid($img_src_url);
2294 - $thumbnail_array = wp_get_attachment_image_src($src_to_id, 'thumbnail');
2295 - if ($thumbnail_array) {
2296 - $thumbnail = $thumbnail_array[0];
2297 - } else {
2298 - $thumbnail = $img_src_url;
2299 - }
2300 - if ( 'layout1' !== $tour_layout ) {
2301 - $html .= '<ul><li title="Double click to view scene"><span class="scene-title" title="' . esc_attr($scene_key_title) . '"> ' . $scene_key_title . '</span><img loading="lazy" class="scctrl" id="' . $scene_key . '_gallery_' . $id . '" src="' . $thumbnail . '"></li></ul>';
2302 - }else {
2303 - $html .= '<ul><li title="Double click to view scene"><img loading="lazy" class="scctrl" id="' . $scene_key . '_gallery_' . $id . '" src="' . $thumbnail . '"><span class="scene-title" title="' . esc_attr($scene_key_title) . '">' . $scene_key_title . '</span></li></ul>';
2304 - }
2305 - }
2306 - }
2307 - $html .= '</div>';
2308 - $html .= '
2309 - <div class="owl-nav wpvr_slider_nav">
2310 - <button type="button" role="presentation" class="owl-prev wpvr_owl_prev">
2311 - <div class="nav-btn prev-slide"><i class="fa fa-angle-left"></i></div>
2312 - </button>
2313 - <button type="button" role="presentation" class="owl-next wpvr_owl_next">
2314 - <div class="nav-btn next-slide"><i class="fa fa-angle-right"></i></div>
2315 - </button>
2316 - </div>
2317 - ';
2318 - //===Carousal setup end===//
2319 - }
2320 -
2321 - $bg_music = isset($postdata['bg_music']) ? $postdata['bg_music'] : 'off';
2322 - $bg_music_url = isset($postdata['bg_music_url']) ? $postdata['bg_music_url'] : '';
2323 - $autoplay_bg_music = isset($postdata['autoplay_bg_music']) ? $postdata['autoplay_bg_music'] : 'off';
2324 - $loop_bg_music = isset($postdata['loop_bg_music']) ? $postdata['loop_bg_music'] : 'off';
2325 -
2326 - $bg_loop = ($loop_bg_music === 'on') ? 'loop' : '';
2327 - $autoplay_attr = ($autoplay_bg_music === 'on') ? 'autoplay' : '';
2328 - $audio_muted_attr = ($autoplay_bg_music === 'on') ? 'muted' : '';
2329 - $audio_icon_class = 'fa-volume-mute'; // Always start with mute icon
2330 -
2331 - if ($bg_music === 'on' && 'valid' == $status && $is_pro) {
2332 - $html .= '<div id="adcontrol' . esc_attr( $id ) . '" class="adcontrol" style="right:' . esc_attr( $audio_right ) . '">';
2333 - $html .= '<audio id="vrAudio' . esc_attr($id) . '" class="vrAudioDefault" data-autoplay="' . esc_attr($autoplay_bg_music) . '" onended="audionEnd' . esc_attr($id) . '()" ' . $autoplay_attr . ' ' . $audio_muted_attr . ' ' . $bg_loop . '>
2334 - <source src="' . esc_url($bg_music_url) . '" type="audio/mpeg">
2335 - Your browser does not support the audio element.
2336 - </audio>';
2337 - $html .= '<button onclick="playPause' . esc_attr($id) . '()" class="ctrl audio_control" id="audio_control' . esc_attr($id) . '">
2338 - <i id="vr-volume' . esc_attr($id) . '" class="wpvrvolumeicon' . esc_attr($id) . ' fas ' . esc_attr($audio_icon_class) . '" style="color:#fff;"></i>
2339 - </button>';
2340 - $html .= '</div>';
2341 - }
2342 -
2343 - //===Explainer video section===//
2344 - $explainerContent = "";
2345 - if (isset($postdata['explainerContent'])) {
2346 - $explainerContent = wpvr_sanitize_iframe_only($postdata['explainerContent']);
2347 - }
2348 - $html .= '<div class="explainer" id="explainer' . esc_attr( $id ) . '" style="display: none">';
2349 - $html .= '<span class="close-explainer-video"><i class="fa fa-times"></i></span>';
2350 - $html .= '' . $explainerContent . '';
2351 - $html .= '</div>';
2352 - //===Explainer video section End===//
2353 -
2354 - //===Floor plan section===//
2355 - $floor_map_image = "";
2356 - $floor_map_pointer = array();
2357 - $floor_map_scene_id = '';
2358 - $floor_plan_custom_color = '#cca92c';
2359 - $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on';
2360 -
2361 - if (isset($postdata['floor_plan_attachment_url'])) {
2362 - $floor_map_image = $postdata['floor_plan_attachment_url'];
2363 - $floor_map_pointer = $postdata['floor_plan_pointer_position'];
2364 - $floor_map_scene_id = $postdata['floor_plan_data_list'];
2365 - $floor_plan_custom_color = $postdata['floor_plan_custom_color'];
2366 - }
2367 - $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $id . '" style="display: none">';
2368 - $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>';
2369 - $html .= '<img loading="lazy" src="' . $floor_map_image . '">';
2370 -
2371 - foreach ($floor_map_pointer as $key => $pointer_position) {
2372 - $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id = "' . esc_attr( $floor_map_scene_id[$key]->value ) . '" id="' . esc_attr( $pointer_position->id ) . '" data-top="' . esc_attr( $pointer_position->data_top ) . '" data-left="' . esc_attr( $pointer_position->data_left ) . '" style="' . esc_attr( $pointer_position->style ) . '">
2373 -
2374 - <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2375 - <circle cx="12" cy="12" r="11.5" stroke="' . esc_attr( $floor_plan_custom_color ) . '"/>
2376 - <circle cx="12" cy="12" r="5" fill="' . esc_attr( $foreground_color_pointer ) . '"/>
2377 - </svg>';
2378 -
2379 - // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on"
2380 - if ($floor_plan_direction_indicator === "on") {
2381 - $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg">
2382 - <path d="M0.454054 1.32433L11.7683 34.3243C11.9069 34.7285 12.287 35 12.7143 35H41.2857C41.713 35 42.0931 34.7285 42.2317 34.3243L53.5459 1.32432C53.7685 0.675257 53.2862 0 52.6 0H1.4C0.713843 0 0.231517 0.675258 0.454054 1.32433Z" fill="url(#paint0_linear_1_10)"/>
2383 - <defs>
2384 - <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse">
2385 - <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/>
2386 - <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/>
2387 - </linearGradient>
2388 - </defs>
2389 - </svg>';
2390 - }
2391 - $html .= '</div>';
2392 - }
2393 - $html .= '</div>';
2394 - //===Floor plan section===//
2395 -
2396 - $html .= '<div class="wpvr-hotspot-tweak-contents-wrapper" style="display: none">';
2397 - $html .= '<i class="fa fa-times cross" data-id="' . esc_attr( $id ) . '"></i>';
2398 - $html .= '<div class="wpvr-hotspot-tweak-contents-flex">';
2399 - $html .= '<div class="wpvr-hotspot-tweak-contents">';
2400 - ob_start();
2401 - do_action('wpvr_hotspot_tweak_contents', $scene_data);
2402 - $hotspot_content = ob_get_clean();
2403 - $html .= $hotspot_content;
2404 - $html .= '</div>';
2405 - $html .= '</div>';
2406 - $html .= '</div>';
2407 -
2408 - $html .= '<div class="custom-ifram-wrapper" style="display: none;">';
2409 - $html .= '<i class="fa fa-times cross" data-id="' . esc_attr( $id ) . '"></i>';
2410 - $html .= '<div class="custom-ifram-flex">';
2411 - $html .= '<div class="custom-ifram">';
2412 - $html .= '</div>';
2413 - $html .= '</div>';
2414 - $html .= '</div>';
2415 - $html .= '</div>';
2416 - $html .= '</div>';
2417 -
2418 -
2419 - if ("fullwidth" == $width) {
2420 - $html .= '</div>';
2421 - }
2422 - if ($status !== false && 'valid' == $status && $is_pro) {
2423 - $call_to_action = isset($postdata['calltoaction']) ? $postdata['calltoaction'] : 'off';
2424 - if ('on' == $call_to_action) {
2425 - $buttontext = isset($postdata['buttontext']) ? $postdata['buttontext'] : '';
2426 - $buttonurl = isset($postdata['buttonurl']) ? $postdata['buttonurl'] : '';
2427 - $cta_btn_style = isset($postdata['button_configuration']) ? $postdata['button_configuration'] : array();
2428 -
2429 - $button_open_new_tab = isset($cta_btn_style['button_open_new_tab']) ? $cta_btn_style['button_open_new_tab'] : "off";
2430 - $target = '_self';
2431 - $button_position = isset($cta_btn_style['button_position']) ? $cta_btn_style['button_position'] : "";
2432 - $background_color = isset($cta_btn_style['button_background_color']) ? $cta_btn_style['button_background_color'] : "";
2433 - $color = isset($cta_btn_style['button_font_color']) ? $cta_btn_style['button_font_color'] : "";
2434 - $font_size = isset($cta_btn_style['button_font_size']) ? $cta_btn_style['button_font_size'] : "";
2435 - $font_weight = isset($cta_btn_style['button_font_weight']) ? $cta_btn_style['button_font_weight'] : "";
2436 - $text_align = isset($cta_btn_style['button_alignment']) ? $cta_btn_style['button_alignment'] : "";
2437 - $text_transform = isset($cta_btn_style['button_transform']) ? $cta_btn_style['button_transform'] : "";
2438 - $font_style = isset($cta_btn_style['button_text_style']) ? $cta_btn_style['button_text_style'] : "";
2439 - $text_decoration = isset($cta_btn_style['button_text_decoration']) ? $cta_btn_style['button_text_decoration'] : "";
2440 - $line_height = isset($cta_btn_style['button_line_height']) ? $cta_btn_style['button_line_height'] : "";
2441 - $letter_spacing = isset($cta_btn_style['button_letter_spacing']) ? $cta_btn_style['button_letter_spacing'] : "";
2442 - $word_spacing = isset($cta_btn_style['button_word_spacing']) ? $cta_btn_style['button_word_spacing'] : "";
2443 -
2444 - $border_width = isset($cta_btn_style['button_border_width']) ? $cta_btn_style['button_border_width'] : "";
2445 - $border_style = isset($cta_btn_style['button_border_style']) ? $cta_btn_style['button_border_style'] : "";
2446 - $border_color = isset($cta_btn_style['button_border_color']) ? $cta_btn_style['button_border_color'] : "";
2447 - $border_radius = isset($cta_btn_style['button_border_radius']) ? $cta_btn_style['button_border_radius'] : "";
2448 -
2449 - $button_pt = isset($cta_btn_style['button_pt']) ? $cta_btn_style['button_pt'] : "";
2450 - $button_pr = isset($cta_btn_style['button_pr']) ? $cta_btn_style['button_pr'] : "";
2451 - $button_pb = isset($cta_btn_style['button_pb']) ? $cta_btn_style['button_pb'] : "";
2452 - $button_pl = isset($cta_btn_style['button_pl']) ? $cta_btn_style['button_pl'] : "";
2453 -
2454 - if ($button_open_new_tab == 'on') {
2455 - $target = '_blank';
2456 - }
2457 - $style = 'background-color: ' . esc_attr( $background_color ) . ';
2458 - color: ' . esc_attr( $color ) . ';
2459 - font-size: ' . esc_attr( $font_size ) . 'px;
2460 - font-weight: ' . esc_attr( $font_weight ) . ';
2461 - text-align: center;
2462 - display: inline-block;
2463 - text-transform: ' . esc_attr( $text_transform ) . ';
2464 - font-style: ' . esc_attr( $font_style ) . ';
2465 - text-decoration: ' . esc_attr( $text_decoration ) . ';
2466 - line-height: ' . esc_attr( $line_height ) . ';
2467 - letter-spacing: ' . esc_attr( $letter_spacing ) . 'px;
2468 - word-spacing: ' . esc_attr( $word_spacing ) . 'px;
2469 - border: ' . esc_attr( $border_width ) . 'px ' . esc_attr( $border_style ) . ' ' . esc_attr( $border_color ) . ';
2470 - border-radius: ' . esc_attr( $border_radius ). 'px;
2471 - padding: ' . esc_attr( $button_pt ) . 'px ' . esc_attr( $button_pr ) . 'px ' . esc_attr( $button_pb ) . 'px ' . esc_attr( $button_pl ) . 'px;
2472 - ';
2473 - $html .= '<div class="wpvr-call-to-action-button position-' . esc_attr( $text_align ) . '" style="max-width:' . esc_attr( $width ) . esc_attr( $width_unit ) . '">
2474 - <a href="' . esc_url( $buttonurl ) . '" style="' . esc_attr( $style ) . '" target="' . esc_attr( $target ) . '">' . esc_attr( $buttontext ) . '</a>
2475 - </div>';
2476 - }
2477 - }
2478 -
2479 - //script started
2480 -
2481 - $html .= '<script>';
2482 - if (isset($postdata['bg_music']) && $bg_music == 'on' && 'valid' == $status && $is_pro) {
2483 - $html .= '
2484 - var x' . $id . ' = document.getElementById("vrAudio' . $id . '");
2485 -
2486 - var playing' . $id . ' = false;
2487 - var autoplaySupported' . $id . ' = false;
2488 - var alertShown' . $id . ' = false;
2489 - var autoplayChecked' . $id . ' = false;
2490 -
2491 - function playPause' . $id . '() {
2492 - if (playing' . $id . ') {
2493 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2494 - x' . $id . '.pause();
2495 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
2496 - playing' . $id . ' = false;
2497 - } else {
2498 - x' . $id . '.muted = false;
2499 - x' . $id . '.play().then(function() {
2500 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2501 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2502 - playing' . $id . ' = true;
2503 - }).catch(function(e) {
2504 - console.log("Play failed:", e);
2505 - });
2506 - }
2507 - }
2508 -
2509 - function audionEnd' . $id . '() {
2510 - playing' . $id . ' = false;
2511 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2512 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
2513 - }
2514 -
2515 - x' . $id . '.addEventListener("ended", audionEnd' . $id . ');';
2516 -
2517 - if ($autoplay_bg_music == 'on') {
2518 - $html .= '
2519 -
2520 - x' . $id . '.addEventListener("loadeddata", function() {
2521 - if (!autoplayChecked' . $id . ') {
2522 - checkAutoplayStatus' . $id . '();
2523 - }
2524 - });
2525 -
2526 - x' . $id . '.addEventListener("canplay", function() {
2527 - if (!autoplayChecked' . $id . ') {
2528 - checkAutoplayStatus' . $id . '();
2529 - }
2530 - });
2531 -
2532 - x' . $id . '.addEventListener("canplaythrough", function() {
2533 - if (!autoplayChecked' . $id . ') {
2534 - checkAutoplayStatus' . $id . '();
2535 - }
2536 - });
2537 -
2538 - setTimeout(function() {
2539 - if (!autoplayChecked' . $id . ') {
2540 - checkAutoplayStatus' . $id . '();
2541 - }
2542 - }, 1000);
2543 -
2544 - x' . $id . '.addEventListener("play", function() {
2545 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2546 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2547 - playing' . $id . ' = true;
2548 - });
2549 -
2550 - x' . $id . '.addEventListener("pause", function() {
2551 - if (!playing' . $id . ') {
2552 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2553 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
2554 - }
2555 - });
2556 -
2557 - function checkAutoplayStatus' . $id . '() {
2558 - autoplayChecked' . $id . ' = true;
2559 -
2560 - x' . $id . '.muted = true;
2561 - var playPromise = x' . $id . '.play();
2562 -
2563 - if (playPromise !== undefined) {
2564 - playPromise.then(function () {
2565 - if (x' . $id . '.muted || x' . $id . '.volume === 0) {
2566 - handleAutoplayBlocked' . $id . '();
2567 - } else {
2568 - autoplaySupported' . $id . ' = true;
2569 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2570 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2571 - playing' . $id . ' = true;
2572 - }
2573 - }).catch(function () {
2574 - handleAutoplayBlocked' . $id . '();
2575 - });
2576 - } else {
2577 - setTimeout(function () {
2578 - if (x' . $id . '.paused || x' . $id . '.currentTime === 0) {
2579 - handleAutoplayBlocked' . $id . '();
2580 - } else {
2581 - autoplaySupported' . $id . ' = true;
2582 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2583 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2584 - playing' . $id . ' = true;
2585 - }
2586 - }, 300);
2587 - }
2588 - }
2589 -
2590 - function handleAutoplayBlocked' . $id . '() {
2591 - autoplaySupported' . $id . ' = false;
2592 - if (!alertShown' . $id . ') {
2593 - alert("Autoplay is not supported in your browser. Please click the audio button to play music.");
2594 - alertShown' . $id . ' = true;
2595 - }
2596 -
2597 - x' . $id . '.pause();
2598 - x' . $id . '.currentTime = 0;
2599 - x' . $id . '.muted = true;
2600 -
2601 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-up").addClass("fas fa-volume-mute");
2602 - jQuery("#audio_control' . $id . '").attr("data-play", "off");
2603 -
2604 - document.getElementById("pano' . $id . '").addEventListener("click", musicPlay' . $id . ');
2605 - document.addEventListener("touchstart", musicPlay' . $id . ', { once: true });
2606 - document.addEventListener("click", musicPlay' . $id . ', { once: true });
2607 - }
2608 -
2609 - function musicPlay' . $id . '() {
2610 - x' . $id . '.muted = false;
2611 - var playPromise = x' . $id . '.play();
2612 -
2613 - if (playPromise !== undefined) {
2614 - playPromise.then(function () {
2615 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2616 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2617 - playing' . $id . ' = true;
2618 - }).catch(function(e) {
2619 - console.log("Play failed:", e);
2620 - });
2621 - } else {
2622 - setTimeout(function () {
2623 - if (!x' . $id . '.paused) {
2624 - jQuery("#vr-volume' . $id . '").removeClass("fas fa-volume-mute").addClass("fas fa-volume-up");
2625 - jQuery("#audio_control' . $id . '").attr("data-play", "on");
2626 - playing' . $id . ' = true;
2627 - }
2628 - }, 100);
2629 - }
2630 -
2631 - document.getElementById("pano' . $id . '").removeEventListener("click", musicPlay' . $id . ');
2632 - document.removeEventListener("touchstart", musicPlay' . $id . ');
2633 - document.removeEventListener("click", musicPlay' . $id . ');
2634 - }
2635 - ';
2636 - }
2637 - }
2638 - $html .= 'jQuery(document).ready(function() {';
2639 - $html .= 'var response = ' . $response . ';';
2640 - $html .= 'var scenes = response[1];';
2641 - $html .= 'if(scenes) {';
2642 - $html .= 'var scenedata = scenes.scenes;';
2643 - $html .= 'for(var i in scenedata) {';
2644 - $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2645 - $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2646 - $html .= 'if(scenehotspot[i].type === "info") {';
2647 - $html .= ' scenehotspot[i]["clickHandlerFunc"] = function(div, args) { if (typeof window.wpvrhotspot === "function") { window.wpvrhotspot(div, args); } };';
2648 - $html .= '} else if(scenehotspot[i].type === "scene") {';
2649 - $html .= ' scenehotspot[i]["clickHandlerArgs"] = scenehotspot[i]["text"];';
2650 - $status = get_option('wpvr_edd_license_status');
2651 - if ($status !== false && $status == 'valid') {
2652 - $html .='if(typeof wpvr_public !== "undefined" && wpvr_public.is_pro_active) {';
2653 - $html .= ' scenehotspot[i]["clickHandlerFunc"] = function(div, args) { if (typeof wpvrhotspotscene === "function") { wpvrhotspotscene(div, args); } else if (typeof window.wpvrhotspotscene === "function") { window.wpvrhotspotscene(div, args); } };';
2654 - $html .='}';
2655 - }
2656 - $html .= '}';
2657 - if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2658 - } else {
2659 - $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2660 - $html .= 'scenehotspot[i]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };';
2661 - $html .= '}';
2662 - }
2663 - $html .= '}';
2664 - $html .= '}';
2665 - $html .= '}';
2666 - $html .= 'var panoshow' . $id . ';';
2667 - $html .= 'var panoshow2' . $id . ';';
2668 - $html .= 'function initWPVRViewer' . $id . '() {';
2669 - $html .= 'if (typeof pannellum === "undefined" || typeof jQuery === "undefined") { setTimeout(initWPVRViewer' . $id . ', 50); return; }';
2670 - $html .= 'panoshow' . $id . ' = pannellum.viewer(response[0]["panoid"], scenes);';
2671 - $html .= '
2672 - window.wpvrViewers = window.wpvrViewers || {};
2673 - window.wpvrViewers[response[0]["panoid"]] = panoshow' . $id . ';
2674 - document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", {
2675 - detail: { containerId: response[0]["panoid"], viewer: panoshow' . $id . ' }
2676 - }));
2677 - ';
2678 - if ( (float) $scene_fade_duration > 0 ) {
2679 - $html .= '
2680 - panoshow' . $id . '.on("scenechange", function() {
2681 - var fadeImage = document.querySelector("#pano' . $id . ' .pnlm-render-container > .pnlm-fade-img");
2682 - if (fadeImage) {
2683 - fadeImage.style.opacity = "1";
2684 - void fadeImage.offsetWidth;
2685 - }
2686 - });';
2687 - }
2688 - $html .= '
2689 - if(typeof wpvr_public === "undefined" || !wpvr_public.is_pro_active || !wpvr_public.is_license_active) {
2690 - panoshow' . $id . '.on("load", function() {
2691 - jQuery(".pnlm-panorama-info").hide();
2692 - jQuery(".pnlm-compass").hide();
2693 - });
2694 -
2695 - panoshow' . $id . '.on("scenechange", function() {
2696 - jQuery(".pnlm-panorama-info").hide();
2697 - jQuery(".pnlm-compass").hide();
2698 - });
2699 - }';
2700 - $html .= '}';
2701 - $html .= 'initWPVRViewer' . $id . '();';
2702 -
2703 - //===Dplicate mode only for vr mode===//
2704 - $response2 = json_decode($response);
2705 - $response2[1]->compass = false;
2706 - $response2[1]->autoRotate = false;
2707 - $response = json_encode($response2);
2708 - $html .= 'var response_duplicate = ' . $response . ';';
2709 - $html .= 'var scenes_duplicate = response_duplicate[1];';
2710 -
2711 - $html .= 'if(scenes_duplicate) {';
2712 - $html .= 'var scenedata = scenes_duplicate.scenes;';
2713 - $html .= 'for(var i in scenedata) {';
2714 - $html .= 'var scenehotspot = scenedata[i].hotSpots;';
2715 - $html .= 'for(var i = 0; i < scenehotspot.length; i++) {';
2716 - $html .= 'if(scenehotspot[i]["clickHandlerArgs"] != "") {';
2717 - $html .= 'scenehotspot[i]["clickHandlerFunc"] = function(div, args) { if (typeof window.wpvrhotspot === "function") { window.wpvrhotspot(div, args); } };';
2718 - $html .= '}';
2719 - if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") {
2720 - } else {
2721 - $html .= 'if(scenehotspot[i]["createTooltipArgs"] != "") {';
2722 - $html .= 'scenehotspot[i]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };';
2723 - $html .= '}';
2724 - }
2725 - $html .= '}';
2726 - $html .= '}';
2727 - $html .= '}';
2728 - $html .= 'var vr_mode = "off";';
2729 - $status = get_option('wpvr_edd_license_status');
2730 - if ($status !== false && 'valid' == $status && $is_pro) {
2731 - $html .= 'function initWPVRViewer2' . $id . '() {';
2732 - $html .= 'if (typeof pannellum === "undefined" || typeof jQuery === "undefined") { setTimeout(initWPVRViewer2' . $id . ', 50); return; }';
2733 - $html .= 'panoshow2' . $id . ' = pannellum.viewer("pano2' . $id . '", scenes_duplicate);';
2734 - $html .= '
2735 - window.wpvrViewers = window.wpvrViewers || {};
2736 - window.wpvrViewers["pano2' . $id . '"] = panoshow2' . $id . ';
2737 - document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", {
2738 - detail: { containerId: "pano2' . $id . '", viewer: panoshow2' . $id . ' }
2739 - }));
2740 - ';
2741 - $html .= '}';
2742 - $html .= 'initWPVRViewer2' . $id . '();';
2743 -
2744 - // Show Cardboard Mode in Tour
2745 - $html .= '
2746 - var tim;
2747 - var im = 0;
2748 - var active_scene = "' . $default_scene . '";
2749 - var c_time;
2750 - c_time = new Date();
2751 - var timer = c_time.getTime() + 2000;
2752 - function panoShowCardBoardOnTrigger(data){
2753 - if(scenes_duplicate) {
2754 - var scenedata = scenes_duplicate.scenes;
2755 - for(var i in scenedata) {
2756 - if(active_scene === i) {
2757 - var scenehotspot = scenedata[i].hotSpots;
2758 - for(var j in scenehotspot) {
2759 - var plusFiveYaw = Math.round(scenehotspot[j].yaw) + 5;
2760 - var minusFiveYaw = Math.round(scenehotspot[j].yaw) - 5;
2761 - var plusFivePitch = Math.round(scenehotspot[j].pitch) + 5;
2762 - var minusFivePitch = Math.round(scenehotspot[j].pitch) - 5;
2763 - var firstCondition = ( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ;
2764 - var secCondition = (Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw);
2765 - if(( Math.round(data.pitch) > minusFivePitch) && (Math.round(data.pitch) < plusFivePitch) ){
2766 - if((Math.round(data.yaw) > minusFiveYaw) && (Math.round(data.yaw) < plusFiveYaw)){
2767 - jQuery(".center-pointer").addClass("wpvr-pluse-effect")
2768 - var getScene = scenehotspot[j].sceneId;
2769 - if(scenehotspot[j].type == "scene"){
2770 - panoshow' . $id . '.loadScene(getScene);
2771 - panoshow2' . $id . '.loadScene(getScene);
2772 -// var inside_current_time_object = new Date();
2773 -// var inside_timer = inside_current_time_object.getTime();
2774 -// if(inside_timer > timer) {
2775 -// panoshow' . $id . '.loadScene(getScene);
2776 -// panoshow2' . $id . '.loadScene(getScene);
2777 -// jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2778 -// }
2779 - }else{
2780 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2781 - }
2782 - }
2783 - else {
2784 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2785 - c_time = new Date();
2786 - timer = c_time.getTime() + 2000;
2787 - }
2788 - }
2789 - else {
2790 - c_time = new Date();
2791 - timer = c_time.getTime() + 2000;
2792 - }
2793 - }
2794 - }
2795 - }
2796 - }
2797 - };
2798 -
2799 - function vrDeviseOrientation(){
2800 - var data = {
2801 - pitch: panoshow' . $id . '.getPitch(),
2802 - yaw: panoshow' . $id . '.getYaw(),
2803 - };
2804 - panoShowCardBoardOnTrigger(data);
2805 - }
2806 - ';
2807 - $html .= '
2808 -
2809 - function requestFullScreen(){
2810 - var elem = document.getElementById("master-container");
2811 - if (elem.requestFullscreen) {
2812 - elem.requestFullscreen();
2813 - } else if (elem.webkitRequestFullscreen) { /* Safari */
2814 - elem.webkitRequestFullscreen();
2815 - } else if (elem.msRequestFullscreen) { /* IE11 */
2816 - elem.msRequestFullscreen();
2817 - }
2818 - }
2819 - function requestExitFullscreen(){
2820 - var elem = document.getElementById("master-container");
2821 - if (document.exitFullscreen) {
2822 - document.exitFullscreen();
2823 - } else if (document.webkitExitFullscreen) { /* Safari */
2824 - document.webkitExitFullscreen();
2825 - } else if (document.msExitFullscreen) { /* IE11 */
2826 - document.msExitFullscreen();
2827 - }
2828 - }
2829 - jQuery(document).on("click",".fullscreen-button .expand",function() {
2830 - jQuery(this).hide()
2831 - jQuery(this).parent().find(".compress").show()
2832 - requestFullScreen()
2833 - screen.orientation.lock("landscape-primary")
2834 - .then(function() {
2835 - })
2836 - .catch(function(error) {
2837 - alert("Not Supported for this devise");
2838 - });
2839 -
2840 - });
2841 - jQuery(document).on("click",".fullscreen-button .compress",function() {
2842 - jQuery(this).hide()
2843 - jQuery(this).parent().find(".expand").show()
2844 - requestExitFullscreen()
2845 - screen.orientation.unlock();
2846 -
2847 - });
2848 -
2849 - let onLoadAnalytics = false;
2850 - let sceneLoadAnalytics = false;
2851 - function storeAnalyticsData(data) {
2852 - if(typeof wpvr_public !== "undefined" && wpvr_public.is_pro_active) {
2853 - jQuery.ajax({
2854 - url: wpvrAnalyticsObj.ajaxUrl,
2855 - type: "POST",
2856 - data: {
2857 - action: "store_scene_hotspot_data",
2858 - scene_id: data.scene_id,
2859 - tour_id: data.tour_id,
2860 - type: data.type,
2861 - hotspot_id: data.hotspot_id || "",
2862 - user_agent: navigator.userAgent,
2863 - device_type: getDeviceType() || "desktop",
2864 - nonce: wpvrAnalyticsObj.nonce,
2865 - },
2866 - success: function (response) {
2867 - console.log("Data stored successfully");
2868 - },
2869 - error: function (error) {
2870 - console.log("Error in storing data");
2871 - }
2872 - });
2873 - }
2874 - }
2875 -
2876 - function getDeviceType() {
2877 - const userAgent = navigator.userAgent.toLowerCase();
2878 -
2879 - if (/mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)) {
2880 - return "mobile";
2881 - } else if (/tablet|ipad/i.test(userAgent)) {
2882 - return "tablet";
2883 - } else {
2884 - return "desktop";
2885 - }
2886 - }
2887 -
2888 - panoshow' . $id . '.on("scenechange", function(scene) {
2889 - onLoadAnalytics = true;
2890 - sceneLoadAnalytics = true;
2891 - let scene_id = scene;
2892 - let tour_id = ' . $id . ';
2893 - let type = "scene";
2894 - let hotspot_id = "";
2895 - let user_agent = navigator.userAgent;
2896 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2897 - storeAnalyticsData({
2898 - scene_id: scene_id,
2899 - tour_id: tour_id,
2900 - type: type,
2901 - hotspot_id: hotspot_id,
2902 - user_agent: user_agent,
2903 - device_type: device_type,
2904 - });
2905 - if(typeof wpvr_public === "undefined" || !wpvr_public.is_pro_active) {
2906 - jQuery(".pnlm-panorama-info").hide();
2907 - setTimeout(function() {
2908 - jQuery(".pnlm-panorama-info").each(function() {
2909 - jQuery(this).hide();
2910 - });
2911 - }, 500);
2912 - }
2913 - });
2914 -
2915 - panoshow' . $id . '.on("load", function() {
2916 - let scene_id = panoshow' . $id . '.getScene();
2917 - let tour_id = ' . $id . ';
2918 - let type = "scene";
2919 - let hotspot_id = "";
2920 - let user_agent = navigator.userAgent;
2921 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2922 - if(!onLoadAnalytics && !sceneLoadAnalytics){
2923 - storeAnalyticsData({
2924 - scene_id: scene_id,
2925 - tour_id: tour_id,
2926 - type: type,
2927 - hotspot_id: hotspot_id,
2928 - user_agent: user_agent,
2929 - device_type: device_type,
2930 - });
2931 - }
2932 - if(typeof wpvr_public === "undefined" || !wpvr_public.is_pro_active) {
2933 - jQuery(".pnlm-panorama-info").hide();
2934 - setTimeout(function() {
2935 - jQuery(".pnlm-panorama-info").each(function() {
2936 - jQuery(this).hide();
2937 - });
2938 - }, 500);
2939 - }
2940 - })
2941 -
2942 - function wpvrhotspotscene(hotSpotDiv, args) {
2943 - onLoadAnalytics = true;
2944 - let scene_id = panoshow' . $id . '.getScene();
2945 - let tour_id = ' . $id . ';
2946 - let type = "hotspot";
2947 - let hotspot_id = args;
2948 - let user_agent = navigator.userAgent;
2949 - let device_type = getDeviceType() ? getDeviceType() : "desktop";
2950 - storeAnalyticsData({
2951 - scene_id: scene_id,
2952 - tour_id: tour_id,
2953 - type: type,
2954 - hotspot_id: hotspot_id,
2955 - user_agent: user_agent,
2956 - device_type: device_type
2957 - });
2958 - }';
2959 -
2960 - $html .= '
2961 - panoshow' . $id . '.on("scenechange", function (scene){
2962 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
2963 - active_scene = scene;
2964 - });
2965 - var compassBlock = "";
2966 - var infoBlock = "";
2967 - var getValue = "";
2968 - jQuery(document).on("click",".vr_mode_change' . $id . '",function (){
2969 -
2970 - jQuery("#pano2' . $id . ' .pnlm-load-button").trigger("click");
2971 - jQuery("#pano' . $id . ' .pnlm-load-button").trigger("click");
2972 -
2973 - getValue = jQuery(this).val();
2974 - var getParent = jQuery(this).parent().parent();
2975 - var fullWidthParent = getParent.parent();
2976 - var compass = getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display");
2977 - var panoInfo = getParent.find("#pano' . $id . ' .pnlm-panorama-info").css("display");
2978 - if(compass == "block"){
2979 - compassBlock = "block";
2980 - }
2981 - if(panoInfo == "block"){
2982 - infoBlock = "block";
2983 - }
2984 - if (getValue == "off") {
2985 - requestFullScreen()
2986 - screen.orientation.lock("landscape-primary")
2987 - .then(function() {
2988 - })
2989 - .catch(function(error) {
2990 - alert("VR Glass Mode not supported in this device");
2991 - });
2992 - getParent.find(".pano-wrap").addClass("wpvr-cardboard-disable-event");
2993 - // localStorage.setItem("vr_mode", "on");
2994 - vr_mode = "on";
2995 - jQuery(".vr-mode-title").show();
2996 - jQuery(this).val("on");
2997 - getParent.find("#pano2' . $id . '").css({
2998 - "opacity": "1",
2999 - "visibility": "visible",
3000 - "position": "relative",
3001 - });
3002 - gyroSwitch = true;
3003 - panoshow' . $id . '.startOrientation();
3004 - panoshow2' . $id . '.startOrientation();
3005 - panoshow2' . $id . '.setPitch(panoshow' . $id . '.getPitch(), 0);
3006 - panoshow2' . $id . '.setYaw(panoshow' . $id . '.getYaw(), 0);
3007 - getParent.find("#pano' . $id . ' #zoom-in-out-controls' . $id . '").hide();
3008 - getParent.find("#pano' . $id . ' #controls' . $id . '").hide();
3009 - getParent.find("#pano' . $id . ' #explainer_button_' . $id . '").hide();
3010 - getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").hide();
3011 - getParent.find("#pano' . $id . ' #floor_map_button_' . $id . '").hide();
3012 - getParent.find("#pano' . $id . ' #vrgcontrols' . $id . '").hide();
3013 - getParent.find("#pano' . $id . ' #sccontrols' . $id . '").hide();
3014 - getParent.find("#pano' . $id . ' #adcontrol' . $id . '").hide();
3015 - getParent.find("#pano' . $id . ' .owl-nav.wpvr_slider_nav").hide();
3016 - getParent.find("#pano' . $id . ' #cp-logo-controls").hide();
3017 -
3018 - getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").hide();
3019 -
3020 - getParent.find("#pano2' . $id . ' .pnlm-controls-container").hide();
3021 - getParent.find("#pano' . $id . ' .pnlm-controls-container").hide();
3022 -
3023 - getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
3024 - getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").hide();
3025 -
3026 - getParent.find("#pano2' . $id . ' .pnlm-panorama-info").hide();
3027 - getParent.find("#pano' . $id . ' .pnlm-panorama-info").hide();
3028 - getParent.find("#pano' . $id . '").addClass("cardboard-half");
3029 -
3030 - getParent.find("#center-pointer' . $id . '").show();
3031 - getParent.find(".fullscreen-button").hide();
3032 -
3033 -
3034 - if (window.DeviceOrientationEvent) {
3035 - window.addEventListener("deviceorientation", vrDeviseOrientation);
3036 - }
3037 -
3038 - panoshow' . $id . '.on("mousemove", function (data){
3039 - panoshow2' . $id . '.setPitch(data.pitch, 0);
3040 - panoshow2' . $id . '.setYaw(data.yaw, 0);
3041 - panoShowCardBoardOnTrigger(data);
3042 -
3043 - });
3044 - panoshow2' . $id . '.on("mousemove", function (data){
3045 - panoshow2' . $id . '.setPitch(data.pitch, 0);
3046 - panoshow' . $id . '.setYaw(data.yaw, 0);
3047 - panoShowCardBoardOnTrigger(data);
3048 -
3049 - });
3050 -
3051 - panoshow' . $id . '.on("zoomchange", function (data){
3052 - panoshow2' . $id . '.setHfov(data, 0);
3053 - });
3054 -
3055 - panoshow2' . $id . '.on("zoomchange", function (data){
3056 - panoshow' . $id . '.setHfov(data, 0);
3057 - });
3058 -
3059 - panoshow' . $id . '.on("touchmove", function (data){
3060 - panoshow' . $id . '.stopOrientation();
3061 - panoshow2' . $id . '.stopOrientation();
3062 - panoshow2' . $id . '.setPitch(data.pitch, 0);
3063 - panoshow2' . $id . '.setYaw(data.yaw, 0);
3064 - panoShowCardBoardOnTrigger(data);
3065 -
3066 - });
3067 -
3068 - panoshow2' . $id . '.on("touchmove", function (data){
3069 - panoshow' . $id . '.stopOrientation();
3070 - panoshow2' . $id . '.stopOrientation();
3071 - panoshow' . $id . '.setPitch(data.pitch, 0);
3072 - panoshow' . $id . '.setYaw(data.yaw, 0);
3073 - panoShowCardBoardOnTrigger(data);
3074 -
3075 - });
3076 -
3077 - }
3078 - else if(getValue == "on") {
3079 - screen.orientation.unlock();
3080 - requestExitFullscreen();
3081 - // localStorage.setItem("vr_mode", "off");
3082 - vr_mode = "off";
3083 - jQuery(".vr-mode-title").hide();
3084 - jQuery(this).val("off");
3085 - getParent.find("#pano2' . $id . '").css({
3086 - "opacity": "0",
3087 - "visibility": "hidden",
3088 - "position": "absolute",
3089 - });
3090 - panoshow' . $id . '.stopOrientation();
3091 - panoshow2' . $id . '.stopOrientation();
3092 - getParent.find(".pano-wrap").removeClass("wpvr-cardboard-disable-event");
3093 - getParent.find("#pano' . $id . ' #zoom-in-out-controls' . $id . '").show();
3094 - getParent.find("#pano' . $id . ' #controls' . $id . '").show();
3095 - getParent.find("#pano' . $id . ' #explainer_button_' . $id . '").show();
3096 - getParent.find("#pano' . $id . ' #generic_form_button_' . $id . '").show();
3097 - getParent.find("#pano' . $id . ' #floor_map_button_' . $id . '").show();
3098 -
3099 - getParent.find("#pano2' . $id . ' .pnlm-controls-container").show();
3100 - getParent.find("#pano' . $id . ' .pnlm-controls-container").show();
3101 - getParent.find("#pano' . $id . ' #vrgcontrols' . $id . '").show();
3102 - getParent.find("#pano' . $id . ' #sccontrols' . $id . '").hide();
3103 - getParent.find("#pano' . $id . ' #adcontrol' . $id . '").show();
3104 - getParent.find("#pano' . $id . ' .owl-nav.wpvr_slider_nav").hide();
3105 - getParent.find("#pano' . $id . ' #cp-logo-controls").show();
3106 - getParent.find("#pano' . $id . ' #custom-scene-navigation' . $id . '").show();
3107 -
3108 - if(compassBlock == "block"){
3109 - getParent.find("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
3110 - getParent.find("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").show();
3111 - }
3112 - if(infoBlock == "block"){
3113 - getParent.find("#pano2' . $id . ' .pnlm-panorama-info").show();
3114 - getParent.find("#pano' . $id . ' .pnlm-panorama-info").show();
3115 - }
3116 -
3117 - getParent.find("#pano' . $id . '").removeClass("cardboard-half");
3118 - getParent.find("#center-pointer' . $id . '").hide();
3119 - getParent.find(".fullscreen-button").hide();
3120 - panoshow' . $id . '.off("mousemove");
3121 - panoshow' . $id . '.off("touchmove");
3122 - panoshow2' . $id . '.off("mousemove");
3123 - panoshow2' . $id . '.off("touchmove");
3124 - if (window.DeviceOrientationEvent) {
3125 - window.removeEventListener("deviceorientation", vrDeviseOrientation);
3126 - }
3127 - }
3128 - });';
3129 -
3130 - $html .= 'panoshow2' . $id . '.on("load", function (){
3131 -// if(localStorage.getItem("vr_mode") == "off") {
3132 - if( vr_mode == "off") {
3133 - jQuery(".vr-mode-title").hide();
3134 - }
3135 - else {
3136 - jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
3137 - jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
3138 - jQuery("#pano2' . $id . ' .pnlm-panorama-info").hide();
3139 - jQuery("#pano' . $id . ' .pnlm-panorama-info").hide();
3140 - jQuery(".vr-mode-title").show();
3141 - }
3142 - });';
3143 - }
3144 -
3145 - $html .= 'jQuery("#pano' . $id . ' .wpvr-floor-map .floor-plan-pointer").on("click",function(){
3146 - var scene_id = jQuery(this).attr("scene_id");
3147 - panoshow' . $id . '.loadScene(scene_id)
3148 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
3149 - jQuery(this).addClass("add-pulse")
3150 - });';
3151 -
3152 - if ($scene_animation_enabled && is_plugin_active('wpvr-pro/wpvr-pro.php') ) {
3153 - $animation_js = apply_filters('wpvr_scene_animation_js', $id, $animation_type, $animationDuration, $animationDelay);
3154 - if (!empty($animation_js)) {
3155 - $html .= $animation_js;
3156 - $html .= 'panoshow' . $id . '.on("load", function (scene){
3157 - if (typeof changeScene === "function") {
3158 - changeScene();
3159 - } else {
3160 - console.warn("changeScene function is not defined.");
3161 - }
3162 - });';
3163 - }
3164 - }
3165 -
3166 -
3167 - $html .= '
3168 - panoshow' . $id . '.on("mousemove", function (data){
3169 - jQuery(".add-pulse").css({"transform":"rotate("+data.yaw+"deg)"});
3170 - });
3171 -';
3172 -
3173 -
3174 -
3175 - $status = get_option('wpvr_edd_license_status');
3176 - if ($status !== false && 'valid' == $status && $is_pro) {
3177 - $html .= 'panoshow' . $id . '.on("scenechange", function (scene){
3178 - jQuery(".center-pointer").removeClass("wpvr-pluse-effect")
3179 - jQuery(".floor-plan-pointer").each(function(index ,element){
3180 - var scene_id = jQuery(this).attr("scene_id");
3181 - if( active_scene == scene_id ){
3182 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
3183 - jQuery(this).addClass("add-pulse")
3184 - }
3185 - });
3186 -
3187 - });';
3188 - $html .= 'panoshow' . $id . '.on("load", function (){
3189 - if(jQuery(".floor-plan-pointer").length > 0){
3190 - jQuery(".floor-plan-pointer").each(function(index ,element){
3191 - var scene_id = jQuery(this).attr("scene_id");
3192 - if( active_scene == scene_id ){
3193 - jQuery(".floor-plan-pointer").removeClass("add-pulse")
3194 - jQuery(this).addClass("add-pulse")
3195 - }
3196 - });
3197 - }
3198 - });';
3199 - }
3200 -
3201 - if ($status !== false && 'valid' == $status && $is_pro) {
3202 - $scene_navigation_content_type = isset($postdata['scene_navigation_content_type']) ? $postdata['scene_navigation_content_type'] : 'scene_id';
3203 - $html .= '
3204 - jQuery("#pano' . $id . ' .custom-scene-navigation").on("click",function(){
3205 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").empty()
3206 - if(scenes){
3207 - var scene_navigation_content_type = ' . "'" . $scene_navigation_content_type . "'" . ';
3208 - var sceneList = scenes.scenes;
3209 - var getScene = panoshow' . $id . '.getScene();
3210 - for (const key in sceneList) {
3211 - let title;
3212 - if (scene_navigation_content_type === "scene_title") {
3213 - if (sceneList[key].title) {
3214 - title = sceneList[key].title;
3215 -
3216 - }else{
3217 - if(title == "" || title == undefined){
3218 - if (sceneList[key].panorama) {
3219 - title = getImageNameWithoutExtension(sceneList[key].panorama);
3220 - }
3221 - }
3222 - }
3223 - } else if (scene_navigation_content_type === "scene_image_name") {
3224 - if (sceneList[key].panorama) {
3225 - title = getImageNameWithoutExtension(sceneList[key].panorama);
3226 - }
3227 - } else {
3228 - title = key;
3229 - }
3230 - if (sceneList.hasOwnProperty(key)) {
3231 - if( key === getScene){
3232 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").append("<li class=\"scene-navigation-list active\" scene_id= " + key + " >" + title + "</li>");
3233 - }else{
3234 - jQuery("#custom-scene-navigation-nav' . $id . ' ul").append("<li class=\"scene-navigation-list\" scene_id= " + key + " >" + title + "</li>");
3235 - }
3236 - }
3237 - }
3238 - }
3239 - jQuery("#custom-scene-navigation-nav' . $id . '").toggleClass("visible");
3240 - });
3241 - ';
3242 -
3243 - $html .= 'function getImageNameWithoutExtension(imageUrl) {
3244 - // Split the URL by "/"
3245 - var parts = imageUrl.split("/");
3246 -
3247 - // Get the last part which contains the image name
3248 - var imageNameWithExtension = parts[parts.length - 1];
3249 -
3250 - // Split the image name by period (.)
3251 - var imageNameParts = imageNameWithExtension.split(".");
3252 -
3253 - // Remove the last part (which is the extension) and join the remaining parts
3254 - var imageNameWithoutExtension = imageNameParts.slice(0, -1).join(".");
3255 -
3256 - // Return the image name without extension
3257 - return imageNameWithoutExtension;
3258 - }';
3259 -
3260 -
3261 - $html .= '
3262 - jQuery("#pano' . $id . ' #custom-scene-navigation-nav' . $id . ' ul").on("click", "li.scene-navigation-list", function() {
3263 - if (scenes) {
3264 - jQuery(this).siblings("li").removeClass("active");
3265 - jQuery(this).addClass("active");
3266 -
3267 - var scene_key = jQuery(this).attr("scene_id");
3268 - panoshow' . $id . '.loadScene(scene_key);
3269 - }
3270 - });
3271 - ';
3272 - }
3273 -
3274 - //Duplicate mode only for vr mode end===//
3275 - $html .= 'panoshow' . $id . '.on("load", function (){
3276 -
3277 -// if(localStorage.getItem("vr_mode") == "off") {
3278 - if( vr_mode == "off") {
3279 - jQuery(".vr-mode-title").hide();
3280 - }
3281 - else {
3282 - jQuery("#pano2' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
3283 - jQuery("#pano' . $id . ' .pnlm-compass.pnlm-controls.pnlm-control").css("display","none");
3284 - jQuery("#pano2' . $id . ' .pnlm-panorama-info").hide();
3285 - jQuery("#pano' . $id . ' .pnlm-panorama-info").hide();
3286 - jQuery(".vr-mode-title").show();
3287 - }
3288 -
3289 -
3290 - if (jQuery("#pano' . $id . '").children().children(".pnlm-panorama-info:visible").length > 0) {
3291 - jQuery("#controls' . $id . '").css("bottom", "80px");
3292 - }
3293 - else {
3294 - jQuery("#controls' . $id . '").css("bottom", "5px");
3295 - }
3296 - });';
3297 -
3298 -
3299 - $html .= '
3300 - if (scenes.autoRotate) {
3301 - var wpvrAutoRotateTimer' . $id . ' = null;
3302 - var wpvrAutoRotateStopDelay' . $id . ' = parseInt(scenes.autoRotateStopDelay, 10) || 0;
3303 - var wpvrScheduleAutoRotate' . $id . ' = function () {
3304 - clearTimeout(wpvrAutoRotateTimer' . $id . ');
3305 - if (wpvrAutoRotateStopDelay' . $id . ' > 0) {
3306 - wpvrAutoRotateTimer' . $id . ' = setTimeout(function () {
3307 - panoshow' . $id . '.stopAutoRotate();
3308 - }, wpvrAutoRotateStopDelay' . $id . ');
3309 - } else {
3310 - wpvrAutoRotateTimer' . $id . ' = setTimeout(function () {
3311 - panoshow' . $id . '.startAutoRotate(scenes.autoRotate, 0);
3312 - }, 3000);
3313 - }
3314 - };
3315 - panoshow' . $id . '.on("load", wpvrScheduleAutoRotate' . $id . ');
3316 - panoshow' . $id . '.on("scenechange", wpvrScheduleAutoRotate' . $id . ');
3317 - }
3318 - ';
3319 - $html .= 'var touchtime = 0;';
3320 - if ($vrgallery) {
3321 - if (isset($panodata["scene-list"])) {
3322 - foreach ($panodata["scene-list"] as $panoscenes) {
3323 - $scene_key = $panoscenes['scene-id'];
3324 - $scene_key_gallery = $panoscenes['scene-id'] . '_gallery_' . $id;
3325 - $img_src_url = $panoscenes['scene-attachment-url'];
3326 - // $html .= 'document.getElementById("' . $scene_key_gallery . '").addEventListener("click", function(e) { ';
3327 - // $html .= 'if (touchtime == 0) {';
3328 - // $html .= 'touchtime = new Date().getTime();';
3329 - // $html .= '} else {';
3330 - // $html .= 'if (((new Date().getTime()) - touchtime) < 800) {';
3331 - // $html .= 'panoshow' . $id . '.loadScene("' . $scene_key . '");';
3332 - // $html .= 'touchtime = 0;';
3333 - // $html .= '} else {';
3334 - // $html .= 'touchtime = new Date().getTime();';
3335 - // $html .= '}';
3336 - // $html .= '}';
3337 - // $html .= '});';
3338 - $html .= '
3339 - jQuery(document).on("click","#' . $scene_key_gallery . '",function() {
3340 - panoshow' . $id . '.loadScene("' . $scene_key . '");
3341 - });
3342 - ';
3343 - }
3344 - }
3345 -
3346 - $html .= '
3347 - var owlGallery' . $id . ' = jQuery("#sccontrols' . $id . '").owlCarousel({
3348 - items: 1,
3349 - loop: true,
3350 - nav: false,
3351 - dots: false,
3352 - margin: 5,
3353 - stagePadding: 30
3354 - });
3355 - jQuery("#pano' . $id . '").on("click", ".wpvr_owl_prev", function() {
3356 - owlGallery' . $id . '.trigger("prev.owl.carousel");
3357 - });
3358 - jQuery("#pano' . $id . '").on("click", ".wpvr_owl_next", function() {
3359 - owlGallery' . $id . '.trigger("next.owl.carousel");
3360 - });
3361 - ';
3362 - }
3363 -
3364 -
3365 -
3366 - //===Custom Control===//
3367 - if (isset($custom_control)) {
3368 - if ($custom_control['panupSwitch'] == "on" && $status == 'valid' && $is_pro) {
3369 - $html .= 'document.getElementById("pan-up' . $id . '").addEventListener("click", function(e) {';
3370 - $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() + 10);';
3371 - $html .= '});';
3372 - }
3373 -
3374 - if ($custom_control['panDownSwitch'] == "on" && $status == 'valid' && $is_pro) {
3375 - $html .= 'document.getElementById("pan-down' . $id . '").addEventListener("click", function(e) {';
3376 - $html .= 'panoshow' . $id . '.setPitch(panoshow' . $id . '.getPitch() - 10);';
3377 - $html .= '});';
3378 - }
3379 -
3380 - if ($custom_control['panLeftSwitch'] == "on" && $status == 'valid' && $is_pro) {
3381 - $html .= 'document.getElementById("pan-left' . $id . '").addEventListener("click", function(e) {';
3382 - $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() - 10);';
3383 - $html .= '});';
3384 - }
3385 -
3386 - if ($custom_control['panRightSwitch'] == "on" && $status == 'valid' && $is_pro) {
3387 - $html .= 'document.getElementById("pan-right' . $id . '").addEventListener("click", function(e) {';
3388 - $html .= 'panoshow' . $id . '.setYaw(panoshow' . $id . '.getYaw() + 10);';
3389 - $html .= '});';
3390 - }
3391 -
3392 - if ($custom_control['panZoomInSwitch'] == "on") {
3393 - $html .= 'document.getElementById("zoom-in' . $id . '").addEventListener("click", function(e) {';
3394 - $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() - 10);';
3395 - $html .= '});';
3396 - }
3397 -
3398 - if ($custom_control['panZoomOutSwitch'] == "on") {
3399 - $html .= 'document.getElementById("zoom-out' . $id . '").addEventListener("click", function(e) {';
3400 - $html .= 'panoshow' . $id . '.setHfov(panoshow' . $id . '.getHfov() + 10);';
3401 - $html .= '});';
3402 - }
3403 -
3404 - if ($custom_control['panFullscreenSwitch'] == "on" && $status == 'valid' && $is_pro) {
3405 - $html .= 'document.getElementById("fullscreen' . $id . '").addEventListener("click", function(e) {';
3406 - $html .= 'panoshow' . $id . '.toggleFullscreen();';
3407 - $html .= '});';
3408 - $html .= '(function() {';
3409 - $html .= 'function wpvrFsChange' . $id . '() {';
3410 - $html .= 'var fsIcon = document.querySelector("#fullscreen' . $id . ' i");';
3411 - $html .= 'if (!fsIcon) return;';
3412 - $html .= 'if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) {';
3413 - $html .= 'fsIcon.classList.remove("fa-expand"); fsIcon.classList.add("fa-minimize");';
3414 - $html .= '} else {';
3415 - $html .= 'fsIcon.classList.remove("fa-minimize"); fsIcon.classList.add("fa-expand");';
3416 - $html .= '}';
3417 - $html .= '}';
3418 - $html .= 'document.addEventListener("fullscreenchange", wpvrFsChange' . $id . ');';
3419 - $html .= 'document.addEventListener("webkitfullscreenchange", wpvrFsChange' . $id . ');';
3420 - $html .= 'document.addEventListener("mozfullscreenchange", wpvrFsChange' . $id . ');';
3421 - $html .= 'document.addEventListener("MSFullscreenChange", wpvrFsChange' . $id . ');';
3422 - $html .= '})();';
3423 - }
3424 -
3425 - if ($custom_control['backToHomeSwitch'] == "on" && $status == 'valid' && $is_pro) {
3426 - $html .= 'document.getElementById("backToHome' . $id . '").addEventListener("click", function(e) {';
3427 - $html .= 'panoshow' . $id . '.loadScene("' . $default_scene . '");';
3428 - $html .= '});';
3429 - }
3430 -
3431 - if ($gyro_button_enabled && 'valid' == $status && $is_pro) {
3432 - $html .= '
3433 - (function() {
3434 - var gyroButton = document.getElementById("gyroscope' . $id . '");
3435 - var gyroIcon = gyroButton ? gyroButton.querySelector("i") : null;
3436 - var activeColor = ' . wp_json_encode($custom_control['gyroscopeColor']) . ';
3437 - var permissionGranted = false;
3438 -
3439 - if (!gyroButton || !gyroIcon) {
3440 - return;
3441 - }
3442 -
3443 - function updateGyroscopeState() {
3444 - gyroIcon.style.color = panoshow' . $id . '.isOrientationActive()
3445 - ? activeColor
3446 - : "red";
3447 - }
3448 -
3449 - function startGyroscope() {
3450 - if (!panoshow' . $id . '.isOrientationSupported()) {
3451 - updateGyroscopeState();
3452 - return;
3453 - }
3454 -
3455 - panoshow' . $id . '.startOrientation();
3456 - window.setTimeout(updateGyroscopeState, 0);
3457 - }
3458 -
3459 - function requestGyroscopePermission() {
3460 - var orientationEvent = window.DeviceOrientationEvent;
3461 - if (orientationEvent) {
3462 - if (typeof orientationEvent.requestPermission === "function") {
3463 - if (!permissionGranted) {
3464 - orientationEvent.requestPermission()
3465 - .then(function(state) {
3466 - permissionGranted = state === "granted";
3467 - if (permissionGranted) {
3468 - startGyroscope();
3469 - } else {
3470 - updateGyroscopeState();
3471 - }
3472 - })
3473 - .catch(updateGyroscopeState);
3474 - return;
3475 - }
3476 - }
3477 - }
3478 -
3479 - startGyroscope();
3480 - }
3481 -
3482 - panoshow' . $id . '.on("load", updateGyroscopeState);
3483 - panoshow' . $id . '.on("scenechange", updateGyroscopeState);
3484 -
3485 - gyroButton.addEventListener("click", function() {
3486 - if (panoshow' . $id . '.isOrientationActive()) {
3487 - panoshow' . $id . '.stopOrientation();
3488 - updateGyroscopeState();
3489 - return;
3490 - }
3491 -
3492 - requestGyroscopePermission();
3493 - });
3494 - })();';
3495 - }
3496 - }
3497 -
3498 - $angle_up = '<i class="fa fa-angle-up"></i>';
3499 - $angle_down = '<i class="fa fa-angle-down"></i>';
3500 - $sin_qout = "'";
3501 -
3502 - //===Explainer Script===//
3503 - $html .= '
3504 - jQuery(document).on("click","#explainer_button_' . $id . '",function() {
3505 - jQuery("#explainer' . $id . '").slideToggle(function(){
3506 - var $explainerVideoId = jQuery("#explainer' . $id . '");
3507 - var $explainerVideoIframe = $explainerVideoId.find("iframe");
3508 - var explainerVideoIframSrc = $explainerVideoIframe.attr("src");
3509 - $explainerVideoIframe.attr("src", "");
3510 - $explainerVideoIframe.attr("src", explainerVideoIframSrc);
3511 - });
3512 - });
3513 -
3514 - jQuery(document).on("click", ".close-explainer-video", function() {
3515 - var $explainer = jQuery(this).parent(".explainer");
3516 - var $iframe = $explainer.find("iframe");
3517 - var src = $iframe.attr("src");
3518 - $iframe.attr("src", "");
3519 - $explainer.hide();
3520 - $iframe.attr("src", src);
3521 - });
3522 -
3523 - jQuery(document).on("click","#pano' . $id . '",function(event) {
3524 - var isActiveModal = event.target.closest(".custom-ifram-wrapper");
3525 - var isForm = event.target.closest(".wpvr-hotspot-tweak-contents");
3526 - var isHotspot = event.target.closest(".pnlm-hotspot-base");
3527 - if( isActiveModal == null && isForm == null && isHotspot == null){
3528 - jQuery(".custom-ifram-wrapper .custom-ifram").empty();
3529 - jQuery(".custom-ifram-wrapper").hide();
3530 - jQuery(this).removeClass("show-modal");
3531 - jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide("show-modal");
3532 - }else if(isForm != null){
3533 - jQuery(this).addClass("show-modal");
3534 - }
3535 - });
3536 -
3537 - ';
3538 - //===Explainer Script End===//
3539 -
3540 - //===generic form script===//
3541 - if (isset($postdata["genericform"]) && $postdata["genericform"] === 'on') {
3542 - $html .= '
3543 - jQuery(document).on("click","#generic_form_button_' . $id . '",function() {
3544 - jQuery("#wpvr-generic-form' . $id . '").fadeToggle();
3545 - });
3546 -
3547 - jQuery(document).on("click",".close-generic-form",function() {
3548 - jQuery(this).parent(".wpvr-generic-form").fadeOut()
3549 - });
3550 - ';
3551 - }
3552 -
3553 - //===generic from script===//
3554 -
3555 - //===Floor map Script===//
3556 - $html .= '
3557 - jQuery(document).on("click","#floor_map_button_' . $id . '",function() {
3558 - jQuery("#wpvr-floor-map' . $id . '").toggle().removeClass("fullwindow");
3559 - });
3560 -
3561 - jQuery(document).on("dblclick","#wpvr-floor-map' . $id . '",function(){
3562 - jQuery(this).addClass("fullwindow");
3563 - jQuery(this).parents(".pano-wrap").addClass("show-modal");
3564 - });
3565 -
3566 - jQuery(document).on("click",".close-floor-map-plan",function() {
3567 - jQuery(this).parent(".wpvr-floor-map").hide();
3568 - jQuery(this).parent(".wpvr-floor-map").removeClass("fullwindow");
3569 - jQuery(this).parents(".pano-wrap").removeClass("show-modal");
3570 - });
3571 -
3572 - ';
3573 - //===Floor map Script End===//
3574 -
3575 - if ($vrgallery_display) {
3576 - if (!$autoload) {
3577 - $html .= '
3578 - jQuery(document).ready(function($){
3579 - jQuery("#sccontrols' . $id . '").hide();
3580 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3581 - jQuery("#sccontrols' . $id . '").hide();
3582 - jQuery("#pano' . $id . ' .wpvr_slider_nav").hide();
3583 - });
3584 - ';
3585 -
3586 - $html .= '
3587 - var slide' . $id . ' = "down";
3588 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
3589 -
3590 - if (slide' . $id . ' == "up") {
3591 - jQuery(".vrgctrl' . $id . '").empty();
3592 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3593 - slide' . $id . ' = "down";
3594 - jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3595 - jQuery("#sccontrols' . $id . '").slideToggle(function(){
3596 - if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3597 - if (jQuery(this).is(":visible")) {
3598 - jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3599 - "display": "flex",
3600 - "justify-content": "center",
3601 - "align-items": "center",
3602 - "gap": "15px"
3603 - });
3604 - }
3605 - }
3606 - if (jQuery(".bricks-is-frontend").length) {
3607 - if (jQuery(this).is(":visible")) {
3608 - jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3609 - "display": "flex",
3610 - "justify-content": "center",
3611 - "align-items": "center"
3612 - });
3613 - }
3614 - }
3615 - });
3616 - }
3617 - else {
3618 - jQuery(".vrgctrl' . $id . '").empty();
3619 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3620 - slide' . $id . ' = "up";
3621 - jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3622 - jQuery("#sccontrols' . $id . '").slideToggle(function(){
3623 - if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3624 - if (jQuery(this).is(":visible")) {
3625 - jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3626 - "display": "flex",
3627 - "justify-content": "center",
3628 - "align-items": "center",
3629 - "gap": "15px"
3630 - });
3631 - }
3632 - }
3633 - if (jQuery(".bricks-is-frontend").length) {
3634 - if (jQuery(this).is(":visible")) {
3635 - jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3636 - "display": "flex",
3637 - "justify-content": "center",
3638 - "align-items": "center"
3639 - });
3640 - }
3641 - }
3642 - });
3643 - }
3644 - });
3645 - ';
3646 - } else {
3647 - $html .= '
3648 - jQuery(document).ready(function($){
3649 - jQuery("#sccontrols' . $id . '").show();
3650 - jQuery("#pano' . $id . ' .wpvr_slider_nav").show();
3651 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3652 - });
3653 - ';
3654 -
3655 - $html .= '
3656 - var slide' . $id . ' = "down";
3657 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
3658 -
3659 - if (slide' . $id . ' == "up") {
3660 - jQuery(".vrgctrl' . $id . '").empty();
3661 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3662 - slide' . $id . ' = "down";
3663 - }
3664 - else {
3665 - jQuery(".vrgctrl' . $id . '").empty();
3666 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3667 - slide' . $id . ' = "up";
3668 - }
3669 - jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3670 - jQuery("#sccontrols' . $id . '").slideToggle(function(){
3671 - if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3672 - if (jQuery(this).is(":visible")) {
3673 - jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3674 - "display": "flex",
3675 - "justify-content": "center",
3676 - "align-items": "center",
3677 - "gap": "15px"
3678 - });
3679 - }
3680 - }
3681 - if (jQuery(".bricks-is-frontend").length) {
3682 - if (jQuery(this).is(":visible")) {
3683 - jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3684 - "display": "flex",
3685 - "justify-content": "center",
3686 - "align-items": "center"
3687 - });
3688 - }
3689 - }
3690 - });
3691 - });
3692 - ';
3693 - }
3694 - } else {
3695 - $html .= '
3696 - jQuery(document).ready(function($){
3697 - jQuery("#sccontrols' . $id . '").hide();
3698 - jQuery("#pano' . $id . ' .wpvr_slider_nav").hide();
3699 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3700 - });
3701 - ';
3702 -
3703 - $html .= '
3704 - var slide' . $id . ' = "down";
3705 - jQuery(document).on("click","#vrgcontrols' . $id . '",function() {
3706 -
3707 - if (slide' . $id . ' == "up") {
3708 - jQuery(".vrgctrl' . $id . '").empty();
3709 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_up . $sin_qout . ');
3710 - slide' . $id . ' = "down";
3711 - }
3712 - else {
3713 - jQuery(".vrgctrl' . $id . '").empty();
3714 - jQuery(".vrgctrl' . $id . '").html(' . $sin_qout . $angle_down . $sin_qout . ');
3715 - slide' . $id . ' = "up";
3716 - }
3717 - jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3718 - jQuery("#sccontrols' . $id . '").slideToggle(function(){
3719 - if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3720 - if (jQuery(this).is(":visible")) {
3721 - jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3722 - "display": "flex",
3723 - "justify-content": "center",
3724 - "align-items": "center",
3725 - "gap": "15px"
3726 - });
3727 - }
3728 - }
3729 - if (jQuery(".bricks-is-frontend").length) {
3730 - if (jQuery(this).is(":visible")) {
3731 - jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3732 - "display": "flex",
3733 - "justify-content": "center",
3734 - "align-items": "center"
3735 - });
3736 - }
3737 - }
3738 - });
3739 - });
3740 - ';
3741 - }
3742 -
3743 - if (!$autoload) {
3744 - $html .= '
3745 -
3746 - jQuery(document).ready(function(){
3747 - jQuery("#controls' . $id . '").hide();
3748 - jQuery("#zoom-in-out-controls' . $id . '").hide();
3749 - jQuery("#adcontrol' . $id . '").hide();
3750 - jQuery("#explainer_button_' . $id . '").hide();
3751 - jQuery("#generic_form_button_' . $id . '").hide();
3752 - jQuery("#floor_map_button_' . $id . '").hide();
3753 - jQuery("#vrgcontrols' . $id . '").hide();
3754 - jQuery("#cp-logo-controls").hide();
3755 - jQuery(".custom-scene-navigation").hide();
3756 - jQuery("#pano' . $id . '").find(".pnlm-panorama-info").hide();
3757 - });
3758 -
3759 - ';
3760 -
3761 - if ($vrgallery_display) {
3762 - $html .= 'var load_once = "true";';
3763 - $html .= 'panoshow' . $id . '.on("load", function (){
3764 - if (load_once == "true") {
3765 - load_once = "false";
3766 - jQuery("#sccontrols' . $id . '").slideToggle(function(){
3767 - if (jQuery(".elementor-edit-mode .elementor-widget-container").length) {
3768 - if (jQuery(this).is(":visible")) {
3769 - jQuery(".elementor-edit-mode .elementor-widget-container .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css("display", "flex");
3770 - }
3771 - }
3772 - if (jQuery(".bricks-is-frontend").length) {
3773 - if (jQuery(this).is(":visible")) {
3774 - jQuery(".bricks-is-frontend .wpvr-cardboard .pnlm-container #sccontrols' . $id . '").css({
3775 - "display": "flex",
3776 - "justify-content": "center",
3777 - "align-items": "center"
3778 - });
3779 - }
3780 - }
3781 - });
3782 - jQuery("#pano' . $id . ' .wpvr_slider_nav").slideToggle();
3783 - }
3784 - });';
3785 - }
3786 -
3787 - $html .= 'panoshow' . $id . '.on("load", function (){
3788 - jQuery("#controls' . $id . '").show();
3789 - jQuery("#zoom-in-out-controls' . $id . '").show();
3790 - jQuery("#adcontrol' . $id . '").show();
3791 - jQuery("#explainer_button_' . $id . '").show();
3792 - jQuery("#generic_form_button_' . $id . '").show();
3793 - jQuery("#floor_map_button_' . $id . '").show();
3794 - jQuery("#vrgcontrols' . $id . '").show();
3795 - jQuery("#cp-logo-controls").show();
3796 - jQuery(".custom-scene-navigation").show();
3797 - jQuery("#pano' . $id . '").find(".pnlm-panorama-info").show();
3798 - });';
3799 - }
3800 -
3801 - $previewText = $postdata['previewtext'] ?? 'Click To Load Panorama';
3802 - if ($previewText) {
3803 - $html .= '
3804 - jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previewText. '")
3805 - ';
3806 - } else {
3807 - $html .= '
3808 - jQuery("#pano' . $id . '").children(".pnlm-ui").find(".pnlm-load-button p").text("Click To Load Panorama")
3809 - ';
3810 - }
3811 -
3812 - $html .= 'jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseenter", function(){
3813 - jQuery(this).attr("title", jQuery(this).text());
3814 - });
3815 - jQuery("#pano' . $id . ' .pnlm-title-box").on("mouseleave", function(){
3816 - jQuery(this).removeAttr("title");
3817 - });';
3818 - $html .= '});';
3819 - $html .= '</script>';
3820 -
3821 - $tour_data = [];
3822 - if(defined("WPVR_PRO_VERSION")){
3823 - $tour_data = array(
3824 - 'explainerControlSwitch' => (
3825 - isset( $postdata['explainerSwitch'] )
3826 - && in_array( $postdata['explainerSwitch'], array( true, 1, '1', 'on' ), true )
3827 - ) ? 'on' : 'off',
3828 - 'floor_plan_enable' => $floor_plan_enable ?? false,
3829 - 'floor_plan_image' => $floor_plan_image ?? '',
3830 - 'custom_control' => $custom_control ?? [],
3831 - );
3832 - }
3833 - return apply_filters('wpvr_generate_tour_layout_html', $html ,$postdata ,$id, $tour_data);
827 + return $output;
3834 828 }
3835 829
3836 830 function sanitize_content_preserve_styles($content, $allow_forms = false) {
3837 831 // Decode HTML entities first (in case content was encoded in database)
@@ -3836,12 +830,16 @@
3836 830 function sanitize_content_preserve_styles($content, $allow_forms = false) {
3837 831 // Decode HTML entities first (in case content was encoded in database)
3838 832 $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
3839 833
3840 - // Escape <script> blocks to display as text instead of removing them
3841 - $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) {
3842 - return esc_html($matches[0]); // Convert to plain text
3843 - }, $content);
834 + // Escape or strip <script> blocks
835 + if ($allow_forms) {
836 + $content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $content);
837 + } else {
838 + $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) {
839 + return esc_html($matches[0]); // Convert to plain text
840 + }, $content);
841 + }
3844 842
3845 843 // Strip dangerous URL-based attributes
3846 844 $content = preg_replace('/(href|action|formaction)\s*=\s*["\']?\s*(javascript|vbscript|data|about):/i', '$1=""', $content);
3847 845
@@ -3884,10 +882,16 @@
3884 882 $css = preg_replace('/-moz-binding\s*:/i', '', $css);
3885 883 return '<style>' . esc_html($css) . '</style>';
3886 884 }, $content);
3887 885
3888 - // Allow iframes from safe sources only (e.g., YouTube, Vimeo)
886 + // Allow iframes and styles from safe sources only
3889 887 $allowed_tags = wp_kses_allowed_html('post');
888 + $allowed_tags['style'] = [
889 + 'type' => true,
890 + 'id' => true,
891 + 'class' => true,
892 + 'media' => true,
893 + ];
3890 894 $allowed_tags['iframe'] = [
3891 895 'src' => true,
3892 896 'width' => true,
3893 897 'height' => true,
@@ -3917,37 +921,47 @@
3917 921 ];
3918 922
3919 923 if ($allow_forms) {
3920 924 $form_attributes = [
3921 - 'id' => true,
3922 - 'class' => true,
3923 - 'style' => true,
3924 - 'name' => true,
3925 - 'value' => true,
3926 - 'type' => true,
3927 - 'placeholder' => true,
3928 - 'action' => true,
3929 - 'method' => true,
3930 - 'target' => true,
3931 - 'enctype' => true,
3932 - 'disabled' => true,
3933 - 'readonly' => true,
3934 - 'required' => true,
3935 - 'checked' => true,
3936 - 'selected' => true,
3937 - 'multiple' => true,
3938 - 'size' => true,
3939 - 'rows' => true,
3940 - 'cols' => true,
3941 - 'maxlength' => true,
3942 - 'minlength' => true,
3943 - 'min' => true,
3944 - 'max' => true,
3945 - 'step' => true,
3946 - 'pattern' => true,
3947 - 'autocomplete'=> true,
3948 - 'autofocus' => true,
3949 - 'for' => true,
925 + 'id' => true,
926 + 'class' => true,
927 + 'style' => true,
928 + 'name' => true,
929 + 'value' => true,
930 + 'type' => true,
931 + 'placeholder' => true,
932 + 'action' => true,
933 + 'method' => true,
934 + 'target' => true,
935 + 'enctype' => true,
936 + 'disabled' => true,
937 + 'readonly' => true,
938 + 'required' => true,
939 + 'checked' => true,
940 + 'selected' => true,
941 + 'multiple' => true,
942 + 'size' => true,
943 + 'rows' => true,
944 + 'cols' => true,
945 + 'maxlength' => true,
946 + 'minlength' => true,
947 + 'min' => true,
948 + 'max' => true,
949 + 'step' => true,
950 + 'pattern' => true,
951 + 'autocomplete' => true,
952 + 'autofocus' => true,
953 + 'for' => true,
954 + 'data-*' => true,
955 + 'data-form_id' => true,
956 + 'data-form_instance' => true,
957 + 'data-name' => true,
958 + 'data-type' => true,
959 + 'aria-invalid' => true,
960 + 'aria-required' => true,
961 + 'aria-label' => true,
962 + 'aria-describedby' => true,
963 + 'aria-labelledby' => true,
3950 964 ];
3951 965 $allowed_tags['form'] = $form_attributes;
3952 966 $allowed_tags['input'] = $form_attributes;
3953 967 $allowed_tags['button'] = $form_attributes;
@@ -3957,8 +971,18 @@
3957 971 $allowed_tags['optgroup'] = $form_attributes;
3958 972 $allowed_tags['label'] = $form_attributes;
3959 973 $allowed_tags['fieldset'] = $form_attributes;
3960 974 $allowed_tags['legend'] = $form_attributes;
975 + if (!isset($allowed_tags['div'])) {
976 + $allowed_tags['div'] = [];
977 + }
978 + $allowed_tags['div']['data-*'] = true;
979 + $allowed_tags['div']['data-form_id'] = true;
980 + $allowed_tags['div']['data-form_instance'] = true;
981 + if (!isset($allowed_tags['span'])) {
982 + $allowed_tags['span'] = [];
983 + }
984 + $allowed_tags['span']['data-*'] = true;
3961 985 }
3962 986
3963 987 // Apply wp_kses() to keep only allowed tags/attributes
3964 988 $content = wp_kses($content, $allowed_tags);
@@ -4075,15 +1099,22 @@
4075 1099 }
4076 1100
4077 1101 function wpvr_rest_route_permission()
4078 1102 {
4079 - return true;
1103 + $post_type_obj = get_post_type_object( 'wpvr_item' );
1104 + $edit_cap = $post_type_obj ? $post_type_obj->cap->edit_posts : 'edit_wpvr_tours';
1105 + return current_user_can( $edit_cap ) || current_user_can( 'edit_posts' );
4080 1106 }
4081 1107
4082 1108 function wpvr_rest_data_set()
4083 1109 {
1110 + $post_type_obj = get_post_type_object( 'wpvr_item' );
1111 + $edit_cap = $post_type_obj ? $post_type_obj->cap->edit_posts : 'edit_wpvr_tours';
1112 + $post_status = current_user_can( $edit_cap ) ? array( 'publish', 'draft', 'private' ) : 'publish';
1113 +
4084 1114 $query = new WP_Query(array(
4085 - 'post_type' => 'wpvr_item',
1115 + 'post_type' => 'wpvr_item',
1116 + 'post_status' => $post_status,
4086 1117 'posts_per_page' => -1,
4087 1118 ));
4088 1119
4089 1120 $wpvr_list = array();
@@ -4096,8 +1127,9 @@
4096 1127 $title = $post_id . ' : ' . $title;
4097 1128 $list_ob = array('value' => $post_id, 'label' => $title);
4098 1129 array_push($wpvr_list, $list_ob);
4099 1130 }
1131 + wp_reset_postdata();
4100 1132
4101 1133 return $wpvr_list;
4102 1134 }
4103 1135
@@ -4102,9 +1134,10 @@
4102 1134 }
4103 1135
4104 1136 function wpvr_isMobileDevice()
4105 1137 {
4106 - return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);
1138 + $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
1139 + return (bool) preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|ipad|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $user_agent);
4107 1140 }
4108 1141
4109 1142 function wpvr_directory()
4110 1143 {
@@ -4293,9 +1326,9 @@
4293 1326 function ($api) {
4294 1327 $elementsToRegister = [
4295 1328 'wpvrelement',
4296 1329 ];
4297 - $pluginBaseUrl = rtrim(plugins_url(basename(__DIR__)), '\\/');
1330 + $pluginBaseUrl = rtrim(WPVR_PLUGIN_DIR_URL, '\\/');
4298 1331 /** @var \VisualComposer\Modules\Elements\ApiController $elementsApi */
4299 1332 $elementsApi = $api->elements;
4300 1333 foreach ($elementsToRegister as $tag) {
4301 1334 $manifestPath = __DIR__ . '/vc/' . $tag . '/manifest.json';
@@ -4406,5 +1439,30 @@
4406 1439 }
4407 1440 }
4408 1441
4409 1442 return wp_kses( $content, $allowed_tags );
1443 +}
1444 +
1445 +add_filter('fluentform/form_vars_for_JS', 'wpvr_fluent_form_register_inline_vars', 10, 2);
1446 +/**
1447 + * Register Fluent Forms JS vars safely via WordPress script API.
1448 + * Prevents raw script tag concatenation in HTML while ensuring form handlers initialize.
1449 + *
1450 + * @param array $vars Form configuration variables from Fluent Forms.
1451 + * @param object $form Fluent Form database record.
1452 + * @return array
1453 + */
1454 +function wpvr_fluent_form_register_inline_vars($vars, $form) {
1455 + if (!empty($vars['form_instance'])) {
1456 + $inline_js = 'window.fluent_form_' . esc_js($vars['form_instance']) . ' = ' . wp_json_encode($vars) . ';';
1457 + if (wp_script_is('fluent-form-submission', 'done') || wp_doing_ajax()) {
1458 + if (function_exists('wp_print_inline_script_tag')) {
1459 + wp_print_inline_script_tag($inline_js);
1460 + } else {
1461 + echo '<script type="text/javascript">' . $inline_js . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1462 + }
1463 + } else {
1464 + wp_add_inline_script('fluent-form-submission', $inline_js, 'before');
1465 + }
1466 + }
1467 + return $vars;
4410 1468 }