The create and list operations need to be re-implemented in D7. At a minimum, they need to be ported to DBTNG and moved to hook_query_alter(). However, many issues have been caused by "guessing" whether the create or list op should be active based on arg() (see #903522: Move control of create into hook_form_alter() and hook_nodeapi() to prevent numerous problems). So, it might be better to use some of the new features of the D7 API instead.
E.g., see: hook_field_read_instance()
Comments
Comment #1
xjmOne plus of using
hook_query_alter()is that other modules might go directly to the database instead of using the field API, and so altering queries is more of a sure thing.The most important consideration is probably Views compatibility. I checked with dereine on IRC, and Views 7.x-3.x uses field_view_field() to load field data, which appears to eventually invokes
hook_field_read_instance().If we have any part of the create op in
hook_form_alter(), it definitely needs to be factored to provide an API that can be used at other points in the node edit process (both for TAC internally and to make supporting other modules easier).Comment #2
xjmAdding tag.
Comment #3
xjmThe correct field hook is
hook_field_attach_view_alter(). However, this hook will only allow us to remove the listing of the term from a node rendering (e.g., on a node page or in views). It does not restrict access totaxonomy/term/x, nor prevent nodes tagged with that term from being listed on that page, nor would it prevent the term from being listed in (e.g.) a taxonomy view. So, to avoid usinghook_query_alter(), we'd need to handle these cases as well.Other possibilities include the taxonomy hooks
hook_taxonomy_term_load()andhook_taxonomy_term_view_alter(). However, it appears these do not provide sufficient support for views. Neither can alter the output of Views' All taxonomy terms field type, for example. For that matter, nor canhook_field_attach_view_alter(). Furthermore, the only tag on the query for All taxonomy terms appears to beterm_access, so there is no obvious way to distinguish it from other situations.At this point, it looks like it may be a matter of letting list take away terms everywhere with
hook_query_term_access_alter(), and then adding the terms back somehow in the taxonomy field editing widget. Other scenarios in which list should not apply would need to be documented and handled on a case-by-case basis.Comment #4
xjmPossible solution suggested by catch on IRC: Override all taxonomy field widgets somehow so that they do not use the tagged query (or so that they add their own tag to the query). See: hook_field_info_alter() and hook_field_widget_info_alter().
Comment #5
xjmUnfortunately, the query tags are added at the lowest level in the taxonomy API. After some investigation, it became clear that we'd have to duplicate half of
taxonomy.modulefor the solution in #4. It could still be used as a workaround: If the user is editing the field somewhere other than the node add/edit forms, we could provide a "create-safe" widget for those circumstances.For the moment, however, I'm leaning toward this solution:
taxonomy_access_create_active()andtaxonomy_access_list_active(). (Could even make these alterable if there is a demand for it.)hook_query_term_access_alter().menu_get_item()'s callback is eithernode_addornode_page_edit.Not a perfect solution, but still a step up from D6.
Comment #6
xjmI found a better solution. We create a static flag that disables the list op's
hook_query_alter()only while values are being generated for a taxonomy field (by overriding the options list), and again during node validation and saving. It works!The only case this doesn't cover is taxonomy widgets not provided by core taxonomy. Perhaps the flag should be set for the duration of a node form generation.
Comment #7
xjmhttp://drupalcode.org/project/taxonomy_access.git/commit/72a75fb includes a functional list op. Create should be ready Soon™!
See also: #1204230: Missing hook_field_widget_form_alter()
Comment #8
xjmhttp://drupalcode.org/project/taxonomy_access.git/commit/f78ea12 disables the list op during field editing. Edit: It appears to have introduced a regression when user does not have any list permissions. (We need to use
IS NULLor something in the query rather thanIN ()).Outstanding questions:
taxonomy/termpages behave as expected?The create grant itself is not yet implemented.
Comment #9
xjmJust confirmed that list permissions are still (incorrectly) filtering autocomplete fields, both the initial listing and the AJAX lookup. Users can add new terms; however, they cannot see these terms on node edit.
Comment #10
xjmAfter many gruesome battles and much gnashing of teeth, the autocomplete widget is working:
http://drupalcode.org/project/taxonomy_access.git/commit/72645f4
We should possibly move the list disable flagging into callbacks added by
hook_form_alter()and out ofhook_node_validate()/hook_node_update()for better portability across entity types. There's still the issue of non-core widgets and fields, but that might be better addressed when we have a real example.Comment #11
xjmIt appears that the current mechanism for create is bugged with hierarchical select's widget. (Multiselect's works fine.) Edit: HS itself is quite buggy at present.
Comment #12
xjmBoth operations are now fully functional.
Outstanding issues with the create grant (mostly minor):
#1209158: Support multiselect widget
#1209154: Form UX: disabling vs. hiding disallowed terms
#1209122: Provide better graceful degradation when jQuery is not available.
#1209104: Re-add field-level validation in hook_field_attach_validate()
#1209108: Provide human-readable error message text on field validation