Problem/Motivation
Given that you have a View configured to use term names as arguments.
Given that the View tries to validate these terms against one vocabulary.
Given that you have two terms, in two different vocabularies, that have the exact same name.
When you try to use this term name as an argument in your View, it is rejected by the \Drupal\taxonomy\Plugin\views\argument_validator\TermName::validateArgument() method even if it should not.
Here is how the TermName::validateArgument() currently works:
load all the terms that matches the argument name
for each term
if the term does not belong to an allowed vocabulary
return FALSE
// If ALL the terms belongs to an allowed vocabulary
return TRUE
Note 1: If we are in that case and we force this validator to pass, the argument still uses the good term for the SQL request.
Note 2: that argument validator does not support multiple values
Steps to reproduce
- Install Drupal standard
- Create a vocabulary "Test" with a term "Yolo"
- Create a term "Yolo" in the vocabulary "Tags"
- Create an "Article" node using the "Yolo" tag
- Create a view of articles
- Add a "Taxonomy term referenced from field_tags" relation
- Add a "Taxonomy term: Name" argument with a "Taxonomy term name" validation criteria restricted on "Tags" vocabulary
- In the preview contextual filters, input "Yolo" then submit
Expected result: your article is shown
Current restult: "No query was run"
Remaining tasks
| Task | Novice task? | Contributor instructions | Complete? |
|---|---|---|---|
| Create a patch | Instructions | Done | |
| Reroll the patch if it no longer applies. | Instructions | Done | |
| Update the issue summary | Instructions | Done | |
| Add automated tests | Instructions | ||
| Update the patch to incorporate feedback from reviews (include an interdiff) | Instructions | Done | |
| Manually test the patch | Novice | Instructions | Done |
| Add steps to reproduce the issue | Novice | Instructions | Done |
| Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards | Instructions | Done |
Proposed resolution
Fix TermName::validateArgument() so it works this way:
load all the terms that matches the argument name
for each term
if the term belongs to an allowed vocabulary
return TRUE
// If none of the terms belongs to an allowed vocabulary
return FALSEUser interface changes
None.
API changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #109 | interdiff_107-109.txt | 4.79 KB | danflanagan8 |
| #109 | 2494617-109.patch | 15.29 KB | danflanagan8 |
| #107 | interdiff_105-107.txt | 1.41 KB | danflanagan8 |
| #107 | 2494617-107.patch | 11.88 KB | danflanagan8 |
| #105 | interdiff_104-105.txt | 694 bytes | danflanagan8 |
Comments
Comment #1
bès commentedComment #2
bès commentedComment #3
dawehnerMh, are you sure this is the expected behaviour?
I would assume that you want to validate all entries. Do you remember how the behaviour has been in Drupal 7?
Comment #4
bès commentedOops it's not the good patch, sorry
Comment #5
bès commentedI think the behavior is good. I add a screenshot of the configuration screen for that.

We want to validate that a taxonomy term passed in the url match a specifc sets of vocabularies.
If we have multiple terms existing we need to check that at least one term match one of the vocabulaires not all of them.
Comment #6
jibranCan we create some tests for the problem described in IS?
Comment #7
dawehnerHonestly, I would expect that all the terms match the configured list of vocabularies ... because this is what you want to filter by at the end ...
Comment #8
bès commentedThe multiple terms that I talked about are terms that are not passed as argument but just terms in the databases.
Let's say that I have 2 vocabularies "Tags" and "Country".
In each of theses I have the term "France".
Then I configure the views as this screenshot

