Search & Filter - Version 1.2.2

Version Description

  • Added support for multi selects - use multiselect as the type for your field
  • Added support for AND & OR operators when using checkboxes or multiselects - use the operators argument with allowed values of and & or
  • Force load search template when search is blank, don't include when search field is not included in shortcode
  • Fixed an issue with navigation disappearing when using post_types
Download this release

Release Info

Developer DesignsAndCode
Plugin Icon 128x128 Search & Filter
Version 1.2.2
Comparing to
See all releases

Code changes from version 1.2.1 to 1.2.2

Files changed (3) hide show
  1. of-taxonomy-walker.php +103 -41
  2. readme.txt +12 -3
  3. search-filter.php +332 -179
of-taxonomy-walker.php CHANGED
@@ -5,6 +5,9 @@ class Taxonomy_Walker extends Walker_Category {
5
 
6
  private $type = '';
7
  private $defaults = array();
 
 
 
8
 
9
  function __construct($type = 'checkbox', $defaults = array()) {
10
  // fetch the list of term ids for the given post
@@ -130,51 +133,15 @@ class Taxonomy_Walker extends Walker_Category {
130
  }
131
  }
132
 
133
- $link = "<label><input type='".$this->type."' name='".$name."[]' value='".$cat_id."'".$checked." /> ".$cat_name."</label>";
134
 
135
 
136
- /*if ( !empty($current_category) ) {
137
- $_current_category = get_term( $current_category, $category->taxonomy );
138
- if ( $category->term_id == $current_category )
139
- $class .= ' current-cat';
140
- elseif ( $category->term_id == $_current_category->parent )
141
- $class .= ' current-cat-parent';
142
- }*/
143
-
144
-
145
- if ( !empty($feed_image) || !empty($feed) ) {
146
- $link .= ' ';
147
-
148
- if ( empty($feed_image) )
149
- $link .= '(';
150
-
151
- $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) ) . '"';
152
-
153
- if ( empty($feed) ) {
154
- $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
155
- } else {
156
- $title = ' title="' . $feed . '"';
157
- $alt = ' alt="' . $feed . '"';
158
- $name = $feed;
159
- $link .= $title;
160
- }
161
-
162
- $link .= '>';
163
-
164
- if ( empty($feed_image) )
165
- $link .= $name;
166
- else
167
- $link .= "<img src='$feed_image'$alt$title" . ' />';
168
-
169
- $link .= '</a>';
170
-
171
- if ( empty($feed_image) )
172
- $link .= ')';
173
- }
174
-
175
  if ( !empty($show_count) )
176
  $link .= ' (' . intval($category->count) . ')';
177
-
 
 
 
178
  if ( 'list' == $args['style'] ) {
179
  $output .= "\t<li";
180
  $class = 'cat-item cat-item-' . $category->term_id;
@@ -191,6 +158,82 @@ class Taxonomy_Walker extends Walker_Category {
191
  $output .= "\t$link<br />\n";
192
  }
193
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
 
196
  }
@@ -211,6 +254,13 @@ class Taxonomy_Walker extends Walker_Category {
211
 
212
  $output .= "</li>\n";
213
  }
 
 
 
 
 
 
 
214
  }
215
 
216
  function start_lvl( &$output, $depth = 0, $args = array() )
@@ -232,6 +282,14 @@ class Taxonomy_Walker extends Walker_Category {
232
  $indent = str_repeat("\t", $depth);
233
  $output .= "$indent<ul class='children'>\n";
234
  }
 
 
 
 
 
 
 
 
235
  }
236
 
237
  function end_lvl( &$output, $depth = 0, $args = array() ) {
@@ -251,6 +309,10 @@ class Taxonomy_Walker extends Walker_Category {
251
  $indent = str_repeat("\t", $depth);
252
  $output .= "$indent</ul>\n";
253
  }
 
 
 
 
254
  }
255
  }
256
 
5
 
6
  private $type = '';
7
  private $defaults = array();
8
+ private $multidepth = 0; //manually calculate depth on multiselects
9
+ private $multilastid = 0; //manually calculate depth on multiselects
10
+ private $multilastdepthchange = 0; //manually calculate depth on multiselects
11
 
12
  function __construct($type = 'checkbox', $defaults = array()) {
13
  // fetch the list of term ids for the given post
133
  }
134
  }
135
 
136
+ $link = "<label><input type='".$this->type."' name='".$name."[]' value='".$cat_id."'".$checked." /> ".$cat_name;
137
 
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  if ( !empty($show_count) )
140
  $link .= ' (' . intval($category->count) . ')';
141
+
142
+
143
+ $link .= "</label>";
144
+
145
  if ( 'list' == $args['style'] ) {
146
  $output .= "\t<li";
147
  $class = 'cat-item cat-item-' . $category->term_id;
158
  $output .= "\t$link<br />\n";
159
  }
160
  }
161
+ else if($this->type=="multiselect")
162
+ {
163
+ extract($args);
164
+
165
+ $cat_name = esc_attr( $category->name );
166
+ $cat_id = esc_attr( $category->term_id );
167
+ $cat_name = apply_filters( 'list_cats', $cat_name, $category );
168
+
169
+ //check a default has been set
170
+ $checked = "";
171
+ if($defaults)
172
+ {
173
+ $noselected = count($this->defaults);
174
+
175
+ if(($noselected>0)&&(is_array($defaults)))
176
+ {
177
+ foreach($defaults as $defaultid)
178
+ {
179
+ if($defaultid==$cat_id)
180
+ {
181
+ $checked = ' selected="selected"';
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
+
188
+ /* Custom depth calculations! :/ */
189
+ if($category->parent == 0)
190
+ {//then this has no parent so reset depth
191
+ $this->multidepth = 0;
192
+ }
193
+ else if($category->parent == $this->multilastid)
194
+ {
195
+ $this->multidepth++;
196
+ $this->multilastdepthchange = $this->multilastid;
197
+ }
198
+ else if($category->parent == $this->multilastdepthchange)
199
+ {//then this is also a child with the same parent so don't change depth
200
+
201
+ }
202
+ else
203
+ {//then this has a different parent so must be lower depth
204
+ if($this->multidepth>0)
205
+ {
206
+ $this->multidepth--;
207
+ }
208
+ }
209
+
210
+ $pad = str_repeat('&nbsp;', $this->multidepth * 3);
211
+ $link = "<option class=\"level-".$this->multidepth."\" value='".$cat_id."'$checked />".$pad.$cat_name;
212
+
213
+ if ( !empty($show_count) )
214
+ $link .= '&nbsp;&nbsp;(' . intval($category->count) . ')';
215
+
216
+
217
+ $link .= "</option>";
218
+ $output .= "\t$link\n";
219
+
220
+
221
+ $this->multilastid = $cat_id;
222
+
223
+
224
+ /*
225
+ $pad = str_repeat('&nbsp;', $depth * 3);
226
+
227
+ $output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\"";
228
+ $cat_name = apply_filters('list_cats', $category->name, $category);
229
+ if ( $category->term_id == $args['selected'] )
230
+ $output .= ' selected="selected"';
231
+ $output .= '>';
232
+ $output .= $pad.$cat_name;
233
+ if ( $args['show_count'] )
234
+ $output .= '&nbsp;&nbsp;('. $category->count .')';
235
+ $output .= "</option>\n";*/
236
+ }
237
 
238
 
239
  }
254
 
255
  $output .= "</li>\n";
256
  }
257
+ else if($this->type=="multiselect")
258
+ {
259
+ if ( 'list' != $args['style'] )
260
+ return;
261
+
262
+ $output .= "</option>\n";
263
+ }
264
  }
265
 
266
  function start_lvl( &$output, $depth = 0, $args = array() )
282
  $indent = str_repeat("\t", $depth);
283
  $output .= "$indent<ul class='children'>\n";
284
  }
