Tejas Rana

WordPress Dynamic Post filter by custom field

Hi to all,
I have recently developed Dynamic post filter as per category with admin section.
Plugin part:
Step 1: Create folder name: category-filters
Step 2: Create php file name: category-filters.php under category-filters folder
Step 3: Add plugin detail in category-filters.php

<?php
/*
Plugin Name: Category-filters
Plugin URI: https://www.tejasrana.com
Description: A filter for post by category using custom field.
Author: Tejas Rana
Twitter: @tejasrana95
Author URI: https://www.tejasrana.com
Version:.1.8.2
License: GPL
Copyright: Tejas Rana
*/

After this add this section. Please read complete code to understand as you are good developer.

class tejasrana_Categoryfilters
/**
 * Holds the values to be used in the fields callbacks
 */
 private $options;
 /**
 * Start up
 */
 public function __construct()
 {
 add_action( 'admin_menu', array( $this, 'add_plugin_page' ) );
 add_action( 'admin_init', array( $this, 'page_init' ) );
 }
 /**
 * Add options page
 */
 public function add_plugin_page()
 {
 // This page will be under "Settings"
 add_options_page(
 'Settings Admin',
 'Category wise filters',
 'manage_options',
 'category-wise-filters',
 array( $this, 'create_admin_page' )
 );
 }
 /**
 * Options page callback
 */
 public function create_admin_page()
 {
 // Set class property
 $this->options = get_option( 'category_wise_filters' );
 ?>
 <div class="wrap">
 <h2>Category Wise filters</h2>
 <form method="post" action="options.php">
 <?php
 // This prints out all hidden setting fields
 settings_fields( 'category_filter_group' );
 do_settings_sections( 'category_filter_group' );
 submit_button();
 ?>
 </form>
 </div>
 <?php
 }
 /**
 * Register and add settings
 */
 public function page_init()
 {
 register_setting(
 'category_filter_group', // Option group
 'category_filter_group', // Option name
 array( $this, 'sanitize' ) // Sanitize
 );
 add_settings_section(
 'setting_section_id', // ID
 'Category Wise filters', // Title
 array( $this, 'print_section_info' ), // Callback
 'category_filter_group' // Page
 );
 add_settings_field(
 'category', // ID
 'Category:', // Title
 array( $this, 'category_id_callback' ), // Callback
 'category_filter_group', // Page
 'setting_section_id' // Section
 );
 }
 /**
 * Sanitize each setting field as needed
 *
 * @param array $input Contains all settings fields as array keys
 */
 public function sanitize( $input )
 {
 $new_input = array();
 if( isset( $_POST['category_filter'] ) )
 $new_input['category_filter'] = ( $_POST['category_filter'] );
 return $new_input;
 }
 /**
 * Print the Section text
 */
 public function print_section_info()
 {
 print 'Select filters below for category';
 }
 /**
 * Get the settings option array and print one of its values
 */
 public function category_id_callback()
 {
 $cate_args = array(
 'orderby' => 'name',
 'parent' => 18
 );
 $parent_category=get_categories($cate_args); ?>
 <?php
 $saved_value = get_option( 'category_filter_group' );
 $saved_value=$saved_value['category_filter'];
 foreach($parent_category as $parent_category){
 $my_query = new WP_Query('category_name='.$parent_category->name.'&showposts=1');
 while ($my_query->have_posts()) : $my_query->the_post();
 $random_post_id[]=get_the_ID();
 endwhile;
 $all_fields = get_fields( $random_post_id[0]);
 $menu_order=array();
 foreach($all_fields as $all_field => $all_field_value){
 $field_data=get_field_object($all_field );
 $menu_order[$all_field] = $field_data["menu_order"];
 }
 //array_multisort($menu_order, SORT_ASC, $all_fields);
 echo '<strong>'.$parent_category->name.':</strong>'; ?>
 <table>
 <?php
 $i=1;
 foreach($all_fields as $all_field => $all_field_value){
 $field_data=get_field_object($all_field );
 if($i==1){
 echo '<tr>';
 }
 ?>
 <td width="300"><label><input type="checkbox" name="category_filter[<?php echo $parent_category->term_id ?>][<?php echo $all_field ?>][field]" value="1" <?php if($saved_value[$parent_category->term_id][$all_field]['field']==1){echo 'checked="checked"';} ?>><?php echo $field_data['label'] ?></label></td>
 <td width="300"><label><input type="number" name="category_filter[<?php echo $parent_category->term_id ?>][<?php echo $all_field ?>][order]" value="<?php if(isset($saved_value[$parent_category->term_id][$all_field]['order'])){echo $saved_value[$parent_category->term_id][$all_field]['order'];} ?>" style="width:50px;"></label></td>
 <?php
 if($i==3){
 echo '</tr>';
 $i=0;
 }
 $i++;
 } ?>
 <td><label><input type="checkbox" name="category_filter[<?php echo $parent_category->term_id ?>][sub_category_filter][field]" value="1" <?php if($saved_value[$parent_category->term_id]['sub_category_filter']['field']==1){echo 'checked="checked"';} ?>>Sub Category Selection</label></td>
 <td width="300"><label><input type="number" name="category_filter[<?php echo $parent_category->term_id ?>][sub_category_filter][order]" value="<?php if(isset($saved_value[$parent_category->term_id]['sub_category_filter']['order'])){echo $saved_value[$parent_category->term_id]['sub_category_filter']['order'];} ?>" style="width:50px;"></label></td>
 </table>
 <hr/>
 <?php
 }
 }
 }
 if( is_admin() )
