Problem/Motivation

If the passed $request argument is NULL (or none), an error is thrown, for the following code: $request->query->get(static::QUERY_PARAMETER);
(https://git.drupalcode.org/project/drupal/-/blob/8.9.x/core/modules/lang...)

Proposed resolution

Check whether $request is set, before trying the access the query property.

Issue fork drupal-3130751

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:

Comments

stefanos.petrakis created an issue. See original summary.

stefanos.petrakis’s picture

Status: Active » Needs review
StatusFileSize
new827 bytes

Here is the patch.

stefanos.petrakis’s picture

Title: Fix LanguageNegotiationMethodInterface::getLangcode() error throwing for a NULL request » Fix LanguageNegotiationMethodInterface::getLangcode() error thrown for a NULL request
stefanos.petrakis’s picture

Title: Fix LanguageNegotiationMethodInterface::getLangcode() error thrown for a NULL request » Fix LanguageNegotiationMethodInterface::getLangcode() errors thrown
Version: 9.1.x-dev » 8.9.x-dev
StatusFileSize
new862 bytes
new731 bytes

Another issue came up while writing unit tests, when the languageManager is not set.

Updated the patch and issue's title.

jungle’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentEntity.php
    @@ -97,6 +97,10 @@ public static function create(ContainerInterface $container, array $configuratio
       public function getLangcode(Request $request = NULL) {
    +    if ($request === NULL || $this->languageManager === NULL) {
    +      return NULL;
    +    }
    

    Code above is from the patch

    
       * @return string
       *   A valid language code or FALSE if the negotiation was unsuccessful.
       */
      public function getLangcode(Request $request = NULL);
    
    

    a) Based on the comments of \Drupal\language\LanguageNegotiationMethodInterface::getLangcode() above, returning NULL is inapplicable. And the type hinting of the interface should be updated to string|false or string|bool, not sure which one is applicable, is false a type? but found usages in core.

    b) Or update the comment to say string or NULL, and change @return string to @return string|null

  2. And the whole method might need to be rewritten

        if ($request === NULL || $this->languageManager === NULL) {
          return NULL;
        }
    
        $langcode = $request->query->get(static::QUERY_PARAMETER);
    
        $language_enabled = array_key_exists($langcode, $this->languageManager->getLanguages());
        return $language_enabled ? $langcode : NULL; 
    

    a) $langcode = $request->query->get(static::QUERY_PARAMETER); is possible to return NULL.
    b) the const name QUERY_PARAMETER is too generic, it's not obvious relevant to langcode or language_content_entity -- the real value. But it's out of the scope here.

stefanos.petrakis’s picture

Thanks for the review!

Regarding (1): See ongoing discussion over at #3126127: Fix LanguageNegotiationMethodInterface::getLangcode() result docblock, if you haven't seen that already. It may be that the docblock could be modified to extend the range of return value types.

Regarding (2): That is a different topic, again, more relevant to #3126127: Fix LanguageNegotiationMethodInterface::getLangcode() result docblock, the code changes I suggest are only focusing on errors coming up during Unit Testing, a WIP from #3130107: Extend unit test coverage for LanguageNegotiationContentEntity

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

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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.

larowlan’s picture

Is this still an issue?

stefanos.petrakis’s picture

Version: 9.4.x-dev » 9.5.x-dev
Status: Needs work » Needs review

Yes, still an issue, albeit on the unit level.

The rest of the @LanguageNegotiation plugins have defensive code in place for $request (when they use it) and sometimes even for the $this->languageManager.

This is really not a big issue, code from core that calls getLangcode() usually has some checks implemented beforehand.
However, since this is a public method, I believe it would be good to add the defenses and keep aligned with the rest of the codes found under core/modules/language/src/Plugin/LanguageNegotiation

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.

larowlan’s picture

Version: 10.1.x-dev » 9.5.x-dev
Priority: Normal » Minor
Issue tags: +Needs tests
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentEntity.php
@@ -97,6 +97,10 @@ public static function create(ContainerInterface $container, array $configuratio
+    if ($request === NULL || $this->languageManager === NULL) {
+      return NULL;

According to the API, this should return a string or FALSE, not NULL - so I think we should update this.

As this is a bug, we need a failing test demonstrating the issue. And whilst \Drupal\Tests\language\Functional\LanguageNegotiationContentEntityTest might seem a logical place for this, I think we can test it in a Unit test to reproduce the reported issue here.

medha kumari’s picture

Rerolled the patch #4 in Drupal 9.5.x and changes comment #14.

stefanos.petrakis’s picture

Version: 9.5.x-dev » 10.1.x-dev
Assigned: Unassigned » stefanos.petrakis

Picking this up; gonna work against 10.1.x to address comments in #14, including the work from #15

stefanos.petrakis’s picture

Tests (including new ones) are green, hiding patch files and this is ready for a review again. This time via the MR.

larowlan’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests

Couple of minor comments on the MR

stefanos.petrakis’s picture

Status: Needs work » Needs review

Thanks for the review, I fixed one more incompatibility issue with the returning value. And extended the tests with 2 more cases, I hope this is good now!

larowlan’s picture

Status: Needs review » Reviewed & tested by the community

This looks good to me, thanks @stefanos.petrakis 🙌

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I don't think we should be changing the return value here. I think we should open a separate issue to discuss the fact the interface docs and the implementations (at least all the ones I've checked) do different things. Personally I think we should always err on the side of changing the docs rather code.

stefanos.petrakis’s picture

stefanos.petrakis’s picture

Status: Needs work » Needs review
Related issues: +#3126127: Fix LanguageNegotiationMethodInterface::getLangcode() result docblock

Now that #3126127: Fix LanguageNegotiationMethodInterface::getLangcode() result docblock is fixed and there is no documentation-inconsistency aspect, this here issue can move forward. Setting it back to NR since my latest changes set the return values to NULL (as was originally) instead of FALSE. That way the change-set focuses only on the reported errors (see description).

stefanos.petrakis’s picture

Title: Fix LanguageNegotiationMethodInterface::getLangcode() errors thrown » Fix LanguageNegotiationContentEntity::getLangcode() errors thrown
larowlan’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @stefanos.petrakis for creating the separate issue and following this one through

This looks good to me

alexpott’s picture

Version: 10.1.x-dev » 10.0.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed 5738144ad9 to 10.1.x and 681c999fea to 10.0.x. Thanks!

Not backporting to 9.5.x because the test needs changing because it has property typehints and we still support PHP 7.3 there and this is a minor bug.

  • alexpott committed 5738144a on 10.1.x
    Issue #3130751 by stefanos.petrakis, Medha Kumari, larowlan, alexpott,...

  • alexpott committed 681c999f on 10.0.x
    Issue #3130751 by stefanos.petrakis, Medha Kumari, larowlan, alexpott,...

Status: Fixed » Closed (fixed)

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