285
+ else if($this->type=="multiselect")
286
+ {
287
+ /*if ( 'list' != $args['style'] )
288
+ return;
289
+
290
+ $indent = str_repeat("\t", $depth);
291
+ $output .= "$indent<ul class='children'>\n";*/
292
+ }
293
  }
294
 
295
  function end_lvl( &$output, $depth = 0, $args = array() ) {
309
  $indent = str_repeat("\t", $depth);
310
  $output .= "$indent</ul>\n";
311
  }
312
+ else if($this->type=="multiselect")
313
+ {
314
+
315
+ }
316
  }
317
  }
318
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: category, filter, taxonomy, search, wordpress, post type, post date
5
  Requires at least: 3.5
6
  Tested up to: 3.8
7
- Stable tag: 1.2.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -34,6 +34,15 @@ The documentation has been updated to include examples almost all configurable o
34
 
35
  == Changelog ==
36
 
 
 
 
 
 
 
 
 
 
37
  = 1.2.0 =
38
  * WARNING - this update includes some major changes to shortcode construction, do not upgrade until you have read how this will affect your setup - updating should be easy.
39
  * Renamed the `taxonomies` argument to `fields` - `taxonomies` is now no longer appropriate as this list contains field types other than taxonomies - this list now contains taxonomies, `post_type`, `post_date` and `search` - `taxonomies` as an argument is still supported however will be deprecated
@@ -88,9 +97,9 @@ The documentation has been updated to include examples almost all configurable o
88
 
89
  == Description ==
90
 
91
- Search & Filter is a simple search and filtering plugin for WordPress. It is essentially an advancement of the WordPress search box, adding taxonomy and post type filters to really refine your searches.
92
 
93
- You can search by Category, Tag, Custom Taxonomy, Post Type or any combination of these easily - you can even remove the search box and simply use it as a filtering system for your posts and pages. Taxonomies and Post Types can be displayed as dropdown selects, checkboxes or radio buttons.
94
 
95
  = Links =
96
 
4
  Tags: category, filter, taxonomy, search, wordpress, post type, post date
5
  Requires at least: 3.5
6
  Tested up to: 3.8
7
+ Stable tag: 1.2.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
34
 
35
  == Changelog ==
36
 
37
+ = 1.2.2 =
38
+ * Added support for multi selects - use `multiselect` as the type for your field
39
+ * Added support for AND & OR operators when using checkboxes or multiselects - use the `operators` argument with allowed values of `and` & `or`
40
+ * Force load search template when search is blank, don't include when search field is not included in shortcode
41
+ * Fixed an issue with navigation disappearing when using post_types
42
+
43
+ = 1.2.1 =
44
+ * Version Bump - bad commit
45
+
46
  = 1.2.0 =
47
  * WARNING - this update includes some major changes to shortcode construction, do not upgrade until you have read how this will affect your setup - updating should be easy.
48
  * Renamed the `taxonomies` argument to `fields` - `taxonomies` is now no longer appropriate as this list contains field types other than taxonomies - this list now contains taxonomies, `post_type`, `post_date` and `search` - `taxonomies` as an argument is still supported however will be deprecated
97
 
98
  == Description ==
99
 
100
+ Search & Filter is a simple search and filtering plugin for WordPress. It is essentially an advancement of the WordPress search box, adding taxonomy, post type and post date filters to really refine your searches.
101
 
102
+ You can search by Category, Tag, Custom Taxonomy, Post Type, Post Date or any combination of these easily - you can even remove the search box and simply use it as a filtering system for your posts and pages. Taxonomies and Post Types can be displayed as dropdown selects, checkboxes, radio buttons or multi selects.
103
 
104
  = Links =
105
 
search-filter.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://www.designsandcode.com/447/wordpress-search-filter-plugin-for
5
  Description: Search and Filtering system for Pages, Posts, Categories, Tags and Taxonomies
6
  Author: Designs & Code
7
  Author URI: http://www.designsandcode.com/
8
- Version: 1.2.0
9
  Text Domain: searchandfilter
10
  License: GPLv2
11
  */
@@ -16,7 +16,7 @@ License: GPLv2
16
  * Set up Plugin Globals
17
  */
18
  if (!defined('SEARCHANDFILTER_VERSION_NUM'))
19
- define('SEARCHANDFILTER_VERSION_NUM', '1.2.0');
20
 
21
  if (!defined('SEARCHANDFILTER_THEME_DIR'))
22
  define('SEARCHANDFILTER_THEME_DIR', ABSPATH . 'wp-content/themes/' . get_template());
@@ -51,8 +51,9 @@ if ( ! class_exists( 'SearchAndFilter' ) )
51
  {
52
  class SearchAndFilter
53
  {
54
- private $has_search_posted = false;
55
  private $hasqmark = false;
 
56
  private $urlparams = "/";
57
  private $searchterm = "";
58
  private $tagid = 0;
@@ -63,6 +64,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
63
 
64
  public function __construct()
65
  {
 
66
  // Set up reserved fields
67
  $this->frmreserved = array(SF_FPRE."category", SF_FPRE."search", SF_FPRE."post_tag", SF_FPRE."submitted", SF_FPRE."post_date", SF_FPRE."post_types");
68
  $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
@@ -78,6 +80,9 @@ if ( ! class_exists( 'SearchAndFilter' ) )
78
  add_shortcode('searchandfilter', array($this, 'shortcode'));
79
  add_filter('widget_text', 'do_shortcode');
80
 
 
 
 
81
  // Check the header to see if the form has been submitted
82
  add_action( 'get_header', array( $this, 'check_posts' ) );
83
 
@@ -85,7 +90,16 @@ if ( ! class_exists( 'SearchAndFilter' ) )
85
  add_action( 'wp_enqueue_scripts', array($this, 'of_enqueue_styles') );
86
  add_action( 'admin_enqueue_scripts', array($this, 'of_enqueue_admin_ss') );
87
  }
88
-
 
 
 
 
 
 
 
 
 
89
  public function of_enqueue_styles()
90
  {
91
  wp_enqueue_style( 'searchandfilter', SEARCHANDFILTER_PLUGIN_URL . '/style.css', false, 1.0, 'all' );
@@ -118,7 +132,10 @@ if ( ! class_exists( 'SearchAndFilter' ) )
118
  'hierarchical' => "",
119
  'hide_empty' => "",
120
  'order_by' => "",
121
- 'order_dir' => ""
 
 
 
122
  ), $atts));
