Content Translation should use EntityPublishedInterface or the 'published' entity key to determine if it needs to add its 'content_translation_status' field

Created on 9 October 2018, about 6 years ago
Updated 4 June 2024, 6 months ago

Problem/Motivation

Before EntityPublishedInterface was introduced in 8.3.0, there was no standard way to determine whether an entity type has a "status / published" field, so Content Translation is simply looking for a field named status when it wants to determine whether to add its own content_translation_status field or not.

This is problematic because, for example, the menu_link_content entity type from core uses a field named enabled for its publishing status.

Proposed resolution

Update Content Translation to look at the published entity key instead.

Remaining tasks

Do it.

User interface changes

Nope.

API changes

Nope.

Data model changes

Nope.

πŸ“Œ Task
Status

Needs work

Version

11.0 πŸ”₯

Component
Content translationΒ  β†’

Last updated about 8 hours ago

No maintainer
Created by

πŸ‡·πŸ‡΄Romania amateescu

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request β†’ as a guide.

    This will need a test case to show the issue.

  • Status changed to Needs review 6 months ago
  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    I stumbled over this also from a performance perspective.

    isPublished() is called a lot from content_translation_language_fallback_candidates_entity_view_alter() if you are displaying many entities, for example nodes in a view or embedded things like paragraphs or also menu link content entities, this is currently quite slow.

    We have EntityPublishedInterface now, which is optimized to use the entity key value system which allows to return this value without instantiating a field object.

    Created a merge request from this and extend the code to also check for EntityPublishedInterface. Unfortunately, this doesn't actually work for menu_link_content, the biggest offender for performance in our case, exactly because of the published/status situation. Just changing this class to respect that isn't enough, we also would need to change \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus(), but that's where things get complicated. If we just fix that, then content_translation will switch over to the enabled field and stop using its own field which might have data in it. I don't really know how to handle that. We would probably need to write an update function, loop over all enabled entity types that have no status field but have a published entity key and then migrate the data over, assuming translatability of the field is set correctly.

    Note that the wrapper currently also blindly assumes that the entities it wraps have a getOwner() and a getChangedTime() method, without checking for the respective interfaces. There's also πŸ› Content Translation does not use EntityOwnerInterface properly Needs work which touches the owner topic.

    Changing this to a task because I don't think it's really a bug, the wrapper can be subclassed, if it doesn't work for you you can customize it, it's a performance optimization/code generalization so it works for more cases out of the box. On the plus side, I think it doesn't really need tests for the current changes. It will need tests if we go all the way for the menu_link_content implications for example.

  • Merge request !8263Resolve #3005398 "Content translation should" β†’ (Open) created by berdir
  • Pipeline finished with Success
    6 months ago
    Total: 660s
    #188092
  • Status changed to RTBC 6 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Doesn't appear to be a data model change, hiding older patches too.

    Change appears to match the issue summary and tests are appearing green.

    Would agree with @berdir around the need for tests, believe an existing test would fail if the change caused disruption. If anything maybe a follow up for extending coverage but wouldn't say a blocker here.

    LGTM

  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    Leaving at this status, but per #15, I don't think this is really done.

    This is only half the picture, the other half is \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus(), which still has the hardcoded status.

    That means the only effective change here is that entities that *do* have a status field will now use isPublished(), which makes this check likely a bit faster (didn't profile yet).

    But entities that don't have a status field but have a published entity like like MenuLinkContent are not yet affected at all. As written, changing them would result in an immediate field structure change that is hard to deal with.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Should we move back for profiling?

  • πŸ‡³πŸ‡ΏNew Zealand quietone

    If I understand #15 and #18 then followups are needed. One concerning \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus(), one about menu_link_content and another for getChangedTime(). The last one will be similar to πŸ› Content Translation does not use EntityOwnerInterface properly Needs work . I have not checked for duplicates.

    The changes in the MR seem correct to me. That leaves tests. In #15 Berdir argues that tests are not needed. But this does introduce logic that I am not sure if it is implicitly tested elsewhere.

  • Status changed to Needs work 6 months ago
  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    Changing back to needs work for now.

    There are two changes now here.

    1) The original change to use the published entity key. Without also changing \Drupal\content_translation\ContentTranslationHandler::hasPublishedStatus(), this does nothing. Any entity that does not have a status field will automatically get the content_translation_status field, and it will never look for status or a published field. That also means this can't be tested with a kernel or functional test since that code path doesn't exist. A unit test would be able to do it, but at that point we're faking up a scenario that's not real. Therefore it is IMHO not useful to make this change in isolation.

    2) The other change is using EntityPublishedInterface, which is a performance optimization. Nothing is broken, it's just isn't as fast as it could be. So we can't have a failing kernel or functional test again. We could wire up a unit test and explicitly assert that it's calling isPublished() when the passed in object implements that interface, but I'm not sure if it's worth doing that.

    At the same time, 2) isn't as good as it could be without having as many cases as possible go through that check, so getting that in on its own isn't *that* useful.

    > one about menu_link_content

    That can't be a separate follow-up either, because it's directly tied to the hasPublicationStatus() logic. If we change that then menu_link_content falls apart. We could customize its handler and wrapper classes to not do that, but we still will break contrib and cutom entity types in the same way, so we need a solution for that anyway.

    These content_translation issues are really hard to untangle...

Production build 0.71.5 2024