$tejasrana_Categoryfilters = new tejasrana_Categoryfilters();

backend part done.
Now move to frontend part:
On frontend:
First of all we need to create a page and assign a template to that page. After we have to write following code in that template.
First we need to get category id:

$cat_id = $cat_id_is->term_id;

After that we need to get one post id for that category so that we can get all custom fields which applied on that post.

$args = array(
						'posts_per_page'   => -1,//12,
						'offset'           => 0,
						'cat'        	   => $cat_id,
						'orderby'          => 'date',
						'order'            => 'DESC',
						'post_type'        => 'post',
						'post_status'      => 'publish',
						);
						//$prod_array = get_posts( $prod_list );
						$wp_query = new WP_Query($args);
						$product_ids=array();
						if($wp_query->have_posts())
						{
							while ( $wp_query->have_posts() ) : $wp_query->the_post();
							$product_ids[]=get_the_ID();
							endwhile;
						}

If we are in sub category then we need parent category:

$get_top_parent= get_top_parent($cat_id);

Now we will fetch all the option for textbox and dropdown:

$saved_value = get_option( 'category_filter_group' );
						$saved_values=$saved_value['category_filter'];
						$saved_values=$saved_values[$get_top_parent];
						//end tejas code
						$saved_values=array_filter($saved_values);
						$filtered_saved_value=array();
						if(!empty($saved_values) && isset($saved_values)){
							foreach($saved_values as $saved_key => $saved_value ){
								if(!empty($saved_value['order']) && !empty($saved_value['field'])){
									$filtered_saved_value[$saved_key]=$saved_value;
									$menu_order[$saved_key]=$saved_value['order'];
								}
							}
						}
						array_multisort($menu_order, SORT_ASC, $filtered_saved_value);
						if(!empty($filtered_saved_value) && isset($filtered_saved_value)){
							foreach($filtered_saved_value as $saved_key => $saved_value ){
								$field = get_field_object($saved_key,$product_ids[0]);
							}
						}

Now we will generate form with dropdown

