With a clean install of drupal-7.15, views 7.x-3.5 (stable and -dev), the "Combine fields filter" doesn't work.

Exposed or not. With Devel installed and debugging enabled, I get :
Exception in test[test]: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'CONCAT_WSnode.titlefield_data_body.body_value' in 'where clause'

This is a clean install, so no strange field type or strange data.

Here is the view :

<?php
$view
= new view();
$view->name = 'test';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'test';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'test';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
$handler->display->display_options['row_options']['inline'] = array(
 
'title' => 'title',
);
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: Body */
$handler->display->display_options['fields']['body']['id'] = 'body';
$handler->display->display_options['fields']['body']['table'] = 'field_data_body';
$handler->display->display_options['fields']['body']['field'] = 'body';
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Global: Combine fields filter */
$handler->display->display_options['filters']['combine']['id'] = 'combine';
$handler->display->display_options['filters']['combine']['table'] = 'views';
$handler->display->display_options['filters']['combine']['field'] = 'combine';
$handler->display->display_options['filters']['combine']['operator'] = 'word';
$handler->display->display_options['filters']['combine']['value'] = 'aye';
$handler->display->display_options['filters']['combine']['exposed'] = TRUE;
$handler->display->display_options['filters']['combine']['expose']['operator_id'] = 'combine_op';
$handler->display->display_options['filters']['combine']['expose']['label'] = 'Combine fields filter';
$handler->display->display_options['filters']['combine']['expose']['operator'] = 'combine_op';
$handler->display->display_options['filters']['combine']['expose']['identifier'] = 'combine';
$handler->display->display_options['filters']['combine']['expose']['remember_roles'] = array(
 
2 => '2',
 
1 => 0,
 
3 => 0,
);
$handler->display->display_options['filters']['combine']['fields'] = array(
 
'title' => 'title',
 
'body' => 'body',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;
$handler->display->display_options['path'] = 'test';
?>

Thanks for all the hard work

Edit : it works with "Contains", but it doesn't work with "Contains any word".

Files: 
CommentFileSizeAuthor
#9 combine_and_contains_word-1782678-9.patch3.68 KBPierre Paul Lefebvre
PASSED: [[SimpleTest]]: [MySQL] 1,603 pass(es).
[ View ]
#3 combine_and_contains_word-1782678-3.patch2.67 KBPierre Paul Lefebvre
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]
#2 combine_and_contains_word-1782678-2.patch2.51 KBPierre Paul Lefebvre
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]
#1 combine_and_contains_word-1782678-1.patch1.83 KBPierre Paul Lefebvre
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]

Comments

Pierre Paul Lefebvre’s picture

StatusFileSize
new1.83 KB
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]

.... The handler doesn't support "Contains word". Here is a patch.

Pierre Paul Lefebvre’s picture

Assigned:Unassigned» Pierre Paul Lefebvre
Status:Active» Needs review
StatusFileSize
new2.51 KB
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]

Completely forgot to split all the words. Inspired greatly from views_handler_filter_string.

Pierre Paul Lefebvre’s picture

StatusFileSize
new2.67 KB
PASSED: [[SimpleTest]]: [MySQL] 1,598 pass(es).
[ View ]

Was matching all words instead of each word.

Pierre Paul Lefebvre’s picture

Title:Combine fields filter doesn't work» "Combine fields" filter doesn't work with "Contains any word"
jorisdejong’s picture

Was your intention to omit matches of words prefixed by a minus? As you're saving a minus in $matches when prefixed.

Pierre Paul Lefebvre’s picture

To tell you the truth I just used the code from views_handler_filter_string.inc. I only changed how the where condition was called to make sure the CONCAT_WS was not stripped further down the pipe.

http://drupalcode.org/project/views.git/blob/HEAD:/handlers/views_handler_filter_string.inc
Line 260-291.

finne’s picture

Found the same issue on my D7.15 minimal install + views 3.5. The fix in #3 worked for me.

jorisdejong’s picture

Same for me in 7.x-3.5 (stable) and 7.x-3.x-dev. I have tested both "Contains any word" and "Contains all words". Code-wise it's all good to go.

For the sake of commenting standards you should capitalize the first letter of the bottom comment, and change "call_user_func_array" to "call_user_func_array()".

Pierre Paul Lefebvre’s picture

StatusFileSize
new3.68 KB
PASSED: [[SimpleTest]]: [MySQL] 1,603 pass(es).
[ View ]

While we're at it, I fixed all the other standards, except function docs and uppercase on the class name.

dawehner’s picture

Status:Needs review» Reviewed & tested by the community

This looks pretty fine!

Pierre Paul Lefebvre’s picture

Yay! My first patch got approved! :D

dawehner’s picture

Version:7.x-3.x-dev» 8.x-3.x-dev
Status:Reviewed & tested by the community» Patch (to be ported)

In general please try to avoid codestyle fixes which are unrelated with your actual patch, that's okay for this patch.

Congratulations to your first commit in views! Committed and pushed to 7.x-3.x
As for example the filename changed in d8, let's move it there.

srgk’s picture

hey, thanks for the patch

What about making the search case-insensitive? now i'm getting results only for matching case

Pierre Paul Lefebvre’s picture

Sure @srgk! Could you open another issue? This one is closed and already in -dev. I don't have time to do it this week, but I will make sure to do it at the beginning of next week.

srgk’s picture

Hey Pierre, thanks
if you have spare time, could you please look into the issue, i've created it here http://drupal.org/node/1805272

eloiguell’s picture

Thank Pierre! Works for me (case insensitive works too, srgk)

eloiguell’s picture

I added the operator "Not contains any word"

I added this code in views_handler_filter_combine.inc :

function op_not_word($field) {
    $where = $this->operator == 'word' ? db_and() : db_or();

    // Don't filter on empty strings.
    if (empty($this->value)) {
      return;
    }

    preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
      $phrase = FALSE;
      // Strip off phrase quotes.
      if ($match[2]{0} == '"') {
        $match[2] = substr($match[2], 1, -1);
        $phrase = TRUE;
      }
      $words = trim($match[2], ',?!();:-');
      $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
      $placeholder = $this->placeholder();
      foreach ($words as $word) {
        $where->where($field . " NOT LIKE $placeholder", array($placeholder => '%' . db_like(trim($word, " ,!?")) . '%'));
      }
    }

    if (!$where) {
      return;
    }

    // Previously this was a call_user_func_array() but that's unnecessary
    // as views will unpack an array that is a single arg.
    $this->query->add_where($this->options['group'], $where);
  }

And in views_handler_filter_string.inc added this:

'word' => array(
        'title' => t('Not contains any word'),
        'short' => t('not has word'),
        'method' => 'op_not_word',
        'values' => 1,
      ),
xjm’s picture

Project:Views» Drupal core
Version:8.x-3.x-dev» 8.x-dev
Component:exposed filters» views.module
xjm’s picture

Issue summary:View changes

adding details about the expression