query->get_default_queries() as $provider => $queries ) { foreach ( $queries as $query_id => $query_args ) { $query_args = jet_smart_filters()->utils->merge_query_args( $query_args, jet_smart_filters()->query->get_query_args() ); $provider_key = $provider . '/' . $query_id; if ( empty( $this->indexing_data[$provider_key] ) ) { continue; } $provider_indexed_data = $this->get_indexed_data( $provider_key, $query_args ); if ( $provider_indexed_data ) { $indexed_data[$provider_key] = $provider_indexed_data; } } } if ( ! empty( $indexed_data ) ) { $args['jetFiltersIndexedData'] = apply_filters( 'jet-smart-filters/filters/indexed-data', $indexed_data ); } do_action( 'jet-smart-filters/indexer/after-prepare-data' ); return $args; } /** * Prepare data for ajax actions */ public function prepare_ajax_data( $args ) { do_action( 'jet-smart-filters/indexer/before-prepare-data' ); $provider_key = isset( $_REQUEST['provider'] ) ? $_REQUEST['provider'] : false; $indexing_filters = isset( $_REQUEST['indexing_filters'] ) ? json_decode( stripcslashes( $_REQUEST['indexing_filters'] ), true ) : false; if ( ! ( $provider_key && $indexing_filters ) ) { return $args; } $indexed_data = array(); foreach ( $indexing_filters as $filter_id ) { $this->add_indexing_data_from_filter( $provider_key, $filter_id ); } if ( ! empty( $this->indexing_data[$provider_key] ) ) { $query_args = jet_smart_filters()->utils->merge_query_args( jet_smart_filters()->query->get_default_queries(), jet_smart_filters()->query->get_query_args() ); //$query_args = jet_smart_filters()->query->get_query_args(); $indexed_data = $this->get_indexed_data( $provider_key, $query_args ); } $args['jetFiltersIndexedData'] = apply_filters( 'jet-smart-filters/filters/indexed-data', array( $provider_key => $indexed_data ) ); do_action( 'jet-smart-filters/indexer/after-prepare-data' ); return $args; } public function get_indexed_data( $provider_key, $query_args ) { $indexed_data = array(); $queried_ids = $this->get_queried_ids( $query_args ); $indexing_data = $this->indexing_data[$provider_key]; $type = ! empty( $query_args['_query_type'] ) && $query_args['_query_type'] === 'users' ? 'user' : 'post'; $sql_and = ''; $pre_get_data = apply_filters( 'jet-smart-filters/pre-get-indexed-data', false, $provider_key, $query_args, $this ); if ( false !== $pre_get_data ) { return $pre_get_data; } foreach ( $indexing_data as $query_type => $query_data ) { switch ( $query_type ) { case 'tax_query': foreach ( $query_data as $tax_key => $tax_data ) { $sql_and .= $sql_and ? ' OR ' : ''; $sql_and .= "(item_query = '$query_type' AND item_key = '$tax_key' AND item_value IN ('" . implode( "','", $tax_data ) . "'))"; } break; case 'meta_query': foreach ( $query_data as $meta_key => $meta_data ) { $sql_and .= $sql_and ? ' OR ' : ''; if ( strpos( $meta_key, '|' ) ) { $suffix_data = explode( '|', $meta_key, 2 ); switch ( $suffix_data[1] ) { case 'range': $range_data = array(); foreach ( $meta_data as $value ) { if ( ! isset( $range_data['min'] ) || $range_data['min'] > $value['min'] ) { $range_data['min'] = $value['min']; } if ( ! isset( $range_data['max'] ) || $range_data['max'] < $value['max'] ) { $range_data['max'] = $value['max']; } } $item_key_condition = strpos( $suffix_data[0], ',' ) ? "item_key IN ('" . str_replace( [",",' '], ["','". ''], $suffix_data[0] ) . "')" : "item_key = '" . $suffix_data[0] . "'"; $sql_and .= "(item_query = '$query_type' AND $item_key_condition AND item_value >= " . $range_data['min'] . " AND item_value <= " . $range_data['max'] . ")"; break; } } else { $item_key_condition = strpos( $meta_key, ',' ) ? "item_key IN ('" . str_replace( [",",' '], ["','". ''], $meta_key ) . "')" : "item_key = '$meta_key'"; if ( $meta_data ) { $sql_and .= "(item_query = '$query_type' AND $item_key_condition AND item_value IN ('" . implode( "','", $meta_data ) . "'))"; } } } break; } } if ( $sql_and ) { $sql_and = "AND ($sql_and)"; } global $wpdb; $sql = " SELECT MAX(item_query) as item_query, MAX(item_key) as item_key, item_value, COUNT(item_id) as count FROM " . jet_smart_filters()->indexer->table_name . " WHERE item_id IN (" . implode( ",", $queried_ids ) . ") AND (type = '$type') $sql_and GROUP BY item_key, item_value ORDER BY item_value ASC"; $result = $wpdb->get_results( $sql, ARRAY_A ); foreach ( $this->indexing_data[$provider_key] as $query_type => $query_type_data ) { $indexed_data[$query_type] = array(); foreach ( $query_type_data as $key => $data ) { if ( strpos( $key, '|' ) ) { $suffix_data = explode( '|', $key, 2 ); switch ( $suffix_data[1] ) { case 'range': foreach ( $data as $range_key => $range_data ) { foreach ( $result as $row ) { $is_current_key = strpos( $suffix_data[0], ',' ) ? boolval( preg_match( "/\b" . $row['item_key'] . "\b/i", $suffix_data[0] ) ) : $row['item_key'] === $suffix_data[0]; if ( ! $is_current_key || $row['item_query'] !== $query_type || $row['item_value'] < $range_data['min'] || $row['item_value'] > $range_data['max'] ) { continue; } if ( ! isset( $indexed_data[$query_type][$suffix_data[0]] ) ) { $indexed_data[$query_type][$suffix_data[0]] = array(); } if ( ! isset( $indexed_data[$query_type][$suffix_data[0]][$range_key] ) ) { $indexed_data[$query_type][$suffix_data[0]][$range_key] = 0; } $indexed_data[$query_type][$suffix_data[0]][$range_key] += $row['count']; } } break; } } elseif ( ! empty( $data ) ) { foreach ( $data as $item ) { foreach ( $result as $row ) { $is_current_key = strpos( $key, ',' ) ? boolval( preg_match( "/\b" . $row['item_key'] . "\b/i", $key ) ) : $row['item_key'] === $key; if ( ! $is_current_key || $row['item_query'] !== $query_type || $row['item_value'] != $item ) { continue; } if ( ! isset( $indexed_data[$query_type][$key] ) ) { $indexed_data[$query_type][$key] = array(); } $indexed_data[$query_type][$key][$item] = $row['count']; } } } } } return $indexed_data; } /** * Add indexing data from filter by id */ public function add_indexing_data_from_filter( $provider_key, $filter_id ) { $data = array(); $query_type = ''; $query_var = ''; $source = get_post_meta( $filter_id ); $data_source = ! empty( $source['_data_source'] ) ? $source['_data_source'][0] : false; if ( $source['_filter_type'][0] === 'check-range' ) { $query_type = 'meta_query'; $query_var = $source['_query_var'][0]; if ( ! $query_var ) { return; } $query_var .= '|range'; if ( ! isset( $this->indexing_data[$provider_key][$query_type] ) ) { $this->indexing_data[$provider_key][$query_type] = array(); } if ( ! isset( $this->indexing_data[$provider_key][$query_type][$query_var] ) ) { $this->indexing_data[$provider_key][$query_type][$query_var] = array(); } foreach ( unserialize( $source['_source_manual_input_range'][0] ) as $range_data ) { $min = ! empty( $range_data['min'] ) ? intval( $range_data['min'] ) : 0; $max = ! empty( $range_data['max'] ) || $range_data['max'] === '0' ? intval( $range_data['max'] ) : 100; $key = $min . '_' . $max; if ( ! isset( $this->indexing_data[$provider_key][$query_type][$query_var][$key] ) ) { $this->indexing_data[$provider_key][$query_type][$query_var][$key] = array( 'min' => $min, 'max' => $max, ); } } return; } else if ( $source['_filter_type'][0] === 'select' && filter_var( $source['_is_hierarchical'][0], FILTER_VALIDATE_BOOLEAN ) ) { $query_type = 'tax_query'; foreach ( unserialize( $source['_ih_source_map'][0] ) as $item ) { $tax = $item['tax']; $data[$tax] = $this->get_terms_by_tax( $tax ); } } else { switch ( $data_source ) { case 'taxonomies': $query_type = 'tax_query'; $tax = ! empty( $source['_source_taxonomy'] ) ? $source['_source_taxonomy'][0] : false; $exclude_include = isset( $source['_use_exclude_include'] ) && isset( $source['_use_exclude_include'][0] ) ? $source['_use_exclude_include'][0] : ''; if ( $exclude_include === 'include' ) { $data[$tax] = unserialize( $source['_data_exclude_include'][0] ); } else { $data[$tax] = $this->get_terms_by_tax( $tax ); if ( $exclude_include === 'exclude' ) { $data[$tax] = array_diff( $data[$tax], unserialize( $source['_data_exclude_include'][0] ) ); } } if ( ! empty( $source['_is_custom_query_var'] ) && filter_var( $source['_is_custom_query_var'][0], FILTER_VALIDATE_BOOLEAN ) && $source['_custom_query_var'][0] ) { $query_type = 'meta_query'; $query_var = $source['_custom_query_var'][0]; $data[$query_var] = $data[$tax]; unset( $data[$tax] ); } break; case 'manual_input': $query_type = 'meta_query'; $query_var = $source['_query_var'][0]; if ( $source['_filter_type'][0] === 'color-image' ) { $input_data = $source['_source_color_image_input'][0]; } else { $input_data = $source['_source_manual_input'][0]; } if ( ! $input_data ) { return; } foreach ( unserialize( $input_data ) as $input_item ) { $data[$query_var][] = $input_item['value']; } break; case 'posts': $query_type = 'meta_query'; $query_var = $source['_query_var'][0]; $post_type = isset( $source['_source_post_type'] ) ? $source['_source_post_type'][0] : false; if ( ! $post_type ) { break; } global $wpdb; $posts_table = $wpdb->posts; $post_type = esc_sql( $post_type ); $input_data = $wpdb->get_results( "SELECT ID FROM $posts_table WHERE post_type = '$post_type' AND post_status = 'publish';" ); if ( empty( $input_data ) ) { break; } foreach ( $input_data as $input_item ) { $data[$query_var][] = $input_item->ID; } break; case 'custom_fields': $query_type = 'meta_query'; $query_var = $source['_query_var'][0]; $custom_field_options = jet_smart_filters()->data->get_choices_from_field_data( array( 'field_key' => $source['_source_custom_field'][0], 'source' => $source['_custom_field_source_plugin'][0], ) ); $data[$query_var] = array_keys( $custom_field_options ); break; default: $query_var = $source['_query_var'][0]; $custom_args = apply_filters( 'jet-smart-filters/indexer/custom-args', array(), $filter_id ); $query_type = isset( $custom_args['query_type'] ) ? $custom_args['query_type'] : 'meta_query'; $options = ! empty( $custom_args['options'] ) ? $custom_args['options'] : false; if ( empty( $options ) ) { $options = apply_filters( 'jet-smart-filters/filters/filter-options', $options, $filter_id, false ); if ( ! empty( $options ) ) { $options = array_filter( array_keys( $options ), function( $value ) { return '' !== $value; } ); } } $data[$query_var] = $options; break; } } if ( $query_type && $data ) { if ( ! isset( $this->indexing_data[$provider_key] ) ) { $this->indexing_data[$provider_key] = array(); } if ( ! isset( $this->indexing_data[$provider_key][$query_type] ) ) { $this->indexing_data[$provider_key][$query_type] = array(); } if ( $query_type === 'tax_query' ) { $this->indexing_data[$provider_key][$query_type] = array_merge_recursive( $this->indexing_data[$provider_key][$query_type], $data ); } else { $this->indexing_data[$provider_key][$query_type] = array_merge( $this->indexing_data[$provider_key][$query_type], $data ); } } } public function get_terms_by_tax( $tax ) { global $wpdb; $terms = array(); $sql = " SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = '$tax'"; $result = $wpdb->get_results( $sql, ARRAY_A ); foreach ( $result as $term_id ) { array_push( $terms, $term_id['term_id'] ); } return $terms; } public function get_queried_ids( $args ) { $ids = array( -1 ); $type = ! empty( $args['_query_type'] ) ? $args['_query_type'] : 'posts'; unset( $args['jet_smart_filters'] ); unset( $args['paged'] ); switch ( $type ) { case 'posts': $post_main_args = [ 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids' ]; $query = new WP_Query( wp_parse_args( $post_main_args, $args ) ); if ( ! empty( $query->posts ) ) { $ids = $query->posts; } break; case 'users': $user_main_args = [ 'number' => -1, 'count_total' => false, 'fields' => 'ID' ]; $users_ids = get_users( wp_parse_args( $user_main_args, $args ) ) ; if ( ! empty( $users_ids ) ) { $ids = $users_ids; } break; case 'wc-product-query': $wc_main_args = [ 'status' => 'publish', 'limit' => -1, 'return' => 'ids' ]; $wc_ids = wc_get_products( wp_parse_args( $wc_main_args, $args ) ) ; if ( ! empty( $wc_ids->products ) ) { $ids = $wc_ids->products; } break; } return $ids; } } }