PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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
← All changes | classes/helpers/FrmFormsHelper.php +821 -384 6.5.2 → trunk View file →
@@ -5,21 +5,43 @@
5 5
6 6 class FrmFormsHelper {
7 7
8 8 /**
9 + * Store and re-use field type data for the insert_opt_html function (to avoid multiple calls to FrmField::all_field_selection).
10 + *
11 + * @since 6.10
12 + *
13 + * @var array|null
14 + */
15 + private static $field_type_data_for_insert_opt_html;
16 +
17 + /**
9 18 * @since 2.2.10
19 + *
20 + * @return string
10 21 */
11 22 public static function form_error_class() {
12 23 return apply_filters( 'frm_form_error_class', 'frm_error_style' );
13 24 }
14 25
26 + /**
27 + * @param string $key
28 + * @param false|object $form
29 + *
30 + * @return string
31 + */
15 32 public static function get_direct_link( $key, $form = false ) {
16 33 $target_url = esc_url( admin_url( 'admin-ajax.php?action=frm_forms_preview&form=' . $key ) );
17 - $target_url = apply_filters( 'frm_direct_link', $target_url, $key, $form );
18 -
19 - return $target_url;
34 + return apply_filters( 'frm_direct_link', $target_url, $key, $form );
20 35 }
21 36
37 + /**
38 + * @param string $field_name
39 + * @param int|string $field_value
40 + * @param array $args
41 + *
42 + * @return void
43 + */
22 44 public static function forms_dropdown( $field_name, $field_value = '', $args = array() ) {
23 45 $defaults = array(
24 46 'blank' => true,
25 47 'field_id' => false,
@@ -34,8 +56,9 @@
34 56 $args['field_id'] = $field_name;
35 57 }
36 58
37 59 $query = array();
60 +
38 61 if ( $args['exclude'] ) {
39 62 $query['id !'] = $args['exclude'];
40 63 }
41 64
@@ -44,41 +67,47 @@
44 67 $add_html = array();
45 68 self::add_html_attr( $args['onchange'], 'onchange', $add_html );
46 69 self::add_html_attr( $args['class'], 'class', $add_html );
47 70
71 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
48 72 ?>
49 73 <select name="<?php echo esc_attr( $field_name ); ?>"
50 74 id="<?php echo esc_attr( $args['field_id'] ); ?>"
51 75 <?php echo wp_strip_all_tags( implode( ' ', $add_html ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
52 76 <?php if ( $args['blank'] ) { ?>
53 - <option value=""><?php echo ( $args['blank'] == 1 ) ? ' ' : '- ' . esc_attr( $args['blank'] ) . ' -'; ?></option>
77 + <option value=""><?php echo $args['blank'] == 1 ? ' ' : '- ' . esc_attr( $args['blank'] ) . ' -'; // phpcs:ignore Universal.Operators.StrictComparisons ?></option>
54 78 <?php } ?>
55 79 <?php foreach ( $forms as $form ) { ?>
56 80 <option value="<?php echo esc_attr( $form->id ); ?>" <?php selected( $field_value, $form->id ); ?>>
57 - <?php echo esc_html( '' === $form->name ? __( '(no title)', 'formidable' ) : FrmAppHelper::truncate( $form->name, 50 ) . ( $form->parent_form_id ? __( ' (child)', 'formidable' ) : '' ) ); ?>
81 + <?php echo esc_html( '' === $form->name ? self::get_no_title_text() : FrmAppHelper::truncate( $form->name, 50 ) . ( $form->parent_form_id ? __( ' (child)', 'formidable' ) : '' ) ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
58 82 </option>
59 83 <?php } ?>
60 84 </select>
61 85 <?php
86 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
62 87 }
63 88
64 89 /**
90 + * @since 2.0.6
91 + *
65 92 * @param string $class
66 93 * @param string $param
67 - * @param array $add_html
94 + * @param array $add_html
68 95 *
69 - * @since 2.0.6
96 + * @return void
70 97 */
71 98 public static function add_html_attr( $class, $param, &$add_html ) {
72 - if ( ! empty( $class ) ) {
73 - $add_html[ $param ] = sanitize_title( $param ) . '="' . esc_attr( trim( sanitize_text_field( $class ) ) ) . '"';
99 + if ( $class ) {
100 + $add_html[ $param ] = sanitize_title( $param ) . '="' . esc_attr( sanitize_text_field( $class ) ) . '"';
74 101 }
75 102 }
76 103
77 104 /**
78 - * @param string|object|false $selected - The label for the placeholder, or the form object.
105 + * @param false|object|string $selected - The label for the placeholder, or the form object.
106 + *
107 + * @return void
79 108 */
80 - public static function form_switcher( $selected = false ) {
109 + public static function form_switcher( $selected = false ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh, Generic.Metrics.CyclomaticComplexity.MaxExceeded, SlevomatCodingStandard.Files.LineLength.LineTooLong
81 110 $where = apply_filters( 'frm_forms_dropdown', array(), '' );
82 111 $forms = FrmForm::get_published_forms( $where );
83 112
84 113 $args = array(
@@ -84,8 +113,9 @@
84 113 $args = array(
85 114 'id' => 0,
86 115 'form' => 0,
87 116 );
117 +
88 118 if ( isset( $_GET['id'] ) && ! isset( $_GET['form'] ) ) {
89 119 unset( $args['form'] );
90 120 } elseif ( isset( $_GET['form'] ) && ! isset( $_GET['id'] ) ) {
91 121 unset( $args['id'] );
@@ -91,37 +121,43 @@
91 121 unset( $args['id'] );
92 122 }
93 123
94 124 $frm_action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
95 - if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $frm_action, array( 'edit', 'show', 'destroy', 'destroy_all' ) ) ) {
125 +
126 + if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $frm_action, array( 'edit', 'show', 'destroy', 'destroy_all' ), true ) ) {
96 127 $args['frm_action'] = 'list';
97 128 $args['form'] = 0;
98 - } elseif ( FrmAppHelper::is_admin_page( 'formidable' ) && in_array( $frm_action, array( 'new', 'duplicate' ) ) ) {
129 + } elseif ( FrmAppHelper::is_admin_page( 'formidable' ) && in_array( $frm_action, array( 'new', 'duplicate' ), true ) ) {
99 130 $args['frm_action'] = 'edit';
100 131 } elseif ( FrmAppHelper::is_style_editor_page() ) {
101 - unset( $args['id'] ); // Avoid passing style into form switcher on style page.
132 + // Avoid passing style into form switcher on style page.
133 + unset( $args['id'] );
102 134 $query_args = array(
103 135 'page' => 'formidable-styles',
104 136 );
137 +
105 138 if ( $frm_action ) {
106 139 $query_args['frm_action'] = $frm_action;
107 140 }
141 +
108 142 $base = add_query_arg( $query_args, admin_url( 'admin.php' ) );
109 143 } elseif ( isset( $_GET['post'] ) ) {
110 144 $args['form'] = 0;
111 145 $base = admin_url( 'edit.php?post_type=frm_display' );
112 - }
146 + }//end if
113 147
114 148 $form_id = 0;
149 +
115 150 if ( is_object( $selected ) ) {
116 151 $form_id = $selected->id;
117 152 $selected = $selected->name;
118 153 }
119 154
120 - $name = ( $selected === false ) ? __( 'Switch Form', 'formidable' ) : $selected;
121 - $name = '' === $name ? __( '(no title)', 'formidable' ) : strip_tags( $name );
155 + $name = $selected === false ? __( 'Switch Form', 'formidable' ) : $selected;
156 + $name = '' === $name || is_null( $name ) ? self::get_no_title_text() : strip_tags( $name );
122 157 $truncated_name = FrmAppHelper::truncate( $name, 25 );
123 158
159 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
124 160 if ( count( $forms ) < 2 ) {
125 161 ?>
126 162 <div id="frm_bs_dropdown">
127 163 <h1>
@@ -151,8 +187,10 @@
151 187 array(
152 188 'input_id' => 'dropform',
153 189 'placeholder' => __( 'Search Forms', 'formidable' ),
154 190 'tosearch' => 'frm-dropdown-form',
191 + // Specify a value to avoid the $_REQUEST['s'] default value.
192 + 'value' => '',
155 193 )
156 194 );
157 195 ?>
158 196 </li>
@@ -166,14 +204,15 @@
166 204
167 205 if ( isset( $args['id'] ) ) {
168 206 $args['id'] = $form->id;
169 207 }
208 +
170 209 if ( isset( $args['form'] ) ) {
171 210 $args['form'] = $form->id;
172 211 }
173 212
174 213 $url = isset( $base ) ? add_query_arg( $args, $base ) : add_query_arg( $args );
175 - $form_name = empty( $form->name ) ? __( '(no title)', 'formidable' ) : $form->name;
214 + $form_name = ! empty( $form->name ) ? $form->name : self::get_no_title_text();
176 215 ?>
177 216 <li class="frm-dropdown-form">
178 217 <a href="<?php echo esc_url( $url ); ?>" tabindex="-1" class="frm-justify-between">
179 218 <?php echo esc_html( $form_name ); ?>
@@ -190,54 +229,48 @@
190 229 </a>
191 230 </li>
192 231 <?php
193 232 unset( $form );
194 - }
233 + }//end foreach
195 234 ?>
196 235 </ul>
197 236 </div>
198 237 <?php
238 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
199 239 }
200 240
201 241 /**
202 - * @since 3.05
203 - * @deprecated 4.0
242 + * @param string $col
243 + * @param string $sort_col
244 + * @param string $sort_dir
204 245 *
205 - * @param array $values - The form array
246 + * @return void
206 247 */
207 - public static function builder_submit_button( $values ) {
208 - FrmDeprecated::builder_submit_button( $values );
209 - }
210 -
211 248 public static function get_sortable_classes( $col, $sort_col, $sort_dir ) {
212 - echo ( $sort_col == $col ) ? 'sorted' : 'sortable';
213 - echo ( $sort_col == $col && $sort_dir === 'desc' ) ? ' asc' : ' desc';
249 + echo $sort_col == $col ? 'sorted' : 'sortable'; // phpcs:ignore Universal.Operators.StrictComparisons
250 + echo $sort_col == $col && $sort_dir === 'desc' ? ' asc' : ' desc'; // phpcs:ignore Universal.Operators.StrictComparisons
214 251 }
215 252
216 253 /**
217 254 * @since 3.0
255 + *
256 + * @param array|string $field_type
257 + *
258 + * @return string
218 259 */
219 260 public static function get_field_link_name( $field_type ) {
220 - if ( is_array( $field_type ) ) {
221 - $field_label = $field_type['name'];
222 - } else {
223 - $field_label = $field_type;
224 - }
225 -
226 - return $field_label;
261 + return is_array( $field_type ) ? $field_type['name'] : $field_type;
227 262 }
228 263
229 264 /**
230 265 * @since 3.0
266 + *
267 + * @param array|string $field_type
268 + *
269 + * @return string
231 270 */
232 271 public static function get_field_link_icon( $field_type ) {
233 - if ( is_array( $field_type ) && isset( $field_type['icon'] ) ) {
234 - $icon = $field_type['icon'];
235 - } else {
236 - $icon = 'frm_icon_font frm_pencil_icon';
237 - }
238 -
239 - return $icon;
272 + return is_array( $field_type ) && isset( $field_type['icon'] ) ? $field_type['icon'] : 'frmfont frm_pencil_icon';
240 273 }
241 274
242 275 /**
243 276 * Get the invalid form error message
@@ -249,44 +282,71 @@
249 282 * @return string
250 283 */
251 284 public static function get_invalid_error_message( $args ) {
252 285 $settings_args = $args;
286 +
253 287 if ( isset( $args['form'] ) ) {
254 288 $settings_args['current_form'] = $args['form']->id;
255 289 }
256 290
257 291 $frm_settings = FrmAppHelper::get_settings( $settings_args );
258 - $invalid_msg = do_shortcode( $frm_settings->invalid_msg );
292 + $invalid_msg = do_shortcode( $frm_settings->invalid_msg );
259 293 return apply_filters( 'frm_invalid_error_message', $invalid_msg, $args );
260 294 }
261 295
262 296 /**
263 297 * @param array $atts {
298 + * The success message details.
299 + *
264 300 * @type string $message
265 301 * @type stdClass $form
266 302 * @type int $entry_id
267 303 * @type string $class
268 304 * }
305 + *
269 306 * @return string
270 307 */
271 308 public static function get_success_message( $atts ) {
272 309 $message = apply_filters( 'frm_content', $atts['message'], $atts['form'], $atts['entry_id'] );
273 - $message = do_shortcode( FrmAppHelper::use_wpautop( $message ) );
274 - $message = '<div class="' . esc_attr( $atts['class'] ) . '" role="status">' . $message . '</div>';
275 - return $message;
310 +
311 + // Only autop if the message includes line breaks.
312 + $autop = str_contains( $message, "\n" );
313 +
314 + /**
315 + * Filters whether to autop the success message.
316 + * This is false by default if the message does not include line breaks.
317 + *
318 + * @since 6.23
319 + *
320 + * @param bool $autop
321 + * @param string $message
322 + * @param object $form
323 + */
324 + $autop = (bool) apply_filters( 'frm_wpautop_success_message', $autop, $message, $atts['form'] );
325 +
326 + if ( $autop ) {
327 + $message = FrmAppHelper::use_wpautop( $message );
328 + }
329 +
330 + $message = do_shortcode( $message );
331 + return '<div class="' . esc_attr( $atts['class'] ) . '" role="status">' . $message . '</div>';
276 332 }
277 333
278 334 /**
279 335 * Used when a form is created
336 + *
337 + * @param array $values
338 + *
339 + * @return array
280 340 */
281 341 public static function setup_new_vars( $values = array() ) {
282 342 global $wpdb;
283 343
284 - if ( ! empty( $values ) ) {
344 + if ( $values ) {
285 345 $post_values = $values;
286 346 } else {
287 347 $values = array();
288 - $post_values = isset( $_POST ) ? $_POST : array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
348 + $post_values = ! empty( $_POST ) ? $_POST : array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
289 349 }
290 350
291 351 $defaults = array(
292 352 'name' => '',
@@ -291,8 +351,9 @@
291 351 $defaults = array(
292 352 'name' => '',
293 353 'description' => '',
294 354 );
355 +
295 356 foreach ( $defaults as $var => $default ) {
296 357 if ( ! isset( $values[ $var ] ) ) {
297 358 $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
298 359 }
@@ -307,8 +368,9 @@
307 368 'is_template' => 0,
308 369 'status' => 'published',
309 370 'parent_form_id' => 0,
310 371 );
372 +
311 373 foreach ( $defaults as $var => $default ) {
312 374 if ( ! isset( $values[ $var ] ) ) {
313 375 $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
314 376 }
@@ -315,9 +377,9 @@
315 377 }
316 378 unset( $defaults );
317 379
318 380 if ( ! isset( $values['form_key'] ) ) {
319 - $values['form_key'] = ( $post_values && isset( $post_values['form_key'] ) ) ? $post_values['form_key'] : FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_forms', 'form_key' );
381 + $values['form_key'] = $post_values && isset( $post_values['form_key'] ) ? $post_values['form_key'] : FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_forms', 'form_key' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
320 382 }
321 383
322 384 $values = self::fill_default_opts( $values, false, $post_values );
323 385 $values['custom_style'] = FrmAppHelper::custom_style_value( $post_values );
@@ -326,16 +388,22 @@
326 388 }
327 389
328 390 /**
329 391 * Used when editing a form
392 + *
393 + * @param array $values
394 + * @param object $record
395 + * @param array $post_values
396 + *
397 + * @return array
330 398 */
331 399 public static function setup_edit_vars( $values, $record, $post_values = array() ) {
332 - if ( empty( $post_values ) ) {
400 + if ( ! $post_values ) {
333 401 $post_values = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
334 402 }
335 403
336 - $values['form_key'] = isset( $post_values['form_key'] ) ? $post_values['form_key'] : $record->form_key;
337 - $values['is_template'] = isset( $post_values['is_template'] ) ? $post_values['is_template'] : $record->is_template;
404 + $values['form_key'] = $post_values['form_key'] ?? $record->form_key;
405 + $values['is_template'] = $post_values['is_template'] ?? $record->is_template;
338 406 $values['status'] = $record->status;
339 407
340 408 $values = self::fill_default_opts( $values, $record, $post_values );
341 409
@@ -341,23 +409,29 @@
341 409
342 410 return apply_filters( 'frm_setup_edit_form_vars', $values );
343 411 }
344 412
345 - public static function fill_default_opts( $values, $record, $post_values ) {
413 + /**
414 + * @param array $values
415 + * @param false|object $record
416 + * @param array|false $post_values
417 + *
418 + * @return array
419 + */
420 + public static function fill_default_opts( $values, $record, $post_values ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
346 421
347 - $defaults = self::get_default_opts();
348 - foreach ( $defaults as $var => $default ) {
422 + foreach ( self::get_default_opts() as $var => $default ) {
349 423 if ( is_array( $default ) ) {
350 424 if ( ! isset( $values[ $var ] ) ) {
351 - $values[ $var ] = ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : array();
425 + $values[ $var ] = $record && isset( $record->options[ $var ] ) ? $record->options[ $var ] : array();
352 426 }
353 427
354 428 foreach ( $default as $k => $v ) {
355 - $values[ $var ][ $k ] = ( $post_values && isset( $post_values[ $var ][ $k ] ) ) ? $post_values[ $var ][ $k ] : ( ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) ) ? $record->options[ $var ][ $k ] : $v );
429 + $values[ $var ][ $k ] = $post_values && isset( $post_values[ $var ][ $k ] ) ? $post_values[ $var ][ $k ] : ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) ? $record->options[ $var ][ $k ] : $v ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
356 430
357 431 if ( is_array( $v ) ) {
358 432 foreach ( $v as $k1 => $v1 ) {
359 - $values[ $var ][ $k ][ $k1 ] = ( $post_values && isset( $post_values[ $var ][ $k ][ $k1 ] ) ) ? $post_values[ $var ][ $k ][ $k1 ] : ( ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) && isset( $record->options[ $var ][ $k ][ $k1 ] ) ) ? $record->options[ $var ][ $k ][ $k1 ] : $v1 );
433 + $values[ $var ][ $k ][ $k1 ] = $post_values && isset( $post_values[ $var ][ $k ][ $k1 ] ) ? $post_values[ $var ][ $k ][ $k1 ] : ( $record && isset( $record->options[ $var ] ) && isset( $record->options[ $var ][ $k ] ) && isset( $record->options[ $var ][ $k ][ $k1 ] ) ? $record->options[ $var ][ $k ][ $k1 ] : $v1 ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
360 434 unset( $k1, $v1 );
361 435 }
362 436 }
363 437
@@ -363,13 +437,13 @@
363 437
364 438 unset( $k, $v );
365 439 }
366 440 } else {
367 - $values[ $var ] = ( $post_values && isset( $post_values['options'][ $var ] ) ) ? $post_values['options'][ $var ] : ( ( $record && isset( $record->options[ $var ] ) ) ? $record->options[ $var ] : $default );
441 + $values[ $var ] = $post_values && isset( $post_values['options'][ $var ] ) ? $post_values['options'][ $var ] : ( $record && isset( $record->options[ $var ] ) ? $record->options[ $var ] : $default ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
368 442 }
369 443
370 444 unset( $var, $default );
371 - }
445 + }//end foreach
372 446
373 447 return $values;
374 448 }
375 449
@@ -384,9 +458,9 @@
384 458 'success_action' => 'message',
385 459 'success_msg' => $frm_settings->success_msg,
386 460 'show_form' => 0,
387 461 'akismet' => '',
388 - 'honeypot' => 'basic',
462 + 'stopforumspam' => 0,
389 463 'antispam' => 0,
390 464 'no_save' => 0,
391 465 'ajax_load' => 0,
392 466 'js_validate' => 0,
@@ -401,17 +475,18 @@
401 475 );
402 476 }
403 477
404 478 /**
479 + * @since 2.0.6
480 + *
405 481 * @param array $options
406 482 * @param array $values
407 483 *
408 - * @since 2.0.6
484 + * @return void
409 485 */
410 486 public static function fill_form_options( &$options, $values ) {
411 - $defaults = self::get_default_opts();
412 - foreach ( $defaults as $var => $default ) {
413 - $options[ $var ] = isset( $values['options'][ $var ] ) ? $values['options'][ $var ] : $default;
487 + foreach ( self::get_default_opts() as $var => $default ) {
488 + $options[ $var ] = $values['options'][ $var ] ?? $default;
414 489 unset( $var, $default );
415 490 }
416 491 }
417 492
@@ -416,22 +491,24 @@
416 491 }
417 492
418 493 /**
419 494 * @param string $loc
495 + *
496 + * @return string
420 497 */
421 498 public static function get_default_html( $loc ) {
422 - if ( $loc == 'submit' ) {
499 + if ( $loc === 'submit' ) {
423 500 $draft_link = self::get_draft_link();
424 501 $start_over = self::get_start_over_shortcode();
425 502 $default_html = <<<SUBMIT_HTML
426 -<div class="frm_submit">
503 +<div class="frm_submit frm_flex">
504 +<button class="frm_button_submit" type="submit" [button_action]>[button_label]</button>
427 505 [if back_button]<button type="submit" name="frm_prev_page" formnovalidate="formnovalidate" class="frm_prev_page" [back_hook]>[back_label]</button>[/if back_button]
428 -<button class="frm_button_submit" type="submit" [button_action]>[button_label]</button>
429 506 $draft_link
430 507 $start_over
431 508 </div>
432 509 SUBMIT_HTML;
433 - } elseif ( $loc == 'before' ) {
510 + } elseif ( $loc === 'before' ) {
434 511 $default_html = <<<BEFORE_HTML
435 512 <legend class="frm_screen_reader">[form_name]</legend>
436 513 [if form_name]<h3 class="frm_form_title">[form_name]</h3>[/if form_name]
437 514 [if form_description]<div class="frm_description">[form_description]</div>[/if form_description]
@@ -442,12 +519,13 @@
442 519
443 520 return $default_html;
444 521 }
445 522
523 + /**
524 + * @return string
525 + */
446 526 public static function get_draft_link() {
447 - $link = '[if save_draft]<a href="#" tabindex="0" class="frm_save_draft" [draft_hook]>[draft_label]</a>[/if save_draft]';
448 -
449 - return $link;
527 + return '[if save_draft]<button class="frm_save_draft" [draft_hook]>[draft_label]</button>[/if save_draft]';
450 528 }
451 529
452 530 /**
453 531 * Gets start over button shortcode.
@@ -459,11 +537,21 @@
459 537 public static function get_start_over_shortcode() {
460 538 return '[if start_over]<a href="#" tabindex="0" class="frm_start_over" [start_over_hook]>[start_over_label]</a>[/if start_over]';
461 539 }
462 540
541 + /**
542 + * @param string $html
543 + * @param object $form
544 + * @param string $submit
545 + * @param object|null $form_action
546 + * @param array $values
547 + *
548 + * @return void
549 + */
463 550 public static function get_custom_submit( $html, $form, $submit, $form_action, $values ) {
464 551 $button = self::replace_shortcodes( $html, $form, $submit, $form_action, $values );
465 - if ( ! strpos( $button, '[button_action]' ) ) {
552 +
553 + if ( ! str_contains( $button, '[button_action]' ) ) {
466 554 echo FrmAppHelper::maybe_kses( $button ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
467 555 return;
468 556 }
469 557
@@ -470,18 +558,21 @@
470 558 /**
471 559 * @since 5.0.06
472 560 */
473 561 $button = apply_filters( 'frm_submit_button_html', $button, compact( 'form' ) );
562 +
474 563 if ( FrmAppHelper::should_never_allow_unfiltered_html() ) {
475 564 $button = FrmAppHelper::kses_submit_button( $button );
476 565 }
566 +
477 567 $button_parts = explode( '[button_action]', $button );
568 + $classes = apply_filters( 'frm_submit_button_class', array(), $form );
478 569
479 - $classes = apply_filters( 'frm_submit_button_class', array(), $form );
480 - if ( ! empty( $classes ) ) {
570 + if ( $classes ) {
481 571 $classes = implode( ' ', $classes );
482 - $button_class = ' class="frm_button_submit';
483 - if ( strpos( $button_parts[0], $button_class ) !== false ) {
572 + $button_class = 'frm_button_submit';
573 +
574 + if ( preg_match( '/\bclass="[^"]*?\b' . preg_quote( $button_class, '/' ) . '\b[^"]*?"/', $button_parts[0] ) ) {
484 575 $button_parts[0] = str_replace( $button_class, $button_class . ' ' . esc_attr( $classes ), $button_parts[0] );
485 576 } else {
486 577 $button_parts[0] .= ' class="' . esc_attr( $classes ) . '"';
487 578 }
@@ -493,54 +584,56 @@
493 584 }
494 585
495 586 /**
496 587 * @since 4.0
588 + *
589 + * @return array
497 590 */
498 591 public static function html_shortcodes() {
499 592 $codes = array(
500 - 'id' => array(
593 + 'id' => array(
501 594 'label' => __( 'Field ID', 'formidable' ),
502 595 'class' => 'show_field_custom_html',
503 596 ),
504 - 'key' => array(
597 + 'key' => array(
505 598 'label' => __( 'Field Key', 'formidable' ),
506 599 'class' => 'show_field_custom_html',
507 600 ),
508 - 'field_name' => array(
601 + 'field_name' => array(
509 602 'label' => __( 'Field Name', 'formidable' ),
510 603 'class' => 'show_field_custom_html',
511 604 ),
512 - 'description' => array(
605 + 'description' => array(
513 606 'label' => __( 'Field Description', 'formidable' ),
514 607 'class' => 'show_field_custom_html',
515 608 ),
516 - 'label_position' => array(
609 + 'label_position' => array(
517 610 'label' => __( 'Label Position', 'formidable' ),
518 611 'class' => 'show_field_custom_html',
519 612 ),
520 - 'required_label' => array(
613 + 'required_label' => array(
521 614 'label' => __( 'Required Label', 'formidable' ),
522 615 'class' => 'show_field_custom_html',
523 616 ),
524 - 'input' => array(
617 + 'input' => array(
525 618 'label' => __( 'Input Field', 'formidable' ),
526 619 'class' => 'show_field_custom_html',
527 620 ),
528 - 'input opt=1' => array(
621 + 'input opt=1' => array(
529 622 'label' => __( 'Single Option', 'formidable' ),
530 623 'title' => __( 'Show a single radio or checkbox option by replacing 1 with the order of the option', 'formidable' ),
531 624 'class' => 'show_field_custom_html',
532 625 ),
533 - 'input label=0' => array(
626 + 'input label=0' => array(
534 627 'label' => __( 'Hide Option Label', 'formidable' ),
535 628 'class' => 'show_field_custom_html',
536 629 ),
537 - 'required_class' => array(
630 + 'required_class' => array(
538 631 'label' => __( 'Required Class', 'formidable' ),
539 632 'title' => __( 'Add class name if field is required', 'formidable' ),
540 633 'class' => 'show_field_custom_html',
541 634 ),
542 - 'error_class' => array(
635 + 'error_class' => array(
543 636 'label' => __( 'Error Class', 'formidable' ),
544 637 'title' => __( 'Add class name if field has an error on form submit', 'formidable' ),
545 638 'class' => 'show_field_custom_html',
546 639 ),
@@ -561,13 +654,13 @@
561 654 'label' => __( 'Delete Entry Link', 'formidable' ),
562 655 'class' => 'show_before_html show_after_html',
563 656 ),
564 657
565 - 'button_label' => array(
658 + 'button_label' => array(
566 659 'label' => __( 'Button Label', 'formidable' ),
567 660 'class' => 'show_submit_html',
568 661 ),
569 - 'button_action' => array(
662 + 'button_action' => array(
570 663 'label' => __( 'Button Hook', 'formidable' ),
571 664 'class' => 'show_submit_html',
572 665 ),
573 666 );
@@ -579,14 +672,20 @@
579 672 }
580 673
581 674 /**
582 675 * @since 4.0
583 - * @param array $args
676 + *
677 + * @param array $args Includes 'id', 'key', 'name', 'type' and 'class'. Optionally 'id_label'
678 + * and 'key_label' to show something other than the id or key, and
679 + * 'name_suffix'/'key_suffix' for text appended after the name or key is
680 + * truncated, so a shortcode option like ' show=first' survives the truncation.
681 + *
682 + * @return void
584 683 */
585 684 public static function insert_opt_html( $args ) {
586 - $class = isset( $args['class'] ) ? $args['class'] : '';
587 - $fields = FrmField::all_field_selection();
588 - $field = isset( $fields[ $args['type'] ] ) ? $fields[ $args['type'] ] : array();
685 + $class = $args['class'] ?? '';
686 + $fields = self::get_field_type_data_for_insert_opt_html();
687 + $field = $fields[ $args['type'] ] ?? array();
589 688
590 689 self::prepare_field_type( $field );
591 690
592 691 if ( ! isset( $field['icon'] ) ) {
@@ -593,8 +692,9 @@
593 692 $field['icon'] = 'frmfont frm_pencil_icon';
594 693 }
595 694
596 695 $possible_email_field = FrmFieldFactory::field_has_property( $args['type'], 'holds_email_values' );
696 +
597 697 if ( $possible_email_field ) {
598 698 $class .= ' show_frm_not_email_to';
599 699 }
600 700
@@ -600,31 +700,69 @@
600 700
601 701 if ( 'url' === $args['type'] ) {
602 702 $class .= ' frm_insert_url';
603 703 }
704 +
705 + $full_name = $args['name'] . ( $args['name_suffix'] ?? '' );
706 + $truncated_name = FrmAppHelper::truncate( $args['name'], 60 ) . ( $args['name_suffix'] ?? '' );
707 +
708 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
604 709 ?>
605 710 <li class="<?php echo esc_attr( $class ); ?>">
606 - <a href="javascript:void(0)" class="frmids frm_insert_code"
607 - data-code="<?php echo esc_attr( $args['id'] ); ?>">
608 - <?php FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) ); ?>
609 - <?php echo esc_attr( FrmAppHelper::truncate( $args['name'], 60 ) ); ?>
610 - <span>[<?php echo esc_attr( isset( $args['id_label'] ) ? $args['id_label'] : $args['id'] ); ?>]</span>
711 + <a href="javascript:void(0)" class="frmids frm_insert_code" data-code="<?php echo esc_attr( $args['id'] ); ?>">
712 + <?php
713 + if ( isset( $field['icon'] ) ) {
714 + FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) );
715 + }
716 +
717 + printf(
718 + '<span title="%s">%s</span>',
719 + esc_attr( $full_name ),
720 + esc_html( $truncated_name )
721 + );
722 + ?>
723 + <span>[<?php echo esc_html( $args['id_label'] ?? $args['id'] ); ?>]</span>
611 724 </a>
612 - <a href="javascript:void(0)" class="frmkeys frm_insert_code frm_hidden"
613 - data-code="<?php echo esc_attr( $args['key'] ); ?>">
614 - <?php if ( isset( $field['icon'] ) ) { ?>
615 - <?php FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) ); ?>
616 - <?php } ?>
617 - <?php echo esc_attr( FrmAppHelper::truncate( $args['name'], 60 ) ); ?>
618 - <span>[<?php echo esc_attr( FrmAppHelper::truncate( isset( $args['key_label'] ) ? $args['key_label'] : $args['key'], 7 ) ); ?>]</span>
725 + <a href="javascript:void(0)" class="frmkeys frm_insert_code frm_hidden" data-code="<?php echo esc_attr( $args['key'] ); ?>">
726 + <?php
727 + if ( isset( $field['icon'] ) ) {
728 + FrmAppHelper::icon_by_class( $field['icon'], array( 'aria-hidden' => 'true' ) );
729 + }
730 +
731 + printf(
732 + '<span title="%s">%s</span>',
733 + esc_attr( $full_name ),
734 + esc_html( $truncated_name )
735 + );
736 + ?>
737 + <span>[<?php echo esc_html( FrmAppHelper::truncate( $args['key_label'] ?? $args['key'], 7 ) . ( $args['key_suffix'] ?? '' ) ); ?>]</span>
619 738 </a>
620 739 </li>
621 740 <?php
741 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
622 742 }
623 743
624 744 /**
745 + * Store and re-use field selection data for use when outputting shortcodes options in shortcode pop up.
746 + * This significantly improves performance by avoiding repeat calls to FrmField::all_field_selection.
747 + *
748 + * @since 6.10
749 + *
750 + * @return array
751 + */
752 + private static function get_field_type_data_for_insert_opt_html() {
753 + if ( ! isset( self::$field_type_data_for_insert_opt_html ) ) {
754 + self::$field_type_data_for_insert_opt_html = FrmField::all_field_selection();
755 + }
756 + return self::$field_type_data_for_insert_opt_html;
757 + }
758 +
759 + /**
625 760 * @since 4.0
761 + *
626 762 * @param array $args
763 + *
764 + * @return void
627 765 */
628 766 public static function insert_code_html( $args ) {
629 767 $defaults = array(
630 768 'class' => '',
@@ -635,20 +773,22 @@
635 773
636 774 $args = array_merge( $defaults, $args );
637 775 $has_tooltip = ! empty( $args['title'] );
638 776
777 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
639 778 ?>
640 779 <li class="<?php echo esc_attr( $args['class'] ); ?>">
641 780 <a href="javascript:void(0)" class="frm_insert_code <?php echo $has_tooltip ? 'frm_help' : ''; ?>"
642 781 <?php echo $has_tooltip ? 'title="' . esc_attr( $args['title'] ) . '"' : ''; ?>
643 782 data-code="<?php echo esc_attr( $args['code'] ); ?>">
644 - <?php echo esc_attr( FrmAppHelper::truncate( $args['label'], 60 ) ); ?>
783 + <?php echo esc_html( FrmAppHelper::truncate( $args['label'], 60 ) ); ?>
645 784 <span>
646 - [<?php echo esc_attr( FrmAppHelper::truncate( $args['code'], 10 ) ); ?>]
785 + [<?php echo esc_html( FrmAppHelper::truncate( $args['code'], 10 ) ); ?>]
647 786 </span>
648 787 </a>
649 788 </li>
650 789 <?php
790 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
651 791 }
652 792
653 793 /**
654 794 * Some field types in add-ons may have been added with only
@@ -654,14 +794,18 @@
654 794 * Some field types in add-ons may have been added with only
655 795 * a field type and name.
656 796 *
657 797 * @since 4.0
798 + *
799 + * @param array|string $field
800 + *
801 + * @return void
658 802 */
659 803 public static function prepare_field_type( &$field ) {
660 804 if ( ! is_array( $field ) ) {
661 805 $field = array(
662 806 'name' => $field,
663 - 'icon' => 'frm_icon_font frm_pencil_icon',
807 + 'icon' => 'frmfont frm_pencil_icon',
664 808 );
665 809 }
666 810 }
667 811
@@ -669,12 +813,16 @@
669 813 * Automatically add end section fields if they don't exist (2.0 migration)
670 814 *
671 815 * @since 2.0
672 816 *
673 - * @param boolean $reset_fields
817 + * @param object $form
818 + * @param array $fields
819 + * @param bool $reset_fields
820 + *
821 + * @return void
674 822 */
675 823 public static function auto_add_end_section_fields( $form, $fields, &$reset_fields ) {
676 - if ( empty( $fields ) ) {
824 + if ( ! $fields ) {
677 825 return;
678 826 }
679 827
680 828 $end_section_values = apply_filters( 'frm_before_field_created', FrmFieldsHelper::setup_new_vars( 'end_divider', $form->id ) );
@@ -681,11 +829,12 @@
681 829 $open = false;
682 830 $prev_order = false;
683 831 $add_order = 0;
684 832 $last_field = false;
833 +
685 834 foreach ( $fields as $field ) {
686 835 if ( $prev_order === $field->field_order ) {
687 - $add_order ++;
836 + ++$add_order;
688 837 }
689 838
690 839 if ( $add_order ) {
691 840 $reset_fields = true;
@@ -712,14 +861,14 @@
712 861 }
713 862
714 863 // There is already an end section here, so there is no need to create one.
715 864 $open = false;
716 - }
865 + }//end switch
717 866 $prev_order = $field->field_order;
718 867
719 868 $last_field = $field;
720 869 unset( $field );
721 - }
870 + }//end foreach
722 871
723 872 self::maybe_create_end_section( $open, $reset_fields, $add_order, $end_section_values, $last_field );
724 873 }
725 874
@@ -725,8 +874,17 @@
725 874
726 875 /**
727 876 * Create end section field if it doesn't exist. This is for migration from < 2.0
728 877 * Fix any ordering that may be messed up
878 + *
879 + * @param bool $open
880 + * @param bool $reset_fields
881 + * @param int $add_order
882 + * @param array $end_section_values
883 + * @param object $field
884 + * @param string $move
885 + *
886 + * @return void
729 887 */
730 888 public static function maybe_create_end_section( &$open, &$reset_fields, &$add_order, $end_section_values, $field, $move = 'no' ) {
731 889 if ( ! $open ) {
732 890 return;
@@ -735,18 +893,27 @@
735 893 $end_section_values['field_order'] = $field->field_order + 1;
736 894
737 895 FrmField::create( $end_section_values );
738 896
739 - if ( $move == 'move' ) {
740 - // bump the order of current field unless we're at the end of the form
897 + if ( $move === 'move' ) {
898 + // Bump the order of current field unless we're at the end of the form
741 899 FrmField::update( $field->id, array( 'field_order' => $field->field_order + 2 ) );
742 900 }
743 901
744 - $add_order += 2;
902 + $add_order += 2;
745 903 $open = false;
746 904 $reset_fields = true;
747 905 }
748 906
907 + /**
908 + * @param string $html
909 + * @param object $form
910 + * @param bool $title
911 + * @param bool $description
912 + * @param array $values
913 + *
914 + * @return string
915 + */
749 916 public static function replace_shortcodes( $html, $form, $title = false, $description = false, $values = array() ) {
750 917 $codes = array(
751 918 'form_name' => $title,
752 919 'form_description' => $description,
@@ -751,29 +918,30 @@
751 918 'form_name' => $title,
752 919 'form_description' => $description,
753 920 'entry_key' => true,
754 921 );
922 +
755 923 foreach ( $codes as $code => $show ) {
756 924 if ( $code === 'form_name' ) {
757 925 $replace_with = $form->name;
758 926 } elseif ( $code === 'form_description' ) {
759 927 $replace_with = FrmAppHelper::use_wpautop( $form->description );
760 - } elseif ( $code === 'entry_key' && isset( $_GET ) && isset( $_GET['entry'] ) ) {
761 - $replace_with = FrmAppHelper::simple_get( 'entry' );
928 + } elseif ( $code === 'entry_key' && ! empty( $_GET ) && isset( $_GET['entry'] ) ) {
929 + $replace_with = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
762 930 } else {
763 931 $replace_with = '';
764 932 }
765 933
766 - FrmShortcodeHelper::remove_inline_conditions( ( FrmAppHelper::is_true( $show ) && $replace_with != '' ), $code, $replace_with, $html );
934 + FrmShortcodeHelper::remove_inline_conditions( FrmAppHelper::is_true( $show ) && $replace_with != '', $code, $replace_with, $html ); // phpcs:ignore Universal.Operators.StrictComparisons, SlevomatCodingStandard.Files.LineLength.LineTooLong
767 935 }
768 936
769 - //replace [form_key]
937 + // Replace [form_key].
770 938 $html = str_replace( '[form_key]', $form->form_key, $html );
771 939
772 - //replace [frmurl]
940 + // Replace [frmurl].
773 941 $html = str_replace( '[frmurl]', FrmFieldsHelper::dynamic_default_values( 'frmurl' ), $html );
774 942
775 - if ( strpos( $html, '[button_label]' ) ) {
943 + if ( str_contains( $html, '[button_label]' ) ) {
776 944 add_filter( 'frm_submit_button', 'FrmFormsHelper::submit_button_label', 1 );
777 945 $submit_label = apply_filters( 'frm_submit_button', $title, $form );
778 946 $submit_label = esc_attr( do_shortcode( $submit_label ) );
779 947 $html = str_replace( '[button_label]', $submit_label, $html );
@@ -780,27 +948,32 @@
780 948 }
781 949
782 950 $html = apply_filters( 'frm_form_replace_shortcodes', $html, $form, $values );
783 951
784 - if ( strpos( $html, '[if back_button]' ) ) {
952 + if ( str_contains( $html, '[if back_button]' ) ) {
785 953 $html = preg_replace( '/(\[if\s+back_button\])(.*?)(\[\/if\s+back_button\])/mis', '', $html );
786 954 }
787 955
788 - if ( strpos( $html, '[if save_draft]' ) ) {
956 + if ( str_contains( $html, '[if save_draft]' ) ) {
789 957 $html = preg_replace( '/(\[if\s+save_draft\])(.*?)(\[\/if\s+save_draft\])/mis', '', $html );
790 958 }
791 959
792 - if ( strpos( $html, '[if start_over]' ) ) {
960 + if ( str_contains( $html, '[if start_over]' ) ) {
793 961 $html = preg_replace( '/(\[if\s+start_over\])(.*?)(\[\/if\s+start_over\])/mis', '', $html );
794 962 }
795 963
796 964 if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
797 - $html = do_shortcode( $html );
965 + return do_shortcode( $html );
798 966 }
799 967
800 968 return $html;
801 969 }
802 970
971 + /**
972 + * @param string $submit
973 + *
974 + * @return string
975 + */
803 976 public static function submit_button_label( $submit ) {
804 977 if ( ! $submit ) {
805 978 $frm_settings = FrmAppHelper::get_settings();
806 979 $submit = $frm_settings->submit_value;
@@ -813,28 +986,32 @@
813 986 * If the Formidable styling isn't being loaded,
814 987 * use inline styling to hide the element
815 988 *
816 989 * @since 2.03.05
990 + *
991 + * @return void
817 992 */
818 993 public static function maybe_hide_inline() {
819 994 $frm_settings = FrmAppHelper::get_settings();
820 - if ( $frm_settings->load_style == 'none' ) {
995 +
996 + if ( $frm_settings->load_style === 'none' ) {
821 997 echo ' style="display:none;"';
822 - } elseif ( $frm_settings->load_style == 'dynamic' ) {
998 + } elseif ( $frm_settings->load_style === 'dynamic' ) {
823 999 FrmStylesController::enqueue_style();
824 1000 }
825 1001 }
826 1002
1003 + /**
1004 + * @param array|bool|int|object|string $form
1005 + *
1006 + * @return string|null
1007 + */
827 1008 public static function get_form_style_class( $form = false ) {
828 1009 $style = self::get_form_style( $form );
829 1010 $class = ' with_frm_style';
830 1011
831 - if ( empty( $style ) ) {
832 - if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) ) {
833 - return $class;
834 - } else {
835 - return;
836 - }
1012 + if ( ! $style ) {
1013 + return FrmAppHelper::is_admin_page( 'formidable-entries' ) ? $class : null;
837 1014 }
838 1015
839 1016 // If submit button needs to be inline or centered.
840 1017 if ( is_object( $form ) ) {
@@ -855,11 +1032,9 @@
855 1032 } elseif ( 'center' === $submit_align ) {
856 1033 $class .= ' frm_center_submit';
857 1034 }
858 1035
859 - $class = apply_filters( 'frm_add_form_style_class', $class, $style, compact( 'form' ) );
860 -
861 - return $class;
1036 + return apply_filters( 'frm_add_form_style_class', $class, $style, compact( 'form' ) );
862 1037 }
863 1038
864 1039 /**
865 1040 * In order for frm_inline_submit to inline the submit button the form must also have the frm_inline_form that adds the grid-column style rules required for it to work.
@@ -866,22 +1041,23 @@
866 1041 *
867 1042 * @since 5.0.12
868 1043 *
869 1044 * @param array $form
1045 + *
870 1046 * @return bool
871 1047 */
872 1048 private static function form_should_be_inline_and_missing_class( $form ) {
873 - if ( isset( $form['form_class'] ) && false !== strpos( ' ' . $form['form_class'] . ' ', ' frm_inline_form ' ) ) {
874 - // not missing class, avoid adding it twice.
1049 + if ( isset( $form['form_class'] ) && str_contains( ' ' . $form['form_class'] . ' ', ' frm_inline_form ' ) ) {
1050 + // Not missing class, avoid adding it twice.
875 1051 return false;
876 1052 }
877 - return ! empty( $form['submit_html'] ) && false !== strpos( $form['submit_html'], 'frm_inline_submit' );
1053 + return ! empty( $form['submit_html'] ) && str_contains( $form['submit_html'], 'frm_inline_submit' );
878 1054 }
879 1055
880 1056 /**
881 1057 * Returns appropriate class if form has top labels
882 1058 *
883 - * @param $form
1059 + * @param array $form
884 1060 *
885 1061 * @return string
886 1062 */
887 1063 private static function maybe_align_fields_top( $form ) {
@@ -890,9 +1066,9 @@
890 1066
891 1067 /**
892 1068 * Determine if a form has fields with top labels so submit button can be aligned properly
893 1069 *
894 - * @param $form
1070 + * @param array $form
895 1071 *
896 1072 * @return bool
897 1073 */
898 1074 private static function form_has_top_labels( $form ) {
@@ -900,16 +1076,20 @@
900 1076 return false;
901 1077 }
902 1078
903 1079 $fields = $form['fields'];
1080 +
904 1081 if ( count( $fields ) <= 0 ) {
905 1082 return false;
906 1083 }
907 1084
908 - $fields = array_reverse( $fields ); // start from the fields closest to the submit button
1085 + // Start from the fields closest to the submit button.
1086 + $fields = array_reverse( $fields );
1087 +
909 1088 foreach ( $fields as $field ) {
910 - $type = isset( $field['original_type'] ) ? $field['original_type'] : $field['type'];
1089 + $type = $field['original_type'] ?? $field['type'];
911 1090 $has_input = FrmFieldFactory::field_has_property( $type, 'has_input' );
1091 +
912 1092 if ( $has_input ) {
913 1093 return self::field_has_top_label( $field, $form );
914 1094 }
915 1095 }
@@ -919,61 +1099,63 @@
919 1099
920 1100 /**
921 1101 * Check if a field's label position is set to "top"
922 1102 *
923 - * @param $field
924 - * @param $form
1103 + * @param array $field
1104 + * @param bool|object|string $form
925 1105 *
926 1106 * @return bool
927 1107 */
928 1108 private static function field_has_top_label( $field, $form ) {
929 1109 $label_position = FrmFieldsHelper::label_position( $field['label'], $field, $form );
930 -
931 - return in_array( $label_position, array( 'top', 'inside', 'hidden' ) );
1110 + return in_array( $label_position, array( 'top', 'inside', 'hidden' ), true );
932 1111 }
933 1112
934 1113 /**
935 - * @param object|string|boolean $form
1114 + * @param array|bool|int|object|string $form
936 1115 *
937 - * @return string
1116 + * @return int|string
938 1117 */
939 1118 public static function get_form_style( $form ) {
940 1119 $style = 1;
941 - if ( empty( $form ) || 'default' === $form ) {
1120 +
1121 + if ( ! $form || 'default' === $form ) {
942 1122 return $style;
943 - } elseif ( is_object( $form ) && $form->parent_form_id ) {
944 - // get the parent form if this is a child
1123 + }
1124 +
1125 + if ( is_object( $form ) && $form->parent_form_id ) {
1126 + // Get the parent form if this is a child
945 1127 $form = $form->parent_form_id;
946 - } elseif ( is_array( $form ) && isset( $form['parent_form_id'] ) && $form['parent_form_id'] ) {
1128 + } elseif ( is_array( $form ) && ! empty( $form['parent_form_id'] ) ) {
947 1129 $form = $form['parent_form_id'];
948 1130 } elseif ( is_array( $form ) && isset( $form['custom_style'] ) ) {
949 1131 $style = $form['custom_style'];
950 1132 }
951 1133
952 - if ( $form && is_string( $form ) ) {
1134 + if ( $form && ( is_string( $form ) || is_int( $form ) ) ) {
953 1135 $form = FrmForm::getOne( $form );
954 1136 }
955 1137
956 - $style = ( $form && is_object( $form ) && isset( $form->options['custom_style'] ) ) ? $form->options['custom_style'] : $style;
957 -
958 - return $style;
1138 + return $form && is_object( $form ) && isset( $form->options['custom_style'] ) ? $form->options['custom_style'] : $style;
959 1139 }
960 1140
961 1141 /**
962 1142 * Display the validation error messages when an entry is submitted
963 1143 *
964 - * @param array $args - includes img, errors
1144 + * @since 2.0.6
965 1145 *
966 - * @since 2.0.6
1146 + * @param array $args Includes img, errors.
1147 + *
1148 + * @return void
967 1149 */
968 1150 public static function show_errors( $args ) {
969 1151 $invalid_msg = self::get_invalid_error_message( $args );
970 1152
971 - if ( empty( $invalid_msg ) ) {
972 - $show_img = false;
973 - } else {
1153 + if ( $invalid_msg ) {
974 1154 echo wp_kses_post( $invalid_msg );
975 1155 $show_img = true;
1156 + } else {
1157 + $show_img = false;
976 1158 }
977 1159
978 1160 self::show_error(
979 1161 array(
@@ -988,19 +1170,22 @@
988 1170 * Display the error message in the front-end along with the image if set
989 1171 * The image was removed from the styling settings, but it may still be set with a hook
990 1172 * If the message in the global settings is empty, show every validation message in the error box
991 1173 *
992 - * @param array $args - includes img, errors, and show_img
1174 + * @since 2.0.6
993 1175 *
994 - * @since 2.0.6
1176 + * @param array $args Includes img, errors, and show_img.
1177 + *
1178 + * @return void
995 1179 */
996 1180 public static function show_error( $args ) {
997 - // remove any blank messages
1181 + // Remove any blank messages
998 1182 $args['errors'] = array_filter( (array) $args['errors'] );
999 1183
1000 1184 $line_break_first = $args['show_img'];
1185 +
1001 1186 foreach ( $args['errors'] as $error_key => $error ) {
1002 - if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key == 'cptch_number' || strpos( $error_key, 'field' ) === 0 ) ) {
1187 + if ( $line_break_first && ! is_numeric( $error_key ) && ( $error_key === 'cptch_number' || str_starts_with( $error_key, 'field' ) ) ) {
1003 1188 continue;
1004 1189 }
1005 1190
1006 1191 $id = str_replace( 'field', 'field_', $error_key );
@@ -1006,9 +1191,9 @@
1006 1191 $id = str_replace( 'field', 'field_', $error_key );
1007 1192 echo '<div id="' . esc_attr( $id ) . '_error">';
1008 1193
1009 1194 if ( $args['show_img'] && ! empty( $args['img'] ) ) {
1010 - echo '<img src="' . esc_attr( $args['img'] ) . '" alt="" />';
1195 + echo '<img src="' . esc_url( $args['img'] ) . '" alt="" />';
1011 1196 } else {
1012 1197 $args['show_img'] = true;
1013 1198 }
1014 1199
@@ -1017,15 +1202,27 @@
1017 1202 echo '</div>';
1018 1203 }
1019 1204 }
1020 1205
1206 + /**
1207 + * @param int|string $id
1208 + *
1209 + * @return void
1210 + */
1021 1211 public static function maybe_get_scroll_js( $id ) {
1022 1212 $offset = apply_filters( 'frm_scroll_offset', 4, array( 'form_id' => $id ) );
1213 +
1214 + // phpcs:ignore Universal.Operators.StrictComparisons
1023 1215 if ( $offset != - 1 ) {
1024 1216 self::get_scroll_js( $id );
1025 1217 }
1026 1218 }
1027 1219
1220 + /**
1221 + * @param int|string $form_id
1222 + *
1223 + * @return void
1224 + */
1028 1225 public static function get_scroll_js( $form_id ) {
1029 1226 echo '<script type="text/javascript">document.addEventListener(\'DOMContentLoaded\',function(){frmFrontForm.scrollMsg(' . (int) $form_id . ');})</script>';
1030 1227 }
1031 1228
@@ -1030,22 +1227,14 @@
1030 1227 }
1031 1228
1032 1229 /**
1033 1230 * @since 3.0
1231 + *
1232 + * @param int|object|string $form_id
1233 + * @param mixed $form
1234 + *
1235 + * @return array
1034 1236 */
1035 - public static function actions_dropdown( $atts ) {
1036 - if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
1037 - $status = $atts['status'];
1038 - $form_id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
1039 - $trash_link = self::delete_trash_info( $form_id, $status );
1040 - $links = self::get_action_links( $form_id, $status );
1041 - include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
1042 - }
1043 - }
1044 -
1045 - /**
1046 - * @since 3.0
1047 - */
1048 1237 public static function get_action_links( $form_id, $form ) {
1049 1238 if ( ! is_object( $form ) ) {
1050 1239 $form = FrmForm::getOne( $form_id );
1051 1240 }
@@ -1051,9 +1240,10 @@
1051 1240 }
1052 1241
1053 1242 $actions = array();
1054 1243 $trash_links = self::delete_trash_links( $form_id );
1055 - if ( 'trash' == $form->status ) {
1244 +
1245 + if ( 'trash' === $form->status ) {
1056 1246 $actions['restore'] = $trash_links['restore'];
1057 1247
1058 1248 if ( current_user_can( 'frm_delete_forms' ) ) {
1059 1249 $actions['trash'] = $trash_links['delete'];
@@ -1059,28 +1249,34 @@
1059 1249 $actions['trash'] = $trash_links['delete'];
1060 1250 }
1061 1251 } elseif ( current_user_can( 'frm_edit_forms' ) ) {
1062 1252 $duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $form_id;
1253 +
1063 1254 if ( $form->is_template ) {
1064 1255 $actions['frm_duplicate'] = array(
1065 1256 'url' => wp_nonce_url( $duplicate_link ),
1066 1257 'label' => __( 'Create Form from Template', 'formidable' ),
1067 - 'icon' => 'frm_icon_font frm_clone_icon',
1258 + 'icon' => 'frmfont frm_clone_icon',
1068 1259 );
1069 1260 } else {
1070 1261 $actions['duplicate'] = array(
1071 1262 'url' => wp_nonce_url( $duplicate_link ),
1072 - 'label' => __( 'Duplicate Form', 'formidable' ),
1073 - 'icon' => 'frm_icon_font frm_clone_icon',
1263 + 'label' => __( 'Duplicate', 'formidable' ),
1264 + 'icon' => 'frmfont frm_clone_icon',
1074 1265 );
1075 1266 }
1076 1267
1077 1268 $actions['trash'] = self::delete_trash_info( $form_id, $form->status );
1078 - }
1269 + }//end if
1079 1270
1080 1271 return $actions;
1081 1272 }
1082 1273
1274 + /**
1275 + * @param int|object|string $data
1276 + *
1277 + * @return string
1278 + */
1083 1279 public static function edit_form_link( $data ) {
1084 1280 $form_id = self::get_form_id_from_data( $data );
1085 1281
1086 1282 if ( ! $form_id ) {
@@ -1087,94 +1283,122 @@
1087 1283 return '';
1088 1284 }
1089 1285
1090 1286 $label = self::edit_form_link_label( $data );
1091 - $link = '<a href="' . esc_url( FrmForm::get_edit_link( $form_id ) ) . '">' . esc_html( $label ) . '</a>';
1092 - return $link;
1287 + return '<a href="' . esc_url( FrmForm::get_edit_link( $form_id ) ) . '">' . esc_html( $label ) . '</a>';
1093 1288 }
1094 1289
1290 + /**
1291 + * Returns a text used when no title is set.
1292 + *
1293 + * @since 6.16.1
1294 + *
1295 + * @return string
1296 + */
1297 + public static function get_no_title_text() {
1298 + return __( '(no title)', 'formidable' );
1299 + }
1300 +
1301 + /**
1302 + * @param int|object|string $data
1303 + *
1304 + * @return string
1305 + */
1095 1306 public static function edit_form_link_label( $data ) {
1096 1307 $name = self::get_form_name_from_data( $data );
1308 +
1097 1309 if ( ! $name ) {
1098 - return __( '(no title)', 'formidable' );
1310 + return self::get_no_title_text();
1099 1311 }
1312 +
1100 1313 return FrmAppHelper::truncate( $name, 40 );
1101 1314 }
1102 1315
1103 1316 /**
1104 - * @param mixed data
1105 - * @return int
1317 + * @param int|object|string $data
1318 + *
1319 + * @return int|string
1106 1320 */
1107 1321 private static function get_form_id_from_data( $data ) {
1108 - if ( is_object( $data ) ) {
1109 - $form_id = $data->id;
1110 - } else {
1111 - $form_id = $data;
1112 - }
1113 - return $form_id;
1322 + return is_object( $data ) ? $data->id : $data;
1114 1323 }
1115 1324
1116 1325 /**
1117 1326 * @param mixed $data
1327 + *
1118 1328 * @return string
1119 1329 */
1120 1330 private static function get_form_name_from_data( $data ) {
1121 1331 if ( is_object( $data ) ) {
1122 - $form_name = $data->name;
1123 - } else {
1124 - $form_id = $data;
1125 - $form_name = FrmForm::getName( $form_id );
1332 + return $data->name;
1126 1333 }
1127 - return $form_name;
1334 +
1335 + $form_id = $data;
1336 + return FrmForm::getName( $form_id );
1128 1337 }
1129 1338
1339 + /**
1340 + * @param int $id
1341 + * @param string $status
1342 + * @param string $length
1343 + *
1344 + * @return string
1345 + */
1130 1346 public static function delete_trash_link( $id, $status, $length = 'label' ) {
1131 1347 $link_details = self::delete_trash_info( $id, $status );
1132 -
1133 1348 return self::format_link_html( $link_details, $length );
1134 1349 }
1135 1350
1136 1351 /**
1137 1352 * @since 3.0
1353 + *
1354 + * @param array $link_details
1355 + * @param string $length
1356 + *
1357 + * @return string
1138 1358 */
1139 1359 public static function format_link_html( $link_details, $length = 'label' ) {
1140 1360 $link = '';
1141 - if ( ! empty( $link_details ) ) {
1142 - $link = '<a href="' . esc_url( $link_details['url'] ) . '" class="frm-trash-link"';
1143 - if ( isset( $link_details['data'] ) ) {
1144 - foreach ( $link_details['data'] as $data => $value ) {
1145 - $link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
1146 - }
1147 - } elseif ( isset( $link_details['confirm'] ) ) {
1148 - $link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
1361 +
1362 + if ( ! $link_details ) {
1363 + return $link;
1364 + }
1365 +
1366 + $link = '<a href="' . esc_url( $link_details['url'] ) . '" class="frm-trash-link"';
1367 +
1368 + if ( isset( $link_details['data'] ) ) {
1369 + foreach ( $link_details['data'] as $data => $value ) {
1370 + $link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
1149 1371 }
1372 + } elseif ( isset( $link_details['confirm'] ) ) {
1373 + $link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
1374 + }
1150 1375
1151 - $label = ( isset( $link_details[ $length ] ) ? $link_details[ $length ] : $link_details['label'] );
1152 - if ( $length == 'icon' && isset( $link_details[ $length ] ) ) {
1153 - $label = '<span class="' . $label . '" title="' . esc_attr( $link_details['label'] ) . '" aria-hidden="true"></span>';
1154 - $link .= ' aria-label="' . esc_attr( $link_details['label'] ) . '"';
1155 - }
1376 + $label = $link_details[ $length ] ?? $link_details['label'];
1156 1377
1157 - $link .= '>' . $label . '</a>';
1378 + if ( $length === 'icon' && isset( $link_details[ $length ] ) ) {
1379 + $label = '<span class="' . $label . '" title="' . esc_attr( $link_details['label'] ) . '" aria-hidden="true"></span>';
1380 + $link .= ' aria-label="' . esc_attr( $link_details['label'] ) . '"';
1158 1381 }
1159 1382
1160 - return $link;
1383 + return $link . ( '>' . $label . '</a>' );
1161 1384 }
1162 1385
1163 1386 /**
1164 1387 * @since 3.0
1388 + *
1389 + * @param int $id
1390 + * @param string $status
1391 + *
1392 + * @return array
1165 1393 */
1166 1394 public static function delete_trash_info( $id, $status ) {
1167 1395 $labels = self::delete_trash_links( $id );
1168 1396
1169 - if ( 'trash' == $status ) {
1397 + if ( 'trash' === $status ) {
1170 1398 $info = $labels['restore'];
1171 1399 } elseif ( current_user_can( 'frm_delete_forms' ) ) {
1172 - if ( EMPTY_TRASH_DAYS ) {
1173 - $info = $labels['trash'];
1174 - } else {
1175 - $info = $labels['delete'];
1176 - }
1400 + $info = EMPTY_TRASH_DAYS ? $labels['trash'] : $labels['delete'];
1177 1401 } else {
1178 1402 $info = array();
1179 1403 }
1180 1404
@@ -1182,10 +1406,14 @@
1182 1406 }
1183 1407
1184 1408 /**
1185 1409 * @since 3.0
1410 + *
1411 + * @param int $id
1412 + *
1413 + * @return array
1186 1414 */
1187 - private static function delete_trash_links( $id ) {
1415 + public static function delete_trash_links( $id ) {
1188 1416 $current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
1189 1417 $base_url = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
1190 1418
1191 1419 return array(
@@ -1197,9 +1425,9 @@
1197 1425 'trash' => array(
1198 1426 'label' => __( 'Move Form to Trash', 'formidable' ),
1199 1427 'short' => __( 'Trash', 'formidable' ),
1200 1428 'url' => wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . absint( $id ) ),
1201 - 'icon' => 'frm_icon_font frm_delete_icon',
1429 + 'icon' => 'frmfont frm_delete_icon',
1202 1430 'data' => array(
1203 1431 'frmverify' => __( 'Do you want to move this form to the trash?', 'formidable' ),
1204 1432 'frmverify-btn' => 'frm-button-red',
1205 1433 ),
@@ -1208,9 +1436,9 @@
1208 1436 'label' => __( 'Delete Permanently', 'formidable' ),
1209 1437 'short' => __( 'Delete', 'formidable' ),
1210 1438 'url' => wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . absint( $id ) ),
1211 1439 'confirm' => __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ),
1212 - 'icon' => 'frm_icon_font frm_delete_icon',
1440 + 'icon' => 'frmfont frm_delete_icon',
1213 1441 'data' => array(
1214 1442 'frmverify' => __( 'This will permanently delete the form and all its entries. This is irreversible. Are you sure you want to continue?', 'formidable' ),
1215 1443 'frmverify-btn' => 'frm-button-red',
1216 1444 ),
@@ -1219,36 +1447,38 @@
1219 1447 }
1220 1448
1221 1449 /**
1222 1450 * @since 3.0
1451 + *
1452 + * @return array
1223 1453 */
1224 1454 public static function css_classes() {
1225 1455 $classes = array(
1226 - 'frm_total' => array(
1456 + 'frm_total' => array(
1227 1457 'label' => __( 'Total', 'formidable' ),
1228 1458 'title' => __( 'Add this to a read-only field to display the text in bold without a border or background.', 'formidable' ),
1229 1459 ),
1230 - 'frm_total_big' => array(
1460 + 'frm_total_big' => array(
1231 1461 'label' => __( 'Big Total', 'formidable' ),
1232 1462 'title' => __( 'Add this to a read-only field to display the text in large, bold text without a border or background.', 'formidable' ),
1233 1463 ),
1234 - 'frm_scroll_box' => array(
1464 + 'frm_scroll_box' => array(
1235 1465 'label' => __( 'Scroll Box', 'formidable' ),
1236 - 'title' => __( 'If you have many checkbox or radio button options, you may add this class to allow your user to easily scroll through the options. Or add a scrolling area around content in an HTML field.', 'formidable' ),
1466 + 'title' => __( 'If you have many checkbox or radio button options, you may add this class to allow your user to easily scroll through the options. Or add a scrolling area around content in an HTML field.', 'formidable' ), // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
1237 1467 ),
1238 - 'frm_first' => array(
1468 + 'frm_first' => array(
1239 1469 'label' => __( 'First', 'formidable' ),
1240 1470 'title' => __( 'Add this to the first field in each row along with a width. ie frm_first frm4', 'formidable' ),
1241 1471 ),
1242 - 'frm_alignright' => __( 'Right', 'formidable' ),
1243 - 'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
1244 - 'frm_grid' => __( 'Even Grid Row', 'formidable' ),
1245 - 'frm_grid_odd' => __( 'Odd Grid Row', 'formidable' ),
1472 + 'frm_alignright' => __( 'Right', 'formidable' ),
1473 + 'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
1474 + 'frm_grid' => __( 'Even Grid Row', 'formidable' ),
1475 + 'frm_grid_odd' => __( 'Odd Grid Row', 'formidable' ),
1246 1476 'frm_color_block' => array(
1247 1477 'label' => __( 'Color Block', 'formidable' ),
1248 1478 'title' => __( 'Add a background color to the field or section.', 'formidable' ),
1249 1479 ),
1250 - 'frm_capitalize' => array(
1480 + 'frm_capitalize' => array(
1251 1481 'label' => __( 'Capitalize', 'formidable' ),
1252 1482 'title' => __( 'Automatically capitalize the first letter in each word.', 'formidable' ),
1253 1483 ),
1254 1484 );
@@ -1255,8 +1485,11 @@
1255 1485
1256 1486 return apply_filters( 'frm_layout_classes', $classes );
1257 1487 }
1258 1488
1489 + /**
1490 + * @return array
1491 + */
1259 1492 public static function grid_classes() {
1260 1493 return array(
1261 1494 'frm_half' => '1/2',
1262 1495 'frm_third' => '1/3',
@@ -1270,12 +1503,18 @@
1270 1503 }
1271 1504
1272 1505 /**
1273 1506 * @since 3.0
1507 + *
1508 + * @param mixed $style
1509 + * @param string $class
1510 + *
1511 + * @return string
1274 1512 */
1275 1513 public static function style_class_label( $style, $class ) {
1276 1514 $label = '';
1277 - if ( empty( $style ) ) {
1515 +
1516 + if ( ! $style ) {
1278 1517 $label = $class;
1279 1518 } elseif ( ! is_array( $style ) ) {
1280 1519 $label = $style;
1281 1520 } elseif ( isset( $style['label'] ) ) {
@@ -1284,8 +1523,13 @@
1284 1523
1285 1524 return $label;
1286 1525 }
1287 1526
1527 + /**
1528 + * @param string $status
1529 + *
1530 + * @return string
1531 + */
1288 1532 public static function status_nice_name( $status ) {
1289 1533 $nice_names = array(
1290 1534 'draft' => __( 'Draft', 'formidable' ),
1291 1535 'trash' => __( 'Trash', 'formidable' ),
@@ -1291,111 +1535,107 @@
1291 1535 'trash' => __( 'Trash', 'formidable' ),
1292 1536 'publish' => __( 'Published', 'formidable' ),
1293 1537 );
1294 1538
1295 - if ( ! in_array( $status, array_keys( $nice_names ) ) ) {
1539 + if ( ! array_key_exists( $status, $nice_names ) ) {
1296 1540 $status = 'publish';
1297 1541 }
1298 1542
1299 - $name = $nice_names[ $status ];
1300 -
1301 - return $name;
1543 + return $nice_names[ $status ];
1302 1544 }
1303 1545
1304 1546 /**
1305 - * @param array $categories
1547 + * Renders a template icon based on the given categories.
1548 + *
1549 + * @param array $categories The categories to render the icon for.
1306 1550 * @param array $atts {
1307 - * @type string $html 'span' or 'div'.
1308 - * @type boolean $bg Whether to add a bg color or not.
1551 + * Optional. An array of attributes for rendering.
1552 + *
1553 + * @type string $html 'span' or 'div'. Default 'span'.
1554 + * @type bool $bg Whether to add a background color or not. Default false.
1309 1555 * }
1310 1556 *
1311 1557 * @return void
1312 1558 */
1313 1559 public static function template_icon( $categories, $atts = array() ) {
1560 + // Define defaults.
1314 1561 $defaults = array(
1315 - 'html' => 'span',
1316 - 'bg' => false,
1562 + 'bg' => true,
1317 1563 );
1318 - $atts = array_merge( $defaults, $atts );
1564 + $atts = array_merge( $defaults, $atts );
1319 1565
1320 - $ignore = self::ignore_template_categories();
1566 + // Filter out ignored categories.
1567 + $ignore = self::get_license_types();
1321 1568 $categories = array_diff( $categories, $ignore );
1322 1569
1570 + // Define icons mapping.
1323 1571 $icons = array(
1324 - 'WooCommerce' => array( 'woocommerce', 'var(--purple)' ),
1325 - 'Post' => array( 'wordpress', 'rgb(0,160,210)' ),
1326 - 'User Registration' => array( 'register', 'var(--pink)' ),
1572 + 'WooCommerce' => array( 'woocommerce', 'var(--purple)' ),
1573 + 'Post' => array( 'wordpress', 'rgb(0,160,210)' ),
1574 + 'User Registration' => array( 'register', 'var(--pink)' ),
1327 1575 'Registration and Signup' => array( 'register', 'var(--pink)' ),
1328 - 'PayPal' => array( 'paypal' ),
1329 - 'Stripe' => array( 'credit_card', 'var(--green)' ),
1330 - 'Twilio' => array( 'sms' ),
1331 - 'Payment' => array( 'credit_card' ),
1332 - 'Order Form' => array( 'product' ),
1333 - 'Finance' => array( 'total' ),
1334 - 'Health and Wellness' => array( 'heart', 'var(--pink)' ),
1335 - 'Event Planning' => array( 'calendar', 'var(--orange)' ),
1336 - 'Real Estate' => array( 'house' ),
1337 - 'Nonprofit' => array( 'heart_solid' ),
1338 - 'Calculator' => array( 'calculator', 'var(--purple)' ),
1339 - 'Quiz' => array( 'percent' ),
1340 - 'Registrations' => array( 'address_card' ),
1341 - 'Customer Service' => array( 'users_solid' ),
1342 - 'Education' => array( 'pencil' ),
1343 - 'Marketing' => array( 'eye' ),
1344 - 'Feedback' => array( 'smile' ),
1345 - 'Business Operations' => array( 'case' ),
1346 - 'Contact Form' => array( 'email' ),
1347 - 'Conversational Forms' => array( 'chat_forms' ),
1348 - 'Survey' => array( 'chat_forms', 'var(--orange)' ),
1349 - 'Application' => array( 'align_right' ),
1350 - 'Signature' => array( 'signature' ),
1351 - '' => array( 'align_right' ),
1576 + 'PayPal' => array( 'paypal' ),
1577 + 'Stripe' => array( 'credit_card', 'var(--green)' ),
1578 + 'Twilio' => array( 'sms' ),
1579 + 'Payment' => array( 'credit_card' ),
1580 + 'Order Form' => array( 'product' ),
1581 + 'Finance' => array( 'total' ),
1582 + 'Health and Wellness' => array( 'heart', 'var(--pink)' ),
1583 + 'Event Planning' => array( 'calendar', 'var(--orange)' ),
1584 + 'Real Estate' => array( 'house' ),
1585 + 'Nonprofit' => array( 'heart_solid' ),
1586 + 'Calculator' => array( 'calculator', 'var(--purple)' ),
1587 + 'Quiz' => array( 'percent' ),
1588 + 'Registrations' => array( 'address_card' ),
1589 + 'Customer Service' => array( 'users_solid' ),
1590 + 'Education' => array( 'pencil' ),
1591 + 'Marketing' => array( 'eye' ),
1592 + 'Feedback' => array( 'smile' ),
1593 + 'Business Operations' => array( 'case' ),
1594 + 'Contact Form' => array( 'email' ),
1595 + 'Conversational Forms' => array( 'chat_forms' ),
1596 + 'Survey' => array( 'chat_forms', 'var(--orange)' ),
1597 + 'Application' => array( 'align_right' ),
1598 + 'Signature' => array( 'signature' ),
1599 + '' => array( 'align_right' ),
1352 1600 );
1353 1601
1354 - $icons[ __( 'My Templates', 'formidable' ) ] = array( 'user', 'var(--orange)' );
1355 -
1602 + // Determine the icon to be used.
1356 1603 $icon = $icons[''];
1357 1604
1358 1605 if ( count( $categories ) === 1 ) {
1359 1606 $category = reset( $categories );
1360 - $icon = isset( $icons[ $category ] ) ? $icons[ $category ] : $icon;
1361 - } elseif ( ! empty( $categories ) ) {
1362 - foreach ( $icons as $cat => $icon ) {
1363 - if ( ! in_array( $cat, $categories ) ) {
1364 - unset( $icons[ $cat ] );
1365 - }
1366 - }
1367 - $icon = reset( $icons );
1607 + $icon = $icons[ $category ] ?? $icon;
1608 + } elseif ( $categories ) {
1609 + $icons = array_intersect_key( $icons, array_flip( $categories ) );
1610 + $icon = reset( $icons );
1368 1611 }
1369 1612
1370 - $bg = isset( $icon[1] ) ? $icon[1] : '';
1613 + // Prepare variables for output.
1614 + $icon_name = $icon[0];
1615 + $bg_color = $icon[1] ?? '';
1371 1616
1372 - if ( $atts['html'] === 'div' ) {
1373 - echo '<div class="frm-category-icon frm-icon-wrapper" role="button"';
1374 - } else {
1375 - echo '<span class="frm-inner-circle"';
1617 + // Render the icon.
1618 + echo '<span class="frm-category-icon frm-icon-wrapper"';
1619 +
1620 + if ( $bg_color && $atts['bg'] ) {
1621 + echo ' style="background-color:' . esc_attr( $bg_color ) . '"';
1376 1622 }
1377 - echo empty( $bg ) || empty( $atts['bg'] ) ? '' : ' style="background-color:' . esc_attr( $bg ) . '"';
1623 +
1378 1624 echo '>';
1379 -
1380 - FrmAppHelper::icon_by_class( 'frmfont frm_' . $icon[0] . '_icon' );
1381 - echo '<span class="frm_hidden">';
1382 - FrmAppHelper::icon_by_class( 'frmfont frm_lock_icon' );
1625 + FrmAppHelper::icon_by_class( 'frmfont frm_' . $icon_name . '_icon' );
1383 1626 echo '</span>';
1384 - echo '</' . esc_attr( $atts['html'] ) . '>';
1385 1627 }
1386 1628
1387 1629 /**
1388 - * @since 4.03.01
1630 + * Get template install link.
1389 1631 *
1390 - * @return array<string>
1391 - */
1392 - public static function ignore_template_categories() {
1393 - return array( 'Business', 'Elite', 'Personal', 'Creator', 'Basic', 'free' );
1394 - }
1395 -
1396 - /**
1397 1632 * @since 4.02
1633 + *
1634 + * @param array $template Template details.
1635 + * @param array $args Additional arguments.
1636 + *
1637 + * @return array The link attributes.
1398 1638 */
1399 1639 public static function get_template_install_link( $template, $args ) {
1400 1640 $defaults = array(
1401 1641 'class' => 'install-now',
@@ -1410,13 +1650,8 @@
1410 1650 'class' => 'frm-install-template',
1411 1651 'href' => 'rel',
1412 1652 'atts' => '',
1413 1653 );
1414 - } elseif ( self::plan_is_allowed( $args ) ) {
1415 - $link = array(
1416 - 'url' => FrmAppHelper::admin_upgrade_link( 'addons', 'account/downloads/' ) . '&utm_content=' . $template['slug'],
1417 - 'label' => __( 'Renew', 'formidable' ),
1418 - );
1419 1654 } else {
1420 1655 $link = array(
1421 1656 'url' => $args['pricing'],
1422 1657 'label' => __( 'Upgrade', 'formidable' ),
@@ -1439,20 +1674,23 @@
1439 1674 if ( empty( $args['license_type'] ) ) {
1440 1675 return false;
1441 1676 }
1442 1677
1443 - $included = $args['license_type'] === strtolower( $args['plan_required'] );
1678 + $plans = array( 'free', 'personal', 'business', 'elite' );
1679 + $license_type = strtolower( $args['license_type'] );
1680 + $plan_required = strtolower( $args['plan_required'] );
1681 + $included = $license_type === $plan_required;
1444 1682
1445 - $plans = array( 'free', 'personal', 'business', 'elite' );
1446 - if ( $included || ! in_array( strtolower( $args['plan_required'] ), $plans, true ) ) {
1683 + if ( $included || ! in_array( $plan_required, $plans, true ) ) {
1447 1684 return $included;
1448 1685 }
1449 1686
1450 1687 foreach ( $plans as $plan ) {
1451 - if ( $included || $plan === $args['license_type'] ) {
1688 + if ( $included || $plan === $license_type ) {
1452 1689 break;
1453 1690 }
1454 - $included = $plan === strtolower( $args['plan_required'] );
1691 +
1692 + $included = $plan === $plan_required;
1455 1693 }
1456 1694
1457 1695 return $included;
1458 1696 }
@@ -1457,34 +1695,33 @@
1457 1695 return $included;
1458 1696 }
1459 1697
1460 1698 /**
1461 - * @since 4.02
1462 - */
1463 - public static function template_install_html( $link, $class = '' ) {
1464 - $link['class'] .= ' ' . $class;
1465 - echo '<a ' . esc_attr( $link['href'] ) . '="' . esc_url( $link['url'] ) . '" class="' . esc_attr( $link['class'] ) . ' " aria-label="' . esc_attr( $link['label'] ) . '"' . ( $link['atts'] ? ' target="_blank" rel="noopener"' : '' ) . '>';
1466 - }
1467 -
1468 - /**
1469 1699 * If a template or add-on cannot be installed, show a message
1470 1700 * about which plan is required.
1471 1701 *
1472 1702 * @since 4.0
1703 + *
1704 + * @param string $requires
1705 + * @param string $link
1706 + *
1707 + * @return void
1473 1708 */
1474 1709 public static function show_plan_required( $requires, $link ) {
1475 - if ( empty( $requires ) ) {
1710 + if ( ! $requires ) {
1476 1711 return;
1477 1712 }
1478 1713
1714 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
1479 1715 ?>
1480 1716 <p class="frm_plan_required">
1481 - <?php esc_html_e( 'License plan required:', 'formidable' ); ?>
1717 + <?php esc_html_e( 'Plan required:', 'formidable' ); ?>
1482 1718 <a href="<?php echo esc_url( $link ); ?>" target="_blank" rel="noopener">
1483 1719 <?php echo esc_html( $requires ); ?>
1484 1720 </a>
1485 1721 </p>
1486 1722 <?php
1723 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1487 1724 }
1488 1725
1489 1726 /**
1490 1727 * @since 4.0
@@ -1489,9 +1726,10 @@
1489 1726 /**
1490 1727 * @since 4.0
1491 1728 *
1492 1729 * @param array $item
1493 - * @return string|false
1730 + *
1731 + * @return false|string
1494 1732 */
1495 1733 public static function get_plan_required( &$item ) {
1496 1734 if ( ! isset( $item['categories'] ) || ! is_array( $item['categories'] ) || ! empty( $item['url'] ) ) {
1497 1735 return false;
@@ -1496,27 +1734,66 @@
1496 1734 if ( ! isset( $item['categories'] ) || ! is_array( $item['categories'] ) || ! empty( $item['url'] ) ) {
1497 1735 return false;
1498 1736 }
1499 1737
1500 - $plans = array( 'free', 'Basic', 'Personal', 'Plus', 'Creator', 'Business', 'Elite' );
1738 + $plans = self::get_license_types();
1501 1739
1502 1740 foreach ( $item['categories'] as $k => $category ) {
1503 1741 if ( in_array( $category, $plans, true ) ) {
1504 1742 unset( $item['categories'][ $k ] );
1743 + return self::convert_legacy_package_names( $category );
1744 + }
1745 + }
1505 1746
1506 - if ( in_array( $category, array( 'Creator', 'Personal' ), true ) ) {
1507 - // Show the current package name.
1508 - $category = 'Plus';
1509 - }
1747 + return false;
1748 + }
1510 1749
1511 - return $category;
1512 - }
1750 + /**
1751 + * Converts legacy package names to the current standard package name.
1752 + *
1753 + * @since 6.15
1754 + *
1755 + * @param string $package_name
1756 + *
1757 + * @return string The updated package name.
1758 + */
1759 + public static function convert_legacy_package_names( $package_name ) {
1760 + if ( in_array( $package_name, array( 'Creator', 'Personal' ), true ) ) {
1761 + return 'Plus';
1513 1762 }
1514 1763
1515 - return false;
1764 + return $package_name;
1516 1765 }
1517 1766
1518 1767 /**
1768 + * Get the license types.
1769 + *
1770 + * @since 6.15
1771 + *
1772 + * @param array $args
1773 + *
1774 + * @return array
1775 + */
1776 + public static function get_license_types( $args = array() ) {
1777 + $defaults = array(
1778 + 'include_all' => true,
1779 + 'case_lower' => false,
1780 + );
1781 + $args = wp_parse_args( $args, $defaults );
1782 + $license_types = array( 'Basic', 'Plus', 'Business', 'Elite' );
1783 +
1784 + if ( $args['include_all'] ) {
1785 + $license_types = array_merge( array( 'free', 'Personal', 'Creator' ), $license_types );
1786 + }
1787 +
1788 + if ( $args['case_lower'] ) {
1789 + return array_map( 'strtolower', $license_types );
1790 + }
1791 +
1792 + return $license_types;
1793 + }
1794 +
1795 + /**
1519 1796 * Checks for warnings to be displayed after form settings are saved.
1520 1797 *
1521 1798 * @since 4.04
1522 1799 *
@@ -1524,10 +1801,9 @@
1524 1801 *
1525 1802 * @return array An array of warnings or an empty array.
1526 1803 */
1527 1804 public static function check_for_warnings( $values ) {
1528 - $warnings = array();
1529 -
1805 + $warnings = array();
1530 1806 $redirect_warning = self::check_redirect_url_for_unsafe_params( $values );
1531 1807
1532 1808 if ( $redirect_warning ) {
1533 1809 $warnings[] = $redirect_warning;
@@ -1552,9 +1828,9 @@
1552 1828
1553 1829 $options = $values['options'];
1554 1830 FrmAppHelper::sanitize_with_html( $options );
1555 1831
1556 - if ( ( ! isset( $options['success_action'] ) ) || $options['success_action'] !== 'redirect' || ! isset( $options['success_url'] ) ) {
1832 + if ( ! isset( $options['success_action'] ) || $options['success_action'] !== 'redirect' || ! isset( $options['success_url'] ) ) {
1557 1833 return false;
1558 1834 }
1559 1835
1560 1836 $unsafe_params_in_redirect = self::get_unsafe_params( $options['success_url'] );
@@ -1572,15 +1848,16 @@
1572 1848 * @return array An array of params whose names are reserved words or an empty array.
1573 1849 */
1574 1850 private static function get_unsafe_params( $url ) {
1575 1851 $redirect_components = parse_url( $url );
1852 +
1576 1853 if ( empty( $redirect_components['query'] ) ) {
1577 1854 return array();
1578 1855 }
1856 +
1579 1857 parse_str( $redirect_components['query'], $redirect_params );
1580 1858 $redirect_param_names = array_keys( $redirect_params );
1581 - $reserved_words = self::reserved_words();
1582 - $unsafe_params_in_redirect = array_intersect( $redirect_param_names, $reserved_words );
1859 + $unsafe_params_in_redirect = array_intersect( $redirect_param_names, self::reserved_words() );
1583 1860
1584 1861 return array_values( $unsafe_params_in_redirect );
1585 1862 }
1586 1863
@@ -1593,26 +1870,27 @@
1593 1870 *
1594 1871 * @return bool|string A string with an unsafe param message or false.
1595 1872 */
1596 1873 private static function create_unsafe_param_warning( $unsafe_params_in_redirect ) {
1597 - $count = count( $unsafe_params_in_redirect );
1598 - $caution = esc_html__( 'Is this intentional?', 'formidable' );
1599 - $reserved_words_intro = esc_html__( 'See the list of reserved words in WordPress.', 'formidable' );
1600 - $reserved_words_link = '<a href="https://codex.wordpress.org/WordPress_Query_Vars" target="_blank"> ' . $reserved_words_intro . '</a>';
1874 + $count = count( $unsafe_params_in_redirect );
1601 1875
1602 1876 if ( $count === 0 ) {
1603 1877 return false;
1604 1878 }
1605 1879
1606 - if ( $count == 1 ) {
1880 + $caution = esc_html__( 'Is this intentional?', 'formidable' );
1881 + $reserved_words_intro = esc_html__( 'See the list of reserved words in WordPress.', 'formidable' );
1882 + $reserved_words_link = '<a href="https://codex.wordpress.org/WordPress_Query_Vars" target="_blank"> ' . $reserved_words_intro . '</a>';
1883 +
1884 + if ( $count === 1 ) {
1607 1885 /* translators: %s: the name of a single parameter in the redirect URL */
1608 - return sprintf( esc_html__( 'The redirect URL is using the parameter "%s", which is reserved by WordPress. ', 'formidable' ), $unsafe_params_in_redirect[0] ) . $caution . $reserved_words_link;
1886 + return sprintf( esc_html__( 'The redirect URL is using the parameter "%s", which is reserved by WordPress. ', 'formidable' ), $unsafe_params_in_redirect[0] ) . $caution . $reserved_words_link; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
1609 1887 }
1610 1888
1611 1889 $unsafe_params_string = implode( '", "', $unsafe_params_in_redirect );
1612 1890
1613 1891 /* translators: %s: the names of two or more parameters in the redirect URL, separated by commas */
1614 - return sprintf( esc_html__( 'The redirect URL is using the parameters "%s", which are reserved by WordPress. ', 'formidable' ), $unsafe_params_string ) . $caution . $reserved_words_link;
1892 + return sprintf( esc_html__( 'The redirect URL is using the parameters "%s", which are reserved by WordPress. ', 'formidable' ), $unsafe_params_string ) . $caution . $reserved_words_link; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
1615 1893 }
1616 1894
1617 1895 /**
1618 1896 * Returns an array of common reserved words in WordPress.
@@ -1671,34 +1949,8 @@
1671 1949 );
1672 1950 }
1673 1951
1674 1952 /**
1675 - * Check an array of templates, determine how many the logged in user can use
1676 - *
1677 - * @param array $templates
1678 - * @param array $args
1679 - * @return int
1680 - */
1681 - public static function available_count( $templates, $args ) {
1682 - return array_reduce(
1683 - $templates,
1684 - function( $total, $template ) use ( $args ) {
1685 - if ( ! empty( $template['url'] ) ) {
1686 - return $total + 1;
1687 - }
1688 -
1689 - $args['plan_required'] = self::get_plan_required( $template );
1690 - if ( self::plan_is_allowed( $args ) ) {
1691 - return $total + 1;
1692 - }
1693 -
1694 - return $total;
1695 - },
1696 - 0
1697 - );
1698 - }
1699 -
1700 - /**
1701 1953 * Make sure the field shortcodes in a url always add the sanitize_url=1 option if nothing is defined.
1702 1954 * This is to prevent some field characters like ', @, and | from being stripped from the redirect URL.
1703 1955 *
1704 1956 * @since 5.0.16
@@ -1704,17 +1956,19 @@
1704 1956 * @since 5.0.16
1705 1957 *
1706 1958 * @param string $url
1707 1959 * @param int $form_id
1960 + *
1708 1961 * @return string
1709 1962 */
1710 1963 public static function maybe_add_sanitize_url_attr( $url, $form_id ) {
1711 - if ( false === strpos( $url, '[' ) ) {
1964 + if ( ! str_contains( $url, '[' ) ) {
1712 1965 // Do nothing if no shortcodes are detected.
1713 1966 return $url;
1714 1967 }
1715 1968
1716 1969 $parsed = wp_parse_url( $url );
1970 +
1717 1971 if ( empty( $parsed['query'] ) ) {
1718 1972 // Do nothing if no query can be detected in the url string.
1719 1973 return $url;
1720 1974 }
@@ -1720,10 +1974,10 @@
1720 1974 }
1721 1975
1722 1976 $original_query = $parsed['query'];
1723 1977 $query = $parsed['query'];
1978 + $shortcodes = FrmFieldsHelper::get_shortcodes( $query, $form_id );
1724 1979
1725 - $shortcodes = FrmFieldsHelper::get_shortcodes( $query, $form_id );
1726 1980 if ( empty( $shortcodes[0] ) ) {
1727 1981 // No shortcodes found, do nothing.
1728 1982 return $url;
1729 1983 }
@@ -1735,22 +1989,23 @@
1735 1989 // Skip if shortcodes.
1736 1990 continue;
1737 1991 }
1738 1992
1739 - if ( false !== strpos( $options, 'sanitize_url=' ) || false !== strpos( $options, 'sanitize=' ) ) {
1993 + if ( str_contains( $options, 'sanitize_url=' ) || str_contains( $options, 'sanitize=' ) ) {
1740 1994 // A sanitize option is already set so leave it alone.
1741 1995 continue;
1742 1996 }
1743 1997
1744 1998 $new_shortcode = '[' . $shortcodes[2][ $key ];
1999 +
1745 2000 if ( $options ) {
1746 2001 $new_shortcode .= ' ' . $options;
1747 2002 }
2003 +
1748 2004 $new_shortcode .= ' sanitize_url=1]';
2005 + $query = str_replace( $shortcode, $new_shortcode, $query );
2006 + }//end foreach
1749 2007
1750 - $query = str_replace( $shortcode, $new_shortcode, $query );
1751 - }
1752 -
1753 2008 if ( $query === $original_query ) {
1754 2009 return $url;
1755 2010 }
1756 2011
@@ -1757,15 +2012,197 @@
1757 2012 return str_replace( $original_query, $query, $url );
1758 2013 }
1759 2014
1760 2015 /**
1761 - * Check if Pro isn't up to date yet.
1762 - * If Pro is active but using a version earlier than v6.2 fallback to Pro for AJAX submit (so things don't all happen twice).
2016 + * Outputs the appropriate button text in the publish box.
1763 2017 *
1764 - * @since 6.2
2018 + * @return void
2019 + */
2020 + public static function publish_box_button_text() {
2021 + $is_new_template = FrmAppHelper::simple_get( 'new_template' );
2022 + $action = FrmAppHelper::simple_get( 'frm_action' );
2023 +
2024 + if ( ( 'edit' === $action || 'settings' === $action ) && $is_new_template ) {
2025 + esc_html_e( 'Save', 'formidable' );
2026 + } else {
2027 + esc_html_e( 'Update', 'formidable' );
2028 + }
2029 + }
2030 +
2031 + /**
2032 + * Strip characters similar to the WordPress sanitize_html_class function, but allow for [ and ].
2033 + * This allows shortcodes inside of the layout classes setting.
1765 2034 *
2035 + * @since 6.16
2036 + *
2037 + * @param string $classname
2038 + *
2039 + * @return string
2040 + */
2041 + public static function sanitize_layout_class( $classname ) {
2042 + // Strip out any percent-encoded characters.
2043 + $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $classname );
2044 +
2045 + // Limit to A-Z, a-z, 0-9, '_', '-', '[', ']'.
2046 + return preg_replace( '/[^A-Za-z0-9_\-\[\]]/', '', $sanitized );
2047 + }
2048 +
2049 + /**
2050 + * Returns true if the preview should be blocked.
2051 + *
2052 + * @since 6.20
2053 + *
2054 + * @param string $form_key
2055 + *
1766 2056 * @return bool
1767 2057 */
1768 - public static function should_use_pro_for_ajax_submit() {
1769 - return is_callable( 'FrmProForm::is_ajax_on' ) && ! is_callable( 'FrmProFormsHelper::lite_supports_ajax_submit' );
2058 + public static function should_block_preview( $form_key ) {
2059 + $should_block = in_array( $form_key, array( 'contact-form', 'contact-us' ), true ) && ! current_user_can( 'frm_view_forms' );
2060 + /**
2061 + * Filters whether the form preview should be blocked.
2062 + *
2063 + * @since 6.20
2064 + *
2065 + * @param bool $should_block
2066 + * @param string $form_key
2067 + */
2068 + return (bool) apply_filters( 'frm_block_preview', $should_block, $form_key );
2069 + }
2070 +
2071 + /**
2072 + * Checks if the form is loaded by API.
2073 + *
2074 + * @since 6.21
2075 + *
2076 + * @return bool
2077 + */
2078 + public static function form_is_loaded_by_api() {
2079 + global $frm_vars;
2080 +
2081 + if ( ! empty( $frm_vars['inplace_edit'] ) ) {
2082 + return true;
2083 + }
2084 +
2085 + return self::is_formidable_api_form() || self::is_block_or_page_builder_preview();
2086 + }
2087 +
2088 + /**
2089 + * Checks if the form is rendered inside a block editor or page builder preview.
2090 + *
2091 + * @since 6.29
2092 + *
2093 + * @return bool
2094 + */
2095 + public static function is_block_or_page_builder_preview() {
2096 + return self::is_gutenberg_editor() || self::is_elementor_ajax() || self::is_visual_views_preview();
2097 + }
2098 +
2099 + /**
2100 + * @since 6.21
2101 + *
2102 + * @return bool
2103 + */
2104 + private static function is_visual_views_preview() {
2105 + return 'frm_views_process_box_preview' === FrmAppHelper::get_post_param( 'action' );
2106 + }
2107 +
2108 + /**
2109 + * @since 6.21
2110 + *
2111 + * @return bool
2112 + */
2113 + private static function is_elementor_ajax() {
2114 + return 'elementor_ajax' === FrmAppHelper::get_post_param( 'action' );
2115 + }
2116 +
2117 + /**
2118 + * @since 6.21
2119 + *
2120 + * @return bool
2121 + */
2122 + private static function is_gutenberg_editor() {
2123 + $url = FrmAppHelper::get_server_value( 'REQUEST_URI' );
2124 +
2125 + if ( str_contains( $url, '/wp-json/wp/v2/block-renderer/formidable/simple-form' ) ) {
2126 + return true;
2127 + }
2128 +
2129 + if ( str_contains( urldecode( $url ), 'rest_route=/wp/v2/block-renderer/formidable/' ) ) {
2130 + return true;
2131 + }
2132 +
2133 + global $pagenow;
2134 + return 'post.php' === $pagenow;
2135 + }
2136 +
2137 + /**
2138 + * @since 6.21
2139 + *
2140 + * @return bool
2141 + */
2142 + private static function is_formidable_api_form() {
2143 + if ( ! class_exists( 'FrmAPIAppController' ) ) {
2144 + return false;
2145 + }
2146 +
2147 + $url = FrmAppHelper::get_server_value( 'REQUEST_URI' );
2148 +
2149 + if ( str_contains( $url, '/wp-json/frm/v2/forms/' ) ) {
2150 + // Prevent the honeypot from appearing for an API loaded form.
2151 + // This is to prevent conflicts where the script is not working.
2152 + return true;
2153 + }
2154 +
2155 + if ( is_callable( 'FrmProFormState::get_from_request' ) ) {
2156 + $api = FrmProFormState::get_from_request( 'a', 0 );
2157 +
2158 + if ( $api ) {
2159 + return true;
2160 + }
2161 + }
2162 +
2163 + return false;
2164 + }
2165 +
2166 + /**
2167 + * @since 6.30
2168 + *
2169 + * @return void
2170 + */
2171 + public static function load_currency_js() {
2172 + global $frm_vars;
2173 +
2174 + if ( empty( $frm_vars['currency'] ) ) {
2175 + return;
2176 + }
2177 +
2178 + echo '<script>';
2179 + echo 'var frmcurrency=' . json_encode( $frm_vars['currency'] ) . ";\n";
2180 + echo 'if(typeof __FRMCURR == "undefined"){__FRMCURR=frmcurrency;}';
2181 + echo 'else{__FRMCURR=jQuery.extend(true,{},__FRMCURR,frmcurrency);}';
2182 + echo '</script>';
2183 + }
2184 +
2185 + /**
2186 + * Returns the form name or the no title text if the form name is empty.
2187 + *
2188 + * @since 6.30
2189 + *
2190 + * @param array|stdClass $form The form data.
2191 + * @param int $length The form name length to truncate to.
2192 + *
2193 + * @return string
2194 + */
2195 + public static function get_form_name( $form, $length = 0 ) {
2196 + $form_name = is_object( $form ) ? $form->name : $form['name'];
2197 +
2198 + if ( '' === $form_name || null === $form_name ) {
2199 + return self::get_no_title_text();
2200 + }
2201 +
2202 + if ( ! $length ) {
2203 + return $form_name;
2204 + }
2205 +
2206 + return FrmAppHelper::truncate( $form_name, $length );
1770 2207 }
1771 2208 }