diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b20c392
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,93 @@
+# Created by .ignore support plugin (hsz.mobi)
+### VisualStudioCode template
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Mongo Explorer plugin:
+.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+### macOS template
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..484438e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,86 @@
+CHANGELOG
+=========
+
+All notable changes to this project will be documented in this file.
+
+
+### [Unreleased]
+ - Better translation support
+ - Add option permalink: no permalink on taxonomy filtering
+ - Add support meta: support to render and filter postmeta
+
+
+
+### 1.2.5
+ - Fixed a PHP error when setting defaults for taxonomies - many users did not see this but resulted in unexpected behaviour
+ - Fixed an error with post date sometimes being undefined for blank searches
+ - Added argument `empty_search_url` - when a users submits the search form without any search preferences selected they will be redirected to this URL
+ - Updated argument `add_search_param` - setting to `1` will force add a "?s=" to all urls generated by the plugin - this may help with the loading of search templates in some themes
+
+
+### 1.2.4
+ - Fixed a bug created in 1.2.3 when doing an empty search
+
+### 1.2.3
+ - Added arguement `all_items_labels` which allows for support for custom `all_items` labels in taxonomies, categories, post tags and post types when using `select` and `radio` types - the default text displaying "All Categories" for example can now be defined using `all_items_labels`
+ - Added `show_count` to arguments - this shows how many posts are in a particular term, in brackets after the term name - works only for categories, tags and taxonomies
+ - Fixed a bug when using when using "all post types" and it displaying no results
+ - Reverted behaviour from 1.2.2 - no longer force load search template when search is blank - let WP handle it again
+ - Added argument `add_search_param` - setting it to `1` will force a "?s=" or "&s=" to be added to the url even when the search is blank - in some circumstances this will force load the search template, instead of other WP templates, such as taxonomy or category templates
+
+### 1.2.2
+ - 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
+
+### 1.2.1
+ - Version Bump - bad commit
+
+### 1.2.0
+ - 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.
+ - 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
+ - Search box can now be positioned anywhere, simply include `search` in the fields list in the position desired. Upgrading from previous versions will cause you to lose your search box, simply include `search` in the fields list to show it again
+ - Drop support for `search` argument as no longer relevant - control display of search input by adding it to the `fields` list
+ - Labels have been completely rewritten - `label` has been renamed to `headings` to avoid confusion with internal taxonomy labels - the `headings` argument now allows for any text to be added and displayed as a heading for each field - this allows for much more flexibility and no longer uses internal taxonomy labels - to hide a label simply leave blank
+ - Added support for hierarchical taxonomies for all input types - checkbox, radio & select
+ - Added support for ordering of taxonomies - use `order_by` argument - allowed values are `id`, `name`, `slug`, `count`, `term_group`
+ - Added support for ordering direction of taxonomies - use `order_dir` argument - allowed values are 'asc' or 'desc'
+ - Added support to show or hide empty taxonomies - use `hide_empty` argument
+ - Added support for `search_placeholder`
+ - Updated `post_date` functionality to work with older versions of WP - can be displayed either as `date` or `daterange` - the `post_date` field uses the HTML 5 input type of `date` - browsers that do not support it will simply show a text box - a tutorial of integrating jquery for graceful degredation is in the works
+ - Renamed `submitlabel` to `submit_label` - `submitlabel` still works for now.
+ - Renamed `type` to `types` - `type` still works for now.
+ - Updated display of checkboxes and radio buttons, inputs are now wrapped in an unordered list which may affect your styling
+ - Various bug fixes
+ - Thanks to `bradaric` for help with hierarchical dropdown lists and date input types - https://github.com/bradaric
+
+### 1.1.3
+ - Added support for `post_date` to be displayed either as `date` or `daterange` (WP 3.7+) type.
+
+### 1.1.2
+ - Added support for all public and custom post types (the attachment post type is excluded) - all post types can be user searchable or predfined and hidden from the user. This allows for users to add multiple search widgets to their site which work on specific post types independantly from eachother.
+ - Added offical updated documentation, created and moved to Search & Filter Docs
+
+### 1.1.1
+ - Fixed: when submitting an empty `search/filter`, `"?s="` now gets appended to the url (an empty search) to force load a results page, previously this was redirecting to the homepage which does not work for many use cases
+
+### 1.1.0
+ - Added support for checkboxes and radio buttons, with the option to control this for each individual taxonomy.
+ - Added support to show or hide headings for each individual taxonomy.
+ - Added support to pass a class name through to Search & Filter widgets, this allows styling of different instances of Search & Filter
+ - Fixed problems with escaping output in search box
+Notice: This update will automatically add headings to taxonomy dropdowns, refer to usage and examples on how to disable them.
+
+### 1.0.3
+ - Added some documention & screenshots to plugin page
+
+### 1.0.2
+ - Version bump for WordPress plugins site
+
+### 1.0.1
+ - Updated to use `label->all_items` in taxonomy object for dropdowns before using `label->name`
+ - Notice: This update may cause some labels to break, ensure you have set up your taxonomy properly including setting `label->all_items`
+
+### 1.0.0
+ - Initial Release
diff --git a/README.md b/README.md
index 1436505..1b009bf 100644
--- a/README.md
+++ b/README.md
@@ -15,80 +15,7 @@ You can search by Category, Tag, Custom Taxonomy or any combination of these eas
## Changelog
-### 1.2.5
- - Fixed a PHP error when setting defaults for taxonomies - many users did not see this but resulted in unexpected behaviour
- - Fixed an error with post date sometimes being undefined for blank searches
- - Added argument `empty_search_url` - when a users submits the search form without any search preferences selected they will be redirected to this URL
- - Updated argument `add_search_param` - setting to `1` will force add a "?s=" to all urls generated by the plugin - this may help with the loading of search templates in some themes
-
-
-### 1.2.4
- - Fixed a bug created in 1.2.3 when doing an empty search
-
-### 1.2.3
- - Added arguement `all_items_labels` which allows for support for custom `all_items` labels in taxonomies, categories, post tags and post types when using `select` and `radio` types - the default text displaying "All Categories" for example can now be defined using `all_items_labels`
- - Added `show_count` to arguments - this shows how many posts are in a particular term, in brackets after the term name - works only for categories, tags and taxonomies
- - Fixed a bug when using when using "all post types" and it displaying no results
- - Reverted behaviour from 1.2.2 - no longer force load search template when search is blank - let WP handle it again
- - Added argument `add_search_param` - setting it to `1` will force a "?s=" or "&s=" to be added to the url even when the search is blank - in some circumstances this will force load the search template, instead of other WP templates, such as taxonomy or category templates
-
-### 1.2.2
- - 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
-
-### 1.2.1
- - Version Bump - bad commit
-
-### 1.2.0
- - 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.
- - 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
- - Search box can now be positioned anywhere, simply include `search` in the fields list in the position desired. Upgrading from previous versions will cause you to lose your search box, simply include `search` in the fields list to show it again
- - Drop support for `search` argument as no longer relevant - control display of search input by adding it to the `fields` list
- - Labels have been completely rewritten - `label` has been renamed to `headings` to avoid confusion with internal taxonomy labels - the `headings` argument now allows for any text to be added and displayed as a heading for each field - this allows for much more flexibility and no longer uses internal taxonomy labels - to hide a label simply leave blank
- - Added support for hierarchical taxonomies for all input types - checkbox, radio & select
- - Added support for ordering of taxonomies - use `order_by` argument - allowed values are `id`, `name`, `slug`, `count`, `term_group`
- - Added support for ordering direction of taxonomies - use `order_dir` argument - allowed values are 'asc' or 'desc'
- - Added support to show or hide empty taxonomies - use `hide_empty` argument
- - Added support for `search_placeholder`
- - Updated `post_date` functionality to work with older versions of WP - can be displayed either as `date` or `daterange` - the `post_date` field uses the HTML 5 input type of `date` - browsers that do not support it will simply show a text box - a tutorial of integrating jquery for graceful degredation is in the works
- - Renamed `submitlabel` to `submit_label` - `submitlabel` still works for now.
- - Renamed `type` to `types` - `type` still works for now.
- - Updated display of checkboxes and radio buttons, inputs are now wrapped in an unordered list which may affect your styling
- - Various bug fixes
- - Thanks to `bradaric` for help with hierarchical dropdown lists and date input types - https://github.com/bradaric
-
-### 1.1.3
- - Added support for `post_date` to be displayed either as `date` or `daterange` (WP 3.7+) type.
-
-### 1.1.2
- - Added support for all public and custom post types (the attachment post type is excluded) - all post types can be user searchable or predfined and hidden from the user. This allows for users to add multiple search widgets to their site which work on specific post types independantly from eachother.
- - Added offical updated documentation, created and moved to Search & Filter Docs
-
-### 1.1.1
- - Fixed: when submitting an empty `search/filter`, `"?s="` now gets appended to the url (an empty search) to force load a results page, previously this was redirecting to the homepage which does not work for many use cases
-
-### 1.1.0
- - Added support for checkboxes and radio buttons, with the option to control this for each individual taxonomy.
- - Added support to show or hide headings for each individual taxonomy.
- - Added support to pass a class name through to Search & Filter widgets, this allows styling of different instances of Search & Filter
- - Fixed problems with escaping output in search box
-Notice: This update will automatically add headings to taxonomy dropdowns, refer to usage and examples on how to disable them.
-
-### 1.0.3
- - Added some documention & screenshots to plugin page
-
-### 1.0.2
- - Version bump for WordPress plugins site
-
-### 1.0.1
- - Updated to use `label->all_items` in taxonomy object for dropdowns before using `label->name`
- - Notice: This update may cause some labels to break, ensure you have set up your taxonomy properly including setting `label->all_items`
-
-### 1.0.0
- - Initial Release
-
+see [CHANGELOG.md](CHANGELOG.md)
## License
- Released under the [GPL v2](http://www.gnu.org/licenses/gpl-2.0.html) License
diff --git a/of-admin.php b/of-admin.php
index b96b5fa..72ccd1a 100644
--- a/of-admin.php
+++ b/of-admin.php
@@ -47,7 +47,7 @@ function searchandfilter_settings()
echo '
Search & Filter is a simple search and filtering plugin for Wordpress brought to you by
Designs & Code .
It is essentially an advancement of the WordPress search box, adding taxonomy and post type filters to really refine your searches.
- 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.
+ 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, radio buttons or multiselects.
';
echo "Documentation ";
echo '
@@ -63,7 +63,7 @@ function searchandfilter_settings()
This will display a search box, a category dropdown and a tag dropdown. You can use the shortcode within posts/pages and widget areas.
- To use this within a theme file you simple need to call the `do_shortcode` function with the shortcode above within the theme file:
+ To use this within a theme file you simple need to call the `do_shorcode` function with the shortcode above within the theme file:
<?php echo do_shortcode( \'[searchandfilter taxonomies="category,post_tag"]\' ); ?>
';
@@ -161,4 +161,4 @@ function searchandfilter_plugin_action_links($links, $file)
return $links;
}
-?>
+?>
\ No newline at end of file
diff --git a/of-list-table.php b/of-list-table.php
index e69eb12..53c019d 100644
--- a/of-list-table.php
+++ b/of-list-table.php
@@ -199,7 +199,7 @@ function __construct()
"ID" => $counter,
"name" => "types",
"defaultval" => "select
",
- "options" => "Comma seperated list of any of the types found below: select checkbox radio
+ "options" => "Comma seperated list of any of the types found below: select checkbox radio multiselect
These types should only be used when the field is `post_date`: date daterange",
"info" => "The order of values in this comma seperated list needs to match the fields list."
);
diff --git a/of-taxonomy-walker.php b/of-taxonomy-walker.php
index b2054dc..5addf30 100644
--- a/of-taxonomy-walker.php
+++ b/of-taxonomy-walker.php
@@ -1,319 +1,319 @@
-term_ids = wp_get_post_terms( $post_id, $taxonomy, 'fields=ids' );
- //var_dump($this->term_ids);
-
- $this->type = $type;
- $this->defaults = $defaults;
- }
-
- function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
- /*$display = false;
-
- $id = $element->term_id;
-
- $display = true;
- if ( isset( $children_elements[ $id ] ) ) {
- // the current term has children
- foreach ( $children_elements[ $id ] as $child ) {
- if ( in_array( $child->term_id, $this->term_ids ) ) {
- // one of the term's children is in the list
- $display = true;
- // can stop searching now
- break;
- }
- }
- }
-
- if ( $display )*/
- parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
- }
-
-
- function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 )
- {
-
- if($this->type=="list")
- {
- extract($args);
-
- $cat_name = esc_attr( $category->name );
- $cat_name = apply_filters( 'list_cats', $cat_name, $category );
- $link = 'description) )
- $link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
- else
- $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
- $link .= '>';
- $link .= $cat_name . ' ';
-
- if ( !empty($feed_image) || !empty($feed) ) {
- $link .= ' ';
-
- if ( empty($feed_image) )
- $link .= '(';
-
- $link .= ' ';
-
- $link .= '';
-
- if ( empty($feed_image) )
- $link .= ')';
- }
-
- if ( !empty($show_count) )
- $link .= ' (' . intval($category->count) . ')';
-
- if ( 'list' == $args['style'] ) {
- $output .= "\tterm_id;
- if ( !empty($current_category) ) {
- $_current_category = get_term( $current_category, $category->taxonomy );
- if ( $category->term_id == $current_category )
- $class .= ' current-cat';
- elseif ( $category->term_id == $_current_category->parent )
- $class .= ' current-cat-parent';
- }
- $output .= ' class="' . $class . '"';
- $output .= ">$link\n";
- } else {
- $output .= "\t$link \n";
- }
- }
- else if(($this->type=="checkbox")||($this->type=="radio"))
- {
- extract($args);
-
- $cat_name = esc_attr( $category->name );
- $cat_id = esc_attr( $category->term_id );
- $cat_name = apply_filters( 'list_cats', $cat_name, $category );
-
- //check a default has been set
- $checked = "";
- if($defaults)
- {
- $noselected = count($this->defaults);
-
- if(($noselected>0)&&(is_array($defaults)))
- {
- foreach($defaults as $defaultid)
- {
- if($defaultid==$cat_id)
- {
- $checked = ' checked="checked"';
- }
- }
- }
- }
-
- $link = " ".$cat_name;
-
-
- if ( !empty($show_count) )
- $link .= ' (' . intval($category->count) . ')';
-
-
- $link .= " ";
-
- if ( 'list' == $args['style'] ) {
- $output .= "\t term_id;
- if ( !empty($current_category) ) {
- $_current_category = get_term( $current_category, $category->taxonomy );
- if ( $category->term_id == $current_category )
- $class .= ' current-cat';
- elseif ( $category->term_id == $_current_category->parent )
- $class .= ' current-cat-parent';
- }
- $output .= ' class="' . $class . '"';
- $output .= ">$link\n";
- } else {
- $output .= "\t$link \n";
- }
- }
- else if($this->type=="multiselect")
- {
- extract($args);
-
- $cat_name = esc_attr( $category->name );
- $cat_id = esc_attr( $category->term_id );
- $cat_name = apply_filters( 'list_cats', $cat_name, $category );
-
- //check a default has been set
- $checked = "";
- if($defaults)
- {
- $noselected = count($this->defaults);
-
- if(($noselected>0)&&(is_array($defaults)))
- {
- foreach($defaults as $defaultid)
- {
- if($defaultid==$cat_id)
- {
- $checked = ' selected="selected"';
- }
- }
- }
- }
-
-
- /* Custom depth calculations! :/ */
- if($category->parent == 0)
- {//then this has no parent so reset depth
- $this->multidepth = 0;
- }
- else if($category->parent == $this->multilastid)
- {
- $this->multidepth++;
- $this->multilastdepthchange = $this->multilastid;
- }
- else if($category->parent == $this->multilastdepthchange)
- {//then this is also a child with the same parent so don't change depth
-
- }
- else
- {//then this has a different parent so must be lower depth
- if($this->multidepth>0)
- {
- $this->multidepth--;
- }
- }
-
- $pad = str_repeat(' ', $this->multidepth * 3);
- $link = "multidepth."\" value='".$cat_id."'$checked />".$pad.$cat_name;
-
- if ( !empty($show_count) )
- $link .= ' (' . intval($category->count) . ')';
-
-
- $link .= " ";
- $output .= "\t$link\n";
-
-
- $this->multilastid = $cat_id;
-
-
- /*
- $pad = str_repeat(' ', $depth * 3);
-
- $output .= "\tterm_id."\"";
- $cat_name = apply_filters('list_cats', $category->name, $category);
- if ( $category->term_id == $args['selected'] )
- $output .= ' selected="selected"';
- $output .= '>';
- $output .= $pad.$cat_name;
- if ( $args['show_count'] )
- $output .= ' ('. $category->count .')';
- $output .= " \n";*/
- }
-
-
- }
-
- function end_el( &$output, $page, $depth = 0, $args = array() )
- {
- if($this->type=="list")
- {
- if ( 'list' != $args['style'] )
- return;
-
- $output .= " \n";
- }
- else if(($this->type=="checkbox")||($this->type=="radio"))
- {
- if ( 'list' != $args['style'] )
- return;
-
- $output .= "\n";
- }
- else if($this->type=="multiselect")
- {
- if ( 'list' != $args['style'] )
- return;
-
- $output .= "\n";
- }
- }
-
- function start_lvl( &$output, $depth = 0, $args = array() )
- {
-
- if($this->type=="list")
- {
- if ( 'list' != $args['style'] )
- return;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent\n";
- }
- else if(($this->type=="checkbox")||($this->type=="radio"))
- {
- if ( 'list' != $args['style'] )
- return;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent\n";
- }
- else if($this->type=="multiselect")
- {
- /*if ( 'list' != $args['style'] )
- return;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent\n";*/
- }
- }
-
- function end_lvl( &$output, $depth = 0, $args = array() ) {
- if($this->type=="list")
- {
- if ( 'list' != $args['style'] )
- return;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent \n";
- }
- else if(($this->type=="checkbox")||($this->type=="radio"))
- {
- if ( 'list' != $args['style'] )
- return;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent \n";
- }
- else if($this->type=="multiselect")
- {
-
- }
- }
-}
-
+term_ids = wp_get_post_terms( $post_id, $taxonomy, 'fields=ids' );
+
+ $this->type = $type;
+ $this->defaults = $defaults;
+ }
+
+ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
+ /*$display = false;
+
+ $id = $element->term_id;
+
+ $display = true;
+ if ( isset( $children_elements[ $id ] ) ) {
+ // the current term has children
+ foreach ( $children_elements[ $id ] as $child ) {
+ if ( in_array( $child->term_id, $this->term_ids ) ) {
+ // one of the term's children is in the list
+ $display = true;
+ // can stop searching now
+ break;
+ }
+ }
+ }
+
+ if ( $display )*/
+ parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
+ }
+
+
+ function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 )
+ {
+
+ if($this->type=="list")
+ {
+ extract($args);
+
+ $cat_name = esc_attr( $sf_name );
+ $cat_name = apply_filters( 'list_cats', $cat_name, $category );
+ $link = 'description) )
+ $link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
+ else
+ $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
+ $link .= '>';
+ $link .= $cat_name . ' ';
+
+ if ( !empty($feed_image) || !empty($feed) ) {
+ $link .= ' ';
+
+ if ( empty($feed_image) )
+ $link .= '(';
+
+ $link .= ' ';
+
+ $link .= '';
+
+ if ( empty($feed_image) )
+ $link .= ')';
+ }
+
+ if ( !empty($show_count) )
+ $link .= ' (' . intval($category->count) . ')';
+
+ if ( 'list' == $args['style'] ) {
+ $output .= "\tterm_id;
+ if ( !empty($current_category) ) {
+ $_current_category = get_term( $current_category, $category->taxonomy );
+ if ( $category->term_id == $current_category )
+ $class .= ' current-cat';
+ elseif ( $category->term_id == $_current_category->parent )
+ $class .= ' current-cat-parent';
+ }
+ $output .= ' class="' . $class . '"';
+ $output .= ">$link\n";
+ } else {
+ $output .= "\t$link \n";
+ }
+ }
+ else if(($this->type=="checkbox")||($this->type=="radio"))
+ {
+ extract($args);
+
+ $cat_name = esc_attr( $category->name );
+ $cat_id = esc_attr( $category->term_id );
+ $cat_name = apply_filters( 'list_cats', $cat_name, $category );
+
+ //check a default has been set
+ $checked = "";
+
+ if($defaults)
+ {
+ $noselected = count($this->defaults);
+
+ if(($noselected>0)&&(is_array($defaults)))
+ {
+ foreach($defaults as $defaultid)
+ {
+ if($defaultid==$cat_id)
+ {
+ $checked = ' checked="checked"';
+ }
+ }
+ }
+ }
+
+ $link = " ".$cat_name;
+
+
+ if ( !empty($show_count) )
+ $link .= ' (' . intval($category->count) . ')';
+
+
+ $link .= " ";
+
+ if ( 'list' == $args['style'] ) {
+ $output .= "\t term_id;
+ if ( !empty($current_category) ) {
+ $_current_category = get_term( $current_category, $category->taxonomy );
+ if ( $category->term_id == $current_category )
+ $class .= ' current-cat';
+ elseif ( $category->term_id == $_current_category->parent )
+ $class .= ' current-cat-parent';
+ }
+ $output .= ' class="' . $class . '"';
+ $output .= ">$link\n";
+ } else {
+ $output .= "\t$link \n";
+ }
+ }
+ else if($this->type=="multiselect")
+ {
+ extract($args);
+
+ $cat_name = esc_attr( $category->name );
+ $cat_id = esc_attr( $category->term_id );
+ $cat_name = apply_filters( 'list_cats', $cat_name, $category );
+
+ //check a default has been set
+ $checked = "";
+ if($defaults)
+ {
+ $noselected = count($this->defaults);
+
+ if(($noselected>0)&&(is_array($defaults)))
+ {
+ foreach($defaults as $defaultid)
+ {
+ if($defaultid==$cat_id)
+ {
+ $checked = ' selected="selected"';
+ }
+ }
+ }
+ }
+
+
+ /* Custom depth calculations! :/ */
+ if($category->parent == 0)
+ {//then this has no parent so reset depth
+ $this->multidepth = 0;
+ }
+ else if($category->parent == $this->multilastid)
+ {
+ $this->multidepth++;
+ $this->multilastdepthchange = $this->multilastid;
+ }
+ else if($category->parent == $this->multilastdepthchange)
+ {//then this is also a child with the same parent so don't change depth
+
+ }
+ else
+ {//then this has a different parent so must be lower depth
+ if($this->multidepth>0)
+ {
+ $this->multidepth--;
+ }
+ }
+
+ $pad = str_repeat(' ', $this->multidepth * 3);
+ $link = "multidepth."\" value='".$cat_id."'$checked />".$pad.$cat_name;
+
+ if ( !empty($show_count) )
+ $link .= ' (' . intval($category->count) . ')';
+
+
+ $link .= " ";
+ $output .= "\t$link\n";
+
+
+ $this->multilastid = $cat_id;
+
+
+ /*
+ $pad = str_repeat(' ', $depth * 3);
+
+ $output .= "\tterm_id."\"";
+ $cat_name = apply_filters('list_cats', $category->sf_name, $category);
+ if ( $category->term_id == $args['selected'] )
+ $output .= ' selected="selected"';
+ $output .= '>';
+ $output .= $pad.$cat_name;
+ if ( $args['show_count'] )
+ $output .= ' ('. $category->count .')';
+ $output .= " \n";*/
+ }
+
+
+ }
+
+ function end_el( &$output, $page, $depth = 0, $args = array() )
+ {
+ if($this->type=="list")
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $output .= " \n";
+ }
+ else if(($this->type=="checkbox")||($this->type=="radio"))
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $output .= "\n";
+ }
+ else if($this->type=="multiselect")
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $output .= "\n";
+ }
+ }
+
+ function start_lvl( &$output, $depth = 0, $args = array() )
+ {
+
+ if($this->type=="list")
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent\n";
+ }
+ else if(($this->type=="checkbox")||($this->type=="radio"))
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent\n";
+ }
+ else if($this->type=="multiselect")
+ {
+ /*if ( 'list' != $args['style'] )
+ return;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent\n";*/
+ }
+ }
+
+ function end_lvl( &$output, $depth = 0, $args = array() ) {
+ if($this->type=="list")
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent \n";
+ }
+ else if(($this->type=="checkbox")||($this->type=="radio"))
+ {
+ if ( 'list' != $args['style'] )
+ return;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent \n";
+ }
+ else if($this->type=="multiselect")
+ {
+
+ }
+ }
+}
+
?>
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
index 32e88ad..5aeb327 100644
--- a/readme.txt
+++ b/readme.txt
@@ -3,8 +3,8 @@ Contributors: DesignsAndCode
Donate link:
Tags: category, filter, taxonomy, search, wordpress, post type, post date
Requires at least: 3.5
-Tested up to: 3.9
-Stable tag: 1.2.5
+Tested up to: 4.7
+Stable tag: 1.2.9
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -34,6 +34,20 @@ The documentation has been updated to include examples almost all configurable o
== Changelog ==
+= 1.2.9 =
+* Fixed - bugs with WP 4.4 compatibility
+* Fixed - an issue with operators being case sensitive - they are no longer case sensitive
+
+= 1.2.8 =
+* Fixed - an issue with rewrites - thanks [@iohannis](https://wordpress.org/support/profile/iohannis)
+
+= 1.2.7 =
+* Fixed - fix for new taxonomy rewrites and problems with multiple selection when using checkboxes
+* Fixed - added previously hidden `multiselect` field type
+
+= 1.2.6 =
+* Fixed - compatibility issues with WP 4.2.x
+
= 1.2.5 =
* Fixed a PHP error when setting defaults for taxonomies - many users did not see this but resulted in unexpected behaviour
* Fixed an error with post date sometimes being undefined for blank searches
@@ -113,13 +127,32 @@ The documentation has been updated to include examples almost all configurable o
== Description ==
-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.
-
-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.
-
-= Links =
+Search & Filter is a simple search and filtering plugin for WordPress - it is an advancement of the WordPress search box.
+
+You can search by Category, Tag, Custom Taxonomy, Post Type, Post Date or any combination of these easily to really refine your searches - remove the search box and use it as a filtering system for your posts and pages. Fields can be displayed as dropdowns, checkboxes, radio buttons or multi selects.
+
+**Links:** [Search & Filter Documentation](http://docs.designsandcode.com/search-filter/) | [Search & Filter Discussion](http://www.designsandcode.com/447/wordpress-search-filter-plugin-for-taxonomies/)
+
+= New: Search & Filter Pro =
+
+
+* View live demo >> [demo 1](http://demo.designsandcode.com/sfpro-movie-reviews/) | [demo 2](http://demo.designsandcode.com/sfpro-woo-mystile/product-search/) | [video](http://www.designsandcode.com/wordpress-plugins/search-filter-pro/)
+* Search **Custom Fields**, **Post Meta**, **Authors**, Post Types, Post Dates, Taxonomies, Tags, Categories
+* Use **AJAX** to display results - no more page reloading!
+* Search **Post Meta/Custom Fields** with checkboxes, radio buttons, dropdowns, multiselects or comboboxes
+* jQuery range slider, date pickers and **auto-complete comboboxes** for selects and multiselects
+* Order Results Field - users can order results by meta value, Post ID, author, title, name, date, date modified, parent ID, random, comment count and menu order
+* Drag & Drop editor
+* Use custom templates
+* Create as many fields and different search forms as you like
+* Use for blogs, reviews sites, news sites, property sites and more.
+* Use for your online shop - tested and compatible with **WooCommerce**, **WP eCommerce**, **Easy Digital Downloads**
+* Place anywhere in your themes and posts using shortcodes and widgets
+* Works with **WPML**
+* Works with **Advanced Custom Fields**
+* Extremely easy to use admin UI, fully integrated with WP 3.8+
+* **Dedicated Support**
+* [More info >>](http://www.designsandcode.com/wordpress-plugins/search-filter-pro/)
-* [Search & Filter Documentation](http://docs.designsandcode.com/search-filter/)
-* [Search & Filter Discussion](http://www.designsandcode.com/447/wordpress-search-filter-plugin-for-taxonomies/)
diff --git a/search-filter.php b/search-filter.php
index 721d26e..62eb496 100644
--- a/search-filter.php
+++ b/search-filter.php
@@ -1,1724 +1,1409 @@
-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 …",
- '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]))
- {
- 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;
-
- $taxs = array();
- //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
-
- 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()
- {
- 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;
- }
- }
-
- /* 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($_POST[SF_FPRE.'category_operator']=="and")
- {
- $operator = "+";
- }
- else if($_POST[SF_FPRE.'category_operator']=="or")
- {
- $operator = ",";
- }
- else
- {
- $operator = "+";
- }
- }
-
- $categories = implode($operator,$catarr);
-
- if(get_option('permalink_structure'))
- {
- //$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;
- }
- }
- }
-
- /* 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=";
- }
- }
-
- /* 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($_POST[SF_FPRE.'post_tag_operator']=="and")
- {
- $operator = "+";
- }
- else if($_POST[SF_FPRE.'post_tag_operator']=="or")
- {
- $operator = ",";
- }
- else
- {
- $operator = "+";
- }
- }
-
- $tags = implode($operator,$tagarr);
-
- if(!$this->hasqmark)
- {
- $this->urlparams .= "?";
- $this->hasqmark = true;
- }
- else
- {
- $this->urlparams .= "&";
- }
- $this->urlparams .= "tag=".$tags;
-
- }
- }
-
-
- /* 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
-
- //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_types_operator']))
- {
- if($_POST[SF_FPRE.'post_types_operator']=="and")
- {
- $operator = "+";
- }
- else if($_POST[SF_FPRE.'post_types_operator']=="or")
- {
- $operator = ",";
- }
- else
- {
- $operator = "+";
- }
- }*/
-
- $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;
- }
- }
- }
- }
-
-
- //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;
-
- //make the post an array for easy looping
- if(!is_array($val))
- {
- $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($_POST[SF_FPRE.$key.'_operator']=="and")
- {
- $operator = "+";
- }
- else if($_POST[SF_FPRE.$key.'_operator']=="or")
- {
- $operator = ",";
- }
- else
- {
- $operator = "+";
- }
- }
-
- $tags = implode($operator,$taxarr);
-
- if(!$this->hasqmark)
- {
- $this->urlparams .= "?";
- $this->hasqmark = true;
- }
- else
- {
- $this->urlparams .= "&";
- }
- $this->urlparams .= $key."=".$tags;
-
- }
- }
- }
- }
-
-
- 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;
- }
- }
-
- wp_redirect((home_url().$this->urlparams));
- }
- }
-
- 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 .= '
- ';
-
- return $returnvar;
- }
-
- ///////////////////////////////////////////////////////////
- function build_post_date_element($labels, $i, $types, $field)
- {
- $returnvar = "";
-
- $taxonomychildren = array();
-
- $taxonomychildren = (object)$taxonomychildren;
-
- $returnvar .= "";
-
- if($labels[$i]!="")
- {
- $returnvar .= "".$labels[$i]." ";
- }
-
- $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 .= " ";
- $returnvar .= $this->generate_date($taxonomychildren, $field, 1);
- }
- $returnvar .= " ";
-
- 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)
- {
- //var_dump(get_post_type_object( $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 .= "";
-
- $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 .= "".$labels[$i]." ";
- }
-
- 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 .= " ";
-
- 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 .= "";
-
- if($labels[$i]!="")
- {
- $returnvar .= "".$labels[$i]." ";
- }
-
- $args = array(
- '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['name']]))
- {
- $args['defaults'] = $this->defaults[$args['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['name']]))
- {
- $args['defaults'] = $this->defaults[$args['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['name']]))
- {
- $args['defaults'] = $this->defaults[$args['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 .= ' ';
- }
- }
-
- $returnvar .= " ";
- }
-
- 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")
- {
- $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 = '';
- $returnvar .= walk_taxonomy('multiselect', $args);
- $returnvar .= " ";
-
- return $returnvar;
- }
-
- //use wp array walker to enable hierarchical display
- public function generate_wp_checkbox($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
- {
- $returnvar = '';
- $returnvar .= walk_taxonomy('checkbox', $args);
- $returnvar .= " ";
-
- 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 = '";
-
- 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 .= '';
- if(isset($labels))
- {
- if($labels->all_items!="")
- {//check to see if all items has been registered in field then use this label
- $returnvar .= ''.$labels->all_items.' ';
- }
- else
- {//check to see if all items has been registered in field then use this label with prefix of "All"
- $returnvar .= 'All '.$labels->name.' ';
- }
- }
-
- 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 .= ''.$dropdown->cat_name.' ';
-
- }
- $returnvar .= " ";
-
- return $returnvar;
- }
-
- public function generate_checkbox($dropdata, $name, $currentid = 0, $labels = null, $defaultval = '')
- {
- $returnvar = '';
-
- return $returnvar;
- }
-
-
- public function generate_radio($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
- {
- $returnvar = '';
-
- 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 .= ' ';
-
- return $returnvar;
- }
- }
-}
-
-
-function walk_taxonomy( $type = "checkbox", $args = array() ) {
-
- $args['walker'] = new Taxonomy_Walker($type, $args['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");
-
-
-?>
\ No newline at end of file
+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)
+ {
+ // Default shortcode configs
+ $defaultConfigs = array(
+ 'permalink' => "1", // if 0, Removes the permalink behavior for taxonomies
+ 'fields' => null,
+ 'taxonomies' => null, //will be deprecated - use `fields` instead
+ 'submit_label' => null,
+ 'submitlabel' => null, //will be deprecated - use `submit_label` instead
+ 'search_placeholder' => esc_attr_x('Search …', 'placeholder'),
+ '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' => ""
+ );
+
+ // extract the attributes into variables
+ extract(shortcode_atts($defaultConfigs, $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;
+
+ $permalink = (int)$permalink;
+
+
+ //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, $permalink);
+ }
+
+
+ function add_queryvars($queryVars)
+ {
+ $queryVars[] = 'post_types';
+ $queryVars[] = 'post_date';
+ return $queryVars;
+ }
+
+ 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;
+
+
+ //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()
+ {
+ 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;
+ $allowPermalink = isset($_POST[SF_FPRE . 'permalink']);
+
+ /* 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 = $this->get_operator($_POST[SF_FPRE . 'category_operator']);
+
+ $categories = implode($operator, $catarr);
+
+
+ if ($allowPermalink && get_option('permalink_structure') && ($taxcount == 0)) {
+ //$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');
+
+ $this->add_urlparam_path($category_base, $categories);
+ } else {
+ $this->add_urlparam("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 = $this->get_operator($_POST[SF_FPRE . 'post_tag_operator']);
+
+ $tags = implode($operator, $tagarr);
+
+ if ($allowPermalink && get_option('permalink_structure') && ($taxcount == 0)) {
+ $this->add_urlparam_path('tag', $tags);
+ } else {
+ $this->add_urlparam("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 the key is not in the reserved array (ie, on a custom taxonomy - not tags, categories, search term, post type & post date)
+ if (!in_array($key, $this->frmreserved)) {
+
+ // 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 = $this->get_operator($_POST[SF_FPRE . $key . '_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 ($allowPermalink && get_option('permalink_structure') && ($taxcount == 0)) {
+ $key_taxonomy = get_taxonomy($key);
+
+ $base = $key;
+
+ if ((isset($key_taxonomy->rewrite)) && (isset($key_taxonomy->rewrite['slug']))) {
+ $base = $key_taxonomy->rewrite['slug'];
+ }
+ $this->add_urlparam_path($base, $taxs);
+ } else {
+ $this->add_urlparam($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 != "") {
+ $this->add_urlparam('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
+ $this->add_urlparam('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);
+
+ $this->add_urlparam("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 != "") {
+ $this->add_urlparam("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;
+ }
+ }
+ wp_redirect((home_url() . $this->urlparams));
+ exit;
+ }
+
+ }
+
+ /**
+ * Update $this->hasqmark and changes $this->urlparams to add new $ value
+ * @param string [$value] - ADD to urlparams
+ */
+ private function set_qmark()
+ {
+ if (!$this->hasqmark) {
+ $this->urlparams .= "?";
+ $this->hasqmark = true;
+ } else {
+ $this->urlparams .= "&";
+ }
+ }
+
+ /**
+ * add a value to $this->urlparams in format 'key=value'
+ * @param string $key - the param key, if value set, or the ey with value
+ * @param string [$value] - if set, will concat with $key by '='
+ * @return bool - add status
+ */
+ private function add_urlparam($key = '', $value = '')
+ {
+ if (!$key) return false;
+
+ $this->set_qmark();
+ if ($value)
+ $key = "{$key}={$value}";
+
+ $this->urlparams .= $key;
+ return true;
+ }
+
+ private function add_urlparam_path($type = '', $path = '')
+ {
+ if (!$type) return false;
+
+ $newPath = "/{$type}";
+
+ if ($path)
+ $newPath .= "/{$path}";
+
+ $this->urlparams = $newPath . $this->urlparams;
+
+ return true;
+ }
+
+ private function get_operator($value = "and", $default = '+')
+ {
+ $operator = $default; //default behaviour
+
+ if (strtolower($value) == "and") {
+ $operator = "+";
+ } else if (strtolower($value) == "or") {
+ $operator = ",";
+ }
+ return $operator;
+ }
+
+
+ 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, $permalink)
+ {
+ $returnvar = '';
+
+ $addclass = "";
+ if ($class != "") {
+ $addclass = ' ' . $class;
+ }
+
+ $returnvar .= '
+ ';
+
+ return $returnvar;
+ }
+
+ ///////////////////////////////////////////////////////////
+ function build_post_date_element($labels, $i, $types, $field)
+ {
+ $returnvar = "";
+
+ $taxonomychildren = array();
+
+ $taxonomychildren = (object)$taxonomychildren;
+
+ $returnvar .= "";
+
+ if ($labels[$i] != "") {
+ $returnvar .= "" . $labels[$i] . " ";
+ }
+
+ $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 .= " ";
+ $returnvar .= $this->generate_date($taxonomychildren, $field, 1);
+ }
+ $returnvar .= " ";
+
+ 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 .= "";
+
+ $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 .= "" . $labels[$i] . " ";
+ }
+
+ 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 .= " ";
+
+ 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 .= "";
+
+ if ($labels[$i] != "") {
+ $returnvar .= "" . $labels[$i] . " ";
+ }
+
+ $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 .= ' ';
+ }
+ }
+
+ $returnvar .= " ";
+ }
+
+ 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 = '';
+ $returnvar .= walk_taxonomy('multiselect', $args);
+ $returnvar .= " ";
+
+ return $returnvar;
+ }
+
+ //use wp array walker to enable hierarchical display
+ public function generate_wp_checkbox($args, $name, $currentid = 0, $labels = null, $defaultval = "0")
+ {
+ $returnvar = '';
+ $returnvar .= walk_taxonomy('checkbox', $args);
+ $returnvar .= " ";
+
+ 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 = '";
+
+ 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 .= '';
+ if (isset($labels)) {
+ if (!$labels->all_items) {//check to see if all items has been registered in field then use this label
+ $returnvar .= '' . $labels->all_items . ' ';
+ } else {//check to see if all items has been registered in field then use this label with prefix of "All"
+ $returnvar .= 'All ' . $labels->name . ' ';
+ }
+ }
+
+ 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 .= '' . $dropdown->cat_name . ' ';
+
+ }
+ $returnvar .= " ";
+
+ return $returnvar;
+ }
+
+ public function generate_checkbox($dropdata, $name, $currentid = 0, $labels = null, $defaultval = '')
+ {
+ $returnvar = '';
+
+ return $returnvar;
+ }
+
+
+ public function generate_radio($dropdata, $name, $currentid = 0, $labels = null, $defaultval = "0")
+ {
+ $returnvar = '';
+
+ 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 .= ' ';
+
+ return $returnvar;
+ }
+ }
+}
+
+
+function walk_taxonomy($type = "checkbox", $args = array())
+{
+
+ $args['walker'] = new Taxonomy_Walker($type, $args['sf_name']);
+
+ //unset($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");