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'] = ' '; } // 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'] = ' '; $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; }