function wpv_filter_post_custom_field($query, $view_settings)
{
    global $WP_Views, $no_parameter_found;
    $meta_keys = $WP_Views->get_meta_keys();
    foreach (array_keys($view_settings) as $key) {
        if (strpos($key, 'custom-field-') === 0 && strpos($key, '_compare') === strlen($key) - strlen('_compare')) {
            $name = substr($key, 0, strlen($key) - strlen('_compare'));
            $name = substr($name, strlen('custom-field-'));
            $meta_name = $name;
            if (!in_array($meta_name, $meta_keys)) {
                $meta_name = str_replace('_', ' ', $meta_name);
            }
            $value = $view_settings['custom-field-' . $name . '_value'];
            $value = wpv_apply_user_functions($value);
            if ($value != $no_parameter_found) {
                // Only add if we have found a parameter
                $compare_mode = $view_settings['custom-field-' . $name . '_compare'];
                if ($compare_mode == 'BETWEEN' || $compare_mode == 'NOT BETWEEN') {
                    // we need to make sure we have values for min and max.
                    $values = explode(',', $value);
                    if (count($values) == 0) {
                        continue;
                    }
                    if (count($values) == 1) {
                        if ($values[0] == $no_parameter_found) {
                            // nothing to compare to so ignore
                            continue;
                        }
                        // assume this is the smaller value
                        if ($compare_mode == 'BETWEEN') {
                            $compare_mode = '>=';
                        } else {
                            $compare_mode = '<=';
                        }
                        $value = $values[0];
                    } else {
                        if ($values[0] == $no_parameter_found && $values[1] == $no_parameter_found) {
                            // nothing to compare so ignore
                            continue;
                        }
                        if ($values[0] == $no_parameter_found) {
                            // minimum value is missing so use less than compare.
                            if ($compare_mode == 'BETWEEN') {
                                $compare_mode = '<=';
                            } else {
                                $compare_mode = '>=';
                            }
                            $value = $values[1];
                        } elseif ($values[1] == $no_parameter_found) {
                            // maximum value is missing so use greater than compare.
                            if ($compare_mode == 'BETWEEN') {
                                $compare_mode = '>=';
                            } else {
                                $compare_mode = '<=';
                            }
                            $value = $values[0];
                        }
                    }
                }
                $value = str_replace($no_parameter_found, '', $value);
                // just in case we have more than on parameter
                if (!isset($query['meta_query']) && isset($view_settings['custom_fields_relationship'])) {
                    $query['meta_query'] = array('relation' => $view_settings['custom_fields_relationship']);
                }
                $query['meta_query'][] = array('key' => $meta_name, 'value' => $value, 'type' => $view_settings['custom-field-' . $name . '_type'], 'compare' => $compare_mode);
            }
        }
    }
    return $query;
}
/**
* get_users_query
*
* Performs the WP_User_Query when a View lists users
*
* @param $view_settings the View settings
*
* @return $items an array of User objects
*
* @note username_exists() does its own sanitization and data validation in WP_User::get_data_by()
*
* @since 1.4.0
*/
function get_users_query($view_settings)
{
    global $WP_Views, $current_user, $wplogger, $no_parameter_found, $WPVDebug, $wpdb;
    $view_id = $WP_Views->get_current_view();
    $items = array();
    $args = array();
    $include = array();
    $exclude = array();
    $WPVDebug->add_log('info', apply_filters('wpv-view-get-content-summary', '', $WP_Views->current_view, $view_settings), 'short_query');
    if (isset($view_settings['roles_type'][0])) {
        $args['role'] = $view_settings['roles_type'][0];
    }
    if (isset($view_settings['users-show-current']) && $view_settings['users-show-current'] == 1) {
        $exclude[] = $current_user->ID;
    }
    if (isset($view_settings['users_orderby'])) {
        $args['orderby'] = $view_settings['users_orderby'];
    }
    if (isset($view_settings['users_order'])) {
        $args['order'] = $view_settings['users_order'];
    }
    // Users orderby and order based on URL params - for table sorting
    if (isset($_GET['wpv_column_sort_id']) && esc_attr($_GET['wpv_column_sort_id']) != '' && esc_attr($_GET['wpv_view_count']) == $WP_Views->get_view_count()) {
        $field = esc_attr($_GET['wpv_column_sort_id']);
        if (in_array($field, array('user_email', 'user_login', 'display_name', 'user_url', 'user_registered'))) {
            $args['orderby'] = $field;
            if (isset($_GET['wpv_column_sort_dir']) && esc_attr($_GET['wpv_column_sort_dir']) != '') {
                $args['order'] = strtoupper(esc_attr($_GET['wpv_column_sort_dir']));
            }
        }
    }
    //Limit & Offset
    if ($view_settings['users_limit'] !== '-1' && $view_settings['users_limit'] !== -1) {
        $args['number'] = $view_settings['users_limit'];
    }
    $args['offset'] = $view_settings['users_offset'];
    if ($args['offset'] > 0) {
        if (!isset($args['number']) || isset($args['number']) && $args['number'] < 1) {
            $args['number'] = 2147483647;
        }
    }
    // Users filter
    if (isset($view_settings['users_mode']) && !empty($view_settings['users_mode'][0])) {
        //Include/Exclude list of users
        if ($view_settings['users_mode'][0] == 'this_user') {
            if ($view_settings['users_query_in'] == 'exclude') {
                if (!empty($view_settings['users_id'])) {
                    $user_list = array_map('trim', explode(',', $view_settings['users_id']));
                    $exclude = array_merge($exclude, $user_list);
                }
            }
            if ($view_settings['users_query_in'] == 'include') {
                if (!empty($view_settings['users_id'])) {
                    $user_list = array_map('trim', explode(',', $view_settings['users_id']));
                    $args['include'] = $user_list;
                }
            }
        }
        //Show user by url
        if ($view_settings['users_mode'][0] == 'by_url') {
            $user_list = array();
            $user_url = isset($view_settings['users_url']) ? $view_settings['users_url'] : '';
            if ('' != $user_url && isset($_GET[$user_url])) {
                if (is_array($_GET[$user_url])) {
                    if ($view_settings['users_url_type'] == 'id') {
                        foreach ($_GET[$user_url] as $user_candidate) {
                            if (is_numeric($user_candidate)) {
                                $user_list[] = $user_candidate;
                            }
                        }
                    } else {
                        foreach ($_GET[$user_url] as $user_candidate) {
                            $user_candidate_id = username_exists($user_candidate);
                            if (!is_null($user_candidate_id) && is_numeric($user_candidate_id)) {
                                $user_list[] = $user_candidate_id;
                            }
                        }
                    }
                } else {
                    if ($view_settings['users_url_type'] == 'id') {
                        if (is_numeric($_GET[$user_url])) {
                            $user_list = array($_GET[$user_url]);
                        }
                    } else {
                        $user_candidate_id = username_exists($_GET[$user_url]);
                        if (!is_null($user_candidate_id) && is_numeric($user_candidate_id)) {
                            $user_list[] = $user_candidate_id;
                        }
                    }
                }
                if ($view_settings['users_query_in'] == 'exclude') {
                    $exclude = array_merge($exclude, $user_list);
                } else {
                    if (empty($user_list)) {
                        $user_list = array('0');
                    }
                    $args['include'] = $user_list;
                }
            }
        }
        //Show user by shortcode
        if ($view_settings['users_mode'][0] == 'shortcode') {
            $users_shortcode = '';
            $users_shortcode_type = '';
            if (isset($view_settings['users_shortcode']) && '' != $view_settings['users_shortcode']) {
                $users_shortcode = $view_settings['users_shortcode'];
            }
            if (isset($view_settings['users_shortcode_type']) && '' != $view_settings['users_shortcode_type']) {
                $users_shortcode_type = $view_settings['users_shortcode_type'];
            }
            if ('' != $users_shortcode && '' != $users_shortcode_type) {
                $view_attrs = $WP_Views->get_view_shortcodes_attributes();
                $user_list = array();
                if (isset($view_attrs[$users_shortcode])) {
                    $users = $view_attrs[$users_shortcode];
                    $users = array_map('trim', explode(',', $users));
                    switch ($users_shortcode_type) {
                        case 'id':
                            foreach ($users as $user_candidate) {
                                if (is_numeric($user_candidate)) {
                                    $user_list[] = $user_candidate;
                                }
                            }
                            break;
                        default:
                            foreach ($users as $user_candidate) {
                                $user_id_candidate = username_exists($user_candidate);
                                if (!is_null($user_id_candidate) && is_numeric($user_id_candidate)) {
                                    $user_list[] = $user_id_candidate;
                                }
                            }
                            break;
                    }
                    if ($view_settings['users_query_in'] == 'exclude') {
                        $exclude = array_merge($exclude, $user_list);
                    } else {
                        if (empty($user_list)) {
                            $user_list = array('0');
                        }
                        $args['include'] = $user_list;
                    }
                }
            }
        }
    }
    // End users filter
    //Usermeta filter
    $total_meta = 0;
    foreach ($view_settings as $index => $value) {
        if (preg_match("/usermeta-field-(.*)_type/", $index, $match)) {
            $field = $match[1];
            $type = $value;
            $compare = $view_settings['usermeta-field-' . $field . '_compare'];
            $value = $view_settings['usermeta-field-' . $field . '_value'];
            $value = wpv_apply_user_functions($value);
            if ($value != $no_parameter_found) {
                if ($field == 'user_email' || $field == 'user_login' || $field == 'user_url' || $field == 'display_name') {
                    $args['search'] = '' . $value . '';
                    // remove * wildcards
                    $args['search_columns'] = array($field);
                } else {
                    $total_meta++;
                    $args['meta_query'][] = array('key' => $field, 'value' => $value, 'compare' => $compare, 'type' => $type);
                }
            }
        }
    }
    if ($total_meta > 1) {
        $args['meta_query']['relation'] = $view_settings['usermeta_fields_relationship'];
    }
    if (!empty($exclude)) {
        $args['exclude'] = $exclude;
    }
    $wplogger->log($args, WPLOG_DEBUG);
    $WPVDebug->add_log('info', "Basic query arguments\n" . print_r($args, true), 'query_args');
    /**
     * Filter wpv_filter_user_query
     *
     * This is where all the filters coming from the View settings to modify the query are (or should be) hooked
     *
     * @param $args the relevant elements of the View settings in an array to be used as arguments in a WP_User_Query() call
     * @param $view_settings the View settings
     * @param $view_id the ID of the View being displayed
     *
     * @return $args
     *
     * @since 1.4.0
     */
    $args = apply_filters('wpv_filter_user_query', $args, $view_settings, $view_id);
    // $args['fields'] = 'all_with_meta';
    $WPVDebug->add_log('filters', "wpv_filter_user_query\n" . print_r($args, true), 'filters', 'Filter arguments before the query using <strong>wpv_filter_user_query</strong>');
    $user_query = new WP_User_Query($args);
    if (!empty($wpdb->queries)) {
        $WPVDebug->add_log('mysql_query', $wpdb->queries, 'users');
    }
    $WPVDebug->add_log('info', print_r($user_query, true), 'query_results', '', true);
    if (!empty($user_query->results)) {
        $items = $user_query->results;
    }
    /**
     * Filter wpv_filter_user_post_query
     *
     * Filter applied to the results of the WP_User_Query() call
     *
     * @param $items array of terms returned by the WP_User_Query() call
     * @param $args the relevant elements of the View settings in an array to be used as arguments in a WP_User_Query() call
     * @param $view_settings the View settings
     * @param $view_id the ID of the View being displayed
     *
     * @return $items
     *
     * @since 1.4.0
     */
    $items = apply_filters('wpv_filter_user_post_query', $items, $args, $view_settings, $view_id);
    $WPVDebug->add_log('filters', "wpv_filter_user_post_query\n" . print_r($items, true), 'filters', 'Filter the returned query using <strong>wpv_filter_user_post_query</strong>');
    return $items;
}
/**
 * 
 * Views-Shortcode: wpv-control
 *
 * Description: Add filters for View
 *
 * Parameters:
 * type: Type of retrieved field layout 'radio', 'checkbox', 'select', 'multi-select', 'textfield', 'checkboxes', 'datepicker'
 * url_param: The URL parameter passed as an argument
 * values: Optional, a list of supplied values
 * display_values: Optional, a list of values to display for the corresponding values
 * auto_fill: Optional, when set to a "field-slug" the control will be populated with custom field values from the database.
 * auto_fill_default: Optional, use to set the default, unselected, value of the control. eg Ignore or Don't care
 * auto_fill_sort: Optional. 'asc', 'desc', 'ascnum', 'descnum', 'none'. Defaults to ascending.
 * field: Optional, a custom field to retrieve values from
 * title: Optional, use for the checkbox title
 * taxonomy: Optional, use when a taxonomy control should be displayed.
 * taxonomy_orderby. Optional. 'name', 'id', 'count', 'slug', 'term_group', 'none'. Defaults to 'name'
 * taxonomy_order: Optional 'ASC', 'DESC'. Defaults to ascending.
 * default_label: Optional, use when a taxonomy control should be displayed using select input type.
 * date_format: Optional, use for a datepicker control
 *
 * Example usage:
 *
 * Link:
 * More details about this shortcode here: <a href="http://wp-types.com/documentation/wpv-control-fields-in-front-end-filters/?utm_source=viewsplugin&utm_campaign=views&utm_medium=filter-help-link&utm_term=http://wp-types.com/documentation/wpv-control-fields-in-front-end-filters/" title="wpv-control – Displaying fields in front-end filters">http://wp-types.com/documentation/wpv-control-fields-in-front-end-filters/</a>
 *
 * Note:
 *
 */
