PluginProbe
Search & Filter / 1.2.2
Search & Filter v1.2.2
trunk 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9
search-filter / search-filter.php

search-filter.php in Search & Filter 1.2.2, at search-filter.php

1,635 lines 40.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Search & Filter
4 Plugin URI: http://www.designsandcode.com/447/wordpress-search-filter-plugin-for-taxonomies/
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 */
12
13 // TO DO - i18n http://codex.wordpress.org/I18n_for_WordPress_Developers
14
15 /*
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());
23
24 if (!defined('SEARCHANDFILTER_PLUGIN_NAME'))
25 define('SEARCHANDFILTER_PLUGIN_NAME', trim(dirname(plugin_basename(__FILE__)), '/'));
26
27 if (!defined('SEARCHANDFILTER_PLUGIN_DIR'))
28 define('SEARCHANDFILTER_PLUGIN_DIR', WP_PLUGIN_DIR . '/' . SEARCHANDFILTER_PLUGIN_NAME);
29
30 if (!defined('SEARCHANDFILTER_PLUGIN_URL'))
31 define('SEARCHANDFILTER_PLUGIN_URL', WP_PLUGIN_URL . '/' . SEARCHANDFILTER_PLUGIN_NAME);
32
33 if (!defined('SEARCHANDFILTER_BASENAME'))
34 define('SEARCHANDFILTER_BASENAME', plugin_basename(__FILE__));
35
36 if (!defined('SEARCHANDFILTER_VERSION_KEY'))
37 define('SEARCHANDFILTER_VERSION_KEY', 'searchandfilter_version');
38
39
40
41 //form prefix for plugin
42 if (!defined('SF_FPRE'))
43 define('SF_FPRE', 'of');
44
45 add_option(SEARCHANDFILTER_VERSION_KEY, SEARCHANDFILTER_VERSION_NUM);
46
47 /*
48 * Set up Plugin Globals
49 */
50 if ( ! class_exists( 'SearchAndFilter' ) )
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;
60 private $catid = 0;
61 private $defaults = array();
62 private $frmreserved = array();
63 private $taxonomylist = array();
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
71
72 //add query vars
73 add_filter('query_vars', array($this,'add_queryvars') );
74
75 //filter post type & date if it is set
76 add_filter('pre_get_posts', array($this,'filter_query_post_types'));
77 add_filter('pre_get_posts', array($this,'filter_query_post_date'));
78
79 // Add shortcode support for widgets
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
89 // Add styles
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' );
106 }
107 public function of_enqueue_admin_ss($hook)
108 {
109 if( 'toplevel_page_searchandfilter-settings' == $hook )
110 {
111 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
112 wp_enqueue_style( 'of_style', SEARCHANDFILTER_PLUGIN_URL.'/admin/style.css', false, 1.0, 'all' );
113 wp_enqueue_script( 'of_syntax_script', SEARCHANDFILTER_PLUGIN_URL.'/admin/syntax.highlight.min.js' );
114 }
115 }
116
117 public function shortcode($atts, $content = null)
118 {
119 // extract the attributes into variables
120 extract(shortcode_atts(array(
121
122 'fields' => null,
123 'taxonomies' => null, //will be deprecated - use `fields` instead
124 'submit_label' => null,
125 'submitlabel' => null, //will be deprecated - use `submit_label` instead
126 'search_placeholder' => "Search &hellip;",
127 'types' => "",
128 'type' => "", //will be deprecated - use `types` instead
129 'headings' => "",
130 'class' => "",
131 'post_types' => "",
132 'hierarchical' => "",
133 'hide_empty' => "",
134 'order_by' => "",
135 'show_count' => "",
136 'order_dir' => "",
137 'operators' => ""
138
139 ), $atts));
140
141 //init `fields`
142 if($fields!=null)
143 {
144 $fields = explode(",",$fields);
145 }
146 else
147 {
148 $fields = explode(",",$taxonomies);
149 }
150
151 $this->taxonomylist = $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
164
165 if($submit_label==null)
166 {
167 //then the new label has not been supplied so do nothing
168 $submit_label = $submitlabel;
169 }
170 else
171 {
172 //then the new label has been supplied so take the new label value
173 //$submit_label = $submit_label;
174 }
175 }
176 else if($submitlabel==null)
177 {
178 if($submit_label==null)
179 {//default value
180 $submit_label = "Submit";
181 }
182 }
183
184 //init `post_types`
185 if($post_types!="")
186 {
187 $post_types = explode(",",$post_types);
188 }
189 else
190 {
191 if(in_array("post_types", $fields))
192 {
193 $post_types = array("all");
194 }
195
196 }
197
198 //init `hierarchical`
199 if($hierarchical!="")
200 {
201 $hierarchical = explode(",",$hierarchical);
202 }
203 else
204 {
205 $hierarchical = array("");
206 }
207
208 //init `hide_empty`
209 if($hide_empty!="")
210 {
211 $hide_empty = explode(",",$hide_empty);
212 }
213 else
214 {
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 {
231 $order_by = explode(",",$order_by);
232 }
233 else
234 {
235 $order_by = array("");
236 }
237
238 //init `order_dir`
239 if($order_dir!="")
240 {
241 $order_dir = explode(",",$order_dir);
242 }
243 else
244 {
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))
264 {
265 $labels = array("default");
266 }
267
268 //init `types`
269 if($types!=null)
270 {
271 $types = explode(",",$types);
272 }
273 else
274 {
275 $types = explode(",",$type);
276 }
277
278 if(!is_array($types))
279 {
280 $types = array();
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
288 //set up types
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 {
315 $types[$i] = "date";
316 }
317 else
318 {
319 $types[$i] = "select";
320 }
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
338 {
339 $order_by[$i] = "name"; //use default
340 }
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 }
368
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
376 function add_queryvars( $qvars )
377 {
378 $qvars[] = 'post_types';
379 $qvars[] = 'post_date';
380 return $qvars;
381 }
382
383 function filter_query_post_types($query)
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
416 return $query;
417 }
418
419
420 function limit_date_range_query( $where )
421 {
422 global $wp_query;
423
424 //get post dates into array
425 $post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
426
427 if (count($post_date) > 1 && $post_date[0] != $post_date[1])
428 {
429 $date_query = array();
430
431 if (!empty($post_date[0]))
432 {
433 $date_query['after'] = date('Y-m-d 00:00:00', strtotime($post_date[0]));
434 }
435
436 if (!empty($post_date[1]))
437 {
438 $date_query['before'] = date('Y-m-d 23:59:59', strtotime($post_date[1]));
439 }
440
441 }
442
443 // Append fragment to WHERE clause to select posts newer than the past week.
444 $where .= " AND post_date >='" . $date_query['after'] . "' AND post_date <='" . $date_query['before'] . "'";
445
446 return $where;
447 }
448
449 /**
450 * Remove the filter limiting posts to the past week.
451 *
452 * Remove the filter after it runs so that it doesn't affect any other
453 * queries that might be performed on the same page (eg. Recent Posts
454 * widget).
455 */
456 function remove_limit_date_range_query()
457 {
458 remove_filter( 'posts_where', 'limit_date_range_query' );
459 }
460
461 function filter_query_post_date($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 }
499 }
500
501 return $query;
502 }
503
504 /*
505 * check to set defaults - to be called after the shortcodes have been init so we can grab the wanted list of fields
506 */
507 public function set_defaults()
508 {
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
539
540 $tags = array();
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 {
549 $tag = get_term_by("slug",$tag_param, "post_tag");
550 if(isset($tag->term_id))
551 {
552 $tags[] = $tag->term_id;
553 }
554 }
555 }
556
557 $this->defaults[SF_FPRE.'post_tag'] = $tags;
558
559 $taxs = array();
560 //loop through all the query vars
561 foreach($wp_query->query as $key=>$val)
562 {
563 if(!in_array(SF_FPRE.$key, $this->frmqreserved))
564 {//make sure the get is not a reserved get as they have already been handled above
565
566 //now check it is a desired key
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 {
576 $tax = get_term_by("slug",$tax_param, $key);
577
578 if(isset($tax->term_id))
579 {
580 $taxs[] = $tax->term_id;
581 }
582 }
583
584 $this->defaults[SF_FPRE.$key] = $taxs;
585 }
586 }
587 }
588
589 $post_date = array("","");
590 if(isset($wp_query->query['post_date']))
591 {
592 $post_date = explode("+", esc_attr(urlencode($wp_query->query['post_date'])));
593 if(count($post_date)==1)
594 {
595 $post_date[1] = "";
596 }
597 }
598 $this->defaults[SF_FPRE.'post_date'] = $post_date;
599
600
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 /*
611 * check to see if form has been submitted and handle vars
612 */
613
614 public function check_posts()
615 {
616 if(isset($_POST[SF_FPRE.'submitted']))
617 {
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
630 //make the post an array for easy looping
631 if(!is_array($_POST[SF_FPRE.'category']))
632 {
633 $post_cat[] = $the_post_cat;
634 }
635 else
636 {
637 $post_cat = $the_post_cat;
638 }
639 $catarr = array();
640
641 foreach ($post_cat as $cat)
642 {
643 $cat = esc_attr($cat);
644 $catobj = get_category($cat);
645
646 if(isset($catobj->slug))
647 {
648 $catarr[] = $catobj->slug;
649 //$catarr[] = $catobj->term_id;
650 }
651 }
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 {
678 //$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
679 $category_base = (get_option( 'category_base' )=="") ? "category" : get_option( 'category_base' );
680 $category_path = $category_base."/".$categories."/";
681 $this->urlparams .= $category_path;
682 }
683 else
684 {
685 if(!$this->hasqmark)
686 {
687 $this->urlparams .= "?";
688 $this->hasqmark = true;
689 }
690 else
691 {
692 $this->urlparams .= "&";
693 }
694 $this->urlparams .= "category_name=".$categories;
695 }
696 }
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 {
706 if(!$this->hasqmark)
707 {
708 $this->urlparams .= "?";
709 $this->hasqmark = true;
710 }
711 else
712 {
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
742 //make the post an array for easy looping
743 if(!is_array($_POST[SF_FPRE.'post_tag']))
744 {
745 $post_tag[] = $the_post_tag;
746 }
747 else
748 {
749 $post_tag = $the_post_tag;
750 }
751
752 $tagarr = array();
753
754 foreach ($post_tag as $tag)
755 {
756 $tag = esc_attr($tag);
757 $tagobj = get_tag($tag);
758
759 if(isset($tagobj->slug))
760 {
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 {
790 $this->urlparams .= "?";
791 $this->hasqmark = true;
792 }
793 else
794 {
795 $this->urlparams .= "&";
796 }
797 $this->urlparams .= "tag=".$tags;
798
799 }
800 }
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
809 if(!is_array($the_post_types))
810 {
811 $post_types_arr[] = $the_post_types;
812 }
813 else
814 {
815 $post_types_arr = $the_post_types;
816 }
817
818 $num_post_types = count($post_types_arr);
819
820 for($i=0; $i<$num_post_types; $i++)
821 {
822 if($post_types_arr[$i]=="0")
823 {
824 $post_types_arr[$i] = "all";
825 }
826 }
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 .= "?";
854 $this->hasqmark = true;
855 }
856 else
857 {
858 $this->urlparams .= "&";
859 }
860 $this->urlparams .= "post_types=".$post_types;
861
862 }
863 }
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
871 //make the post an array for easy looping
872 if(!is_array($the_post_date))
873 {
874 $post_date_arr[] = $the_post_date;
875 }
876 else
877 {
878 $post_date_arr = $the_post_date;
879 }
880
881 $num_post_date = count($post_date_arr);
882
883 for($i=0; $i<$num_post_date; $i++)
884 {
885 if($post_date_arr[$i]=="0")
886 {
887 $post_date_arr[$i] = "all";
888 }
889 }
890
891 if(count($post_date_arr)>0)
892 {
893 $post_date_count = count($post_date_arr);
894
895 if($post_date_count==2)
896 {//see if there are 2 elements in arr (second date range selector)
897
898 if(($post_date_arr[0]!="")&&($post_date_arr[1]==""))
899 {
900 $post_date = $post_date_arr[0];
901 }
902 else if($post_date_arr[1]=="")
903 {//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
904 unset($post_date_arr[1]);
905 }
906 else if($post_date_arr[0]=="")
907 {
908 $post_date = "+".$post_date_arr[1];
909 }
910 else
911 {
912 $post_date = implode("+",array_filter($post_date_arr));
913 }
914 }
915 else
916 {
917 $post_date = $post_date_arr[0];
918 }
919
920 if($post_date!="")
921 {
922 if(!$this->hasqmark)
923 {
924 $this->urlparams .= "?";
925 $this->hasqmark = true;
926 }
927 else
928 {
929 $this->urlparams .= "&";
930 }
931 $this->urlparams .= "post_date=".$post_date;
932 }
933 }
934 }
935
936
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 {
950 $key = substr($key, strlen(SF_FPRE));
951 }
952
953 $the_post_tax = $val;
954
955 //make the post an array for easy looping
956 if(!is_array($val))
957 {
958 $post_tax[] = $the_post_tax;
959 }
960 else
961 {
962 $post_tax = $the_post_tax;
963 }
964 $taxarr = array();
965
966 foreach ($post_tax as $tax)
967 {
968 $tax = esc_attr($tax);
969 $taxobj = get_term_by('id',$tax,$key);
970
971 if(isset($taxobj->slug))
972 {
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 {
1003 $this->urlparams .= "?";
1004 $this->hasqmark = true;
1005 }
1006 else
1007 {
1008 $this->urlparams .= "&";
1009 }
1010 $this->urlparams .= $key."=".$tags;
1011
1012 }
1013 }
1014 }
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=="/")
1022 {//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
1023 $this->urlparams .= "?s=";
1024 }
1025 wp_redirect( (home_url().$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
1033 $addclass = "";
1034 if($class!="")
1035 {
1036 $addclass = ' '.$class;
1037 }
1038
1039 $returnvar .= '
1040 <form action="" method="post" class="searchandfilter'.$addclass.'">
1041 <div>';
1042
1043 if(!in_array("post_types", $fields))
1044 {//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
1045
1046 if(($post_types!="")&&(is_array($post_types)))
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 }
1054 $returnvar .= '
1055 <ul>';
1056
1057 $i = 0;
1058
1059 foreach($fields as $field)
1060 {
1061 //special cases - post_types & post_date.. all others assumed regular wp taxonomy
1062
1063 if($field == "search")
1064 {
1065 $returnvar .= '<li>';
1066 if($labels[$i]!="")
1067 {
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
1092 }
1093 else if($field == 'post_date')
1094 {
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
1103 }
1104
1105 $returnvar .=
1106 '<li>
1107 <input type="hidden" name="'.SF_FPRE.'submitted" value="1">
1108 <input type="submit" value="'.$submitlabel.'">
1109 </li>';
1110
1111 $returnvar .= "</ul>";
1112 $returnvar .= '</div>
1113 </form>';
1114
1115 return $returnvar;
1116 }
1117
1118 ///////////////////////////////////////////////////////////
1119 function build_post_date_element($labels, $i, $types, $field)
1120 {
1121 $returnvar = "";
1122
1123 $taxonomychildren = array();
1124
1125 $taxonomychildren = (object)$taxonomychildren;
1126
1127 $returnvar .= "<li>";
1128
1129 if($labels[$i]!="")
1130 {
1131 $returnvar .= "<h4>".$labels[$i]."</h4>";
1132 }
1133
1134 $defaultval = "";
1135
1136 if($types[$i]=="date")
1137 {
1138 $returnvar .= $this->generate_date($taxonomychildren, $field, $this->tagid);
1139 }
1140 if($types[$i]=="daterange")
1141 {
1142 $returnvar .= $this->generate_date($taxonomychildren, $field, 0);
1143 $returnvar .= "</li><li>";
1144 $returnvar .= $this->generate_date($taxonomychildren, $field, 1);
1145 }
1146 $returnvar .= "</li>";
1147
1148 return $returnvar;
1149 }
1150
1151
1152 function build_post_type_element($types, $labels, $post_types, $field, $i)
1153 {
1154 $returnvar = "";
1155 $taxonomychildren = array();
1156 $post_type_count = count($post_types);
1157
1158 //then check the post types array
1159 if(is_array($post_types))
1160 {
1161 if(($post_type_count==1)&&($post_types[0]=="all"))
1162 {
1163 $args = array('public' => true);
1164 $output = 'object'; // names or objects, note names is the default
1165 $operator = 'and'; // 'and' or 'or'
1166
1167 $post_types_objs = get_post_types( $args, $output, $operator );
1168
1169 $post_types = array();
1170
1171 foreach ( $post_types_objs as $post_type )
1172 {
1173 if($post_type->name!="attachment")
1174 {
1175 $tempobject = array();
1176 $tempobject['term_id'] = $post_type->name;
1177 $tempobject['cat_name'] = $post_type->labels->name;
1178
1179 $taxonomychildren[] = (object)$tempobject;
1180
1181 $post_types[] = $post_type->name;
1182
1183 }
1184 }
1185 $post_type_count = count($post_types_objs);
1186
1187 }
1188 else
1189 {
1190 foreach($post_types as $post_type)
1191 {
1192 //var_dump(get_post_type_object( $post_type ));
1193 $post_type_data = get_post_type_object( $post_type );
1194
1195 if($post_type_data)
1196 {
1197 $tempobject = array();
1198 $tempobject['term_id'] = $post_type;
1199 $tempobject['cat_name'] = $post_type_data->labels->name;
1200
1201 $taxonomychildren[] = (object)$tempobject;
1202 }
1203 }
1204 }
1205 }
1206 $taxonomychildren = (object)$taxonomychildren;
1207
1208 $returnvar .= "<li>";
1209
1210 $post_type_labels = array();
1211 $post_type_labels['name'] = "Post Types";
1212 $post_type_labels['singular_name'] = "Post Type";
1213 $post_type_labels['search_items'] = "Search Post Types";
1214 $post_type_labels['all_items'] = "All Post Types";
1215
1216 $post_type_labels = (object)$post_type_labels;
1217
1218 if($labels[$i]!="")
1219 {
1220 $returnvar .= "<h4>".$labels[$i]."</h4>";
1221 }
1222
1223 if($post_type_count>0)
1224 {
1225 $defaultval = implode("+",$post_types);
1226 }
1227 else
1228 {
1229 $defaultval = "all";
1230 }
1231
1232 if($types[$i]=="select")
1233 {
1234 $returnvar .= $this->generate_select($taxonomychildren, $field, $this->tagid, $post_type_labels, $defaultval);
1235 }
1236 else if($types[$i]=="checkbox")
1237 {
1238
1239 $returnvar .= $this->generate_checkbox($taxonomychildren, $field, $this->tagid);
1240 }
1241 else if($types[$i]=="radio")
1242 {
1243 $returnvar .= $this->generate_radio($taxonomychildren, $field, $this->tagid, $post_type_labels, $defaultval);
1244 }
1245 $returnvar .= "</li>";
1246
1247 return $returnvar;
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
1255 $taxonomydata = get_taxonomy($taxonomy);
1256
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,
1271 'echo' => false,
1272 'hide_if_empty' => false,
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]))
1281 {
1282 if($hierarchical[$i]==1)
1283 {
1284 $args['hierarchical'] = true;
1285 }
1286 }
1287
1288 if(isset($hide_empty[$i]))
1289 {
1290 if($hide_empty[$i]==0)
1291 {
1292 $args['hide_empty'] = false;
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")
1307 {
1308
1309 $returnvar .= $this->generate_wp_dropdown($args, $taxonomy, $this->tagid, $taxonomydata->labels);
1310 }
1311 else if($types[$i]=="checkbox")
1312 {
1313 $args['title_li'] = '';
1314 $args['defaults'] = $this->defaults[$args['name']];
1315 $args['show_option_all'] = 0;
1316
1317 $returnvar .= $this->generate_wp_checkbox($args, $taxonomy, $this->tagid, $taxonomydata->labels);
1318 }
1319 else if($types[$i]=="radio")
1320 {
1321 $args['title_li'] = '';
1322 $args['defaults'] = $this->defaults[$args['name']];
1323 $args['show_option_all'] = 0;
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
1350 return $returnvar;
1351 }
1352
1353
1354 /*
1355 * Display various forms
1356 */
1357
1358 //use wp array walker to enable hierarchical display
1359 public function generate_wp_dropdown($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
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];
1367 if (is_array($defaults)) {
1368 if (count($defaults) == 1) {
1369 $args['selected'] = $defaults[0];
1370 }
1371 }
1372 else {
1373 $args['selected'] = $defaultval;
1374 }
1375 }
1376
1377 $returnvar .= wp_dropdown_categories($args);
1378
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>";
1398
1399 return $returnvar;
1400 }
1401
1402 //use wp array walker to enable hierarchical display
1403 public function generate_wp_radio($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
1404 {
1405 $checked = ($defaultval=="0") ? " checked='checked'" : "";
1406 $returnvar = '<ul>';
1407 $returnvar .= '<li>'."<label><input type='radio' name='".$args['name']."[]' value='0'$checked /> ".$labels->all_items."</label>".'</li>';
1408 $returnvar .= walk_taxonomy('radio', $args);
1409 $returnvar .= "</ul>";
1410
1411 return $returnvar;
1412 }
1413
1414 //generate generic form inputs for use elsewhere, such as post types and non taxonomy fields
1415 public function generate_select($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
1416 {
1417 $returnvar = "";
1418
1419 $returnvar .= '<select class="postform" name="'.SF_FPRE.$name.'">';
1420 if(isset($labels))
1421 {
1422 if($labels->all_items!="")
1423 {//check to see if all items has been registered in field then use this label
1424 $returnvar .= '<option class="level-0" value="'.$defaultval.'">'.$labels->all_items.'</option>';
1425 }
1426 else
1427 {//check to see if all items has been registered in field then use this label with prefix of "All"
1428 $returnvar .= '<option class="level-0" value="'.$defaultval.'">All '.$labels->name.'</option>';
1429 }
1430 }
1431
1432 foreach($dropdata as $dropdown)
1433 {
1434 $selected = "";
1435
1436 if(isset($this->defaults[SF_FPRE.$name]))
1437 {
1438 $defaults = $this->defaults[SF_FPRE.$name];
1439
1440 $noselected = count($defaults);
1441
1442 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"
1443 {
1444 foreach($defaults as $defaultid)
1445 {
1446 if($defaultid==$dropdown->term_id)
1447 {
1448 $selected = ' selected="selected"';
1449 }
1450 }
1451 }
1452 }
1453 $returnvar .= '<option class="level-0" value="'.$dropdown->term_id.'"'.$selected.'>'.$dropdown->cat_name.'</option>';
1454
1455 }
1456 $returnvar .= "</select>";
1457
1458 return $returnvar;
1459 }
1460
1461 public function generate_checkbox($dropdata, $name, $currentid = 0, $labels = null, $defaultval = '')
1462 {
1463 $returnvar = '<ul>';
1464
1465 foreach($dropdata as $dropdown)
1466 {
1467 $checked = "";
1468
1469 //check a default has been set
1470 if(isset($this->defaults[SF_FPRE.$name]))
1471 {
1472 $defaults = $this->defaults[SF_FPRE.$name];
1473
1474 $noselected = count($defaults);
1475
1476 if(($noselected>0)&&(is_array($defaults)))
1477 {
1478 foreach($defaults as $defaultid)
1479 {
1480 if($defaultid==$dropdown->term_id)
1481 {
1482 $checked = ' checked="checked"';
1483 }
1484 }
1485 }
1486 }
1487 $returnvar .= '<li class="cat-item"><label><input class="postform cat-item" type="checkbox" name="'.SF_FPRE.$name.'[]" value="'.$dropdown->term_id.'"'.$checked.'> '.$dropdown->cat_name.'</label></li>';
1488
1489 }
1490
1491 $returnvar .= '</ul>';
1492
1493 return $returnvar;
1494 }
1495
1496
1497 public function generate_radio($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
1498 {
1499 $returnvar = '<ul>';
1500
1501 if(isset($labels))
1502 {
1503 $checked = "";
1504 if(isset($this->defaults[SF_FPRE.$name]))
1505 {
1506 $defaults = $this->defaults[SF_FPRE.$name];
1507 $noselected = count($defaults);
1508
1509 if($noselected==0)
1510 {
1511 $checked = ' checked="checked"';
1512 }
1513 else if($noselected==1)
1514 {
1515 if($this->defaults[SF_FPRE.$name][0]==$defaultval)
1516 {
1517 $checked = ' checked="checked"';
1518 }
1519 }
1520 }
1521 else
1522 {
1523 $checked = ' checked="checked"';
1524 }
1525
1526 if(isset($this->defaults[SF_FPRE.$name]))
1527 {
1528 $defaults = $this->defaults[SF_FPRE.$name];
1529 if(count($defaults)>1)
1530 {//then we are dealing with multiple defaults - this means mutliple radios are selected, this is only possible with "ALL" so set as default.
1531 $checked = ' checked="checked"';
1532 }
1533 }
1534
1535 $all_items_name = "";
1536 if($labels->all_items!="")
1537 {//check to see if all items has been registered in field then use this label
1538 $all_items_name = $labels->all_items;
1539 }
1540 else
1541 {//check to see if all items has been registered in field then use this label with prefix of "All"
1542 $all_items_name = "All ".$labels->name;
1543 }
1544
1545 $returnvar .= '<li class="cat-item"><label><input class="postform" type="radio" name="'.SF_FPRE.$name.'[]" value="'.$defaultval.'"'.$checked.'> '.$all_items_name.'</label></li>';
1546 }
1547
1548 foreach($dropdata as $dropdown)
1549 {
1550 $checked = "";
1551
1552 //check a default has been set
1553 if(isset($this->defaults[SF_FPRE.$name]))
1554 {
1555 $defaults = $this->defaults[SF_FPRE.$name];
1556
1557 $noselected = count($defaults);
1558
1559 if(($noselected==1)&&(is_array($defaults)))
1560 {
1561 foreach($defaults as $defaultid)
1562 {
1563 if($defaultid==$dropdown->term_id)
1564 {
1565 $checked = ' checked="checked"';
1566 }
1567 }
1568 }
1569 }
1570 $returnvar .= '<li class="cat-item"><label><input class="postform" type="radio" name="'.SF_FPRE.$name.'[]" value="'.$dropdown->term_id.'"'.$checked.'> '.$dropdown->cat_name.'</label></li>';
1571
1572 }
1573
1574 $returnvar .= '</ul>';
1575
1576 return $returnvar;
1577 }
1578
1579 public function generate_date($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
1580 {
1581 $returnvar = '';
1582 $current_date = '';
1583 //check a default has been set - upto two possible vars for array
1584
1585 if(isset($this->defaults[SF_FPRE.$name]))
1586 {
1587 $defaults = $this->defaults[SF_FPRE.$name];
1588
1589 $noselected = count($defaults);
1590
1591 if(($noselected>0)&&(is_array($defaults)))
1592 {
1593 $current_date = $defaults[$currentid];
1594 }
1595 }
1596
1597 $returnvar .= '<input class="postform" type="date" name="'.SF_FPRE.$name.'[]" value="' . $current_date . '" />';
1598
1599 return $returnvar;
1600 }
1601 }
1602 }
1603
1604
1605 function walk_taxonomy( $type = "checkbox", $args = array() ) {
1606
1607 $args['walker'] = new Taxonomy_Walker($type, $args['name']);
1608
1609 $output = wp_list_categories($args);
1610 if ( $output )
1611 return $output;
1612 }
1613
1614
1615
1616
1617 if ( class_exists( 'SearchAndFilter' ) )
1618 {
1619 global $SearchAndFilter;
1620 $SearchAndFilter = new SearchAndFilter();
1621 }
1622
1623 /*
1624 * Includes
1625 */
1626
1627 // classes
1628 require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-list-table.php");
1629 require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-taxonomy-walker.php");
1630
1631 // admin screens & plugin mods
1632 require_once(SEARCHANDFILTER_PLUGIN_DIR."/of-admin.php");
1633
1634
1635 ?>