Problem/Motivation
When dealing with Menu Link plugins programmatically, a developer might need to retrieve the content entity to access their fields or translations, at the moment the current best way to do this, seems to load the the entity using the uuid.
Steps to reproduce
N/A
Proposed resolution
Make the getEntity method public so it can be used from the \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent plugin.
Remaining tasks
- Approve the change
- Find a suitable test.
- Create a Change Record.
User interface changes
N/A
API changes
Visibility of MenuLinkContent::getEntity changed to public.
Data model changes
N/A
Release notes snippet
Before the change (extracted from) https://drupal.stackexchange.com/questions/235754/get-menu-link-item-fro...
if ($link instanceof \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent) {
$uuid = $link->getDerivativeId();
$entity = \Drupal::service('entity.repository')
->loadEntityByUuid('menu_link_content', $uuid);
$field_value = $entity->field_example->value;
}
After:
if ($link instanceof \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent) {
$entity = $link->getEntity();
$field_value = $entity->field_example->value;
}
Original report by Grimreaper
Hello,
When manipulating menu, it would be convenient to be able to access the menu link content entity easily.
Setting the visibility of the getEntity method would help.
I will upload a patch.
| Comment | File | Size | Author |
|---|---|---|---|
| #60 | interdiff-2997790-54-59.txt | 2.71 KB | mohit_aghera |
| #60 | 2997790-59.patch | 2.91 KB | mohit_aghera |
| #54 | interdiff-2997790-40-54.txt | 4.43 KB | mohit_aghera |
| #54 | 2997790-54.patch | 4.43 KB | mohit_aghera |
| #41 | 2997790-40.patch | 2.49 KB | pcambra |
Comments
Comment #2
grimreaperHere is a patch.
Thanks for the review.
Comment #3
webapp's commentedLooks great!
Comment #4
stijnstroobantsPatch works as expected!
Thanks!
Comment #6
stijnstroobantsSorry, my patch was not necessary.
I recreated the patch because the original failed, but the fail was not related to the patch.
Comment #7
brentgSeems to be working, removing the duplicate patch from @StijnStroobants and making the original one from @Grimreaper the default one.
Putting it back to reviewed and tested since it's still working
Comment #9
webapp's commentedComment #10
webapp's commentedComment #11
grimreaperBack to RTBC as the fail was not related to the patch.
Comment #12
larowlanCan you elaborate on what the use-case is here? We like to limit the API we expose so want to make sure there is a genuine need for this.
Also, if we're making it public - having at least one usage of it in core would be useful - so a test would probably be the easist thing there, because otherwise, someone might change it back without realising
Comment #13
grimreaperHello,
On the project I am currently working on and for which the original patch has been made, we use it in several times.
Comment #14
grimreaperHello,
Also found out that this feature would be useful in the "menu per role" module: https://git.drupalcode.org/project/menu_per_role/blob/8.x-1.x/src/MenuPe...
Comment #15
lozsmile commentedHello,
here's an updated patch for an automated test, thanks for review!
Comment #16
grimreaperQueeing on 8.8.x branch.
Comment #17
grimreaperTests are green on the right branch :)
Comment #18
catchThis test isn't necessary, we know PHP visibility works. Do we have an existing test in core that checks that this actually returns an entity already?
Also if the method is going to be public it should probably be added to MenuLinkContentInterface.
Tagging for issue summary update too, and Needs Change Record because this is an API addition - the change record should include an example use-case.
Comment #19
catchThis time with the tags.
Comment #20
keeneganThis could be very usefull. Here is the patch with the method added in the interface and the comments
Comment #21
keeneganAnd here is the same patch that should work for 8.6.x
Edit : woops, not the right interface
Comment #23
keeneganComment #24
keeneganComment #25
keeneganHere is the patch for Drupal 8.6.x (without the interface changes, I needed it for a project)
Comment #27
jhedstromThis is still at NW for all the reasons mentioned above.
Comment #28
ravi.shankar commentedI have re-rolled the patch #25
Comment #29
nterbogt commented+1
The translatable_menu_link_url module could also use this to reduce a bunch of entity loads they've manually coded.
We would also use it for some custom menu rendering.
Comment #31
matthieuscarset commentedIn a project of mine, menu link content should not be visible if
$entity->access('view')is not allowed. Therefore, I needed to access the menu link content's entity.+1 for opening this issue and thank you for the work.
I confirm patch works as expected.
Comment #32
nterbogt commentedComment #33
xjmThanks for proposing this issue!
This still needs a change record and an issue summary update. It may also need automated tests to confirm the method works properly when called externally. We should check for existing test coverage of the method and document what already exists. If the method doesn't already have test coverage, then we need to add a simple test for it.
Finally, we probably want subsystem maintainer approval to increase the visibility of this part of the API, so tagging for that. (If we don't receive subsystem maintainer review in a timely fashion, the framework managers can evaluate it instead.)
Thanks!
Comment #34
xjmAlso see #18 and #12. Three committers have now requested these things. :) Let's not mark it RTBC again until those things are addressed. Thanks!
Comment #38
pcambraNot sure why the interface changes got removed, but I've added it back.
I'm tagging this as DX because it is a bit weird that you need to load the entity when needed (i.e. how do you retrieve a translated title of a menu from the plugin?) when it is already on the object.
I've tried to find a good usage for core so we can add a ad-hoc test, but haven't been able to find any, however, as some have pointed out, contrib modules could benefit of this visibility increase.
Comment #39
pcambraWrong, patch, this is the right one.
Updating the summary shortly.
Comment #40
pcambraComment #41
pcambraAh wrong interface, we need to create one I think
Comment #42
matthieuscarset commentedReplying to @pcambra for a real use case in core is, for instance, if you want to check access by language.
Comment #43
joachim commentedA bit of a nitpick, but I don't think CFPI should be on here. It should stay on the class.
If a plugin class has DI, then that's an implementation detail of that particular class. It's not a behaviour we expect menu link plugins to have in general.
Comment #46
samirmtl commentedHi
I was faced this issue, in our context, we are using graphql-4.x producers to fetch the menu via GraphQl calls, in a multilanguale website, we must return the current language of the menu_link_content properties, and in a decouled Drupal website the language context is not easy to deal with, the graphQl Producer method had to access to the menu_link_content entity to be able to get correct field languages.
Now our problem and after updating to last Drupal Core 9.4.8, the pathes here, are not applied any more onour Drupal Deployement pipeline (that uses composer install)
I agree with @joachim, " I don't think CFPI should be on here. It should stay on the class."
Comment #47
ravi.shankar commentedAdded reroll of patch #46.
Comment #48
anchal_gupta commentedI have fixed CS error.
Comment #49
pooja saraah commentedFixed failed commands on #48
Attached interdiff patch
Comment #50
shubham chandra commentedRe-rolled patch against #41 in drupal 10.1.x
Comment #51
gaurav-mathur commentedRe-rolled patch against #41 in drupal 10.1.x-dev
Comment #52
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #53
angrytoast commentedQuestion: Per #18
Is this accurate? We're looking at the menu link plugin class, which extends
MenuLinkBasewhich implementsMenuLinkInterfaceMenuLinkContentInterfaceis about a content entity class interface.Should it be on
MenuLinkInterfaceorMenuLinkContentInterface?Comment #54
mohit_aghera commentedI think the patch in #46 #47 #48 #49 #50 #51 seems incorrect re-rolls.
All are missing the new interface added in patch #40
Hiding all 5 patches.
- Adding a new test case to validate the
getEntitymethod and validate the return value.- CR added here https://www.drupal.org/node/3361300
Comment #56
smustgrave commentedBeen 3 years without submaintainer review so moving to framework.
Comment #57
smustgrave commentedTo get this in front of a committer for their thoughts.
Comment #58
catchIt's a bit confusing having two classes called MenuLinkContentEntityInterface. I don't think I realised this would happen when I asked for the method to be added to the interface.
Sorry to contradict myself from 2019, but I think we should not add this interface and just make the method on the plugin class public instead.
I checked for duplicate test coverage and couldn't find any, so that bit is fine.
Comment #59
mohit_aghera commentedDone, removed the additional interface and test is passing on local.
Comment #60
mohit_aghera commentedOops, accidentally removed keyword.
Putting back.
Interdiff is against #54
Hiding #59
Comment #61
catchOK this looks good.
It just being a public method on a plugin means there's no official bc guarantee, but in practice unless we do a major reworking of the menu links system again I can't see this changing dramatically, and for core I think it makes more sense than adding an interface for a plugin implementation.
Comment #63
lauriiiCommitted 7961aba and pushed to 11.x. Thanks!
Comment #64
grimreaperHi,
Thanks for the merge!
I think some info in the change record are wrong:
- Introduced in branch should be 11.x, not 10.2.x
- Introduced in version should be 11.0.0, not 10.2.0
Or am I confused with https://www.drupal.org/about/core/blog/new-drupal-core-branching-scheme-...?
Comment #65
lauriii10.2.x will be branched from 11.x later this year. I’m not sure if the introduced in branch should 11.x or 10.2.x but the version is correct.
Comment #66
grimreaperThanks for the quick reply!
So I was confused :)
I also searched for a 10.2.x branch in Gitlab in the meantime and did not find one, so this is the explanation.
As Drupal 10.1.0 was out, I thought a 10.2.x branch would already exist.
Sorry!