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 +42 -8 9.1.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',
@@ -163,9 +164,8 @@
163 164 'video-autoplay' => ! empty( $video_data['autoplay'] ) ? 'on' : 'off',
164 165 'video-loop' => ! empty( $video_data['loop'] ) ? 'on' : 'off',
165 166 'autoplay' => ! empty( $video_data['autoplay'] ) ? 'on' : 'off',
166 167 'loop' => ! empty( $video_data['loop'] ) ? 'on' : 'off',
167 - 'vidid' => $tour_type === 'video' && ! empty( $video_data['url'] ) ? ( 'vid' . ( $data['tourId'] ?? $data['id'] ?? wp_rand( 1000, 99999 ) ) ) : '',
168 168 'streetviewurl' => esc_url_raw( $street_view_data['embedUrl'] ?? '' ),
169 169 'streetview' => ! empty( $street_view_data['embedUrl'] ) ? 'on' : 'off',
170 170 'panodata' => [
171 171 'scene-list' => $this->scenes_from_api(
@@ -173,10 +173,15 @@
173 173 $default_scene_id,
174 174 ( $settings['showSceneInfo'] ?? true ) !== false
175 175 ),
176 176 ],
177 + 'wpvr_social_share' => ! empty( $settings['socialShare'] ) ? 'on' : 'off',
177 178 ];
178 179
180 + if ( $tour_type === 'video' && ! empty( $video_data['url'] ) ) {
181 + $raw['vidid'] = 'vid' . ( $data['tourId'] ?? $data['id'] ?? wp_rand( 1000, 99999 ) );
182 + }
183 +
179 184 return $raw;
180 185 }
181 186
182 187 // -------------------------------------------------------------------------
@@ -269,9 +274,9 @@
269 274 }
270 275 if ( isset( $raw['streetviewdata'] ) || ! empty( $raw['streetviewurl'] ) ) {
271 276 return 'street-view';
272 277 }
273 - if ( isset( $raw['vidid'] ) || ! empty( $raw['vidurl'] ) ) {
278 + if ( ! empty( $raw['vidid'] ) || ! empty( $raw['vidurl'] ) ) {
274 279 return 'video';
275 280 }
276 281 return 'image';
277 282 }
@@ -565,8 +570,17 @@
565 570 : null;
566 571 $scene_yaw = isset( $hotspot['hotspot-scene-yaw'] ) && $hotspot['hotspot-scene-yaw'] !== ''
567 572 ? (float) $hotspot['hotspot-scene-yaw']
568 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 +
569 583 $hotspots[] = [
570 584 'id' => $hotspot['hotspot-id'] ?? wp_generate_uuid4(),
571 585 'type' => $hotspot['hotspot-type'] ?? 'info',
572 586 'pitch' => isset( $hotspot['hotspot-pitch'] ) ? (float) $hotspot['hotspot-pitch'] : 0,
@@ -577,8 +591,11 @@
577 591 'urlOpen' => $hotspot['hotspot-url-open'] ?? 'off',
578 592 'hover' => $hotspot['hotspot-hover'] ?? '',
579 593 'targetSceneId' => $hotspot['hotspot-scene'] ?? '',
580 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,
581 598 // Pro styling fields
582 599 'iconClass' => ( ( $hotspot['hotspot-customclass-pro'] ?? '' ) === 'none' || ( $hotspot['hotspot-customclass-pro'] ?? '' ) === '' ) ? '' : $hotspot['hotspot-customclass-pro'],
583 600 'iconBgColor' => $hotspot['hotspot-customclass-color-icon-value'] ?? '#00b4ff',
584 601 'iconColor' => $hotspot['hotspot-custom-icon-color-value'] ?? '#ffffff',
@@ -604,11 +621,17 @@
604 621 $is_fluent_form = $hotspot_type === 'fluent_form';
605 622 $raw_content = (string) ( $hotspot['content'] ?? '' );
606 623 $raw_hover = (string) ( $hotspot['hover'] ?? '' );
607 624
608 - $content = function_exists( 'sanitize_content_preserve_styles' )
609 - ? sanitize_content_preserve_styles( $raw_content, $is_fluent_form )
610 - : wp_kses_post( $raw_content );
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 + }
611 634 $hover = function_exists( 'sanitize_content_preserve_styles' )
612 635 ? sanitize_content_preserve_styles( $raw_hover, false )
613 636 : wp_kses_post( $raw_hover );
614 637
@@ -626,8 +649,20 @@
626 649 'hotspot-customclass' => sanitize_text_field( $hotspot['customClass'] ?? '' ),
627 650 'hotspot-scene-list' => 'none',
628 651 ];
629 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 +
630 665 if ( $this->is_pro ) {
631 666 $hs = array_merge( $hs, [
632 667 // Pro styling fields
633 668 'hotspot-customclass-pro' => !empty( $hotspot['iconClass'] ) ? $hotspot['iconClass'] : 'none',
@@ -638,11 +673,10 @@
638 673 'hotspot-border' => $hotspot['border'] ?? 'off',
639 674 'hotspot-border-width' => $hotspot['borderWidth'] ?? '1',
640 675 'hotspot-border-style' => $hotspot['borderStyle'] ?? 'none',
641 676 'hotspot-border-color' => $hotspot['borderColor'] ?? '#00b4ff',
642 - // Pro navigation entry point fields
643 - 'hotspot-scene-pitch' => $hotspot['scenePitch'] !== null ? (string) $hotspot['scenePitch'] : '',
644 - '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'] : '',
645 679 'hotspot-scene-entry-point-mode' => in_array( $hotspot['sceneEntryPointMode'] ?? '', [ 'inherit', 'custom' ], true )
646 680 ? $hotspot['sceneEntryPointMode']
647 681 : 'inherit',
648 682 ] );