diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..39eb4dc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,76 @@ +WP Advanced Search +================== + +[0.0.1] + +##Initial commit + +[0.0.2] + +##Add +- Added function _the_form_shortcodes()_ to make the form work properly within shortcodes. + +###Modified files +* wpas.php + +## Add +- Implemented functionality to show the number of results for each search via AJAX. (Needs an element with id wpas-no-of-results). + +###Modified files +- lib.php +- js/scripts.js + +[0.0.3] + +## Add +- Added span to display the number of results for each input. + +###Modified files +- src/InputMarkup.php + +[0.0.4] + +##Add +- Added function to display post count on each taxonomy input. +- Added parameter show_results to display the number of results within each input label + +###Modified files +- src/Input.php +- src/InputMarkup.php +- src/Field.php +- lib.php +- wpas.php +- js/scripts.js + +[0.0.5] + +##Add +- Added filter display, working for taxonomies, search and meta_key fields. Also added functionality to delete each filter and run an updated AJAX request. + +##Edit +- Edited display post results within each taxonomy input to include meta fields if exist. +- Edited display post results within each taxonomy input to include additional tax_queries if defined on the search form. + +###Modified files +- lib.php +- wpas.php -> Added get_args() function so we could retrieve the args set on the form and include tax_queries if they exist +- js/scripts.js + + +[0.0.6] + +##Add +- Added functionality to make meta queries on several meta keys. +- Added option to include a custom img to close the filters boxes. If none is defined, a svg formatted cross will appear. +- Added option to hide taxonomy elements if count is 0 + +##Fix +- Fixed some checkboxes unchecking when closing filters. (If there were two or more checkboxes with the same value, they would all uncheck). + +###Modified files +- js/scripts.js +- src/Field.php +- src/MetaQuery.php +- src/Form.php +- src/AjaxConfig.php +- src/Input.php diff --git a/js/scripts.js b/js/scripts.js index 88ce35c..9f3a209 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -8,6 +8,9 @@ var __WPAS = { FORM_ID: "", KEY_PREFIX: "wpasInstance_", HASH: "", + NUMBER: "#wpas-no-of-results", + INPUT_COUNT: '#wpas-input-count-', + FILTERS: '#wpas-input-filters', STORAGE_KEY: function() { return this.KEY_PREFIX + this.FORM_ID; } @@ -49,6 +52,9 @@ jQuery(document).ready(function($) { }); }); + + + /** * AJAX Functionality */ @@ -151,7 +157,7 @@ jQuery(document).ready(function($) { function sendRequest(data, page) { ajaxLoader.hideButton(); ajaxLoader.showImage(); - jQuery.ajax({ + $.ajax({ type: 'POST', url: WPAS_Ajax.ajaxurl, data: { @@ -159,10 +165,51 @@ jQuery(document).ready(function($) { page: page, form_data: data }, + success: function(data, textStatus, XMLHttpRequest) { response = JSON.parse(data); setTimeout(function() { appendHTML(__WPAS.INNER, response.results); + updateHTML(__WPAS.NUMBER, response.count); //Update the element showing the total number of results. + $.each(response.values, function(id, inputs){ + $.each(inputs, function(name, value){ + updateHTML(__WPAS.INPUT_COUNT+id+'-'+name, ' (' + value + ')'); + if(inputs.hide){ + if(value == 0){ + $('input[value="'+name+'"][name="'+id+'[]"]').parent().hide(); + } + else{ + $('input[value="'+name+'"][name="'+id+'[]"]').parent().show(); + } + } + else{ + if(value == 0){ + $('input[value="'+name+'"][name="'+id+'[]"]').parent().addClass('disabled'); + $('input[value="'+name+'"][name="'+id+'[]"]').prop('disabled', true); + } + else{ + $('input[value="'+name+'"][name="'+id+'[]"]').parent().removeClass('disabled'); + $('input[value="'+name+'"][name="'+id+'[]"]').prop('disabled', false); + } + } + }); + }); + + updateHTML(__WPAS.FILTERS, ''); + $.each(response.selected, function(id, inputs){ + $.each(inputs.selected, function(number, value){ + appendHTML(__WPAS.FILTERS, '
'+inputs.label+':
'+$(__WPAS.FORM).data('ajax-close-img-html')+'
'); + $('#'+inputs.id+'_filter_'+number).siblings().addClass('filters-close').attr('data-value', value.slug ? value.slug : value).attr('data-id', inputs.id); //Add the necessary attributes to the custom filters close img. + $('.filters-close').on('click', function(){ + $(this).parent().hide(); + $('input[value="'+$(this).attr('data-value')+'"][name="'+$(this).attr('data-id')+'[]"]').prop('checked', false); //Filter to prevent several checkboxes with same value to be unchecked. + $('input[name="'+inputs.id+'"]').val(''); + $('form.wpas-autosubmit :input').parents('form').submit(); + }); + appendHTML('#'+inputs.id+'_filter_'+number, (value.name ? value.name : value) + ' '); + + }); + }); ajaxLoader.hideImage(); updateHTML(__WPAS.DEBUG_CONTAINER,response.debug); CURRENT_PAGE = response.current_page; @@ -175,16 +222,17 @@ jQuery(document).ready(function($) { } else { ajaxLoader.showButton(); } - + window.location.hash = __WPAS.HASH; storeInstance(); unlockForm(); + }, T); }, error: function(MLHttpRequest, textStatus, errorThrown){ - console.log(errorThrown); + console.log(MLHttpRequest); } }); } diff --git a/lib.php b/lib.php index 64fa65a..d9975ae 100644 --- a/lib.php +++ b/lib.php @@ -28,25 +28,132 @@ function wpas_build_ajax_response(array $post) { $request['paged'] = $page; $wpas_id = $request['wpas_id']; + $wpas = new WP_Advanced_Search($wpas_id, $request); $q = $wpas->query(); $template = $wpas->get_ajax()->resultsTemplate(); $response = array(); + $response['query'] = $q; + $response["count"] = $q->found_posts; //Access the query object on order to retrieve the total number of found posts. $response["results"] = wpas_load_template_part($template, $q); $response["current_page"] = $q->query_vars['paged']; - $response["max_page"] = $q->max_num_pages; + $response["max_page"] = $q->max_num_pages; + $response["values"] = wpas_get_tax_count($wpas->inputs, $q, $wpas->get_args()); + $response["selected"] = wpas_get_selected($wpas->inputs); + if ($response["results"] === false) { $wpas->set_error("AJAX results template '".$template."' not found in theme root."); } - + $response["debug"] = ""; if ($wpas->debug_enabled()) $response["debug"] = "
". $wpas->create_debug_output() . "
"; return json_encode($response); } +function wpas_get_selected($inputs){ + $response = array(); + foreach ($inputs as $input){ + $selected = $input->getSelected(); + + //Apply some filters + if(empty($selected)) continue; + if($input->getFieldType() != 'taxonomy' && $input->getFieldType() != 'search' && $input->getFieldType() != 'meta_key') continue; + if($selected[0] == '') continue; //If text inputs are empty, continue. Otherwise, they will appear on filters even if they are empty. + // + + if(isset($input->taxonomy)){ + $label = get_taxonomy($input->taxonomy); + $terms = get_terms(array('taxonomy' => $input->taxonomy),array('slug' => $selected)); + } + $response[] = array( + 'selected' => isset($terms) ? $terms : $selected, + 'type' => $input->getFieldType(), + 'id' => $input->getId(), + 'label' => isset($label) ? $label->label : $input->getLabel(), + ); + } + + return $response; +} + +function wpas_get_tax_count($inputs, $q, $query_args){ + + $response = array(); + $values = array(); + $all_values = array(); + $tax = array(); + + foreach($inputs as $id => $input){ + if(isset($input->taxonomy)){ + $values[$input->taxonomy] = array( + 'selected' => $input->getSelected(), + 'format' => $input->term_format, + 'operator' => $input->operator, + ); + $all_values[$input->getId()] = $input->getValues(); + $tax[] = array('tax' => $input->taxonomy, 'format' => $input->term_format); + + $response[$input->getId()]['hide'] = $input->hideEmpty(); //Set hide_empty option so AJAX knows whether to hide it. + } + } + + $args = array(); + + $args['meta_query'] = $q->meta_query->queries; //If a meta_query is set, set it to each subQuery. + $i = 0; + foreach($values as $taxonomy => $elements){ + $terms = array(); + + $args['tax_query'][$i] = array( + 'taxonomy' => $taxonomy, + 'operator' => $elements['operator'], + 'field' => $elements['format'], + ); + foreach($elements['selected'] as $selection){ + $terms[] = $selection; + } + + if(!empty($terms)){ + $args['tax_query'][$i]['terms'] = $terms; + } + + if(!isset($args['tax_query'][$i]['terms'])) unset($args['tax_query'][$i]); + + $i++; + } + + //If tax_query was set on the form, include it here. + if(!empty($query_args['wp_query']['tax_query'])) $args['tax_query'][] = $query_args['wp_query']['tax_query']; + + $i = 0; + foreach($all_values as $id => $value){ + foreach($value as $slug => $label){ + if(isset($args['tax_query'][$i])){ + array_push($args['tax_query'][$i]['terms'], $slug); + $query = new WP_Query($args); + $response[$id][$slug] = $query->found_posts; + array_pop($args['tax_query'][$i]['terms']); + } + else{ + $args['tax_query'][] = array( + 'taxonomy' => $tax[$i]['tax'], + 'field' => $tax[$i]['format'], + 'terms' => $slug, + ); + $query = new WP_Query($args); + $response[$id][$slug] = $query->found_posts; + array_pop($args['tax_query']); + } + } + $i++; + } + + return $response; + +} /** * Loads and returns a template part * @@ -58,7 +165,6 @@ function wpas_build_ajax_response(array $post) { */ function wpas_load_template_part($template, $query_object) { global $wp_query; - $template_suffix = '/'.ltrim($template,'/'); $template = get_stylesheet_directory().$template_suffix; if (!file_exists($template)) { @@ -67,12 +173,10 @@ function wpas_load_template_part($template, $query_object) { } $temp = $wp_query; $wp_query = $query_object; - ob_start(); load_template($template); $var = ob_get_contents(); ob_end_clean(); - $wp_query = $temp; return $var; } diff --git a/src/AjaxConfig.php b/src/AjaxConfig.php index a6c9dd7..efb243c 100644 --- a/src/AjaxConfig.php +++ b/src/AjaxConfig.php @@ -9,6 +9,7 @@ class AjaxConfig extends StdObject private $show_default_results; private $results_template; private $url_hash; + private $close_img_html; protected $args; static protected $rules = array( @@ -17,15 +18,17 @@ class AjaxConfig extends StdObject 'button_text' => 'string', 'show_default_results' => 'bool', 'results_template' => 'string', - 'url_hash' => 'string' + 'url_hash' => 'string', + 'close_img_html' => 'string', ); static protected $defaults = array( 'enabled' => false, 'button_text' => 'LOAD MORE RESULTS', 'show_default_results' => true, - 'url_hash' => 'results' - ); + 'url_hash' => 'results', + ); + //'close_img' => function __construct($args = array()) { @@ -51,6 +54,10 @@ private function processArgs(array $args) { $args['results_template'] = $dir . '/templates/template-ajax-results.php'; } + if(empty($args['close_img_html'])){ + $args['close_img_html'] = ""; + } + return $args; } @@ -83,4 +90,8 @@ public function urlHash() { return $this->url_hash; } + public function closeImg(){ + return $this->close_img_html; + } + } \ No newline at end of file diff --git a/src/Field.php b/src/Field.php index 2db5e23..231643e 100644 --- a/src/Field.php +++ b/src/Field.php @@ -11,12 +11,13 @@ class Field extends StdObject { private $operator; private $compare; private $data_type; + private $meta_keys; protected static $rules = array( 'type' => array('type' => 'FieldType', 'required' => true), 'inputs' => 'array', 'taxonomy' => 'string', - 'meta_key' => 'string', + 'meta_key' => 'array', 'data_type' => 'DataType', 'group_method' => array('type' => 'string', 'matches' => 'merge|distinct'), 'relation' => array('type'=>'Relation','required' => true), @@ -58,7 +59,9 @@ class Field extends StdObject { 'date_type' => 1, 'orderby_values' => 1, 'id' => 1, - 'term_args' => 1 + 'term_args' => 1, + 'display_count' => 1, + 'hide_empty' => 1, ); public function __construct($args) { @@ -74,6 +77,7 @@ public function __construct($args) { $this->compare = $args['compare']; $this->data_type = $args['data_type']; $this->populateInputs($this->field_id, $args); + $this->meta_keys = $this->setMetaKeys($args); } private function populateInputs($field_id, $args) { @@ -107,13 +111,8 @@ private function addRemainingArgs($input_args, $field_args) { private function setFieldId($args) { switch($args['field_type']) { - case 'meta_key' : - if (empty($args['meta_key'])) { - throw new \Exception('Field is missing '. - 'argument \'meta_key\''); - return; - } - return $args['meta_key']; + case 'meta_key': + return $args['meta_key'][0]; case 'taxonomy' : if (empty($args['taxonomy'])) { throw new \Exception('Field is missing '. @@ -126,6 +125,20 @@ private function setFieldId($args) { } } + private function setMetaKeys($args){ + switch($args['field_type']) { + case 'meta_key' : + if (empty($args['meta_key'])) { + throw new \Exception('Field is missing '. + 'argument \'meta_key\''); + return false; + } + return $args['meta_key']; + default: + return false; + } + } + protected static function parseArgs(array $args, array $defaults) { $args = parent::parseArgs($args, self::$defaults); return $args; @@ -177,6 +190,13 @@ public function getFieldId() return $this->field_id; } + /** + * @return array + */ + public function getMetaKeys(){ + return $this->meta_keys; + } + /** * @return mixed */ diff --git a/src/Form.php b/src/Form.php index 3b79294..cbd9aa6 100644 --- a/src/Form.php +++ b/src/Form.php @@ -117,11 +117,14 @@ private function dataAttributesString() { $output = ""; if ($this->ajax->isEnabled() == false) return $output; + $output .= "data-ajax-close-img-html=\"".$this->ajax->closeImg()."\""; $output .= "data-ajax-button=\"".$this->ajax->buttonText()."\" "; $output .= "data-ajax-loading=\"".$this->ajax->loadingImage()."\" "; $show_default = ($this->ajax->showDefaultResults()) ? "1" : "0"; $output .= "data-ajax-show-default=\"".$show_default."\" "; $output .= "data-ajax-url-hash=\"".$this->ajax->urlHash()."\" "; + //$output .= "data-ajax-close-img=\"".$this->ajax->closeImg()."\" "; + // return $output; } diff --git a/src/Input.php b/src/Input.php index 40e9f63..af3a088 100644 --- a/src/Input.php +++ b/src/Input.php @@ -1,213 +1,229 @@ - 'string', - 'attributes' => 'array', - 'field_type' => array('type' => 'FieldType', - 'required' => true), - 'label' => 'string', - 'class' => 'array', - 'format' => array('type' => 'InputFormat', - 'required' => true), - 'placeholder' => 'string|bool', - 'values' => 'array', - 'selected' => 'array', - 'nested' => 'bool', - 'allow_null' => 'bool|string', - 'default_all' => 'bool', - 'pre_html' => 'string', - 'post_html' => 'string'); - - protected static $defaults = array( - 'label' => '', - 'placeholder' => false, - 'values' => array(), - 'selected' => array(), - 'nested' => false, - 'allow_null' => false, - 'default_all' => false, - 'disable_wrapper' => false, - 'pre_html' => '', - 'post_html' => '' ); - - public function __construct($input_name, $args = array()) { - $args = $this->parseArgs($args,self::$defaults); - $args = $this->validateInput($input_name, $args, self::$defaults); - $this->initMembers($input_name, $args); - } - - /** - * Validates the input_name and arguments - * - * @param string $input_name - * @param array $args - * @throws \Exception - * @throws \InvalidArgumentException - * @return array - */ - private function validateInput( $input_name, $args, $defaults ) { - $args = self::validate($args); - - if (!is_string($input_name)) { - $err_msg = $this->validationErrorMsg( - array('Argument 1 `$field_name` ' . - 'must be a string.')); - throw new \InvalidArgumentException($err_msg); - } - - return $args; - } - - /** - * Initializes object members - * - * @param string $input_name - * @param array $args - */ - private function initMembers($input_name, $args) { - $this->input_name = $input_name; - - foreach($args as $key => $value) { - $this->$key = $value; - } - - // For select fields, add null value if specified - if ($this->format == 'select' && $this->allow_null && !empty($this->values)) { - $null_val = ($this->allow_null === true) ? '' : $this->allow_null; - $this->addNullOption($null_val); - } - - if (!empty($this->class) && is_array($this->class)) { - $this->class = implode(' ', $this->class); - } - - $this->id = $this->input_name; - $this->ctr = 1; - } - - /** - * Returns a string containing the full HTML content of the input, including - * a wrapper div - * - * @return string - */ - public function toHTML() - { - $markup = new InputMarkup($this); - return $markup->generate(); - } - - /** - * For select fields, adds a null option to the beginning of the menu - * - * @since 1.3 - */ - private function addNullOption( $null_label ) { - if ($this->nested) { - $null_option = array( - 'value' => '', - 'label' => $null_label, - 'children' => array() - ); - } else { - $null_option = $null_label; - } - - $arr = array_reverse($this->values, true); - $arr[''] = $null_option; - $arr = array_reverse($arr, true); - $this->values = $arr; - } - - public function disableWrapper() { - $this->disable_wrapper = true; - } - - public function wrappersDisabled() { - return $this->disable_wrapper; - } - - public function getId() - { - return $this->id; - } - - public function getFormat() - { - return $this->format; - } - - public function getInputName() - { - return $this->input_name; - } - - public function getClass() - { - return $this->class; - } - - public function getFieldType() { - return $this->field_type; - } - - public function getAttributes() - { - return $this->attributes; - } - - public function getLabel() - { - return $this->label; - } - - public function getPlaceholder() - { - return $this->placeholder; - } - - public function getValues() - { - return $this->values; - } - - public function isNested() - { - return $this->nested; - } - - public function getSelected() - { - return $this->selected; - } - - public function getPreHtml() - { - return $this->pre_html; - } - - public function getPostHtml() - { - return $this->post_html; - } - + 'string', + 'attributes' => 'array', + 'field_type' => array('type' => 'FieldType', + 'required' => true), + 'label' => 'string', + 'class' => 'array', + 'format' => array('type' => 'InputFormat', + 'required' => true), + 'placeholder' => 'string|bool', + 'values' => 'array', + 'selected' => 'array', + 'nested' => 'bool', + 'allow_null' => 'bool|string', + 'default_all' => 'bool', + 'pre_html' => 'string', + 'post_html' => 'string', + 'display_count' => 'bool', + 'hide_empty' => 'bool', + ); + + protected static $defaults = array( + 'label' => '', + 'placeholder' => false, + 'values' => array(), + 'selected' => array(), + 'nested' => false, + 'allow_null' => false, + 'default_all' => false, + 'disable_wrapper' => false, + 'pre_html' => '', + 'post_html' => '', + 'display_count' => false, + 'hide_empty' => false, + ); + + public function __construct($input_name, $args = array()) { + $args = $this->parseArgs($args,self::$defaults); + $args = $this->validateInput($input_name, $args, self::$defaults); + $this->initMembers($input_name, $args); + } + + /** + * Validates the input_name and arguments + * + * @param string $input_name + * @param array $args + * @throws \Exception + * @throws \InvalidArgumentException + * @return array + */ + private function validateInput( $input_name, $args, $defaults ) { + $args = self::validate($args); + + if (!is_string($input_name)) { + $err_msg = $this->validationErrorMsg( + array('Argument 1 `$field_name` ' . + 'must be a string.')); + throw new \InvalidArgumentException($err_msg); + } + + return $args; + } + + /** + * Initializes object members + * + * @param string $input_name + * @param array $args + */ + private function initMembers($input_name, $args) { + $this->input_name = $input_name; + + foreach($args as $key => $value) { + $this->$key = $value; + } + + // For select fields, add null value if specified + if ($this->format == 'select' && $this->allow_null && !empty($this->values)) { + $null_val = ($this->allow_null === true) ? '' : $this->allow_null; + $this->addNullOption($null_val); + } + + if (!empty($this->class) && is_array($this->class)) { + $this->class = implode(' ', $this->class); + } + + $this->id = $this->input_name; + $this->ctr = 1; + } + + /** + * Returns a string containing the full HTML content of the input, including + * a wrapper div + * + * @return string + */ + public function toHTML() + { + $markup = new InputMarkup($this); + return $markup->generate(); + } + + /** + * For select fields, adds a null option to the beginning of the menu + * + * @since 1.3 + */ + private function addNullOption( $null_label ) { + if ($this->nested) { + $null_option = array( + 'value' => '', + 'label' => $null_label, + 'children' => array() + ); + } else { + $null_option = $null_label; + } + + $arr = array_reverse($this->values, true); + $arr[''] = $null_option; + $arr = array_reverse($arr, true); + $this->values = $arr; + } + + public function disableWrapper() { + $this->disable_wrapper = true; + } + + public function wrappersDisabled() { + return $this->disable_wrapper; + } + + public function getId() + { + return $this->id; + } + + public function getFormat() + { + return $this->format; + } + + public function getInputName() + { + return $this->input_name; + } + + public function getClass() + { + return $this->class; + } + + public function getFieldType() { + return $this->field_type; + } + + public function getAttributes() + { + return $this->attributes; + } + + public function getLabel() + { + return $this->label; + } + + public function getPlaceholder() + { + return $this->placeholder; + } + + public function getValues() + { + return $this->values; + } + + public function getShow() + { + return $this->display_count; + } + + public function hideEmpty() + { + return $this->hide_empty; + } + + public function isNested() + { + return $this->nested; + } + + public function getSelected() + { + return $this->selected; + } + + public function getPreHtml() + { + return $this->pre_html; + } + + public function getPostHtml() + { + return $this->post_html; + } + } \ No newline at end of file diff --git a/src/InputMarkup.php b/src/InputMarkup.php index 2762251..de896e6 100644 --- a/src/InputMarkup.php +++ b/src/InputMarkup.php @@ -353,6 +353,7 @@ private function listOption($value, $label, $type = 'checkbox') { $element = ($this->input->isNested()) ? 'li' : 'div'; $id = $this->input->getId(); $name = $this->input->getInputName(); + $show = $this->input->getShow() ? '' : ''; $name .= ($type == 'checkbox') ? '[]' : ''; $output = '<'.$element.' class="wpas-'.$id.'-'.$type.'-'.$ctr.'-container wpas-'.$id.'-'.$type.'-container wpas-'.$type.'-container">' . ' '.$label.''; + $output .= ''.$show.''; $this->ctr++; return $output; } diff --git a/src/MetaQuery.php b/src/MetaQuery.php index c404330..eaa2e47 100644 --- a/src/MetaQuery.php +++ b/src/MetaQuery.php @@ -46,11 +46,10 @@ public function build(array $fields, $relation = 'AND', HttpRequest $request) { */ private function metaQueryGroup($field, HttpRequest $request) { $group = array(); - $meta_key = $field->getFieldId(); + $meta_key = $field->getMetaKeys(); $inputs = $field->getInputs(); $data_type = $field->getDataType(); $compare = $field->getCompare(); - $clauses = $this->clauseList($inputs, $meta_key, $compare, $data_type); foreach ($clauses as $clause) { @@ -72,6 +71,7 @@ private function metaQueryGroup($field, HttpRequest $request) { * @return array */ private function clauseList($inputs, $meta_key, $compare, $data_type) { + if ($compare == Compare::between) { return array($this->metaQueryClauseBetween($meta_key, $inputs, 2)); } @@ -81,6 +81,7 @@ private function clauseList($inputs, $meta_key, $compare, $data_type) { // Disallow multiple input sources if not using BETWEEN comparison // This is a (potentially) temporary restriction $keys = array_keys($inputs); + $inputs = array($keys[0] => $inputs[$keys[0]]); // // @@ -114,7 +115,7 @@ private function metaQueryClause($meta_key, $input_name, $input) { if (empty($val)) return array(); $clause = array(); - $clause['key'] = $meta_key; + $clause['key'] = $meta_key[0]; $clause['compare'] = $input['compare']; $clause['value'] = $val; $clause['type'] = $input['data_type']; @@ -146,7 +147,6 @@ private function metaQueryClauseBetween($meta_key, array $inputs, $limit = false $count++; if ($limit && $count > $limit) break; } - if (!empty($compare)) { $clause['compare'] = $compare; } else if (count($inputs) == 1) { @@ -200,7 +200,9 @@ private function mergeRequestValues(array $values, $name) { */ private function metaQueryClauseArray($meta_key, $input_name, $input) { $request_var = RequestVar::nameToVar($input_name, 'meta_key'); + $var = $this->request->get($request_var); + if (empty($var)) return array(); $clause = array(); @@ -221,12 +223,20 @@ private function metaQueryClauseArray($meta_key, $input_name, $input) { } private function subClause($meta_key, $input, $value) { - return array( - 'key' => $meta_key, - 'type' => DataType::isArrayType($input['data_type']), - 'value' => $value, - 'compare' => $input['compare'] - ); + + $queries = array(); + $queries['relation'] = $input['relation']; + foreach($meta_key as $key){ + $queries[] = array( + 'key' => $key, + 'type' => DataType::isArrayType($input['data_type']), + 'value' => $value, + 'compare' => $input['compare'] + ); + } + + return $queries; + } /** diff --git a/src/Query.php b/src/Query.php index 29ec40e..cff1dd7 100644 --- a/src/Query.php +++ b/src/Query.php @@ -168,7 +168,15 @@ private function addSubQuery(array $query, FieldGroup $field_group, $field_type, $s_query = $this->getSubQuery($classnames[$field_type], $fields, $field_group->getRelation(), $request ); - if (!empty($s_query)) $query[RequestVar::wpQueryVar($field_type)] = $s_query; + if (!empty($s_query)){ + //If a tax_query was set on the form and another taxonomy was selected, it would overwrite the one set before. This adds all subqueries to the main query. + if(isset($this->wp_query_args['tax_query']) && $field_type == 'taxonomy'){ + $this->wp_query_args['tax_query'][] = $s_query; + } + else{ + $query[RequestVar::wpQueryVar($field_type)] = $s_query; + } + } return $query; } diff --git a/wpas.php b/wpas.php index 69e70df..8791cb2 100644 --- a/wpas.php +++ b/wpas.php @@ -23,6 +23,7 @@ class WP_Advanced_Search { private $ajax; private $query; public $debug_level; + public $inputs; function __construct($id = '', $request = null) { $this->errors = array(); @@ -34,6 +35,7 @@ function __construct($id = '', $request = null) { $this->debug_level = $this->args['debug_level']; $this->factory = new WPAS\Factory($this->args, $request); $this->query = $this->factory->buildQueryObject(); + $this->inputs = $this->factory->getInputs(); } /** @@ -68,6 +70,18 @@ public function the_form() { echo $form->toHTML(); } + /** + * Print HTML in shortcodes + * (When using the_form function within a shortcode, it would cause issues because it returns HTML via echo. Changed for return to fix it). + * @return string + */ + public function the_form_shortcode() { + $form = $this->factory->getForm(); + if ($this->debug) $form->addClass('wpas-debug-enabled'); + return $form->toHTML(); + } + + /** * Create and return WP_Query object for the search instance * @@ -205,6 +219,10 @@ public function ajax_enabled() { return $this->ajax->isEnabled(); } + public function get_args(){ + return $this->args; + } + /** * Pre process arguments, translate argument blocks into config objects *