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 +35 -6 9.1.29.1.3 View file →
@@ -570,8 +570,17 @@
570 570 : null;
571 571 $scene_yaw = isset( $hotspot['hotspot-scene-yaw'] ) && $hotspot['hotspot-scene-yaw'] !== ''
572 572 ? (float) $hotspot['hotspot-scene-yaw']
573 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 +
574 583 $hotspots[] = [
575 584 'id' => $hotspot['hotspot-id'] ?? wp_generate_uuid4(),
576 585 'type' => $hotspot['hotspot-type'] ?? 'info',
577 586 'pitch' => isset( $hotspot['hotspot-pitch'] ) ? (float) $hotspot['hotspot-pitch'] : 0,
@@ -582,8 +591,11 @@
582 591 'urlOpen' => $hotspot['hotspot-url-open'] ?? 'off',
583 592 'hover' => $hotspot['hotspot-hover'] ?? '',
584 593 'targetSceneId' => $hotspot['hotspot-scene'] ?? '',
585 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,
586 598 // Pro styling fields
587 599 'iconClass' => ( ( $hotspot['hotspot-customclass-pro'] ?? '' ) === 'none' || ( $hotspot['hotspot-customclass-pro'] ?? '' ) === '' ) ? '' : $hotspot['hotspot-customclass-pro'],
588 600 'iconBgColor' => $hotspot['hotspot-customclass-color-icon-value'] ?? '#00b4ff',
589 601 'iconColor' => $hotspot['hotspot-custom-icon-color-value'] ?? '#ffffff',
@@ -609,11 +621,17 @@
609 621 $is_fluent_form = $hotspot_type === 'fluent_form';
610 622 $raw_content = (string) ( $hotspot['content'] ?? '' );
611 623 $raw_hover = (string) ( $hotspot['hover'] ?? '' );
612 624
613 - $content = function_exists( 'sanitize_content_preserve_styles' )
614 - ? sanitize_content_preserve_styles( $raw_content, $is_fluent_form )
615 - : 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 + }
616 634 $hover = function_exists( 'sanitize_content_preserve_styles' )
617 635 ? sanitize_content_preserve_styles( $raw_hover, false )
618 636 : wp_kses_post( $raw_hover );
619 637
@@ -631,8 +649,20 @@
631 649 'hotspot-customclass' => sanitize_text_field( $hotspot['customClass'] ?? '' ),
632 650 'hotspot-scene-list' => 'none',
633 651 ];
634 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 +
635 665 if ( $this->is_pro ) {
636 666 $hs = array_merge( $hs, [
637 667 // Pro styling fields
638 668 'hotspot-customclass-pro' => !empty( $hotspot['iconClass'] ) ? $hotspot['iconClass'] : 'none',
@@ -643,11 +673,10 @@
643 673 'hotspot-border' => $hotspot['border'] ?? 'off',
644 674 'hotspot-border-width' => $hotspot['borderWidth'] ?? '1',
645 675 'hotspot-border-style' => $hotspot['borderStyle'] ?? 'none',
646 676 'hotspot-border-color' => $hotspot['borderColor'] ?? '#00b4ff',
647 - // Pro navigation entry point fields
648 - 'hotspot-scene-pitch' => $hotspot['scenePitch'] !== null ? (string) $hotspot['scenePitch'] : '',
649 - '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'] : '',
650 679 'hotspot-scene-entry-point-mode' => in_array( $hotspot['sceneEntryPointMode'] ?? '', [ 'inherit', 'custom' ], true )
651 680 ? $hotspot['sceneEntryPointMode']
652 681 : 'inherit',
653 682 ] );