PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.3
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.3
9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 All 222 releases
← All changes | src/Api/Transformers/TourTransformer.php +69 -16 9.0.09.1.3 View file →
@@ -53,8 +53,9 @@
53 53 'previewImage' => $raw['preview'] ?? '',
54 54 'sceneFadeDuration' => isset( $raw['scenefadeduration'] ) ? (int) $raw['scenefadeduration'] : 0,
55 55 'showSceneInfo' => ( $raw['scene-info-enabled'] ?? 'on' ) !== 'off',
56 56 'autoRotate' => $auto_rotate,
57 + 'socialShare' => ( $raw['wpvr_social_share'] ?? 'off' ) === 'on',
57 58 ],
58 59 'floorPlan' => $this->floor_plan_to_api( $raw ),
59 60 'backgroundTour' => [
60 61 'enabled' => ( $raw['bg_tour_enabler'] ?? 'off' ) === 'on',
@@ -62,10 +63,10 @@
62 63 'subtitle' => $raw['bg_tour_subtitle'] ?? '',
63 64 ],
64 65 'videoData' => [
65 66 'url' => $raw['vidurl'] ?? '',
66 - 'autoplay' => ( $raw['video-autoplay'] ?? 'off' ) === 'on',
67 - 'loop' => ( $raw['video-loop'] ?? 'off' ) === 'on',
67 + 'autoplay' => ( $raw['video-autoplay'] ?? $raw['autoplay'] ?? 'off' ) === 'on',
68 + 'loop' => ( $raw['video-loop'] ?? $raw['loop'] ?? 'off' ) === 'on',
68 69 ],
69 70 'streetViewData' => [
70 71 'embedUrl' => $raw['streetviewurl'] ?? '',
71 72 ],
@@ -109,10 +110,14 @@
109 110 ? $requested_default_scene_id
110 111 : ( $scenes[0]['id'] ?? '' );
111 112
112 113 $raw = [
113 - 'autoLoad' => ! empty( $settings['autoLoad'] ),
114 + 'autoLoad' => ! empty( $settings['autoLoad'] ) && $settings['autoLoad'] !== 'off' && $settings['autoLoad'] !== 'false',
114 115 'showControls' => ! empty( $settings['showControls'] ),
116 + 'draggable' => ( isset( $advanced_control['draggable'] ) && ( $advanced_control['draggable'] === 'off' || $advanced_control['draggable'] === false ) ) ? 'off' : 'on',
117 + 'mouseZoom' => ( isset( $advanced_control['mouseZoom'] ) && ( $advanced_control['mouseZoom'] === 'off' || $advanced_control['mouseZoom'] === false ) ) ? 'off' : 'on',
118 + 'diskeyboard' => ( isset( $advanced_control['diskeyboard'] ) && ( $advanced_control['diskeyboard'] === 'off' || $advanced_control['diskeyboard'] === false ) ) ? 'on' : 'off',
119 + 'keyboardzoom' => ( isset( $advanced_control['keyboardzoom'] ) && ( $advanced_control['keyboardzoom'] === 'off' || $advanced_control['keyboardzoom'] === false ) ) ? false : true,
115 120 'previewtext' => $settings['previewText'] ?? '',
116 121 'scenefadeduration' => isset( $settings['sceneFadeDuration'] ) ? (string) $settings['sceneFadeDuration'] : '0',
117 122 'scene-info-enabled' => array_key_exists( 'showSceneInfo', $settings ) && ! $settings['showSceneInfo'] ? 'off' : 'on',
118 123 'defaultscene' => $default_scene_id,
@@ -157,8 +162,10 @@
157 162 'tour-type' => $tour_type,
158 163 'vidurl' => esc_url_raw( $video_data['url'] ?? '' ),
159 164 'video-autoplay' => ! empty( $video_data['autoplay'] ) ? 'on' : 'off',
160 165 'video-loop' => ! empty( $video_data['loop'] ) ? 'on' : 'off',
166 + 'autoplay' => ! empty( $video_data['autoplay'] ) ? 'on' : 'off',
167 + 'loop' => ! empty( $video_data['loop'] ) ? 'on' : 'off',
161 168 'streetviewurl' => esc_url_raw( $street_view_data['embedUrl'] ?? '' ),
162 169 'streetview' => ! empty( $street_view_data['embedUrl'] ) ? 'on' : 'off',
163 170 'panodata' => [
164 171 'scene-list' => $this->scenes_from_api(
@@ -166,10 +173,15 @@
166 173 $default_scene_id,
167 174 ( $settings['showSceneInfo'] ?? true ) !== false
168 175 ),
169 176 ],
177 + 'wpvr_social_share' => ! empty( $settings['socialShare'] ) ? 'on' : 'off',
170 178 ];
171 179
180 + if ( $tour_type === 'video' && ! empty( $video_data['url'] ) ) {
181 + $raw['vidid'] = 'vid' . ( $data['tourId'] ?? $data['id'] ?? wp_rand( 1000, 99999 ) );
182 + }
183 +
172 184 return $raw;
173 185 }
174 186
175 187 // -------------------------------------------------------------------------
@@ -262,9 +274,9 @@
262 274 }
263 275 if ( isset( $raw['streetviewdata'] ) || ! empty( $raw['streetviewurl'] ) ) {
264 276 return 'street-view';
265 277 }
266 - if ( isset( $raw['vidid'] ) || ! empty( $raw['vidurl'] ) ) {
278 + if ( ! empty( $raw['vidid'] ) || ! empty( $raw['vidurl'] ) ) {
267 279 return 'video';
268 280 }
269 281 return 'image';
270 282 }
@@ -290,9 +302,9 @@
290 302 return [
291 303 'tourLayout' => $tour_layout,
292 304 'layout_icon_bg_color' => (string) ( $raw['layout_icon_bg_color'] ?? '#5a536e' ),
293 305 'layout_icon_color' => (string) ( $raw['layout_icon_color'] ?? '#ffffff' ),
294 - 'diskeyboard' => $b( $raw['diskeyboard'] ?? null, true ),
306 + 'diskeyboard' => ! in_array( $raw['diskeyboard'] ?? 'off', [ 'on', 'true', true ], true ),
295 307 'keyboardzoom' => $b( $raw['keyboardzoom'] ?? null, true ),
296 308 'draggable' => $b( $raw['draggable'] ?? null, true ),
297 309 'mouseZoom' => $b( $raw['mouseZoom'] ?? null, true ),
298 310 'gyro' => $b( $raw['gyro'] ?? null, false ),
@@ -558,8 +570,17 @@
558 570 : null;
559 571 $scene_yaw = isset( $hotspot['hotspot-scene-yaw'] ) && $hotspot['hotspot-scene-yaw'] !== ''
560 572 ? (float) $hotspot['hotspot-scene-yaw']
561 573 : null;
574 + $product_id = isset( $hotspot['hotspot-product-id'] ) ? (string) $hotspot['hotspot-product-id'] : '';
575 + $product_name = '';
576 + if ( ! empty( $product_id ) && function_exists( 'wc_get_product' ) ) {
577 + $product_obj = wc_get_product( $product_id );
578 + if ( is_object( $product_obj ) ) {
579 + $product_name = $product_obj->get_formatted_name();
580 + }
581 + }
582 +
562 583 $hotspots[] = [
563 584 'id' => $hotspot['hotspot-id'] ?? wp_generate_uuid4(),
564 585 'type' => $hotspot['hotspot-type'] ?? 'info',
565 586 'pitch' => isset( $hotspot['hotspot-pitch'] ) ? (float) $hotspot['hotspot-pitch'] : 0,
@@ -570,8 +591,11 @@
570 591 'urlOpen' => $hotspot['hotspot-url-open'] ?? 'off',
571 592 'hover' => $hotspot['hotspot-hover'] ?? '',
572 593 'targetSceneId' => $hotspot['hotspot-scene'] ?? '',
573 594 'customClass' => $hotspot['hotspot-customclass'] ?? '',
595 + 'fluentFormId' => isset( $hotspot['fluent-form-id'] ) ? (string) $hotspot['fluent-form-id'] : '',
596 + 'productId' => $product_id,
597 + 'productName' => $product_name,
574 598 // Pro styling fields
575 599 'iconClass' => ( ( $hotspot['hotspot-customclass-pro'] ?? '' ) === 'none' || ( $hotspot['hotspot-customclass-pro'] ?? '' ) === '' ) ? '' : $hotspot['hotspot-customclass-pro'],
576 600 'iconBgColor' => $hotspot['hotspot-customclass-color-icon-value'] ?? '#00b4ff',
577 601 'iconColor' => $hotspot['hotspot-custom-icon-color-value'] ?? '#ffffff',
@@ -592,23 +616,53 @@
592 616
593 617 protected function hotspots_from_api( array $hotspots ): array {
594 618 $hotspot_list = [];
595 619 foreach ( $hotspots as $hotspot ) {
620 + $hotspot_type = sanitize_key( $hotspot['type'] ?? 'info' );
621 + $is_fluent_form = $hotspot_type === 'fluent_form';
622 + $raw_content = (string) ( $hotspot['content'] ?? '' );
623 + $raw_hover = (string) ( $hotspot['hover'] ?? '' );
624 +
625 + // For fluent_form hotspots, content is dynamically rendered server-side from fluent-form-id.
626 + // User-supplied content is never used and must not be saved, completely eliminating stored XSS.
627 + if ( $is_fluent_form ) {
628 + $content = '';
629 + } else {
630 + $content = function_exists( 'sanitize_content_preserve_styles' )
631 + ? sanitize_content_preserve_styles( $raw_content, false )
632 + : wp_kses_post( $raw_content );
633 + }
634 + $hover = function_exists( 'sanitize_content_preserve_styles' )
635 + ? sanitize_content_preserve_styles( $raw_hover, false )
636 + : wp_kses_post( $raw_hover );
637 +
596 638 $hs = [
597 639 'hotspot-id' => $hotspot['id'] ?? wp_generate_uuid4(),
598 - 'hotspot-type' => $hotspot['type'] ?? 'info',
640 + 'hotspot-type' => $hotspot_type,
599 641 'hotspot-pitch' => (string) ( $hotspot['pitch'] ?? 0 ),
600 642 'hotspot-yaw' => (string) ( $hotspot['yaw'] ?? 0 ),
601 - 'hotspot-title' => $hotspot['text'] ?? '',
602 - 'hotspot-content' => $hotspot['content'] ?? '',
603 - 'hotspot-url' => $hotspot['url'] ?? '',
604 - 'hotspot-url-open' => $hotspot['urlOpen'] ?? 'off',
605 - 'hotspot-hover' => $hotspot['hover'] ?? '',
606 - 'hotspot-scene' => $hotspot['targetSceneId'] ?? '',
607 - 'hotspot-customclass' => $hotspot['customClass'] ?? '',
643 + 'hotspot-title' => sanitize_text_field( $hotspot['text'] ?? '' ),
644 + 'hotspot-content' => $content,
645 + 'hotspot-url' => sanitize_text_field( $hotspot['url'] ?? '' ),
646 + 'hotspot-url-open' => ( $hotspot['urlOpen'] ?? 'off' ) === 'on' ? 'on' : 'off',
647 + 'hotspot-hover' => $hover,
648 + 'hotspot-scene' => sanitize_text_field( $hotspot['targetSceneId'] ?? '' ),
649 + 'hotspot-customclass' => sanitize_text_field( $hotspot['customClass'] ?? '' ),
608 650 'hotspot-scene-list' => 'none',
609 651 ];
610 652
653 + if ( isset( $hotspot['fluentFormId'] ) ) {
654 + $hs['fluent-form-id'] = (string) absint( $hotspot['fluentFormId'] );
655 + } elseif ( isset( $hotspot['fluent-form-id'] ) ) {
656 + $hs['fluent-form-id'] = (string) absint( $hotspot['fluent-form-id'] );
657 + }
658 +
659 + if ( isset( $hotspot['productId'] ) ) {
660 + $hs['hotspot-product-id'] = sanitize_text_field( $hotspot['productId'] );
661 + } elseif ( isset( $hotspot['hotspot-product-id'] ) ) {
662 + $hs['hotspot-product-id'] = sanitize_text_field( $hotspot['hotspot-product-id'] );
663 + }
664 +
611 665 if ( $this->is_pro ) {
612 666 $hs = array_merge( $hs, [
613 667 // Pro styling fields
614 668 'hotspot-customclass-pro' => !empty( $hotspot['iconClass'] ) ? $hotspot['iconClass'] : 'none',
@@ -619,11 +673,10 @@
619 673 'hotspot-border' => $hotspot['border'] ?? 'off',
620 674 'hotspot-border-width' => $hotspot['borderWidth'] ?? '1',
621 675 'hotspot-border-style' => $hotspot['borderStyle'] ?? 'none',
622 676 'hotspot-border-color' => $hotspot['borderColor'] ?? '#00b4ff',
623 - // Pro navigation entry point fields
624 - 'hotspot-scene-pitch' => $hotspot['scenePitch'] !== null ? (string) $hotspot['scenePitch'] : '',
625 - 'hotspot-scene-yaw' => $hotspot['sceneYaw'] !== null ? (string) $hotspot['sceneYaw'] : '',
677 + 'hotspot-scene-pitch' => ( isset( $hotspot['scenePitch'] ) && $hotspot['scenePitch'] !== null ) ? (string) $hotspot['scenePitch'] : '',
678 + 'hotspot-scene-yaw' => ( isset( $hotspot['sceneYaw'] ) && $hotspot['sceneYaw'] !== null ) ? (string) $hotspot['sceneYaw'] : '',
626 679 'hotspot-scene-entry-point-mode' => in_array( $hotspot['sceneEntryPointMode'] ?? '', [ 'inherit', 'custom' ], true )
627 680 ? $hotspot['sceneEntryPointMode']
628 681 : 'inherit',
629 682 ] );