Patch updates to a log by a user with non-default language fail w/ 405

OK, interesting! Thanks for these clues @Farmer-Ed and @pat. It makes me wonder if maybe the langcode is being saved to the log as en/no depending on what language the user is using when they save it? But then the API is trying to save it as the opposite, or something…

Are you creating AND updating the log both through the API? Or was it created through the UI and then being updated through the API? (Or some other combination of things?)

1 Like

All is done through API from Node-Red.

I could try to patch a log created in the UI

1 Like

Result:

Created in UI, EN - change to NO - PATCH = error 405
Created in UI, NO - no change - PATCH = error 405

2 Likes

What happens when you do this @pat? Change your user’s language to EN and then try PATCH.

Oh wait you already did that above, and it worked… :smile:

Yep.
Patching with norwegian user don’t

1 Like

Found this: https://www.drupal.org/project/drupal/issues/3043168

Reading through it now to see if I can find any potential clues…

One thing that would be useful @pat … could you paste the JSON representation of the log you are trying to PATCH? Or at least the top bit (don’t need all the attributes and relationships I don’t think).

Here is the line in the Drupal core JSON:API module that produces the error: core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php · b9b6fa58648511a957d3dc82bd017a008885b6e7 · project / drupal · GitLab

The condition is pretty simple, so I bet we can figure out what’s failing…

if ($method === 'PATCH' && $entity->language()->getId() !== $current_content_language) {
  $available_translations = implode(', ', array_keys($entity->getTranslationLanguages()));
  throw new MethodNotAllowedHttpException(['GET'], sprintf('The requested translation of the resource object does not exist, instead modify one of the translations that do exist: %s.', $available_translations));
}

Right above that $current_content_language gets set:

$current_content_language = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();

I can run that same code via Drush to see what it returns…

drush php-eval "print(\Drupal::service('language_manager')->getCurrentLanguage('language_content')->getId());"

@pat On your instance that returns nb.

I’m curious what $entity->language()->getId() is… I’m guessing en@pat (or @Farmer-Ed) could you confirm what the langcode is on the log before you try to PATCH it?

1 Like

Ah ha looks like @Farmer-Ed beat me to this up above. :sweat_smile:

1 Like

Assuming this is the case…

… that would cause the issue.

So maybe the question is: why is $current_content_language set to nb? Maybe that should always be en if we aren’t using the content translation module? Perhaps the farm_l10n module could force that?

1 Like

This is insightful: https://www.drupal.org/project/drupal/issues/2794431

1 Like

@pat One idea for a workaround while we continue to investigate this… I think if you created a dedicated API user in your instance, with a language of English, you could use that for API requests and it would work.

1 Like

This is interesting, and suggests that Drupal core is still working through all the different ways that JSON:API could/should work with translations. This sums it up:

The problem with this is that it depends on and varies by each site’s language negotiation configuration. This means translations may behave differently on Drupal-powered JSON:API instances A versus B.

I think that’s basically what we’re running into here. Although I’m curious if we can solve this with a simple hack/override in farm_l10n… with the understanding/assumption that farmOS does NOT support support content translations and the default language is always en. Like I said above…

These assumptions may not be “forever”, though, so would this create roadblocks for some of those next steps… ? Seems like they would.

1 Like

Specifically by “next steps” I mean:

  • Allowing other languages to be the “default” (referring specifically to what was decided upon here, which refers to a very specific configuration, mind you: https://www.drupal.org/project/farm/issues/3257430)
  • Allowing use of the content translation modules.

Neither of those are priorities for future farmOS development, so it would only be creating roadblocks for developers/hackers who wanted to go farther on their own.

1 Like

All of mine would have been en, as I created the data before adding the new language.

1 Like

Here:

msg.payload = {
    "data": {
        "type": "log--lab_test",
        "attributes": {
            "name": "Jordprøve",
            "status": "pending",
            "notes": "",
            "lab_test_type": "soil"
        }
    }
}

The above log created with Norwegian user:

langcode : "en"
1 Like

Also

default_langcode : true
1 Like

I think he means the stored JSON

{
	"type": "log--lab_test",
	"id": "03979e6e-e6e6-44a9-8581-5a6ace4eec99",
	"links": {
		"self": {
			"href": "http://192.168.1.18/api/log/lab_test/03979e6e-e6e6-44a9-8581-5a6ace4eec99?resourceVersion=id%3A374"
		}
	},
	"attributes": {
		"drupal_internal__id": 243,
		"drupal_internal__revision_id": 374,
		"langcode": "en",
		"revision_created": "2023-01-16T15:50:18+00:00",
		"revision_log_message": null,
		"name": "Jordprøve",
		"timestamp": "2023-01-15T15:53:18+00:00",
		"status": "done",
		"created": "2023-01-15T15:53:18+00:00",
		"changed": "2023-01-16T14:49:55+00:00",
		"default_langcode": true,
		"revision_translation_affected": null,
		"data": null,
		"notes": null,
		"flag": [],
		"is_group_assignment": null,
		"geometry": null,
		"is_movement": false,
		"lab_test_type": null,
		"lab_received_date": null,
		"lab_processed_date": null
	}
}
1 Like

@mstenta
I found something Interesting…

I think if you don’t support translations in content that you shouldn’t use the "langcode": "en" it should be "langcode": "und"

It works with Logs created through the API and UI and regardless of the Users Language.
Not sure where the existing logs(and other entities?) would stand though if this change was made to existing sites? I can modify them manually one at a time from UI but get not allowed from API

zxx also seems to work as langcode

und = Not Specified
zxx = Not Applicable

3 Likes

This seems like the right answer to me. It would let us punt on the whole concept of “content language” until the desired behavior can be nailed down.

3 Likes