If the view receive "France" as its only one arguments, the test will fail because it will test again the "France" from the "Country" vocabulary.
Anyway, thanks @dawehner because you also right that my patch is not good in case we have multiple terms passed as argument. I will work on that.
Comment #9
bès commentedAfter verification the TermName argument validator is not multiple arguments capable. So we don't have to care of that for now.
Comment #10
bès commentedI assume that this issue https://www.drupal.org/node/1739846 will help me to add a more specific test case once it will be closed.
Comment #11
dawehnerThat argument is convincing ... yeah that code is just no obvious to read.
I think instead we should not add the todo here but rather make the entire logic easier to read, until we potentially have multiple terms support.
Comment #12
duaelfrWe have multiple term support. The validator is called once per value in the argument.
(I just updated the IS with a bunch of information)
Comment #13
duaelfrComment #14
duaelfrFixed pseudo code indentation.
Comment #15
bès commentedNo TermName argument_validator does not currently support multiple term (via , or + signs)
Comment #16
duaelfrFixed the IS, sorry for that misunderstanding.
Comment #17
bès commentedCross post with @DuaelFr during IS edition :)
Please let the multiple term stuff out of the range of this issue since it leads to misunderstanding. If we need this feature we can open a new issue for that.
In our case and to be clear about the code, the $terms in the patch is an array of all the terms in the database, that match the argument name.
Comment #18
duaelfrWe are going to finalize this patch this afternoon.
Comment #19
bès commentedHere is a patch with a new version that only load the terms from bundles that has to be validated. Also contains tests.
Comment #20
dawehnerThis certainly is an improvement, fixes a bug and adds test coverage, even I still think that using the foreach which technically isn't is really confusing.
Do you mind adding a newline? I guess someone can do that on commit as well.
Comment #21
bès commentedHere is a new version with the newline.
About the foreach, I remember our irc chat about the possibility of removing it. But, we found that we need to test each term via validateEntity() because it also check access.
Comment #23
bès commentedreroll test
Comment #26
duaelfrTestbot is still happy and the newline is there.
So, let's RTBC and get this bug fixed!
Comment #27
alexpottSo if $bundles is empty this will fatal because $terms is not defined. We're obviously missing test coverage.
Comment #28
drubbModified patch #21 for empty bundles.
Comment #29
drubbComment #30
duaelfrThat looks good to me.
Thank you @drubb
Comment #33
lendudeLooks great, just a bit of nitpicking:
Can we make this a proper english sentence that actually describes what's happening?
maybe change this to !empty and move the foreach into this, bit more concise.
Comment #34
shreya shetty commentedto make it more concise added !empty condition
Comment #35
shreya shetty commentedComment #36
duaelfr@Shreya Shetty thank you for your work but I think that there is something wrong in the patch you posted.
Previous patch file was 10.1KB, yours is 4.13KB and contains a lot of unwanted changes (mostly on coding standards but not only).
You should restart from #28 and just change what's asked in #33. If you do that, please also post an interdiff file.
If needed, you can find a good documentation of what to do on these pages :
- https://www.drupal.org/contributor-tasks/create-patch
- https://www.drupal.org/novice
Comment #37
shreya shetty commentedComment #38
shreya shetty commentedComment #39
lendudeI think this is almost ready, but needed a bit of a clean up I feel. Fixed some comments, added some comments, took out the mockStandardInstall bit and just moved it to setup.
Also added a test only patch cause we didn't have one of those yet.
Comment #41
duaelfrExcellent! Thank you @Lendude!
I made a round of manual testing and the bug is still fixed by the last patch.
Nothing to add about the code neither.
Let's get it commited! :)
Comment #42
alexpottNot the same logic... why has this changed? And is this change correct?
loadByProperties always returns an array so checking if empty is not needed.
Comment #43
lendude1. Yeah that's the whole point of this fix, instead of returning FALSE when one term doesn't pass, return TRUE when one term does pass and only return FALSE when all terms don't pass.
2. Good point, fixed.
also put the use statements in the right order.
Comment #44
duaelfrStill working :)
Comment #45
alexpottSome minor code style things to fix up.
Comment #46
lendudefixed code style per #45
Comment #47
duaelfrThanks @alexpott and @Lendude
All clear!
Comment #48
alexpottLooking at other argument validators (eg.
\Drupal\user\Plugin\views\argument_validator\UserName) I think we should revert this and check emptiness of $terms above. This means that if we ever make theTermNamemultiple capable then this logic will still work correctly. Also (and more importantly) if the result is not limited by bundle and there a two terms with the same name in different bundles - one which the user has access to and one which they don't - the current behaviour in HEAD is to return FALSE. With the current patch it would return TRUE. I don't think this behaviour change is desired.Comment #49
duaelfr@alexpott let's split your comment in two parts.
1- regarding the multiple capacity.
This validator does not need to be multiple capable as Views sends it the values one by one. It might allow to optimize a bit but I'm not even sure it's possible. The change you ask for is quite simple so we could do it, though.
2- regarding the access control.
The purpose of this validator is to validate that the given term name belong to a term in the wanted vocabularies and of which the user has access. Somewhere else or somehow else, Views uses the proper term for its request.
Currently, if two terms have the same name, one you can access and the other you cannot, this validator is going to deny you the access to the View. I don't think it's the behavior we want.
Comment #50
alexpottWell at the very least we need to add a test around this behaviour BUT also this is different what happens with Term for example where if you can't access any of the terms it will prevent access. I'm not convinced the behaviour change is desired - if you have per bundle access on Terms you need to limit views using this argument to a specific bundle (imo).
Comment #51
bès commentedThis behaviour has been changed between D7 and D8. I tested that on a D7 installation with TAC
Given two taxonomies : Tags and taxo both with the 'test' term.
The taxo 'test' term is deny for auth.
With a view that do not bundle filer.
When access to /path/to/view/test admin user can see the contents and auth only the one in Tags.
http://i.haza.fr/di/9J95/2494617-d7-test.png
Comment #52
bès commentedComment #53
duaelfrComment #54
duaelfr@alexpott about your comparison with the Term validator, I think we cannot really do the same. The thing is that the Term validator take a TID as argument which cannot match more than one term. So it's normal that if the user cannot access this term we deny immediately return FALSE. In our case, the same term name can match a lot of different terms, even in the same vocabulary. Plus, I agree with @Bès about the regression, I made the same tests as him under D7 and it used to work well.
Do we still need to revert something as you said in #48 or is the last patch OK?
Comment #55
alexpott@Bès nice work testing this on D7.
So this is tricky because something that was an empty view currently in D8 will now have a response but it appears that this is the way it was in D7. I definitely think we need a test of the behaviour regardless of how we solve it and I would like the views maintainers to have a think about what is best to do...
Comment #56
dawehnerRegarding changing the logic back to d7. Beside earlier disagreements in the issue, I agree now, especially because we just support the single usecase currently, this change is what we want. What matters is to make it possible to see information, those would be otherwise exposed on the site most probably anyway.
Yeah adding some test coverage for multiple passed in names would be nice, just to check/document what happens (it won't be splitted). Adding test coverage for the bundle filtering would be nice as well.
Comment #57
lendude56.1 Not quite sure what you mean. Is it ok as it is, or should we change anything?
56.2 Added two tests.
Comment #58
dawehnerYes, it is okay. I was just thinking loud.
What about adding the term to two vocabularies, one which is allowed and one which isn't as well?
Comment #59
lendudethat's this one, was already in there, might need to update the comment to make that a little more clear
Comment #60
dawehnerOh interesting, but I thought about the case where this is valid ... when the term actually exists.
Comment #61
lendudeSorry, I don't follow your line of thought. In that test the terms actually exists in both vocabularies, one that is in the the bundle settings, and one that isn't.
Comment #62
dawehnerPlease call be stupid, but why is this then an invalid term name?
Comment #63
duaelfrIs it a simple way in Core to deny access to a particular taxonomy term? It'd make that test easier.
Comment #64
stborchertDumb question: does using the term name validator works for you using the patch? I mean, the path is working fine and fixes the validator in general, but ... the term name is never converted to a term ID and this filters the result query using a wrong value.
Using the validator and a simple term reference field as argument, the query looks like this:
WHERE (( (node__field_channel.field_channel_target_id = 'ideas' ) ) ...In Drupal 7 we had an additional option how to handle the argument ("Filter value type"). Do we want to convert the term name always to the ID or do we need to implement the value type selector?
Comment #65
stborchertAdded the conversion to always use the term ID.
Comment #66
bès commented@stBorchert did you use a term name argument ? To do so you should add a relationship to a taxonomy reference field. Then choose "Taxonomy term: Name" contextual filters, using this relationship.
If you choose a "Has taxonomy term ID" filter or others it is not relevant to try using the taxonomy term name validator.
Comment #67
stborchertNo, I've used the term field directly without any reference. I expected it to work, since Drupal 7 acted like this ...
Comment #68
Saphyel commentedIn D7 the behaviour was you get a name and it'll be convert to an ID, right?
if in D8 we know that looking for ID is working fine... why duplicate code?
Comment #69
bès commentedIn my case I really want to validate term name and not term ID, so I don't see the problem to have a "term validation name" when the goal is to test that the term name passed to the filter match the good condition (that it could to be in multiple vocabulary for instance). If you use term ID you can't do that since it referrer to only one term.
I can see that maybe having the choice of irrelevant validation method is a problem, but it's not the frame of this issue. You could also choose to validate your term name with file ID or role validator and it will obviously don't work, but it's a views UI issue.
Comment #70
stborchertOk, I see the point here.
So its either using different validators for different requirements (
TermNameToTid, etc.) or implement something like the type-selector as in Drupal 7.Comment #73
boobaaRerolled @stBorchert's patch from #65 without the term name to term ID conversion.
Comment #75
duaelfrRerolled against 8.4.x
Comment #76
duaelfrI did some manual testing while writing the steps to reproduce and reviewed the coding standards while rerolling.
If the testbot is OK, it should be good to go.
Comment #78
rjg commented#76 has been working for us for many months.
Comment #80
dwwAgreed, this validator is definitely not working as expected. Especially when used with the most obvious possible contextual filter: core's "Has taxonomy term ID". In D7, there was a single taxonomy term validator that let you choose the style of validation you wanted, and it had an option for 'Term name converted to Term ID' which is actually what you want (since it leads to the most efficient queries). Sadly, all that is (for now) gone from D8 core.
I'd like to completely fix this at some point, consolidate all the term-related argument validation into a single plugin that lets you configure what kind of validation (and optional transformation) you want. It would simultaneously let this use case work smoothly, and simplify the UI by removing the 2 different 'Taxonomy term name' and 'Taxonomy term ID' choices (presented to all possible contextual filters).
Until then, for anyone else who needs the good ole' 'Term name converted to Term ID' functionality, enjoy:
https://www.drupal.org/project/views_taxonomy_term_name_into_id
Comment #81
malcolm_p commentedThe patch in #75 is working for me as well. I'm testing against a very basic case that fails currently with a term name in 2 different vocabularies.
This bug can be very confusing for site builders so hopefully we can get this into 8.6 before code freeze.
Comment #83
tea.time commentedI encountered this and it definitely caused a good moment of confusion for me too.
The patch in #75 still applied cleanly to 8.5.x and 8.6.x for me. It's working to resolve the same case, of a single-value argument validated against one vocabulary, and with two terms with the same name in different vocabularies.
Comment #84
dpagini commentedConsidering #78, #81 and #83, I can also confirm this is working for me, and am bumping to RTBC for maybe the next step review...?
Comment #86
alexpottThis needs to be converted to use
\Drupal\Tests\taxonomy\Functional\TaxonomyTestBaseand moved tocore/modules/taxonomy/tests/src/Functional/Views/ArgumentValidatorTermNameTest.phpas WebTestBase tests are deprecated. At this point we should not be adding more.Comment #88
alisonFWIW #75 still works great for me on 8.6.10!
Comment #89
rabbitlair commentedI would like to confirm #75 is working for me on 8.6.13.
Comment #90
knaffles commented#75 works for me on 8.7.3.
Comment #91
alisonComment #93
alison(#75 still works on 8.7.7!)
Comment #96
lendudeDuplicates: #3202689: Term name as contextual filter doesn't work if there are terms in other taxonomies and #3029807: Views Taxonomy contextual filter issue closed
Comment #97
joey-santiago commentedAdding a patch with a working test for this.
Comment #98
mvantuch commentedI had raised the dupplicate #3029807 and can verify that as far as I can see, #75 is doing exactly the same thing as the patch I had provided there.
Comment #99
nikitagupta commentedComment #100
adambraun commented#99 worked great. Attempting to mark Reviewed and Test by the Community.
Comment #101
adambraun commentedComment #104
danflanagan8I'm interested in helping to get this issue over the finish line. The latest patch has tests, but there are two problems with the tests:
1. They have never been run by the testbot without the fix applied
2. The tests could more closely imitate the tests for other argument_validators.
I'm attaching a test-only patch that uses the test View that is present in that latest patch (with the change of the name
tagstoviews_testing_tags). I have removed the Functional test and replaced it with a Kernel test that is very closely modeled off of the test for the taxonomy term id argument validator. Kernel is faster than Functional, so this gains us speed in addition to consistency.There's no interdiff because I don't think it would help.
Update: This is a long and winding issue, no? I just found comment #57 which included a test that is nearly identical to the one I added, and a slightly less ambitious one was added in #39. That one was even run as a test-only fail patch. Somehow that test got lost and was replaced with the Functional test that was still present in #99.
Comment #105
danflanagan8Fixing spelling...
Comment #107
danflanagan8The new test failed just as anticipated. Removing the Needs tests tag.
Now I'm adding the fix from #99. This should pass.
Comment #108
danflanagan8A couple things I'm thinking about now that I've spent more time reading through the issue:
We could go on all day with adding tests though. Part of the problem here is that there is apparently no existing (direct) test coverage for the taxonomy_term_name argument validator. So how much coverage do we need to add before we are happy committing this fix that has been used by many sites for many years? It's a tough situation.
Comment #109
danflanagan8I figured it wouldn't hurt to just go ahead and bulk up the test coverage. Here's a new patch with more tests. If you look at the interdiff, you'll see that this is purely additions, with the exception of a changed comment. Therefore we don't need to do a new test-only patch.
I think the new access check tests give us a very good frame of reference for further discussion if we need it. There's a few more additions too including validation of multiple names (not supported) and tests that change the
bundlesarray.Comment #111
joey-santiago commentedConfirm the patch #109 works great. Thanks a lot!
Comment #112
joey-santiago commentedComment #114
danflanagan8That was a random fail. Resetting status.
Comment #117
catchCommitted/pushed to 10.1.x and cherry-picked back through to 9.4.x, thanks!
Removing the 'needs subsystem maintainer' review tag since both dawehner and lendude have reviewed this in the six years since that tag was added.