Problem/Motivation

The documentation of \Drupal\Core\Plugin\Context\ContextRepositoryInterface::getAvailableContexts() says:

Gets all available contexts *for the purposes of configuration.*

The expected flow is that you have something like a block edit form with context mapping. You call the available contexts, you configure it, and then at runtime, you only load the contexts that you need.

There is no caching, static or otherwise on this method. There's nothing very expensive in core, but we have have context providers expose terms of certain bundles as context, and we run an entity query in that method. And @EclipseGc always had similar plans for core as well. I didn't notice until recently, but the entity upcasting can easily be called dozens of times on a page when upcasting entities of menu link access checks. That means dozens of entity queries for our project.

I honestly don't understand why we use the plugin context system on that level. The implementation is hardcoded, we only care about two specific language contexts, and we have the language manager injected, there is no reason why the current language contexts would return anything else than getCurrentLanguage($type).

The only actual context that we pass along we have to create as a fake context is the the translation operation context, which IMHO shows quite nicely that this is the wrong approach. Plugin context is meant to be provided as a global thing to you, similar to cache contexts, not that you hardcode it and pass it to something else

Maybe I should have pushed back more on that in the original issue :)

Proposed resolution

Remove the getAvailableContexts() calls in EntityRepository and EntityConverter.
Remove the user context workaround that's apparently still causing some problems as we don't need the user context at all.
Switch EntityRepository::getContentLanguageFromContexts() to use LanguageManager::getCurrentLanguage().

Remaining tasks

Decide if we need BC here.

(For BC, we could keep using those language context for the unlikely case that someone did use it. And maybe switch "back" to simple context keys like operation and language if you do want to get the the canonical entity for a specific language.)

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork drupal-3158130

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Berdir created an issue. See original summary.

Berdir’s picture

Status: Active » Needs review
FileSize
3.79 KB

This keeps BC if something is explicitly passed in, EntityRepositoryTest still passes but as mentioned, wondering if we should deprecate the use of those plugin context keys. It seems like a conceptual mismatch.

The only "API" change is the text that says that it defaults to all, but that's an implementation detail, not an API.

I'm also not sure if I understand why only canonical supports the legacy translation context and active doesn't.

Berdir’s picture