<div class="filter_box">
						<form action="" method="get">
							<?php $count_filters=count($filtered_saved_value);
								if($count_filters>=6){
									$class="col-md-2";
								}
								elseif($count_filters==5){
									$class="col-md-2";
								}
								elseif($count_filters==4){
									$class="col-md-3";
								}
								elseif($count_filters==3){
									$class="col-md-4";
								}
								elseif($count_filters==2){
									$class="col-md-6";
								}
								elseif($count_filters==1){
									$class="col-md-12";
								} ?>
								<div class="">
									<?php
										if(!empty($filtered_saved_value) && isset($filtered_saved_value)){
											foreach($filtered_saved_value as $saved_key => $saved_value ){
												$field = get_field_object($saved_key,$product_ids[0]);
												$category_filter_custom=null;
												if(!empty($field)){
													if($field['type']=="text"){
														$field_value_texts=array();
														foreach($product_ids as $product_id){
															$field_value=get_field( $field['name'],$product_id );
															if($field_value!=""){
																$field_value_texts[$field['name']][]=$field_value;
															}
														}
														$field_value_texts[$field['name']]=array_unique($field_value_texts[$field['name']]);
													}
													//check if value has meta tag or not
													$filter_args = array(
													'posts_per_page'   => -1,//12,
													'offset'           => 0,
													'cat'        	   => $cat_id,
													'orderby'          => 'date',
													'order'            => 'DESC',
													'post_type'        => 'post',
													'post_status'      => 'publish',
													'meta_query'	=> array(
													'relation'		=> 'AND',
													array(
													'key'	 	=> $field['name'],
													'value'	  	=> null,
													'compare' 	=> '!=',
													),
													),
													);
													$filter_wp_query = new WP_Query($filter_args);
													$post_have_meta=false;
													if($filter_wp_query->have_posts())
													{
														$post_have_meta=true;
													}
												}
												else{
													$field['name']=$saved_key;
													$category_slugs=explode('/', $current_page_url);
													$category_slug=$category_slugs[count($category_slugs)-2];
													$cate_id = get_category_by_slug($category_slug);
													//print_r($cate_id);
													$get_child_cat = array(
													'type'                     => 'post',
													'child_of'                   => $cate_id->term_id,
													'orderby'                  => 'id',
													'order'                    => 'ASC',
													'taxonomy'                 => 'category',
													'hide_empty'               => 0,
													'hierarchical'             => 0,
													'exclude'				   => array(1,4,10,18),
													'pad_counts'               => false,
													'number'				   => 3
													);
													$categories = get_categories( $get_child_cat );
													foreach($categories as $single_cat)
													{
														$cat_title = $single_cat->name;
														$split = explode(' ', $cat_title);
														$last_elem = count($split);
														$cate_title = $split[$last_elem-1];
														$field['choices'][get_category_link($single_cat->term_id)]=$cate_title;
													}
													$field['choices'][get_category_link( $cate_id->term_id )]="Browse All";
													$field['type']="select";
													//current_category
													$current_category=$category_slugs[count($category_slugs)-1];
													$category_filter_custom=$current_category;
												}
											?>
											<?php if(isset($post_have_meta) && $post_have_meta!="" && !empty($post_have_meta)){  ?>
												<div class="<?php echo $class ?>">
													<select name="<?php echo $field['name'] ?><?php if(empty($category_filter_custom)){ ?>[]<?php } ?>" multiple class="filter_dropdown" id="<?php echo $field['name'] ?>" onchange="this.form.submit()">
														<?php
															$selected_value=array();
															if($field['type']=="text"){
																foreach($field_value_texts[$field['name']] as $field_value_text){
																	echo '<option value="'.$field_value_text.'"';
																	if(isset($_GET[$field['name']])){
																		if(is_array( $_GET[$field['name']]))
																		{
																			if(in_array($field_select_value, $_GET[$field['name']]))
																			{
																				$selected_value[$_GET[$field['name']][0]]=$field_select_value;
																				echo 'selected';
																				}elseif($field_select_value==$_GET[$field['name']]){
																				$selected_value[$_GET[$field['name']][0]]=$field_select_value;
																				echo 'selected';
																			}
																		}
																		$selected_value[$_GET[$field['name']][0]]=$field_value_text;
																	echo 'selected';}
																	$selected_value[$_GET[$field['name']][0]]=$field_value_text;
																	echo '>'.$field_value_text.'</option>';
																}
																}elseif($field['type']=="select"){
																foreach($field['choices'] as $field_select_value=>$field_select_label){
																	echo '<option value="'.$field_select_value.'" ';
																	if(isset($_GET[$field['name']])  && empty($category_filter_custom)){
																		if(is_array( $_GET[$field['name']]))
																		{
																			if(in_array($field_select_value, $_GET[$field['name']]))
																			{
																				$selected_value[$_GET[$field['name']][0]]=$field_select_value;
																				echo 'selected';
																				}elseif($field_select_value==$_GET[$field['name']]){
																				$selected_value[$_GET[$field['name']][0]]=$field_select_value;
																				echo 'selected';
																			}
																		}
																	}
																	elseif(!empty($category_filter_custom) && strtolower($field_select_label)==strtolower($category_filter_custom)){
																		echo 'selected';
																	}
																	$selected_value[$_GET[$field['name']][0]]=$field_select_value;
																	echo ' >'.$field_select_label.'</option>';
																}
															}
														?>
													</select>
													<?php if((!isset($_GET[$field['name']]) || empty($_GET[$field['name']])) && empty($category_filter_custom)){ $no_selected_value="no_selected_value"; }else{ $no_selected_value="";} ?>
													<div class="selected_value <?php echo  $no_selected_value; ?>">
														<?php if(!empty($category_filter_custom)){
															$remove_link_parent=str_replace($category_filter_custom,'',$current_page_url);
														?>
														<div class="selected_value_with_cross">
															<?php echo ucfirst($category_filter_custom); ?><a href="<?php echo $remove_link_parent ?>" class="remove_selected_value">x</a>
														</div>
														<?php
															}elseif(!empty($_GET[$field['name']])){
															foreach($_GET[$field['name']] as $selected_field){
																$remove_link_parent=home_url( $wp->request );
																$query_string=urldecode($_SERVER['QUERY_STRING']);
																$query_string=str_replace($field['name'].'[]='.$selected_field.'&',"",$query_string);
															?>
															<div class="selected_value_with_cross">
																<?php echo $field['choices'][$selected_field]; ?><a href="<?php echo $remove_link_parent.'?'.$query_string ?>" class="remove_selected_value">x</a>
																</div><?php
															}
														}
														?>
													</div>
												</div>
												<?php
												}
											}
										}
									?>
									<input type="hidden" name="filter" value="filter">
								</div>
						</form>
					</div>

