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

FrmFieldFormHtml.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.01.02, at classes/models/FrmFieldFormHtml.php

453 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @since 3.0
4 */
5
6 class FrmFieldFormHtml {
7
8 private $html;
9
10 private $html_id;
11
12 /**
13 * @var FrmFieldType
14 */
15 private $field_obj;
16
17 private $field_id;
18
19 private $form = array();
20
21 private $pass_args = array();
22
23 /**
24 * @since 3.0
25 *
26 * @param array $atts
27 */
28 public function __construct( $atts ) {
29 $this->_set( 'field_obj', $atts );
30 $this->set_field_id( $atts );
31 $this->_set( 'form', $atts );
32 $this->_set( 'html_id', $atts );
33 $this->set_html( $atts );
34 $this->set_pass_args( $atts );
35 }
36
37 /**
38 * @since 3.0
39 *
40 * @param string $param
41 * @param array $atts
42 */
43 private function _set( $param, $atts ) {
44 if ( isset( $atts[ $param ] ) ) {
45 $this->{$param} = $atts[ $param ];
46 }
47 }
48
49 /**
50 * @since 3.0
51 *
52 * @param array $atts
53 */
54 private function set_html( $atts ) {
55 $this->set_from_field(
56 $atts,
57 array(
58 'param' => 'html',
59 'default' => 'custom_html',
60 )
61 );
62 }
63
64 /**
65 * @since 3.0
66 *
67 * @param array $atts
68 */
69 private function set_field_id( $atts ) {
70 $this->set_from_field(
71 $atts,
72 array(
73 'param' => 'field_id',
74 'default' => 'id',
75 )
76 );
77 }
78
79 /**
80 * @since 3.0
81 *
82 * @param array $atts
83 */
84 private function set_pass_args( $atts ) {
85 $this->pass_args = $atts;
86
87 $exclude = array( 'field_obj', 'html' );
88 foreach ( $exclude as $ex ) {
89 if ( isset( $atts[ $ex ] ) ) {
90 unset( $this->pass_args[ $ex ] );
91 }
92 }
93 }
94
95 /**
96 * @since 3.0
97 *
98 * @param array $atts
99 * @param array $set
100 */
101 private function set_from_field( $atts, $set ) {
102 if ( isset( $atts[ $set['param'] ] ) ) {
103 $this->{$set['param']} = $atts[ $set['param'] ];
104 } else {
105 $this->{$set['param']} = $this->field_obj->get_field_column( $set['default'] );
106 }
107 }
108
109 public function get_html() {
110 $this->replace_shortcodes_before_input();
111 $this->replace_shortcodes_with_atts();
112 $this->replace_shortcodes_after_input();
113
114 return $this->html;
115 }
116
117 /**
118 * @since 3.0
119 */
120 private function replace_shortcodes_before_input() {
121 $this->html = apply_filters( 'frm_before_replace_shortcodes', $this->html, $this->field_obj->get_field(), $this->pass_args['errors'], $this->form );
122
123 $this->replace_field_values();
124
125 $this->replace_required_label_shortcode();
126 $this->replace_required_class();
127 $this->maybe_replace_description_shortcode( false );
128 $this->replace_error_shortcode();
129 $this->add_class_to_label();
130 $this->add_field_div_classes();
131
132 $this->replace_entry_key();
133 $this->replace_form_shortcodes();
134 $this->process_wp_shortcodes();
135 $this->maybe_replace_description_shortcode( true );
136 }
137
138 /**
139 * @since 3.0
140 */
141 private function replace_field_values() {
142 //replace [id]
143 $this->html = str_replace( '[id]', $this->field_id, $this->html );
144
145 // set the label for
146 $this->html = str_replace( 'field_[key]', $this->html_id, $this->html );
147
148 //replace [key]
149 $this->html = str_replace( '[key]', $this->field_obj->get_field_column( 'field_key' ), $this->html );
150
151 //replace [field_name]
152 $this->html = str_replace( '[field_name]', $this->field_obj->get_field_column( 'name' ), $this->html );
153 }
154
155 /**
156 * @since 3.0
157 */
158 private function replace_required_label_shortcode() {
159 $required = FrmField::is_required( $this->field_obj->get_field() ) ? $this->field_obj->get_field_column( 'required_indicator' ) : '';
160 FrmShortcodeHelper::remove_inline_conditions( ! empty( $required ), 'required_label', $required, $this->html );
161 }
162
163 /**
164 * If this is an HTML field, the values are included in the description.
165 * In this case, we don't want to run the wp shortcodes with the description included.
166 *
167 * @since 3.0
168 */
169 private function maybe_replace_description_shortcode( $wp_processed = false ) {
170 $is_html = 'html' === $this->field_obj->get_field_column( 'type' );
171 $should_replace = ( $is_html && $wp_processed ) || ( ! $is_html && ! $wp_processed );
172 if ( $should_replace ) {
173 $this->replace_description_shortcode();
174 }
175 }
176
177 /**
178 * @since 3.0
179 */
180 private function replace_description_shortcode() {
181 $this->maybe_add_description_id();
182 $description = $this->field_obj->get_field_column( 'description' );
183 FrmShortcodeHelper::remove_inline_conditions( ( $description && $description != '' ), 'description', $description, $this->html );
184 }
185
186 /**
187 * Add an ID to the description for aria-describedby.
188 * This ID was added to the HTML in v3.0.
189 *
190 * @since 3.0
191 */
192 private function maybe_add_description_id() {
193 $description = $this->field_obj->get_field_column( 'description' );
194 if ( $description != '' ) {
195 $this->add_element_id( 'description', 'desc' );
196 }
197 }
198
199 /**
200 * Insert an ID if it doesn't exist.
201 *
202 * @since 3.06.02
203 */
204 private function add_element_id( $param, $id ) {
205 preg_match_all( '/(\[if\s+' . $param . '\])(.*?)(\[\/if\s+' . $param . '\])/mis', $this->html, $inner_html );
206 if ( ! isset( $inner_html[2] ) ) {
207 return;
208 }
209
210 if ( ! is_string( $inner_html[2] ) && count( $inner_html[2] ) === 1 ) {
211 $inner_html[2] = $inner_html[2][0];
212 }
213
214 if ( is_string( $inner_html[2] ) ) {
215 $has_id = strpos( $inner_html[2], ' id=' );
216 if ( ! $has_id ) {
217 $id = 'frm_' . $id . '_' . $this->html_id;
218 $this->html = str_replace( 'class="frm_' . $param, 'id="' . esc_attr( $id ) . '" class="frm_' . esc_attr( $param ), $this->html );
219 }
220 }
221 }
222
223 /**
224 * @since 3.0
225 */
226 private function replace_error_shortcode() {
227 $this->maybe_add_error_id();
228 $error = isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ? $this->pass_args['errors'][ 'field' . $this->field_id ] : false;
229 FrmShortcodeHelper::remove_inline_conditions( ! empty( $error ), 'error', $error, $this->html );
230 }
231
232 /**
233 * Add an ID to the error message for aria-describedby.
234 * This ID was added to the HTML in v3.06.02.
235 *
236 * @since 3.06.02
237 */
238 private function maybe_add_error_id() {
239 if ( ! isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ) {
240 return;
241 }
242
243 $this->add_element_id( 'error', 'error' );
244 }
245
246 /**
247 * Replace [required_class]
248 *
249 * @since 3.0
250 */
251 private function replace_required_class() {
252 $required_class = FrmField::is_required( $this->field_obj->get_field() ) ? ' frm_required_field' : '';
253 $this->html = str_replace( '[required_class]', $required_class, $this->html );
254 }
255
256 /**
257 * @since 3.0
258 */
259 private function replace_form_shortcodes() {
260 if ( ! empty( $this->form ) ) {
261 $form = (array) $this->form;
262
263 //replace [form_key]
264 $this->html = str_replace( '[form_key]', $form['form_key'], $this->html );
265
266 //replace [form_name]
267 $this->html = str_replace( '[form_name]', $form['name'], $this->html );
268 }
269 }
270
271 /**
272 * @since 3.0
273 */
274 public function replace_shortcodes_after_input() {
275 $this->html .= "\n";
276
277 // Stop html filtering on confirmation field to prevent loop
278 if ( $this->field_obj->get_field_column( 'conf_field' ) != 'stop' ) {
279 $this->filter_for_more_shortcodes();
280 }
281 }
282
283 /**
284 * @since 3.0
285 */
286 private function filter_for_more_shortcodes() {
287 $atts = $this->pass_args;
288
289 //If field is not in repeating section
290 if ( empty( $atts['section_id'] ) ) {
291 $atts = array(
292 'errors' => $this->pass_args['errors'],
293 'form' => $this->form,
294 );
295 }
296 $this->html = apply_filters( 'frm_replace_shortcodes', $this->html, $this->field_obj->get_field(), $atts );
297 }
298
299 /**
300 * Remove [collapse_this] if it's still included after all processing
301 *
302 * @since 3.0
303 *
304 * @param string $html
305 */
306 public function remove_collapse_shortcode( &$html ) {
307 if ( strpos( $html, '[collapse_this]' ) ) {
308 $html = str_replace( '[collapse_this]', '', $html );
309 }
310 }
311
312 /**
313 * @since 3.0
314 */
315 private function replace_shortcodes_with_atts() {
316 preg_match_all( "/\[(input|deletelink)\b(.*?)(?:(\/))?\]/s", $this->html, $shortcodes, PREG_PATTERN_ORDER );
317
318 foreach ( $shortcodes[0] as $short_key => $tag ) {
319 $shortcode_atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[2][ $short_key ] );
320 $tag = FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key );
321
322 $replace_with = '';
323
324 if ( $tag == 'deletelink' && FrmAppHelper::pro_is_installed() ) {
325 $replace_with = FrmProEntriesController::entry_delete_link( $shortcode_atts );
326 } elseif ( $tag == 'input' ) {
327 $replace_with = $this->replace_input_shortcode( $shortcode_atts );
328 }
329
330 $this->html = str_replace( $shortcodes[0][ $short_key ], $replace_with, $this->html );
331 }
332 }
333
334 /**
335 * @param array $shortcode_atts
336 *
337 * @return string
338 */
339 private function replace_input_shortcode( $shortcode_atts ) {
340 $shortcode_atts = $this->prepare_input_shortcode_atts( $shortcode_atts );
341
342 return $this->field_obj->include_front_field_input( $this->pass_args, $shortcode_atts );
343 }
344
345 /**
346 * @param array $shortcode_atts
347 *
348 * @return array
349 */
350 private function prepare_input_shortcode_atts( $shortcode_atts ) {
351 if ( isset( $shortcode_atts['opt'] ) ) {
352 $shortcode_atts['opt'] --;
353 }
354
355 $field_class = isset( $shortcode_atts['class'] ) ? $shortcode_atts['class'] : '';
356 $this->field_obj->set_field_column( 'input_class', $field_class );
357
358 if ( isset( $shortcode_atts['class'] ) ) {
359 unset( $shortcode_atts['class'] );
360 }
361
362 if ( isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ) {
363 $shortcode_atts['aria-invalid'] = 'true';
364 }
365
366 $this->field_obj->set_field_column( 'shortcodes', $shortcode_atts );
367
368 return $shortcode_atts;
369 }
370
371 /**
372 * Add the label position class into the HTML
373 * If the label position is inside, add a class to show the label if the field has a value.
374 *
375 * @since 3.0
376 */
377 private function add_class_to_label() {
378 $label_class = $this->field_obj->get_label_class();
379 $this->html = str_replace( '[label_position]', $label_class, $this->html );
380 if ( $this->field_obj->get_field_column( 'label' ) == 'inside' && $this->field_obj->get_field_column( 'value' ) != '' ) {
381 $this->html = str_replace( 'frm_primary_label', 'frm_primary_label frm_visible', $this->html );
382 }
383 }
384
385 /**
386 * Replace [entry_key]
387 *
388 * @since 3.0
389 */
390 private function replace_entry_key() {
391 $entry_key = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
392 $this->html = str_replace( '[entry_key]', $entry_key, $this->html );
393 }
394
395 /**
396 * Add classes to a field div
397 *
398 * @since 3.0
399 */
400 private function add_field_div_classes() {
401 $classes = $this->get_field_div_classes();
402
403 if ( $this->field_obj->get_field_column( 'type' ) == 'html' && strpos( $this->html, '[error_class]' ) === false ) {
404 // there is no error_class shortcode for HTML fields
405 $this->html = str_replace( 'class="frm_form_field', 'class="frm_form_field ' . $classes, $this->html );
406 }
407 $this->html = str_replace( '[error_class]', $classes, $this->html );
408 }
409
410 /**
411 * Get the classes for a field div
412 *
413 * @since 3.0
414 *
415 * @return string $classes
416 */
417 private function get_field_div_classes() {
418 // Add error class
419 $classes = isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ? ' frm_blank_field' : '';
420
421 // Add label position class
422 $settings = $this->field_obj->display_field_settings();
423 if ( isset( $settings['label_position'] ) && $settings['label_position'] ) {
424 $classes .= ' frm_' . $this->field_obj->get_field_column( 'label' ) . '_container';
425 }
426
427 // Add CSS layout classes
428 $extra_classes = $this->field_obj->get_field_column( 'classes' );
429 if ( ! empty( $extra_classes ) ) {
430 if ( ! strpos( $this->html, 'frm_form_field ' ) ) {
431 $classes .= ' frm_form_field';
432 }
433 $classes .= ' ' . $extra_classes;
434 }
435
436 $classes .= $this->field_obj->get_container_class();
437
438 // Get additional classes
439 return apply_filters( 'frm_field_div_classes', $classes, $this->field_obj->get_field(), array( 'field_id' => $this->field_id ) );
440 }
441
442 /**
443 * This filters shortcodes in the field HTML
444 *
445 * @since 3.0
446 */
447 private function process_wp_shortcodes() {
448 if ( apply_filters( 'frm_do_html_shortcodes', true ) ) {
449 $this->html = do_shortcode( $this->html );
450 }
451 }
452 }
453