+++ b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
@@ -105,24 +105,9 @@ public function convert($value, $definition, $name, array $defaults) {
-    // @todo Consider deprecating the legacy context operation altogether in
-    //   https://www.drupal.org/node/3031124.
-    $contexts = $contexts_repository->getAvailableContexts();
+    $contexts = [];
     $contexts[EntityRepositoryInterface::CONTEXT_ID_LEGACY_CONTEXT_OPERATION] =

The @todo shouldn't be deleted.

mayurjadhav’s picture

Assigned: Unassigned » mayurjadhav

Working on it, Assigning to me.

mayurjadhav’s picture

mayurjadhav’s picture

Assigned: mayurjadhav » Unassigned
larowlan’s picture

acbramley’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Entity/EntityRepository.php
    @@ -133,13 +133,9 @@ public function getActive($entity_type_id, $entity_id, array $contexts = NULL) {
    +  public function getActiveMultiple($entity_type_id, array $entity_ids, array $contexts = []) {
    
    @@ -177,7 +173,7 @@ public function getCanonical($entity_type_id, $entity_id, array $contexts = NULL
    +  public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $contexts = []) {
    

    I don't think we should be changing this here.

  2. +++ b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
    @@ -105,24 +105,11 @@ public function convert($value, $definition, $name, array $defaults) {
         // @todo Consider deprecating the legacy context operation altogether in
    ...
    +    //   https://www.drupal.org/node/3031124
    

    as per #3 this should be removed entirely.

mayurjadhav’s picture

Assigned: Unassigned » mayurjadhav

Working on the #8 comments.

mayurjadhav’s picture

Assigned: mayurjadhav » Unassigned

@acbramley Thanks for the review,

As we are overriding the $contexts right after the function start then initialising the argument in defensive case the right way.

regarding point 2 do we need to delete the todo along with legacy context?

Berdir’s picture

#8.2: No, this change is correct. I removed too much. The $context changes however should be reverted from the changes in #5, we don't want to change the function definition here, that's part of the interface.

mayurjadhav’s picture

Status: Needs work » Needs review

Updated the patch as per #11. I changed function definition in my last patch which was wrong.

mayurjadhav’s picture

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ranjith_kumar_k_u’s picture

Re-rolled #13 for 9.4.

ranjith_kumar_k_u’s picture

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Shubham Chandra’s picture

Added Patch against #18 in Drupal 10.1.x

gaurav-mathur’s picture

Patch #13 not work in drupal 10.1.x-dev please reroll the patch.
Thank you.

himanshu_jhaloya’s picture

FileSize
56.66 KB

#21 applied cleanly drupal 10.1.x-dev

dpi’s picture

Status: Needs review » Needs work

The patch doesn't need a re-roll, it needs to be fixed as it is failing CI.

_pratik_’s picture

Assigned: Unassigned » _pratik_
_pratik_’s picture

Assigned: _pratik_ » Unassigned
Status: Needs work » Needs review
FileSize
3.78 KB
773 bytes

This patch is applying for 10.1.x clean. Also PHPstan CCF failed is fixed in it.
Thanks

andypost’s picture

It looks ready to go, all places are cleaned and no tests failed!

It needs change record to point what effect module developers can get as only one language context is available

andypost’s picture

Also issue summary needs update about API changes or language change could go to follow-up

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Berdir’s picture

Status: Needs work » Needs review
FileSize
3.74 KB

Reroll for 11.x.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update

For the API change mentioned in #28 and CR in #27

jasonawant’s picture

FileSize
3.73 KB

Here's a patch for 10.1.x branch.

This resolves an issue I was experiencing when attempting to apply runtime contexts to condition plugins. The condition plugins, specifically entity_bundle:node, was not able to evaluate b/c of missing context value.

        $contexts = $this->contextRepository->getRuntimeContexts($condition_plugin->getContextMapping());
        $this->contextHandler->applyContextMapping($condition_plugin, $contexts);

Sorry, I'm not able to help with CR or the issue summary; I'm not sure what exactly is needed.

voleger made their first commit to this issue’s fork.

voleger’s picture

FileSize
3.74 KB

Created MR based on #30.
Attaching the patch for 10.2.x branch

longwave’s picture

Ran into this today when doing some profiling. Tracing the code before finding this issue I also discovered that we load all the contexts to only use the language ones; I don't fully understand this subsystem but it seems like we could optimise here. LazyContextRepository::getAvailableContexts() takes 15% of the request time in some cases according to xhprof so if we can remove this entirely it looks like it would be a good performance gain.

longwave’s picture

Status: Needs work » Needs review

Fixed the performance test assertions (decreasing some values!) and rebased.

longwave’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Updated IS. Does this need a change record? Not sure who this would affect or who to write the change record for.

longwave’s picture

@Berdir thanks for the explanation - this is quite the mess and I'm not sure either how to immediately start untangling it.

To fix the immediate performance issue (all contexts are loaded but only two are ever used) I attempted a stopgap approach in MR!7222. This only loads the contexts that EntityRepository needs - if the site isn't multilingual then it doesn't load them at all. This also removes one of the @todos but replaces it with another :)

I think longer term that just passing around an optional $langcode would be a better idea and perhaps we should try to untangle it all in one go by switching to that, but without diving in and trying it I'm not sure of the full implications.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
FileSize
1.54 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

longwave’s picture

Status: Needs work » Needs review
longwave’s picture

On my test site MR!7222 shaves at least 2-3ms off every page load that invokes EntityConverter::convert().

Berdir’s picture

I updated the main MR with an attempt to implement what I suggested in my comment, I also added the test from #2978048: Unpublished translations should fallback to the original language because this should allow that one to pass as well. Didn't really test yet beyond that.

Berdir’s picture

So my proposal basically works, but after working through #3031124: Deprecate the "entity_upcast" operation specified in EntityConverter and #2942907: Entity system does not provide an API for retrieving an entity variant that is safe for editing once again, the operation/entity_upcast thing is not as straight forward as the langcode thing is, so I think that needs to stay for now to avoid too much complexity and change in a single issue. I think I can revert it to the point where the operation is just passed in as a regular array key, in sync with existing language fallback context parameters, without those pseudo-plugin-context-ids.

smustgrave’s picture

Status: Needs review » Needs work

Not sure which MR is to be reviewed. Could one be hidden please?

longwave changed the visibility of the branch 3158130-performance-fix to hidden.

longwave’s picture

Hidden mine, while it looks like it works I think Berdir's covers more ground in the direction we want to go in.

Still NW for now as it needs rebasing.

weekbeforenext made their first commit to this issue’s fork.

weekbeforenext’s picture

Resolved merge conflicts in the MR, then realized that the patch from #35 applies to 10.2.4. :shrug:

longwave’s picture

Status: Needs work » Needs review

Rebased again.

smustgrave’s picture

Status: Needs review » Needs work

Left some comments on the MR.

longwave’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record

Had a go at a change record, @Berdir can hopefully correct my mistakes and flesh this out a bit more! https://www.drupal.org/node/3437685

Changing the argument defaults from NULL to [] means changing the interface, not worth doing here with all the other changes, let's just leave this as-is for now.

Berdir’s picture

Status: Needs review » Needs work

Did a review, will try to do that myself when I find time, but feel free to pick it up if you have time earlier, not exactly sure when I will.

Berdir’s picture

Status: Needs work » Needs review

Addressed my review. Also deprecated the constant, FWIW, there's not a single usage of this in all of contrib.

longwave’s picture

Status: Needs review » Needs work

Added a question to the MR as it appears we're also implementing #2978048: Unpublished translations should fallback to the original language here. If this is unavoidable I think we need a change notice for that issue explaining the change and also how to revert it back to the previous behaviour.

Berdir’s picture

Status: Needs work » Needs review

Found the problem, I needed to drop the $legacy_contexts and instead just pass $contexts through. Thanks for catching that!

And yes, that single 200/403 line is literally the whole test coverage that exists in core for the current entity_upcast behaviour, and we only added that in a separate issue as part of the translate-editable-content permission. There's that unit test mock, but that does not test what's going on inside EntityRepository.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
FileSize
3.39 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

longwave’s picture

Status: Needs work » Reviewed & tested by the community

Thanks - the explanation and fix makes perfect sense, and it seems in that other issue people are relying on that test assertion so let's keep it as is and defer fixing that until later (or never).

Everything else here looks great so marking RTBC, we have some other good performance improvements in 10.3 so would be nice to land this one as well.

  • catch committed 5535002d on 10.3.x
    Issue #3158130 by longwave, Berdir, voleger, mayurjadhav,...

  • catch committed adedbb17 on 11.x
    Issue #3158130 by longwave, Berdir, voleger, mayurjadhav,...
catch’s picture

Version: 11.x-dev » 10.3.x-dev
Status: Reviewed & tested by the community » Fixed

Nice work untangling the various scope issues here, hopefully we can keep going in the related issues and make all this a bit more understandable.

Also pleased to see the performance tests pick up that there is some improvement (even if the improvement is not really that we're removing the cache get, at least we can see that something is happening less than it previously was).

Committed/pushed to 11.x and cherry-picked to 10.3.x, thanks!