Skip to content

Instantly share code, notes, and snippets.

@andrea-calligaris
Last active June 26, 2022 14:28
Show Gist options
  • Save andrea-calligaris/fe2f52c06f792dc4b37ab27e9a9e0a16 to your computer and use it in GitHub Desktop.
Save andrea-calligaris/fe2f52c06f792dc4b37ab27e9a9e0a16 to your computer and use it in GitHub Desktop.
Search & Filter plugin for WordPress: Polylang compatibility fix, edited from 1.2.15
<?php
/*
Plugin Name: Search & Filter
Plugin URI: https://free.searchandfilter.com/
Description: Search and Filtering system for Pages, Posts, Categories, Tags and Taxonomies
Author: Code Amp; edited by Andrea Calligaris, fix distributed under WTFPL
Author URI: https://codeamp.com
Version: 1.2.15
Text Domain: searchandfilter
License: GPLv2
*/
/*
* Set up Plugin Globals
*/
if (!defined('SEARCHANDFILTER_VERSION_NUM'))
define('SEARCHANDFILTER_VERSION_NUM', '1.2.15');
if (!defined('SEARCHANDFILTER_THEME_DIR'))
define('SEARCHANDFILTER_THEME_DIR', ABSPATH . 'wp-content/themes/' . get_template());
if (!defined('SEARCHANDFILTER_PLUGIN_NAME'))
define('SEARCHANDFILTER_PLUGIN_NAME', trim(dirname(plugin_basename(__FILE__)), '/'));
if (!defined('SEARCHANDFILTER_PLUGIN_DIR'))
define('SEARCHANDFILTER_PLUGIN_DIR', WP_PLUGIN_DIR . '/' . SEARCHANDFILTER_PLUGIN_NAME);
if (!defined('SEARCHANDFILTER_PLUGIN_URL'))
define('SEARCHANDFILTER_PLUGIN_URL', WP_PLUGIN_URL . '/' . SEARCHANDFILTER_PLUGIN_NAME);
if (!defined('SEARCHANDFILTER_BASENAME'))
define('SEARCHANDFILTER_BASENAME', plugin_basename(__FILE__));
if (!defined('SEARCHANDFILTER_VERSION_KEY'))
define('SEARCHANDFILTER_VERSION_KEY', 'searchandfilter_version');
//form prefix for plugin
if (!defined('SF_FPRE'))
define('SF_FPRE', 'of');
add_option(SEARCHANDFILTER_VERSION_KEY, SEARCHANDFILTER_VERSION_NUM);
/*
* Set up Plugin Globals
*/
if ( ! class_exists( 'SearchAndFilter' ) )
{
class SearchAndFilter
{
private $has_form_posted = false;
private $hasqmark = false;
private $hassearchquery = false;
private $urlparams = "/";
private $searchterm = "";
private $tagid = 0;
private $catid = 0;
private $defaults = array();
private $frmreserved = array();
private $taxonomylist = array();
public function __construct()
{
// Set up reserved fields
$this->frmreserved = array(SF_FPRE."category", SF_FPRE."search", SF_FPRE."post_tag", SF_FPRE."submitted", SF_FPRE."post_date", SF_FPRE."post_types");
$this->frmqreserved = array(SF_FPRE."category_name", SF_FPRE."s", SF_FPRE."tag", SF_FPRE."submitted", SF_FPRE."post_date", SF_FPRE."post_types"); //same as reserved
//add query vars
add_filter('query_vars', array($this,'add_queryvars') );
//filter post type & date if it is set
add_filter('pre_get_posts', array($this,'filter_query_post_types'));
add_filter('pre_get_posts', array($this,'filter_query_post_date'));
//add_filter('pre_get_posts',array($this, 'fix_blank_search')); //temporaril disabled
// Add shortcode support for widgets
add_shortcode('searchandfilter', array($this, 'shortcode'));
add_filter('widget_text', 'do_shortcode');
// Check the header to see if the form has been submitted
add_action( 'get_header', array( $this, 'check_posts' ) );
// Add styles
add_action( 'wp_enqueue_scripts', array($this, 'of_enqueue_styles') );
add_action( 'admin_enqueue_scripts', array($this, 'of_enqueue_admin_ss') );
}
public function of_enqueue_styles()
{
wp_enqueue_style( 'searchandfilter', SEARCHANDFILTER_PLUGIN_URL . '/style.css', false, 1.0, 'all' );
}
public function of_enqueue_admin_ss($hook)
{
if( 'toplevel_page_searchandfilter-settings' == $hook )
{
wp_enqueue_style( 'of_syntax_style', SEARCHANDFILTER_PLUGIN_URL.'/admin/github.css', false, 1.0, 'all' ); //more highlight styles http://softwaremaniacs.org/media/soft/highlight/test.html
wp_enqueue_style( 'of_style', SEARCHANDFILTER_PLUGIN_URL.'/admin/style.css', false, 1.0, 'all' );
//wp_enqueue_script( 'of_syntax_script', SEARCHANDFILTER_PLUGIN_URL.'/admin/syntax.highlight.min.js' );
}
}
public function shortcode($atts, $content = null)
{
// extract the attributes into variables
extract(shortcode_atts(array(
'fields' => null,
'taxonomies' => null, //will be deprecated - use `fields` instead
'submit_label' => null,
'submitlabel' => null, //will be deprecated - use `submit_label` instead
'search_placeholder' => "Search &hellip;",
'types' => "",
'type' => "", //will be deprecated - use `types` instead
'headings' => "",
'all_items_labels' => "",
'class' => "",
'post_types' => "",
'hierarchical' => "",
'hide_empty' => "",
'order_by' => "",
'show_count' => "",
'order_dir' => "",
'operators' => "",
'add_search_param' => "0",
'empty_search_url' => ""
), $atts));
//init `fields`
if($fields!=null)
{
$fields = explode(",",$fields);
}
else
{
$fields = explode(",",$taxonomies);
}
$this->taxonomylist = $fields;
$nofields = count($fields);
$add_search_param = (int)$add_search_param;
//init `submitlabel`
if($submitlabel!=null)
{//then the old "submitlabel" has been supplied
if($submit_label==null)
{
//then the new label has not been supplied so do nothing
$submit_label = $submitlabel;
}
else
{
//then the new label has been supplied so take the new label value
//$submit_label = $submit_label;
}
}
else if($submitlabel==null)
{
if($submit_label==null)
{//default value
$submit_label = "Submit";
}
}
//init `post_types`
if($post_types!="")
{
$post_types = explode(",",$post_types);
}
else
{
if(in_array("post_types", $fields))
{
$post_types = array("all");
}
}
//init `hierarchical`
if($hierarchical!="")
{
$hierarchical = explode(",",$hierarchical);
}
else
{
$hierarchical = array("");
}
//init `hide_empty`
if($hide_empty!="")
{
$hide_empty = explode(",",$hide_empty);
}
else
{
$hide_empty = array("");
}
//init `show_count`
if($show_count!="")
{
$show_count = explode(",",$show_count);
}
else
{
$show_count = array();
}
//init `order_by`
if($order_by!="")
{
$order_by = explode(",",$order_by);
}
else
{
$order_by = array("");
}
//init `order_dir`
if($order_dir!="")
{
$order_dir = explode(",",$order_dir);
}
else
{
$order_dir = array("");
}
//init `operators`
if($operators!="")
{
$operators = explode(",",$operators);
}
else
{
$operators = array("");
}
//init `labels`
$labels = explode(",",$headings);
if(!is_array($labels))
{
$labels = array();
}
//init `all_items_labels`
$all_items_labels = explode(",",$all_items_labels);
if(!is_array($all_items_labels))
{
$all_items_labels = array();
}
//init `types`
if($types!=null)
{
$types = explode(",",$types);
}
else
{
$types = explode(",",$type);
}
if(!is_array($types))
{
$types = array();
}
//init empty_search_url
//Loop through Fields and set up default vars
for($i=0; $i<$nofields; $i++)
{//loop through all fields
//set up types
if(isset($types[$i]))
{
if($fields[$i] == 'post_date')
{//check for post date field
if(($types[$i]!="date")&&($types[$i]!="daterange"))
{//if not expected value
$types[$i] = "date"; //use default
}
}
else
{//everything else can use a standard form input - checkbox/radio/dropdown/list/multiselect
if(($types[$i]!="select")&&($types[$i]!="checkbox")&&($types[$i]!="radio")&&($types[$i]!="list")&&($types[$i]!="multiselect"))
{//no accepted type matched - non compatible type defined by user
$types[$i] = "select"; //use default
}
}
}
else
{//omitted, so set default
if($fields[$i] == 'post_date')
{
$types[$i] = "date";
}
else
{
$types[$i] = "select";
}
}
//setup labels
if(!isset($labels[$i]))
{
$labels[$i] = "";
}
//setup all_items_labels
if(!isset($all_items_labels[$i]))
{
$all_items_labels[$i] = "";
}
if(isset($order_by[$i]))
{
if(($order_by[$i]!="id")&&($order_by[$i]!="name")&&($order_by[$i]!="slug")&&($order_by[$i]!="count")&&($order_by[$i]!="term_group"))
{
$order_by[$i] = "name"; //use default - possible typo or use of unknown value
}
}
else
{
$order_by[$i] = "name"; //use default
}
if(isset($order_dir[$i]))
{
if(($order_dir[$i]!="asc")&&($order_dir[$i]!="desc"))
{//then order_dir is not a wanted value
$order_dir[$i] = "asc"; //set to default
}
}
else
{
$order_dir[$i] = "asc"; //use default
}
if(isset($operators[$i]))
{
$operators[$i] = strtolower($operators[$i]);
if(($operators[$i]!="and")&&($operators[$i]!="or"))
{
$operators[$i] = "and"; //else use default - possible typo or use of unknown value
}
}
else
{
$operators[$i] = "and"; //use default
}
}
//set all form defaults / dropdowns etc
$this->set_defaults();
return $this->get_search_filter_form($submit_label, $search_placeholder, $fields, $types, $labels, $hierarchical, $hide_empty, $show_count, $post_types, $order_by, $order_dir, $operators, $all_items_labels, $empty_search_url, $add_search_param, $class);
}
function add_queryvars( $qvars )
{
$qvars[] = 'post_types';
$qvars[] = 'post_date';
return $qvars;
}
function filter_query_post_types($query)
{
global $wp_query;
if(($query->is_main_query())&&(!is_admin()))
{
if(isset($wp_query->query['post_types']))
{
$search_all = false;
$post_types = explode(",",esc_attr($wp_query->query['post_types']));
if(isset($post_types[0]))
{
if(count($post_types)==1)
{
if($post_types[0]=="all")
{
$search_all = true;
}
}
}
if($search_all)
{
$post_types = get_post_types( '', 'names' );
$query->set('post_type', $post_types); //here we set the post types that we want WP to search
}
else
{
$query->set('post_type', $post_types); //here we set the post types that we want WP to search
}
}
}
return $query;
}
function limit_date_range_query( $where )
{
global $wp_query;
//get post dates into array
$post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
if (count($post_date) > 1 && $post_date[0] != $post_date[1])
{
$date_query = array();
if (!empty($post_date[0]))
{
$date_query['after'] = date('Y-m-d 00:00:00', strtotime($post_date[0]));
}
if (!empty($post_date[1]))
{
$date_query['before'] = date('Y-m-d 23:59:59', strtotime($post_date[1]));
}
}
// Append fragment to WHERE clause to select posts newer than the past week.
$where .= " AND post_date >='" . $date_query['after'] . "' AND post_date <='" . $date_query['before'] . "'";
return $where;
}
/**
* Remove the filter limiting posts to the past week.
*
* Remove the filter after it runs so that it doesn't affect any other
* queries that might be performed on the same page (eg. Recent Posts
* widget).
*/
function remove_limit_date_range_query()
{
remove_filter( 'posts_where', 'limit_date_range_query' );
}
function fix_blank_search($query)
{//needs to be re-implemented
if((isset($_GET['s'])) && (empty($_GET['s'])) && ($query->is_main_query()))
{
$query->is_search = true;
$query->is_home = false;
}
}
function filter_query_post_date($query)
{
global $wp_query;
if(($query->is_main_query())&&(!is_admin()))
{
if(isset($wp_query->query['post_date']))
{
//get post dates into array
$post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
if(!empty($post_date))
{
//if there is more than 1 post date and the dates are not the same
if (count($post_date) > 1 && $post_date[0] != $post_date[1])
{
if((!empty($post_date[0]))&&(!empty($post_date[1])))
{
// Attach hook to filter WHERE clause.
add_filter('posts_where', array($this,'limit_date_range_query'));
// Remove the filter after it is executed.
add_action('posts_selection', array($this,'remove_limit_date_range_query'));
}
}
else
{ //else we are dealing with one date or both dates are the same (so need to find posts for a single day)
if (!empty($post_date[0]))
{
$post_time = strtotime($post_date[0]);
$query->set('year', date('Y', $post_time));
$query->set('monthnum', date('m', $post_time));
$query->set('day', date('d', $post_time));
}
}
}
}
}
return $query;
}
/*
* check to set defaults - to be called after the shortcodes have been init so we can grab the wanted list of fields
*/
public function set_defaults()
{
global $wp_query;
$categories = array();
if(isset($wp_query->query['category_name']))
{
$category_params = (preg_split("/[,\+ ]/", esc_attr($wp_query->query['category_name']))); //explode with 2 delims
//$category_params = explode("+",esc_attr($wp_query->query['category_name']));
foreach($category_params as $category_param)
{
$category = get_category_by_slug( $category_param );
if(isset($category->cat_ID))
{
$categories[] = $category->cat_ID;
}
}
}
$this->defaults[SF_FPRE.'category'] = $categories;
//grab search term for prefilling search input
if(isset($wp_query->query['s']))
{//!"�$%^&*()
$this->searchterm = trim(get_search_query());
}
//check to see if tag is set
$tags = array();
if(isset($wp_query->query['tag']))
{
$tag_params = (preg_split("/[,\+ ]/", esc_attr($wp_query->query['tag']))); //explode with 2 delims
//$tag_params = explode("+",esc_attr($wp_query->query['tag']));
foreach($tag_params as $tag_param)
{
$tag = get_term_by("slug",$tag_param, "post_tag");
if(isset($tag->term_id))
{
$tags[] = $tag->term_id;
}
}
}
$this->defaults[SF_FPRE.'post_tag'] = $tags;
if ( isset( $wp_query->query ) && is_array( $wp_query->query ) ) {
//loop through all the query vars
foreach($wp_query->query as $key=>$val) {
if(!in_array(SF_FPRE.$key, $this->frmqreserved))
{//make sure the get is not a reserved get as they have already been handled above
//now check it is a desired key
if(in_array($key, $this->taxonomylist))
{
$taxslug = ($val);
//$tax_params = explode("+",esc_attr($taxslug));
$tax_params = (preg_split("/[,\+ ]/", esc_attr($taxslug))); //explode with 2 delims
$taxs = array();
foreach($tax_params as $tax_param)
{
$tax = get_term_by("slug",$tax_param, $key);
if(isset($tax->term_id))
{
$taxs[] = $tax->term_id;
}
}
$this->defaults[SF_FPRE.$key] = $taxs;
}
}
}
}
$post_date = array("","");
if(isset($wp_query->query['post_date']))
{
$post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
if(count($post_date)==1)
{
$post_date[1] = "";
}
}
$this->defaults[SF_FPRE.'post_date'] = $post_date;
$post_types = array();
if(isset($wp_query->query['post_types']))
{
$post_types = explode(",",esc_attr($wp_query->query['post_types']));
}
$this->defaults[SF_FPRE.'post_types'] = $post_types;
}
/*
* check to see if form has been submitted and handle vars
*/
public function check_posts()
{
$uses_polylang = false;
// check if the site uses Polylang
if(function_exists('pll_home_url')){
$uses_polylang = true;
}
if(isset($_POST[SF_FPRE.'submitted']))
{
if($_POST[SF_FPRE.'submitted']==="1")
{
//set var to confirm the form was posted
$this->has_form_posted = true;
}
}
$taxcount = 0;
/* CATEGORIES */
if((isset($_POST[SF_FPRE.'category']))&&($this->has_form_posted))
{
$the_post_cat = ($_POST[SF_FPRE.'category']);
//make the post an array for easy looping
if(!is_array($_POST[SF_FPRE.'category']))
{
$post_cat[] = $the_post_cat;
}
else
{
$post_cat = $the_post_cat;
}
$catarr = array();
foreach ($post_cat as $cat)
{
$cat = esc_attr($cat);
$catobj = get_category($cat);
if(isset($catobj->slug))
{
$catarr[] = $catobj->slug;
//$catarr[] = $catobj->term_id;
}
}
if(count($catarr)>0)
{
$operator = "+"; //default behaviour
//check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
if(isset($_POST[SF_FPRE.'category_operator']))
{
if(strtolower($_POST[SF_FPRE.'category_operator'])=="and")
{
$operator = "+";
}
else if(strtolower($_POST[SF_FPRE.'category_operator'])=="or")
{
$operator = ",";
}
else
{
$operator = "+";
}
}
$categories = implode($operator,$catarr);
if(get_option('permalink_structure')&&($taxcount==0)&&(!$uses_polylang))
{
//$catrel = trim(str_replace(home_url(), "", get_category_link()), "/").$categories."/"; //get full category link, remvoe the home url to get relative, trim traling slashed, the append slash at the end
$category_base = (get_option( 'category_base' )=="") ? "category" : get_option( 'category_base' );
$category_path = $category_base."/".$categories."/";
$this->urlparams .= $category_path;
}
else
{
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "category_name=".$categories;
}
$taxcount++;
}
}
/* TAGS */
if((isset($_POST[SF_FPRE.'post_tag']))&&($this->has_form_posted))
{
$the_post_tag = ($_POST[SF_FPRE.'post_tag']);
//make the post an array for easy looping
if(!is_array($_POST[SF_FPRE.'post_tag']))
{
$post_tag[] = $the_post_tag;
}
else
{
$post_tag = $the_post_tag;
}
$tagarr = array();
foreach ($post_tag as $tag)
{
$tag = esc_attr($tag);
$tagobj = get_tag($tag);
if(isset($tagobj->slug))
{
$tagarr[] = $tagobj->slug;
}
}
if(count($tagarr)>0)
{
$operator = "+"; //default behaviour
//check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
if(isset($_POST[SF_FPRE.'post_tag_operator']))
{
if(strtolower($_POST[SF_FPRE.'post_tag_operator'])=="and")
{
$operator = "+";
}
else if(strtolower($_POST[SF_FPRE.'post_tag_operator'])=="or")
{
$operator = ",";
}
else
{
$operator = "+";
}
}
$tags = implode($operator,$tagarr);
if(get_option('permalink_structure')&&($taxcount==0)&&(!$uses_polylang))
{
$tag_path = "tag/".$tags."/";
$this->urlparams .= $tag_path;
}
else
{
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "tag=".$tags;
}
$taxcount++;
}
}
//now we have dealt with the all the special case fields - search, tags, categories, post_types, post_date
//loop through the posts - double check that it is the search form that has been posted, otherwise we could be looping through the posts submitted from an entirely unrelated form
if($this->has_form_posted)
{
foreach($_POST as $key=>$val)
{
if(!in_array($key, $this->frmreserved))
{//if the key is not in the reserved array (ie, on a custom taxonomy - not tags, categories, search term, post type & post date)
// strip off all prefixes for custom fields - we just want to do a redirect - no processing
if (strpos($key, SF_FPRE) === 0)
{
$key = substr($key, strlen(SF_FPRE));
}
$the_post_tax = $val;
$post_tax = array();
//make the post an array for easy looping
if(!is_array($the_post_tax))
{
$post_tax[] = $the_post_tax;
}
else
{
$post_tax = $the_post_tax;
}
$taxarr = array();
foreach ($post_tax as $tax)
{
$tax = esc_attr($tax);
$taxobj = get_term_by('id', $tax, $key);
if(isset($taxobj->slug))
{
$taxarr[] = $taxobj->slug;
}
}
if(count($taxarr)>0)
{
$operator = "+"; //default behaviour
//check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
if(isset($_POST[SF_FPRE.$key.'_operator']))
{
if(strtolower($_POST[SF_FPRE.$key.'_operator'])=="and")
{
$operator = "+";
}
else if(strtolower($_POST[SF_FPRE.$key.'_operator'])=="or")
{
$operator = ",";
}
else
{
$operator = "+";
}
}
$taxs = implode($operator,$taxarr);
//**due to some new wierd rewrite in WordPress, the first taxonomy which get rewritten to /taxonomyname/taxonomyvalue only uses the first value of an array - so do it manually
if(get_option('permalink_structure')&&($taxcount==0)&&(!$uses_polylang))
{
$key_taxonomy = get_taxonomy( $key );
$tax_path = $key."/".$taxs."/";
if((isset($key_taxonomy->rewrite))&&(isset($key_taxonomy->rewrite['slug'])))
{
$tax_path = $key_taxonomy->rewrite['slug']."/".$taxs."/";
}
$this->urlparams .= $tax_path;
}
else
{
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= $key."=".$taxs;
}
$taxcount++;
}
}
}
}
/* SEARCH BOX */
if((isset($_POST[SF_FPRE.'search']))&&($this->has_form_posted))
{
$this->searchterm = trim(stripslashes($_POST[SF_FPRE.'search']));
if($this->searchterm!="")
{
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "s=".urlencode($this->searchterm);
$this->hassearchquery = true;
}
}
if(!$this->hassearchquery)
{
if((isset($_POST[SF_FPRE.'add_search_param']))&&($this->has_form_posted))
{//this is only set when a search box is displayed - it tells S&F to append a blank search to the URL to indicate a search has been submitted with no terms, however, still load the search template
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "s=";
}
}
/* POST TYPES */
if((isset($_POST[SF_FPRE.'post_types']))&&($this->has_form_posted))
{
$the_post_types = ($_POST[SF_FPRE.'post_types']);
//make the post an array for easy looping
if(!is_array($the_post_types))
{
$post_types_arr[] = $the_post_types;
}
else
{
$post_types_arr = $the_post_types;
}
$num_post_types = count($post_types_arr);
for($i=0; $i<$num_post_types; $i++)
{
if($post_types_arr[$i]=="0")
{
$post_types_arr[$i] = "all";
}
}
if(count($post_types_arr)>0)
{
$operator = ","; //default behaviour
$post_types = implode($operator,$post_types_arr);
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "post_types=".$post_types;
}
}
/* POST DATE */
if((isset($_POST[SF_FPRE.'post_date']))&&($this->has_form_posted))
{
$the_post_date = ($_POST[SF_FPRE.'post_date']);
//make the post an array for easy looping
if(!is_array($the_post_date))
{
$post_date_arr[] = $the_post_date;
}
else
{
$post_date_arr = $the_post_date;
}
$num_post_date = count($post_date_arr);
for($i=0; $i<$num_post_date; $i++)
{
if($post_date_arr[$i]=="0")
{
$post_date_arr[$i] = "all";
}
}
if(count($post_date_arr)>0)
{
$post_date_count = count($post_date_arr);
if($post_date_count==2)
{//see if there are 2 elements in arr (second date range selector)
if(($post_date_arr[0]!="")&&($post_date_arr[1]==""))
{
$post_date = $post_date_arr[0];
}
else if($post_date_arr[1]=="")
{//if second date range is blank then remove the array element - this remove the addition of a '+' by implode below and only use first element
unset($post_date_arr[1]);
}
else if($post_date_arr[0]=="")
{
$post_date = "+".$post_date_arr[1];
}
else
{
$post_date = implode("+",array_filter($post_date_arr));
}
}
else
{
$post_date = $post_date_arr[0];
}
if(isset($post_date))
{
if($post_date!="")
{
if(!$this->hasqmark)
{
$this->urlparams .= "?";
$this->hasqmark = true;
}
else
{
$this->urlparams .= "&";
}
$this->urlparams .= "post_date=".$post_date;
}
}
}
}
if($this->has_form_posted)
{//if the search has been posted, redirect to the newly formed url with all the right params
if($this->urlparams=="/")
{//check to see if url params are set, if not ("/") then add "?s=" to force load search results, without this it would redirect to the homepage, which may be a custom page with no blog items/results
$this->urlparams .= "?s=";
}
if($this->urlparams=="/?s=")
{//if a blank search was submitted - need to check for this string here in case `add_search_param` has already added a "?s=" to the url
if(isset($_POST[SF_FPRE.'empty_search_url']))
{//then redirect to the provided empty search url
wp_redirect(esc_url($_POST[SF_FPRE.'empty_search_url']));
exit;
}
}
$actual_home_url = home_url();
if($uses_polylang) {
$actual_home_url = pll_home_url();
$actual_home_url = rtrim($actual_home_url, '/');
}
wp_redirect(($actual_home_url.$this->urlparams));
exit;
}
}
public function get_search_filter_form($submitlabel, $search_placeholder, $fields, $types, $labels, $hierarchical, $hide_empty, $show_count, $post_types, $order_by, $order_dir, $operators, $all_items_labels, $empty_search_url, $add_search_param, $class)
{
$returnvar = '';
$addclass = "";
if($class!="")
{
$addclass = ' '.$class;
}
$returnvar .= '
<form action="" method="post" class="searchandfilter'.$addclass.'">
<div>';
if(!in_array("post_types", $fields))
{//then the user has not added it to the fields list so the user does not want a post types drop down... so add (if any) the post types to a hidden attribute
if(($post_types!="")&&(is_array($post_types)))
{
foreach($post_types as $post_type)
{
$returnvar .= "<input type=\"hidden\" name=\"".SF_FPRE."post_types[]\" value=\"".esc_attr($post_type)."\" />";
}
}
}
$returnvar .= '
<ul>';
$i = 0;
foreach($fields as $field)
{
//special cases - post_types & post_date.. all others assumed regular wp taxonomy
if($field == "search")
{
$returnvar .= '<li>';
if($labels[$i]!="")
{
$returnvar .= "<h4>".$labels[$i]."</h4>";
}
$clean_searchterm = (esc_attr($this->searchterm));
$returnvar .= '<input type="text" name="'.SF_FPRE.'search" placeholder="'.esc_attr($search_placeholder).'" value="'.esc_attr($clean_searchterm).'">';
$returnvar .= '</li>';
}
else if($field == "post_types") //a post can only every have 1 type, so checkboxes & multiselects will always be "OR"
{//build field array
//check to see if operator is set for this field
/*if(isset($operators[$i]))
{
$operators[$i] = strtolower($operators[$i]);
if(($operators[$i]=="and")||($operators[$i]=="or"))
{
$returnvar .= '<input type="hidden" name="'.SF_FPRE.$field.'_operator" value="'.$operators[$i].'" />';
}
}*/
$returnvar .= $this->build_post_type_element($types, $labels, $post_types, $field, $all_items_labels, $i);
}
else if($field == 'post_date')
{
$returnvar .= $this->build_post_date_element($labels, $i, $types, $field);
}
else
{
$returnvar .= $this->build_taxonomy_element($types, $labels, $field, $hierarchical, $hide_empty, $show_count, $order_by, $order_dir, $operators, $all_items_labels, $i);
}
$i++;
}
$returnvar .='<li>';
if($add_search_param==1)
{
$returnvar .= "<input type=\"hidden\" name=\"".SF_FPRE."add_search_param\" value=\"1\" />";
}
if($empty_search_url!="")
{
$returnvar .= "<input type=\"hidden\" name=\"".SF_FPRE."empty_search_url\" value=\"".esc_url($empty_search_url)."\" />";
}
$returnvar .=
'<input type="hidden" name="'.SF_FPRE.'submitted" value="1">
<input type="submit" value="'.esc_attr($submitlabel).'">
</li>';
$returnvar .= "</ul>";
$returnvar .= '</div>
</form>';
return $returnvar;
}
///////////////////////////////////////////////////////////
function build_post_date_element($labels, $i, $types, $field)
{
$returnvar = "";
$taxonomychildren = array();
$taxonomychildren = (object)$taxonomychildren;
$returnvar .= "<li>";
if($labels[$i]!="")
{
$returnvar .= "<h4>".$labels[$i]."</h4>";
}
$defaultval = "";
if($types[$i]=="date")
{
$returnvar .= $this->generate_date($taxonomychildren, $field, $this->tagid);
}
if($types[$i]=="daterange")
{
$returnvar .= $this->generate_date($taxonomychildren, $field, 0);
$returnvar .= "</li><li>";
$returnvar .= $this->generate_date($taxonomychildren, $field, 1);
}
$returnvar .= "</li>";
return $returnvar;
}
function build_post_type_element($types, $labels, $post_types, $field, $all_items_labels, $i)
{
$returnvar = "";
$taxonomychildren = array();
$post_type_count = count($post_types);
//then check the post types array
if(is_array($post_types))
{
if(($post_type_count==1)&&($post_types[0]=="all"))
{
$args = array('public' => true);
$output = 'object'; // names or objects, note names is the default
$operator = 'and'; // 'and' or 'or'
$post_types_objs = get_post_types( $args, $output, $operator );
$post_types = array();
foreach ( $post_types_objs as $post_type )
{
if($post_type->name!="attachment")
{
$tempobject = array();
$tempobject['term_id'] = $post_type->name;
$tempobject['cat_name'] = $post_type->labels->name;
$taxonomychildren[] = (object)$tempobject;
$post_types[] = $post_type->name;
}
}
$post_type_count = count($post_types_objs);
}
else
{
foreach($post_types as $post_type)
{
$post_type_data = get_post_type_object( $post_type );
if($post_type_data)
{
$tempobject = array();
$tempobject['term_id'] = $post_type;
$tempobject['cat_name'] = $post_type_data->labels->name;
$taxonomychildren[] = (object)$tempobject;
}
}
}
}
$taxonomychildren = (object)$taxonomychildren;
$returnvar .= "<li>";
$post_type_labels = array();
$post_type_labels['name'] = "Post Types";
$post_type_labels['singular_name'] = "Post Type";
$post_type_labels['search_items'] = "Search Post Types";
if($all_items_labels[$i]!="")
{
$post_type_labels['all_items'] = $all_items_labels[$i];
}
else
{
$post_type_labels['all_items'] = "All Post Types";
}
$post_type_labels = (object)$post_type_labels;
if($labels[$i]!="")
{
$returnvar .= "<h4>".$labels[$i]."</h4>";
}
if($post_type_count>0)
{
$defaultval = implode(",",$post_types);
}
else
{
$defaultval = "all";
}
if($types[$i]=="select")
{
$returnvar .= $this->generate_select($taxonomychildren, $field, $this->tagid, $post_type_labels, $defaultval);
}
else if($types[$i]=="checkbox")
{
$returnvar .= $this->generate_checkbox($taxonomychildren, $field, $this->tagid);
}
else if($types[$i]=="radio")
{
$returnvar .= $this->generate_radio($taxonomychildren, $field, $this->tagid, $post_type_labels, $defaultval);
}
$returnvar .= "</li>";
return $returnvar;
}
//gets all the data for the taxonomy then display as form element
function build_taxonomy_element($types, $labels, $taxonomy, $hierarchical, $hide_empty, $show_count, $order_by, $order_dir, $operators, $all_items_labels, $i)
{
$returnvar = "";
$taxonomydata = get_taxonomy($taxonomy);
if($taxonomydata)
{
$returnvar .= "<li>";
if($labels[$i]!="")
{
$returnvar .= "<h4>".$labels[$i]."</h4>";
}
$args = array(
'sf_name' => SF_FPRE . $taxonomy,
'taxonomy' => $taxonomy,
'hierarchical' => false,
'child_of' => 0,
'echo' => false,
'hide_if_empty' => false,
'hide_empty' => true,
'order' => $order_dir[$i],
'orderby' => $order_by[$i],
'show_option_none' => '',
'show_count' => '0',
'show_option_all' => '',
'show_option_all_sf' => ''
);
if(isset($hierarchical[$i]))
{
if($hierarchical[$i]==1)
{
$args['hierarchical'] = true;
}
}
if(isset($hide_empty[$i]))
{
if($hide_empty[$i]==0)
{
$args['hide_empty'] = false;
}
}
if(isset($show_count[$i]))
{
if($show_count[$i]==1)
{
$args['show_count'] = true;
}
}
if($all_items_labels[$i]!="")
{
$args['show_option_all_sf'] = $all_items_labels[$i];
}
$taxonomychildren = get_categories($args);
if($types[$i]=="select")
{
$returnvar .= $this->generate_wp_dropdown($args, $taxonomy, $this->tagid, $taxonomydata->labels);
}
else if($types[$i]=="checkbox")
{
$args['title_li'] = '';
$args['defaults'] = "";
if(isset($this->defaults[$args['sf_name']]))
{
$args['defaults'] = $this->defaults[$args['sf_name']];
}
//$args['show_option_all'] = 0;
$returnvar .= $this->generate_wp_checkbox($args, $taxonomy, $this->tagid, $taxonomydata->labels);
}
else if($types[$i]=="radio")
{
$args['title_li'] = '';
$args['defaults'] = "";
if(isset($this->defaults[$args['sf_name']]))
{
$args['defaults'] = $this->defaults[$args['sf_name']];
}
$returnvar .= $this->generate_wp_radio($args, $taxonomy, $this->tagid, $taxonomydata->labels);
}
else if($types[$i]=="multiselect")
{
$args['title_li'] = '';
$args['defaults'] = "";
if(isset($this->defaults[$args['sf_name']]))
{
$args['defaults'] = $this->defaults[$args['sf_name']];
}
$returnvar .= $this->generate_wp_multiselect($args, $taxonomy, $this->tagid, $taxonomydata->labels);
}
//check to see if operator is set for this field
if(isset($operators[$i]))
{
$operators[$i] = strtolower($operators[$i]);
if(($operators[$i]=="and")||($operators[$i]=="or"))
{
$returnvar .= '<input type="hidden" name="'.esc_attr(SF_FPRE.$taxonomy).'_operator" value="'.esc_attr($operators[$i]).'" />';
}
}
$returnvar .= "</li>";
}
return $returnvar;
}
/*
* Display various forms
*/
//use wp array walker to enable hierarchical display
public function generate_wp_dropdown($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$args['name'] = $args['sf_name'];
$returnvar = '';
if($args['show_option_all_sf']=="")
{
$args['show_option_all'] = $labels->all_items != "" ? $labels->all_items : 'All ' . $labels->name;
}
else
{
$args['show_option_all'] = $args['show_option_all_sf'];
}
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE . $name];
if (is_array($defaults)) {
if (count($defaults) == 1) {
$args['selected'] = $defaults[0];
}
}
else {
$args['selected'] = $defaultval;
}
}
$returnvar .= wp_dropdown_categories($args);
return $returnvar;
}
//use wp array walker to enable hierarchical display
public function generate_wp_multiselect($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$returnvar = '<select multiple="multiple" name="'.$args['sf_name'].'[]" class="postform">';
$returnvar .= walk_taxonomy('multiselect', $args);
$returnvar .= "</select>";
return $returnvar;
}
//use wp array walker to enable hierarchical display
public function generate_wp_checkbox($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$returnvar = '<ul>';
$returnvar .= walk_taxonomy('checkbox', $args);
$returnvar .= "</ul>";
return $returnvar;
}
//use wp array walker to enable hierarchical display
public function generate_wp_radio($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
if($args['show_option_all_sf']=="")
{
$show_option_all = $labels->all_items != "" ? $labels->all_items : 'All ' . $labels->name;
}
else
{
$show_option_all = $args['show_option_all_sf'];
}
$checked = ($defaultval=="0") ? " checked='checked'" : "";
$returnvar = '<ul>';
$returnvar .= '<li>'."<label><input type='radio' name='".esc_attr($args['sf_name'])."[]' value='0'$checked /> ".$show_option_all."</label>".'</li>';
$returnvar .= walk_taxonomy('radio', $args);
$returnvar .= "</ul>";
return $returnvar;
}
//generate generic form inputs for use elsewhere, such as post types and non taxonomy fields
public function generate_select($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$returnvar = "";
$returnvar .= '<select class="postform" name="'.SF_FPRE.$name.'">';
if(isset($labels))
{
if($labels->all_items!="")
{//check to see if all items has been registered in field then use this label
$returnvar .= '<option class="level-0" value="'.$defaultval.'">'.$labels->all_items.'</option>';
}
else
{//check to see if all items has been registered in field then use this label with prefix of "All"
$returnvar .= '<option class="level-0" value="'.$defaultval.'">All '.$labels->name.'</option>';
}
}
foreach($dropdata as $dropdown)
{
$selected = "";
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
$noselected = count($defaults);
if(($noselected==1)&&(is_array($defaults))) //there should never be more than 1 default in a select, if there are then don't set any, user is obviously searching multiple values, in the case of a select this must be "all"
{
foreach($defaults as $defaultid)
{
if($defaultid==$dropdown->term_id)
{
$selected = ' selected="selected"';
}
}
}
}
$returnvar .= '<option class="level-0" value="'.$dropdown->term_id.'"'.$selected.'>'.$dropdown->cat_name.'</option>';
}
$returnvar .= "</select>";
return $returnvar;
}
public function generate_checkbox($dropdata, $name, $currentid = 0, $labels = null, $defaultval = '')
{
$returnvar = '<ul>';
foreach($dropdata as $dropdown)
{
$checked = "";
//check a default has been set
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
$noselected = count($defaults);
if(($noselected>0)&&(is_array($defaults)))
{
foreach($defaults as $defaultid)
{
if($defaultid==$dropdown->term_id)
{
$checked = ' checked="checked"';
}
}
}
}
$returnvar .= '<li class="cat-item"><label><input class="postform cat-item" type="checkbox" name="'.esc_attr(SF_FPRE.$name).'[]" value="'.esc_attr($dropdown->term_id).'"'.$checked.'> '.$dropdown->cat_name.'</label></li>';
}
$returnvar .= '</ul>';
return $returnvar;
}
public function generate_radio($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$returnvar = '<ul>';
if(isset($labels))
{
$checked = "";
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
$noselected = count($defaults);
if($noselected==0)
{
$checked = ' checked="checked"';
}
else if($noselected==1)
{
if($this->defaults[SF_FPRE.$name][0]==$defaultval)
{
$checked = ' checked="checked"';
}
}
}
else
{
$checked = ' checked="checked"';
}
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
if(count($defaults)>1)
{//then we are dealing with multiple defaults - this means mutliple radios are selected, this is only possible with "ALL" so set as default.
$checked = ' checked="checked"';
}
}
$all_items_name = "";
if($labels->all_items!="")
{//check to see if all items has been registered in field then use this label
$all_items_name = $labels->all_items;
}
else
{//check to see if all items has been registered in field then use this label with prefix of "All"
$all_items_name = "All ".$labels->name;
}
$returnvar .= '<li class="cat-item"><label><input class="postform" type="radio" name="'.esc_attr(SF_FPRE.$name).'[]" value="'.esc_attr($defaultval).'"'.$checked.'> '.$all_items_name.'</label></li>';
}
foreach($dropdata as $dropdown)
{
$checked = "";
//check a default has been set
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
$noselected = count($defaults);
if(($noselected==1)&&(is_array($defaults)))
{
foreach($defaults as $defaultid)
{
if($defaultid==$dropdown->term_id)
{
$checked = ' checked="checked"';
}
}
}
}
$returnvar .= '<li class="cat-item"><label><input class="postform" type="radio" name="'.esc_attr(SF_FPRE.$name).'[]" value="'.esc_attr($dropdown->term_id).'"'.$checked.'> '.$dropdown->cat_name.'</label></li>';
}
$returnvar .= '</ul>';
return $returnvar;
}
public function generate_date($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
{
$returnvar = '';
$current_date = '';
//check a default has been set - upto two possible vars for array
if(isset($this->defaults[SF_FPRE.$name]))
{
$defaults = $this->defaults[SF_FPRE.$name];
$noselected = count($defaults);
if(($noselected>0)&&(is_array($defaults)))
{
$current_date = $defaults[$currentid];
}
}
$returnvar .= '<input class="postform" type="date" name="'.esc_attr(SF_FPRE.$name).'[]" value="'. esc_attr($current_date) .'" />';
return $returnvar;
}
}
}
function walk_taxonomy( $type = "checkbox", $args = array() ) {
$args['walker'] = new Taxonomy_Walker($type, $args['sf_name']);
$output = wp_list_categories($args);
if ( $output ){
return $output;
}
}
if ( class_exists( 'SearchAndFilter' ) )
{
global $SearchAndFilter;
$SearchAndFilter = new SearchAndFilter();
}
/*
* Includes
*/
// classes
require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-list-table.php");
require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-taxonomy-walker.php");
// admin screens & plugin mods
require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-admin.php");
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment