This is a 2 part issue related to this use case:
problem: Joe user wants to compose a view that shows all content of type salad that has any one of 3 ingredients (stored as taxonomy terms). That view needs to also filter the salads dynamically via the url to only show for a specific ingredient.
solution: a view is composed with a taxonomy->tid filter that limits to only the 3 desired ingredients/terms. the taxonomy->tid argument is then applied with "if no argument is supplied, show all values" and validation is set to the same "ingredients" vocabulary.
part one of this issue when you compose a view that has both a filter and an argument for taxonomy->tid, the many_to_one argument handler takes the values that are specifically specified in the filter, and negates them out in the join. the desired output based on this functionality should be a join that looks something like:
....
LEFT JOIN term_node term_node2 ON node.vid = term_node2.vid AND (term_node2.tid != 3 AND term_node2.tid != 2 AND term_node2.tid != 6)
...but in actuality you get only the last selected term from the filter value:
....
LEFT JOIN term_node term_node2 ON node.vid = term_node2.vid AND term_node2.tid != 6
...this is due to a foreach() in handlers.inc that loops through all the values passed in the many_to_one queue, but only sets the current index to $join->extra in this code:
// views/includes/handlers.inc line 683
...
foreach ($this->handler->value as $value) {
$join = $this->get_join();
if ($this->handler->operator == 'and') {
$join->type = 'INNER';
}
$join->extra = array(
array(
'field' => $this->handler->real_field,
'value' => $value,
'numeric' => !empty($this->handler->definition['numeric']),
),
);
...a patch that addresses this part of the issue is attached, but probably needs lots of refinement and testing.
part 2 of this issue is that if this is implemented, you wind up with a query that looks like so:
SELECT node.nid AS nid,
node.title AS node_title,
node.changed AS node_changed
FROM node node
INNER JOIN term_node term_node ON node.vid = term_node.vid
LEFT JOIN term_node term_node2 ON node.vid = term_node2.vid AND (term_node2.tid != 3 AND term_node2.tid != 2 AND term_node2.tid != 6)
WHERE (node.type in ('salad')) AND (term_node.tid IN (3, 2, 6)) AND (term_node2.tid = 3)
Note that term_node2 is filtering out tid's 2,3 & 6, then specifically looking for tid 3 in the where clause. This is because the argument is excluding the values from the filter even though they are allowed values it can filter by.
I'd suggest a few possible approaches here.
1) it might make sense for the multiple to one functionality to distinguish between filters and arguments to keep them separate from each other.
2) make term_node not participate in the multiple to one functionality.
3) allow users to chose an opt in / opt out of the multiple to one functionality
I'm happy to put together a patch for this, but I'd rather go the approach people want rather than what I want :)
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 982728-handler_extra.patch | 1.02 KB | dawehner |
| views_handler_extra_bug.patch | 1.3 KB | netw3rker |
Comments
Comment #1
netw3rker commentedswitched this to the proper version.. selected 2.9 before whoops ;)
Comment #2
netw3rker commentedComment #3
dawehnerI'm not convinced totally.
Don't you want to avoid to override $join->extra?
So what about this patch?
Comment #4
ludo.rI have a similar issue.
My view takes a termID as an argument from URL.This argument is always present.
I added a taxonomy term filter to include the termIDs that can be displayed (Is one of).
But it seems the request always exclude the last termID from the results :
Do you see this?
AND term_node2.tid != 83So when i want to show the termID 83 the request returns no result.
When using termID 79,81 or 82 it works.
If i uncheck the termID from the filter, then it is the termID 83 that is excluded :
Am i missing something or is this a bug?
Comment #5
dawehnerBefore committing that patch someone definitive has to test that.
Comment #6
tim.plunkettFixing tag.
Comment #9
mustanggb commented