float|null. */ private static $calcs = array(); /** While a form renders: what tables need for their starting values. */ private static $ctx = array(); public static function form( $form ) { $config = $form['config']; $settings = $config['settings']; $form_id = (int) $form['id']; if ( 'yes' === $settings['login_required'] && ! is_user_logged_in() ) { return '
' . esc_html__( 'Please log in to use this form.', 'mammoth-forms' ) . '
'; } self::$instances++; $uid = 'mammoth-' . $form_id . '-' . self::$instances; self::enqueue_assets(); $classes = array( 'mammoth-form', 'mammoth-labels-' . $settings['labels_position'] ); // Back from a submission made without JavaScript (see Mammoth_Submit::handle_fallback()). $outcome = Mammoth_Submit::fallback_result( $form_id ); self::$errors = array(); if ( $outcome && $outcome['success'] && ! empty( $outcome['hide'] ) ) { $classes[] = 'mammoth-done'; } if ( $outcome && ! $outcome['success'] ) { self::$errors = $outcome['errors']; $config['fields'] = self::prefill( $config['fields'], $outcome['raw'] ); } // Back through a "continue later" link: the saved answers. $resume = ( ! $outcome && Mammoth_Drafts::enabled( $settings ) ) ? Mammoth_Drafts::resume( $form_id ) : null; if ( $resume ) { $config['fields'] = self::prefill( $config['fields'], $resume['raw'] ); } // Answers from the page address (?mf_room=Kitchen&mf_area=20), when the form allows it. if ( ! $outcome && ! $resume && ( ! isset( $settings['url_prefill'] ) || 'no' !== $settings['url_prefill'] ) ) { $from_url = self::answers_from_url( $config ); if ( $from_url ) { $config['fields'] = self::prefill( $config['fields'], $from_url ); } } // Results for the starting answers, so totals are right before (or without) JavaScript. $start = self::starting_raw( $config['fields'] ); $visible = Mammoth_Submit::settle_visibility( $config, $start ); self::$calcs = Mammoth_Submit::calculate( $config, $start, $visible ); self::$ctx = array( 'raw' => $start, 'visible' => $visible, 'vars' => Mammoth_Submit::last_vars(), 'fields' => Mammoth_Forms::fields_by_key( $config ), 'settings' => $settings, 'form_id' => $form_id, ); // Formulas that cannot be worked out: remembered for the admin notice // (only from real page views, not the builder's preview of unsaved // changes) and shown above the form to whoever can fix it. $problems = Mammoth_Health::check( $config ); if ( ! is_admin() && ! wp_doing_ajax() ) { Mammoth_Health::record( $form_id, $problems ); } $health_box = Mammoth_Health::box( $form_id, $problems ); $anchor = ''; if ( empty( self::$anchored[ $form_id ] ) ) { self::$anchored[ $form_id ] = true; $anchor = ''; } ob_start(); ?>
>
raw answer */ private static function answers_from_url( $config ) { $out = array(); foreach ( $config['fields'] as $field ) { if ( Mammoth_Fields::is_display( $field['type'] ) || 'calculated' === $field['type'] ) { continue; } $param = 'mf_' . $field['key']; if ( ! isset( $_GET[ $param ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only defaults for a public form. continue; } $value = is_array( $_GET[ $param ] ) ? map_deep( wp_unslash( $_GET[ $param ] ), 'sanitize_text_field' ) : sanitize_text_field( wp_unslash( $_GET[ $param ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only defaults for a public form. $out[ $field['key'] ] = Mammoth_Transfer::cell_to_raw( $field, $value, $config['settings'] ); } return $out; } private static function wrap_classes( $settings, $form = array() ) { $classes = array( 'mammoth-form-wrap' ); $theme = isset( $settings['style_theme'] ) ? $settings['style_theme'] : 'default'; if ( 'default' !== $theme ) { $classes[] = 'mammoth-theme-' . sanitize_html_class( $theme ); } if ( isset( $settings['style_size'] ) && 'large' === $settings['style_size'] ) { $classes[] = 'mammoth-size-large'; } if ( isset( $settings['style_width'] ) && in_array( $settings['style_width'], array( '720', '560' ), true ) ) { $classes[] = 'mammoth-width-' . $settings['style_width']; } /** * Classes on the form's outer wrapper, e.g. for an add-on's styles. * * @param string[] $classes Class names. * @param array $settings The form's settings. * @param array $form The form. */ $classes = (array) apply_filters( 'mammoth_wrap_classes', $classes, $settings, $form ); return implode( ' ', array_map( 'sanitize_html_class', $classes ) ); } /** The colour and corners chosen for this form, as CSS variables. */ private static function wrap_style( $settings ) { $vars = array(); $accent = isset( $settings['style_accent'] ) ? sanitize_hex_color( $settings['style_accent'] ) : ''; if ( $accent ) { $vars[] = '--mammoth-accent:' . $accent; } if ( isset( $settings['style_radius'] ) && '' !== (string) $settings['style_radius'] ) { $vars[] = '--mammoth-radius:' . absint( $settings['style_radius'] ) . 'px'; } return $vars ? ' style="' . esc_attr( implode( ';', $vars ) ) . '"' : ''; } /** * Answers the form starts with: defaults and pre-selected options. * * @return array key => string|array, like Mammoth_Submit::collect_raw(). */ public static function starting_raw( $fields ) { $raw = array(); foreach ( $fields as $field ) { if ( Mammoth_Fields::is_display( $field['type'] ) || 'calculated' === $field['type'] ) { continue; } $type = $field['type']; if ( in_array( $type, array( 'select', 'radio', 'checkboxes' ), true ) ) { $picked = array(); foreach ( (array) $field['options'] as $option ) { if ( 'yes' === $option['selected'] ) { $picked[] = (string) $option['value']; } } $many = 'checkboxes' === $type || ( 'select' === $type && 'yes' === $field['multiple'] ); $raw[ $field['key'] ] = $many ? $picked : ( $picked ? $picked[0] : '' ); } elseif ( Mammoth_Fields::is_single_box( $type ) ) { $on = '' !== $field['default'] && '0' !== $field['default'] && 'no' !== $field['default']; $raw[ $field['key'] ] = $on ? '1' : ''; } elseif ( 'slider' === $type ) { $raw[ $field['key'] ] = '' !== $field['default'] ? $field['default'] : ( '' !== $field['min'] ? $field['min'] : '0' ); } elseif ( 'range' === $type ) { $raw[ $field['key'] ] = isset( $field['_value'] ) ? array_values( (array) $field['_value'] ) : array( '', '' ); } elseif ( 'address' === $type ) { $raw[ $field['key'] ] = isset( $field['_value'] ) ? (array) $field['_value'] : array_fill_keys( array_keys( Mammoth_Fields::address_parts( $field ) ), '' ); } else { $raw[ $field['key'] ] = (string) $field['default']; } } return $raw; } /** * The visitor's answers back in the fields after a failed no-JS submission, * as defaults and pre-selected options. */ private static function prefill( $fields, $raw ) { foreach ( $fields as $i => $field ) { $key = $field['key']; if ( ! array_key_exists( $key, $raw ) || 'calculated' === $field['type'] ) { continue; } $value = $raw[ $key ]; if ( in_array( $field['type'], array( 'select', 'radio', 'checkboxes' ), true ) ) { $chosen = array_map( 'strval', (array) $value ); foreach ( (array) $field['options'] as $j => $option ) { $fields[ $i ]['options'][ $j ]['selected'] = in_array( (string) $option['value'], $chosen, true ) ? 'yes' : 'no'; } } elseif ( Mammoth_Fields::is_single_box( $field['type'] ) ) { $fields[ $i ]['default'] = '' !== (string) $value ? '1' : ''; } elseif ( in_array( $field['type'], array( 'range', 'address' ), true ) ) { // Several boxes: the answers go back box by box. if ( is_array( $value ) ) { $fields[ $i ]['_value'] = $value; } } elseif ( is_array( $value ) && ( array_filter( $value, 'is_array' ) || array_filter( array_keys( $value ), 'is_string' ) ) ) { $fields[ $i ]['_value'] = $value; // Rows or named parts of an add-on field type. } else { $fields[ $i ]['default'] = is_array( $value ) ? implode( ', ', array_filter( $value, 'is_scalar' ) ) : (string) $value; } } return $fields; } /** * Everything the frontend engine needs: formulas, conditions, choice values. */ public static function js_config( $form ) { $config = $form['config']; $settings = $config['settings']; $fields = array(); $has_table = false; foreach ( $config['fields'] as $field ) { if ( 'table' === $field['type'] && self::table_is_live( $field ) ) { $has_table = true; } } foreach ( $config['fields'] as $field ) { $live_table = 'table' === $field['type'] && self::table_is_live( $field ); if ( Mammoth_Fields::is_display( $field['type'] ) && ! $live_table && ! Mammoth_Conditions::has_rules( $field ) ) { continue; } $entry = array( 'key' => $field['key'], 'type' => $field['type'], 'required' => 'yes' === $field['required'], 'width' => $field['width'], 'conditions' => $field['conditions'], ); if ( 'calculated' === $field['type'] ) { $entry['formula'] = $field['formula']; $entry['decimals'] = (int) $field['decimals']; $entry['prefix'] = $field['prefix']; $entry['suffix'] = $field['suffix']; $entry['thousands'] = 'yes' === $field['thousands']; $entry['editable'] = 'yes' === $field['editable']; $entry['deps'] = Mammoth_Formula::dependencies( $field['formula'] ); } if ( $live_table ) { $entry['cells'] = self::table_cells( $field, (int) $form['id'] ); $entry['decimals'] = (int) $field['decimals']; $entry['prefix'] = $field['prefix']; $entry['suffix'] = $field['suffix']; $entry['thousands'] = 'yes' === $field['thousands']; } // {key:label} in a table shows the chosen option's label. if ( $has_table && in_array( $field['type'], array( 'select', 'radio', 'checkboxes' ), true ) ) { $entry['options'] = array(); foreach ( $field['options'] as $option ) { $entry['options'][] = array( 'value' => $option['value'], 'label' => '' !== $option['label'] ? $option['label'] : $option['value'], ); } } if ( '' !== $field['validation_rule'] ) { $entry['rule'] = $field['validation_rule']; } if ( '' !== $field['pattern'] ) { $entry['pattern'] = $field['pattern']; } if ( '' !== $field['error_message'] ) { $entry['errorMessage'] = $field['error_message']; } if ( 'address' === $field['type'] ) { $entry['parts'] = array_keys( Mammoth_Fields::address_parts( $field ) ); $entry['requiredParts'] = Mammoth_Fields::address_required_parts( $field ); } if ( in_array( $field['type'], array( 'date', 'datetime' ), true ) ) { $entry['min'] = $field['min']; $entry['max'] = $field['max']; } if ( in_array( $field['type'], array( 'number', 'slider', 'range' ), true ) ) { $entry['min'] = $field['min']; $entry['max'] = $field['max']; // The slider's bubble is redrawn in JS: without these it lost its "€" / " m²". $entry['prefix'] = $field['prefix']; $entry['suffix'] = $field['suffix']; } $fields[] = $entry; } return apply_filters( 'mammoth_js_config', array( 'formId' => (int) $form['id'], 'fields' => $fields, 'settings' => array( 'yes' => __( 'Yes', 'mammoth-forms' ), 'no' => __( 'No', 'mammoth-forms' ), 'decimalSep' => $settings['decimal_sep'], 'thousandSep' => $settings['thousand_sep'], 'redirect' => $settings['redirect_url'], ), ), $form ); } public static function enqueue_assets() { wp_enqueue_style( 'mammoth-form' ); wp_enqueue_script( 'mammoth-form' ); } public static function register_assets() { wp_register_style( 'mammoth-form', MAMMOTH_PLUGIN_URL . 'assets/css/form.css', array(), MAMMOTH_VERSION ); wp_register_script( 'mammoth-formula', MAMMOTH_PLUGIN_URL . 'assets/js/formula.js', array(), MAMMOTH_VERSION, true ); wp_register_script( 'mammoth-form', MAMMOTH_PLUGIN_URL . 'assets/js/form.js', array( 'mammoth-formula' ), MAMMOTH_VERSION, true ); wp_localize_script( 'mammoth-form', 'MAMMOTH_AJAX', array( 'url' => admin_url( 'admin-ajax.php' ), // REST first (skips admin_init); form.js falls back to admin-ajax. 'rest' => Mammoth_Rest::urls(), 'restNonce' => wp_create_nonce( 'wp_rest' ), 'strings' => array( 'required' => __( 'This field is required.', 'mammoth-forms' ), 'email' => __( 'Please enter a valid email address.', 'mammoth-forms' ), 'number' => __( 'Please enter a number.', 'mammoth-forms' ), /* translators: %s: minimum value */ 'min' => __( 'The minimum is %s.', 'mammoth-forms' ), /* translators: %s: maximum value */ 'max' => __( 'The maximum is %s.', 'mammoth-forms' ), 'error' => __( 'Something went wrong. Please try again.', 'mammoth-forms' ), 'pattern' => __( 'Please use the requested format.', 'mammoth-forms' ), 'addressParts' => __( 'Please fill in every part of the address.', 'mammoth-forms' ), 'rule' => __( 'Please check this answer.', 'mammoth-forms' ), 'both' => __( 'Please enter both numbers.', 'mammoth-forms' ), 'order' => __( 'The first number cannot be larger than the second.', 'mammoth-forms' ), 'date' => __( 'Please enter a valid date.', 'mammoth-forms' ), /* translators: %s: earliest date */ 'dateMin' => __( 'The earliest is %s.', 'mammoth-forms' ), /* translators: %s: latest date */ 'dateMax' => __( 'The latest is %s.', 'mammoth-forms' ), 'saving' => __( 'Saving…', 'mammoth-forms' ), 'copied' => __( 'Copied', 'mammoth-forms' ), 'submitting' => __( 'Sending…', 'mammoth-forms' ), ), ) ); do_action( 'mammoth_register_assets' ); } /** * One field, wrapper included. */ public static function field( $field, $settings, $uid ) { $type = $field['type']; $key = $field['key']; $input_id = $uid . '-' . $key; $classes = array( 'mammoth-field', 'mammoth-type-' . $type, 'mammoth-w-' . $field['width'] ); if ( 'yes' === $field['required'] ) { $classes[] = 'mammoth-required'; } if ( $field['css_class'] ) { $classes[] = $field['css_class']; } if ( 'calculated' === $type && 'yes' === $field['hide_field'] ) { $classes[] = 'mammoth-hidden-field'; } if ( 'hidden' === $type ) { $classes[] = 'mammoth-hidden-field'; } $attrs = array( 'class' => implode( ' ', $classes ), 'data-key' => $key, 'data-type' => $type, ); if ( Mammoth_Conditions::has_rules( $field ) ) { $attrs['data-conditional'] = '1'; } $html = ' $value ) { $html .= ' ' . $name . '="' . esc_attr( $value ) . '"'; } $html .= '>'; $show_label = ! in_array( $type, array( 'hidden', 'divider', 'html', 'checkbox', 'consent' ), true ) && '' !== trim( (string) $field['label'] ); if ( 'heading' === $type ) { $html .= '

' . esc_html( $field['label'] ) . '

'; if ( $field['description'] ) { $html .= '
' . wp_kses_post( $field['description'] ) . '
'; } return $html . ''; } if ( 'divider' === $type ) { return $html . '
'; } if ( 'html' === $type ) { return $html . '
' . wp_kses_post( $field['html'] ) . '
'; } if ( 'image' === $type ) { return $html . self::image( $field ) . ''; } if ( 'table' === $type ) { return $html . self::table( $field ) . ''; } if ( $show_label ) { $html .= ''; } $html .= '
' . self::input( $field, $settings, $input_id ) . '
'; if ( '' !== trim( (string) $field['description'] ) ) { $html .= '
' . wp_kses_post( $field['description'] ) . '
'; } $error = isset( self::$errors[ $key ] ) ? (string) self::$errors[ $key ] : ''; if ( '' !== $error ) { $html = str_replace( 'class="mammoth-field ', 'class="mammoth-field mammoth-has-error ', $html ); } $html .= ''; return $html . ''; } private static function image( $field ) { $img = ''; $alt = $field['alt']; if ( $field['image_id'] ) { $img = wp_get_attachment_image( $field['image_id'], $field['image_size'], false, array( 'alt' => $alt, 'class' => 'mammoth-image-img', 'loading' => 'lazy', ) ); } if ( '' === $img && '' !== $field['image_url'] ) { $img = '' . esc_attr( $alt ) . ''; } if ( '' === $img ) { return ''; } if ( '' !== $field['link_url'] ) { $img = '' . $img . ''; } $caption = '' !== $field['caption'] ? '
' . esc_html( $field['caption'] ) . '
' : ''; return '
' . $img . $caption . '
'; } /** * A table's cells as shown. Add-ons can fill in their own tokens here * (Pro: {stat:avg:total}); the browser gets the same cells. * * @return array Rows of cell texts. */ public static function table_cells( $field, $form_id ) { return (array) apply_filters( 'mammoth_table_cells', $field['table'], $field, (int) $form_id ); } /** True when some cell shows a value or a formula, so the table needs form.js. */ public static function table_is_live( $field ) { foreach ( (array) $field['table'] as $row ) { foreach ( $row as $cell ) { if ( self::cell_is_live( $cell ) ) { return true; } } } return false; } private static function cell_is_live( $cell ) { return '=' === substr( (string) $cell, 0, 1 ) || 1 === preg_match( '/\{[a-z0-9_]+(?::label)?\}/i', (string) $cell ); } private static function table( $field ) { $rows = self::table_cells( $field, isset( self::$ctx['form_id'] ) ? self::$ctx['form_id'] : 0 ); $out = ''; if ( '' !== trim( (string) $field['label'] ) ) { $out .= '
' . esc_html( $field['label'] ) . '
'; } if ( ! $rows ) { return $out; } $head = 'yes' === $field['table_header'] ? array_shift( $rows ) : null; $foot = ( 'yes' === $field['table_footer'] && $rows ) ? array_pop( $rows ) : null; $r = null === $head ? 0 : 1; $cell = function ( $text, $row, $col, $tag ) use ( $field ) { $attrs = ''; if ( self::cell_is_live( $text ) ) { $attrs = ' data-mammoth-cell="' . esc_attr( $row . '-' . $col ) . '"'; $text = self::cell_value( $text, $field ); } $scope = 'th' === $tag ? ' scope="col"' : ''; return '<' . $tag . $scope . $attrs . '>' . esc_html( $text ) . ''; }; $out .= '
'; if ( null !== $head ) { $out .= ''; foreach ( $head as $c => $text ) { $out .= $cell( $text, 0, $c, 'th' ); } $out .= ''; } $out .= ''; foreach ( $rows as $row ) { $out .= ''; foreach ( $row as $c => $text ) { $out .= $cell( $text, $r, $c, 'td' ); } $out .= ''; $r++; } $out .= ''; if ( null !== $foot ) { $out .= ''; foreach ( $foot as $c => $text ) { $out .= $cell( $text, $r, $c, 'td' ); } $out .= ''; } return $out . '
'; } /** * A live cell with the starting answers. Mirrors cellText() in form.js. */ public static function cell_value( $text, $table ) { $ctx = self::$ctx; if ( ! $ctx ) { return ''; } $settings = $ctx['settings']; if ( '=' === substr( $text, 0, 1 ) ) { $value = Mammoth_Formula::evaluate_strict( substr( $text, 1 ), $ctx['vars'] ); $value = is_wp_error( $value ) ? null : Mammoth_Formula::round_half_up( $value, (int) $table['decimals'] ); return Mammoth_Formula::format( $value, $table, $settings ); } return preg_replace_callback( '/\{([a-z0-9_]+)(:label)?\}/i', function ( $m ) use ( $ctx, $settings ) { $key = strtolower( $m[1] ); if ( ! isset( $ctx['fields'][ $key ] ) || empty( $ctx['visible'][ $key ] ) ) { return ''; } $field = $ctx['fields'][ $key ]; if ( 'calculated' === $field['type'] ) { return Mammoth_Formula::format( array_key_exists( $key, self::$calcs ) ? self::$calcs[ $key ] : 0.0, $field, $settings ); } $raw = isset( $ctx['raw'][ $key ] ) ? $ctx['raw'][ $key ] : ''; if ( ! empty( $m[2] ) ) { return Mammoth_Submit::answer_label( $field, $raw ); } if ( is_array( $raw ) ) { return implode( ', ', $raw ); } $raw = (string) $raw; // "25.5" from a number box reads as "25,5" in a form with a decimal comma. if ( in_array( $field['type'], array( 'number', 'slider' ), true ) && preg_match( '/^-?\d+\.\d+$/', $raw ) ) { $raw = str_replace( '.', $settings['decimal_sep'], $raw ); } return $raw; }, $text ); } private static function input( $field, $settings, $input_id ) { $key = $field['key']; $name = 'mammoth[' . $key . ']'; $req = 'yes' === $field['required'] ? ' aria-required="true"' : ''; $ph = $field['placeholder'] ? ' placeholder="' . esc_attr( $field['placeholder'] ) . '"' : ''; $type = $field['type']; $value = $field['default']; switch ( $type ) { case 'calculated': $editable = 'yes' === $field['editable']; // Starting result (form.js takes over as soon as it runs). $start = array_key_exists( $key, self::$calcs ) ? self::$calcs[ $key ] : 0.0; $shown = Mammoth_Formula::format( $start, array_merge( $field, array( 'prefix' => '', 'suffix' => '' ) ), $settings ); $out = ''; if ( $editable ) { $out .= ''; } else { $out .= '
' . '' . esc_html( $field['prefix'] ) . '' . '' . esc_html( $shown ) . '' . '' . esc_html( $field['suffix'] ) . '' . '
' . ''; } return $out; case 'number': $attrs = ''; if ( '' !== $field['min'] ) { $attrs .= ' min="' . esc_attr( $field['min'] ) . '"'; } if ( '' !== $field['max'] ) { $attrs .= ' max="' . esc_attr( $field['max'] ) . '"'; } $attrs .= ' step="' . esc_attr( '' !== $field['step'] ? $field['step'] : 'any' ) . '"'; $pre = $field['prefix'] ? '' . esc_html( $field['prefix'] ) . '' : ''; $suf = $field['suffix'] ? '' . esc_html( $field['suffix'] ) . '' : ''; return $pre . '' . $suf; case 'slider': $min = '' !== $field['min'] ? $field['min'] : '0'; $max = '' !== $field['max'] ? $field['max'] : '100'; $step = '' !== $field['step'] ? $field['step'] : '1'; $val = '' !== $value ? $value : $min; return '
' . '' . '' . esc_html( $field['prefix'] . $val . $field['suffix'] ) . '' . '
'; case 'select': $multiple = 'yes' === $field['multiple']; $out = ''; case 'radio': case 'checkboxes': $is_radio = 'radio' === $type; $look = isset( $field['choice_style'] ) ? $field['choice_style'] : 'list'; $out = '
'; $i = 0; foreach ( $field['options'] as $option ) { $oid = $input_id . '-' . $i; $out .= ''; $i++; } return $out . '
'; case 'checkbox': $checked = ( '' !== $value && '0' !== $value && 'no' !== $value ) ? ' checked' : ''; return ''; case 'consent': $text = '' !== trim( (string) $field['consent_text'] ) ? $field['consent_text'] : __( 'I agree to the {privacy_policy}.', 'mammoth-forms' ); $url = function_exists( 'get_privacy_policy_url' ) ? get_privacy_policy_url() : ''; $link = $url ? '' . esc_html__( 'privacy policy', 'mammoth-forms' ) . '' : esc_html__( 'privacy policy', 'mammoth-forms' ); $text = str_replace( '{privacy_policy}', $link, wp_kses( $text, Mammoth_Fields::inline_html() ) ); $checked = ( '' !== $value && '0' !== $value && 'no' !== $value ) ? ' checked' : ''; return ''; // Escaped above: wp_kses() and esc_*. case 'textarea': return ''; case 'hidden': return ''; case 'date': $attrs = ''; if ( '' !== $field['min'] ) { $attrs .= ' min="' . esc_attr( $field['min'] ) . '"'; } if ( '' !== $field['max'] ) { $attrs .= ' max="' . esc_attr( $field['max'] ) . '"'; } return ''; case 'datetime': $attrs = ''; foreach ( array( 'min', 'max' ) as $limit ) { if ( '' !== $field[ $limit ] ) { $attrs .= ' ' . $limit . '="' . esc_attr( str_replace( ' ', 'T', $field[ $limit ] ) ) . '"'; } } return ''; case 'range': $values = isset( $field['_value'] ) ? array_values( (array) $field['_value'] ) : array(); $attrs = ''; if ( '' !== $field['min'] ) { $attrs .= ' min="' . esc_attr( $field['min'] ) . '"'; } if ( '' !== $field['max'] ) { $attrs .= ' max="' . esc_attr( $field['max'] ) . '"'; } $attrs .= ' step="' . esc_attr( '' !== $field['step'] ? $field['step'] : 'any' ) . '"'; $pre = $field['prefix'] ? '' . esc_html( $field['prefix'] ) . '' : ''; $suf = $field['suffix'] ? '' . esc_html( $field['suffix'] ) . '' : ''; $label = '' !== $field['label'] ? $field['label'] : $key; $box = function ( $index, $id, $aria ) use ( $values, $name, $attrs, $req ) { return ''; }; return '
' /* translators: %s: field label */ . '' . $pre . $box( 0, $input_id, sprintf( __( '%s: from', 'mammoth-forms' ), $label ) ) . $suf . '' . '' /* translators: %s: field label */ . '' . $pre . $box( 1, $input_id . '-to', sprintf( __( '%s: to', 'mammoth-forms' ), $label ) ) . $suf . '' . '
'; case 'country': $out = ''; case 'address': $values = isset( $field['_value'] ) && is_array( $field['_value'] ) ? $field['_value'] : array(); $fill = array( 'street' => 'address-line1', 'street2' => 'address-line2', 'city' => 'address-level2', 'postcode' => 'postal-code', 'region' => 'address-level1', 'country' => 'country', ); $needed = 'yes' === $field['required'] ? Mammoth_Fields::address_required_parts( $field ) : array(); $out = '
'; foreach ( Mammoth_Fields::address_parts( $field ) as $part => $part_label ) { $pid = 'street' === $part ? $input_id : $input_id . '-' . $part; $pname = $name . '[' . $part . ']'; $val = isset( $values[ $part ] ) && is_scalar( $values[ $part ] ) ? (string) $values[ $part ] : ''; $preq = in_array( $part, $needed, true ) ? ' aria-required="true"' : ''; $out .= '
'; if ( 'country' === $part ) { $out .= ''; } else { $out .= ''; } $out .= '
'; } return $out . '
'; case 'email': case 'tel': case 'text': default: $html_type = in_array( $type, array( 'email', 'tel' ), true ) ? $type : 'text'; $custom = apply_filters( 'mammoth_render_input', '', $field, $settings, $input_id ); if ( '' !== $custom ) { return $custom; } return ''; } } }