Problem/Motivation

This is a part of #2960253: [meta] Allow Paragraphs widget/field and similar use cases to to be considered translatable which is being split into 3 separate issues and converted to a meta issue.

* While we don't want the paragraph field values to be replaced, we basically need to be able to apply the same/similar logic to our referenced entities. So when a new "merge-revision" of the node is created, we want to do the same to the paragraphs, so that they too merge their translatable/untranslatable fields together. And later on when we have fancy conflict resolution that will replace this special case, we'll need to be able to apply that recursively as well.

Proposed resolution

Add hook_entity_revision_create() and hook_ENTITY_TYPE_revision_create()

Remaining tasks

User interface changes

None

API changes

Two new hooks, no changes.

Data model changes

None.

CommentFileSizeAuthor
#2 revision-create-hooks-2975754-2.patch10.69 KBberdir

Comments

Berdir created an issue. See original summary.

berdir’s picture

Status: Active » Needs review
StatusFileSize
new10.69 KB

These are the relevant parts from the other issue.

hchonov’s picture

+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -237,6 +237,8 @@ public function createRevision(RevisionableInterface $entity, $default = TRUE, $
+    $original_keep_untranslatable_fields = $keep_untranslatable_fields;

@@ -307,6 +309,11 @@ public function createRevision(RevisionableInterface $entity, $default = TRUE, $
+    $arguments = [$new_revision, $entity, $original_keep_untranslatable_fields];
+    $this->moduleHandler()->invokeAll($this->entityTypeId . '_revision_create', $arguments);
+    $this->moduleHandler()->invokeAll('entity_revision_create', $arguments);

+++ b/core/lib/Drupal/Core/Entity/entity.api.php
@@ -909,6 +909,54 @@ function hook_ENTITY_TYPE_create(\Drupal\Core\Entity\EntityInterface $entity) {
+ *   default revision (FALSE) when generating a merged revision. If no value was
+ *   explicitly specified (NULL), a default value of TRUE should be assumed if
+ *   the provided entity is the default translation and untranslatable fields
+ *   should only affect the default translation, FALSE otherwise.
...
+ *   default revision (FALSE) when generating a merged revision. If no value was
+ *   explicitly specified (NULL), a default value of TRUE should be assumed if
+ *   the provided entity is the default translation and untranslatable fields
+ *   should only affect the default translation, FALSE otherwise.

The value of $keep_untranslatable_fields might change in the function body before the hooks are executed. We provide a documentation of the hook, which is explaining this, but this makes the whole pretty complex for developers. We could instead skip documenting that NULL should be assumed as TRUE and instead of calling the hooks with value of NULL we call them with value of TRUE if we've changed the value in the function body before calling the hooks. What do you think about this?

berdir’s picture

Just providing more context for now, we discussed that in the meta issue, see comments #20-22 or so over there.

hchonov’s picture

Well then probably we have to pass both values to the hook - the original one and the newly computed one, which has been used by the method.

berdir’s picture

The idea was that if you want to, you can recalculate the value yourself which is I think pretty well documented on the hook documentation.

I expect that cases where you really need to care about it are fairly rare, for example in ERR with the nested composite entity use case, I'm just passing it along again to createRevision().

plach’s picture

Status: Needs review » Reviewed & tested by the community

@hchonov:

Tentatively marking this RTBC, feel free to unmark if you still have concerns.

plach’s picture

Title: Add hooks to acton on a new revision being created » Add hooks to act on on a new revision being created
berdir’s picture

Title: Add hooks to act on on a new revision being created » Add hooks to act on a new revision being created

still wrong :)

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

I think we need a change record to announce the new hooks.

plach’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs change record

@alexpott:

An all-encompassing CR for the parent meta issue is available at https://www.drupal.org/node/2975280, I guess we should publish it once the meta itself is fixed, right?

alexpott’s picture

@plach thanks for adding this issue to the CR :) https://www.drupal.org/node/2975280/revisions/view/10983402/10990108

plach’s picture

Yep, that was missing :)

alexpott’s picture

  1. +++ b/core/lib/Drupal/Core/Entity/TranslatableRevisionableStorageInterface.php
    @@ -20,7 +20,9 @@
        * @param bool|null $keep_untranslatable_fields
        *   (optional) Whether untranslatable field values should be kept or copied
    -   *   from the default revision when generating a merged revision.
    +   *   from the default revision when generating a merged revision. Defaults to
    +   *   TRUE if the provided entity is the default translation and untranslatable
    +   *   fields should only affect the default translation, FALSE otherwise.
    

    This description doesn't explain the NULL state.

  2. +++ b/core/lib/Drupal/Core/Entity/entity.api.php
    @@ -909,6 +909,54 @@ function hook_ENTITY_TYPE_create(\Drupal\Core\Entity\EntityInterface $entity) {
    + *   Whether untranslatable field values were kept (TRUE) or copied from the
    + *   default revision (FALSE) when generating a merged revision. If no value was
    + *   explicitly specified (NULL), a default value of TRUE should be assumed if
    + *   the provided entity is the default translation and untranslatable fields
    + *   should only affect the default translation, FALSE otherwise.
    

    Is there anyway we can remove the NULL state and set it to either TRUE or FALSE according to the logic specified in this comment?

  3. I'm leaving this at RTBC because I'm not sure what is possible but the docs confuse me on first reading. I have not looked at in-depth to work out what they are describing.
berdir’s picture

> Defaults to TRUE if the provided entity is the default translation and untranslatable fields should only affect the default translation, FALSE otherwise.

This is the part that tries to explains the NULL state. it is an implicit TRUE or FALSE depending on those two conditions. See discussion here and in the meta issue, the idea is that it is relatively easy to figure this out if it's null and if you really need it, but it also seemed important to us to be able to be able to know if it was set explicitly or not.

The need to use it is likely relatively rare (e.g. the ERR patch that uses this just passes it along to the nested createRevision() call and while passing NULL does make it a bit more complicated to use, it allows for all possible scenarios.

webchick’s picture

It sounds like this is a blocker for contrib, so adding that tag.

gábor hojtsy’s picture

I created https://www.drupal.org/node/2985957 as a change record with a copy of the part of https://www.drupal.org/node/2975280 that is relevant for this issue. Ideally all issues would be committed and that big CR published, but if there is no CR for this and the rest cannot make it, then we are not allowed to commit this one either. So let's make that possible at least :) We make this CR a redirect later or replace its body with a link to the bigger CR once it becomes obsolete.

Also giving all the credits possible here. Also carried over credits from #2960253: [meta] Allow Paragraphs widget/field and similar use cases to to be considered translatable.

  • Gábor Hojtsy committed 1e8a4de on 8.7.x
    Issue #2975754 by Berdir, plach, alexpott, hchonov, mkalkbrenner,...

  • Gábor Hojtsy committed 687a191 on 8.6.x
    Issue #2975754 by Berdir, plach, alexpott, hchonov, mkalkbrenner,...
gábor hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for the explanation @berdir, makes sense to me.

Committed 1e8a4de and pushed to 8.7.x and merged to 8.6.x. Thanks!

plach’s picture

@Gábor Hojtsy:

Thanks for committing this, a separate CR makes sense for now, I just wanted to point out that the only other core ticket mentioned in the parent CR is #2826021: FieldItemList::equals is sufficient from the storage perspective but not for code checking for changes, which has stalled but seemed very close at a certain point, so we might still be able to fix core parts before alpha.

Status: Fixed » Closed (fixed)

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

matsbla’s picture

To me it seems like this hook is not always fired when creating new revisions, I made a new issue about it here #3031405: New hook_entity_revision_create() is not always fiered when new revisions are created