Closed (fixed)
Project:
Drupal core
Version:
8.7.x-dev
Component:
content_moderation.module
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
9 Oct 2017 at 11:55 UTC
Updated:
18 Jul 2019 at 07:29 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
matoeil commentedComment #3
douggreen commentedI believe that the problem is the UI. You're supposed to use the "Back to content editing" link when in preview mode. This link is not obvious, especially with the moderation state form still in the middle of the page. IMO we should remove that form on the preview page. There's probably more to do to make it pretty, but I think that's a start.
https://www.evernote.com/l/ARYvYkwAeZBNT6lRj6PD6DfRzUyhPvCbZfUB/image.png
Comment #4
douggreen commentedComment #5
sam152 commentedI agree, it doesn't make sense to have the moderation control from appear during a preview, but I don't think that is what the issue summary is describing. The problem can be reproduced even when you disable the "Moderation control" component on the entity display. Exact steps that worked for me were:
I think this issue could focus on what happens when a state changes on an unsaved entity and a new one could be spun out to hide the moderation form during a preview.
Comment #6
sam152 commentedAttached is a pretty hacky solution. If the entity is new, always use the default state. If the entity already exists, reload the revision that has already been saved and use that. Comment in the patch kind of describes the issue too:
Beyond doing some juggling like this, I can't think of an easy way to address this.
Comment #8
nick.james commentedHere is my attempt at resolving the issue. I also included a new test case in ModerationStateNodeTest.php
Comment #9
nick.james commentedComment #10
timmillwoodThis will load the default revision, if there are pending revisions won't this cause incorrect transitions from being loaded?
We should add a test here for pending revisions as they're full of edge cases.
Comment #11
sam152 commentedRe #10.1, I think
\Drupal\content_moderation\Entity\ContentModerationState::loadFromModeratedEntitymight help with this. Haven't had a chance to review the latest changes of the test.Comment #12
nick.james commentedOk so I ended taking a slightly different approach. I was having issues with some of the translation test passing but I finally think I figured it out. I also added test cases for pending revisions. Lastly, this patch includes the changes in https://www.drupal.org/project/drupal/issues/2940701 since the changes for both issues live in the same file in the same area. Fixing one kinda fixed the other. So if the test pass here, I will close out the other ticket as a duplicate.
Comment #13
timmillwood@nick.james the patch is empty.
Comment #14
nick.james commentedLol woops. Thanks @timmillwood.
Comment #15
nick.james commentedComment #16
jhedstromDoes workflow need to be set outside of this conditional?
Also, this entire new section is doing quite a bit. Can some code comments be added to clarify what's going on in here?
Comment #17
nick.james commented@jhedstrom,
1. Great point. Code comments have been added.
2.
If you are referring to
$workflow = $this->moderationInformation->getWorkflowForEntity($entity);, yes that part is still needed because it is used to grab the initial state for the entity if it is just being created.Comment #18
nick.james commented@jhedstrom, Sorry I think I misunderstood you. The
$workflowbeing defined in the if statement may not even be needed. The workflow should be the same for the saved entity vs the provided entity. I removed line that redefines the $workflow variable and tried it manually and saw no issues. I am running the test suite locally to see if it does indeed break something.Comment #19
nick.james commentedRedefining of
$workflowhas been removed.Comment #20
nick.james commentedComment #21
timmillwoodLooking good @nick.james, I think my only suggestion would be to test the preview and back to edit form when editing the pending revision. Just to test that the widget it loading the current state for the latest revision and not the default revision.
#4 @douggreen - #2942497: Using content moderation block in preview mode causes EntityStorageException
Comment #22
malcomio commentedAs discussed on #2942497: Using content moderation block in preview mode causes EntityStorageException, my suggestion would be to remove the moderation form from the preview page altogether.
To me, it doesn't belong in the preview - I think editors generally want to see what the page will look like to site visitors, rather than what it looks like for other editors.
Comment #24
chr.fritschI rerolled tha patch and created a pending revision in the tests.
Comment #26
sam152 commentedWe actually use all of this same logic in
\Drupal\content_moderation\Plugin\Validation\Constraint\ModerationStateConstraintValidator::getOriginalOrInitialState. I wonder if we should centralise that somewhere and make getting this info a lot easier.Comment #27
chr.fritschNice catch,
what about moving
::getOriginalOrInitialState()to theModerationInformationInterface?Comment #28
sam152 commentedYeah, seems like the most appropriate place. Lets do that!
Comment #29
chr.fritschOk, so I moved ::getOriginalOrInitialState() to the ModerationInformationInterface
Comment #30
alexpottNeeds a change record to detail this new functionality.
The name of this is interesting. It feels like too much implementation detail in the name. Why not
getOriginalState()? That fact that for new entities this is the initial state from the Workflow seems okay to me. I know this name is from the old validator method but now it is going on a public interface we need to consider the name a bit more. I've looked at the current ModerationInformationInterface and either name does not conflict with existing methods which is nice.Multiple uncached reads of a revision. I wonder if we can try using $entity->original if it is there.
Comment #31
alexpottOne concern I have with this using the initial state is the intersection between this issue and #2873287: Dispatch events for changing content moderation states which fires an event for state change. That defines the original state as NULL for new entities. Not the initial state for the workflow.
Comment #32
chr.fritschAddressing #30.2 and .3
Comment #34
sam152 commentedI think #2873287: Dispatch events for changing content moderation states should fall in line and use this new method if it ever lands. I'm not sure
NULLis ever a valid original state, since the initial state options the user has access to are based on a starting state selected by the system, even if that starting state was never saved to a specific entity revision.With all that in mind, I think the new method makes it significantly easier for other integrations to query what is happening during the entity lifecycle with regards to moderation states, so hopefully that addresses #31?
With that in mind, I think all that's left is a review of the interdiff from #32 and a change record.
Comment #35
sam152 commentedComment #36
sam152 commentedTo be honest, I thought
$entity->original->moderation_statewas broken, see this issue. Not sure why it serves our purposes in this specific instance.I wonder if we should avoid using
->originalat all i this patch. It feels a lot like a circular dependency, especially when accessing theModerationStateFieldItemListclass from it and I think is a complexity that is worth avoiding, given the complex nature of what we're already dealing with. What do you think @alexpott?Assigning
->originalalso seems like a new and risky side-effect, with a complex debugging profile.Overall my preference would be to revert #30.3 before RTBC.
Comment #37
alexpott@Sam152 @chr.fritsch -- I'm okay with reverting #30.3 for now. I do think we should provide a safe way of accessing the original entity at all times in a safe manner but I concede that $entity->original is not it. That is only assigned during preSave - \Drupal\Core\Entity\EntityStorageBase::doPreSave()
Let's revert those changes and open / look for a follow-up to add a better way of getting the original entity in all situations.
Comment #38
chr.fritschOk, so I am starting again from #29 and only applied #30.2.
I am also linking #2839195: Add a method to access the original property as a potential follow-up.
Comment #39
sam152 commentedPersonally the
->originalproperty always felt a bit of a mystery with regards to: when will it exist and what exactly does it represent. As far as I've encountered it, I can only define it as: the version of the entity we compare against for the purposes of evaluating what storage changes need to be made. Explicit methods seem like a reliable path forward and it looks like that is already being discussed in the related issue.Thanks for reviewing again @alexpott and @chr.fritsch for sticking with it. This is a super annoying and quite visible bug, so appreciate the persistence. I've done another full detailed review of the whole patch.
These are all +1s or comments, the only code changes I think we should make are points 4 and 7.
Okay, so here we reload the entity in storage for the purposes of calling
getValidTransitions, since that method is the valid transitions for that entity, at that point in time, not necessarily what is already in storage which when dealing with a widget is the only thing we're interested in.Makes sense to me.
The control flow for these methods match exactly what was already present in
ModerationStateConstraintValidator, so +1 to keeping the scope narrow in this issue.This whole doc-block reads okay to me for the purposes of the interface. I think the specific info about how this method is used for validation makes sense to live here.
It looks like this was introduced in #8 but I can't figure out if/why we need it. I think this should be reverted as well, and if not followed-up with a very specific kernel test that proves why it exists.
No need to translate these strings. I can see you're following the pattern in the rest of the test though, so maybe lets leave this and follow-up to fix the whole test at once.
This could probably be excluded from the test, I think we've proved the test case by this point.
This seemed questionable, but I realised this is very similar to the existing test case in the file, that makes me wonder: should we actually just insert "Preview" -> "Back to edit" button presses into the existing test cases? The rest of the test case should be unaffected if this bug has been resolved and the duplication of the steps in these two new test cases seems like it'll be a pain to maintain.
Comment #40
sam152 commentedImplementing the feedback from #39.
Comment #41
alexpottSo we're adding a method to an interface. That means we can only commit this to 8.8.x as per https://www.drupal.org/core/d8-bc-policy#interfaces - this falls under the "Interfaces within non-experimental, non-test modules not tagged with either @api or @internal" section.
http://grep.xnddx.ru/search?text=implements+ModerationInformationInterfa... shows that nothing in contrib is implementing it - workbench moderation has its own interface with the same name.
Comment #42
sam152 commentedPerhaps we could backport this simply by copying the method on to the widget class?
It has been broken a long time, so also probably not the end of the world to ship it in 8.8.
Comment #43
sam152 commentedReroll and removing stray newline.
@alexpott did you have any other feedback on the implementation? If this is fine for 8.8 I'm willing to backport it without any interface changes.
Comment #44
alexpottI think #43 is fine for 8.8.x as long as we have a change record. As I pointed out in #41 method additions are permitted in minor releases.
And yeah if we what to backport to 8.7.x we can put the method on the widget but fixing it right first in 8.8.x feels correct.
Comment #45
sam152 commentedAdded a change record: Additional "getOriginalState" method added to the moderation information service and ModerationInformationInterface
Comment #46
sam152 commentedMost of the legwork was done by @chr.fritsch, so RTBC, would be good to get this long standing bug resolved.
Comment #47
alexpottCredited @malcomio, @alexpott, @timmillwood for code reviews.
Committed 4a1e820 and pushed to 8.8.x. Thanks!
Comment #49
sam152 commentedBackported to 8.7.
Comment #50
sam152 commentedComment #51
chr.fritschLet's get this into to 8.7
Comment #52
mtodor commentedI have tested preview with content moderation on 8.8.x and I have encountered following problem.
When you have state that can not be transitioned to it self. For example:
draft->unpublishedandunpublished->draft, but withoutunpublished->unpublished. When you select that state and go to preview and back, state selection combobox is not available anymore.Note: it happens only for new content create. fe.
/node/add/articleComment #53
mtodor commentedI have investigated further and found a solution. Here are patches for 8.8.x and 8.7.x (+ interdiff for 8.7).
I wanted to keep changes small, so that's easier to review solution. If solution is good, then I would just reverse
ifstatement and check forisNew()first.Comment #54
sam152 commentedLets open up a new issue, it seems a bit weird to continue committing incremental patches to 8.8 and then combined patches to 8.7. Lets commit the bugfix to 8.8 in a new issue and then backport both at once in either a new issue or one of the 8.8 issues?
Comment #55
sam152 commentedLets start fresh: