PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
profile-builder / form-builder / form-builder-preview.php

form-builder-preview.php in User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor 4.0.3, at form-builder/form-builder-preview.php

232 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Capability-gated front-end form preview (CPTs are public=>false).
4 * Build by post ID (drafts work); bare wp_head/wp_footer (block themes break get_header).
5 * Display-only — neutralize anything that mutates data or fires external actions.
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) exit;
9
10 add_action( 'init', 'wppb_fb_preview_scrub_submission_request', 0 );
11 /**
12 * Strip action/form_name at init:0 — before OAuth/add-on routers read $_REQUEST.
13 * No auth: only removes keys; renderer still gates on nonce + edit_post.
14 */
15 function wppb_fb_preview_scrub_submission_request() {
16 if ( empty( $_GET['wppb_fb_preview'] ) ) {
17 return;
18 }
19 unset( $_POST['action'], $_GET['action'], $_REQUEST['action'] );
20 unset( $_POST['form_name'], $_GET['form_name'], $_REQUEST['form_name'] );
21 }
22
23 add_action( 'template_redirect', 'wppb_fb_maybe_render_form_preview' );
24 /**
25 * Render and exit when `?wppb_fb_preview=<id>` is present.
26 */
27 function wppb_fb_maybe_render_form_preview() {
28 if ( empty( $_GET['wppb_fb_preview'] ) ) {
29 return;
30 }
31
32 $post_id = absint( wp_unslash( $_GET['wppb_fb_preview'] ) );
33
34 if ( ! isset( $_GET['_wppbnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wppbnonce'] ) ), 'wppb_fb_preview' ) ) {
35 wp_die( esc_html__( 'This form preview link has expired. Reopen the preview from the form editor.', 'profile-builder' ), '', array( 'response' => 403 ) );
36 }
37
38 $post = get_post( $post_id );
39
40 if ( ! $post instanceof WP_Post || ! in_array( $post->post_type, array( 'wppb-rf-cpt', 'wppb-epf-cpt' ), true ) ) {
41 wp_die( esc_html__( 'The requested form could not be found.', 'profile-builder' ), '', array( 'response' => 404 ) );
42 }
43
44 if ( ! current_user_can( 'edit_post', $post_id ) ) {
45 wp_die( esc_html__( 'You are not allowed to preview this form.', 'profile-builder' ), '', array( 'response' => 403 ) );
46 }
47
48 wppb_fb_render_form_preview( $post );
49 exit;
50 }
51
52 /**
53 * Adds `disabled` to the form's submit button while a preview renders.
54 *
55 * @param string $attrs Existing extra attributes for the submit input.
56 * @param string $form_type 'register' | 'edit_profile' (unused).
57 * @return string
58 */
59 function wppb_fb_preview_disable_submit( $attrs, $form_type = '' ) {
60 return $attrs . ' disabled="disabled"';
61 }
62
63 /** Note under the disabled submit button. */
64 function wppb_fb_preview_submit_note() {
65 echo '<span class="wppb-fb-preview-submit-note">'
66 . esc_html__( 'Submitting is disabled in preview mode.', 'profile-builder' )
67 . '</span>';
68 }
69
70 /**
71 * Dequeue Social Connect OAuth SDKs and the GDPR delete-account handler.
72 * CSS alone cannot stop self-init SDKs; dequeue alone leaves inline handlers live.
73 */
74 function wppb_fb_preview_dequeue_unsafe_scripts() {
75 global $wp_scripts;
76 if ( ! $wp_scripts instanceof WP_Scripts ) {
77 return;
78 }
79 foreach ( $wp_scripts->queue as $handle ) {
80 if ( strpos( $handle, 'wppb-sc-' ) === 0 || $handle === 'wppb-gdpr-delete-script' ) {
81 wp_dequeue_script( $handle );
82 }
83 }
84 }
85
86 /**
87 * Renders the standalone preview document for a form post.
88 *
89 * @param WP_Post $post Form post (already validated by the caller).
90 */
91 function wppb_fb_render_form_preview( $post ) {
92 if ( ! class_exists( 'Profile_Builder_Form_Creator' ) ) {
93 wp_die( esc_html__( 'The form rendering engine is unavailable.', 'profile-builder' ) );
94 }
95
96 // wp_resource_hints() reads SERVER_NAME without isset; absent in CLI/some FastCGI.
97 if ( empty( $_SERVER['SERVER_NAME'] ) ) {
98 $_SERVER['SERVER_NAME'] = wp_parse_url( home_url(), PHP_URL_HOST ) ?: 'localhost';
99 }
100
101 add_filter( 'show_admin_bar', '__return_false' );
102
103 // Unset action/form_name from ALL three superglobals: wppb_form_logic() gates
104 // on $_REQUEST['action'], and the $_POST['action'] check only gates the message.
105 unset( $_POST['action'], $_GET['action'], $_REQUEST['action'] );
106 unset( $_POST['form_name'], $_GET['form_name'], $_REQUEST['form_name'] );
107 add_filter( 'wppb_form_submit_button_extra_attributes', 'wppb_fb_preview_disable_submit', 10, 2 );
108 add_action( 'wppb_form_after_submit_button', 'wppb_fb_preview_submit_note' );
109
110 // Enqueue phase + wp_footer@1 (GDPR script enqueues during field render).
111 add_action( 'wp_enqueue_scripts', 'wppb_fb_preview_dequeue_unsafe_scripts', 9999 );
112 add_action( 'wp_footer', 'wppb_fb_preview_dequeue_unsafe_scripts', 1 );
113
114 add_filter( 'wppb_display_edit_other_users_dropdown', '__return_false' );
115 unset( $_GET['edit_user'] );
116
117 $is_epf = ( $post->post_type === 'wppb-epf-cpt' );
118 $form_type = $is_epf ? 'edit_profile' : 'register';
119
120 // form_name 'unspecified' skips publish-only slug resolver; ajax must be set
121 // (class has no default — shortcode_atts normally supplies it).
122 $form = new Profile_Builder_Form_Creator( array(
123 'form_type' => $form_type,
124 'form_name' => 'unspecified',
125 'ID' => $post->ID,
126 'ajax' => false,
127 ) );
128
129 $title = $post->post_title !== '' ? $post->post_title : __( '(no title)', 'profile-builder' );
130
131 // Clone post with embed shortcode as content so add-ons sniffing $post enqueue
132 // (e.g. Progress Bar). Hint only — shortcode is not executed.
133 $sniff_shortcode = wppb_fb_build_form_shortcode( $post );
134 if ( $sniff_shortcode === '' ) {
135 $sniff_shortcode = $is_epf ? '[wppb-edit-profile]' : '[wppb-register]';
136 }
137 $preview_post = clone $post;
138 $preview_post->post_content = $sniff_shortcode;
139 $GLOBALS['post'] = $preview_post;
140
141 nocache_headers();
142
143 ?>
144 <!DOCTYPE html>
145 <html <?php language_attributes(); ?>>
146 <head>
147 <meta charset="<?php bloginfo( 'charset' ); ?>" />
148 <meta name="viewport" content="width=device-width, initial-scale=1" />
149 <meta name="robots" content="noindex, nofollow" />
150 <title><?php echo esc_html( sprintf( /* translators: %s: form title */ __( 'Preview: %s', 'profile-builder' ), $title ) ); ?></title>
151 <?php wp_head(); ?>
152 <style>
153 body.wppb-fb-preview-body {
154 margin: 0;
155 background: #f0f0f1;
156 padding-top: 52px;
157 }
158 .wppb-fb-preview-bar {
159 position: fixed;
160 top: 0;
161 left: 0;
162 right: 0;
163 z-index: 99999;
164 display: flex;
165 align-items: center;
166 gap: 8px;
167 height: 52px;
168 box-sizing: border-box;
169 padding: 0 16px;
170 background: #1e1e1e;
171 color: #fff;
172 font: 13px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
173 }
174 .wppb-fb-preview-bar strong { font-weight: 600; }
175 .wppb-fb-preview-bar .wppb-fb-preview-badge {
176 background: #2271b1;
177 border-radius: 2px;
178 padding: 2px 8px;
179 text-transform: uppercase;
180 letter-spacing: .04em;
181 font-size: 11px;
182 }
183 .wppb-fb-preview-canvas {
184 max-width: 700px;
185 margin: 24px auto;
186 padding: 32px;
187 background: #fff;
188 border: 1px solid #dcdcde;
189 border-radius: 4px;
190 box-sizing: border-box;
191 }
192 @media (max-width: 782px) {
193 .wppb-fb-preview-canvas { margin: 16px; padding: 20px; }
194 }
195 .wppb-fb-preview-canvas .form-submit input[type="submit"][disabled] {
196 cursor: not-allowed;
197 opacity: .6;
198 }
199 .wppb-fb-preview-submit-note {
200 display: inline-block;
201 margin-left: 10px;
202 color: #757575;
203 font-style: italic;
204 font-size: 13px;
205 }
206 /* Social Connect + GDPR delete — independent of submit. */
207 .wppb-fb-preview-canvas .wppb-sc-buttons-container,
208 .wppb-fb-preview-canvas .wppb-sc-linked-accounts-text,
209 .wppb-fb-preview-canvas .wppb-delete-account {
210 pointer-events: none !important;
211 opacity: .6;
212 cursor: not-allowed;
213 }
214 #wppb-epaa-admin-review-links {
215 display: none !important;
216 }
217 </style>
218 </head>
219 <body class="wppb-fb-preview-body">
220 <div class="wppb-fb-preview-bar">
221 <span class="wppb-fb-preview-badge"><?php esc_html_e( 'Preview', 'profile-builder' ); ?></span>
222 <span><strong><?php echo esc_html( $title ); ?></strong> &mdash; <?php echo $is_epf ? esc_html__( 'Edit Profile form', 'profile-builder' ) : esc_html__( 'Registration form', 'profile-builder' ); ?></span>
223 </div>
224 <div class="wppb-fb-preview-canvas">
225 <?php echo $form; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- form output is built and escaped by Profile_Builder_Form_Creator. ?>
226 </div>
227 <?php wp_footer(); ?>
228 </body>
229 </html>
230 <?php
231 }
232