diff --git a/contrib/search_api_views/includes/handler_filter_entity.inc b/contrib/search_api_views/includes/handler_filter_entity.inc new file mode 100644 index 0000000..f095f16 --- /dev/null +++ b/contrib/search_api_views/includes/handler_filter_entity.inc @@ -0,0 +1,201 @@ + $this->isMultiValued() ? t('Is one of') : t('Is'), + 'all of' => t('Is all of'), + '<>' => $this->isMultiValued() ? t('Is not one of') : t('Is not'), + 'empty' => t('Is empty'), + 'not empty' => t('Is not empty'), + ); + if (!$this->isMultiValued()) { + unset($operators['all of']); + } + return $operators; + } + + /** + * {@inheritdoc} + */ + public function option_definition() { + $options = parent::option_definition(); + + $options['expose']['multiple']['default'] = TRUE; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function value_form(&$form, &$form_state) { + parent::value_form($form, $form_state); + if (!is_array($this->value)) { + $this->value = $this->value ? array($this->value) : array(); + } + } + + /** + * {@inheritdoc} + */ + public function value_validate($form, &$form_state) { + if (!empty($form['value'])) { + $value = &$form_state['values']['options']['value']; + $values = $this->isMultiValued($form_state['values']['options']) ? drupal_explode_tags($value) : array($value); + $ids = $this->validate_entity_strings($form['value'], $values); + + if ($ids) { + $value = $ids; + } + } + } + + /** + * {@inheritdoc} + */ + public function accept_exposed_input($input) { + $rc = parent::accept_exposed_input($input); + + if ($rc) { + // If we have previously validated input, override. + if ($this->validated_exposed_input) { + $this->value = $this->validated_exposed_input; + } + } + + return $rc; + } + + /** + * {@inheritdoc} + */ + public function exposed_validate(&$form, &$form_state) { + if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) { + return; + } + + $identifier = $this->options['expose']['identifier']; + $input = $form_state['values'][$identifier]; + + if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) { + $this->operator = $this->options['group_info']['group_items'][$input]['operator']; + $input = $this->options['group_info']['group_items'][$input]['value']; + } + + $values = $this->isMultiValued() ? drupal_explode_tags($input) : array($input); + + if (!$this->options['is_grouped'] || ($this->options['is_grouped'] && ($input != 'All'))) { + $this->validated_exposed_input = $this->validate_entity_strings($form[$identifier], $values); + } + else { + $this->validated_exposed_input = FALSE; + } + } + + /** + * Determines whether multiple user names can be entered into this filter. + * + * This is either the case if the form isn't exposed, or if the " Allow + * multiple selections" option is enabled. + * + * @param array $options + * (optional) The options array to use. If not supplied, the options set on + * this filter will be used. + * + * @return bool + * TRUE if multiple values can be entered for this filter, FALSE otherwise. + */ + protected function isMultiValued(array $options = array()) { + $options = $options ? $options : $this->options; + return empty($options['exposed']) || !empty($options['expose']['multiple']); + } + + /** + * {@inheritdoc} + */ + public function admin_summary() { + $value = $this->value; + $this->value = empty($value) ? '' : $this->ids_to_strings($value); + $ret = parent::admin_summary(); + $this->value = $value; + return $ret; + } + + /** + * {@inheritdoc} + */ + public function query() { + if ($this->operator === 'empty') { + $this->query->condition($this->real_field, NULL, '=', $this->options['group']); + } + elseif ($this->operator === 'not empty') { + $this->query->condition($this->real_field, NULL, '<>', $this->options['group']); + } + elseif (is_array($this->value)) { + if (count($this->value) == 1) { + $this->query->condition($this->real_field, reset($this->value), $this->operator, $this->options['group']); + } + else { + $filter = $this->query->createFilter($this->operator === '<>' || $this->operator === 'all of' ? 'AND' : 'OR'); + foreach ($this->value as $value) { + $filter->condition($this->real_field, $value, $this->operator === 'all of' ? '=' : $this->operator); + } + $this->query->filter($filter, $this->options['group']); + } + } + } + +} diff --git a/contrib/search_api_views/includes/handler_filter_taxonomy_term.inc b/contrib/search_api_views/includes/handler_filter_taxonomy_term.inc index fe1d190..f295f81 100644 --- a/contrib/search_api_views/includes/handler_filter_taxonomy_term.inc +++ b/contrib/search_api_views/includes/handler_filter_taxonomy_term.inc @@ -10,24 +10,7 @@ * * Based on views_handler_filter_term_node_tid. */ -class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilter { - - /** - * {@inheritdoc} - */ - public function operator_options() { - $operators = array( - '=' => $this->isMultiValued() ? t('Is one of') : t('Is'), - 'all of' => t('Is all of'), - '<>' => $this->isMultiValued() ? t('Is not one of') : t('Is not'), - 'empty' => t('Is empty'), - 'not empty' => t('Is not empty'), - ); - if (!$this->isMultiValued()) { - unset($operators['all of']); - } - return $operators; - } +class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilterEntity { /** * {@inheritdoc} @@ -42,7 +25,6 @@ class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilte public function option_definition() { $options = parent::option_definition(); - $options['expose']['multiple']['default'] = TRUE; $options['type'] = array('default' => 'textfield'); $options['limit'] = array('default' => TRUE, 'bool' => TRUE); $options['vocabulary'] = array('default' => 0); @@ -108,27 +90,13 @@ class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilte } parent::value_form($form, $form_state); - if (!is_array($this->value)) { - $this->value = $this->value ? array($this->value) : array(); - } if ($this->options['type'] == 'textfield') { - $default = ''; if ($this->value) { - $result = db_select('taxonomy_term_data', 'td') - ->fields('td') - ->condition('td.tid', $this->value) - ->execute(); - foreach ($result as $term) { - if ($default) { - $default .= ', '; - } - $default .= $term->name; - } + $form['value']['#default_value'] = $this->ids_to_strings($this->value); } $form['value']['#title'] = $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'); - $form['value']['#default_value'] = $default; if ($this->options['limit']) { $form['value']['#autocomplete_path'] = 'admin/views/ajax/autocomplete/taxonomy/' . $vocabulary->vid; @@ -222,12 +190,7 @@ class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilte return; } - $values = $this->isMultiValued() ? drupal_explode_tags($form_state['values']['options']['value']) : array($form_state['values']['options']['value']); - $tids = $this->validate_term_strings($form['value'], $values); - - if ($tids) { - $form_state['values']['options']['value'] = $tids; - } + parent::value_validate($form, $form_state); } /** @@ -249,61 +212,37 @@ class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilte return FALSE; } - $rc = parent::accept_exposed_input($input); - if ($rc) { - // If we have previously validated input, override. - if (isset($this->validated_exposed_input)) { - $this->value = $this->validated_exposed_input; - } - } - - return $rc; + return parent::accept_exposed_input($input); } /** * {@inheritdoc} */ public function exposed_validate(&$form, &$form_state) { - if (empty($this->options['exposed'])) { + if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) { return; } - $identifier = $this->options['expose']['identifier']; - // We only validate if they've chosen the text field style. if ($this->options['type'] != 'textfield') { - if ($form_state['values'][$identifier] != 'All') { - $this->validated_exposed_input = (array) $form_state['values'][$identifier]; + $input = $form_state['values'][$this->options['expose']['identifier']]; + if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) { + $input = $this->options['group_info']['group_items'][$input]['value']; } - return; - } - if (empty($this->options['expose']['identifier'])) { + if ($input != 'All') { + $this->validated_exposed_input = (array) $input; + } return; } - $values = $this->isMultiValued() ? drupal_explode_tags($form_state['values'][$identifier]) : array($form_state['values'][$identifier]); - - $tids = $this->validate_term_strings($form[$identifier], $values); - if ($tids) { - $this->validated_exposed_input = $tids; - } + parent::exposed_validate($form, $form_state); } /** - * Validate the user string. Since this can come from either the form - * or the exposed filter, this is abstracted out a bit so it can - * handle the multiple input sources. - * - * @param $form - * The form which is used, either the views ui or the exposed filters. - * @param $values - * The taxonomy names which will be converted to tids. - * - * @return array - * The taxonomy ids fo all validated terms. + * {@inheritdoc} */ - public function validate_term_strings(&$form, $values) { + protected function validate_entity_strings(array &$form, array $values) { if (empty($values)) { return array(); } @@ -358,58 +297,14 @@ class SearchApiViewsHandlerFilterTaxonomyTerm extends SearchApiViewsHandlerFilte } /** - * Determines whether multiple terms can be entered into this filter. - * - * This is either the case if the form isn't exposed, or if the "Allow - * multiple selections" option is enabled. - * - * @return bool - * TRUE if multiple values can be entered for this filter, FALSE otherwise. - */ - protected function isMultiValued() { - return empty($this->options['exposed']) || !empty($this->options['expose']['multiple']); - } - - /** - * {@inheritdoc} - */ - function admin_summary() { - // set up $this->value_options for the parent summary - $this->value_options = array(); - - if ($this->value) { - $this->value = array_filter($this->value); - $result = db_select('taxonomy_term_data', 'td') - ->fields('td') - ->condition('td.tid', $this->value) - ->execute(); - foreach ($result as $term) { - $this->value_options[$term->tid] = $term->name; - } - } - return parent::admin_summary(); - } - - /** * {@inheritdoc} */ - public function query() { - if ($this->operator === 'empty') { - $this->query->condition($this->real_field, NULL, '=', $this->options['group']); - } - elseif ($this->operator === 'not empty') { - $this->query->condition($this->real_field, NULL, '<>', $this->options['group']); - } - elseif (count($this->value) == 1) { - $this->query->condition($this->real_field, reset($this->value), $this->operator, $this->options['group']); - } - else { - $filter = $this->query->createFilter($this->operator === '<>' || $this->operator === 'all of' ? 'AND' : 'OR'); - foreach ($this->value as $value) { - $filter->condition($this->real_field, $value, $this->operator === 'all of' ? '=' : $this->operator); - } - $this->query->filter($filter, $this->options['group']); - } + protected function ids_to_strings(array $ids) { + return implode(',', db_select('taxonomy_term_data', 'td') + ->fields('td', array('name')) + ->condition('td.tid', array_filter($ids)) + ->execute() + ->fetchCol()); } } diff --git a/contrib/search_api_views/includes/handler_filter_user.inc b/contrib/search_api_views/includes/handler_filter_user.inc index 0cfba71..e3abd95 100644 --- a/contrib/search_api_views/includes/handler_filter_user.inc +++ b/contrib/search_api_views/includes/handler_filter_user.inc @@ -10,44 +10,13 @@ * * Based on views_handler_filter_user_name. */ -class SearchApiViewsHandlerFilterUser extends SearchApiViewsHandlerFilter { - - /** - * If exposed form input was successfully validated, the entered user UIDs. - * - * @var array - */ - protected $filtered_uids; - - /** - * {@inheritdoc} - */ - public function option_definition() { - $options = parent::option_definition(); - $options['expose']['multiple']['default'] = TRUE; - return $options; - } - - /** - * {@inheritdoc} - */ - public function operator_options() { - return array( - '=' => $this->isMultiValued() ? t('Is one of') : t('Is'), - '<>' => $this->isMultiValued() ? t('Is not one of') : t('Is not'), - 'empty' => t('Is empty'), - 'not empty' => t('Is not empty'), - ); - } +class SearchApiViewsHandlerFilterUser extends SearchApiViewsHandlerFilterEntity { /** * {@inheritdoc} */ public function value_form(&$form, &$form_state) { parent::value_form($form, $form_state); - if (!is_array($this->value)) { - $this->value = $this->value ? array($this->value) : array(); - } // Set autocompletion. $path = $this->isMultiValued() ? 'admin/views/ajax/autocomplete/user' : 'user/autocomplete'; @@ -57,26 +26,19 @@ class SearchApiViewsHandlerFilterUser extends SearchApiViewsHandlerFilter { // value is present). The value is used if the form is either not exposed, // or the exposed form wasn't submitted yet (there is if ($this->value && (empty($form_state['input']) || !empty($form_state['input']['live_preview']))) { - $form['value']['#default_value'] = $this->uids_to_names($this->value); + $form['value']['#default_value'] = $this->ids_to_strings($this->value); } } /** - * Transforms an array of UIDs into a comma-separated list of names. - * - * @param array $uids - * The UIDs to transform. - * - * @return string - * A string containing the names corresponding to the UIDs, separated by - * commas. + * {@inheritdoc} */ - protected function uids_to_names(array $uids) { + protected function ids_to_strings(array $ids) { $names = array(); - $args[':uids'] = array_filter($uids); + $args[':uids'] = array_filter($ids); $result = db_query("SELECT uid, name FROM {users} u WHERE uid IN (:uids)", $args); $result = $result->fetchAllKeyed(); - foreach ($uids as $uid) { + foreach ($ids as $uid) { if (!$uid) { $names[] = 'Anonymous'; } @@ -90,75 +52,7 @@ class SearchApiViewsHandlerFilterUser extends SearchApiViewsHandlerFilter { /** * {@inheritdoc} */ - public function value_validate($form, &$form_state) { - if (!empty($form['value'])) { - $value = &$form_state['values']['options']['value']; - $values = $this->isMultiValued($form_state['values']['options']) ? drupal_explode_tags($value) : array($value); - $uids = $this->validate_user_strings($form['value'], $values); - - if ($uids) { - $value = $uids; - } - } - } - - /** - * {@inheritdoc} - */ - public function accept_exposed_input($input) { - $rc = parent::accept_exposed_input($input); - - if ($rc) { - // If we have previously validated input, override. - if ($this->filtered_uids) { - $this->value = $this->filtered_uids; - } - } - - return $rc; - } - - /** - * {@inheritdoc} - */ - public function exposed_validate(&$form, &$form_state) { - if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) { - return; - } - - $identifier = $this->options['expose']['identifier']; - $input = $form_state['values'][$identifier]; - - if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) { - $this->operator = $this->options['group_info']['group_items'][$input]['operator']; - $input = $this->options['group_info']['group_items'][$input]['value']; - } - - $values = $this->isMultiValued() ? drupal_explode_tags($input) : array($input); - - if (!$this->options['is_grouped'] || ($this->options['is_grouped'] && ($input != 'All'))) { - $this->filtered_uids = $this->validate_user_strings($form[$identifier], $values); - } - else { - $this->filtered_uids = FALSE; - } - } - - /** - * Validates the user string. - * - * Since this can come from either the form or the exposed filter, this is - * abstracted out a bit so it can handle the multiple input sources. - * - * @param array $form - * The form or form element for which any errors should be set. - * @param array $values - * The entered user names to validate. - * - * @return array - * The UIDs corresponding to all user names that could be found. - */ - protected function validate_user_strings(array &$form, array $values) { + protected function validate_entity_strings(array &$form, array $values) { $uids = array(); $missing = array(); foreach ($values as $value) { @@ -187,58 +81,4 @@ class SearchApiViewsHandlerFilterUser extends SearchApiViewsHandlerFilter { return $uids; } - /** - * Determines whether multiple user names can be entered into this filter. - * - * This is either the case if the form isn't exposed, or if the " Allow - * multiple selections" option is enabled. - * - * @param array $options - * (optional) The options array to use. If not supplied, the options set on - * this filter will be used. - * - * @return bool - * TRUE if multiple values can be entered for this filter, FALSE otherwise. - */ - protected function isMultiValued(array $options = array()) { - $options = $options ? $options : $this->options; - return empty($options['exposed']) || !empty($options['expose']['multiple']); - } - - /** - * {@inheritdoc} - */ - public function admin_summary() { - $value = $this->value; - $this->value = empty($value) ? '' : $this->uids_to_names($value); - $ret = parent::admin_summary(); - $this->value = $value; - return $ret; - } - - /** - * {@inheritdoc} - */ - public function query() { - if ($this->operator === 'empty') { - $this->query->condition($this->real_field, NULL, '=', $this->options['group']); - } - elseif ($this->operator === 'not empty') { - $this->query->condition($this->real_field, NULL, '<>', $this->options['group']); - } - elseif (is_array($this->value)) { - if (count($this->value) == 1) { - $this->query->condition($this->real_field, reset($this->value), $this->operator, $this->options['group']); - } - else { - $neg = $this->operator == '<>'; - $filter = $this->query->createFilter($neg ? 'AND' : 'OR'); - foreach ($this->value as $value) { - $filter->condition($this->real_field, $value, $this->operator); - } - $this->query->filter($filter, $this->options['group']); - } - } - } - } diff --git a/contrib/search_api_views/search_api_views.info b/contrib/search_api_views/search_api_views.info index f87866b..edef611 100644 --- a/contrib/search_api_views/search_api_views.info +++ b/contrib/search_api_views/search_api_views.info @@ -16,6 +16,7 @@ files[] = includes/handler_argument_taxonomy_term.inc files[] = includes/handler_filter.inc files[] = includes/handler_filter_boolean.inc files[] = includes/handler_filter_date.inc +files[] = includes/handler_filter_entity.inc files[] = includes/handler_filter_fulltext.inc files[] = includes/handler_filter_language.inc files[] = includes/handler_filter_options.inc