function wpv_shortcode_wpv_control($atts) {
	
	// First control checks
	if ( !isset( $atts['url_param'] ) ) {
		return __('The url_param is missing from the wpv-control shortcode argument.', 'wpv-views');
	}
	if ( ( !isset( $atts['type'] ) || $atts == '' ) && !isset( $atts['field'] ) ) {
		return __('The "type" or "field" needs to be set in the wpv-control shortcode argument.', 'wpv-views');
	}
	
	//Start the shortcode management
	global $WP_Views, $no_parameter_found;
	$aux_array = $WP_Views->view_used_ids;
	$view_name = get_post_field( 'post_name', end( $aux_array ) );
	
	extract(
		shortcode_atts(array(
				'type' => '', // select, multi-select, checbox, checkboxes, radio/radios, date/datepicker, textfield
				'values' => array(), // (optional) comma-separated list of user-provided values
                'display_values' => array(), // (optional) comma-separated list of user-provided display values
				'field' => '', // name of the custom field
				'url_param' => '', // URL parameter to be used
                'title' => '', // title to be used on a checkbox field type
                'taxonomy' => '', // name of the taxonomy for taxonomies filter controls
                'taxonomy_orderby' => 'name', // order of the terms for taxonomies filter controls
                'taxonomy_order' => 'ASC', // orderby of the terms for taxonomies filter controls
                'format' => false, // format of the display value, use %%NAME%% or %%COUNT%% as placeholders
                'default_label' => '', // default label for taxonomies filter controls when using select input type
                'hide_empty' => 'false', // option to hide empty terms for taxonomies filter controls
                'auto_fill' => '', // options to auto fill values for custom fields filter controls - provide the field name
                'auto_fill_default' => '', // default value when using auto_fill for custom fields filter controls
                'auto_fill_sort' => '', // order when using auto_fill for custom fields filter controls
                'date_format' => '', // date format for date controls
				'default_date' => '',  // default date for date controls
				'force_zero' => 'false',
                'style' => '', // inline styles for input
                'class' => '', // input classes
                'label_style' => '', // inline styles for input label
                'label_class' => '' // classes for input label
			), $atts)
	);
	
    $style = esc_attr( $style );
    $class = esc_attr( $class );
    $label_style = esc_attr( $label_style );
    $label_class = esc_attr( $label_class );  
    
	// First, parametric search control for taxonomy
	if ( $taxonomy != '' ) {
		// Translate the default label if any
		if ( !empty( $default_label ) ) {
			$default_label = wpv_translate( $url_param . '_default_label', $default_label, false, 'View ' . $view_name );
			$atts['default_label'] = $default_label;
		}
		// Render the taxonomy control
		return wpv_render_taxonomy_control( $atts );
    }
	
	// Before doing anything else, rule out textfields
	if ( $type == 'textfield' ) {
		// Textfield field
		$default_value = '';
		if ( isset( $_GET[ $url_param ] ) ) {
			$default_value = stripslashes( urldecode( sanitize_text_field( $_GET[ $url_param ] ) ) );
		}
		
		// Render the form content
		$element = wpv_form_control( array(
				'field' => array(
						'#type' => 'textfield',
						'#id' => 'wpv_control_textfield_' . $url_param,
						'#name' => $url_param,
						'#attributes' => array( 'style' => $style, 'class' => 'js-wpv-filter-trigger-delayed ' . $class  ),
						'#inline' => true,
						'#value' => $default_value ) ) );
		return $element;
	}
    
	// Check if the View has dependency enabled
    $view_settings = $WP_Views->get_view_settings();
	$dependant = false;
	$counters = ( $format && strpos( $format, '%%COUNT%%' ) !== false ) ? true : false;
	$empty_action = array();
	if ( isset( $view_settings['dps'] )
		&& is_array( $view_settings['dps'] )
		&& isset( $view_settings['dps']['enable_dependency'] )
		&& $view_settings['dps']['enable_dependency'] == 'enable' )
	{
		$dependant = true;
		$force_disable_dependant = $WP_Views->get_force_disable_dependant_parametric_search();
		if ( $force_disable_dependant ) {
			$dependant = false;
		}
	}
	
	// Some basic values
	if ( empty( $field ) ) {
		if ( empty( $auto_fill ) ) {
			// In this case, the shortcode is not about a custom field filter but a generic one without taxonomy, field or auto_fill attributes
			// It can be used to generate custom form inputs, given that the user provides values (and maybe display_values)
			// So we need to disable dependency
			$dependant = false;
			$counters = false;
		} else {
			$field_real_name = _wpv_get_field_real_slug( $auto_fill );
		}
	} else {
		$field_real_name = _wpv_get_field_real_slug( $field );
	}
	
	$display_values_trans = false; // flag to whether the display_values need to be translated
	$out = '';
	
	// If dependency is ON, build the basic data and cache
	if ( $dependant || $counters ) {
		$empty_default = 'hide';
		$empty_alt = 'disable';
		$empty_options = array( 'select', 'radios', 'checkboxes' ); // multi-select is a special case because of dashes and underscores
		foreach ( $empty_options as $empty_opt ) {
			if ( isset( $view_settings['dps'][ 'empty_' . $empty_opt ] )
				&& $view_settings['dps'][ 'empty_' . $empty_opt ] == $empty_alt )
			{
				$empty_action[ $empty_opt ] = $empty_alt;
			} else {
				$empty_action[ $empty_opt ] = $empty_default;
			}
		}
		if ( isset( $view_settings['dps']['empty_multi_select'] )
			&& $view_settings['dps']['empty_multi_select'] == $empty_alt )
		{
			$empty_action['multi-select'] = $empty_alt;
		} else {
			$empty_action['multi-select'] = $empty_default;
		}
		$wpv_data_cache = array();
		$original_value = $view_settings[ 'custom-field-' . $field_real_name . '_value' ];
		$processed_value = wpv_apply_user_functions( $original_value );
		$compare_function = $view_settings[ 'custom-field-' . $field_real_name . '_compare' ];
		$current_value_key = false;
		// @todo check IN, NOT IN and != compare functions
		$comparator = 'equal';
		$filter_full_list = false;
		if ( $compare_function == 'BETWEEN' ) {
			$original_value_array = array_map( 'trim', explode( ',', $original_value ) );
			$processed_value_array = array_map( 'trim', explode( ',', $processed_value ) );
			$current_value_key = array_search( 'URL_PARAM(' . $url_param . ')', $original_value_array );
			if ( $current_value_key !== false ) {
				$processed_value = isset( $processed_value_array[ $current_value_key ] ) ? $processed_value_array[ $current_value_key ] : $no_parameter_found;
				if ( $current_value_key < 1 ) {
					$comparator = 'lower-equal-than';
				} else if ( $current_value_key > 0 ) {
					$comparator = 'greater-equal-than';
				}
			}
		} else if ( $compare_function == '>' ) {
			$comparator = 'lower-than';
		} else if ( $compare_function == '>=' ) {
			$comparator = 'lower-equal-than';
		} else if ( $compare_function == '<' ) {
			$comparator = 'greater-than';
		} else if ( $compare_function == '<=' ) {
			$comparator = 'greater-equal-than';
		}
		// Construct $wpv_data_cache['post_meta']
		if ( $processed_value == $no_parameter_found ) {
			global $wp_object_cache;
			$wpv_data_cache = isset( $wp_object_cache->cache ) ? $wp_object_cache->cache : array();
			$aux_query_count = null;
		} else {
			// When there is a selected value, create a pseudo-cache based on all the other filters
			// Note that checkboxes filters can generate nested meta_query entries
			$query = wpv_get_dependant_view_query_args();
			$aux_cache_query = null;
			$filter_full_list = true;
			if ( isset( $query['meta_query'] ) && is_array( $query['meta_query'] ) ) {
				foreach ( $query['meta_query'] as $qt_index => $qt_val ) {
					if ( is_array( $qt_val ) ) {
						foreach ( $qt_val as $qt_val_key => $qt_val_val ) {
							if ( 
								$qt_val_key == 'key' 
								&& $qt_val_val == $field_real_name
							) {
								if ( $compare_function == 'BETWEEN' ) {
									if ( 
										$qt_val['compare'] == 'BETWEEN' 
										&& $current_value_key !== false 
									) {
										$qt_val['value'] = isset( $qt_val['value'] ) ? $qt_val['value'] : '';
										$passed_values = is_array( $qt_val['value'] ) ? $qt_val['value'] : array_map( 'trim', explode( ',', $qt_val['value'] ) );
										if ( $current_value_key < 1 && isset( $passed_values[1] ) ) {
											$query['meta_query'][ $qt_index ]['compare'] = '<=';
											$query['meta_query'][ $qt_index ]['value']= $passed_values[1];
										} else if ( $current_value_key > 0 && isset( $passed_values[0] ) ) {
											$query['meta_query'][ $qt_index ]['compare'] = '>=';
											$query['meta_query'][ $qt_index ]['value']= $passed_values[0];
										}
									} else {
										unset( $query['meta_query'][ $qt_index ] );
									}
									// if $compare_function is BETWEEN and we have a meta_query not using BETWEEN, we have a partial query here, so keep it
								} else {
									unset( $query['meta_query'][$qt_index] );
								}
							} else if ( 
								is_array( $qt_val_val ) 
								&& isset( $qt_val_val['key'] ) 
								&& $qt_val_val['key'] == $field_real_name
							) {
								if ( $compare_function == 'BETWEEN' ) {
									if ( 
										$qt_val_val['compare'] == 'BETWEEN' 
										&& $current_value_key !== false 
									) {
										$qt_val_val['value'] = isset( $qt_val_val['value'] ) ? $qt_val_val['value'] : '';
										$passed_values = is_array( $qt_val_val['value'] ) ? $qt_val_val['value'] : array_map( 'trim', explode( ',', $qt_val_val['value'] ) );
										if ( $current_value_key < 1 && isset( $passed_values[1] ) ) {
											$query['meta_query'][ $qt_index ][ $qt_val_key ]['compare'] = '<=';
											$query['meta_query'][ $qt_index ][ $qt_val_key ]['value']= $passed_values[1];
										} else if ( $current_value_key > 0 && isset( $passed_values[0] ) ) {
											$query['meta_query'][ $qt_index ][ $qt_val_key ]['compare'] = '>=';
											$query['meta_query'][ $qt_index ][ $qt_val_key ]['value']= $passed_values[0];
										}
									} else {
										unset( $query['meta_query'][ $qt_index ][ $qt_val_key ] );
									}
									// if $compare_function is BETWEEN and we have a meta_query not using BETWEEN, we have a partial query here, so keep it
								} else {
									unset( $query['meta_query'][$qt_index][ $qt_val_key ] );
								}
							}
						}
					}
				}
			}
			$aux_cache_query = new WP_Query($query);
			if ( is_array( $aux_cache_query->posts ) && !empty( $aux_cache_query->posts ) ) {
				$aux_query_count = count( $aux_cache_query->posts );
				$f_fields = array( $field_real_name );
				$wpv_data_cache = wpv_custom_cache_metadata( $aux_cache_query->posts, array( 'cf' => $f_fields ) );
			}
		}
		if ( !isset( $wpv_data_cache['post_meta'] ) ) {
			$wpv_data_cache['post_meta'] = array();
		}
		
		// OK, for checkboxes custom fields the stored value is NOT the one we use for filtering
		// So instead of filtering $wpv_data_cache['post_meta'] we will loop it to see if the $field_real_name key exists
		// AND check the serialized value to see if it contains the given real value (warning, not the label!)
		// AND break as soon as true because we need no counters
		// Expensive, but not sure if more than wp_list_filter though
	}
	
	// Management of multiselect
	$multi = '';
	if ( $type == 'multi-select') {
		$type = 'select';
		$multi = 'multiple';
	}
	
	//  $filter_check_type = _wpv_is_field_of_type( $auto_fill, 'checkboxes' ) ? 'checkboxes' : 'other';
	$filter_check_type = wpv_types_get_field_type( $field );
	
	if ( $auto_fill != '' ) {
		/**
		* If using auto_fill, populate the values and display_values arrays
		*/
        
        /**
        * First we are going to populate those variables
        */
        $fields = array(); // this will hold the Types fields from the Options
        $db_values = array(); // this will hold the field values from Types options or from the database
        $display_text = array(); // this will hold the field values pretty display text, if it is a Types field with options
        $auto_fill_default_trans = false; // flag to whether the auto_fill_default has translated, based on whether it is one of the existing values
        
        if ( !function_exists( 'wpcf_admin_fields_get_fields' ) ) {
			if( defined( 'WPCF_EMBEDDED_ABSPATH' ) ) {
				include WPCF_EMBEDDED_ABSPATH . '/includes/fields.php';
			}
		}
		if ( function_exists( 'wpcf_admin_fields_get_fields' ) ) {
			$fields = wpcf_admin_fields_get_fields();
		}
		// $field_name = substr($auto_fill, 5); // TODO DONE check this for fields created outside of Types and brought under Types control
		if ( strpos( $auto_fill, 'wpcf-' ) === 0 ) {
			$field_name = substr( $auto_fill, 5 );
        } else {
			$field_name = $auto_fill;
        }

        // If it is a Types field with options
        if ( isset( $fields[ $field_name ] ) && isset( $fields[ $field_name ]['data']['options'] ) ) { 
			// If it is a checkboxes Types field
			if ( _wpv_is_field_of_type( $auto_fill, 'checkboxes' ) ) { 
				$options = $fields[ $field_name ]['data']['options'];
				foreach( $options as $field_key => $option ) {
					// Fill the db_values and display_text (translated if needed) arrays
					$db_values[] = $option['title'];
					$display_text[ $option['title'] ] = wpv_translate( 'field '. $fields[ $field_name ]['id'] .' option '. $field_key .' title', $option['title'], false, 'plugin Types' );
				}
			} else {
				// If it is a Types field different from checkboxes but with options
				$options = $fields[ $field_name ]['data']['options'];
				if ( isset( $options['default'] ) ) {
					// remove the default option from the array
					unset( $options['default'] );
				}
				if ( isset( $fields[ $field_name ]['data']['display'] ) ) {
					$display_option =  $fields[ $field_name ]['data']['display'];
				}
				foreach ( $options as $field_key => $option ) {
					if ( isset( $option['value'] ) ) {
						$db_values[] = $option['value'];
					}
					if ( isset( $display_option )
						&& 'value' == $display_option
						&& isset( $option['display_value'] ) )
					{
						$display_text[ $option['value'] ] = wpv_translate( 'field '. $fields[ $field_name ]['id'] .' option '. $field_key .' title', $option['display_value'], false, 'plugin Types' );
					} else {
						$display_text[ $option['value'] ] = wpv_translate( 'field '. $fields[ $field_name ]['id'] .' option '. $field_key .' title', $option['title'], false, 'plugin Types' );
					}
					if ( $auto_fill_default != '' ) {
						// translate the auto_fill_default option if needed, just when it's one of the existing options
						$auto_fill_default = str_replace( '\,', ',', $auto_fill_default );
						if ( $auto_fill_default == $option['title'] ) {
							$auto_fill_default = wpv_translate( 'field '. $fields[ $field_name ]['id'] .' option '. $field_key .' title', $option['title'], false, 'plugin Types' );
							// set this flat to true: we already have translated auto_fill_default
							$auto_fill_default_trans = true; 
						}
						$auto_fill_default = str_replace( ',', '\,', $auto_fill_default );
					}
				}
			}

			// Now sort the values based on auto_fill_sort
			switch ( strtolower( $auto_fill_sort ) ) {
				case 'desc':
					sort( $db_values );
					$db_values = array_reverse( $db_values );
					break;
				case 'descnum':
					sort( $db_values, SORT_NUMERIC );
					$db_values = array_reverse( $db_values );
					break;
				case 'none':
					break;
				case 'ascnum':
					sort( $db_values, SORT_NUMERIC );
					break;
				default:
					sort( $db_values );
					break;
			}
			
        } else {
			// If it is not a Types field OR is a Types field without options

			global $wpdb;
			$values_to_prepare = array();
			$values_to_prepare[] = $auto_fill;
			$wpdb_where = '';
			if ( isset( $view_settings['post_type'] )
				&& is_array( $view_settings['post_type'] )
				&& ! empty( $view_settings['post_type'] )
				&& ! in_array( 'any', $view_settings['post_type'] ) 
			) {
				$post_type_count = count( $view_settings['post_type'] );
				$post_type_placeholders = array_fill( 0, $post_type_count, '%s' );
				$wpdb_where .= " AND p.post_type IN (" . implode( ",", $post_type_placeholders ) . ") ";
				foreach ( $view_settings['post_type'] as $pt ) {
					$values_to_prepare[] = $pt;
				}
			}
			if ( 
				isset( $view_settings['post_status'] ) 
				&& is_array( $view_settings['post_status'] ) 
				&& ! empty( $view_settings['post_status'] )
			) {
				if ( ! in_array( 'any', $view_settings['post_status'] ) ) {
					$post_status_count = count( $view_settings['post_status'] );
					$post_status_placeholders = array_fill( 0, $post_status_count, '%s' );
					$wpdb_where .= " AND p.post_status IN (" . implode( ",", $post_status_placeholders ) . ") ";
					foreach ( $view_settings['post_status'] as $ps ) {
						$values_to_prepare[] = $ps;
					}
				}
			} else {
				$status = array( 'publish' );
				if ( current_user_can( 'read_private_posts' ) ) {
					$status[] = 'private';
				}
				$wpdb_where .= " AND p.post_status IN ( '" . implode( "','", $status ) . "' ) ";
			}
			$wpdb_orderby = '';
			switch ( strtolower( $auto_fill_sort ) ) {
				case 'desc':
					$wpdb_orderby = "ORDER BY pm.meta_value DESC";
					break;
				case 'descnum':
					$wpdb_orderby = "ORDER BY pm.meta_value + 0 DESC";
					break;
				case 'ascnum':
					$wpdb_orderby = "ORDER BY pm.meta_value + 0 ASC";
					break;
				default:
					$wpdb_orderby = "ORDER BY pm.meta_value ASC";
					break;
			}
			$db_values = $wpdb->get_col( 
				$wpdb->prepare(
					"SELECT DISTINCT pm.meta_value FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id 
					WHERE pm.meta_key = %s AND pm.meta_value IS NOT NULL AND pm.meta_value != '' 
					{$wpdb_where} 
					{$wpdb_orderby}",
					$values_to_prepare 
				) 
			);
        }
        
        /**
        * Now we are going to fill the $values and $display_values comma-separated strings based on $db_values and, in case, $display_text
        * NOTE if $auto_fill_default_trans is FALSE then the auto_fill_default is NOT one of the existing option titles so we will translate it
        */
        if ( $auto_fill_default != '' ) {
			// If auto_fill_default is not empty, adjust and translate when needed
			if ( !$auto_fill_default_trans ) {
				// translate the auto_fill_default option when it's not one of the existing options
				$auto_fill_default = str_replace( '\,', ',', $auto_fill_default );
				$auto_fill_default = wpv_translate( $url_param . '_auto_fill_default', stripslashes( $auto_fill_default ), false, 'View ' . $view_name );
				$auto_fill_default = str_replace( ',', '\,', $auto_fill_default );
			}
            $values = '';
            $display_values = str_replace( '\,', '%comma%', $auto_fill_default );
            // flag to whether there is an auto_fill_default value that we ad at the beginning of the $display_value string
            $first = false; 
        } else {
            $values = '';
            $display_values = '';
            $first = true;
        }
        foreach( $db_values as $value ) {
            if ( $value !== false ) {
                if ( !$first ) {
                    $values .= ',';
                    $display_values .= ',';
                }
                // HACK to handle commas in values
                $values .= str_replace( ',', '%comma%', $value ); 
                if ( isset( $display_text[$value] ) ) {
					// HACK to handle commas in display_values
					$display_values .= str_replace( ',', '%comma%', $display_text[ $value ] ); 
				} else {
					// HACK to handle commas in display_values
					$display_values .= str_replace( ',', '%comma%', $value ); 
				}
                $first = false;
            }
        }
    // If not using auto_fill, check if there are manually added display_values
    } else if ( !empty( $display_values ) ) { 
		// mark that the display_values need to be translated
		$display_values_trans = true; 
    }
    
	/*
	* Now we have a comma-separated list of $values and $display_values, hopefully ;-D
	* In fact, we count with a $values comma-separated list
	* We will fill the $values_arr array and transform $display_values into an array
	*/
	
	if( !empty( $values ) ) {
		// When values attributes are manually defined, the inner commas are formatted as \, and we need to apply the same HACK as for the automatically set values
		$values_fix = str_replace( '\,', '%comma%', $values );
		// Now, get the $values_arr array of values
		$values_arr = explode( ',', $values_fix );
		// And undo the comma HACK
		$values_arr = str_replace( '%comma%', ',', $values_arr );
        if ( !empty( $display_values ) ) {
			// If there are display_values,again sync the comma HACK
			$display_values = str_replace( '\,', '%comma%', $display_values );
			// Get an array of $display_values
			$display_values = explode( ',', $display_values );
			// And undo the comma HACK
			$display_values = str_replace( '%comma%', ',', $display_values );
			if ( $display_values_trans ) {
				// If we need to translate the $display_values
				$translated_values = array();
				foreach ( $display_values as $index => $valuetrans ) {
					$translated_values[ $index ] = wpv_translate( $url_param . '_display_values_' . ( $index + 1 ), stripslashes( $valuetrans ), false, 'View ' . $view_name );
				}
				$display_values = $translated_values;
			}
        }

		// Parse date expressions in values.
		$values_count = count( $values_arr );
		for( $i = 0; $i < $values_count; ++$i ) {
			$values_arr[ $i ] = wpv_filter_parse_date( $values_arr[ $i ] );
		}
        
		/**
		* Now that we have the $values_arr and $display_values we focus on the kind of output
		* Based on $type we will popuate an $options variable and use the wpv_form_control() function
		*/
		
        if( !in_array( $type, array( 'radio', 'radios', 'select', 'checkboxes' ) ) ) {
            // For wpv-control shortcodes using auto_fill or values/display_values we only allow those kind of types
            $type = 'select';
        }
        if ( $type == 'radio' ) {
            // In fact, radios == radio
            $type = 'radios';
        }
        $options = array();
		// Now, depending on $type
        switch ( $type ) {
        
            case 'checkboxes':
                // If we need to render CHECKBOXES
                $defaults = array();
                $original_get = null;
                if ( isset( $auto_fill_default ) ) {
					// First, check if the defaul value already exists and set the appropriate arrays and values
					$num_auto_fill_default_display = array_count_values( $display_values );
					$auto_fill_default_trans = str_replace( '\,', ',', $auto_fill_default );
					if (
							// if the auto_fill_default is one of the display_values
							( isset( $num_auto_fill_default_display[ $auto_fill_default_trans ] )
							&& $num_auto_fill_default_display[ $auto_fill_default_trans ] > 1 )  
						||
							// OR if the auto_fill_default is one of the values
							in_array( $auto_fill_default_trans, $values_arr ) ) 
					{ 
						// Take out the first element of the $values_arr and the $display_values, which holds and empty string and the auto_fill_default value
						$values_arr_def = array_shift( $values_arr );
						$display_values_def = array_shift( $display_values );
					}
					// Then, set the preliminary $defaults value based on auto_fill_default
					$defaults = str_replace( '\,', '%comma%', $auto_fill_default );
					$defaults = explode( ',', $defaults );
					$defaults = str_replace( '%comma%', ',', $defaults );
					$defaults = array_map( 'trim', $defaults );
                }
                if ( isset( $_GET[ $url_param ] ) ) {
                    // Override $defaults if a set of values is coming from the URL parameter
                    $original_get = $_GET[ $url_param ];
                    $defaults = $_GET[ $url_param ];
                    if ( is_string( $defaults ) ) {
						$defaults = explode( ',',$defaults );
					}
                    unset( $_GET[ $url_param ] );
                }
                $count_values_array = count( $values_arr );
                for( $i = 0; $i < $count_values_array; $i++ ) {
                    // Loop through the $values_arr
                    $value = $values_arr[ $i ];
                    $value = trim( $value );
                    // Check for a display value
                    if ( isset( $display_values[ $i ] ) ) {
                        $display_value = $display_values[ $i ];
                    } else {
                        $display_value = $value;
                    }
                    // Compose the $options for this value
                    $options[ $value ]['#name'] = $url_param . '[]';
                    $options[ $value ]['#title'] = $display_value;
                    $options[ $value ]['#value'] = $value;
                    // set default using option titles too
                    $options[ $value ]['#default_value'] = in_array( $value, $defaults ) || in_array( $options[ $value ]['#title'], $defaults); 
                    $options[ $value ]['#attributes']['class'] = 'js-wpv-filter-trigger ' . $class;
                    $options[ $value ]['#attributes']['style'] = $style;
                    $options[ $value ]['#labelclass'] = $label_class;
                    $options[ $value ]['#labelstyle'] = $label_style;
                    // Dependant stuff
                    if ( $dependant || $counters ) {
						if ( $format ) {
							$display_value_formatted_name = str_replace( '%%NAME%%', $options[ $value ]['#title'], $format );
							$options[ $value ]['#title'] = $display_value_formatted_name;
						}
						$meta_criteria_to_filter = array( $field_real_name => array( $value ) );
						$this_query = $WP_Views->get_query();
						if ( empty( $value ) && !is_numeric( $value ) && is_object( $this_query ) ) {
							if ( isset( $aux_query_count ) ) {
								$this_checker = $aux_query_count;
							} else {
								$this_checker = $this_query->found_posts;
							}
						} else {
							$data = array();
							$data['list'] = $wpv_data_cache['post_meta'];
							$data['args'] = $meta_criteria_to_filter;
							$data['kind'] = $filter_check_type;
							$data['comparator'] = $comparator;
							if ( $counters ) {
								$data['count_matches'] = true;
							}
							$data['filter_full_list'] = $filter_full_list;
							$this_checker = wpv_list_filter_checker( $data );
						}
						if ( $counters ) {
							$display_value_formatted_name = str_replace( '%%COUNT%%', $this_checker, $options[ $value ]['#title'] );
							$options[ $value ]['#title'] = $display_value_formatted_name;                            
						}
						if ( !$this_checker && ( !empty( $value ) || is_numeric( $value ) ) && !$options[ $value ]['#default_value'] && $dependant ) {
							$options[ $value ]['#attributes']['#disabled'] = 'true';
							$options[ $value ]['#labelclass'] .= ' wpv-parametric-disabled ';
							if ( isset( $empty_action['checkboxes'] ) && $empty_action['checkboxes'] == 'hide' ) {
								unset( $options[ $value ] );
							}
						}
					}
//                    $options[$value]['#inline'] = true;
//                    $options[$value]['#after'] = '&nbsp;&nbsp;';
                }
                // Render the form control element
               	$element = wpv_form_control( array(
						'field' => array(
				                '#type' => $type,
				                '#id' => 'wpv_control_' . $type . '_' . $url_param,
				                '#name' => $url_param . '[]',
				                '#attributes' => array( 'style' => '' ),
				                '#inline' => true,
				                '#options' => $options,
								'#before' => '<div class="wpcf-checkboxes-grou">', //we need to wrap them for js purposes
								'#after' => '</div>' ) ) );
                
                if ( $original_get ) {
                    $_GET[ $url_param ] = $original_get;
                }
                break;
                
            default:
                // If we need to check any other field with values and a type that is not checkboxes (radios or select)
                $options_array = array();

                // This one will hold options in a display_vaue => value format so we can use it to compose the default_value later
                $options = array(); 

                $count_values_array = count( $values_arr );
                for( $i = 0; $i < $count_values_array; $i++ ) {
                    // Loop through the $values_arr
                    $value = $values_arr[ $i ];
                    $value = trim( $value );
                    // Check for a display value
                    if ( isset( $display_values[ $i ] ) ) {
                        $display_value = $display_values[ $i ];
                    } else {
                        $display_value = $value;
                    }
                    // Compose the $options for this value
                    $options[ $display_value ] = $value;
                    $options_array[ $display_value ] = array(
							'#title' => $display_value,
							'#value' => $value,
							'#inline' => true,
							'#after' => '<br />' );
                    $options_array[ $display_value ]['#attributes']['class'] = 'js-wpv-filter-trigger';
                    
                    if ( $type == 'radios' ) {
                        $options_array[ $display_value ]['#attributes']['class'] .= ' ' . $class;
                        $options_array[ $display_value ]['#attributes']['style'] = $style;
                        $options_array[ $display_value ]['#labelclass'] = $label_class;
                        $options_array[ $display_value ]['#labelstyle'] = $label_style;
                    }
                    // Dependant stuff
					if ( $dependant || $counters ) {
						if ( $format ) {
							$display_value_formatted_name = str_replace( '%%NAME%%', $options_array[ $display_value ]['#title'], $format );
							$options_array[ $display_value ]['#title'] = $display_value_formatted_name;
						}
						$this_query = $WP_Views->get_query();
						if ( empty( $value ) && !is_numeric( $value ) && is_object( $this_query ) ) {
							if ( isset( $aux_query_count ) ) {
								$this_checker = $aux_query_count;
							} else {
								$this_checker = $this_query->found_posts;
							}
						} else {
							$meta_criteria_to_filter = array( $field_real_name => array( $value ) );
							$data = array();
							$data['list'] = $wpv_data_cache['post_meta'];
							$data['args'] = $meta_criteria_to_filter;
							$data['kind'] = $filter_check_type;
							$data['comparator'] = $comparator;
							if ( $counters ) {
								$data['count_matches'] = true;
							}
							$data['filter_full_list'] = $filter_full_list;
							$this_checker = wpv_list_filter_checker( $data );
						}
						if ( $counters ) {
							$display_value_formatted_counter = str_replace( '%%COUNT%%', $this_checker, $options_array[ $display_value ]['#title'] );
							$options_array[ $display_value ]['#title'] = $display_value_formatted_counter;
						}
						
						if ( !$this_checker && ( !empty( $value ) || is_numeric( $value ) ) && $dependant ) {
							// TODO DONE need to merge this with the default_value below, to avoid hiddin or disabling selected items
							$options_array[ $display_value ]['#disable'] = 'true';
							$options_array[ $display_value ]['#labelclass'] = 'wpv-parametric-disabled';
							if ( $type == 'select' && $multi == 'multiple' ) {
								if ( isset( $empty_action['multi-select'] ) && $empty_action['multi-select'] == 'hide' ) {
									unset( $options_array[ $display_value ] );
								}
							} else if ( isset( $empty_action[ $type ] ) && $empty_action[ $type ] == 'hide' ) {
								unset( $options_array[ $display_value ] );
							}
						}
					}
                }
                
                if ( count( $values_arr ) != count( $options ) ) {
					// if the $values_arr has one more item than $options, there is a repeating value: the default one added to the beginning
					$default_value = reset( $options );
				} else {
					if ( 
						$type == 'radios' 
						|| $multi == 'multiple'
					) {
						$default_value = '';
					} else {
						// so the default value in this case is the first element in $values_arr
						$default_value = isset( $values_arr[0] ) ? $values_arr[0] : '';
					}
				}
				if ( $type == 'radios' ) {
					if ( isset( $_GET[ $url_param ] ) && in_array( $_GET[ $url_param ], $options ) ) {
						$default_value = $_GET[ $url_param ];
					}
					$name_aux = $url_param;
				} else {
					// Basically, if $type == 'select'
					if ( isset( $_GET[ $url_param ] ) ) {
						if ( is_array( $_GET[ $url_param ] ) ) {
							if ( count( array_intersect($_GET[ $url_param ], $options) ) > 0 ) {
								$default_value = $_GET[ $url_param ];
							}
						} else {
							if ( in_array( $_GET[ $url_param ], $options ) ) {
								$default_value = $_GET[ $url_param ];
							}
						}
					}
					$name_aux = $url_param . '[]';
				}

				// Now we need to recreate the $options_array element if it is a default one and is disabled or removed
				if ( is_array( $default_value ) ) {
					foreach ( $default_value as $dv ) {
						$aux_display_values = array_keys( $options, $dv, true );
						foreach ( $aux_display_values as $aux_dv ) {
							// TODO where is $aux_dv defined??
							if ( isset( $options_array[ $aux_dv ] ) ) {
								if ( isset( $options_array[ $aux_dv ]['#disable'] ) ) {
									unset( $options_array[ $aux_dv ]['#disable'] );
								}
								$options_array[ $aux_dv ]['#labelclass'] = '';
							} else {
								$options_array[ $aux_dv ] = array(
										'#title' => $aux_dv,
										'#value' => $dv,
										'#inline' => true,
										'#after' => '<br />' );
								$options_array[ $aux_dv ]['#attributes']['class'] = 'js-wpv-filter-trigger ';
							}
						}
					}
				} else {
					$aux_display_values = array_keys( $options, $default_value, true );
					foreach ( $aux_display_values as $aux_dv ) {
						if ( isset( $options_array[ $aux_dv ] ) ) {
							if ( isset( $options_array[$aux_dv]['#disable'] ) ) {
								unset( $options_array[$aux_dv]['#disable'] );
							}
							$options_array[ $aux_dv ]['#labelclass'] = '';
						} else {
							$options_array[ $aux_dv ] = array(
									'#title' => $aux_dv,
									'#value' => $default_value,
									'#inline' => true,
									'#after' => '<br />' );
							$options_array[ $aux_dv ]['#attributes']['class'] = 'js-wpv-filter-trigger';
						}
					}
				}
				
				$element = wpv_form_control( array(
						'field' => array(
								'#type' => $type,
								'#id' => 'wpv_control_' . $type . '_' . $url_param,
								'#name' => $name_aux,
								'#attributes' => array('style' => $style, 'class' => 'js-wpv-filter-trigger' . $class ),
								'#inline' => true,
								'#options' => $options_array, // NOTE this was originally $options but as it's not an array I can not set a "disabled" option
								'#default_value' => $default_value,
								'#multiple' => $multi // NOTE I'd say that radios do not need multiple but it should do no harm
								) )	);
				break;
        }
		return $element;
		
	} else if ( !empty( $field ) ) {
		/**
		* When field attribute is defined but we do not have auto_fill nor manually entered values
		* In this case, we display the control input based on $type or the field type itself if needed (mainly for Types auto style, but we can expect other combinations)
		*/

		// Check if Types is active because we are using wpcf_admin_fields_get_field()
		if ( !function_exists( 'wpcf_admin_fields_get_field' ) ) {
			if ( defined( 'WPCF_EMBEDDED_ABSPATH' ) ) {
				include WPCF_EMBEDDED_ABSPATH . '/includes/fields.php';
			} else {
				return __( 'Types plugin is required.', 'wpv-views' );
			}
		}
		if ( !function_exists( 'wpv_form_control' ) ) {
			include '../common/functions.php';
		}
		//This is important cause wpcf_admin_fields_get_field works with id: $field - 'wpcf-' and search with 'wpcf-'.$field
		/*if( strpos($field, 'wpcf-') !== false ) {
			$tmp = explode('wpcf-', $field);
			$field = $tmp[1];
		}*/
		// Get field options and translate name if needed
		$field_options = wpcf_admin_fields_get_field( $field );
		if ( empty( $field_options ) ) {
			return __( 'Empty field values or incorrect field defined. ', 'wpv-views' );
		}
        $field_options['name'] = wpv_translate( 'field ' . $field_options['id'] . ' name', $field_options['name'], false, 'plugin Types' );
		// Get field type, override if $type exists and default it to textfield if needed
		$field_type = $field_options['type'];
		if ( !empty( $type ) ) {
			// Watch out: this is where we can override the field type itself
			$field_type = $type;
		}
        if ( !in_array( $field_type, array( 'radio', 'checkbox', 'checkboxes', 'select', 'textfield', 'date', 'datepicker' ) ) ) {
            $field_type = 'textfield';
        }
		// Display time!!
		if ( $field_type == 'radio' ) {
			// Radio field
			$field_radio_options = isset( $field_options['data']['options'] ) ? $field_options['data']['options'] : array();
			$options = array();
			foreach ( $field_radio_options as $key => $opts ) {
				if ( is_array( $opts ) ) {
					
					if ( isset( $field_options['data']['display'] )
						&& 'value' == $field_options['data']['display']
						&& isset( $opts['display_value'] ) )
					{
						// if we have an actual display value and is set to be used, use it
						$display_value = $opts['display_value'];
						$value = $opts['value'];
					} else {
						// else, use the field value title and watch out because checkboxes fields need their titles as values
						$display_value = wpv_translate( 'field '. $field_options['id'] .' option '. $key .' title', $opts['title'], false, 'plugin Types' );
						if ( _wpv_is_field_of_type( 'wpcf-' . $field, 'checkboxes' ) ) {
							$value = $opts['title'];
						} else {
							$value = $opts['value'];
						}
					}
					$options[ $display_value ] = array(
						'#title' => $display_value,
						'#value' => $value,
						'#inline' => true,
						'#after' => '<br />'
                    );
                    $options[ $display_value ]['#attributes']['class'] = 'js-wpv-filter-trigger ' . $class;
                    $options[ $display_value ]['#attributes']['style'] = $style;
					// Dependant stuff
					if ( $dependant || $counters ) {
						if ( $format ) {
							$display_value_formatted_name = str_replace( '%%NAME%%', $options[ $display_value ]['#title'], $format );
							$options[ $display_value ]['#title'] = $display_value_formatted_name;
						}
						$this_query = $WP_Views->get_query();
						if ( empty( $value ) && !is_numeric( $value ) && is_object( $this_query ) ) {
							if ( isset( $aux_query_count ) ) {
								$this_checker = $aux_query_count;
							} else {
								$this_checker = $this_query->found_posts;
							}
						} else {
							$meta_criteria_to_filter = array( $field_real_name => array( $value ) );
							$data = array();
							$data['list'] = $wpv_data_cache['post_meta'];
							$data['args'] = $meta_criteria_to_filter;
							$data['kind'] = $filter_check_type;
							$data['comparator'] = $comparator;
							if ( $counters ) {
								$data['count_matches'] = true;
							}
							$data['filter_full_list'] = $filter_full_list;
							$this_checker = wpv_list_filter_checker( $data );
						}
						if ( $counters ) {
							$display_value_formatted_counter = str_replace( '%%COUNT%%', $this_checker, $options[ $display_value ]['#title'] );
							$options[ $display_value ]['#title'] = $display_value_formatted_counter;
						}
						if ( !$this_checker
							&& ( !empty( $value ) || is_numeric( $value ) )
							&& ( !isset( $_GET[$url_param] ) || $_GET[$url_param] !== $value )
							&& $dependant )
						{
							$options[ $display_value ]['#disable'] = 'true';
							$options[ $display_value ]['#labelclass'] = 'wpv-parametric-disabled';
							if ( isset( $empty_action['radios'] ) && $empty_action['radios'] == 'hide' ) {
								unset( $options[ $display_value ] );
							}
						}
					}
				}
			}
			// Render the form content
			$element = wpv_form_control( array(
					'field' => array(
							'#type' => 'radios',
							'#id' => 'wpv_control_radio_' . $field,
							'#name' => $url_param,
							'#attributes' => array( 'style' => $style, 'class' => $class ),
							'#inline' => true,
							'#options' => $options,
							'#default_value' => isset( $_GET[ $url_param ] ) ? $_GET[ $url_param ] : '' ) ) );
							
            return $element;
		} else if ( $field_type == 'checkbox' ) {
            // Checkbox field
            // Populate the $checkbox_name with the wpv-control title attribute OR the field name itself
            if ( isset( $atts['title'] ) ) {
                $checkbox_name =  wpv_translate( $url_param . '_title', $title, false, 'View ' . $view_name );
            } else {
				// NOTE mmmmmm we seem to have translated this $field_options['name'] right above...
                $checkbox_name = wpv_translate( 'field ' . $field_options['name'] . ' name', $field_options['name'], false, 'plugin Types' );
            }
            
            $value = $field_options['data']['set_value'];
            $coming_value = '';
			if ( isset( $_GET[ $url_param ] ) && !empty( $_GET[ $url_param ] ) ) {
				$value = esc_attr( $_GET[ $url_param ] );
				$coming_value = esc_attr( $_GET[ $url_param ] );
			} else if ( isset( $_GET[ $url_param ] ) && is_numeric( $_GET[ $url_param ] ) ) {
				// this only happens when the value to store when checked is actually zero - nonsense
				$value = 0;
				$coming_value = 0;
			} else if ( empty( $_GET[ $url_param ] ) ) {
				unset( $_GET[ $url_param ] );
			}
			$attributes = array( 'style' => '', 'class' => 'js-wpv-filter-trigger' );
            $labelclass = '';
            $show_checkbox = true;
            // Dependant stuff
			if ( $dependant || $counters ) {
				if ( $format ) {
					$display_value_formatted_name = str_replace( '%%NAME%%', $checkbox_name, $format );
					$checkbox_name = $display_value_formatted_name;
				}
				$meta_criteria_to_filter = array( $field_real_name => array( $value ) );
				$data = array();
				$data['list'] = $wpv_data_cache['post_meta'];
				$data['args'] = $meta_criteria_to_filter;
				$data['kind'] = $filter_check_type;
				$data['comparator'] = $comparator;
				if ( $counters ) {
					$data['count_matches'] = true;
				}
				$data['filter_full_list'] = $filter_full_list;
				$this_checker = wpv_list_filter_checker( $data );
				if ( $counters ) {
					$display_value_formatted_count = str_replace( '%%COUNT%%', $this_checker, $checkbox_name );
					$checkbox_name = $display_value_formatted_count;
				}
				if ( !$this_checker && empty( $coming_value ) && $dependant ) {
					$attributes['#disabled'] = 'true';
					$labelclass = 'wpv-parametric-disabled';
					if ( isset( $empty_action['checkboxes'] ) && $empty_action['checkboxes'] == 'hide' ) {
						$show_checkbox = false;
					}
				}
			}
            if ( $show_checkbox ) {
				// Render the form content
                $attributes['class'] .= ' ' . $class;
                $attributes['style'] = $style;
                
				$element = wpv_form_control( array(
						'field' => array(
								'#type' => 'checkbox',
								'#id' => 'wpv_control_checkbox_' . $field,
								'#name' => $url_param,
								'#attributes' => $attributes,
								'#inline' => true,
								'#title' => $checkbox_name,
								'#labelclass' => $labelclass . ' ' . $label_class,
                                '#labelstyle' => $label_style,
								'#value' => $field_options['data']['set_value'],
								'#default_value' => 0 ) ) );
				if ( isset( $field_options['data']['save_empty'] ) && $field_options['data']['save_empty'] == 'yes' && $force_zero == 'true' ) {
					$attributes['class'] = '';
					$attributes['checked'] = 'checked';
					$element .= wpv_form_control( array(
							'field' => array(
									'#type' => 'hidden',
									'#id' => 'wpv_control_checkbox_' . $field . '_fakezero',
									'#name' => $url_param . '_fakezero',
									'#attributes' => $attributes,
									'#inline' => true,
									'#value' => 'yes',
									'#default_value' => 0 ) ) );
				}
			} else {
				$element = '';
			}
            return $element;
            
		} else if ( $field_type == 'checkboxes' ) {

            // Checkboxes field
            $defaults = array();
            $original_get = null;
            if ( isset( $_GET[ $url_param ] ) ) {
                $original_get = $_GET[ $url_param ];
                $defaults = $_GET[ $url_param ];
                if ( is_string( $defaults ) ) {
					$defaults = explode( ',',$defaults );
				}
                unset( $_GET[ $url_param ] );
            }
            $field_checkboxes_options = isset( $field_options['data']['options'] ) ? $field_options['data']['options'] : array();
            if ( isset( $field_checkboxes_options['default'] ) ) {
				// Remove the default option from the array because it breaks the loop below
				unset( $field_checkboxes_options['default'] );
			}
            foreach( $field_checkboxes_options as $key => $value ) {
                $display_value = wpv_translate( 'field '. $field_options['id'] .' option '. $key .' title', trim( $value['title'] ), false, 'plugin Types' );
                if ( _wpv_is_field_of_type( 'wpcf-' . $field, 'checkboxes' ) ) {
					$value = trim( $value['title'] );
				} else {
					$value = trim( $value['value'] );
                }
                
                $options[ $value ]['#name'] = $url_param . '[]';
                $options[ $value ]['#title'] = $display_value;
                $options[ $value ]['#value'] = $value;
                $options[ $value ]['#default_value'] = in_array( $value, $defaults );
                //$options[$value]['#inline'] = true;
                //$options[$value]['#after'] = '&nbsp;&nbsp;';
                $options[ $value ]['#attributes']['class'] = 'js-wpv-filter-trigger ' . $class;
                $options[ $value ]['#attributes']['style'] = $style;
                $options[ $value ]['#labelclass'] = $label_class;
                $options[ $value ]['#labelstyle'] = $label_style;
                // Dependant stuff
				if ( $dependant || $counters ) {
					if ( $format ) {
						$display_value_formatted_name = str_replace( '%%NAME%%', $options[ $value ]['#title'], $format );
						$options[ $value ]['#title'] = $display_value_formatted_name;
					}
					$meta_criteria_to_filter = array( $field_real_name => array( $value ) ); // TODO DONE IMPORTANT check what is coming here as value, maybe $opts['title'] sometimes
					$this_query = $WP_Views->get_query();
					if ( empty( $value ) && !is_numeric( $value ) && is_object( $this_query ) ) {
						if ( isset( $aux_query_count ) ) {
							$this_checker = $aux_query_count;
						} else {
							$this_checker = $this_query->found_posts;
						}
					} else {
						$data = array();
						$data['list'] = $wpv_data_cache['post_meta'];
						$data['args'] = $meta_criteria_to_filter;
						$data['kind'] = $filter_check_type;
						$data['comparator'] = $comparator;
						if ( $counters ) {
							$data['count_matches'] = true;
						}
						$data['filter_full_list'] = $filter_full_list;
						$this_checker = wpv_list_filter_checker( $data );
					}
					if ( $counters ) {
						$display_value_formatted = str_replace( '%%COUNT%%', $this_checker, $options[ $value ]['#title'] );
						$options[ $value ]['#title'] = $display_value_formatted;
					}
					if ( !$this_checker && ( !empty( $value ) || is_numeric( $value ) ) && !$options[ $value ]['#default_value'] && $dependant ) {
						$options[ $value ]['#attributes']['#disabled'] = 'true';
						$options[ $value ]['#labelclass'] .= ' wpv-parametric-disabled';
						if ( isset( $empty_action['checkboxes'] ) && $empty_action['checkboxes'] == 'hide' ) {
							unset( $options[ $value ] );
						}
					}
				}
            }
            // Render the form content
            $element = wpv_form_control( array(
					'field' => array(
                            '#type' => 'checkboxes',
                            '#id' => 'wpv_control_checkbox_' . $field,
                            '#name' => $url_param . '[]',
                            '#attributes' => array( 'style' => '' ),
                            '#inline' => true,
                            '#options' => $options ) ) );
            if ( $original_get ) {
                $_GET[ $url_param ] = $original_get;
            }
            return $element;
		} else if ( $field_type == 'select' ) {
			// Select field
			$field_select_options = isset( $field_options['data']['options'] ) ? $field_options['data']['options'] : array();;
			$options = array();
			$opt_aux = array();
			foreach ( $field_select_options as $key => $opts ) {
				if ( is_array( $opts ) ) {
					
					$display_value = wpv_translate( 'field '. $field_options['id'] .' option '. $key .' title', $opts['title'], false, 'plugin Types' );
					if ( _wpv_is_field_of_type( 'wpcf-' . $field, 'checkboxes' ) ) {
						$value = $opts['title'];
					} else {
						$value = $opts['value'];
					}
					
					$options[ $display_value ] = array(
						'#title' => $display_value,
						'#value' => $value,
						'#inline' => true,
						'#after' => '<br />'
                    );
                    $opt_aux[ $display_value ] = $value;
					$options[ $display_value ]['#attributes']['class'] = 'js-wpv-filter-trigger';
					// Dependant stuff
					if ( $dependant || $counters ) {
						if ( $format ) {
							$display_value_formatted_name = str_replace( '%%NAME%%', $options[ $display_value ]['#title'], $format );
							$options[ $display_value ]['#title'] = $display_value_formatted_name;
						}
						$this_query = $WP_Views->get_query();
						if ( empty( $value ) && !is_numeric( $value ) && is_object( $this_query ) ) {
							if ( isset( $aux_query_count ) ) {
								$this_checker = $aux_query_count;
							} else {
								$this_checker = $this_query->found_posts;
							}
						} else {
							$meta_criteria_to_filter = array( $field_real_name => array( $value ) );
							$data = array();
							$data['list'] = $wpv_data_cache['post_meta'];
							$data['args'] = $meta_criteria_to_filter;
							$data['kind'] = $filter_check_type;
							$data['comparator'] = $comparator;
							if ( $counters ) {
								$data['count_matches'] = true;
							}
							$data['filter_full_list'] = $filter_full_list;
							$this_checker = wpv_list_filter_checker( $data );
						}
						if ( $counters ) {
							$display_value_formatted_counter = str_replace( '%%COUNT%%', $this_checker, $options[ $display_value ]['#title'] );
							$options[ $display_value ]['#title'] = $display_value_formatted_counter;
						}
						if ( !$this_checker && ( !empty( $value ) || is_numeric( $value ) ) && $dependant ) {
							// TODO DONE we need to adjust this with the $default_value below
							$options[ $display_value ]['#disable'] = 'true';
							$options[ $display_value ]['#labelclass'] = 'wpv-parametric-disabled';
							if ( $multi == 'multiple' ) {
								if ( isset( $empty_action['multi-select'] ) && $empty_action['multi-select'] == 'hide' ) {
									unset( $options[ $display_value ] );
								}
							} else if ( isset( $empty_action['select'] ) && $empty_action['select'] == 'hide' ) {
								unset( $options[ $display_value ] );
							}
						}
					}
				}
			}
			$default_value = false;
			if ( isset( $_GET[ $url_param ] ) ) {
				if ( is_array( $_GET[ $url_param ] ) ) {
					if ( count( array_intersect($_GET[ $url_param ], $opt_aux) ) > 0 ) {
						$default_value = $_GET[ $url_param ];
					}
				} else {
					if ( in_array( $_GET[ $url_param ], $opt_aux ) ) {
						$default_value = $_GET[ $url_param ];
					}
				}
			}
			
			// Now we need to recreate the $options element if it is a default one and is disabled or removed
			if ( $default_value !== false && is_array( $default_value ) ) {
				foreach ( $default_value as $dv ) {
					$aux_display_values = array_keys( $opt_aux, $dv, true );
					foreach ( $aux_display_values as $aux_dv ) {
						if ( isset( $options[ $aux_dv ] ) ) {
							if ( isset( $options[ $aux_dv ]['#disable'] ) ) {
								unset( $options[ $aux_dv ]['#disable'] );
							}
							$options[ $aux_dv ]['#labelclass'] = '';
						} else {
							$options[ $aux_dv ] = array(
								'#title' => $aux_dv,
								'#value' => $dv,
								'#inline' => true,
								'#after' => '<br />'
							);
							$options[ $aux_dv ]['#attributes']['class'] = 'js-wpv-filter-trigger';
						}
					}
				}
			} else if ( $default_value !== false ) {
				$aux_display_values = array_keys( $opt_aux, $default_value, true );
				foreach ( $aux_display_values as $aux_dv ) {
					if ( isset( $options[ $aux_dv ] ) ) {
						if ( isset( $options[ $aux_dv ]['#disable'] ) ) {
							unset( $options[ $aux_dv ]['#disable'] );
						}
						$options[ $aux_dv ]['#labelclass'] = '';
					} else {
						$options[ $aux_dv ] = array(
							'#title' => $aux_dv,
							'#value' => $default_value,
							'#inline' => true,
							'#after' => '<br />'
						);
						$options[ $aux_dv ]['#attributes']['class'] = 'js-wpv-filter-trigger';
					}
				}
			}
			
			
			// Render the form content
			$element = wpv_form_control( array(
					'field' => array(
	                        '#type' => 'select',
	                        '#id' => 'wpv_control_select_' . $url_param,
	                        '#name' => $url_param . '[]',
	                        '#attributes' => array( 'style' => $style, 'class' => $class ),
	                        '#inline' => true,
							'#options' => $options,
							'#default_value' => $default_value,
							'#multiple' => $multi ) ) );
	        return $element;
	        
		} else if ( $field_type == 'textfield' ) {
			// Textfield field
			$default_value = '';
			if ( isset( $_GET[ $url_param ] ) ) {
				$default_value = stripslashes( urldecode( sanitize_text_field( $_GET[ $url_param ] ) ) );
			}
			
			// Render the form content
			$element = wpv_form_control( array(
					'field' => array(
	                        '#type' => 'textfield',
	                        '#id' => 'wpv_control_textfield_' . $url_param,
	                        '#name' => $url_param,
	                        '#attributes' => array( 'style' => $style, 'class' => 'js-wpv-filter-trigger-delayed ' . $class  ),
	                        '#inline' => true,
							'#value' => $default_value ) ) );
	        return $element;
	        
		} else if ( $field_type == 'date' || $field_type == 'datepicker' ) {
			// Date or datepicker field
			$out = wpv_render_datepicker( $url_param, $date_format, $default_date );
            return $out;
        }
        // In case we have a field attribute but it does not match any vaid type, return nothing
		return '';
		
	} else {
        // When there is a type attribute without field or auto_fill or values attributes it's likely for a checkbox or a datepicker
        // But I'm not sure what is this used for, because it really does not filter by any field
        $default_value = '';
        if ( isset( $_GET[ $url_param ] ) ) {
            $default_value = $_GET[ $url_param ];
        }
        switch ( $type ) {
            case 'checkbox':
                // In this case, there is no way to implement dependant parametric search, because we have no field to check against
                $element = array(
						'field' => array(
                                '#type' => $type,
                                '#id' => 'wpv_control_' . $type . '_' . $url_param,
                                '#name' => $url_param,
                                '#attributes' => array( 'style' => $style, 'class' => 'js-wpv-filter-trigger ' . $class ),
                                '#inline' => true,
                                '#value' => $default_value ) );
                $element['field']['#title'] = wpv_translate( $url_param . '_title', $title, false, 'View ' . $view_name );
                $element = wpv_form_control( $element );
                break;
            case 'datepicker':
                $element = wpv_render_datepicker( $url_param, $date_format, $default_date );
                break;
            default:
                $element = array(
						'field' => array(
                                '#type' => $type,
                                '#id' => 'wpv_control_' . $type . '_' . $url_param,
                                '#name' => $url_param,
                                '#attributes' => array( 'style' => $style, 'class' => $class ),
                                '#inline' => true,
                                '#value' => $default_value ) );
                $element = wpv_form_control( $element );
                break;
        }
        return $element;
    }
}
function wpv_filter_post_custom_field($query, $view_settings)
{
    global $WP_Views, $no_parameter_found;
    $meta_keys = array();
    foreach (array_keys($view_settings) as $key) {
        if (strpos($key, 'custom-field-') === 0 && strpos($key, '_compare') === strlen($key) - strlen('_compare')) {
            if (empty($meta_keys)) {
                $meta_keys = $WP_Views->get_meta_keys();
            }
            $name = substr($key, 0, strlen($key) - strlen('_compare'));
            $name = substr($name, strlen('custom-field-'));
            $meta_name = $name;
            if (!in_array($meta_name, $meta_keys)) {
                // this is needed for fields with keys containing spaces - we map those spaces to underscores when creating the filter
                $meta_name = str_replace('_', ' ', $meta_name);
            }
            // TODO add filter here: what happens when a meta_name contains a space AND an underscore?
            $value = $view_settings['custom-field-' . $name . '_value'];
            $view_id = $WP_Views->get_current_view();
            /**
             * Filter wpv_filter_custom_field_filter_original_value
             *
             * @param $value the value coming from the View settings filter after passing through the check for URL params, shortcode attributes and date functions comparison
             * @param $meta_name the key of the custom field being used to filter by
             * @param $view_id the ID of the View being displayed
             *
             * $value comes from the View settings. It's a string containing a single-value or a comma-separated list of single-values if the filter needs more than one value (for IN, NOT IN, BETWEEN and NOT BETWEEN comparisons)
             * Each individual single-value element in the list can use any of the following formats:
             * (string|numeric) if the single-value item is fixed
             * (string) URL_PARAM(parameter) if the filter is done via a URL param "parameter"
             * (string) VIEW_PARAM(parameter) if the fiter is done via a [wpv-view] shortcode attribute "parameter"
             * (string) NOW() | TODAY() | FUTURE_DAY() | PAST_DAY() | THIS_MONTH() | FUTURE_MONTH() | PAST_MONTH() | THIS_YEAR() | FUTURE_YEAR() | PAST_YEAR() | SECONDS_FROM_NOW() | MONTHS_FROM_NOW() | YEARS_FROM_NOW() | DATE()
             *
             * @return $value
             *
             * @since 1.4.0
             */
            $value = apply_filters('wpv_filter_custom_field_filter_original_value', $value, $meta_name, $view_id);
            $value = wpv_apply_user_functions($value);
            /**
             * Filter wpv_filter_custom_field_filter_processed_value
             *
             * @param $value the value coming from the View settings filter after passing through the check for URL params, shortcode attributes and date functions comparison
             * @param $meta_name the key of the custom field being used to filter by
             * @param $view_id the ID of the View being displayed
             *
             * @return $value
             *
             * @since 1.4.0
             */
            $value = apply_filters('wpv_filter_custom_field_filter_processed_value', $value, $meta_name, $view_id);
            if ($value !== $no_parameter_found) {
                // Only add if we have found a parameter
                $compare_mode = $view_settings['custom-field-' . $name . '_compare'];
                if ($compare_mode == 'BETWEEN' || $compare_mode == 'NOT BETWEEN') {
                    // we need to make sure we have values for min and max.
                    $values = explode(',', $value);
                    $values = array_map('trim', $values);
                    if (count($values) == 0) {
                        continue;
                    }
                    if (count($values) == 1) {
                        if ($values[0] == $no_parameter_found) {
                            // nothing to compare to so ignore
                            continue;
                        }
                        // assume this is the smaller value
                        if ($compare_mode == 'BETWEEN') {
                            $compare_mode = '>=';
                        } else {
                            $compare_mode = '<=';
                        }
                        $value = $values[0];
                    } else {
                        if ($values[0] == $no_parameter_found && $values[1] == $no_parameter_found) {
                            // nothing to compare so ignore
                            continue;
                        }
                        if ($values[0] == $no_parameter_found) {
                            // minimum value is missing so use less than compare.
                            if ($compare_mode == 'BETWEEN') {
                                $compare_mode = '<=';
                            } else {
                                $compare_mode = '>=';
                            }
                            $value = $values[1];
                        } elseif ($values[1] == $no_parameter_found) {
                            // maximum value is missing so use greater than compare.
                            if ($compare_mode == 'BETWEEN') {
                                $compare_mode = '>=';
                            } else {
                                $compare_mode = '<=';
                            }
                            $value = $values[0];
                        }
                    }
                }
                $value = str_replace($no_parameter_found, '', $value);
                // just in case we have more than one parameter
                if ($compare_mode == 'IN' || $compare_mode == 'NOT IN') {
                    // WordPress query expects an array in this case
                    $value = explode(',', $value);
                    // make it an array and separate values, for multiple values in shortcode mode
                }
                if (!isset($query['meta_query']) && isset($view_settings['custom_fields_relationship'])) {
                    $query['meta_query'] = array('relation' => $view_settings['custom_fields_relationship']);
                }
                // Sanitize $value so they can contain quotes
                if (is_array($value)) {
                    foreach ($value as $key => $val) {
                        $value[$key] = stripslashes(urldecode(sanitize_text_field(trim($val))));
                    }
                } else {
                    $value = stripslashes(urldecode(sanitize_text_field(trim($value))));
                }
                if (empty($value) && ($compare_mode == '>=' || $compare_mode == '<=' || $compare_mode == '>' || $compare_mode == '<')) {
                    // do nothing as we are comparing greater than / lower than to an empty value
                } else {
                    $query['meta_query'][] = array('key' => $meta_name, 'value' => $value, 'type' => $view_settings['custom-field-' . $name . '_type'], 'compare' => $compare_mode);
                }
            }
        }
    }
    return $query;
}