123
 
124
  //init `fields`
@@ -135,6 +152,12 @@ if ( ! class_exists( 'SearchAndFilter' ) )
135
  $nofields = count($fields);
136
 
137
 
 
 
 
 
 
 
138
  //init `submitlabel`
139
  if($submitlabel!=null)
140
  {//then the old "submitlabel" has been supplied
@@ -192,6 +215,16 @@ if ( ! class_exists( 'SearchAndFilter' ) )
192
  $hide_empty = array("");
193
  }
194
 
 
 
 
 
 
 
 
 
 
 
195
  //init `order_by`
196
  if($order_by!="")
197
  {
@@ -212,10 +245,19 @@ if ( ! class_exists( 'SearchAndFilter' ) )
212
  $order_dir = array("");
213
  }
214
 
 
 
 
 
 
 
 
 
 
 
215
 
216
  //init `labels`
217
  $labels = explode(",",$headings);
218
- $showlabels = true;
219
  $labeldefault = "name";
220
 
221
  if(!is_array($labels))
@@ -239,7 +281,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
239
  }
240
 
241
 
242
- //Loop through Fields and set up default types
243
  for($i=0; $i<$nofields; $i++)
244
  {//loop through all fields
245
 
@@ -247,31 +289,26 @@ if ( ! class_exists( 'SearchAndFilter' ) )
247
  if(isset($types[$i]))
248
  {
249
  if($fields[$i] == 'post_date')
250
- {//force use of input for date
251
- if(($types[$i]=="date")||($types[$i]=="daterange"))
252
- {
253
- $types[$i] = $types[$i];
254
- }
255
- else
256
- {//set default for post_date to 'date'
257
-
258
- $types[$i] = "date";
259
- }
260
  }
261
  else
262
- {//everything else can use a standard form input - checkbox/radio/dropdown/list
263
- if(($types[$i]=="select")||($types[$i]=="wp_dropdown")||($types[$i]=="checkbox")||($types[$i]=="radio")||($types[$i]=="wp_list"))
264
- {
265
- $types[$i] = $types[$i];
266
- }
267
- else
268
- {
269
- $types[$i] = "select";
270
  }
271
  }
272
  }
273
  else
274
- {//set default if omitted
275
 
276
  if($fields[$i] == 'post_date')
277
  {
@@ -284,46 +321,17 @@ if ( ! class_exists( 'SearchAndFilter' ) )
284
  }
285
 
286
  //setup labels
287
- if(isset($labels[0]))
288
- {//these means at least one option has been set
289
-
290
- if(($labels[0]=="0")||($labels[0]=="none"))
291
- {
292
- if($i!=0)
293
- {
294
- $labels[$i] = ""; //then set all fields to blank ("no label").
295
- }
296
- }
297
- else
298
- {//then one or more options were passed, and the value wasn't "0" or "none"
299
-
300
- if(isset($labels[$i]))
301
- {
302
- //then use text supplied
303
- $labels[$i] = $labels[$i];
304
- }
305
- else
306
- {
307
- $labels[$i] = "";
308
- }
309
- }
310
- }
311
- else
312
- {//then it has been completely omitted so use default display
313
- $labels[$i] = "";
314
  }
315
 
 
316
  if(isset($order_by[$i]))
317
  {
318
-
319
- if(($order_by[$i]=="id")||($order_by[$i]=="name")||($order_by[$i]=="slug")||($order_by[$i]=="count")||($order_by[$i]=="term_group"))
320
  {
321
- //then use text supplied
322
- $order_by[$i] = $order_by[$i];
323
- }
324
- else
325
- {
326
- $order_by[$i] = "name"; //else use default - possible typo or use of unknown value
327
  }
328
  }
329
  else
@@ -333,19 +341,27 @@ if ( ! class_exists( 'SearchAndFilter' ) )
333
 
334
  if(isset($order_dir[$i]))
335
  {
336
- if(($order_dir[$i]=="asc")||($order_dir[$i]=="desc"))
337
- {
338
- //then use text supplied
339
- $order_dir[$i] = $order_dir[$i];
340
  }
341
- else
 
 
 
 
 
 
 
 
342
  {
343
- $order_dir[$i] = "asc"; //else use default - possible typo or use of unknown value
344
  }
345
  }
346
  else
347
  {
348
- $order_dir[$i] = "asc"; //use default
349
  }
350
 
351
  }
@@ -353,7 +369,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
353
  //set all form defaults / dropdowns etc
354
  $this->set_defaults();
355
 
356
- return $this->get_search_filter_form($submit_label, $search_placeholder, $fields, $types, $labels, $hierarchical, $hide_empty, $post_types, $order_by, $order_dir, $class);
357
  }
358
 
359
 
@@ -368,29 +384,32 @@ if ( ! class_exists( 'SearchAndFilter' ) )
368
  {
369
  global $wp_query;
370
 
371
- if(isset($wp_query->query['post_types']))
372
  {
373
- $search_all = false;
374
-
375
- $post_types = explode("+",esc_attr(urlencode($wp_query->query['post_types'])));
376
- if(isset($post_types[0]))
377
  {
378
- if(count($post_types)==1)
 
 
 
379
  {
380
- if($post_types[0]=="all")
381
  {
382
- $search_all = true;
 
 
 
383
  }
384
  }
385
- }
386
- if($search_all)
387
- {
388
- $post_types = get_post_types( '', 'names' );
389
- $query->set('post_type', $post_types); //here we set the post types that we want WP to search
390
- }
391
- else
392
- {
393
- $query->set('post_type', $post_types); //here we set the post types that we want WP to search
394
  }
395
  }
396
 
@@ -398,15 +417,6 @@ if ( ! class_exists( 'SearchAndFilter' ) )
398
  }
399
 
400
 
401
-
402
-
403
- /**
404
- * Filter the SQL WHERE clause to limit the query to grabbing posts from the
405
- * past week.
406
- *
407
- * @param string $where SQL WHERE clause passed from the filter.
408
- * @return string Modified WHERE clause.
409
- */
410
  function limit_date_range_query( $where )
