Problem/Motivation
I built a small module (see https://gist.github.com/rachellawson/36f7c8d99085d98ab561a263834ac304) that adds a new tab to content. It has a _custom_access function to determine whether it should be shown and, for some reason, only when content moderation is enabled and in use, creates the exception below:
The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\content_moderation\ModerationInformation::isModeratedEntity() must implement interface Drupal\Core\Entity\EntityInterface, string given, called in /var/www/drupalvm/web/core/modules/content_moderation/src/Plugin/Menu/EditTab.php on line 81 in Drupal\content_moderation\ModerationInformation->isModeratedEntity() (line 37 of core/modules/content_moderation/src/ModerationInformation.php).
Drupal\content_moderation\ModerationInformation->isModeratedEntity('12336') (Line: 81)
Drupal\content_moderation\Plugin\Menu\EditTab->getTitle()
call_user_func_array(Array, Array) (Line: 174)
Drupal\Core\Menu\LocalTaskManager->getTitle(Object) (Line: 323)
Drupal\Core\Menu\LocalTaskManager->getTasksBuild('social_commentary.social_comment', Object) (Line: 358)
Drupal\Core\Menu\LocalTaskManager->getLocalTasks('social_commentary.social_comment', 0) (Line: 94)
Drupal\Core\Menu\Plugin\Block\LocalTasksBlock->build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
etc ...
Steps to reproduce include having code to add a tab as above. Once enabled and a content type including a field_facebook_comment boolean field is included, visiting content *seems* to be fine *until* a new draft is added and then published. Visiting the social tab then causes the exception.
Obviously, the exception is not apparent when content moderation is not enabled on the content type.
Comment | File | Size | Author |
---|---|---|---|
#38 | interdiff.txt | 473 bytes | timmillwood |
#38 | 2828438-38.patch | 7.74 KB | timmillwood |
Comments
Comment #2
rachel_norfolkjust a little more info
Comment #3
rachel_norfolkAfter a loooong conversation with timmillwood and jp_stacey on IRC, we determined that the drupal_moderation module was struggling to find the $node entity when working it magic on the routes surrounding the node.
In the end, I resolved *my* issues and had a working Social tab again by changing the method signature of my \Drupal\social_commentary\Controller\DefaultController::content controller such that it specified the type of object for $node.
Changing
public function content($node) {}
to
public function content(\Drupal\node\NodeInterface $node) {}
Made everything work just fine.
The question remaining is whether this is something we need to document or whether we can work around this?
Comment #4
jp.stacey CreditAttribution: jp.stacey at Magnetic Phield commentedWhat is it that convinces content moderation to believe that it *ought* to be trying to moderate a non-entity (string) parameter in the first place? I would expect content moderation to not even be invoked, if the parameter in question weren't an entity.
Comment #5
timmillwoodI'm wondering if we need a check in Content Moderation EntityTab class that $this->entity is actually an entity.
Comment #6
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedI've hit this exact issue with creating a tab which was a view. In that case you can't hint Node on a controller because views has it's own controller and argument processing. The solution in the end was a route subscriber which altered the route definition like so:
A check would be good, because even if the label becomes inconsistent on some routes created by the user, it doesn't fatal. Then some good docs around making this work when the tabs are extended should be enough.
Comment #7
larowlanpretty sure the issue here is the access controller runs before the paramconverter has upcast the ID to an entity.
Comment #8
timmillwoodI think as a quick fix for this we should just update
\Drupal\content_moderation\Plugin\Menu\EditTab
to check$this->entity
is an instance ofEntityInterface
.Comment #9
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #10
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #11
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #14
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedI have previously removed for
Drupal\content_moderation\ModerationInformation
thisbut it's necessary for other calls.
Comment #15
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #16
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedClasses need to be imported at the top of the file.
If this check fails and the entity is null it still falls through the the following lines:
return $this->moderationInfo->isLiveRevision($this->entity)
..which reading the code, will still fatal.
Perhaps a test for this is needed after all.
Comment #17
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #18
Ada Hernandez CreditAttribution: Ada Hernandez at MTech, LLC commentedComment #19
timmillwoodCould this be merged into a single if?
Comment #20
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedAlso, if the entity can't be determined we probably should return something generic like "Edit", not null.
Also NW based on tests.
Comment #21
rachel_norfolkAlso, I've noticed the following exception on a view added as a tab, after applying the current patch at #17.
Comment #22
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedHere is a test and fix for this which I think is correct. Originally it looked like we could just load the entity ourselves if it wasn't upcast, we have access to the ID and the entity_type_id, but a few things made me think this is possibly wrong:
Overall I think it's safest just to ignore non ContentEntityInterface params.
Comment #24
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedComment #25
rachel_norfolkJust tried the latest patch in #22 and it is stopping the exception being thrown on both my own code-created tab and one added via Views.
Timmillwood's comment in #19 also appear to have been dealt with (though an interdiff would have been useful! :) )
Comment #26
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedSorry, didn't start from the original patch, hence no interdiff.
Comment #27
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedComment #28
rachel_norfolkComment #29
timmillwoodLooks like a nice solution to me!
Comment #32
catchCommitted/pushed to 8.3.x and 8.2.x, thanks!
Comment #34
xjmThe test introduced by this issue is failing in HEAD:
https://www.drupal.org/pift-ci-job/553399
Comment #36
timmillwoodThe patch in #22 is still fine for 8.2.x, but here's a patch for 8.3.x
Comment #37
rachel_norfolkWhat is the "lo" for??
Comment #38
timmillwoodNo idea! Where'd that come from? Re-rolled without it.
Comment #39
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedInterdiff LGTM
Comment #41
timmillwoodPutting back to RTBC
Comment #43
timmillwoodComment #45
timmillwoodComment #46
rachel_norfolkI don't think testbot likes timmillwood...
Comment #47
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedFails look unrelated, running again.
Comment #49
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedShould have been RTBC.
Comment #50
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commented#38 is green again against 8.3.x so I think this is ready.
Comment #51
alexpottI don't think this code will last but it is good to have it fixed just in case we don't do #2843083: Select entity type / bundle in workflow settings.
Committed 0391e31 and pushed to 8.2.x. Thanks!
Fixed unused use on commit.
Comment #54
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedThis isn't for the field API tabs, but the tabs you see when you are looking at a full node page, so I think this will actually stick around? Since #38 this applies, passes and is needed for 8.3.x as well.
Comment #55
alexpottAh that explains it - I was surprised when this got committed to 8.2.x - I thought I had committed it there #51 - I assumed I'd messed up by committing it to both branches. Committed a76eef7 and pushed to 8.3.x. Thanks!
Unused use fixed on commit.