After that we will generate dynamic wordpress query with meta tag which passed in query string:

wp_reset_query();
						$post_per_page=12;
						$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
						$args = array(
						'posts_per_page'   => $post_per_page,//12,
						'offset'           => 0,
						'cat'        	   => $cat_id,
						'orderby'          => 'date',
						'order'            => 'DESC',
						'post_type'        => 'post',
						'post_status'      => 'publish',
						'paged' 		   => $paged,
						);
						if(@$_GET['filter']=="filter"){
							$args['meta_query']['relation']="AND";
							foreach($saved_values as $saved_key => $saved_value ){
								$field = get_field_object($saved_key,$product_ids[0]);
								if(@$_GET[$field['name']]!="" && !empty($_GET[$field['name']])){
									$args['meta_query'][]=array('key'=> $field['name'],'value'=>$_GET[$field['name']],'compare'=> 'IN',);
								}
							}
						}
						//$prod_array = get_posts( $prod_list );
						$wp_query = new WP_Query($args);

And now finally output generate

if($wp_query->have_posts())
						{
						?>
						<div class="row">
							<?php
								//foreach ( $prod_array as $post ) : setup_postdata( $post );
								while ( $wp_query->have_posts() ) : $wp_query->the_post();
								/* $cat_title = $single_cat->name;
									$split = explode(' ', $cat_title, 2);
								$maincate_title = $split[1]; */
								$image_path = wp_get_attachment_url( get_post_thumbnail_id() );
								/* echo "<br/>".$image_path."<br/>";
									echo "<br/>".the_title();
								echo "<br/>".$page_title."<br/>"; */
							?>
							<div class="col-md-3 cat-pro-box">
								<div class="cat-img-box"><img src="<?php echo $image_path; ?>" class="img-responsive" /></div>
								<div class="cat-pro-desc text-center">
								<div class="cat-title"><?php echo the_title() ." ". get_field("product_number"); ?></div>
								<div class="cat-content"><?php echo $parent_page_title; ?></div>
								<div class="cat-btn-box"><a href="<?php echo the_permalink(); ?>" class="sm-red-btn">Learn More</a></div>
								</div>
							</div>
							<?php
								//endforeach;
								endwhile;
								//wp_reset_postdata();
							?>
						</div>
<?php } ?>

 

Exit mobile version