PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.4.2
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.4.2
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / helpers / FrmStylesPreviewHelper.php

FrmStylesPreviewHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.4.2, at classes/helpers/FrmStylesPreviewHelper.php

354 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 /**
7 * @since 6.0
8 */
9 class FrmStylesPreviewHelper {
10
11 /**
12 * @param int $form_id
13 */
14 private $form_id;
15
16 /**
17 * This is tracked so we can show a note that the CAPTCHA was turned off.
18 *
19 * @var bool
20 */
21 private $form_includes_captcha = false;
22
23 /**
24 * Track the field ids with the default label position.
25 * A field with a default label position will have a frm-default-label-position class in the styler preview.
26 * Only fields with this class will change when you update the position setting in the styler.
27 *
28 * @since 6.0.1
29 *
30 * @var array
31 */
32 private $default_label_position_field_ids;
33
34 /**
35 * @param string|int $form_id
36 * @return void
37 */
38 public function __construct( $form_id ) {
39 $this->form_id = (int) $form_id;
40 $this->default_label_position_field_ids = array();
41 }
42
43 /**
44 * Modify form behaviours for the styler preview.
45 *
46 * @since 6.0
47 *
48 * @return void
49 */
50 public function adjust_form_for_preview() {
51 add_filter( 'frm_run_antispam', '__return_false', 99 ); // Don't bother including the antispam token in the preview as the form isn't submitted.
52 add_filter( 'frm_run_honeypot', '__return_false' ); // We don't need the honeypot in the preview so leave it out.
53 $this->hide_captcha_fields();
54 $this->disable_javascript_validation();
55 $this->add_a_div_class_for_default_label_positions();
56 }
57
58 /**
59 * Add a frm-default-label-position class to any field with a default label position.
60 * A field with a custom label position shouldn't ever change in the styler preview.
61 *
62 * @since 6.0.1
63 * @return void
64 */
65 private function add_a_div_class_for_default_label_positions() {
66 // Only fields with no label position set hit this filter, so track those for the frm_field_div_classes filter.
67 add_filter(
68 'frm_html_label_position',
69 /**
70 * @param string $position
71 * @param object|array $field
72 * @return string
73 */
74 function( $position, $field ) {
75 if ( is_array( $field ) ) {
76 $this->default_label_position_field_ids[] = (int) $field['id'];
77 }
78 return $position;
79 },
80 10,
81 2
82 );
83
84 add_filter(
85 'frm_field_div_classes',
86 /**
87 * @param string $classes
88 * @param object|array $field
89 * @return string
90 */
91 function( $classes, $field ) {
92 if ( is_array( $field ) && in_array( (int) $field['id'], $this->default_label_position_field_ids, true ) ) {
93 $classes .= ' frm-default-label-position';
94 }
95 return $classes;
96 },
97 10,
98 2
99 );
100 }
101
102 /**
103 * Captcha does not initialize in the preview. Hide it so we don't see the label either.
104 *
105 * @since 6.0
106 *
107 * @return void
108 */
109 private function hide_captcha_fields() {
110 add_filter(
111 'frm_show_normal_field_type',
112 /**
113 * @param bool $show
114 * @param string $field_type
115 * @param string $target_field_type
116 * @return bool
117 */
118 function( $show, $field_type ) {
119 if ( 'captcha' === $field_type ) {
120 $show = false;
121 }
122 return $show;
123 },
124 10,
125 2
126 );
127 }
128
129 /**
130 * Turn off JavaScript validation for the preview.
131 * Without this we hit a "PHP Fatal error: Uncaught Error: Maximum function nesting level of '256' reached" error.
132 * This only happened with specific Look up fields when FrmProLookupFieldsController::get_independent_lookup_field_options is called in Pro.
133 *
134 * @since 6.0
135 *
136 * @return void
137 */
138 private function disable_javascript_validation() {
139 add_filter(
140 'frm_form_object',
141 function( $form ) {
142 $form->options['js_validate'] = false;
143 return $form;
144 }
145 );
146 }
147
148 /**
149 * @since 6.0
150 *
151 * @param string|int $form_id
152 * @return string
153 */
154 public function get_html_for_form_preview() {
155 // Force is_admin to false so the "Entry Key" field doesn't render in the preview.
156 add_filter( 'frm_is_admin', '__return_false' );
157
158 $target_form_preview_html = FrmFormsController::show_form( $this->form_id, '', 'auto', 'auto' );
159
160 $this->form_includes_captcha = wp_script_is( 'captcha-api', 'enqueued' );
161 if ( $this->form_includes_captcha ) {
162 // If a form includes a CAPTCHA field, don't try to load the CAPTCHA scripts for the visual styler preview.
163 wp_dequeue_script( 'captcha-api' );
164 }
165
166 // Return the is_admin status.
167 // Otherwise success messages won't use the proper mark up and will appear without the green background and padding.
168 remove_filter( 'frm_is_admin', '__return_false' );
169
170 return $target_form_preview_html;
171 }
172
173 /**
174 * @since 6.0
175 *
176 * @todo Only show the note once for a form per user per month or something.
177 *
178 * @return array<string>
179 */
180 public function get_notes_for_styler_preview() {
181 $notes = array();
182
183 $fallback_form_note = $this->get_fallback_form_note();
184 if ( is_string( $fallback_form_note ) ) {
185 $notes[] = $fallback_form_note;
186 }
187
188 $frm_settings = FrmAppHelper::get_settings();
189 if ( 'none' === $frm_settings->load_style ) {
190 $notes[] = function() {
191 printf(
192 // translators: %1$s: Anchor tag open, %2$s: Anchor tag close.
193 esc_html__( 'Formidable styles are disabled. This needs to be enabled in %1$sGlobal Settings%2$s.', 'formidable' ),
194 '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-settings' ) ) . '">',
195 '</a>'
196 );
197 };
198 }
199
200 if ( class_exists( 'FrmProStylesController' ) && ! class_exists( 'FrmProStylesPreviewHelper' ) ) {
201 $notes[] = __( 'You are using an outdated version of Formidable Pro. Please update to version 6.0 to get access to all styler features.', 'formidable' );
202 }
203
204 if ( is_callable( 'FrmProStylesController::get_notes_for_styler_preview' ) ) {
205 $notes = array_merge( $notes, FrmProStylesController::get_notes_for_styler_preview() );
206 }
207
208 $disabled_features_note = $this->get_disabled_features_note();
209 if ( is_string( $disabled_features_note ) ) {
210 $notes[] = $disabled_features_note;
211 }
212
213 return $notes;
214 }
215
216 /**
217 * @since 6.0
218 *
219 * @return string|false
220 */
221 private function get_disabled_features_note() {
222 $disabled_features = array();
223
224 if ( $this->form_includes_captcha ) {
225 $disabled_features[] = __( 'Captcha fields are hidden.', 'formidable' );
226 }
227
228 if ( is_callable( 'FrmProStylesController::get_disabled_javascript_features' ) ) {
229 $disabled_pro_features = FrmProStylesController::get_disabled_javascript_features();
230 if ( is_string( $disabled_pro_features ) ) {
231 $disabled_features[] = $disabled_pro_features;
232 }
233 }
234
235 if ( $disabled_features ) {
236 return __( 'Not all JavaScript is loaded in this preview.', 'formidable' ) . ' ' . implode( ' ', $disabled_features );
237 }
238
239 return false;
240 }
241
242 /**
243 * @since 6.0
244 *
245 * @return string|false
246 */
247 private function get_fallback_form_note() {
248 if ( ! FrmAppHelper::simple_get( 'form', 'absint' ) ) {
249 return __( 'This form is being previewed because no form was selected. Use the form dropdown to select a new preview target.', 'formidable' );
250 }
251 return false;
252 }
253
254 /**
255 * Get all warnings to display above the visual styler preview.
256 *
257 * @since 6.0
258 *
259 * @param WP_Post|stdClass $style A new style is not a WP_Post object.
260 * @param WP_Post $default_style
261 * @param string $view Either 'list' or 'edit'.
262 * @return array<string>
263 */
264 public function get_warnings_for_styler_preview( $style, $default_style, $view ) {
265 $warnings = array();
266
267 if ( 'edit' === $view && $this->should_show_multiple_forms_warning( $style->ID, $default_style->ID ) ) {
268 $warnings[] = __( 'Changes that you will make to this style will apply to every form using this style.', 'formidable' );
269 }
270
271 return $warnings;
272 }
273
274 /**
275 * @since 6.0
276 *
277 * @param int $style_id
278 * @param int $default_style_id
279 * @return bool
280 */
281 private function should_show_multiple_forms_warning( $style_id, $default_style_id ) {
282 $is_default_style = $style_id === $default_style_id;
283
284 if ( ! $is_default_style ) {
285 // Also check for the conversational default.
286 $conversational_style_id = FrmDb::get_var( 'posts', array( 'post_name' => 'lines-no-boxes' ), 'ID' );
287 if ( $conversational_style_id && (int) $conversational_style_id === $style_id ) {
288 $is_default_style = true;
289 }
290 }
291
292 $form_count = FrmStylesHelper::get_form_count_for_style( $style_id, $is_default_style );
293
294 if ( $form_count <= 1 ) {
295 return false;
296 }
297
298 // Only show the warning once per user per style.
299 $user_id = get_current_user_id();
300 $meta_key = 'frm_dismiss_multiple_forms_warning_' . $style_id;
301 $meta = get_user_meta( $user_id, $meta_key, true );
302
303 if ( $meta ) {
304 return false;
305 }
306
307 add_user_meta( $user_id, $meta_key, 1 );
308 return true;
309 }
310
311 /**
312 * @since 6.0
313 *
314 * @param WP_Styles $styles
315 * @return void
316 */
317 public static function disable_conflicting_wp_admin_css( $styles ) {
318 if ( ! is_callable( array( $styles, 'remove' ) ) || ! array_key_exists( 'wp-admin', $styles->registered ) ) {
319 return;
320 }
321
322 $styles->remove( 'edit' );
323
324 $wp_admin_dependencies = $styles->registered['wp-admin']->deps;
325 $edit_key = array_search( 'edit', $wp_admin_dependencies );
326 if ( false === $edit_key ) {
327 return;
328 }
329
330 // Remove the edit dependency from wp-admin so it still loads, just without edit.css.
331 self::remove_wp_admin_dependency( $styles, 'edit' );
332 }
333
334 /**
335 * @since 6.0
336 *
337 * @param WP_Styles $styles
338 * @param string $key
339 * @return void
340 */
341 private static function remove_wp_admin_dependency( $styles, $key ) {
342 $dependencies = $styles->registered['wp-admin']->deps;
343 $index = array_search( $key, $dependencies );
344 if ( false === $index ) {
345 return;
346 }
347
348 unset( $dependencies[ $index ] );
349 $dependencies = array_values( $dependencies );
350
351 $styles->registered['wp-admin']->deps = $dependencies;
352 }
353 }
354