PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.12
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.12
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.12, at classes/helpers/FrmStylesPreviewHelper.php

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