File "FrmProFieldsController.php"
Full path: /home/bud/public_html/swamp/wp-admin/wp-content/plugins/formidable-pro/classes/controllers/FrmProFieldsController.php
File size: 59.15 KB
MIME-type: text/x-php
Charset: utf-8
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'You are not allowed to call this page directly.' );
}
class FrmProFieldsController {
/**
* @var array|null $visible_embedded_form_ids used to determine if a field has been made visible by its embedded form parent.
*/
private static $visible_embedded_form_ids;
public static function &change_type( $type, $field ) {
global $frm_vars;
remove_filter( 'frm_field_type', 'FrmFieldsController::change_type' );
// Don't change user ID fields or repeating sections to hidden
if ( ! ( $type === 'divider' && FrmField::is_option_true( $field, 'repeat' ) ) && $type !== 'user_id' && ! FrmProGlobalVarsHelper::get_instance()->field_is_visible( $field ) ) {
$type = 'hidden';
}
if ( $type === '10radio' ) {
$type = 'scale';
}
if ( ! FrmAppHelper::is_admin() && $type !== 'hidden' && $type !== 'divider' && ! FrmProFieldsHelper::is_field_visible_to_user( $field ) ) {
$type = 'hidden';
}
return $type;
}
public static function use_field_key_value( $opt, $opt_key, $field ) {
//if(in_array($field['post_field'], array( 'post_category', 'post_status')) or ($field['type'] == 'user_id' and is_admin() and current_user_can('administrator')))
if ( FrmField::is_option_true( $field, 'use_key' ) ||
( isset($field['type']) && $field['type'] == 'data' ) ||
( isset($field['post_field']) && $field['post_field'] == 'post_status' )
) {
$opt = $opt_key;
}
return $opt;
}
/**
* @param array $field
* @param stdClass $form
* @param int $parent_form_id
* @return void
*/
public static function show_field( $field, $form, $parent_form_id ) {
global $frm_vars;
$is_custom_range = self::field_is_custom_format_range( $field );
if ( empty( $field['calc'] ) && ! $is_custom_range ) {
return;
}
if ( FrmProForm::is_ajax_on( $form ) && FrmAppHelper::doing_ajax() && empty( $frm_vars['inplace_edit'] ) ) {
return;
}
if ( ! isset( $frm_vars['calc_fields'] ) ) {
$frm_vars['calc_fields'] = array();
}
$attributes = array(
'field' => $field,
'form_id' => $form->id,
'parent_form_id' => $parent_form_id,
);
if ( $is_custom_range ) {
$attributes['calc'] = '[' . absint( $field['id'] ) . ']';
if ( empty( $field['custom_currency'] ) ) {
// Make sure default currency is loaded if field does not use a custom currency.
FrmProCurrencyHelper::add_currency_to_global( $form->id );
}
}
$frm_vars['calc_fields'][ $field['field_key'] ] = FrmProFormsHelper::get_calc_rule_for_field( $attributes );
}
/**
* @since x.x
*
* @param array $field
* @return bool
*/
private static function field_is_custom_format_range( $field ) {
return 'range' === $field['type'] && ! empty( $field['is_currency'] );
}
public static function build_field_class( $classes, $field ) {
if ( 'inline' == $field['conf_field'] ) {
$classes .= ' frm_conf_inline';
} else if ( 'below' == $field['conf_field'] ) {
$classes .= ' frm_conf_below';
}
$columns = '';
if ( FrmField::is_field_type( $field, 'checkbox' ) || FrmField::is_field_type( $field, 'radio' ) ) {
if ( isset( $field['align'] ) ) {
$columns = $field['align'];
}
if ( ! empty( $columns ) ) {
$field_obj = FrmFieldFactory::get_field_type( $field['type'] );
if ( is_callable( array( $field_obj, 'prepare_align_class' ) ) ) {
$field_obj->prepare_align_class( $columns );
}
}
}
$classes = str_replace( ' frmstart ', ' frmstart ' . $columns . ' ', $classes );
return $classes;
}
public static function input_html( $field, $echo = true ) {
$add_html = '';
self::add_readonly_input_attributes( $field, $add_html );
self::maybe_add_data_attribute_for_section( $field, $add_html );
self::add_multiple_select_attribute( $field, $add_html );
self::add_select_placeholder( $field, $add_html );
if ( FrmAppHelper::is_admin_page('formidable' ) ) {
if ( $echo ) {
echo $add_html;
}
//don't continue if we are on the form builder page
return $add_html;
}
FrmProLookupFieldsController::maybe_add_lookup_input_html( $field, $add_html );
self::add_html5_input_attributes( $field, $add_html );
self::add_checkbox_limit( $field, $add_html );
$add_html .= self::setup_input_masks( $field );
self::add_currency_field_attributes( $field, $add_html );
self::add_html_autocomplete( $field, $add_html );
if ( $echo ) {
echo $add_html;
}
return $add_html;
}
/**
* Add autocomplete attribute to the field html.
*
* @since 5.4.1
*
* @param array $field The field properties.
* @param string $add_html The field html.
* @return void
*/
private static function add_html_autocomplete( $field, &$add_html ) {
if ( ! empty( $field['autocomplete'] ) ) {
$add_html .= 'autocomplete="' . esc_attr( $field['autocomplete'] ) . '"';
}
}
public static function setup_input_masks( $field ) {
$html = '';
$text_lookup = $field['type'] == 'lookup' && $field['data_type'] == 'text';
$is_format_field = in_array( $field['type'], array( 'phone', 'text' ) ) || $text_lookup;
if ( FrmProField::is_format_option_true_with_no_regex( $field ) && $is_format_field ) {
$html = self::setup_input_mask( $field['format'] );
}
return $html;
}
public static function setup_input_mask( $format ) {
global $frm_input_masks;
$frm_input_masks[] = true;
return ' data-frmmask="' . esc_attr( preg_replace( '/\d/', '9', $format ) ) . '"';
}
/**
* Add product attributes to fields in multi-paged forms.
*
* @since 4.04
*/
public static function add_currency_field_attributes( $field, &$add_html, $parent = null ) {
$type = isset( $field['original_type'] ) ? $field['original_type'] : $field['type'];
$is_product_field = in_array( $type, array( 'total', 'quantity', 'product' ) );
if ( ! $is_product_field ) {
return;
}
if ( $type === 'total' ) {
$add_html .= ' data-frmtotal ';
} elseif ( $type === 'quantity' ) {
$product_field = FrmField::get_option( $field, 'product_field' );
$add_html .= ' data-frmproduct="' . esc_attr( json_encode( $product_field ) ) . '" ';
} elseif ( $type === 'product' && 'hidden' === $field['type'] ) {
// We want to do this only for fields that are hidden because it's
// not their page, hence the check : 'hidden' === $field['type'].
$price = empty( $field['value'] ) ? 0 : self::get_product_price( $field );
/**
* This helps to know if this field should be included in the total calc of the current page by JS.
* Fields on higher pages aren't included, else you get error of invalid total on submission.
*
* For fields in a repeater or embedded form, their parents are used instead, else the page check may be incorrect.
*/
$use_this = null === $parent ? $field : $parent;
$higher_pg = FrmProFieldsHelper::field_on_page( $use_this, 'higher' ) ? 'data-frmhigherpg ' : '';
$add_html .= ' data-frmprice="' . esc_attr( $price ) . '" ' . $higher_pg;
}
if ( FrmProFieldsHelper::is_on_skipped_page( $field, $parent ) ) {
$add_html .= ' data-frmhidden="1" ';
}
}
private static function get_product_price( $field ) {
if ( is_array( $field['value'] ) ) {
// '' is unlikely though, let's just do it to prevent warnings
$value = isset( $field['opt_key'] ) && isset( $field['value'][ $field['opt_key'] ] ) ?
$field['value'][ $field['opt_key'] ] : '';
} else {
$value = $field['value'];
}
$field_obj = FrmFieldFactory::get_field_object( $field['id'] );
$price = $field_obj->get_posted_price( $value );
unset( $field_obj ); // lighten up on memory
return $price;
}
/**
* Add readonly/disabled input attributes
*
* @since 2.02.06
* @param array $field
* @param string $add_html
*/
private static function add_readonly_input_attributes( $field, &$add_html ) {
if ( FrmField::is_option_true( $field, 'read_only' ) && $field['type'] != 'hidden' && $field['type'] != 'lookup' ) {
global $frm_vars;
if ( ( isset( $frm_vars['readonly'] ) && $frm_vars['readonly'] == 'disabled' ) || ( current_user_can( 'frm_edit_entries' ) && FrmAppHelper::is_admin() ) ) {
//not read only
} elseif ( in_array( $field['type'], array( 'select', 'radio', 'checkbox', 'time' ) ) ) {
$add_html .= ' disabled="disabled" ';
} else {
$add_html .= ' readonly="readonly" ';
}
}
}
/**
* Add multiple select attribute
*
* @since 2.02.06
* @param array $field
* @param string $add_html
*/
private static function add_multiple_select_attribute( $field, &$add_html ) {
if ( FrmField::is_multiple_select( $field ) ) {
$add_html .= ' multiple="multiple" ';
}
}
/**
* @since 4.0
*/
private static function add_select_placeholder( $field, &$add_html ) {
if ( ! FrmField::is_field_type( $field, 'select' ) ) {
return;
}
$placeholder = FrmField::get_option( $field, 'placeholder' );
$autocomplete = FrmField::get_option( $field, 'autocom' );
if ( $placeholder === '' && empty( $autocomplete ) ) {
// The field doesn't need a placeholder.
return;
}
$default = FrmField::is_multiple_select( $field ) ? __( 'Select options', 'formidable-pro' ) : __( 'Select an option', 'formidable-pro' );
$add_html .= ' data-placeholder="' . esc_attr( ! empty( $placeholder ) ? $placeholder : $default ) . '" ';
}
/**
* Add a few HTML5 input attributes
*
* @since 2.02.06
* @param array $field
* @param string $add_html
*/
private static function add_html5_input_attributes( $field, &$add_html ) {
global $frm_vars;
$frm_settings = FrmAppHelper::get_settings();
if ( $frm_settings->use_html ) {
if ( FrmField::is_option_true( $field, 'autocom' ) && $field['type'] !== 'hidden' && FrmField::is_field_type( $field, 'select' ) ) {
//add label for autocomplete fields
$add_html .= ' data-placeholder=" "';
}
if ( in_array( $field['type'], array( 'url', 'email' ) ) ) {
if ( ( ! isset($frm_vars['novalidate']) || ! $frm_vars['novalidate'] ) && ( $field['type'] != 'email' || ( isset($field['value']) && $field['default_value'] == $field['value'] ) ) ) {
// add novalidate for drafts
$frm_vars['novalidate'] = true;
}
}
}
}
/**
* If the field has a limit set, add it to the HTML.
*
* @since 4.02
*/
private static function add_checkbox_limit( $field, &$add_html ) {
$selections_limit = FrmField::get_option( $field, 'limit_selections' );
if ( $selections_limit ) {
$add_html .= ' data-frmlimit="' . esc_attr( $selections_limit ) . '" ';
}
}
/**
* Add data-sectionid attribute for fields in section
*
* @since 2.01.0
* @param array $field
* @param string $add_html
*/
private static function maybe_add_data_attribute_for_section( $field, &$add_html ) {
if ( FrmField::is_option_true_in_array( $field, 'in_section' ) ) {
$add_html .= ' data-sectionid="' . $field['in_section'] . '"';
}
// TODO: Add data attribute for embedded form fields as well
}
public static function add_field_class( $class, $field ) {
if ( FrmAppHelper::is_admin() || FrmField::is_read_only( $field ) ) {
return $class;
}
$is_hidden = FrmField::get_field_type( $field ) === 'hidden';
if ( ! $is_hidden && FrmField::is_option_true( $field, 'autocom' ) && FrmField::is_field_type( $field, 'select' ) && ! empty( $field['options'] ) ) {
self::add_autocomplete_classes( $field, $class );
}
return $class;
}
/**
* Add the autocomplete classes to a $class string
*
* @since 2.01.0
*
* @param array $field
* @param string $class
*/
public static function add_autocomplete_classes( $field, &$class ) {
global $frm_vars;
$frm_vars['chosen_loaded'] = true;
$class .= ' frm_chzn';
$style = FrmStylesController::get_form_style( $field['form_id'] );
if ( $style && 'rtl' == $style->post_content['direction'] ) {
$class .= ' chosen-rtl';
}
}
/**
* Add Other Option after click.
*
* @since 4.0
*/
public static function add_other_option() {
FrmAppHelper::permission_check( 'frm_edit_forms' );
check_ajax_referer( 'frm_ajax', 'nonce' );
$id = FrmAppHelper::get_post_param( 'field_id', 0, 'absint' );
$opt_type = FrmAppHelper::get_post_param( 'opt_type', '', 'sanitize_text_field' );
$opt_key = FrmAppHelper::get_post_param( 'opt_key', 0, 'absint' );
$field = FrmField::getOne( $id );
$field_data = $field;
$field = (array) $field;
$field['separate_value'] = isset( $field_data->field_options['separate_value'] ) ? $field_data->field_options['separate_value'] : 0;
unset( $field_data );
$field['html_name'] = 'item_meta[' . $field['id'] . ']';
$field['options'] = array( 'other_' . $opt_key => __( 'Other', 'formidable-pro' ) );
FrmFieldsHelper::show_single_option( $field );
wp_die();
}
public static function options_form_before( $field ) {
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/options-before.php' );
}
public static function options_form_top( $field, $display, $values ) {
if ( $display['conf_field'] && ! in_array( $field['type'], array( 'email', 'password' ) ) ) {
_deprecated_function( __FUNCTION__, '4.0', 'FrmFieldType->show_primary_options' );
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/confirmation.php' );
}
}
/**
* @since 4.0
*
* @param array $args {
* @type array $display
* @type array $field
* }
* @return void
*/
public static function advanced_field_options( $args ) {
$display = $args['display'];
$field = $args['field'];
$is_checkbox = FrmField::is_field_type( $field, 'checkbox' );
$is_radio = FrmField::is_field_type( $field, 'radio' );
if ( $display['type'] === 'radio' || $display['type'] === 'checkbox' || $is_radio || $is_checkbox ) {
self::alignment_setting( $args );
}
if ( ! empty( $display['prefix'] ) ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/prepend-options.php';
}
if ( $field['type'] === 'divider' && ! empty( $field['repeat'] ) ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/repeat-options.php';
}
if ( 'textarea' === $field['type'] ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/auto-grow.php';
}
if ( ! empty( $display['autocomplete'] ) ) {
self::show_autocomplete_option( $args['field'] );
}
if ( ! empty( $display['visibility'] ) ) {
self::show_visibility_option( $args['field'] );
}
}
/**
* @since 4.0
* @param array $args - includes 'field'
*/
public static function alignment_setting( $args ) {
$field = $args['field'];
$columns = array(
'block' => __( 'One Column', 'formidable-pro' ),
'frm_two_col' => __( 'Two Columns', 'formidable-pro' ),
'frm_three_col' => __( 'Three Columns', 'formidable-pro' ),
'frm_four_col' => __( 'Four Columns', 'formidable-pro' ),
'inline' => __( 'Inline Options', 'formidable-pro' ),
);
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/alignment.php' );
}
/**
* @since 4.0
* @param array $args - includes 'field', 'display', and 'values'
*/
public static function options_form_after( $args ) {
if ( isset( $args['display']['logic'] ) && $args['display']['logic'] ) {
self::show_conditional_logic_option( $args['field'] );
}
}
/**
* Add calc details.
*
* @since 4.0
* @param array $types
* @param array $atts Includes 'display'
*/
public static function default_value_types( $types, $atts ) {
$types['calc']['class'] = ''; // Remove upgrade links.
$types['calc']['data'] = array(
'frmshow' => '#calc-for-',
);
if ( ! isset( $atts['display']['calc'] ) || ! $atts['display']['calc'] ) {
unset( $types['calc'] );
}
$types['get_values_field']['class'] = 'frm-show-inline-modal'; // Remove upgrade links.
$types['get_values_field']['data'] = array(
'open' => 'frm-lookup-box-',
'frmshow' => '.frm-lookup-box-',
'frmhide' => '.frm-inline-modal,.default-value-section-',
);
if ( ! isset( $atts['display']['autopopulate'] ) || ! $atts['display']['autopopulate'] ) {
unset( $types['get_values_field'] );
}
return $types;
}
/**
* @since 4.0
* @param array $args - includes 'field', 'display', 'default_value_types'.
*/
public static function more_default_values( $args ) {
$field = $args['field'];
$default_value_types = $args['default_value_types'];
self::maybe_include_default_values( $field );
if ( ! empty( $args['display']['calc'] ) ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/calculations.php';
}
if ( ! empty( $args['display']['autopopulate'] ) ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/autopopulate.php';
}
}
/**
* Use a list of values in the field instead of smart values for
* post categories and dynamic fields.
*
* @since 4.01.02
*
* @param array $field
*/
private static function maybe_include_default_values( $field ) {
$is_taxonomy = isset( $field['post_field'] ) && $field['post_field'] === 'post_category';
$is_dynamic = $field['type'] === 'data';
if ( ! $is_taxonomy && ! $is_dynamic ) {
return;
}
FrmFieldsHelper::inline_modal(
array(
'title' => __( 'Default Value', 'formidable' ),
'callback' => array( 'FrmProFieldsController', 'default_dynamic_options' ),
'args' => $field,
'id' => 'frm-tax-box-' . $field['id'],
'class' => 'frm-tax-modal frm-tax-box-' . $field['id'],
)
);
}
/**
* Show a list of options in a dynamic field or category field
* in order to set the default value.
*
* @since 4.01.02
*
* @param array $field
*/
public static function default_dynamic_options( $field ) {
$tags = $field['options'];
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/default-terms.php' );
}
/**
* @since 4.0
* @param array $args - includes 'field'
*/
public static function calculation_settings( $args ) {
$field = $args['field'];
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/calculation-settings.php' );
}
/**
* Display the visibility option
*
* @since 2.02.06
* @param array $field
*/
public static function show_visibility_option( $field ) {
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/visibility.php' );
}
/**
* Display the autocomplete option
*
* @since 5.4.1
*
* @param array $field
* @return void
*/
public static function show_autocomplete_option( $field ) {
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/autocomplete.php';
}
/**
* Display the conditional logic option
*
* @since 2.02.06
* @param array $field
*/
public static function show_conditional_logic_option( $field ) {
$form_fields = false;
if ( ! empty( $field['hide_field'] ) && is_array( $field['hide_field'] ) ) {
$form_id = isset( $field['parent_form_id'] ) ? $field['parent_form_id'] : $field['form_id'];
$form_fields = FrmField::get_all_for_form( $form_id );
}
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/back-end/logic.php' );
}
public static function get_field_selection() {
FrmAppHelper::permission_check('frm_view_forms');
check_ajax_referer( 'frm_ajax', 'nonce' );
$current_field_id = FrmAppHelper::get_post_param( 'field_id', '', 'absint' );
$form_id = FrmAppHelper::get_post_param( 'form_id', '', 'sanitize_text_field' );
if ( is_numeric( $form_id ) ) {
$selected_field = '';
$fields = self::get_field_selection_fields( $form_id );
if ( $fields ) {
require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/field-selection.php' );
}
} else {
$selected_field = $form_id;
if ( $selected_field == 'taxonomy' ) {
echo '<div class="frm-inline-message">' . esc_html__( 'Select a taxonomy on the Form Actions tab of the Form Settings page', 'formidable-pro' ) . '</div>';
echo '<input type="hidden" name="field_options[form_select_' . esc_attr( $current_field_id ) . ']" value="taxonomy" />';
}
}
wp_die();
}
/**
* Gets fields for field selection.
*
* @since 5.0.04
*
* @param int $form_id Form ID.
* @return object[]
*/
public static function get_field_selection_fields( $form_id ) {
$fields = FrmField::get_all_for_form( $form_id );
if ( $fields ) {
/**
* Allows modifying fields in Field selection of Dynamic field.
*
* @since 5.0.04
*
* @param array $fields The fields.
* @param array $args Includes `form_id`.
*/
$fields = apply_filters( 'frm_pro_fields_in_dynamic_selection', $fields, compact( 'form_id' ) );
}
return $fields;
}
/**
* Get the field value selector for field or action logic
*/
public static function get_field_values() {
FrmAppHelper::permission_check('frm_view_forms');
check_ajax_referer( 'frm_ajax', 'nonce' );
$selector_args = array(
'value' => '',
);
$selector_args['html_name'] = sanitize_text_field( $_POST['name'] );
if ( empty( $selector_args['html_name'] ) || $selector_args['html_name'] == 'undefined' ) {
$selector_args['html_name'] = 'field_options[hide_opt_' . absint( $_POST['current_field'] ) . '][]';
}
if ( FrmAppHelper::get_param( 'form_action', '', 'get', 'sanitize_text_field' ) == 'update_settings' ) {
$selector_args['source'] = 'form_actions';
} else {
$field_type = sanitize_text_field( $_POST['t'] );
$selector_args['source'] = ! empty( $field_type ) ? $field_type : 'unknown';
}
FrmFieldsHelper::display_field_value_selector( absint( $_POST['field_id'] ), $selector_args );
wp_die();
}
public static function get_dynamic_widget_opts() {
check_ajax_referer( 'frm_ajax', 'nonce' );
$form_id = get_post_meta( (int) $_POST['display_id'], 'frm_form_id', true );
if ( ! $form_id ) {
wp_die();
}
$fields = FrmField::getAll( array( 'fi.type not' => FrmField::no_save_fields(), 'fi.form_id' => $form_id ), 'field_order');
$options = array(
'titleValues' => array(),
'catValues' => array(),
);
foreach ( $fields as $field ) {
$options['titleValues'][ $field->id ] = $field->name;
if ( $field->type == 'select' || $field->type == 'radio' ) {
$options['catValues'][ $field->id ] = $field->name;
}
unset($field);
}
echo json_encode($options);
wp_die();
}
public static function date_field_js( $field_id, $options ) {
if ( empty( $options['unique'] ) ) {
return;
}
$defaults = array(
'entry_id' => 0,
'start_year' => '-10',
'end_year' => '+10',
'locale' => '',
'unique' => 0,
'field_id' => 0,
);
$options = wp_parse_args( $options, $defaults );
global $wpdb;
$field = FrmField::getOne( $options['field_id'] );
if ( isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] != '' ) {
$query = array( 'post_status' => array( 'publish', 'draft', 'pending', 'future', 'private' ) );
if ( $field->field_options['post_field'] === 'post_custom' ) {
$get_field = 'meta_value';
$get_table = $wpdb->postmeta . ' pm LEFT JOIN ' . $wpdb->posts . ' p ON (p.ID=pm.post_id)';
$query['meta_value !'] = '';
$query['meta_key'] = $field->field_options['custom_field'];
} else {
$get_field = sanitize_title( $field->field_options['post_field'] );
$get_table = $wpdb->posts;
}
$post_dates = FrmDb::get_col( $get_table, $query, $get_field );
}
if ( ! is_numeric( $options['entry_id'] ) ) {
$disabled = wp_cache_get($options['field_id'], 'frm_used_dates');
}
if ( ! isset($disabled) || ! $disabled ) {
$disabled = FrmDb::get_col( $wpdb->prefix . 'frm_item_metas', array( 'field_id' => $options['field_id'], 'item_id !' => $options['entry_id'] ), 'meta_value' );
}
if ( isset($post_dates) && $post_dates ) {
$disabled = array_unique(array_merge( (array) $post_dates, (array) $disabled ));
}
/**
* Allows additional logic to be added to selectable dates
* To prevent weekends from being selectable, 'true' would be changed to '(day != 0 && day != 6)'
*
* @since 2.0
*/
$selectable_response = apply_filters( 'frm_selectable_dates', 'true', compact( 'field', 'options' ) );
$disabled = apply_filters('frm_used_dates', $disabled, $field, $options);
if ( ! is_numeric( $options['entry_id'] ) && ! empty( $disabled ) ) {
wp_cache_set( $options['field_id'], $disabled, 'frm_used_dates' );
}
// This function is added in v1.04 of the Dates add on. Before that version, these filters are not supported.
if ( is_callable( 'FrmDatesAppHelper::plugin_version' ) ) {
add_filter(
'frm_dates_selectable_response',
function( $is_enabled, $filter_field ) use ( $selectable_response, $field ) {
if ( ! $field->field_options['unique'] ) {
return $is_enabled;
}
return $filter_field->field_key !== $field->field_key ? $is_enabled : $selectable_response;
},
10,
2
);
add_filter(
'frm_dates_disabled',
function( $blackout_dates, $filter_field ) use ( $disabled, $field ) {
return $filter_field->field_key !== $field->field_key ? $blackout_dates : array_merge( $blackout_dates, $disabled );
},
10,
2
);
return;
}
$js_vars = 'var m=(date.getMonth()+1),d=date.getDate(),y=date.getFullYear(),day=date.getDay();';
if ( empty( $disabled ) ) {
if ( $selectable_response != 'true' ) {
// If the filter has been used, include it
echo ',beforeShowDay:function(date){' . $js_vars . 'return [' . $selectable_response . '];}';
}
return;
}
$formatted = array();
foreach ( $disabled as $dis ) {
// format to match javascript dates
$formatted[] = gmdate( 'Y-n-j', strtotime( $dis ) );
}
$disabled = $formatted;
unset( $formatted );
echo ',beforeShowDay: function(date){' . $js_vars . 'var disabled=' . json_encode( $disabled ) . ';if($.inArray(y+"-"+m+"-"+d,disabled) != -1){return [false];} return [' . $selectable_response . '];}';
}
/**
* @since 2.0.23
*/
public static function maybe_make_field_optional( $required, $field ) {
if ( $required && ! FrmAppHelper::is_admin_page('formidable' ) ) {
global $frm_vars;
$is_editing = isset( $frm_vars['editing_entry'] ) && $frm_vars['editing_entry'] && is_numeric( $frm_vars['editing_entry'] );
if ( $is_editing ) {
$optional_on_edit = apply_filters( 'frm_optional_fields_on_edit', array( 'password', 'credit_card' ) );
if ( in_array( $field['type'], (array) $optional_on_edit ) ) {
$entry = FrmEntry::getOne( $frm_vars['editing_entry'] );
if ( $entry && $entry->form_id === $field['form_id'] && ! $entry->is_draft ) {
$required = false;
}
}
}
}
return $required;
}
/**
* @since 5.2.04
*/
public static function ajax_get_data_arr() {
$post_data = FrmAppHelper::get_param( 'postData' );
$response = array();
foreach ( $post_data as $data ) {
if ( ! isset( $data['entry_id'] ) || ! isset( $data['current_field'] ) || ! isset( $data['hide_id'] ) ) {
continue;
}
$result_str = '';
$entry_id = is_array( $data['entry_id'] ) ? array_map( 'intval', $data['entry_id'] ) : intval( $data['entry_id'] );
$current_field = intval( $data['current_field'] );
$hidden_field_id = sanitize_text_field( wp_unslash( $data['hide_id'] ) );
$current = FrmField::getOne( $current_field );
$data_field = FrmField::getOne( $current->field_options['form_select'] );
$meta_value = self::get_meta_value_for_ajax_handler( $entry_id, $data_field );
if ( $meta_value === null ) {
$response[] = $result_str;
continue;
}
$data_display_opts = apply_filters( 'frm_display_data_opts', array( 'html' => true, 'wpautop' => false ) );
$value = FrmFieldsHelper::get_display_value( $meta_value, $data_field, $data_display_opts );
if ( is_array( $value ) ) {
$value = implode( ', ', $value );
}
if ( is_array( $meta_value ) ) {
$meta_value = implode( ', ', $meta_value );
}
$current_field = (array) $current;
foreach ( $current->field_options as $o => $v ) {
if ( ! isset( $current_field[ $o ] ) ) {
$current_field[ $o ] = $v;
}
unset($o, $v);
}
// Set up HTML ID and HTML name
$html_id = '';
$field_name = 'item_meta';
FrmProFieldsHelper::get_html_id_from_container($field_name, $html_id, (array) $current, $hidden_field_id);
$on_current_page = $data['on_current_page'];
$on_current_page = ( 'true' === $on_current_page );
if ( $on_current_page && FrmProFieldsHelper::is_field_visible_to_user( $current ) ) {
if ( FrmAppHelper::is_not_empty_value( $value ) && $value !== false ) {
$result_str .= apply_filters(
'frm_show_it',
'<p class="frm_show_it">' . $value . "</p>\n",
$value,
array(
'field' => $data_field,
'value' => $meta_value,
'entry_id' => $entry_id,
)
);
}
$result_str .= '<input type="hidden" id="' . esc_attr( $html_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '" ' . do_action( 'frm_field_input_html', $current_field, false ) . '/>';
} else {
$result_str .= esc_attr( $value );
}
$response[] = $result_str;
}
wp_send_json( $response );
}
/**
* @deprecated 5.2.03
*/
public static function ajax_get_data() {
_deprecated_function( __METHOD__, '5.2.03' );
//check_ajax_referer( 'frm_ajax', 'nonce' );
$entry_id = self::get_posted_entry_ids();
$current_field = FrmAppHelper::get_param( 'current_field', '', 'get', 'absint' );
$hidden_field_id = FrmAppHelper::get_param( 'hide_id', '', 'get', 'sanitize_text_field' );
self::get_data_for_ajax_handler( $entry_id, $current_field, $hidden_field_id );
wp_die();
}
/**
* Gets meta value for ajax handler.
*
* @since 5.2.04
* @since 5.2.05 The first parameter can be int or array.
*
* @param int|array $entry_id Entry ID or array of entry IDs.
* @param object $data_field The data field.
* @return string|array
*/
private static function get_meta_value_for_ajax_handler( $entry_id, $data_field ) {
if ( is_array( $entry_id ) ) {
$meta_value = array();
foreach ( $entry_id as $eid ) {
$new_meta = FrmProEntryMetaHelper::get_post_or_meta_value( $eid, $data_field );
if ( $new_meta ) {
foreach ( (array) $new_meta as $nm ) {
array_push( $meta_value, $nm );
unset( $nm );
}
}
unset( $new_meta, $eid );
}
$meta_value = array_unique( $meta_value );
} else {
$meta_value = FrmProEntryMetaHelper::get_post_or_meta_value( $entry_id, $data_field );
}
return $meta_value;
}
/**
* @since 5.2.04
*/
private static function get_data_for_ajax_handler( $entry_id, $current_field, $hidden_field_id ) {
$current = FrmField::getOne( $current_field );
$data_field = FrmField::getOne( $current->field_options['form_select'] );
$meta_value = self::get_meta_value_for_ajax_handler( $entry_id, $data_field );
if ( null === $meta_value ) {
wp_die();
}
$data_display_opts = apply_filters( 'frm_display_data_opts', array( 'html' => true, 'wpautop' => false ) );
$value = FrmFieldsHelper::get_display_value( $meta_value, $data_field, $data_display_opts );
if ( is_array( $value ) ) {
$value = implode( ', ', $value );
}
if ( is_array( $meta_value ) ) {
$meta_value = implode( ', ', $meta_value );
}
$current_field = (array) $current;
foreach ( $current->field_options as $o => $v ) {
if ( ! isset( $current_field[ $o ] ) ) {
$current_field[ $o ] = $v;
}
unset( $o, $v );
}
// Set up HTML ID and HTML name
$html_id = '';
$field_name = 'item_meta';
FrmProFieldsHelper::get_html_id_from_container( $field_name, $html_id, (array) $current, $hidden_field_id );
$on_current_page = FrmAppHelper::get_param( 'on_current_page', 'true', 'get', 'sanitize_text_field' );
$on_current_page = ( $on_current_page == 'true' );
if ( $on_current_page && FrmProFieldsHelper::is_field_visible_to_user( $current ) ) {
if ( FrmAppHelper::is_not_empty_value( $value ) && $value !== false ) {
echo apply_filters( 'frm_show_it', "<p class='frm_show_it'>" . $value . "</p>\n", $value, array( 'field' => $data_field, 'value' => $meta_value, 'entry_id' => $entry_id ) );
}
echo '<input type="hidden" id="' . esc_attr( $html_id ) . '" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $value ) . '" ' . do_action( 'frm_field_input_html', $current_field, false ) . '/>';
} else {
echo esc_attr( $value );
}
}
/**
* @since 2.05.04
*/
private static function get_posted_entry_ids() {
$entry_id = FrmAppHelper::get_param( 'entry_id', '', 'get', 'sanitize_text_field' );
if ( is_array( $entry_id ) ) {
$entry_id = implode(',', $entry_id);
}
return trim( $entry_id, ',' );
}
/**
* Get the HTML for a dependent Dynamic field when the parent changes
*/
public static function ajax_data_options() {
//check_ajax_referer( 'frm_ajax', 'nonce' );
$args = array(
'trigger_field_id' => FrmAppHelper::get_param( 'trigger_field_id', '', 'post', 'absint' ),
'entry_id' => FrmAppHelper::get_param( 'entry_id', '', 'post', 'sanitize_text_field' ),
'field_id' => FrmAppHelper::get_param( 'field_id', '', 'post', 'absint' ),
'container_id' => FrmAppHelper::get_param( 'container_id', '', 'post', 'sanitize_title' ),
'default_value' => FrmAppHelper::get_param( 'default_value', '', 'post', 'sanitize_title' ),
'prev_val' => FrmAppHelper::get_param( 'prev_val', '', 'post', 'absint' ),
);
if ( $args['entry_id'] == '' ) {
wp_die();
}
if ( ! is_array( $args['entry_id'] ) ) {
$entry_id = explode( ',', $args['entry_id'] );
}
$args['field_data'] = FrmField::getOne( $args['field_id'] );
$field = self::initialize_dependent_dynamic_field( $args );
if ( is_numeric( $args['field_data']->field_options['form_select'] ) ) {
// If Dynamic field is pulling options from a regular field
self::get_dependent_dynamic_field_options( $args, $field );
} else if ( $args['field_data']->field_options['form_select'] == 'taxonomy' ) {
// If Dynamic field is pulling options from a taxonomy
self::get_dependent_category_field_options( $args, $field );
}
self::get_dependent_dynamic_field_value( $args['prev_val'], $field );
// Set up HTML ID and HTML name
$input_args = array(
'field_name' => 'item_meta',
'field_id' => $args['field_data']->id,
'field_plus_id' => '',
'section_id' => '',
'html_id' => '',
);
FrmProFieldsHelper::get_html_id_from_container( $input_args['field_name'], $input_args['html_id'], $field, $args['container_id'] );
if ( FrmField::is_multiple_select( $args['field_data'] ) ) {
$input_args['field_name'] .= '[]';
}
$field_obj = FrmFieldFactory::get_field_type( 'data', $field );
echo $field_obj->include_front_field_input( $input_args, array() );
wp_die();
}
/**
* Initialize the field array for a dependent dynamic field
*
* @param array $args
* @return array $field
*/
private static function initialize_dependent_dynamic_field( $args ) {
$field = FrmProFieldsHelper::initialize_array_field( $args['field_data'], $args );
return $field;
}
/**
* Get the options for a dependent Dynamic field
*
* @since 2.0.16
* @param array $args
* @param array $field
*/
private static function get_dependent_dynamic_field_options( $args, &$field ) {
$linked_field = FrmField::getOne( $args['field_data']->field_options['form_select'] );
$field['options'] = array();
$metas = array();
FrmProEntryMetaHelper::meta_through_join( $args['trigger_field_id'], $linked_field, $args['entry_id'], $args['field_data'], $metas );
$metas = wp_unslash( $metas );
if ( FrmProDynamicFieldsController::include_blank_option( $metas, $args['field_data'] ) ) {
$field['options'][''] = '';
}
foreach ( $metas as $meta ) {
$field['options'][ $meta->item_id ] = FrmEntriesHelper::display_value(
$meta->meta_value,
$linked_field,
array(
'type' => $linked_field->type,
'show_icon' => true,
'show_filename' => false,
)
);
unset($meta);
}
// change the form_select value so the filter doesn't override the values
$args['field_data']->field_options['form_select'] = 'filtered_' . $args['field_data']->field_options['form_select'];
FrmFieldsHelper::prepare_new_front_field( $field, $args['field_data'] );
// Sort the options
$pass_args = array( 'metas' => $metas, 'field' => $linked_field, 'dynamic_field' => $field );
$field['options'] = apply_filters( 'frm_data_sort', $field['options'], $pass_args );
}
/**
* Get the options for a dependent Dynamic category field
*
* @since 2.0.16
* @param array $args
* @param array $field
*/
private static function get_dependent_category_field_options( $args, &$field ) {
if ( $args['entry_id'] == 0 ) {
wp_die();
}
if ( is_array( $args['entry_id'] ) ) {
$zero = array_search(0, $args['entry_id']);
if ( $zero !== false ) {
unset( $args['entry_id'][ $zero ] );
}
if ( empty( $args['entry_id'] ) ) {
wp_die();
}
}
FrmFieldsHelper::prepare_new_front_field( $field, $args['field_data'] );
$cat_ids = array_keys($field['options']);
$cat_args = array( 'include' => implode(',', $cat_ids), 'hide_empty' => false);
$post_type = FrmProFormsHelper::post_type( $args['field_data']->form_id );
$cat_args['taxonomy'] = FrmProAppHelper::get_custom_taxonomy($post_type, $args['field_data']);
if ( ! $cat_args['taxonomy'] ) {
wp_die();
}
$cats = get_categories($cat_args);
foreach ( $cats as $cat ) {
if ( ! in_array( $cat->parent, (array) $args['entry_id'] ) ) {
unset( $field['options'][ $cat->term_id ] );
}
}
if ( count($field['options']) == 1 && reset($field['options']) == '' ) {
wp_die();
}
// Sort the options
$field['options'] = apply_filters( 'frm_data_sort', $field['options'], array( 'dynamic_field' => $field ) );
}
/**
* Get the field value for a dependent dynamic field
*
* @since 2.0.16
* @param array $prev_val
* @param array $field
*/
private static function get_dependent_dynamic_field_value( $prev_val, &$field ) {
// Set the value to the previous value if it was set. Otherwise, set to default value.
if ( $prev_val ) {
$prev_val = array_unique( $prev_val );
$field['value'] = $prev_val;
} else {
$field['value'] = $field['default_value'];
}
// Unset the field value if it isn't an option
if ( $field['value'] ) {
$field['value'] = (array) $field['value'];
foreach ( $field['value'] as $key => $field_val ) {
if ( ! array_key_exists( $field_val, $field['options'] ) ) {
unset( $field['value'][ $key ] );
}
}
}
if ( is_array( $field['value'] ) && empty( $field['value'] ) ) {
$field['value'] = '';
}
// If we have a radio field, set the field value to a string
if ( $field['data_type'] == 'radio' && is_array( $field['value'] ) ) {
$field['value'] = reset( $field['value'] );
}
}
/**
* @deprecated 2.03
* @codeCoverageIgnore
*/
public static function ajax_time_options() {
_deprecated_function( __FUNCTION__, '2.03', 'FrmProTimeFieldsController::ajax_time_options' );
FrmProTimeFieldsController::ajax_time_options();
}
/**
* Add an option at the top of the media library page
* to show the unattached Formidable files based on user role.
*
* @since 2.02
*/
public static function filter_media_library_link() {
global $current_screen;
if ( $current_screen && 'upload' == $current_screen->base && current_user_can('frm_edit_entries') ) {
echo '<label for="frm-attachment-filter" class="screen-reader-text">';
echo esc_html__( 'Show form uploads', 'formidable-pro' );
echo '</label>';
$filtered = FrmAppHelper::get_param( 'frm-attachment-filter', '', 'get', 'absint' );
echo '<select name="frm-attachment-filter" id="frm-attachment-filter">';
echo '<option value="">' . esc_html__( 'Hide form uploads', 'formidable-pro' ) . '</option>';
echo '<option value="1" ' . selected( $filtered, 1 ) . '>' . esc_html__( 'Show form uploads', 'formidable-pro' ) . '</option>';
echo '</select>';
}
}
/**
* If this file is a Formidable file,
* temp redirect to the home page
*
* @since 2.02
*/
public static function redirect_attachment() {
global $post;
if ( ! is_object( $post ) || ! is_attachment() || absint( $post->post_parent ) >= 1 || ! FrmProFileField::is_formidable_file( $post->ID ) ) {
return;
}
$user_has_file_access = current_user_can('frm_edit_entries') && FrmProFileField::user_has_permission( $post->ID );
if ( ! $user_has_file_access ) {
wp_redirect( get_bloginfo('wpurl'), 302 );
die();
}
}
/**
* Check for old temp files and delete them
*
* @since 2.02
*/
public static function delete_temp_files() {
remove_action( 'pre_get_posts', 'FrmProFileField::filter_media_library', 99 );
$cutoff_period = apply_filters( 'frm_delete_temp_files_period', '-3 hours' );
$timestamp_cutoff = gmdate( 'Y-m-d H:i:s', strtotime( $cutoff_period ) );
$old_uploads = get_posts(
array(
'post_type' => 'attachment',
'posts_per_page' => 50,
'date_query' => array(
'column' => 'post_date_gmt',
'before' => $timestamp_cutoff,
),
'meta_query' => array(
array(
'key' => '_frm_temporary',
'compare' => 'EXISTS',
),
),
'post_parent' => 0,
)
);
foreach ( $old_uploads as $upload ) {
// double check in case other plugins have changed the query
if ( FrmProFileField::file_is_temporary( $upload->ID ) ) {
wp_delete_attachment( $upload->ID, true );
}
}
add_action( 'pre_get_posts', 'FrmProFileField::filter_media_library', 99 );
}
public static function ajax_upload() {
// Skip nonce for caching.
$response = FrmProFileField::ajax_upload();
if ( ! empty( $response['errors'] ) ) {
status_header( 403 );
$status = 403;
echo implode( ' ', $response['errors'] );
} else {
$status = 200;
echo json_encode( $response['media_ids'] );
}
wp_die( '', '', array( 'response' => $status ) );
}
/**
* Allow more field types for switching.
*
* @since 4.05
*
* @return array
*/
public static function single_input_fields( $fields ) {
$fields[] = 'range';
return $fields;
}
public static function _logic_row() {
check_ajax_referer( 'frm_ajax', 'nonce' );
FrmAppHelper::permission_check('frm_edit_forms', 'show');
$meta_name = FrmAppHelper::get_post_param( 'meta_name', '', 'absint' );
$field_id = FrmAppHelper::get_post_param( 'field_id', '', 'absint');
$form_id = FrmAppHelper::get_post_param( 'form_id', '', 'absint' );
$hide_field = '';
$field = FrmField::getOne($field_id);
$field = FrmFieldsHelper::setup_edit_vars($field);
if ( $field['form_id'] != $form_id ) {
$field['parent_form_id'] = $form_id;
}
if ( ! isset( $field['hide_field_cond'][ $meta_name ] ) ) {
$field['hide_field_cond'][ $meta_name ] = '==';
}
$form_fields = self::get_live_fields( $form_id );
include(FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/_logic_row.php');
wp_die();
}
/**
* Merge fields from DB with live field list.
*
* @since 4.0
*/
private static function get_live_fields( $form_id ) {
$form_fields = FrmField::get_all_for_form( $form_id );
$field_names = FrmAppHelper::get_param( 'fields', '', 'post', 'sanitize_text_field' );
if ( empty( $field_names ) ) {
return $form_fields;
}
$fields = array();
foreach ( $field_names as $field ) {
if ( ! empty( $field->type ) ) {
$fields[ $field['fieldId'] ] = $field;
}
}
foreach ( $form_fields as $k => $form_field ) {
if ( ! isset( $fields[ $form_field->id ] ) ) {
continue;
}
$form_fields[ $k ]->type = $fields[ $form_field->id ]['fieldType'];
$form_fields[ $k ]->name = $fields[ $form_field->id ]['fieldName'];
}
return $form_fields;
}
public static function create_multiple_fields( $new_field, $form_id ) {
// $args = compact('field_data', 'form_id', 'field');
if ( empty($new_field) || $new_field['type'] != 'divider' ) {
return;
}
// Add an "End section" when a section field is created
FrmFieldsController::include_new_field('end_divider', $form_id);
}
/**
* Set the form id for the repeating section and any fields inside it
*
* @since 2.0
* @deprecated 3.06.01
*/
public static function toggle_repeat() {
_deprecated_function( __METHOD__, '3.06.01' );
wp_die();
}
/**
* Update a field after dragging and dropping it on the form builder page
*
* @since 2.0.24
*/
public static function update_field_after_move() {
FrmAppHelper::permission_check( 'frm_edit_forms' );
check_ajax_referer( 'frm_ajax', 'nonce' );
$field_id = FrmAppHelper::get_post_param( 'field', 0, 'absint' );
$form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
$section_id = FrmAppHelper::get_post_param( 'section_id', 0, 'absint' );
if ( ! $field_id ) {
wp_die();
}
$update_values = array();
$field_options = FrmDb::get_var( 'frm_fields', array( 'id' => $field_id ), 'field_options' );
FrmProAppHelper::unserialize_or_decode( $field_options );
// Update the in_section value
if ( ! isset( $field_options['in_section'] ) || $field_options['in_section'] != $section_id ) {
$field_options['in_section'] = $section_id;
$update_values['field_options'] = $field_options;
self::maybe_place_field_before_end_divider( $field_id );
}
// Update the form_id value
if ( $form_id ) {
$update_values['form_id'] = $form_id;
}
FrmField::update( $field_id, $update_values );
wp_die();
}
/**
* Make sure that when a new field is dragged into a repeater that it is at least before the end_divider so that it doesn't end up appearing outside of the repeater.
*
* @param int $field_id
*/
private static function maybe_place_field_before_end_divider( $field_id ) {
$row = FrmDb::get_row( 'frm_fields', array( 'id' => $field_id ), 'field_order, form_id' );
if ( ! $row ) {
return;
}
$field_order = $row->field_order;
$form_id = $row->form_id;
$field_order_before = $field_order - 1;
$where_end_divider = array(
'field_order' => $field_order_before,
'type' => 'end_divider',
'form_id' => $form_id,
);
$end_divider_field_id = FrmDb::get_var( 'frm_fields', $where_end_divider );
if ( ! $end_divider_field_id ) {
return;
}
FrmField::update( $field_id, array( 'field_order' => $field_order_before ) );
FrmField::update( $end_divider_field_id, array( 'field_order' => $field_order ) );
}
public static function duplicate_section( $section_field, $form_id ) {
FrmAppHelper::permission_check('frm_edit_forms');
check_ajax_referer( 'frm_ajax', 'nonce' );
global $wpdb, $frm_duplicate_ids;
if ( isset( $_POST['children'] ) ) {
$children = array_filter( (array) $_POST['children'], 'is_numeric');
$fields = FrmField::getAll( array( 'fi.id' => $children ), 'field_order');
} else {
$fields = array();
}
array_unshift( $fields, $section_field );
$order_query = array( 'field_order >' => $section_field->field_order, 'form_id' => $form_id, 'type' => 'end_divider' );
$end_section_order = FrmDb::get_var( 'frm_fields', $order_query, 'field_order', array( 'order_by' => 'field_order ASC' ) );
$field_order = max( $section_field->field_order, $end_section_order );
$ended = false;
if ( isset($section_field->field_options['repeat']) && $section_field->field_options['repeat'] ) {
// create the repeatable form
$new_form_id = FrmProField::create_repeat_form( 0, array( 'parent_form_id' => $form_id, 'field_name' => $section_field->name ) );
} else {
$new_form_id = $form_id;
}
foreach ( $fields as $field ) {
// keep the current form id or give it the id of the newly created form
$this_form_id = $field->form_id == $form_id ? $form_id : $new_form_id;
$values = array();
FrmFieldsHelper::fill_field( $values, $field, $this_form_id );
if ( FrmField::is_repeating_field( $field ) ) {
$values['field_options']['form_select'] = $new_form_id;
}
$values['field_order'] = $field_order;
$field_order++;
$values = apply_filters( 'frm_duplicated_field', $values );
$field_id = FrmField::create( $values );
$copy_field = $field;
do_action( 'frm_after_duplicate_field', compact( 'field_id', 'values', 'copy_field', 'form_id' ) );
if ( ! $field_id ) {
continue;
}
$frm_duplicate_ids[ $field->id ] = $field_id;
$frm_duplicate_ids[ $field->field_key ] = $field_id;
if ( 'end_divider' == $field->type ) {
$ended = true;
}
$values['id'] = $this_form_id;
FrmFieldsController::load_single_field($field_id, $values);
}
if ( ! $ended ) {
//make sure the section is ended
self::create_multiple_fields( (array) $section_field, $form_id );
}
// Prevent the function in the free version from completing
wp_die();
}
/**
*
* Update the repeating form name when a repeating section name is updated
*
* @since 3.0.03
*
* @param array $values
* @return array $values
*/
public static function update_repeater_form_name( $values ) {
if ( isset( $values['field_options']['repeat'] ) && $values['field_options']['repeat'] ) {
FrmForm::update( $values['field_options']['form_select'], array( 'name' => $values['name'] ) );
}
return $values;
}
/**
*
* Update the repeating form name when a repeating section name is updated
*
* @since 2.0.12
* @deprecated 2.04
* @codeCoverageIgnore
*
* @param array $atts
*/
public static function update_repeating_form_name( $atts ) {
_deprecated_function( __FUNCTION__, '3.0.03', 'FrmProFieldsController::update_repeater_form_name' );
$field = FrmField::getOne( $atts['id'] );
if ( FrmField::is_repeating_field( $field ) ) {
FrmForm::update( $field->field_options['form_select'], array( 'name' => $atts['value'] ) );
}
}
/**
* Setup each field's array when an entry is being edited
* Similar to FrmAppHelper::fill_field_defaults
*
* @since 2.01.0
*
* @param object $entry
* @param array $fields
* @param array $args (always contains 'parent_form_id')
* If field is repeating, $args includes 'repeating', 'parent_field_id' and 'key_pointer'
* If field is embedded, $args includes 'in_embed_form'
* @return array
*/
public static function setup_field_data_for_editing_entry( $entry, $fields, $args ) {
$new_fields = array();
foreach ( $fields as $field ) {
$default_value = apply_filters('frm_get_default_value', $field->default_value, $field, true );
$field_value = self::get_posted_or_saved_value( $entry, $field, $args );
$field_array = array(
'id' => $field->id,
'value' => $field_value,
'default_value' => $default_value,
'name' => $field->name,
'description' => $field->description,
'type' => apply_filters('frm_field_type', $field->type, $field, $field_value),
'options' => $field->options,
'required' => $field->required,
'field_key' => $field->field_key,
'field_order' => $field->field_order,
'form_id' => $field->form_id,
'parent_form_id' => $args['parent_form_id'],
'in_embed_form' => isset( $args['in_embed_form'] ) ? $args['in_embed_form'] : '0',
);
FrmFieldsHelper::prepare_edit_front_field( $field_array, $field, $entry->id, $args );
if ( ! isset( $field_array['unique'] ) || ! $field_array['unique'] ) {
$field_array['unique_msg'] = '';
}
$field_array = array_merge( $field->field_options, $field_array );
$values['fields'][ $field->id ] = $field_array;
$new_fields[ $field->id ] = $field_array;
}
return $new_fields;
}
/**
* If the field has a posted value, get it. Otherwise, get the saved field value
*
* @since 2.01.0
* @param object $entry
* @param object $field
* @param array $args (if repeating, this includes 'repeating', 'parent_field_id', and 'key_pointer')
* @return string|array $field_value
*/
private static function get_posted_or_saved_value( $entry, $field, $args ) {
if ( isset( $args['save_draft_click'] ) && $args['save_draft_click'] && FrmField::is_repeating_field( $field ) ) {
// If save draft was just clicked, and this is a repeating section, get the saved value
$field_value = self::get_saved_value( $entry, $field );
} else if ( FrmEntriesHelper::value_is_posted( $field, $args ) ) {
$field_value = '';
FrmEntriesHelper::get_posted_value( $field, $field_value, $args );
} else {
$field_value = self::get_saved_value( $entry, $field );
}
return $field_value;
}
/**
* Get the saved value for a field
*
* @since 2.02.05
* @param object $entry
* @param object $field
* @return array|bool|mixed|string
*/
private static function get_saved_value( $entry, $field ) {
$pass_args = array(
'links' => false,
'truncate' => false,
);
return FrmProEntryMetaHelper::get_post_or_meta_value( $entry, $field, $pass_args );
}
/**
* Product Bulk Edit
*
* @since 4.04
*/
public static function bulk_edit_products() {
FrmAppHelper::permission_check( 'frm_edit_forms' );
check_ajax_referer( 'frm_ajax', 'nonce' );
$field_id = FrmAppHelper::get_param( 'field_id', '', 'post', 'absint' );
$field = FrmField::getOne( $field_id );
if ( ! $field || 'product' !== $field->type ) {
wp_die();
}
$field = FrmFieldsHelper::setup_edit_vars( $field );
$separate = FrmAppHelper::get_param( 'separate', '', 'post', 'sanitize_text_field' );
$field['separate_value'] = ( $separate === 'true' );
$field['options'] = self::product_strings_to_array();
FrmProFieldProduct::single_option( $field );
wp_die();
}
/**
* When bulk editing, convert | to array.
*
* @since 4.04
*/
private static function product_strings_to_array() {
$opts = FrmAppHelper::get_param( 'opts', '', 'post', 'wp_kses_post' );
$opts = explode( "\n", rtrim( $opts, "\n" ) );
$opts = array_map( 'trim', $opts );
foreach ( $opts as $opt_key => $opt ) {
if ( empty( $opt ) ) {
unset( $opts[ $opt_key ] );
continue;
}
if ( strpos( $opt, '|' ) === false ) {
continue;
}
$vals = explode( '|', $opt );
$count = count( $vals );
$label = isset( $vals[0] ) ? trim( $vals[0] ) : '';
// only product name is available
$opts[ $opt_key ] = array(
'label' => $label,
'value' => $label,
'price' => '',
);
if ( 2 === $count ) {
// product name & price
$opts[ $opt_key ]['price'] = trim( $vals[1] );
} elseif ( 3 === $count ) {
// product name, separate value & price
$opts[ $opt_key ]['value'] = trim( $vals[1] );
$opts[ $opt_key ]['price'] = trim( $vals[2] );
}
unset( $vals, $opt_key, $opt );
}
// just to renumber indices from 0.
return array_values( $opts );
}
/*
* Autocomplete users admin ajax endpoint
*
* @since 4.03.06
*/
public static function user_search() {
FrmAppHelper::permission_check( 'frm_edit_entries' );
check_ajax_referer( 'frm_ajax', 'nonce' );
global $wpdb;
$term = FrmAppHelper::get_param( 'term', '', 'get', 'sanitize_text_field' );
if ( empty( $term ) ) {
$args = array( 'limit' => 20, 'order_by' => 'display_name' );
$items = FrmDb::get_results( $wpdb->users, array(), 'ID, display_name', $args );
} else {
$items = $wpdb->get_results(
$wpdb->prepare(
"SELECT ID, display_name FROM {$wpdb->users}
WHERE ID = %d OR user_email LIKE %s OR user_login LIKE %s OR display_name LIKE %s LIMIT 25",
absint( $term ),
'%' . $wpdb->esc_like( $term ) . '%',
'%' . $wpdb->esc_like( $term ) . '%',
'%' . $wpdb->esc_like( $term ) . '%'
)
);
}
$results = array();
foreach ( $items as $item ) {
$results[] = array(
'value' => $item->ID,
'label' => $item->display_name,
);
}
wp_send_json( $results );
}
/**
* Changes options of Display format setting of Radio field.
*
* @since 5.0
*
* @param array $options The options.
* @return array
*/
public static function change_radio_display_format_options( $options ) {
if ( isset( $options['1']['addon'] ) ) {
unset( $options['1']['addon'] );
}
return $options;
}
/**
* Changes arguments of Display format setting of Radio field.
*
* @since 5.0
*
* @param array $args The arguments.
* @param array $method_args The arguments from the method. Contains `field`, `options`.
* @return array
*/
public static function change_radio_display_format_args( $args, array $method_args ) {
$field = $method_args['field'];
$args['selected'] = ! empty( $field['image_options'] ) ? '1' : '0';
return $args;
}
/**
* Prevent field creation when license is expired.
*
* @since 5.4.2
*
* @param string $field_type
* @return void
*/
public static function before_create_field( $field_type ) {
if ( ! FrmProAddonsController::is_expired_outside_grace_period() ) {
return;
}
$pro_fields = FrmField::pro_field_selection();
$field_type_is_allowed = ! array_key_exists( $field_type, $pro_fields );
if ( ! $field_type_is_allowed ) {
// Die early instead of adding a pro field for an expired license.
wp_die( -1 );
}
}
/**
* @deprecated 4.0
*/
public static function populate_calc_dropdown() {
_deprecated_function( __METHOD__, '4.0', 'javascript' );
check_ajax_referer( 'frm_ajax', 'nonce' );
FrmAppHelper::permission_check('frm_edit_forms');
if ( isset( $_POST['form_id'] ) && isset( $_POST['field_id'] ) ) {
echo FrmProFieldsHelper::get_shortcode_select( sanitize_text_field( $_POST['form_id'] ), 'frm_calc_' . sanitize_text_field( $_POST['field_id'] ), 'calc' );
}
wp_die();
}
/**
* @deprecated 4.0
*/
public static function options_form( $field, $display, $values ) {
_deprecated_function( __METHOD__, '4.0' );
}
/**
* Display the Dynamic Values section
*
* @since 2.02.06
* @deprecated 4.0
*
* @param array $field
* @param array $display
*/
public static function show_dynamic_values_options( $field, $display ) {
_deprecated_function( __METHOD__, '4.0', __CLASS__ . '::more_default_values' );
}
/**
* @deprecated 4.0
*/
public static function add_separate_value_opt_label( $field ) {
_deprecated_function( __METHOD__, '4.0' );
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function show_normal_field( $show ) {
_deprecated_function( __METHOD__, '3.0' );
return $show;
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function &normal_field_html( $show ) {
_deprecated_function( __METHOD__, '3.0' );
return $show;
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function show_other() {
_deprecated_function( __METHOD__, '3.0' );
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function show( $field, $name = '' ) {
_deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType::show_on_form_builder' );
}
/**
* Display the format option
*
* @since 2.02.06
* @param array $field
*
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function show_format_option( $field ) {
_deprecated_function( __FUNCTION__, '3.0', 'FrmFieldsController::show_format_option' );
FrmFieldsController::show_format_option( $field );
}
/**
* @deprecated 2.05
*/
public static function &label_position( $position ) {
_deprecated_function( __METHOD__, '2.05', 'FrmFieldsHelper::label_position' );
return $position;
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function display_field_options( $display ) {
_deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType Modals' );
return $display;
}
/**
* @deprecated 3.0
* @codeCoverageIgnore
*/
public static function form_fields( $field, $field_name, $atts ) {
_deprecated_function( __FUNCTION__, '3.0', 'FrmFieldType Modals' );
}
/**
* @deprecated 2.03.10
* @codeCoverageIgnore
*/
public static function prepare_single_field_for_duplication( $field_values ) {
_deprecated_function( __FUNCTION__, '2.03.10', 'custom code' );
return $field_values;
}
}