411
  {
412
  global $wp_query;
@@ -452,34 +462,37 @@ if ( ! class_exists( 'SearchAndFilter' ) )
452
  {
453
  global $wp_query;
454
 
455
- if(isset($wp_query->query['post_date']))
456
  {
457
- //get post dates into array
458
- $post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
459
-
460
- if(!empty($post_date))
461
  {
462
- //if there is more than 1 post date and the dates are not the same
463
- if (count($post_date) > 1 && $post_date[0] != $post_date[1])
 
 
464
  {
465
- if((!empty($post_date[0]))&&(!empty($post_date[1])))
 
466
  {
467
- // Attach hook to filter WHERE clause.
468
- add_filter('posts_where', array($this,'limit_date_range_query'));
469
-
470
- // Remove the filter after it is executed.
471
- add_action('posts_selection', array($this,'remove_limit_date_range_query'));
 
 
 
472
  }
473
- }
474
- else
475
- { //else we are dealing with one date or both dates are the same (so need to find posts for a single day)
476
-
477
- if (!empty($post_date[0]))
478
- {
479
- $post_time = strtotime($post_date[0]);
480
- $query->set('year', date('Y', $post_time));
481
- $query->set('monthnum', date('m', $post_time));
482
- $query->set('day', date('d', $post_time));
483
  }
484
  }
485
  }
@@ -496,30 +509,30 @@ if ( ! class_exists( 'SearchAndFilter' ) )
496
  global $wp_query;
497
 
498
  $categories = array();
499
- //if(is_category())
500
- //{
501
- if(isset($wp_query->query['category_name']))
 
 
 
 
 
502
  {
503
-
504
- $category_params = explode("+",esc_attr($wp_query->query['category_name']));
505
-
506
- foreach($category_params as $category_param)
507
  {
508
- $category = get_category_by_slug( $category_param );
509
- if(isset($category->cat_ID))
510
- {
511
- $categories[] = $category->cat_ID;
512
- }
513
  }
514
  }
515
- //}
 
516
  $this->defaults[SF_FPRE.'category'] = $categories;
517
 
518
 
519
  //grab search term for prefilling search input
520
  if(isset($wp_query->query['s']))
521
  {//!"�$%^&*()
522
- $this->searchterm = get_search_query();
523
  }
524
 
525
  //check to see if tag is set
@@ -528,7 +541,8 @@ if ( ! class_exists( 'SearchAndFilter' ) )
528
 
529
  if(isset($wp_query->query['tag']))
530
  {
531
- $tag_params = explode("+",esc_attr($wp_query->query['tag']));
 
532
 
533
  foreach($tag_params as $tag_param)
534
  {
@@ -553,7 +567,9 @@ if ( ! class_exists( 'SearchAndFilter' ) )
553
  if(in_array($key, $this->taxonomylist))
554
  {
555
  $taxslug = ($val);
556
- $tax_params = explode("+",esc_attr($taxslug));
 
 
557
 
558
  foreach($tax_params as $tax_param)
559
  {
@@ -585,18 +601,10 @@ if ( ! class_exists( 'SearchAndFilter' ) )
585
  $post_types = array();
586
  if(isset($wp_query->query['post_types']))
587
  {
588
- $post_types = explode("+",esc_attr(urlencode($wp_query->query['post_types'])));
589
  }
590
  $this->defaults[SF_FPRE.'post_types'] = $post_types;
591
-
592
- //now we may be on a taxonomy page
593
- /*if(is_tax())
594
- {
595
- $taxobj = get_queried_object();
596
- $taxid = $taxobj->term_id;
597
- $this->defaults[SF_FPRE.$taxobj->taxonomy] = $taxobj->term_id;
598
- }*/
599
-
600
  }
601
 
602
  /*
@@ -610,12 +618,12 @@ if ( ! class_exists( 'SearchAndFilter' ) )
610
  if($_POST[SF_FPRE.'submitted']==="1")
611
  {
612
  //set var to confirm the form was posted
613
- $this->has_search_posted = true;
614
  }
615
  }
616
-
617
  /* CATEGORIES */
618
- if((isset($_POST[SF_FPRE.'category']))&&($this->has_search_posted))
619
  {
620
  $the_post_cat = ($_POST[SF_FPRE.'category']);
621
 
@@ -634,7 +642,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
634
  {
635
  $cat = esc_attr($cat);
636
  $catobj = get_category($cat);
637
-
638
  if(isset($catobj->slug))
639
  {
640
  $catarr[] = $catobj->slug;
@@ -644,7 +652,26 @@ if ( ! class_exists( 'SearchAndFilter' ) )
644
 
645
  if(count($catarr)>0)
646
  {
647
- $categories = implode("+",$catarr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
 
649
  if(get_option('permalink_structure'))
650
  {
@@ -670,9 +697,9 @@ if ( ! class_exists( 'SearchAndFilter' ) )
670
  }
671
 
672
  /* SEARCH BOX */
673
- if((isset($_POST[SF_FPRE.'search']))&&($this->has_search_posted))
674
  {
675
- $this->searchterm = stripslashes($_POST[SF_FPRE.'search']);
676
 
677
  if($this->searchterm!="")
678
  {
@@ -686,11 +713,29 @@ if ( ! class_exists( 'SearchAndFilter' ) )
686
  $this->urlparams .= "&";
687
  }
688
  $this->urlparams .= "s=".urlencode($this->searchterm);
 
689
  }
690
  }
691
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
  /* TAGS */
693
- if((isset($_POST[SF_FPRE.'post_tag']))&&($this->has_search_posted))
694
  {
695
  $the_post_tag = ($_POST[SF_FPRE.'post_tag']);
696
 
@@ -703,6 +748,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
703
  {
704
  $post_tag = $the_post_tag;
705
  }
 
706
  $tagarr = array();
707
 
708
  foreach ($post_tag as $tag)
@@ -715,10 +761,29 @@ if ( ! class_exists( 'SearchAndFilter' ) )
715
  $tagarr[] = $tagobj->slug;
716
  }
717
  }
718
-
719
  if(count($tagarr)>0)
720
  {
721
- $tags = implode("+",$tagarr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
722
 
723
  if(!$this->hasqmark)
724
  {
@@ -736,9 +801,8 @@ if ( ! class_exists( 'SearchAndFilter' ) )
736
 
737
 
738
  /* POST TYPES */
739
- if((isset($_POST[SF_FPRE.'post_types']))&&($this->has_search_posted))
740
  {
741
-
742
  $the_post_types = ($_POST[SF_FPRE.'post_types']);
743
 
744
  //make the post an array for easy looping
@@ -763,8 +827,27 @@ if ( ! class_exists( 'SearchAndFilter' ) )
763
 
764
  if(count($post_types_arr)>0)
765
  {
766
- $post_types = implode("+",$post_types_arr);
767
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  if(!$this->hasqmark)
769
  {
770
  $this->urlparams .= "?";
@@ -781,7 +864,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
781
 
782
 
783
  /* POST DATE */
784
- if((isset($_POST[SF_FPRE.'post_date']))&&($this->has_search_posted))
785
  {
786
  $the_post_date = ($_POST[SF_FPRE.'post_date']);
787
 
@@ -854,13 +937,13 @@ if ( ! class_exists( 'SearchAndFilter' ) )
854
  //now we have dealt with the all the special case fields - search, tags, categories, post_types, post_date
855
 
856
  //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
857
- if($this->has_search_posted)
858
  {
859
  foreach($_POST as $key=>$val)
860
  {
861
  if(!in_array($key, $this->frmreserved))
862
- {//if the key is not in the reserved array (ie, on a custom taxonomy - not tags, categories, search term)
863
-
864
  // strip off all prefixes for custom fields - we just want to do a redirect - no processing
865
  if (strpos($key, SF_FPRE) === 0)
866
  {
@@ -890,10 +973,30 @@ if ( ! class_exists( 'SearchAndFilter' ) )
890
  $taxarr[] = $taxobj->slug;
891
  }
892
  }
893
-
 
894
  if(count($taxarr)>0)
895
  {
896
- $tags = implode("+",$taxarr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
897
 
898
  if(!$this->hasqmark)
899
  {
@@ -912,7 +1015,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
912
  }
913
 
914
 
915
- if($this->has_search_posted)
916
  {//if the search has been posted, redirect to the newly formed url with all the right params
917
 
918
  if($this->urlparams=="/")
@@ -923,7 +1026,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
923
  }
924
  }
925
 
926
- public function get_search_filter_form($submitlabel, $search_placeholder, $fields, $types, $labels, $hierarchical, $hide_empty, $post_types, $order_by, $order_dir, $class)
927
  {
928
  $returnvar = '';
929
 
@@ -944,7 +1047,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
944
  {
945
  foreach($post_types as $post_type)
946
  {
947
- $returnvar .= "<input type=\"hidden\" name=\"ofpost_types[]\" value=\"".$post_type."\" />";
948
  }
949
  }
950
  }
@@ -965,11 +1068,24 @@ if ( ! class_exists( 'SearchAndFilter' ) )
965
  $returnvar .= "<h4>".$labels[$i]."</h4>";
966
  }
967
  $clean_searchterm = (esc_attr($this->searchterm));
968
- $returnvar .= '<input type="text" name="ofsearch" placeholder="'.$search_placeholder.'" value="'.$clean_searchterm.'">';
 
969
  $returnvar .= '</li>';
970
  }
971
- else if($field == "post_types")
972
  {//build field array
 
 
 
 
 
 
 
 
 
 
 
 
973
 
974
  $returnvar .= $this->build_post_type_element($types, $labels, $post_types, $field, $i);
975
 
@@ -979,9 +1095,8 @@ if ( ! class_exists( 'SearchAndFilter' ) )
979
  $returnvar .= $this->build_post_date_element($labels, $i, $types, $field);
980
  }
981
  else
982
- {
983
-
984
- $returnvar .= $this->build_taxonomy_element($types, $labels, $field, $hierarchical, $hide_empty, $order_by, $order_dir, $i);
985
  }
986
  $i++;
987
 
@@ -1133,7 +1248,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1133
  }
1134
 
1135
  //gets all the data for the taxonomy then display as form element
1136
- function build_taxonomy_element($types, $labels, $taxonomy, $hierarchical, $hide_empty, $order_by, $order_dir, $i)
1137
  {
1138
  $returnvar = "";
1139
 
@@ -1142,14 +1257,14 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1142
  if($taxonomydata)
1143
  {
1144
  $returnvar .= "<li>";
1145
-
1146
  if($labels[$i]!="")
1147
  {
1148
  $returnvar .= "<h4>".$labels[$i]."</h4>";
1149
  }
1150
 
1151
  $args = array(
1152
- 'name' => 'of' . $taxonomy,
1153
  'taxonomy' => $taxonomy,
1154
  'hierarchical' => false,
1155
  'child_of' => 0,
@@ -1158,7 +1273,8 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1158
  'hide_empty' => true,
1159
  'order' => $order_dir[$i],
1160
  'orderby' => $order_by[$i],
1161
- 'show_option_none' => ''
 
1162
  );
1163
 
1164
  if(isset($hierarchical[$i]))
@@ -1177,6 +1293,14 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1177
  }
1178
  }
1179
 
 
 
 
 
 
 
 
 
1180
  $taxonomychildren = get_categories($args);
1181
 
1182
  if($types[$i]=="select")
@@ -1200,6 +1324,26 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1200
 
1201
  $returnvar .= $this->generate_wp_radio($args, $taxonomy, $this->tagid, $taxonomydata->labels);
1202
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1203
  $returnvar .= "</li>";
1204
  }
1205
 
@@ -1216,7 +1360,7 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1216
  {
1217
  $returnvar = '';
1218
  $args['show_option_all'] = $labels->all_items != "" ? $labels->all_items : 'All ' . $labels->name;
1219
-
1220
  if(isset($this->defaults[SF_FPRE.$name]))
1221
  {
1222
  $defaults = $this->defaults[SF_FPRE . $name];
@@ -1235,10 +1379,19 @@ if ( ! class_exists( 'SearchAndFilter' ) )
1235
  return $returnvar;
1236
  }
1237
 
 
 
 
 
 
 
 
 
 
 
1238
  //use wp array walker to enable hierarchical display
1239
  public function generate_wp_checkbox($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
1240
  {
1241
- $checked = ($defaultval=="0") ? " checked='checked'" : "";
1242
  $returnvar = '<ul>';
1243
  $returnvar .= walk_taxonomy('checkbox', $args);
1244
  $returnvar .= "</ul>";
5
  Description: Search and Filtering system for Pages, Posts, Categories, Tags and Taxonomies
6
  Author: Designs & Code
7
  Author URI: http://www.designsandcode.com/
8
+ Version: 1.2.2
9
  Text Domain: searchandfilter
10
  License: GPLv2
11
  */
16
  * Set up Plugin Globals
17
  */
18
  if (!defined('SEARCHANDFILTER_VERSION_NUM'))
19
+ define('SEARCHANDFILTER_VERSION_NUM', '1.2.2');
20
 
21
  if (!defined('SEARCHANDFILTER_THEME_DIR'))
22
  define('SEARCHANDFILTER_THEME_DIR', ABSPATH . 'wp-content/themes/' . get_template());
51
  {
52
  class SearchAndFilter
53
  {
54
+ private $has_form_posted = false;
55
  private $hasqmark = false;
56
+ private $hassearchquery = false;
57
  private $urlparams = "/";
58
  private $searchterm = "";
59
  private $tagid = 0;
64
 
65
  public function __construct()
66
  {
67
+
68
  // Set up reserved fields
69
  $this->frmreserved = array(SF_FPRE."category", SF_FPRE."search", SF_FPRE."post_tag", SF_FPRE."submitted", SF_FPRE."post_date", SF_FPRE."post_types");
70
  $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
80
  add_shortcode('searchandfilter', array($this, 'shortcode'));
81
  add_filter('widget_text', 'do_shortcode');
82
 
83
+ //force search template if `?s=` is in the url
84
+ add_filter( 'request', array($this, 'force_search_template') );
85
+
86
  // Check the header to see if the form has been submitted
87
  add_action( 'get_header', array( $this, 'check_posts' ) );
88
 
90
  add_action( 'wp_enqueue_scripts', array($this, 'of_enqueue_styles') );
91
  add_action( 'admin_enqueue_scripts', array($this, 'of_enqueue_admin_ss') );
92
  }
93
+
94
+ function force_search_template( $query_vars )
95
+ {
96
+ if( isset( $_GET['s'] ) && empty( $_GET['s'] ) ) {
97
+ $query_vars['s'] = " ";
98
+ }
99
+ return $query_vars;
100
+ }
101
+
102
+
103
  public function of_enqueue_styles()
104
  {
105
  wp_enqueue_style( 'searchandfilter', SEARCHANDFILTER_PLUGIN_URL . '/style.css', false, 1.0, 'all' );
132
  'hierarchical' => "",
133
  'hide_empty' => "",
134
  'order_by' => "",
135
+ 'show_count' => "",
136
+ 'order_dir' => "",
137
+ 'operators' => ""
138
+
139
  ), $atts));
140
 
141
  //init `fields`
152
  $nofields = count($fields);
153
 
154
 
155
+ // Force blank searches to be registered as a valid search and load the search template
156
+ /*if($force_search_template==1)
157
+ {
158
+ add_filter( 'request', array($this, 'force_blank_search') );
159
+ }*/
160
+
161
  //init `submitlabel`
162
  if($submitlabel!=null)
163
  {//then the old "submitlabel" has been supplied
215
  $hide_empty = array("");
216
  }
217
 
218
+ //init `show_count`
219
+ if($show_count!="")
220
+ {
221
+ $show_count = explode(",",$show_count);
222
+ }
223
+ else
224
+ {
225
+ $show_count = array();
226
+ }
227
+
228
  //init `order_by`
229
  if($order_by!="")
230
  {
245
  $order_dir = array("");
246
  }
247
 
248
+ //init `operators`
249
+ if($operators!="")
250
+ {
251
+ $operators = explode(",",$operators);
252
+ }
253
+ else
254
+ {
255
+ $operators = array("");
256
+ }
257
+
258
 
259
  //init `labels`
260
  $labels = explode(",",$headings);
 
261
  $labeldefault = "name";
262
 
263
  if(!is_array($labels))
281
  }
282
 
283
 
284
+ //Loop through Fields and set up default vars
285
  for($i=0; $i<$nofields; $i++)
286
  {//loop through all fields
287
 
289
  if(isset($types[$i]))
290
  {
291
  if($fields[$i] == 'post_date')
292
+ {//check for post date field
293
+
294
+ if(($types[$i]!="date")&&($types[$i]!="daterange"))
295
+ {//if not expected value
296
+
297
+ $types[$i] = "date"; //use default
298
+ }
 
 
 
299
  }
300
  else
301
+ {//everything else can use a standard form input - checkbox/radio/dropdown/list/multiselect
302
+
303
+ if(($types[$i]!="select")&&($types[$i]!="checkbox")&&($types[$i]!="radio")&&($types[$i]!="list")&&($types[$i]!="multiselect"))
304
+ {//no accepted type matched - non compatible type defined by user
305
+
306
+ $types[$i] = "select"; //use default
 
 
307
  }
308
  }
309
  }
310
  else
311
+ {//omitted, so set default
312
 
313
  if($fields[$i] == 'post_date')
314
  {
321
  }
322
 
323
  //setup labels
324
+ if(!isset($labels[$i]))
325
+ {
326
+ $labels[$i] = "";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  }
328
 
329
+
330
  if(isset($order_by[$i]))
331
  {
332
+ if(($order_by[$i]!="id")&&($order_by[$i]!="name")&&($order_by[$i]!="slug")&&($order_by[$i]!="count")&&($order_by[$i]!="term_group"))
 
333
  {
334
+ $order_by[$i] = "name"; //use default - possible typo or use of unknown value
 
 
 
 
 
335
  }
336
  }
337
  else
341
 
342
  if(isset($order_dir[$i]))
343
  {
344
+ if(($order_dir[$i]!="asc")&&($order_dir[$i]!="desc"))
345
+ {//then order_dir is not a wanted value
346
+
347
+ $order_dir[$i] = "asc"; //set to default
348
  }
349
+ }
350
+ else
351
+ {
352
+ $order_dir[$i] = "asc"; //use default
353
+ }
354
+
355
+ if(isset($operators[$i]))
356
+ {
357
+ if(($operators[$i]!="and")&&($operators[$i]!="or"))
358
  {
359
+ $operators[$i] = "and"; //else use default - possible typo or use of unknown value
360
  }
361
  }
362
  else
363
  {
364
+ $operators[$i] = "and"; //use default
365
  }
366
 
367
  }
369
  //set all form defaults / dropdowns etc
370
  $this->set_defaults();
371
 
372
+ 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, $class);
373
  }
374
 
375
 
384
  {
385
  global $wp_query;
386
 
387
+ if(($query->is_main_query())&&(!is_admin()))
388
  {
389
+ if(isset($wp_query->query['post_types']))
 
 
 
390
  {
391
+ $search_all = false;
392
+
393
+ $post_types = explode(",",esc_attr($wp_query->query['post_types']));
394
+ if(isset($post_types[0]))
395
  {
396
+ if(count($post_types)==1)
397
  {
398
+ if($post_types[0]=="all")
399
+ {
400
+ $search_all = true;
401
+ }
402
  }
403
  }
404
+ if($search_all)
405
+ {
406
+ $post_types = get_post_types( '', 'names' );
407
+ $query->set('post_type', $post_types); //here we set the post types that we want WP to search
408
+ }
409
+ else
410
+ {
411
+ $query->set('post_type', $post_types); //here we set the post types that we want WP to search
412
+ }
413
  }
414
  }
415
 
417
  }
418
 
419
 
 
 
 
 
 
 
 
 
 
420
  function limit_date_range_query( $where )
421
  {
422
  global $wp_query;
462
  {
463
  global $wp_query;
464
 
465
+ if(($query->is_main_query())&&(!is_admin()))
466
  {
467
+ if(isset($wp_query->query['post_date']))
 
 
 
468
  {
469
+ //get post dates into array
470
+ $post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
471
+
472
+ if(!empty($post_date))
473
  {
474
+ //if there is more than 1 post date and the dates are not the same
475
+ if (count($post_date) > 1 && $post_date[0] != $post_date[1])
476
  {
477
+ if((!empty($post_date[0]))&&(!empty($post_date[1])))
478
+ {
479
+ // Attach hook to filter WHERE clause.
480
+ add_filter('posts_where', array($this,'limit_date_range_query'));
481
+
482
+ // Remove the filter after it is executed.
483
+ add_action('posts_selection', array($this,'remove_limit_date_range_query'));
484
+ }
485
  }
486
+ else
487
+ { //else we are dealing with one date or both dates are the same (so need to find posts for a single day)
488
+
489
+ if (!empty($post_date[0]))
490
+ {
491
+ $post_time = strtotime($post_date[0]);
492
+ $query->set('year', date('Y', $post_time));
493
+ $query->set('monthnum', date('m', $post_time));
494
+ $query->set('day', date('d', $post_time));
495
+ }
496
  }
497
  }
498
  }
509
  global $wp_query;
510
 
511
  $categories = array();
512
+
513
+ if(isset($wp_query->query['category_name']))
514
+ {
515
+ $category_params = (preg_split("/[,\+ ]/", esc_attr($wp_query->query['category_name']))); //explode with 2 delims
516
+
517
+ //$category_params = explode("+",esc_attr($wp_query->query['category_name']));
518
+
519
+ foreach($category_params as $category_param)
520
  {
521
+ $category = get_category_by_slug( $category_param );
522
+ if(isset($category->cat_ID))
 
 
523
  {
524
+ $categories[] = $category->cat_ID;
 
 
 
 
525
  }
526
  }
527
+ }
528
+
529
  $this->defaults[SF_FPRE.'category'] = $categories;
530
 
531
 
532
  //grab search term for prefilling search input
533
  if(isset($wp_query->query['s']))
534
  {//!"�$%^&*()
535
+ $this->searchterm = trim(get_search_query());
536
  }
537
 
538
  //check to see if tag is set
541
 
542
  if(isset($wp_query->query['tag']))
543
  {
544
+ $tag_params = (preg_split("/[,\+ ]/", esc_attr($wp_query->query['tag']))); //explode with 2 delims
545
+ //$tag_params = explode("+",esc_attr($wp_query->query['tag']));
546
 
547
  foreach($tag_params as $tag_param)
548
  {
567
  if(in_array($key, $this->taxonomylist))
568
  {
569
  $taxslug = ($val);
570
+ //$tax_params = explode("+",esc_attr($taxslug));
571
+
572
+ $tax_params = (preg_split("/[,\+ ]/", esc_attr($taxslug))); //explode with 2 delims
573
 
574
  foreach($tax_params as $tax_param)
575
  {
601
  $post_types = array();
602
  if(isset($wp_query->query['post_types']))
603
  {
604
+ $post_types = explode(",",esc_attr($wp_query->query['post_types']));
605
  }
606
  $this->defaults[SF_FPRE.'post_types'] = $post_types;
607
+
 
 
 
 
 
 
 
 
608
  }
609
 
610
  /*
618
  if($_POST[SF_FPRE.'submitted']==="1")
619
  {
620
  //set var to confirm the form was posted
621
+ $this->has_form_posted = true;
622
  }
623
  }
624
+
625
  /* CATEGORIES */
626
+ if((isset($_POST[SF_FPRE.'category']))&&($this->has_form_posted))
627
  {
628
  $the_post_cat = ($_POST[SF_FPRE.'category']);
629
 
642
  {
643
  $cat = esc_attr($cat);
644
  $catobj = get_category($cat);
645
+
646
  if(isset($catobj->slug))
647
  {
648
  $catarr[] = $catobj->slug;
652
 
653
  if(count($catarr)>0)
654
  {
655
+ $operator = "+"; //default behaviour
656
+
657
+ //check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
658
+ if(isset($_POST[SF_FPRE.'category_operator']))
659
+ {
660
+ if($_POST[SF_FPRE.'category_operator']=="and")
661
+ {
662
+ $operator = "+";
663
+ }
664
+ else if($_POST[SF_FPRE.'category_operator']=="or")
665
+ {
666
+ $operator = ",";
667
+ }
668
+ else
669
+ {
670
+ $operator = "+";
671
+ }
672
+ }
673
+
674
+ $categories = implode($operator,$catarr);
675
 
676
  if(get_option('permalink_structure'))
677
  {
697
  }
698
 
699
  /* SEARCH BOX */
700
+ if((isset($_POST[SF_FPRE.'search']))&&($this->has_form_posted))
701
  {
702
+ $this->searchterm = trim(stripslashes($_POST[SF_FPRE.'search']));
703
 
704
  if($this->searchterm!="")
705
  {
713
  $this->urlparams .= "&";
714
  }
715
  $this->urlparams .= "s=".urlencode($this->searchterm);
716
+ $this->hassearchquery = true;
717
  }
718
  }
719
+ if(!$this->hassearchquery)
720
+ {
721
+ if((isset($_POST[SF_FPRE.'search_is_set']))&&($this->has_form_posted))
722
+ {//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
723
+
724
+ if(!$this->hasqmark)
725
+ {
726
+ $this->urlparams .= "?";
727
+ $this->hasqmark = true;
728
+ }
729
+ else
730
+ {
731
+ $this->urlparams .= "&";
732
+ }
733
+ $this->urlparams .= "s=";
734
+ }
735
+ }
736
+
737
  /* TAGS */
738
+ if((isset($_POST[SF_FPRE.'post_tag']))&&($this->has_form_posted))
739
  {
740
  $the_post_tag = ($_POST[SF_FPRE.'post_tag']);
741
 
748
  {
749
  $post_tag = $the_post_tag;
750
  }
751
+
752
  $tagarr = array();
753
 
754
  foreach ($post_tag as $tag)
761
  $tagarr[] = $tagobj->slug;
762
  }
763
  }
764
+
765
  if(count($tagarr)>0)
766
  {
767
+ $operator = "+"; //default behaviour
768
+
769
+ //check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
770
+ if(isset($_POST[SF_FPRE.'post_tag_operator']))
771
+ {
772
+ if($_POST[SF_FPRE.'post_tag_operator']=="and")
773
+ {
774
+ $operator = "+";
775
+ }
776
+ else if($_POST[SF_FPRE.'post_tag_operator']=="or")
777
+ {
778
+ $operator = ",";
779
+ }
780
+ else
781
+ {
782
+ $operator = "+";
783
+ }
784
+ }
785
+
786
+ $tags = implode($operator,$tagarr);
787
 
788
  if(!$this->hasqmark)
789
  {
801
 
802
 
803
  /* POST TYPES */
804
+ if((isset($_POST[SF_FPRE.'post_types']))&&($this->has_form_posted))
805
  {
 
806
  $the_post_types = ($_POST[SF_FPRE.'post_types']);
807
 
808
  //make the post an array for easy looping
827
 
828
  if(count($post_types_arr)>0)
829
  {
830
+ $operator = ","; //default behaviour
831
+
832
+ //check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
833
+ /*if(isset($_POST[SF_FPRE.'post_types_operator']))
834
+ {
835
+ if($_POST[SF_FPRE.'post_types_operator']=="and")
836
+ {
837
+ $operator = "+";
838
+ }
839
+ else if($_POST[SF_FPRE.'post_types_operator']=="or")
840
+ {
841
+ $operator = ",";
842
+ }
843
+ else
844
+ {
845
+ $operator = "+";
846
+ }
847
+ }*/
848
+
849
+ $post_types = implode($operator,$post_types_arr);
850
+
851
  if(!$this->hasqmark)
852
  {
853
  $this->urlparams .= "?";
864
 
865
 
866
  /* POST DATE */
867
+ if((isset($_POST[SF_FPRE.'post_date']))&&($this->has_form_posted))
868
  {
869
  $the_post_date = ($_POST[SF_FPRE.'post_date']);
870
 
937
  //now we have dealt with the all the special case fields - search, tags, categories, post_types, post_date
938
 
939
  //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
940
+ if($this->has_form_posted)
941
  {
942
  foreach($_POST as $key=>$val)
943
  {
944
  if(!in_array($key, $this->frmreserved))
945
+ {//if the key is not in the reserved array (ie, on a custom taxonomy - not tags, categories, search term, post type & post date)
946
+
947
  // strip off all prefixes for custom fields - we just want to do a redirect - no processing
948
  if (strpos($key, SF_FPRE) === 0)
949
  {
973
  $taxarr[] = $taxobj->slug;
974
  }
975
  }
976
+
977
+
978
  if(count($taxarr)>0)
979
  {
980
+ $operator = "+"; //default behaviour
981
+
982
+ //check to see if an operator has been specified - only applies with fields that use multiple selects such as checkboxes or multi selects
983
+ if(isset($_POST[SF_FPRE.$key.'_operator']))
984
+ {
985
+ if($_POST[SF_FPRE.$key.'_operator']=="and")
986
+ {
987
+ $operator = "+";
988
+ }
989
+ else if($_POST[SF_FPRE.$key.'_operator']=="or")
990
+ {
991
+ $operator = ",";
992
+ }
993
+ else
994
+ {
995
+ $operator = "+";
996
+ }
997
+ }
998
+
999
+ $tags = implode($operator,$taxarr);
1000
 
1001
  if(!$this->hasqmark)
1002
  {
1015
  }
1016
 
1017
 
1018
+ if($this->has_form_posted)
1019
  {//if the search has been posted, redirect to the newly formed url with all the right params
1020
 
1021
  if($this->urlparams=="/")
1026
  }
1027
  }
1028
 
1029
+ public function get_search_filter_form($submitlabel, $search_placeholder, $fields, $types, $labels, $hierarchical, $hide_empty, $show_count, $post_types, $order_by, $order_dir, $operators, $class)
1030
  {
1031
  $returnvar = '';
1032
 
1047
  {
1048
  foreach($post_types as $post_type)
1049
  {
1050
+ $returnvar .= "<input type=\"hidden\" name=\"".SF_FPRE."post_types[]\" value=\"".$post_type."\" />";
1051
  }
1052
  }
1053
  }
1068
  $returnvar .= "<h4>".$labels[$i]."</h4>";
1069
  }
1070
  $clean_searchterm = (esc_attr($this->searchterm));
1071
+ $returnvar .= '<input type="text" name="'.SF_FPRE.'search" placeholder="'.$search_placeholder.'" value="'.$clean_searchterm.'">';
1072
+ $returnvar .= "<input type=\"hidden\" name=\"".SF_FPRE."search_is_set\" value=\"1\" />";
1073
  $returnvar .= '</li>';
1074
  }
1075
+ else if($field == "post_types") //a post can only every have 1 type, so checkboxes & multiselects will always be "OR"
1076
  {//build field array
1077
+
1078
+ //check to see if operator is set for this field
1079
+ /*if(isset($operators[$i]))
1080
+ {
1081
+ $operators[$i] = strtolower($operators[$i]);
1082
+
1083
+ if(($operators[$i]=="and")||($operators[$i]=="or"))
1084
+ {
1085
+ $returnvar .= '<input type="hidden" name="'.SF_FPRE.$field.'_operator" value="'.$operators[$i].'" />';
1086
+ }
1087
+ }*/
1088
+
1089
 
1090
  $returnvar .= $this->build_post_type_element($types, $labels, $post_types, $field, $i);
1091
 
1095
  $returnvar .= $this->build_post_date_element($labels, $i, $types, $field);
1096
  }
1097
  else
1098
+ {
1099
+ $returnvar .= $this->build_taxonomy_element($types, $labels, $field, $hierarchical, $hide_empty, $show_count, $order_by, $order_dir, $operators, $i);
 
1100
  }
1101
  $i++;
1102
 
1248
  }
1249
 
1250
  //gets all the data for the taxonomy then display as form element
1251
+ function build_taxonomy_element($types, $labels, $taxonomy, $hierarchical, $hide_empty, $show_count, $order_by, $order_dir, $operators, $i)
1252
  {
1253
  $returnvar = "";
1254
 
1257
  if($taxonomydata)
1258
  {
1259
  $returnvar .= "<li>";
1260
+
1261
  if($labels[$i]!="")
1262
  {
1263
  $returnvar .= "<h4>".$labels[$i]."</h4>";
1264
  }
1265
 
1266
  $args = array(
1267
+ 'name' => SF_FPRE . $taxonomy,
1268
  'taxonomy' => $taxonomy,
1269
  'hierarchical' => false,
1270
  'child_of' => 0,
1273
  'hide_empty' => true,
1274
  'order' => $order_dir[$i],
1275
  'orderby' => $order_by[$i],
1276
+ 'show_option_none' => '',
1277
+ 'show_count' => '0'
1278
  );
1279
 
1280
  if(isset($hierarchical[$i]))
1293
  }
1294
  }
1295
 
1296
+ if(isset($show_count[$i]))
1297
+ {
1298
+ if($show_count[$i]==1)
1299
+ {
1300
+ $args['show_count'] = true;
1301
+ }
1302
+ }
1303
+
1304
  $taxonomychildren = get_categories($args);
1305
 
1306
  if($types[$i]=="select")
1324
 
1325
  $returnvar .= $this->generate_wp_radio($args, $taxonomy, $this->tagid, $taxonomydata->labels);
1326
  }
1327
+ else if($types[$i]=="multiselect")
1328
+ {
1329
+ $args['title_li'] = '';
1330
+ $args['defaults'] = $this->defaults[$args['name']];
1331
+ $args['show_option_all'] = 0;
1332
+
1333
+ $returnvar .= $this->generate_wp_multiselect($args, $taxonomy, $this->tagid, $taxonomydata->labels);
1334
+ }
1335
+
1336
+ //check to see if operator is set for this field
1337
+ if(isset($operators[$i]))
1338
+ {
1339
+ $operators[$i] = strtolower($operators[$i]);
1340
+
1341
+ if(($operators[$i]=="and")||($operators[$i]=="or"))
1342
+ {
1343
+ $returnvar .= '<input type="hidden" name="'.SF_FPRE.$taxonomy.'_operator" value="'.$operators[$i].'" />';
1344
+ }
1345
+ }
1346
+
1347
  $returnvar .= "</li>";
1348
  }
1349
 
1360
  {
1361
  $returnvar = '';
1362
  $args['show_option_all'] = $labels->all_items != "" ? $labels->all_items : 'All ' . $labels->name;
1363
+
1364
  if(isset($this->defaults[SF_FPRE.$name]))
1365
  {
1366
  $defaults = $this->defaults[SF_FPRE . $name];
1379
  return $returnvar;
1380
  }
1381
 
1382
+ //use wp array walker to enable hierarchical display
1383
+ public function generate_wp_multiselect($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
1384
+ {
1385
+ $returnvar = '<select multiple="multiple" name="'.$args['name'].'[]" class="postform">';
1386
+ $returnvar .= walk_taxonomy('multiselect', $args);
1387
+ $returnvar .= "</select>";
1388
+
1389
+ return $returnvar;
1390
+ }
1391
+
1392
  //use wp array walker to enable hierarchical display
1393
  public function generate_wp_checkbox($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
1394
  {
 
1395
  $returnvar = '<ul>';
1396
  $returnvar .= walk_taxonomy('checkbox', $args);
1397
  $returnvar .= "</ul>";