settings = apply_filters( "forminator_field_{$this->slug}_general_settings", array() );
$this->autofill_settings = apply_filters( "forminator_field_{$this->slug}_autofill_settings", $this->autofill_settings() );
$this->defaults = apply_filters( "forminator_field_{$this->slug}_defaults", $this->defaults() );
$this->position = apply_filters( "forminator_field_{$this->slug}_position", $this->position );
$this->is_calculable = apply_filters( "forminator_field_{$this->slug}_is_calculable", $this->is_calculable );
}
/**
* Return field name
*
* @since 1.0
* @return string
*/
public function get_name() {
return $this->name;
}
/**
* Return field slug
*
* @since 1.0
* @return string
*/
public function get_slug() {
return $this->slug;
}
/**
* Get Category
*
* @return string
*/
public function get_category() {
return $this->category;
}
/**
* Return field settings
*
* @since 1.0
* @return array
*/
public function get_settings() {
return $this->settings;
}
/**
* Create decimals pattern from decimals number
*
* @since 1.7
* @param integer $decimals Decimals.
* @return mixed
*/
protected static function create_step_string( $decimals = 2 ) {
$step = 1;
if ( ! empty( $decimals ) ) {
for ( $i = 1; $i < $decimals; $i++ ) {
$step = '0' . $step;
}
$step = '0.' . $step;
}
return $step;
}
/**
* Return field property
*
* @since 1.0
* @since 1.6 add $data_type, to cast it
*
* @param string $property Property.
* @param array $field Field.
* @param string $fallback Fallback.
* @param string $data_type data type to return.
*
* @return mixed
*/
public static function get_property( $property, $field, $fallback = '', $data_type = null ) {
$property_value = $fallback;
if ( isset( $field[ $property ] ) ) {
$property_value = $field[ $property ];
}
if ( ! empty( $data_type ) ) {
$property_value = forminator_var_type_cast( $property_value, $data_type );
}
if ( 'required_message' === $property ) {
$property_value = wp_kses_post( $property_value );
}
return $property_value;
}
/**
* Get options for radio and selectbox fields
*
* @param array $field Field settings.
* @return array
*/
public static function get_options( $field ) {
$options = self::get_property( 'options', $field, array() );
if ( ! empty( $field['options_order'] ) && 'random' === $field['options_order'] ) {
shuffle( $options );
if ( ! empty( $field['enable_custom_option'] ) ) {
// Move custom option to the end of the array.
$key = array_search( 'custom_option', array_column( $options, 'key' ), true );
if ( false !== $key ) {
$custom_option = $options[ $key ];
unset( $options[ $key ] );
$options[] = $custom_option;
$options = array_values( $options );
}
}
}
return $options;
}
/**
* Get description position
*
* @param array $field Field settings.
* @param array $settings Form Settings.
*
* @return string
*/
public static function get_description_position( array $field, array $settings ): string {
$possible_values = array( 'above', 'below' );
$field_pos = self::get_property( 'description-position', $field );
// Check field description position.
if ( in_array( $field_pos, $possible_values, true ) ) {
return $field_pos;
}
if ( ! empty( $field['type'] ) && 'group' === $field['type'] && empty( $field_pos ) ) {
return 'above';
}
// Check form description position.
if ( ! empty( $settings['description-position'] ) && in_array( $settings['description-position'], $possible_values, true ) ) {
return $settings['description-position'];
}
// For backward compatibility.
return 'below';
}
/**
* Markup
*
* @since 1.0
*
* @param mixed $field Field.
* @param Forminator_Render_Form $views_obj Forminator_Render_Form object.
*
* @return mixed
*/
public function markup( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
// @noinspection PhpUnusedParameterInspection.
$field,
$views_obj
) {
return '';
}
/**
* Defaults
*
* @since 1.0
* @return array
*/
public function defaults() {
return array();
}
/**
* Return description
*
* @since 1.0
*
* @param string $description Description.
* @param string $get_id Id.
* @param string $descr_position Description position.
*
* @return string
*/
public static function get_description( $description, $get_id = '', $descr_position = 'above' ) {
$html = '';
if ( ! empty( $description ) ) {
$html .= sprintf(
'%s',
esc_attr( $get_id . '-description' ),
self::convert_markdown( self::esc_description( $description, $get_id ) )
);
}
return apply_filters(
'forminator_field_description',
$html,
$description,
$get_id,
$descr_position
);
}
/**
* Escape description
*
* @param string $description Description.
* @param string $field_id Field ID.
*
* @return string
*/
public static function esc_description( $description, $field_id ) {
$allowed_html = apply_filters(
'forminator_field_description_allowed_html',
array(
'a' => array(
'href' => true,
'title' => true,
'target' => true,
'rel' => true,
),
'span' => array(
'class' => true,
),
'br' => array(),
'em' => array(),
'strong' => array(),
),
$description,
$field_id
);
return wp_kses( $description, $allowed_html );
}
/**
* Return new input field
*
* @since 1.0
*
* @param array $attr Attribute.
*
* @param string $label Label.
* @param string $description Description.
* @param bool $required Required.
* @param string $descr_position Description position.
* @param array $wrapper_input Wrapper Input.
*
* @return mixed
*/
public static function create_input( $attr = array(), $label = '', $description = '', $required = false, $descr_position = 'above', $wrapper_input = array() ) {
$html = '';
// Override value by the posted value.
$value = isset( $attr['value'] ) ? $attr['value'] : false;
if ( isset( $attr['name'] ) ) {
$value = self::get_post_data( $attr['name'], $value );
}
$attr['value'] = $value;
if ( ! empty( $description ) ) {
$attr['aria-describedby'] = $attr['id'] . '-description';
}
$markup = self::implode_attr( $attr );
// Get field id.
$get_id = $attr['id'];
$html .= self::get_field_label( $label, $get_id, $required );
if ( 'above' === $descr_position ) {
$html .= self::get_description( $description, $get_id, $descr_position );
}
if ( isset( $wrapper_input[0] ) ) {
$html .= $wrapper_input[0];
}
if ( ! empty( $wrapper_input[2] ) ) {
$html .= sprintf( '', $wrapper_input[2] );
}
if ( ! empty( $wrapper_input[3] ) ) {
$html .= sprintf( '%s', $wrapper_input[3] );
}
$html .= sprintf( '', $markup );
if ( isset( $wrapper_input[1] ) ) {
$html .= $wrapper_input[1];
}
if ( 'above' !== $descr_position ) {
$html .= self::get_description( $description, $get_id, $descr_position );
}
return apply_filters( 'forminator_field_create_input', $html, $attr, $label, $description );
}
/**
* Return new textarea field
*
* @since 1.0
*
* @param array $attr Field Attribute.
* @param string $label Field Label.
* @param string $description Field Description.
* @param bool $required Required.
* @param string $description_position Description Position.
*
* @return mixed
*/
public static function create_textarea( $attr = array(), $label = '', $description = '', $required = false, $description_position = 'above' ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
$html = '';
$content = isset( $attr['content'] ) ? $attr['content'] : '';
if ( isset( $attr['name'] ) ) {
$content = self::get_post_data( $attr['name'], $content );
}
unset( $attr['content'] );
if ( ! empty( $description ) ) {
$attr['aria-describedby'] = $attr['id'] . '-description';
}
$markup = self::implode_attr( $attr );
$html .= self::get_field_label( $label, $attr['id'], $required );
if ( 'above' === $description_position ) {
$html .= self::get_description( $description, $attr['id'], $description_position );
}
$html .= sprintf( '', $markup, wp_kses_post( $content ) );
if ( 'above' !== $description_position ) {
$html .= self::get_description( $description, $attr['id'], $description_position );
}
return apply_filters( 'forminator_field_create_textarea', $html, $attr, $label, $description );
}
/**
* Return wp_editor_field
*
* @since 1.0.2
*
* @param array $attr Field Attribute.
* @param string $label Field Label.
* @param string $description Field Description.
* @param bool $required Required.
* @param string $default_height Height.
* @param integer $limit Limit.
* @param bool $media_buttons Whether to show media buttons or not.
*
* @return mixed
*/
public static function create_wp_editor( $attr = array(), $label = '', $description = '', $required = false, $default_height = '140', $limit = 0, $media_buttons = false ) {
$html = '';
$content = isset( $attr['content'] ) ? $attr['content'] : '';
if ( isset( $attr['name'] ) ) {
$content = self::get_post_data( $attr['name'], $content );
}
unset( $attr['content'] );
$editor_id = 'forminator-wp-editor-' . ( isset( $attr['id'] ) ? $attr['id'] : '' );
if ( $label ) {
$html .= '
';
$html .= sprintf(
'',
$editor_id,
$attr['id'],
self::convert_markdown( esc_html( $label ) ) . ( $required ? ' ' . forminator_get_required_icon() : '' )
);
$html .= '
';
}
if ( 'above' === self::$description_position ) {
$html .= self::get_description( $description, '', self::$description_position );
}
$wp_editor_class = isset( $attr['class'] ) ? $attr['class'] : '';
if ( $required ) {
add_filter( 'the_editor', array( __CLASS__, 'add_required_wp_editor' ) );
$wp_editor_class .= ' do-validate forminator-wp-editor-required';
} elseif ( ! empty( $limit ) ) {
$wp_editor_class .= ' do-validate';
}
$settings = array(
'textarea_name' => isset( $attr['name'] ) ? $attr['name'] : '',
'media_buttons' => $media_buttons,
'editor_class' => $wp_editor_class,
'editor_height' => $default_height,
);
if ( did_action( 'elementor/loaded' ) ) {
// Disable TinyMCE and Quicktags in Elementor to prevent console errors when wp.editor.initialize is triggered.
$settings['tinymce'] = false;
$settings['quicktags'] = false;
$settings['media_buttons'] = false;
}
ob_start();
wp_editor(
$content,
$editor_id,
$settings
);
if ( did_action( 'elementor/loaded' ) ) {
// Ensure the editor script is loaded; otherwise, wp.editor.initialize will not function in the Elementor popup.
Forminator_CForm_Front::$load_wp_enqueue_editor = true;
$args = self::get_tinymce_args( $editor_id, $media_buttons );
?>
%s',
esc_attr( $id ),
esc_attr( $id . '-label' ),
self::convert_markdown( esc_html( $label ) ) . ( $required ? ' ' . forminator_get_required_icon() : '' )
);
}
return $html;
}
/**
* Convert markdown to HTML.
*
* @param string $original_string Original string.
*
* @return string
*/
public static function convert_markdown( string $original_string ): string {
$string = $original_string;
// Apply markdown replacements.
$patterns = array(
'/(?<=^|\s)`(\S(?:.*?\S)?)`(?=\s|$)/u' => '$1',
'/(?<=^|\s)~(\S(?:.*?\S)?)~(?=\s|$)/u' => '$1',
'/(?<=^|\s)_(\S(?:.*?\S)?)_(?=\s|$)/u' => '$1',
'/(?<=^|\s)\*(\S(?:.*?\S)?)\*(?=\s|$)/u' => '$1',
);
foreach ( $patterns as $pattern => $replacement ) {
$string = preg_replace( $pattern, $replacement, $string );
}
/**
* Filter for custom markdown.
*/
return apply_filters( 'forminator_markdown_result', $string, $original_string );
}
/**
* Get full field id
*
* @param string $element_id Field slug.
* @return string
*/
protected static function get_field_id( $element_id ) {
return 'forminator-field-' . $element_id . '_' . Forminator_CForm_Front::$uid;
}
/**
* Return new select field
*
* @since 1.0
*
* @param array $attr Field attribute.
* @param string $label Field label.
* @param array $options Field option.
* @param string $value Field value.
* @param string $description Field description.
* @param bool $required Required.
* @param string $descr_position Description position.
*
* @return mixed
*/
public static function create_select( $attr = array(), $label = '', $options = array(), $value = '', $description = '', $required = false, $descr_position = 'above' ) {
$html = '';
if ( ! empty( $description ) ) {
$attr['aria-describedby'] = $attr['id'] . '-description';
}
if ( isset( $attr['id'] ) ) {
$get_id = $attr['id'];
} else {
$get_id = uniqid( 'forminator-select-' );
}
! empty( $label ) ? $attr['aria-labelledby'] = $get_id . '-label' : '';
! empty( $description ) ? $attr['aria-describedby'] = $get_id . '-description' : '';
$markup = self::implode_attr( $attr );
if ( self::get_post_data( $attr['name'], false ) ) {
$value = self::get_post_data( $attr['name'] );
}
$html .= self::get_field_label( $label, $get_id, $required );
if ( 'above' === $descr_position ) {
$html .= self::get_description( $description, $get_id, $descr_position );
}
$markup .= ' data-default-value="' . esc_attr( $value ) . '"';
$html .= sprintf( '';
if ( 'above' !== $descr_position ) {
$html .= self::get_description( $description, $get_id, $descr_position );
}
return apply_filters( 'forminator_field_create_select', $html, $attr, $label, $options, $value, $description );
}
/**
* Return new simple select field
*
* @since 1.0
*
* @param array $attr Field Attribute.
* @param array $options Field Options.
* @param string $value Field Value.
* @param string $description Field Description.
*
* @return mixed
*/
public static function create_simple_select( $attr = array(), $options = array(), $value = '', $description = '' ) {
_deprecated_function( 'create_simple_select', '1.6.1', 'create_select' );
$html = '';
$get_id = uniqid( 'forminator-select-' );
! empty( $description ) ? $attr['aria-describedby'] = $get_id . '-description' : '';
$markup = self::implode_attr( $attr );
if ( self::get_post_data( $attr['name'], false ) ) {
$value = self::get_post_data( $attr['name'] );
}
$html .= sprintf( '';
if ( ! empty( $description ) ) {
$html .= self::get_description( $description, $get_id );
}
return apply_filters( 'forminator_field_create_simple_select', $html, $attr, $options, $value, $description );
}
/**
* Populate s for