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