Both WPML and Toolset Access are paid-only plugins. While this doesn’t mean they are completely unavailable for testing, as both are GPL licensed, I didn’t have much luck when attempting a test.
Here is some general notes for consideration:
- Toolset Access is
166,031
lines of code. Much of this is likely user interface, but what it is doing is complex.
- WPML stores its translation data to custom tables and runs custom queries on those tables. Pods isn’t able to do much with these types of data structures. Extending the behavior or Polylang tends to be much easier as it uses a
language
taxonomy for querying translations. Using WordPress multisite to manage translations is even easier, as it uses no plugins, and in the case of your requirement for user access management, access to a language would be managed by access to a subsite.
- In attempting to test a concept with WPML, the setup interface failed, leaving the plugin in an unstable state.
- Looking through the plugin’s code, and the database schema documentation, the likely table to filter responses from would be
icl_translations
, where IDs of posts and taxonomies are stored with element_type
values like post_{$post_type}
and tax_{$taxonomy}
, the ID of the object in element_id
and a short language code like en
in language_code
.
- If one wanted to restrict what posts a user could see, e.g., by their current Admin language settings returned by get_user_locale(), one could add an action to pre_get_posts, which would check:
- Whether the current query is in the admin.
- Whether the current query is for a post type or a taxonomy.
- If a post type, query
icl_translations
for element_id
‘s WHERE element_type
= post_{ $query->get( 'post_type' ) }
and language_code
= explode( '_', get_user_locale() )[0]
and then $query->set( 'post__not_in', $excluded_ids )
where $excluded_ids
would be the values returned by $wpdb->get_col()
for the query on icl_translations
. This is a very inefficient sort of query filter to run, and would likely fail if the number of translated posts grew to many thousands of IDs. It would additionally need to be done with taxonomies, using a tax_query
with operator
NOT IN
. See WP_Query. pre_get_posts
is an action that passes the WP_Query object by reference. It is not a filter. Nothing needs to be returned by the attached action; the query is modified with ->get()
and ->set()
methods on the query.
- The above action would be much simpler with Polylang functions, where the queries could be modified to only add a
tax_query
with NOT IN
to all post and taxonomy admin queries for a user.
- It’s simpler still if using multisite and no plugins for access management, as access to a site would equal access to a language.
- The above filters have to do with with modifying what post objects and taxonomy terms a user can query in the admin. It may or may not also remove editing capabilities. If a strict editing restriction is desired, user capabilities can be filtered programmatically with the user_has_cap filter. For example, see the comment on that filter for a way of modifying what posts a user can edit. If simply restricting what can be edited, but not necessarily affecting admin visibility, is the desired result, this is a much simpler approach, for example if combined with WPML’s wpml_current_language filter to get the current object language to compare against the value of get_user_locale() or a custom language setting added to the User object with Pods.
Other than the fact that one could attach a custom field to a User with Pods, such as multi-select language listing or a relationship to Polylang’s language taxonomy, the custom tables and queries of WPML specifically are not under Pod’s control, and the functionality you’ve described is generally in the ballpark of the pre_get_posts action and user_has_cap filter.
Using a multisite to manage languages greatly simplifies all of this, as it removes the need for any plugins or custom access management, except perhaps an occasional switch_to_blog() to get information from other language sites, or get_sites() to get a list of all sites in the network.