Problem/Motivation

If you try to filter a User view by language, you are filtering on the Users's preferred language, which is also the language of the original if the user data is translated. The translation language is not exposed. Same as was for nodes in #2217943: Views cannot be filtered by language of translation.

The reason is that in UserViewsData, the language field/filter is only added for original language.

    $data['users']['langcode'] = array(
      'title' => t('Language'),
      'help' => t('Language of the user'),
      'field' => array(
        'id' => 'user_language',
      ),
      'sort' => array(
        'id' => 'standard',
      ),
      'filter' => array(
        'id' => 'language',
      ),
      'argument' => array(
        'id' => 'language',
      ),
    );

There are actually 4 languages that are relevant for Users:
- langcode: Original submission language of the entity
- The translation language of the entity (on the field data table)
- preferred_langcode: The user's language preference.
- preferred_admin_langcode: If the admin language negotiation is enabled, the user's admin preferred language.

Proposed resolution

Make sure all 4 languages are included as fields/filters for Views.

Remaining tasks

- Do it.
- Tests.
- Review.

User interface changes

Existing language filter name changed.
New language fields/filters added.

API changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Gábor Hojtsy’s picture

Well, so the fun thing about users is they may have 3 different languages on them. Woot, right? :D They are the following:

- langcode: Original submission language of the entity
- preferred_langcode: The user's language preference.
- preferred_admin_langcode: If the admin language negotiation is enabled, the user's admin preferred language.

To complicate matters a bit, the language the user can set by default is BOTH the first two at once and the third one (if admin language preference is turned on). It is theoretically possible that a user would have their profile fields in a different language to their preferred language, but not very likely. If so, we have this code in AccountForm.php that addresses that:

    // User entities contain both a langcode property (for identifying the
    // language of the entity data) and a preferred_langcode property (see
    // above). Rather than provide a UI forcing the user to choose both
    // separately, assume that the user profile data is in the user's preferred
    // language. This element provides that synchronization. For use-cases where
    // this synchronization is not desired, a module can alter or remove this
    // element.
    $form['language']['langcode'] = array(
      '#type' => 'value',
      '#value_callback' => '_user_language_selector_langcode_value',
      // For the synchronization to work, this element must have a larger weight
      // than the preferred_langcode element. Set a large weight here in case
      // a module alters the weight of the other element.
      '#weight' => 100,
    );

So the User's preferred language may or may not be the same as the original entity language. I think naming this the "Original language" like we did for nodes is better for consistency. We may also want to expose the other two languages to views in some ways, but they are less useful I guess. Knowing those would be great for heavy duty admin views probably.

jhodgdon’s picture

Ah, good point.

So I think we need to provide filter/field/sort/argument for all 3 base languages, and also for the translation language.

Currently there is only support for 1 of the base languages, and I agree this should be named "Original language" like we did for nodes; we need to add the other two.

I'll probably make a patch soon if someone else doesn't get to it first.

jhodgdon’s picture

Status: Active » Postponed
Related issues: +#1740492: Implement a default entity views data handler

The proposed patch on #1740492: Implement a default entity views data handler would take care of part of this... so we may want to postpone until that is done and then hopefully close this issue as a duplicate. But if that issue isn't moving forward, we can do this here.

jhodgdon’s picture

Issue summary: View changes
Status: Postponed » Active

#1740492: Implement a default entity views data handler has been committed, so it's time to get back to this issue.

What needs to be done for User is something similar to what that issue's patch did for Node: convert User's views data handler to derive from the new default Views data handler. Which will automatically add the necessary filter on the original language and the translation language.

Then we also need to add fields/filters for the other languages related to the user (see summary).

jhodgdon’s picture

Status: Active » Needs review
FileSize
10.06 KB

OK, here's a patch. This was actually pretty easy, because the base Views class automatically adds all the base fields, so all of the language fields get added by default. The user-readable field names are not quite right though in this case, because they're always set to "Original language" and "Translation language" by the base class, and since User has these different fields, those labels don't make sense. But that's easy to fix.

Status: Needs review » Needs work

The last submitted patch, 5: 2323939-user-views-data.patch, failed testing.

jhodgdon’s picture

FileSize
10.05 KB
803 bytes

I slipped up in one spot in that last patch. This one should work better. Tests++.

jhodgdon’s picture

FileSize
10.43 KB
985 bytes
22.92 KB

And: a small tweak to the field labels. Screenshot shows what you see if you add fields (filters look similar) to a User view.
User language fields with this patch

jhodgdon’s picture

Status: Needs work » Needs review
dawehner’s picture

+++ b/core/modules/user/src/UserViewsData.php
@@ -350,6 +222,9 @@ public function getViewsData() {
 
+    unset($data['users_field_data']['signature']);
+    unset($data['users_field_data']['signature_format']);
+

I don't get that ... what is the reason to not get integration for it?

jhodgdon’s picture

RE #10 - Look just a few lines down in the original file (unpatched):

    if (\Drupal::moduleHandler()->moduleExists('filter')) {
      $data['users_field_data']['signature'] = array(
        'title' => t('Signature'),
        'help' => t("The user's signature."),
        'field' => array(
          'id' => 'markup',
          'format' => filter_fallback_format(),
          'click sortable' => FALSE,
        ),
        'filter' => array(
          'id' => 'string',
        ),
      );
    }

I decided to leave this as it is.. but thought we didn't probably want the default stuff that the Views data base class was putting in. Right?

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +sprint

Changes look good to me in this patch especially the fix of the admin/non-admin language preferences that was backward before (oops).

Re #10, the extended context of the changes looks like this, showing the code just removes the default values and adds custom values conditionally:

+++ b/core/modules/user/src/UserViewsData.php
@@ -350,6 +222,9 @@ public function getViewsData() {
+    unset($data['users_field_data']['signature']);
+    unset($data['users_field_data']['signature_format']);
+
     if (\Drupal::moduleHandler()->moduleExists('filter')) {
       $data['users_field_data']['signature'] = array(
         'title' => t('Signature'),

Because this already does some refactoring to take the default values from the base class instead of having brand new values generated solely in this class, I think we can keep the scope as-is and not change this part (which is not related to language either). The patch does not change behaviour in my understanding in that part.

So overall looks good to me :) Thanks for the screenshot of the different user language options.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Looks good. Committed 8c2b42d and pushed to 8.0.x. Thanks!

Whilst reviewing the patch I noticed that the filter format used for user signatures is the fallback format and not the one the user has chosen - that's problematic and we should open a followup to fix that.

  • alexpott committed 8c2b42d on 8.0.x
    Issue #2323939 by jhodgdon: Fixed Views user language field/filter is...
jhodgdon’s picture

Gábor Hojtsy’s picture

Issue tags: -sprint

Thanks so much for sticking to this, consistency is amazing!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.