| @@ -922,9 +922,10 @@ | ||
| 922 | 922 | } else { |
| 923 | 923 | $default_data = array("firstScene" => $default_scene, "sceneFadeDuration" => $scene_fade_duration); |
| 924 | 924 | } |
| 925 | 925 | |
| 926 | - $scene_data = array(); | |
| 926 | + $scene_data = array(); | |
| 927 | + $mobile_media_resize = get_option('mobile_media_resize'); | |
| 927 | 928 | |
| 928 | 929 | if (!empty($panodata["scene-list"])) { |
| 929 | 930 | foreach ($panodata["scene-list"] as $panoscenes) { |
| 930 | 931 | $scene_ititle = ''; |
| @@ -1051,10 +1052,18 @@ | ||
| 1051 | 1052 | ob_start(); |
| 1052 | 1053 | do_action('wpvr_hotspot_content', $hotspot_data); |
| 1053 | 1054 | $hotspot_content = ob_get_clean(); |
| 1054 | 1055 | |
| 1055 | - if (!$hotspot_content) { | |
| 1056 | - $hotspot_content = $hotspot_data["hotspot-content"]; | |
| 1056 | + $is_fluent_form = isset($hotspot_data["hotspot-type"]) && 'fluent_form' === $hotspot_data["hotspot-type"]; | |
| 1057 | + | |
| 1058 | + if ($is_fluent_form) { | |
| 1059 | + if (!empty($hotspot_content)) { | |
| 1060 | + $hotspot_content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $hotspot_content); | |
| 1061 | + } | |
| 1062 | + } else { | |
| 1063 | + if (!$hotspot_content) { | |
| 1064 | + $hotspot_content = $hotspot_data["hotspot-content"] ?? ''; | |
| 1065 | + } | |
| 1057 | 1066 | } |
| 1058 | 1067 | |
| 1059 | 1068 | $hotspot_url = $this->normalize_hotspot_external_url($hotspot_data["hotspot-url"] ?? ''); |
| 1060 | 1069 | |
| @@ -1074,9 +1083,8 @@ | ||
| 1074 | 1083 | $hotspot_data['hotspot-hover'] ?? '' |
| 1075 | 1084 | ); |
| 1076 | 1085 | |
| 1077 | 1086 | |
| 1078 | - $is_fluent_form = isset($hotspot_data["hotspot-type"]) && 'fluent_form' === $hotspot_data["hotspot-type"]; | |
| 1079 | 1087 | $on_hover_content = $this->sanitize_content_preserve_styles($on_hover_content ?? '', false); |
| 1080 | 1088 | $on_click_content = preg_replace_callback('/<img[^>]*>/', "replace_callback", $hotspot_content ?? ''); |
| 1081 | 1089 | $on_click_content = $this->sanitize_content_preserve_styles($on_click_content ?? '', $is_fluent_form); |
| 1082 | 1090 | |
| @@ -1131,41 +1139,134 @@ | ||
| 1131 | 1139 | } |
| 1132 | 1140 | } |
| 1133 | 1141 | $hotspot_info['URL'] = ($hotspot_data['hotspot-type'] === 'fluent_form' || $hotspot_data['hotspot-type'] === 'wc_product') ? '' : $hotspot_info['URL']; |
| 1134 | 1142 | |
| 1135 | - if ($hotspot_data["hotspot-customclass"] == 'none' || $hotspot_data["hotspot-customclass"] == '') { | |
| 1136 | - unset($hotspot_info["cssClass"]); | |
| 1143 | + $is_sticker = ( ( $hotspot_data['hotspot-type'] ?? '' ) === 'sticker' ); | |
| 1144 | + if ( $is_sticker ) { | |
| 1145 | + $custom_class_pro = ! empty( $hotspot_data['hotspot-customclass'] ) && $hotspot_data['hotspot-customclass'] !== 'none' | |
| 1146 | + ? ' ' . $hotspot_data['hotspot-customclass'] | |
| 1147 | + : ''; | |
| 1148 | + $hotspot_info['cssClass'] = 'wpvr-hs-custom wpvr-hs-sticker' . $custom_class_pro; | |
| 1149 | + $hotspot_info['scale'] = true; | |
| 1150 | + $hotspot_info['stickerTemplate'] = $hotspot_data['hotspot-sticker-template'] ?? 'social_proof'; | |
| 1151 | + $hotspot_info['stickerReviewText'] = $hotspot_data['hotspot-sticker-review-text'] ?? 'The support is super responsive and responds without worries to our requests and needs! Big up to the entire RexTheme team!'; | |
| 1152 | + $hotspot_info['stickerClientName'] = $hotspot_data['hotspot-sticker-client-name'] ?? 'Elena R.'; | |
| 1153 | + $hotspot_info['stickerClientAvatar'] = $hotspot_data['hotspot-sticker-client-avatar'] ?? ''; | |
| 1154 | + $hotspot_info['stickerRating'] = isset( $hotspot_data['hotspot-sticker-rating'] ) ? (int) $hotspot_data['hotspot-sticker-rating'] : 5; | |
| 1155 | + $is_separate_icon = ( $hotspot_data['hotspot-sticker-template'] ?? '' ) === 'button_with_separate_icon'; | |
| 1156 | + $is_add_to_cart = ( $hotspot_data['hotspot-sticker-template'] ?? '' ) === 'add_to_cart'; | |
| 1157 | + $is_social_share = ( $hotspot_data['hotspot-sticker-template'] ?? '' ) === 'social_share'; | |
| 1158 | + $hotspot_info['stickerBgColor'] = $hotspot_data['hotspot-sticker-bg-color'] ?? '#201b2c'; | |
| 1159 | + $hotspot_info['stickerBgOpacity'] = isset( $hotspot_data['hotspot-sticker-bg-opacity'] ) ? (float) $hotspot_data['hotspot-sticker-bg-opacity'] : ( ( $is_separate_icon || $is_add_to_cart || $is_social_share ) ? 75 : 95 ); | |
| 1160 | + $hotspot_info['stickerBlur'] = isset( $hotspot_data['hotspot-sticker-blur'] ) ? (float) $hotspot_data['hotspot-sticker-blur'] : 12; | |
| 1161 | + $hotspot_info['stickerBrightness'] = isset( $hotspot_data['hotspot-sticker-brightness'] ) ? (float) $hotspot_data['hotspot-sticker-brightness'] : 100; | |
| 1162 | + $hotspot_info['stickerTextColor'] = $hotspot_data['hotspot-sticker-text-color'] ?? '#ffffff'; | |
| 1163 | + $hotspot_info['stickerBorderColor'] = $hotspot_data['hotspot-sticker-border-color'] ?? ( ( $is_separate_icon || $is_add_to_cart || $is_social_share ) ? '#40355a' : '#3a3051' ); | |
| 1164 | + $default_radius = $is_separate_icon ? 135 : ( ( $is_add_to_cart || $is_social_share ) ? 15 : 20 ); | |
| 1165 | + $hotspot_info['stickerBorderRadius'] = $hotspot_data['hotspot-sticker-border-radius'] ?? [ | |
| 1166 | + 'topLeft' => $default_radius, | |
| 1167 | + 'topRight' => $default_radius, | |
| 1168 | + 'bottomRight' => $default_radius, | |
| 1169 | + 'bottomLeft' => $default_radius, | |
| 1170 | + ]; | |
| 1171 | + $hotspot_info['stickerPadding'] = $hotspot_data['hotspot-sticker-padding'] ?? [ | |
| 1172 | + 'top' => 21, | |
| 1173 | + 'right' => 21, | |
| 1174 | + 'bottom' => 21, | |
| 1175 | + 'left' => 21, | |
| 1176 | + ]; | |
| 1177 | + $hotspot_info['stickerStarColor'] = $hotspot_data['hotspot-sticker-star-color'] ?? '#EF991F'; | |
| 1178 | + // Text before button (for add_to_cart) | |
| 1179 | + $hotspot_info['stickerPrefixText'] = $hotspot_data['hotspot-sticker-prefix-text'] ?? '$1,090 -'; | |
| 1180 | + $hotspot_info['stickerSubText'] = $hotspot_data['hotspot-sticker-sub-text'] ?? 'Ready to ship'; | |
| 1181 | + // Discount button, add to cart & social share sticker fields | |
| 1182 | + $hotspot_info['stickerBtnText'] = $hotspot_data['hotspot-sticker-btn-text'] ?? ( $is_social_share ? 'SHARE EXPERIENCE' : ( $is_add_to_cart ? 'ADD TO CART' : ( $is_separate_icon ? 'Limited “Midnight Horizon” Edition' : 'GET 20% OFF NOW' ) ) ); | |
| 1183 | + $hotspot_info['stickerBtnColor'] = $hotspot_data['hotspot-sticker-btn-color'] ?? ( $is_social_share ? '#201a2b' : ( $is_add_to_cart ? '#3f04fe' : ( $is_separate_icon ? '#ffffff' : '#EF991F' ) ) ); | |
| 1184 | + $hotspot_info['stickerBtnTextColor'] = $hotspot_data['hotspot-sticker-btn-text-color'] ?? ( ( $is_add_to_cart || $is_social_share ) ? '#ffffff' : '#000000' ); | |
| 1185 | + $hotspot_info['stickerBtnIconColor'] = $hotspot_data['hotspot-sticker-btn-icon-color'] ?? '#000000'; | |
| 1186 | + $hotspot_info['stickerBtnUrl'] = $hotspot_data['hotspot-sticker-btn-url'] ?? ''; | |
| 1187 | + $hotspot_info['stickerBtnNewTab'] = $hotspot_data['hotspot-sticker-btn-new-tab'] ?? 'off'; | |
| 1188 | + $hotspot_info['stickerMainBg'] = $hotspot_data['hotspot-sticker-main-bg'] ?? ( $hotspot_data['hotspot-sticker-card-bg'] ?? 'on' ); | |
| 1189 | + $hotspot_info['stickerCardBg'] = $hotspot_info['stickerMainBg']; | |
| 1190 | + $hotspot_info['stickerBtnBg'] = $hotspot_data['hotspot-sticker-btn-bg'] ?? 'on'; | |
| 1191 | + $hotspot_info['stickerBtnWidth'] = isset( $hotspot_data['hotspot-sticker-btn-width'] ) && $hotspot_data['hotspot-sticker-btn-width'] !== '' ? $hotspot_data['hotspot-sticker-btn-width'] : ( $is_social_share ? 222 : ( $is_add_to_cart ? 163 : ( $is_separate_icon ? 356 : '' ) ) ); | |
| 1192 | + $hotspot_info['stickerBtnHeight'] = isset( $hotspot_data['hotspot-sticker-btn-height'] ) && $hotspot_data['hotspot-sticker-btn-height'] !== '' ? $hotspot_data['hotspot-sticker-btn-height'] : ( ( $is_social_share || $is_add_to_cart || $is_separate_icon ) ? 60 : '' ); | |
| 1193 | + $hotspot_info['stickerBtnRadius'] = isset( $hotspot_data['hotspot-sticker-btn-radius'] ) && $hotspot_data['hotspot-sticker-btn-radius'] !== '' ? (float) $hotspot_data['hotspot-sticker-btn-radius'] : ( $is_separate_icon ? 30 : 10 ); | |
| 1194 | + $hotspot_info['stickerBtnBorder'] = isset( $hotspot_data['hotspot-sticker-btn-border'] ) && $hotspot_data['hotspot-sticker-btn-border'] !== '' ? (float) $hotspot_data['hotspot-sticker-btn-border'] : ( $is_social_share ? 1 : 0 ); | |
| 1195 | + $hotspot_info['stickerBtnBorderColor'] = $hotspot_data['hotspot-sticker-btn-border-color'] ?? ( $is_social_share ? '#3a3051' : ( ( $is_add_to_cart || $is_separate_icon ) ? '#ffffff' : '#EF991F' ) ); | |
| 1196 | + $hotspot_info['stickerBtnTextSize'] = isset( $hotspot_data['hotspot-sticker-btn-text-size'] ) && $hotspot_data['hotspot-sticker-btn-text-size'] !== '' ? (float) $hotspot_data['hotspot-sticker-btn-text-size'] : 18; | |
| 1197 | + $hotspot_info['stickerBtnTextWeight'] = $hotspot_data['hotspot-sticker-btn-text-weight'] ?? ( ( $is_social_share || $is_add_to_cart || $is_separate_icon ) ? '600' : '700' ); | |
| 1198 | + $hotspot_info['stickerBtnIcon'] = ( $is_add_to_cart || $is_social_share ) ? 'none' : ( $hotspot_data['hotspot-sticker-btn-icon'] ?? 'fas fa-tag' ); | |
| 1199 | + // Button with separate icon fields | |
| 1200 | + $hotspot_info['stickerIconBoxBgColor'] = $hotspot_data['hotspot-sticker-icon-box-bg-color'] ?? '#ffffff'; | |
| 1201 | + $hotspot_info['stickerIconBoxRadius'] = isset( $hotspot_data['hotspot-sticker-icon-box-radius'] ) && $hotspot_data['hotspot-sticker-icon-box-radius'] !== '' ? (float) $hotspot_data['hotspot-sticker-icon-box-radius'] : 30; | |
| 1202 | + $hotspot_info['stickerIconBoxBorder'] = isset( $hotspot_data['hotspot-sticker-icon-box-border'] ) && $hotspot_data['hotspot-sticker-icon-box-border'] !== '' ? (float) $hotspot_data['hotspot-sticker-icon-box-border'] : 0; | |
| 1203 | + $hotspot_info['stickerIconBoxBorderColor'] = $hotspot_data['hotspot-sticker-icon-box-border-color'] ?? '#ffffff'; | |
| 1204 | + $hotspot_info['stickerIconBoxSize'] = isset( $hotspot_data['hotspot-sticker-icon-box-size'] ) && $hotspot_data['hotspot-sticker-icon-box-size'] !== '' ? (float) $hotspot_data['hotspot-sticker-icon-box-size'] : 60; | |
| 1205 | + // Social share sticker fields | |
| 1206 | + $hotspot_info['stickerSocialColor'] = $hotspot_data['hotspot-sticker-social-color'] ?? '#ffffff'; | |
| 1207 | + $hotspot_info['stickerSocialSize'] = isset( $hotspot_data['hotspot-sticker-social-size'] ) && $hotspot_data['hotspot-sticker-social-size'] !== '' ? (float) $hotspot_data['hotspot-sticker-social-size'] : 20; | |
| 1208 | + $hotspot_info['stickerSocialGap'] = isset( $hotspot_data['hotspot-sticker-social-gap'] ) && $hotspot_data['hotspot-sticker-social-gap'] !== '' ? (float) $hotspot_data['hotspot-sticker-social-gap'] : 16; | |
| 1209 | + $hotspot_info['stickerSocialLinks'] = isset( $hotspot_data['hotspot-sticker-social-links'] ) ? ( is_array( $hotspot_data['hotspot-sticker-social-links'] ) ? $hotspot_data['hotspot-sticker-social-links'] : json_decode( (string) $hotspot_data['hotspot-sticker-social-links'], true ) ) : [ | |
| 1210 | + [ 'id' => '1', 'icon' => 'fab fa-linkedin-in', 'customSvg' => '', 'url' => 'https://linkedin.com', 'openNewTab' => 'on' ], | |
| 1211 | + [ 'id' => '2', 'icon' => 'fab fa-facebook-f', 'customSvg' => '', 'url' => 'https://facebook.com', 'openNewTab' => 'on' ], | |
| 1212 | + [ 'id' => '3', 'icon' => 'fab fa-instagram', 'customSvg' => '', 'url' => 'https://instagram.com', 'openNewTab' => 'on' ], | |
| 1213 | + [ 'id' => '4', 'icon' => 'fab fa-dribbble', 'customSvg' => '', 'url' => 'https://dribbble.com', 'openNewTab' => 'on' ], | |
| 1214 | + ]; | |
| 1215 | + $hotspot_info['stickerShowPlaceholderText'] = $hotspot_data['hotspot-sticker-show-placeholder-text'] ?? 'on'; | |
| 1216 | + } else { | |
| 1217 | + if ( isset( $hotspot_data['hotspot-scale'] ) && ( $hotspot_data['hotspot-scale'] === 'on' || $hotspot_data['hotspot-scale'] === true ) ) { | |
| 1218 | + $hotspot_info['scale'] = true; | |
| 1219 | + } | |
| 1220 | + if ($hotspot_data["hotspot-customclass"] == 'none' || $hotspot_data["hotspot-customclass"] == '') { | |
| 1221 | + unset($hotspot_info["cssClass"]); | |
| 1222 | + } | |
| 1137 | 1223 | } |
| 1138 | 1224 | array_push($hotspots, $hotspot_info); |
| 1139 | 1225 | } |
| 1140 | 1226 | |
| 1141 | - $device_scene = $panoscenes['scene-attachment-url']; | |
| 1142 | - $mobile_media_resize = get_option('mobile_media_resize'); | |
| 1143 | - $file_accessible = ini_get('allow_url_fopen'); | |
| 1144 | - if ($mobile_media_resize == "true" && $device_scene ) { | |
| 1145 | - if ($file_accessible == "1") { | |
| 1146 | - $image_info = getimagesize($device_scene); | |
| 1147 | - if ( isset($image_info[0]) && $image_info[0] > 4096) { | |
| 1148 | - $src_to_id_for_mobile = ''; | |
| 1149 | - $src_to_id_for_desktop = ''; | |
| 1150 | - if (wpvr_isMobileDevice()) { | |
| 1151 | - $src_to_id_for_mobile = attachment_url_to_postid($panoscenes['scene-attachment-url']); | |
| 1152 | - if ($src_to_id_for_mobile) { | |
| 1153 | - $mobile_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'wpvr_mobile'); | |
| 1154 | - if ($mobile_scene[3]) { | |
| 1155 | - $device_scene = $mobile_scene[0]; | |
| 1156 | - } | |
| 1227 | + $device_scene = $panoscenes['scene-attachment-url']; | |
| 1228 | + $mobile_scene_url = ''; | |
| 1229 | + $desktop_scene_url = $device_scene; | |
| 1230 | + | |
| 1231 | + if ($mobile_media_resize == "true" && !empty($device_scene)) { | |
| 1232 | + $attachment_id = !empty($panoscenes['scene-attachment-id']) | |
| 1233 | + ? (int) $panoscenes['scene-attachment-id'] | |
| 1234 | + : $this->get_attachment_id_by_url($device_scene); | |
| 1235 | + | |
| 1236 | + if ($attachment_id) { | |
| 1237 | + $image_width = 0; | |
| 1238 | + $image_meta = wp_get_attachment_metadata($attachment_id); | |
| 1239 | + | |
| 1240 | + if (isset($image_meta['width'])) { | |
| 1241 | + $image_width = (int) $image_meta['width']; | |
| 1242 | + } elseif (function_exists('get_attached_file')) { | |
| 1243 | + // Local file fallback only if attachment metadata is missing (no network request) | |
| 1244 | + $file_path = get_attached_file($attachment_id); | |
| 1245 | + if ($file_path && file_exists($file_path)) { | |
| 1246 | + $image_info = @getimagesize($file_path); | |
| 1247 | + if (isset($image_info[0])) { | |
| 1248 | + $image_width = (int) $image_info[0]; | |
| 1157 | 1249 | } |
| 1158 | - } else { | |
| 1159 | - $src_to_id_for_desktop = attachment_url_to_postid($panoscenes['scene-attachment-url']); | |
| 1160 | - if ($src_to_id_for_desktop) { | |
| 1161 | - $desktop_scene = wp_get_attachment_image_src($src_to_id_for_mobile, 'full'); | |
| 1162 | - if (isset($desktop_scene[0])) { | |
| 1163 | - $device_scene = $desktop_scene[0]; | |
| 1164 | - } | |
| 1165 | - } | |
| 1166 | 1250 | } |
| 1167 | 1251 | } |
| 1252 | + | |
| 1253 | + if ($image_width > 4096) { | |
| 1254 | + $mobile_scene = wp_get_attachment_image_src($attachment_id, 'wpvr_mobile'); | |
| 1255 | + if (!empty($mobile_scene[3])) { // is_intermediate verifies resized image exists | |
| 1256 | + $mobile_scene_url = $mobile_scene[0]; | |
| 1257 | + } | |
| 1258 | + | |
| 1259 | + $desktop_scene = wp_get_attachment_image_src($attachment_id, 'full'); | |
| 1260 | + if (isset($desktop_scene[0])) { | |
| 1261 | + $desktop_scene_url = $desktop_scene[0]; | |
| 1262 | + $device_scene = $desktop_scene[0]; | |
| 1263 | + } | |
| 1264 | + | |
| 1265 | + if (wpvr_isMobileDevice() && !empty($mobile_scene_url)) { | |
| 1266 | + $device_scene = $mobile_scene_url; | |
| 1267 | + } | |
| 1268 | + } | |
| 1168 | 1269 | } |
| 1169 | 1270 | } |
| 1170 | 1271 | |
| 1171 | 1272 | $scene_info = array(); |
| @@ -1182,8 +1283,13 @@ | ||
| 1182 | 1283 | |
| 1183 | 1284 | $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); |
| 1184 | 1285 | } else { |
| 1185 | 1286 | $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); |
| 1287 | + if (!empty($mobile_scene_url)) { | |
| 1288 | + $scene_info['mobile_panorama'] = $mobile_scene_url; | |
| 1289 | + $scene_info['desktop_panorama'] = $desktop_scene_url; | |
| 1290 | + $scene_info['desktop_width'] = $image_width; | |
| 1291 | + } | |
| 1186 | 1292 | } |
| 1187 | 1293 | |
| 1188 | 1294 | |
| 1189 | 1295 | if (isset($panoscenes["ptyscene"])) { |
| @@ -1319,8 +1425,11 @@ | ||
| 1319 | 1425 | if ( empty( $panoscenes['hotspot-list'] ) || ! is_array( $panoscenes['hotspot-list'] ) ) { |
| 1320 | 1426 | continue; |
| 1321 | 1427 | } |
| 1322 | 1428 | foreach($panoscenes['hotspot-list'] as $hotspot){ |
| 1429 | + if ( ( $hotspot['hotspot-type'] ?? '' ) === 'sticker' ) { | |
| 1430 | + continue; | |
| 1431 | + } | |
| 1323 | 1432 | if (isset($hotspot['hotspot-customclass-color-icon-value']) && !empty($hotspot['hotspot-customclass-color-icon-value'])) { |
| 1324 | 1433 | $hotspoticoncolor = $hotspot['hotspot-customclass-color-icon-value']; |
| 1325 | 1434 | } else { |
| 1326 | 1435 | $hotspoticoncolor = "#00b4ff"; |
| @@ -1515,16 +1624,24 @@ | ||
| 1515 | 1624 | $animation_css = apply_filters('wpvr_tour_scene_animation',$animation_type,$animationDuration,$animationDelay,$postdata,$id); |
| 1516 | 1625 | $html .= $animation_css; |
| 1517 | 1626 | } |
| 1518 | 1627 | |
| 1628 | + $container_width = $width; | |
| 1629 | + $container_height = $height; | |
| 1630 | + $container_mobile_height = $mobile_height; | |
| 1631 | + | |
| 1519 | 1632 | if ($width == 'fullwidth') { |
| 1520 | - $width = "100%"; | |
| 1633 | + $container_width = "100%"; | |
| 1634 | + } elseif ($width == 'embed') { | |
| 1635 | + $container_width = "100%"; | |
| 1636 | + $container_height = "100%"; | |
| 1637 | + $container_mobile_height = "100%"; | |
| 1521 | 1638 | } |
| 1522 | 1639 | |
| 1523 | 1640 | if (wpvr_isMobileDevice()) { |
| 1524 | - $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $mobile_height . '; border-radius:' . $radius . '; direction:ltr; ">'; | |
| 1641 | + $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $container_width . '; width: 100%; height: ' . $container_mobile_height . '; border-radius:' . $radius . '; direction:ltr; ">'; | |
| 1525 | 1642 | } else { |
| 1526 | - $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $height . '; border-radius:' . $radius . '; direction:ltr; ">'; | |
| 1643 | + $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $container_width . '; width: 100%; height: ' . $container_height . '; border-radius:' . $radius . '; direction:ltr; ">'; | |
| 1527 | 1644 | } |
| 1528 | 1645 | $is_pro = apply_filters('is_wpvr_pro_active',false); |
| 1529 | 1646 | $status = get_option('wpvr_edd_license_status'); |
| 1530 | 1647 | $is_cardboard = get_option('wpvr_cardboard_disable'); |
| @@ -1569,9 +1686,9 @@ | ||
| 1569 | 1686 | } |
| 1570 | 1687 | } elseif ($width == 'embed') { |
| 1571 | 1688 | $html .= '<div class="cardboard-vrembed vrembed">'; |
| 1572 | 1689 | $html .= '<div id="' . $panoid2 . '" class="pano-wrap pano-left pano2' . $id . '" style=" width: 49%!important; text-align:center; direction:ltr;" ><div id="center-pointer2' . $pano_suffix . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>'; |
| 1573 | - $html .= '<div id="' . $panoid . '" class="pano-wrap pano-right pano' . $id . '" style=" text-align:center; direction:ltr;" >'; | |
| 1690 | + $html .= '<div id="' . $panoid . '" class="pano-wrap pano-right pano' . $id . '" style="width: 100%; height: 100%; text-align:center; direction:ltr;" >'; | |
| 1574 | 1691 | } else { |
| 1575 | 1692 | if (wpvr_isMobileDevice()) { |
| 1576 | 1693 | $html .= '<div id="' . $panoid2 . '" class="pano-wrap pano-left cardboard-half pano2' . $id . '" style="width: 49%; border-radius:' . $radius . '"><div id="center-pointer2' . $pano_suffix . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>'; |
| 1577 | 1694 | if ($radius) { |
| @@ -1750,14 +1867,13 @@ | ||
| 1750 | 1867 | //===explainer button end===// |
| 1751 | 1868 | |
| 1752 | 1869 | //===Floor map button===// |
| 1753 | 1870 | $status = get_option('wpvr_edd_license_status'); |
| 1754 | - if ($status !== false && 'valid' == $status && $is_pro){ | |
| 1755 | - if ($floor_plan_enable == "on" && !empty($floor_plan_image)) { | |
| 1756 | - $html .= '<div class="floor_map_button" id="floor_map_button_' . $pano_suffix . '" style="right:'.$floor_map_right.'">'; | |
| 1757 | - $html .= '<div class="ctrl" id="floor_map_target_' . $pano_suffix . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>'; | |
| 1758 | - $html .= '</div>'; | |
| 1759 | - } | |
| 1871 | + $has_floor_plan = ( $status !== false && 'valid' == $status && $is_pro && 'on' == $floor_plan_enable && ! empty( $floor_plan_image ) ); | |
| 1872 | + if ( $has_floor_plan ) { | |
| 1873 | + $html .= '<div class="floor_map_button" id="floor_map_button_' . $pano_suffix . '" style="right:'.$floor_map_right.'">'; | |
| 1874 | + $html .= '<div class="ctrl" id="floor_map_target_' . $pano_suffix . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>'; | |
| 1875 | + $html .= '</div>'; | |
| 1760 | 1876 | } |
| 1761 | 1877 | //===floor map button===// |
| 1762 | 1878 | |
| 1763 | 1879 | if ($vrgallery && 'valid' == $status && $is_pro ) { |
| @@ -1893,45 +2009,88 @@ | ||
| 1893 | 2009 | </div>'; |
| 1894 | 2010 | } |
| 1895 | 2011 | } |
| 1896 | 2012 | //===Floor plan section===// |
| 1897 | - $floor_map_image = ""; | |
| 1898 | - $floor_map_pointer = array(); | |
| 1899 | - $floor_map_scene_id = ''; | |
| 1900 | - $floor_plan_custom_color = '#cca92c'; | |
| 1901 | - $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on'; | |
| 2013 | + if ( $has_floor_plan ) { | |
| 2014 | + $floor_map_image = $floor_plan_image; | |
| 2015 | + $floor_map_pointer = isset($postdata['floor_plan_pointer_position']) && is_array($postdata['floor_plan_pointer_position']) ? $postdata['floor_plan_pointer_position'] : array(); | |
| 2016 | + $floor_map_scene_id = isset($postdata['floor_plan_data_list']) && is_array($postdata['floor_plan_data_list']) ? $postdata['floor_plan_data_list'] : array(); | |
| 2017 | + $floor_plan_custom_color = isset($postdata['floor_plan_custom_color']) && ! empty($postdata['floor_plan_custom_color']) ? $postdata['floor_plan_custom_color'] : '#cca92c'; | |
| 2018 | + $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on'; | |
| 1902 | 2019 | |
| 1903 | - if (isset($postdata['floor_plan_attachment_url'])) { | |
| 1904 | - $floor_map_image = $postdata['floor_plan_attachment_url']; | |
| 1905 | - $floor_map_pointer = $postdata['floor_plan_pointer_position']; | |
| 1906 | - $floor_map_scene_id = $postdata['floor_plan_data_list']; | |
| 1907 | - $floor_plan_custom_color = $postdata['floor_plan_custom_color']; | |
| 1908 | - } | |
| 1909 | - $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $pano_suffix . '" style="display: none">'; | |
| 1910 | - $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>'; | |
| 1911 | - $html .= '<img loading="lazy" src="'.$floor_map_image.'">'; | |
| 1912 | - foreach($floor_map_pointer as $key=> $pointer_position){ | |
| 1913 | - $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id = "'.$floor_map_scene_id[$key]->value.'" id="'.$pointer_position->id.'" data-top="'.$pointer_position->data_top.'" data-left="'.$pointer_position->data_left.'" style="'.$pointer_position->style.'"> | |
| 1914 | - <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
| 1915 | - <circle cx="12" cy="12" r="11.5" stroke="'.$floor_plan_custom_color.'"/> | |
| 1916 | - <circle cx="12" cy="12" r="5" fill="'.$foreground_color_pointer.'"/> | |
| 1917 | - </svg>'; | |
| 1918 | - | |
| 1919 | - // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on" | |
| 1920 | - if ($floor_plan_direction_indicator === "on") { | |
| 1921 | - $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
| 1922 | - <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)"/> | |
| 1923 | - <defs> | |
| 1924 | - <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse"> | |
| 1925 | - <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/> | |
| 1926 | - <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/> | |
| 1927 | - </linearGradient> | |
| 1928 | - </defs> | |
| 1929 | - </svg>'; | |
| 2020 | + $media_alt = ''; | |
| 2021 | + $attachment_id = attachment_url_to_postid( $floor_map_image ); | |
| 2022 | + | |
| 2023 | + if ( $attachment_id ) { | |
| 2024 | + $media_alt = sanitize_text_field( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ); | |
| 2025 | + } | |
| 2026 | + | |
| 2027 | + if ( ! empty( $media_alt ) ) { | |
| 2028 | + $floor_map_alt = $media_alt; | |
| 2029 | + } else { | |
| 2030 | + $tour_title = sanitize_text_field( get_the_title( $id ) ); | |
| 2031 | + | |
| 2032 | + $floor_map_alt = ! empty( $tour_title ) | |
| 2033 | + /* translators: %s: tour title */ | |
| 2034 | + ? sprintf( __( '%s - Floor Plan', 'wpvr' ), $tour_title ) | |
| 2035 | + : __( 'Floor Plan', 'wpvr' ); | |
| 2036 | + } | |
| 2037 | + | |
| 2038 | + $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $pano_suffix . '" style="display: none">'; | |
| 2039 | + $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>'; | |
| 2040 | + $html .= '<img loading="lazy" src="' . esc_url( $floor_map_image ) . '" alt="' . esc_attr( $floor_map_alt ) . '">'; | |
| 2041 | + foreach ( $floor_map_pointer as $key => $pointer_position ) { | |
| 2042 | + $pointer_id = ''; | |
| 2043 | + $data_top = ''; | |
| 2044 | + $data_left = ''; | |
| 2045 | + $style = ''; | |
| 2046 | + | |
| 2047 | + if ( is_object( $pointer_position ) ) { | |
| 2048 | + $pointer_id = isset( $pointer_position->id ) ? (string) $pointer_position->id : ''; | |
| 2049 | + $data_top = isset( $pointer_position->data_top ) ? (string) $pointer_position->data_top : ''; | |
| 2050 | + $data_left = isset( $pointer_position->data_left ) ? (string) $pointer_position->data_left : ''; | |
| 2051 | + $style = isset( $pointer_position->style ) ? (string) $pointer_position->style : ''; | |
| 2052 | + } elseif ( is_array( $pointer_position ) ) { | |
| 2053 | + $pointer_id = isset( $pointer_position['id'] ) ? (string) $pointer_position['id'] : ''; | |
| 2054 | + $data_top = isset( $pointer_position['data_top'] ) ? (string) $pointer_position['data_top'] : ''; | |
| 2055 | + $data_left = isset( $pointer_position['data_left'] ) ? (string) $pointer_position['data_left'] : ''; | |
| 2056 | + $style = isset( $pointer_position['style'] ) ? (string) $pointer_position['style'] : ''; | |
| 2057 | + } | |
| 2058 | + | |
| 2059 | + $scene_id_val = ''; | |
| 2060 | + if ( isset( $floor_map_scene_id[ $key ] ) ) { | |
| 2061 | + $scene_item = $floor_map_scene_id[ $key ]; | |
| 2062 | + if ( is_object( $scene_item ) && isset( $scene_item->value ) ) { | |
| 2063 | + $scene_id_val = (string) $scene_item->value; | |
| 2064 | + } elseif ( is_array( $scene_item ) && isset( $scene_item['value'] ) ) { | |
| 2065 | + $scene_id_val = (string) $scene_item['value']; | |
| 2066 | + } elseif ( is_scalar( $scene_item ) ) { | |
| 2067 | + $scene_id_val = (string) $scene_item; | |
| 1930 | 2068 | } |
| 2069 | + } | |
| 2070 | + | |
| 2071 | + $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id="' . esc_attr( $scene_id_val ) . '" id="' . esc_attr( $pointer_id ) . '" data-top="' . esc_attr( $data_top ) . '" data-left="' . esc_attr( $data_left ) . '" style="' . esc_attr( $style ) . '"> | |
| 2072 | + <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
| 2073 | + <circle cx="12" cy="12" r="11.5" stroke="' . esc_attr( $floor_plan_custom_color ) . '"/> | |
| 2074 | + <circle cx="12" cy="12" r="5" fill="' . esc_attr( $foreground_color_pointer ) . '"/> | |
| 2075 | + </svg>'; | |
| 2076 | + | |
| 2077 | + // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on" | |
| 2078 | + if ( $floor_plan_direction_indicator === 'on' ) { | |
| 2079 | + $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
| 2080 | + <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)"/> | |
| 2081 | + <defs> | |
| 2082 | + <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse"> | |
| 2083 | + <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/> | |
| 2084 | + <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/> | |
| 2085 | + </linearGradient> | |
| 2086 | + </defs> | |
| 2087 | + </svg>'; | |
| 2088 | + } | |
| 2089 | + $html .= '</div>'; | |
| 2090 | + } | |
| 1931 | 2091 | $html .= '</div>'; |
| 1932 | 2092 | } |
| 1933 | - $html .= '</div>'; | |
| 1934 | 2093 | //===Floor plan section===// |
| 1935 | 2094 | |
| 1936 | 2095 | $html .= '<div class="wpvr-hotspot-tweak-contents-wrapper" style="display: none">'; |
| 1937 | 2096 | $html .= '<i class="fa fa-times cross" data-id="' . $id . '"></i>'; |
| @@ -2011,9 +2170,10 @@ | ||
| 2011 | 2170 | border: '.$border_width.'px '.$border_style.' '.$border_color.'; |
| 2012 | 2171 | border-radius: '.$border_radius.'px; |
| 2013 | 2172 | padding: '.$button_pt.'px '.$button_pr.'px '.$button_pb.'px '.$button_pl.'px; |
| 2014 | 2173 | '; |
| 2015 | - $html .= '<div class="wpvr-call-to-action-button position-'.$text_align.'" style="max-width:' . $width.'"> | |
| 2174 | + $cta_width = ( $width === 'fullwidth' || $width === 'embed' ) ? '100%' : $width; | |
| 2175 | + $html .= '<div class="wpvr-call-to-action-button position-'.$text_align.'" style="max-width:' . $cta_width . '"> | |
| 2016 | 2176 | <a href="'.$buttonurl.'" style="'.$style.'" target="'.$target.'">'.$buttontext.'</a> |
| 2017 | 2177 | </div>'; |
| 2018 | 2178 | |
| 2019 | 2179 | } |
| @@ -2186,8 +2346,40 @@ | ||
| 2186 | 2346 | $html .= '(function ($) {'; |
| 2187 | 2347 | $html .= 'jQuery(document).ready(function() {'; |
| 2188 | 2348 | $html .= 'var response = ' . $response . ';'; |
| 2189 | 2349 | $html .= 'var scenes = response[1];'; |
| 2350 | + $html .= 'function wpvrResolveDevicePanorama(scenesConfig) {'; | |
| 2351 | + $html .= ' if (!scenesConfig || !scenesConfig.scenes) return;'; | |
| 2352 | + $html .= ' var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);'; | |
| 2353 | + $html .= ' var isSmallScreen = (window.innerWidth <= 768);'; | |
| 2354 | + $html .= ' if (typeof window.wpvrMaxTexture === "undefined") {'; | |
| 2355 | + $html .= ' window.wpvrMaxTexture = 16384;'; | |
| 2356 | + $html .= ' try {'; | |
| 2357 | + $html .= ' var testCanvas = document.createElement("canvas");'; | |
| 2358 | + $html .= ' var gl = testCanvas.getContext("webgl") || testCanvas.getContext("experimental-webgl");'; | |
| 2359 | + $html .= ' if (gl) {'; | |
| 2360 | + $html .= ' window.wpvrMaxTexture = gl.getParameter(gl.MAX_TEXTURE_SIZE) || 16384;'; | |
| 2361 | + $html .= ' var ext = gl.getExtension("WEBGL_lose_context");'; | |
| 2362 | + $html .= ' if (ext) { ext.loseContext(); }'; | |
| 2363 | + $html .= ' }'; | |
| 2364 | + $html .= ' } catch (e) {}'; | |
| 2365 | + $html .= ' }'; | |
| 2366 | + $html .= ' var maxTexture = window.wpvrMaxTexture;'; | |
| 2367 | + $html .= ' for (var scId in scenesConfig.scenes) {'; | |
| 2368 | + $html .= ' if (!scenesConfig.scenes.hasOwnProperty(scId)) continue;'; | |
| 2369 | + $html .= ' var sc = scenesConfig.scenes[scId];'; | |
| 2370 | + $html .= ' if (!sc) continue;'; | |
| 2371 | + $html .= ' var exceedsGpu = sc.desktop_width && (sc.desktop_width > maxTexture);'; | |
| 2372 | + $html .= ' if (isMobile || isSmallScreen || exceedsGpu) {'; | |
| 2373 | + $html .= ' if (sc.mobile_panorama) {'; | |
| 2374 | + $html .= ' sc.panorama = sc.mobile_panorama;'; | |
| 2375 | + $html .= ' }'; | |
| 2376 | + $html .= ' } else if (sc.desktop_panorama) {'; | |
| 2377 | + $html .= ' sc.panorama = sc.desktop_panorama;'; | |
| 2378 | + $html .= ' }'; | |
| 2379 | + $html .= ' }'; | |
| 2380 | + $html .= '}'; | |
| 2381 | + $html .= 'wpvrResolveDevicePanorama(scenes);'; | |
| 2190 | 2382 | $html .= 'if(scenes) {'; |
| 2191 | 2383 | $html .= 'var scenedata = scenes.scenes;'; |
| 2192 | 2384 | $html .= 'for(var scId in scenedata) {'; |
| 2193 | 2385 | $html .= 'if(!scenedata.hasOwnProperty(scId)) continue;'; |
| @@ -2207,12 +2399,22 @@ | ||
| 2207 | 2399 | $html .='}'; |
| 2208 | 2400 | } |
| 2209 | 2401 | $html .= '}'; |
| 2210 | 2402 | |
| 2403 | + $html .= 'if(scenehotspot[hIdx].hotspot_type === "sticker" || scenehotspot[hIdx].type === "sticker" || scenehotspot[hIdx].stickerTemplate) {'; | |
| 2404 | + $html .= ' (function(hs) {'; | |
| 2405 | + $html .= ' hs["createTooltipFunc"] = function(div) {'; | |
| 2406 | + $html .= ' if (typeof window.wpvrRenderStickerHotspot === "function") {'; | |
| 2407 | + $html .= ' window.wpvrRenderStickerHotspot(div, hs);'; | |
| 2408 | + $html .= ' }'; | |
| 2409 | + $html .= ' };'; | |
| 2410 | + $html .= ' })(scenehotspot[hIdx]);'; | |
| 2411 | + $html .= '}'; | |
| 2412 | + | |
| 2211 | 2413 | if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") { |
| 2212 | 2414 | } else { |
| 2213 | - $html .= 'if(scenehotspot[hIdx]["createTooltipArgs"] != "") {'; | |
| 2214 | - $html .= 'scenehotspot[hIdx]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };'; | |
| 2415 | + $html .= 'else if(scenehotspot[hIdx]["createTooltipArgs"] != "") {'; | |
| 2416 | + $html .= ' scenehotspot[hIdx]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };'; | |
| 2215 | 2417 | $html .= '}'; |
| 2216 | 2418 | } |
| 2217 | 2419 | |
| 2218 | 2420 | $html .= '}'; |
| @@ -2262,8 +2464,9 @@ | ||
| 2262 | 2464 | $response2[1]->autoRotate = false; |
| 2263 | 2465 | $response = json_encode($response2); |
| 2264 | 2466 | $html .= 'var response_duplicate = ' . $response . ';'; |
| 2265 | 2467 | $html .= 'var scenes_duplicate = response_duplicate[1];'; |
| 2468 | + $html .= 'wpvrResolveDevicePanorama(scenes_duplicate);'; | |
| 2266 | 2469 | |
| 2267 | 2470 | $html .= 'if(scenes_duplicate) {'; |
| 2268 | 2471 | $html .= 'var scenedata = scenes_duplicate.scenes;'; |
| 2269 | 2472 | $html .= 'for(var scId in scenedata) {'; |
| @@ -2273,12 +2476,22 @@ | ||
| 2273 | 2476 | $html .= 'for(var hIdx = 0; hIdx < scenehotspot.length; hIdx++) {'; |
| 2274 | 2477 | $html .= 'if(scenehotspot[hIdx]["clickHandlerArgs"] != "") {'; |
| 2275 | 2478 | $html .= 'scenehotspot[hIdx]["clickHandlerFunc"] = function(div, args) { if (typeof window.wpvrhotspot === "function") { window.wpvrhotspot(div, args); } };'; |
| 2276 | 2479 | $html .= '}'; |
| 2480 | + $html .= 'if(scenehotspot[hIdx].hotspot_type === "sticker" || scenehotspot[hIdx].type === "sticker" || scenehotspot[hIdx].stickerTemplate) {'; | |
| 2481 | + $html .= ' (function(hs) {'; | |
| 2482 | + $html .= ' hs["createTooltipFunc"] = function(div) {'; | |
| 2483 | + $html .= ' if (typeof window.wpvrRenderStickerHotspot === "function") {'; | |
| 2484 | + $html .= ' window.wpvrRenderStickerHotspot(div, hs);'; | |
| 2485 | + $html .= ' }'; | |
| 2486 | + $html .= ' };'; | |
| 2487 | + $html .= ' })(scenehotspot[hIdx]);'; | |
| 2488 | + $html .= '}'; | |
| 2489 | + | |
| 2277 | 2490 | if (wpvr_isMobileDevice() && get_option('dis_on_hover') == "true") { |
| 2278 | 2491 | } else { |
| 2279 | - $html .= 'if(scenehotspot[hIdx]["createTooltipArgs"] != "") {'; | |
| 2280 | - $html .= 'scenehotspot[hIdx]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };'; | |
| 2492 | + $html .= 'else if(scenehotspot[hIdx]["createTooltipArgs"] != "") {'; | |
| 2493 | + $html .= ' scenehotspot[hIdx]["createTooltipFunc"] = function(div, args) { if (typeof window.wpvrtooltip === "function") { window.wpvrtooltip(div, args); } };'; | |
| 2281 | 2494 | $html .= '}'; |
| 2282 | 2495 | } |
| 2283 | 2496 | $html .= '}'; |
| 2284 | 2497 | $html .= '}'; |
| @@ -2839,8 +3052,13 @@ | ||
| 2839 | 3052 | if (!hotspot) { |
| 2840 | 3053 | return; |
| 2841 | 3054 | } |
| 2842 | 3055 | |
| 3056 | + // Social share icons navigate independently using their own links and targets. | |
| 3057 | + if (hotspot.querySelector(".wpvr-sticker-card--social-share")) { | |
| 3058 | + return; | |
| 3059 | + } | |
| 3060 | + | |
| 2843 | 3061 | var hotspotLink = hotspot.closest("a[href]"); |
| 2844 | 3062 | if (!hotspotLink) { |
| 2845 | 3063 | hotspotLink = hotspot.querySelector("a[href]"); |
| 2846 | 3064 | } |
| @@ -2867,9 +3085,9 @@ | ||
| 2867 | 3085 | $scene_key = $panoscenes['scene-id']; |
| 2868 | 3086 | $gallery_scene_ids[] = (string) $scene_key; |
| 2869 | 3087 | $scene_key_gallery = $panoscenes['scene-id'] . '_gallery_' . $pano_suffix; |
| 2870 | 3088 | $html .= 'jQuery(document).on("click","#' . $scene_key_gallery . '",function() { |
| 2871 | - panoshow' . $pano_suffix . '.loadScene("' . $scene_key . '"); | |
| 3089 | + panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $scene_key ) . '); | |
| 2872 | 3090 | });'; |
| 2873 | 3091 | } |
| 2874 | 3092 | } |
| 2875 | 3093 | |
| @@ -3094,9 +3312,9 @@ | ||
| 3094 | 3312 | $html .= '})();'; |
| 3095 | 3313 | } |
| 3096 | 3314 | if ($custom_control['backToHomeSwitch'] == "on" && 'valid' == $status && $is_pro) { |
| 3097 | 3315 | $html .= 'document.getElementById("backToHome' . $pano_suffix . '").addEventListener("click", function(e) {'; |
| 3098 | - $html .= 'panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '");'; | |
| 3316 | + $html .= 'panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $default_scene ) . ');'; | |
| 3099 | 3317 | $html .= '});'; |
| 3100 | 3318 | } |
| 3101 | 3319 | if ($gyro_button_enabled && 'valid' == $status && $is_pro) { |
| 3102 | 3320 | $html .= ' |
| @@ -3205,11 +3423,15 @@ | ||
| 3205 | 3423 | } |
| 3206 | 3424 | |
| 3207 | 3425 | $html .= ' |
| 3208 | 3426 | jQuery(document).on("click","#' . $panoid . '",function(event) { |
| 3427 | + var isCross = event.target.closest(".cross"); | |
| 3209 | 3428 | var isActiveModal = event.target.closest(".custom-ifram-wrapper"); |
| 3210 | - var isForm = event.target.closest(".wpvr-hotspot-tweak-contents"); | |
| 3429 | + var isForm = event.target.closest(".wpvr-hotspot-tweak-contents-wrapper"); | |
| 3211 | 3430 | var isHotspot = event.target.closest(".pnlm-hotspot-base"); |
| 3431 | + if(isCross != null){ | |
| 3432 | + return; | |
| 3433 | + } | |
| 3212 | 3434 | if(isForm != null){ |
| 3213 | 3435 | jQuery(this).addClass("show-modal"); |
| 3214 | 3436 | }else if(isActiveModal == null){ |
| 3215 | 3437 | if(isHotspot == null){ |
| @@ -3215,9 +3437,9 @@ | ||
| 3215 | 3437 | if(isHotspot == null){ |
| 3216 | 3438 | jQuery(".custom-ifram-wrapper .custom-ifram").empty(); |
| 3217 | 3439 | jQuery(".custom-ifram-wrapper").hide(); |
| 3218 | 3440 | jQuery(this).removeClass("show-modal"); |
| 3219 | - jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide("show-modal"); | |
| 3441 | + jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide(); | |
| 3220 | 3442 | } |
| 3221 | 3443 | } |
| 3222 | 3444 | });'; |
| 3223 | 3445 | |
| @@ -3477,9 +3699,9 @@ | ||
| 3477 | 3699 | window.wpvrViewers[response[0]["panoid"]] = panoshow' . $pano_suffix . '; |
| 3478 | 3700 | document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", { |
| 3479 | 3701 | detail: { containerId: response[0]["panoid"], viewer: panoshow' . $pano_suffix . ' } |
| 3480 | 3702 | })); |
| 3481 | - jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '") | |
| 3703 | + jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text(' . wp_json_encode( (string) $previeword ) . ') | |
| 3482 | 3704 | setTimeout(function() { |
| 3483 | 3705 | // panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '"); |
| 3484 | 3706 | window.dispatchEvent(new Event("resize")); |
| 3485 | 3707 | if (jQuery("#' . $panoid . '").children().children(".pnlm-panorama-info:visible").length > 0) { |
| @@ -3500,9 +3722,9 @@ | ||
| 3500 | 3722 | document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", { |
| 3501 | 3723 | detail: { containerId: response[0]["panoid"], viewer: panoshow' . $pano_suffix . ' } |
| 3502 | 3724 | })); |
| 3503 | 3725 | setTimeout(function() { |
| 3504 | - panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '"); | |
| 3726 | + panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $default_scene ) . '); | |
| 3505 | 3727 | window.dispatchEvent(new Event("resize")); |
| 3506 | 3728 | if (jQuery("#' . $panoid . '").children().children(".pnlm-panorama-info:visible").length > 0) { |
| 3507 | 3729 | jQuery("#controls' . $pano_suffix . '").css("bottom", "55px"); |
| 3508 | 3730 | } |
| @@ -3512,9 +3734,9 @@ | ||
| 3512 | 3734 | }, 200); |
| 3513 | 3735 | });'; |
| 3514 | 3736 | if (isset($previeword) && $previeword != '') { |
| 3515 | 3737 | $html .= ' |
| 3516 | - jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '") | |
| 3738 | + jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text(' . wp_json_encode( (string) $previeword ) . ') | |
| 3517 | 3739 | '; |
| 3518 | 3740 | } |
| 3519 | 3741 | if ($default_global_zoom != '' || $max_global_zoom != '' || $min_global_zoom != '') { |
| 3520 | 3742 | $html .= 'jQuery(".globalzoom").val("on").change();'; |
| @@ -3558,12 +3780,16 @@ | ||
| 3558 | 3780 | private function sanitize_content_preserve_styles($content, $allow_forms = false) { |
| 3559 | 3781 | // Decode HTML entities first (in case content was encoded in database) |
| 3560 | 3782 | $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8'); |
| 3561 | 3783 | |
| 3562 | - // Escape <script> blocks to display as text instead of removing them | |
| 3563 | - $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) { | |
| 3564 | - return esc_html($matches[0]); // Convert to plain text | |
| 3565 | - }, $content); | |
| 3784 | + // Escape or strip <script> blocks | |
| 3785 | + if ($allow_forms) { | |
| 3786 | + $content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $content); | |
| 3787 | + } else { | |
| 3788 | + $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) { | |
| 3789 | + return esc_html($matches[0]); // Convert to plain text | |
| 3790 | + }, $content); | |
| 3791 | + } | |
| 3566 | 3792 | |
| 3567 | 3793 | // Strip dangerous URL-based attributes |
| 3568 | 3794 | $content = preg_replace('/(href|action|formaction)\s*=\s*["\']?\s*(javascript|vbscript|data|about):/i', '$1=""', $content); |
| 3569 | 3795 | |
| @@ -3606,10 +3832,16 @@ | ||
| 3606 | 3832 | $css = preg_replace('/-moz-binding\s*:/i', '', $css); |
| 3607 | 3833 | return '<style>' . esc_html($css) . '</style>'; |
| 3608 | 3834 | }, $content); |
| 3609 | 3835 | |
| 3610 | - // Allow iframes from safe sources only (e.g., YouTube, Vimeo) | |
| 3836 | + // Allow iframes and styles from safe sources only | |
| 3611 | 3837 | $allowed_tags = wp_kses_allowed_html('post'); |
| 3838 | + $allowed_tags['style'] = [ | |
| 3839 | + 'type' => true, | |
| 3840 | + 'id' => true, | |
| 3841 | + 'class' => true, | |
| 3842 | + 'media' => true, | |
| 3843 | + ]; | |
| 3612 | 3844 | $allowed_tags['iframe'] = [ |
| 3613 | 3845 | 'src' => true, |
| 3614 | 3846 | 'width' => true, |
| 3615 | 3847 | 'height' => true, |
| @@ -3639,37 +3871,47 @@ | ||
| 3639 | 3871 | ]; |
| 3640 | 3872 | |
| 3641 | 3873 | if ($allow_forms) { |
| 3642 | 3874 | $form_attributes = [ |
| 3643 | - 'id' => true, | |
| 3644 | - 'class' => true, | |
| 3645 | - 'style' => true, | |
| 3646 | - 'name' => true, | |
| 3647 | - 'value' => true, | |
| 3648 | - 'type' => true, | |
| 3649 | - 'placeholder' => true, | |
| 3650 | - 'action' => true, | |
| 3651 | - 'method' => true, | |
| 3652 | - 'target' => true, | |
| 3653 | - 'enctype' => true, | |
| 3654 | - 'disabled' => true, | |
| 3655 | - 'readonly' => true, | |
| 3656 | - 'required' => true, | |
| 3657 | - 'checked' => true, | |
| 3658 | - 'selected' => true, | |
| 3659 | - 'multiple' => true, | |
| 3660 | - 'size' => true, | |
| 3661 | - 'rows' => true, | |
| 3662 | - 'cols' => true, | |
| 3663 | - 'maxlength' => true, | |
| 3664 | - 'minlength' => true, | |
| 3665 | - 'min' => true, | |
| 3666 | - 'max' => true, | |
| 3667 | - 'step' => true, | |
| 3668 | - 'pattern' => true, | |
| 3669 | - 'autocomplete'=> true, | |
| 3670 | - 'autofocus' => true, | |
| 3671 | - 'for' => true, | |
| 3875 | + 'id' => true, | |
| 3876 | + 'class' => true, | |
| 3877 | + 'style' => true, | |
| 3878 | + 'name' => true, | |
| 3879 | + 'value' => true, | |
| 3880 | + 'type' => true, | |
| 3881 | + 'placeholder' => true, | |
| 3882 | + 'action' => true, | |
| 3883 | + 'method' => true, | |
| 3884 | + 'target' => true, | |
| 3885 | + 'enctype' => true, | |
| 3886 | + 'disabled' => true, | |
| 3887 | + 'readonly' => true, | |
| 3888 | + 'required' => true, | |
| 3889 | + 'checked' => true, | |
| 3890 | + 'selected' => true, | |
| 3891 | + 'multiple' => true, | |
| 3892 | + 'size' => true, | |
| 3893 | + 'rows' => true, | |
| 3894 | + 'cols' => true, | |
| 3895 | + 'maxlength' => true, | |
| 3896 | + 'minlength' => true, | |
| 3897 | + 'min' => true, | |
| 3898 | + 'max' => true, | |
| 3899 | + 'step' => true, | |
| 3900 | + 'pattern' => true, | |
| 3901 | + 'autocomplete' => true, | |
| 3902 | + 'autofocus' => true, | |
| 3903 | + 'for' => true, | |
| 3904 | + 'data-*' => true, | |
| 3905 | + 'data-form_id' => true, | |
| 3906 | + 'data-form_instance' => true, | |
| 3907 | + 'data-name' => true, | |
| 3908 | + 'data-type' => true, | |
| 3909 | + 'aria-invalid' => true, | |
| 3910 | + 'aria-required' => true, | |
| 3911 | + 'aria-label' => true, | |
| 3912 | + 'aria-describedby' => true, | |
| 3913 | + 'aria-labelledby' => true, | |
| 3672 | 3914 | ]; |
| 3673 | 3915 | $allowed_tags['form'] = $form_attributes; |
| 3674 | 3916 | $allowed_tags['input'] = $form_attributes; |
| 3675 | 3917 | $allowed_tags['button'] = $form_attributes; |
| @@ -3679,8 +3921,18 @@ | ||
| 3679 | 3921 | $allowed_tags['optgroup'] = $form_attributes; |
| 3680 | 3922 | $allowed_tags['label'] = $form_attributes; |
| 3681 | 3923 | $allowed_tags['fieldset'] = $form_attributes; |
| 3682 | 3924 | $allowed_tags['legend'] = $form_attributes; |
| 3925 | + if (!isset($allowed_tags['div'])) { | |
| 3926 | + $allowed_tags['div'] = []; | |
| 3927 | + } | |
| 3928 | + $allowed_tags['div']['data-*'] = true; | |
| 3929 | + $allowed_tags['div']['data-form_id'] = true; | |
| 3930 | + $allowed_tags['div']['data-form_instance'] = true; | |
| 3931 | + if (!isset($allowed_tags['span'])) { | |
| 3932 | + $allowed_tags['span'] = []; | |
| 3933 | + } | |
| 3934 | + $allowed_tags['span']['data-*'] = true; | |
| 3683 | 3935 | } |
| 3684 | 3936 | |
| 3685 | 3937 | // Apply wp_kses() to keep only allowed tags/attributes |
| 3686 | 3938 | $content = wp_kses($content, $allowed_tags); |
| @@ -3714,7 +3966,41 @@ | ||
| 3714 | 3966 | return 'https://' . $url; |
| 3715 | 3967 | } |
| 3716 | 3968 | |
| 3717 | 3969 | return $url; |
| 3970 | +} | |
| 3971 | + | |
| 3972 | +/** | |
| 3973 | + * Get attachment ID from URL with in-memory static cache and WordPress object cache. | |
| 3974 | + * | |
| 3975 | + * @param string $url Image URL. | |
| 3976 | + * @return int Attachment ID or 0. | |
| 3977 | + */ | |
| 3978 | +private function get_attachment_id_by_url($url) | |
| 3979 | +{ | |
| 3980 | + static $memory_cache = array(); | |
| 3981 | + | |
| 3982 | + if (empty($url) || !is_string($url)) { | |
| 3983 | + return 0; | |
| 3984 | + } | |
| 3985 | + | |
| 3986 | + if (isset($memory_cache[$url])) { | |
| 3987 | + return $memory_cache[$url]; | |
| 3988 | + } | |
| 3989 | + | |
| 3990 | + $cache_key = 'wpvr_att_id_' . md5($url); | |
| 3991 | + $cached_id = wp_cache_get($cache_key, 'wpvr'); | |
| 3992 | + if (false !== $cached_id) { | |
| 3993 | + $memory_cache[$url] = (int) $cached_id; | |
| 3994 | + return (int) $cached_id; | |
| 3995 | + } | |
| 3996 | + | |
| 3997 | + $attachment_id = attachment_url_to_postid($url); | |
| 3998 | + $attachment_id = $attachment_id ? (int) $attachment_id : 0; | |
| 3999 | + | |
| 4000 | + wp_cache_set($cache_key, $attachment_id, 'wpvr', HOUR_IN_SECONDS); | |
| 4001 | + $memory_cache[$url] = $attachment_id; | |
| 4002 | + | |
| 4003 | + return $attachment_id; | |
| 3718 | 4004 | } |
| 3719 | 4005 | |
| 3720 | 4006 | } |