Problem/Motivation
It is not reliable to deploy configuration of Views that reference taxonomy terms when the local site and production site are not exactly matching because they reference the Term ID (content) rather than the UUID. Creating a view which has a filter on a term from a node field should export to configuration with UUID filter values rather than taxonomy term entity IDs.
Steps to reproduce
- Create a term in a local site
- Content editor creates multiple a term in production in a different order than local
- Term IDs don't match but UUIDs would
- Since Term IDs don't match, the View is unexpectedly configured to filter by the wrong term.
Proposed resolution
Views configuration with filters on taxonomy terms should use the UUID of the entity chosen. On the front-end, keep everything using entity IDs. On the back-end (storage), store IDs as UUIDs, and convert them when passing between the front-end.
Remaining tasks
None:
Support viewing, editing and saving the filter form with text/autocomplete.Support viewing, editing and saving the filter form with select options.Ensure that views are displaying the correct results.Update existing schema: Ensure that views can be saved and re-read properly, with the same config.Migrate existing data: Add update hook to convert entity IDs in config to UUIDs.Fix test failures.
User interface changes
None
Introduced terminology
N/A
API changes
N/A
Data model changes
Views configuration will store references to taxonomy terms as UUIDs not IDs.
Release notes snippet
Change record added here: https://www.drupal.org/node/3464158
Original proposal
Add a checkbox to the filter configuration form to allow users to use the uuid of the term as the filter value rather than the tid.
As a stop-gap until this is implemented in core, I implemented it as a custom filter which extends the current taxonomy term id filter. This may help in determining which parts of the code need to be touched when implementing https://gist.github.com/acbramley/1127c4698a9ae86885e03716f47e3281
| Comment | File | Size | Author |
|---|
Issue fork drupal-2761157
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
nevergoneCool! Please create generic solution (not only taxonomy term, not only filter) and attach patch. Thanks! :)
Comment #7
sdrong commented@nevergone should this be optional? seems like it would be better to just use uuid by default unless there is a reason to keep tid/nid as the stored filtered id? Not sure providing a user facing interface to switch between one or other is going to be helpful. We migrated a lot of content and id drift between views and migrations is an issue for us currently.
Comment #10
leisurman commentedHas there been any new information on this topic? We would also like to use the UUID instead of NID and TID in Views filters. Our NID and TIDs are out of sync across server source and destination servers.
Comment #11
pburgh commentedThis causes an issue for us as well. Some of our view filters break each time configuration is imported.
Hopefully someone can address this.
Comment #12
tomasdev commentedIs there a patch that allows this to work? I am also having trouble when migrating configuration to different environments where taxonomies have different ids (but proper uuid)
Comment #13
Orestis Nerantzis commentedI don't know if there is a patch for this but i managed to solve this problem with module Default Content , which will import taxonomies to different enviroment with same tid so views won't break.
Hope it helps.
Comment #15
colanComment #16
colanAs alluded to by the IS, it looks like the IDs are being set in
core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid->valueForm(), which is tricky to sift through as it's way too long and has way too many nestedifs. It'll need to be refactored to make it understandable enough to work on.I agree with #7.
Here's the idea: Just use UUIDs, and forget about the checkbox. When reading them back from configuration, convert them to entity IDs. We can implement an update hook that migrates existing configuration with entity IDs to UUIDs. Then we won't need the checkbox.
Would there be any reason not to do that?
Comment #17
colanI'm trying to see what I can throw together.
Comment #18
colanThere's still work to do, but I'd like to see what the testbot says.
I updated the IS with tasks, and was able to get "Support viewing, editing and saving the filter form with text/autocomplete" working. I'll look at select options next (and keep refactoring).
Questions for to-dos:
Comment #19
larowlanIt happens in the
method - in there it sets $this->value (an array)
You might have a config-schema issue here - taxonomy.views.schema.yml is probably telling the config API that the filter value is an integer
Comment #20
colanThanks!
init()really did the trick. I believe all that's left (other than tests) is an update hook to update the schema and data within it.Comment #22
colanSo, how do I change the data type from an integer to a string in existing config? I can change the values, but they still come out as integers, even though I updated the schema definition. It looks like there's a way to do this with field configuration, but not with views. Views configurations don't seem to have a
toArray()method.Would someone kindly point me to an example?
Comment #23
colanFixed accidental status change.
Comment #24
colanSetting to NR so we're know what test failures come back; will turn to NW shortly.
It's possible we won't actually need additional tests for this as there seems to be coverage (given the failures), but it may be worthwhile to check if conversions between the ID types are happening (even though this wouldn't be functional testing).
I'm giving up for now as I spend enough time trying to figure out #22. If someone can provide a hint, I'll pick it up again. Alternately, having someone else figure this out would be great. I left a
@todoin the update hook.Also, I refactored
valueForm()some more, which has shrunken significantly. It should be much easier to see what's going on. (I can now see the entire thing in my IDE!)Comment #26
colanLooks like the last part of
views_update_8500()may be helpful here. (Thanks to @larowlan for the idea to look in there!)Comment #27
colanComment #28
colanI think I got it. The filters may be losing their vocabulary IDs, but this could just be my set-up. Further testing is required.
The above plan for an upgrade path wasn't workable because the way views configuration updates are done has changed. These now have to be done in Views post-save hooks. See #2989745: views_update_8500() inlines configuration changes instead of this being done on config save for bc for details.
Please test (as I'll be doing tomorrow) and report back.
Comment #30
colanI forgot to check for an unset array index.
Comment #32
colanWays to test
These are the processes I used to test, in order from top to bottom (as they lead into each other). They all work for me.
Upgrade path
Exporting configuration
Importing configuration
drush site-install.)Drupal.org test failures
There's now only one test failure, which looks like a test needs to be updated. I'll take a closer look. Updating status as not everything is green yet.
Given that, it looks like we have good coverage for this already so I don't believe we needs additional tests. Removing tag.
Comment #33
colanUpdating title.
Comment #34
colanHopefully this does it, changing the test ID value from an integer to a (UUID) string.
Comment #36
colanComment #38
colanHere's a reroll for 8.9.x.
Comment #40
lisa.rae commentedRerolled patch 38 against Drupal 9.2-dev, commit hash 1bcb278060b75c4f45c82cdb8784262c2f45723b
Comment #41
sja112 commentedComment #42
sja112 commentedRerolled patch 40 against Drupal 9.2.x branch
Comment #43
sja112 commentedWorking on issues reported in test
Comment #44
sja112 commentedComment #46
lisa.rae commentedComment #47
lisa.rae commentedComment #48
lisa.rae commentedComment #49
lisa.rae commentedComment #50
lisa.rae commentedComment #51
lisa.rae commentedComment #52
vsujeetkumar commentedFixing tests, missing class "Drupal\Core\Config\Entity\ConfigEntityUpdater" addes, Please have a look.
Comment #54
ravi.shankar commentedFixing failed tests of patch #52.
Comment #56
kkasson commentedWe've been using the patch from #38 successfully on an 8.9.x installation for a while now. We discovered one bug, using the patch causes the "Limit list to selected items" option to not work. We fixed that by changing line 10 of the getEntityIdsFromUuids function from
to
Not sure of any other possible consequences of that, but it seems to fix the above option.
Comment #57
vsujeetkumar commentedRe-roll patch to 9.3.x.
Comment #59
vsujeetkumar commentedTrying to fix Fail test, Not sure these test fix are up to date or not. Please have a look and advise.
Comment #61
vsujeetkumar commentedFixing the fail tests because of "accessCheck()".
Comment #62
colanUpdating status as per #56. Looks like that hasn't been included yet.
Comment #63
vsujeetkumar commentedWorked on #56 as mentioned in #62, Please have a look.
Comment #64
duaelfrPatch from #63 looks good and is working. I just had to make a quick reroll because taxonomy.post_update.php has been changed in 9.3.x.
Even if there are already a lot of coding standards issues in those files, shouldn't all new functions/methods have docblock comments?
Do not forget to clear cache after applying the patch and before running updates if you plan to use it right now.
Comment #66
andypostempty() called twice for no reason, it could always call function and have empty check inside
Also protected method needs docblock
Also reset() validates only first element of values
missing doc-block
better use loadMultiple() here
Comment #67
trafo commentedPost update hook does not update filters correctly, because it checks wrong array keys. I'd say we could just check for
taxonomy_index_tidviews filter plugin and update values.Comment #69
scott_euser commentedUpdated patch for 9.4.0, addresses feedback in #66 and #67.
An interdiff was not possible because patch was rejected, but other than addressing the feedback, I had to add lines 166-171 in core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php to have tests pass. The stored UUID in core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml does not match the UUIDs available, so no filter is applied. I therefore have the test update the View to select an existing Term and see if filtering works correctly. I feel a bit nervous that perhaps that is defying the point of this work, so please pay attention to that when reviewing. I could not find another way to resolve, but probably there is a better way than what I have done.
Comment #70
erikbrgn commented@scott_euser, just fixing the codesniffer errors in your patch.
Comment #72
rassoni commentedComment #73
c-logemannComment #74
jhedstromComment #76
larowlanout of scope
should this use an aggregate query instead of loading the terms or do the terms end up getting loaded anyway?
pretty sure the return is keyed by tid, so you can just array_combine with array_keys
Comment #77
rosk0There is no interdiff as the patch from #72 didn't want to apply to latest core on one of the inheritdoc tag that was mentioned in #76 as out of scope.
{@inheritdoc}with actual description for introduced in the patchgetFormValueOptions()Comment #78
joachim commented(Incomplete review, as about to serve up dinner.)
Should be 'Gets'.
Why would someone call this with IDs? What's the reason for this guard clause?
What's the reason for the aggregate query and group by?
What's configuration time?
Is the return keyed by tid? The @return should say.
Gets.
render array? But returned var is called $form_value, doesn't match up.
Written FormAPI, usually.
Comment #79
pooja saraah commentedAddressed the comment #78 Point 1,6,8
Keeping it needs work to address other points on #78
Attached patch against Drupal 10.1.x
Comment #80
shital.mahajan commentedThe scenario is missed when there is no term associated with the TID which is causing drush updb to fail.
(In our case there are TIDs in the views config files but the same TID wont be present on environment as TID is dynamic)
Modifying patch to handle such scenario
Comment #81
c-logemannComment #82
anchal_gupta commentedI fixed CS error, and I have uploaded the patch. Please review it
Comment #83
tushar1 commentedOur site is running on 9.4.x version and we are facing below issue in build, we have also checked by upgrading platform version to latest 7.24.1 but still no luck
Error: > [notice] Update started: taxonomy_post_update_convert_term_views_filters_to_uuids
> [warning] Undefined array key "plugin_id" taxonomy.post_update.php:48
> [error] TypeError: Drupal\views\Plugin\views\PluginBase::init(): Argument #3 ($options) must be of type ?array, string given, called in /site-archive/pfpfizerforyoudk-1670742508/app/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php on line 1131 in Drupal\views\Plugin\views\PluginBase->init() (line 137 of /site-archive/pfpfizerforyoudk-1670742508/app/core/modules/views/src/Plugin/views/PluginBase.php)
So we have added below patch by adding fix into core view module and that issue is resolved.
Comment #84
_utsavsharma commentedFixed CCF for #83.
Please review.
Comment #85
rosk0Please stop posting wrong patches.
Patch in #80 introduces a change without the interdiff, comments after reduce patch size from 20 Kb to bytes...
If people want their patches to be helpful, please learn how to work with them first https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupa... .
Updates to patches must be supplemented with the interdiff to simplify review process.
Comment #86
rosk0I believe there is one more thing that needs improvement - at the moment
taxonomy_post_update_convert_term_views_filters_to_uuids()needlessly setsfilters: { }on all displays views.We should wrap
$display['display_options']['filters'] = $filters;in an empty check to prevent this.Comment #87
manuel garcia commentedWe needed this patch for 9.4.x so I have rerolled #79 here against that. Attaching in case its useful to someone else.
Comment #88
xurizaemonThis patch may fail in the case of a Views filter configuration referencing a term which no longer exists in the site DB.
In
taxonomy_convert_entity_ids_to_uuids():While that's not a valid configuration state with reference to the DB content, it is possible to encounter it (eg: term was deleted but view configuration was not updated), and the patch could handle it better by checking the result of
Term::load()before calling its->uuid()method.We could either drop the item from the list of UUIDs (which feels wrong, even though the configuration was already not valid with reference to content), or we could fail the DB update in order to notify the site owners. I believe the latter is safer?
Comment #90
Prudhvi32 commentedUnable to decode output into JSON: Syntax error
Error: Call to a member function uuid() on null in taxonomy_convert_entity_ids_to_uuids().
on line 78 app\core\modules\taxonomy\taxonomy.post_update.php
For this issue, we created a patch and patch is working fine.
Comment #91
vasikeHere it is just a re-roll of previous patch. i hope i didn't miss a thing.
Let's see if it passes. Maybe we'll have also a MR that could help chasing and keep it updated till ... it's done
Comment #92
vasikeSmall update, attempting to fix CS/phpstan errors.
+ A version for 10.1.x, as it seems they are not the same.
Comment #93
smustgrave commentedTaking a brief look and looks like this is very close.
Seems like changing to UUID should be captured in a change record though, just to let others know.
Comment #94
lendudeThere is still a lot of clean up happening here, which makes it really hard to review. While I like that logic is moved to its own methods instead of having one giant method, it makes reviewing this very hard, because its really hard to see which changes are needed here and which changes are just moving existing logic around. Please please please keep the patch/MR as small as possible
This feels very light on test coverage, but again, since it's hard to see what is actually new code here that should have test coverage, it might be sufficient.
Since we have an update hook, it should have an upgrade path test for that hook.
Comment #96
scott_euser commentedMoving to an MR for now, still needs addressing feedback from #94 as next step, ie:
Comment #97
scott_euser commentedThe failure is unrelated it seems. I am not sure why it still fails as it seems @dww had fixed that here https://www.drupal.org/project/drupal/issues/2640994#comment-15597379 and it was committed to 10.3.x through to 11.x. @smustgrave, any chance you have seen this elsewhere as well? The MR/Fork is new from today so I would think it should not have that problem
Comment #98
scott_euser commentedBeyond that I think test coverage actually may not need much change as the existing test coverage before this issue should actually be validating that the existing complete process of updating, saving, filtering by continues to work.
Comment #100
scott_euser commentedComment #102
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #103
mefianf commentedA small patch update for 10.3.x, as it seems they are not the same.
Comment #104
scott_euser commented2761157-views-taxonomy-uuidbranch still merges and passes fine, with expected config validation change (if I understand that warning right). So back to needs review since I believe #94 has been addressed/responded to. So it would be good if someone could confirm and change to RTBC since I made too many changes to this myself.(Also hiding patches, for those adding them, please instead follow the documentation for downloading merge requests as patches locally to avoid confusion + avoid issues with needs review bot pushing these issues back to needs work unecessarily)
Comment #105
scott_euser commentedChange record added here: https://www.drupal.org/node/3464158
Update issue summary to standard template but kept the original solution additional chapter.
Comment #106
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #107
scott_euser commentedResolved conflict.
Comment #109
smustgrave commentedSo for the schema update should it be of type: uuid?
Which is validated
Comment #110
scott_euser commentedComment #111
scott_euser commentedTests no longer passing, back to NW
Comment #112
smustgrave commentedMy comment for uuid I could be wrong just seemed like it lined up
Comment #113
scott_euser commentedNo, it really does look right. All 3 failures pass locally when I re-run so I triggered re-run via gitlab CI now
Comment #114
scott_euser commented:facepalm, I hadn't pulled because the changes were applied via gitlab UI. They do fail locally. Not a valid UUID error, so could be our sample data...
Comment #115
scott_euser commentedOkay its really legitimately showing again what we are seeing now and then, that the Views configuration stored in test views & config install | config optional are not updated by update hooks and therefore out of date and need to be manually update.
However in this case, even when
phpunit -c core/phpunit.xml core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyIndexTidFilterTest.phpThere is actually a problem with calculateDependencies() in the code itself revealed here. The 'content' key is not getting populated with the references to the UUIDs and therefore does not match the view. We need to fix that first. I updated the issue summary with this.
Comment #116
tonibarbera commentedThe patch doesn´t apply to Drupal 10.3.1. Rerolled the patch for that version
Comment #117
tonibarbera commentedComment #118
scott_euser commented#115 not yet addressed, let's keep it at needs work as it needs work still. Hiding patches in favour of merge request.
Comment #119
scott_euser commented2761157-views-taxonomy-uuid--10-3-x branch updated to apply to 10.3.2.
Comment #120
olmyr commentedThe patch for the 10.3.4
Comment #121
olmyr commentedThe patch for the 10.3.4
Comment #124
olmyr commentedComment #125
scott_euser commentedComment #126
smustgrave commentedVery neat!
Left some comments on the MR.
Comment #127
scott_euser commentedThanks for the feedback! Comments address + update test added + 2nd change record added
Comment #128
smustgrave commentedMR appears to need a rebase.
Comment #129
duaelfrMR squashed and rerolled.
Patch attached for composer.
Comment #132
smustgrave commentedClosed the old MRs for. 10.3 as they were failing and probably missed the boat for them.
Rebased 11.x and still all green
All threads appear to be resolved, templated to tag 11.2 highlight but will let committer decide.
Comment #133
catchOne (non-trivial) comment on the MR about the upgrade path.
Comment #136
duaelfrMR rerolled
Patch attached for composer
Comment #133 is still to consider