Posted by Pierre Paul Lefebvre on September 12, 2012 at 6:08pm
9 followers
| Project: | Drupal core |
| Version: | 8.x-dev |
| Component: | views.module |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Pierre Paul Lefebvre |
| Status: | patch (to be ported) |
Issue Summary
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".
Comments
#1
.... The handler doesn't support "Contains word". Here is a patch.
#2
Completely forgot to split all the words. Inspired greatly from views_handler_filter_string.
#3
Was matching all words instead of each word.
#4
#5
Was your intention to omit matches of words prefixed by a minus? As you're saving a minus in $matches when prefixed.
#6
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.
#7
Found the same issue on my D7.15 minimal install + views 3.5. The fix in #3 worked for me.
#8
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()".
#9
While we're at it, I fixed all the other standards, except function docs and uppercase on the class name.
#10
This looks pretty fine!
#11
Yay! My first patch got approved! :D
#12
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.
#13
hey, thanks for the patch
What about making the search case-insensitive? now i'm getting results only for matching case
#14
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.
#15
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
#16
Thank Pierre! Works for me (case insensitive works too, srgk)
#17
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,
),
#18