Problem/Motivation
Language negotiation is handled by the LanguageNegotiator class. It should not be making runtime changes to the Language or ConfigurableLanguage object.
Proposed resolution
Remove method_id from Language and ConfigurableLanguage
Remaining tasks
Review patch
User interface changes
No.
API changes
- Add ConfigurableLanguageManagerInterface::getNegotiatedLanguageMethod($type = LanguageInterface::TYPE_INTERFACE) so that the system can get information as to how language negotiation has occurred for a particular language type.
- Change LanguageNegotiatorInterface::initializeType($type) to support the above addition.
Original report
#2226533: Changes to the Language class due to the LanguageInterface (followup) is setting method_id to protected was
diff --git a/core/modules/language/src/LanguageNegotiationMethodBase.php b/core/modules/language/src/LanguageNegotiationMethodBase.php
index 3f48f7a..8fc98e9 100644
--- a/core/modules/language/src/LanguageNegotiationMethodBase.php
+++ b/core/modules/language/src/LanguageNegotiationMethodBase.php
@@ -63,7 +63,7 @@ public function setCurrentUser(AccountInterface $current_user) {
*/
public function persist(BaseLanguageInterface $language) {
// Remember the method ID used to detect the language.
- $language->method_id = static::METHOD_ID;
+ $language->setNegotiationMethodId(static::METHOD_ID);
}
}
but #2334763: Tidy up of LanguageInterface - removal of setters and other unnecessary methods is taking out method_id and setNegotiationMethodId()
Comment | File | Size | Author |
---|---|---|---|
#13 | interdiff.2337847.6.13.txt | 1.08 KB | YesCT |
#13 | 2337847.13.patch | 9.57 KB | YesCT |
#6 | 2337847.6.patch | 9.64 KB | alexpott |
#6 | 4-6-interdiff.txt | 2.93 KB | alexpott |
#4 | 3-4-interdiff.txt | 6.5 KB | alexpott |
Comments
Comment #1
YesCT CreditAttribution: YesCT commentedsimilar in
diff --git a/core/modules/language/src/LanguageNegotiator.php b/core/modules/language/src/LanguageNegotiator.php
index eb1df93..b00b3fc 100644
--- a/core/modules/language/src/LanguageNegotiator.php
+++ b/core/modules/language/src/LanguageNegotiator.php
@@ -152,7 +152,7 @@ public function initializeType($type) {
if (!$language) {
// If no other language was found use the default one.
$language = $this->languageManager->getDefaultLanguage();
- $language->method_id = LanguageNegotiatorInterface::METHOD_ID;
+ $language->setNegotiationMethodId(LanguageNegotiatorInterface::METHOD_ID);
}
return $language;
Comment #2
martin107 CreditAttribution: martin107 commentedIt a howler when you see it. Simple to fix.
Comment #3
alexpottActually there is no need to set method id on the language and in fact we probably should not since languages are what is negotiated and the method is what is use to do the negotiation - it's not really a property of the language at all. It's a state of the languageNegotiator - i.e. what method have been used to negotiate which languages.
Patch attached removes the method_id property from both Language and ConfigurableLanguage and adds a method to LanguageNegotiator to retrieve the current state.
Comment #4
alexpottI'm not 100% certain about this change - obviously we don't have test coverage for it since the patch is green but the patch attached moves stuff around so you can get the negotiation method from the ConfigurableLanuageManager. This feels correct since it is responsible for integrating all the language subsystems. This means that the negotiator remains resettable.
Comment #5
Gábor HojtsyI agree with the goals, the language indeed does not have anything to do with how it got to be born :) AKA the negotiator. But we need it for at least testing that it works right and possible for other reasons in the future. I have concern with the implementation though.
While it is a neat trick to store the method ID on an array element, this array will only ever contain one element, so the array nesting is used to store metainfo on how the negotiation got the value. Why not store it in another property of the configurable language manager for each type? Sounds less nifty tricks but maybe easier to understand?
Comment #6
alexpottHow about something like this. I'm keen to keep LanguageNegotiatorInterface::initializeType($type) returning an array since this means the typehint works. And anything else that uses it can get the method id just as easily.
Comment #7
Gábor HojtsyThat looks better, thanks. As for your concern on the change in #4, you are not making that change anymore in recent patches? I am not sure why it was added/removed? :)
Comment #8
alexpottIn the changes from #3 to #4 I moved stuff to the LanguageManager from LanguageNegotiator so yep no longer a concern.
Comment #9
Gábor HojtsyAll good with me then, thanks!
Comment #10
martin107 CreditAttribution: martin107 commentedI can see a minor snafu by running this patch through a lint checker...
Method 'getNegotiatedLanguageMethod' not found in class
from this code in language_test.module
drupal_set_message(t('Language negotiation method: @name', array('@name' => \Drupal::languageManager()->getNegotiatedLanguageMethod())));
From the annotations in Drupal.php the return from \Drupal::languageManager() is a \Drupal\Core\Language\LanguageManagerInterface object
and not \Drupal\language\ConfigurableLanguageManagerInterface
Comment #11
alexpott@martin107 that's not really a snafu - the ConfigurableLanguageManger implements LanguageManagerInterface as well as ConfigurableLanguageManagerInterface but \Drupal can only be sure that it returns a object that implements LanguageManagerInterface. There is no way of changing \Drupal return types if a module is enabled that replaces a service that is returned by \Drupal and extends the original interface. That is exactly what the language module does.
Comment #12
martin107 CreditAttribution: martin107 commented@alexpott thanks for the update
Comment #13
YesCT CreditAttribution: YesCT commentedread through this. Interested because it effects #2226533: Changes to the Language class due to the LanguageInterface (followup)
found two small nits while reading. fixed. The standards got updated ... a year ago taking out the need to restate the Default value on @params, when it is just repeating the info in the function signature. #1916652: defaults to in 1354 doc standards for optional args
The other was a double blank line.
Should still be rtbc.
Comment #14
alexpottI agree :)
Comment #15
alexpottAnd thanks @YesCT - I didn't know about that update to the standard.
Comment #16
catchCommitted/pushed to 8.0.x, thanks!
Comment #18
Gábor Hojtsy